chiark / gitweb /
noip: set ACLs from environment variables.
authormdw <mdw>
Fri, 6 May 2005 14:25:06 +0000 (14:25 +0000)
committermdw <mdw>
Fri, 6 May 2005 14:25:06 +0000 (14:25 +0000)
noip.1
noip.c

diff --git a/noip.1 b/noip.1
index fe56efdecb3d47d7d7ca6876897b602cfb2b0ad1..36b4cf0eae14f4e18ac61cbc6cdc7accc8db8220 100644 (file)
--- a/noip.1
+++ b/noip.1
@@ -81,7 +81,11 @@ in the calling user's home directory, as determined by the
 .B HOME
 environment, or, failing that, looking up the 
 .I real
-(not effective) user id in the password database.
+(not effective) user id in the password database.  However, if the
+environment variable
+.B NOIP_CONFIG
+is set, then the file it names is read instead (assuming it exists; if
+it doesn't, no configuration is read).
 .PP
 The configuration file has a simple line-based format.  A line is
 ignored if it consists only of whitespace, or if its first whitespace
@@ -106,7 +110,9 @@ can be used to control this.
 .BI "socketdir " directory
 Store the Unix-domain sockets in
 .IR directory 
-rather than the default.
+rather than the default.  The environment variable
+.B NOIP_SOCKETDIR
+can also be used to control which directory is used for sockets.
 .TP
 .BI "realbind " acl-entry
 Add an entry to the
@@ -117,9 +123,23 @@ a socket to an address, the
 .B realbind
 ACL is consulted.  If the address is matched, then the program is
 allowed to bind a real Internet socket to that address; otherwise, the
-socket is bound to a Unix-domain socket.
+socket is bound to a Unix-domain socket.  Three environment variables
+are consulted too:
+.BR NOIP_REALBIND_BEFORE ,
+.BR NOIP_REALBIND ,
+and
+.BR NOIP_REALBIND_AFTER .
+The
+.B _BEFORE
+rules are inserted at the front of the list; the
+.B _AFTER
+rules are appended on the end.  Currently, the rules in
+.B NOIP_REALBIND
+are also put at the end (before the
+.B _AFTER
+rules), though this may change later.
 .TP
-.BI "realbind " acl-entry
+.BI "realconnect " acl-entry
 Add an entry to the
 .B realconnect
 access control list (ACL).  When a program attempts to
@@ -132,7 +152,21 @@ the
 .B realconnect
 ACL is consulted.  If the destination address is matched, then the
 program is allowed to contact the real Internet socket; otherwise, the
-attempt is made to contact a Unix-domain socket.
+attempt is made to contact a Unix-domain socket.  Three environment variables
+are consulted too:
+.BR NOIP_REALCONNET_BEFORE ,
+.BR NOIP_REALCONNECT ,
+and
+.BR NOIP_REALCONNECT_AFTER .
+The
+.B _BEFORE
+rules are inserted at the front of the list; the
+.B _AFTER
+rules are appended on the end.  Currently, the rules in
+.B NOIP_REALCONNECT
+are also put at the end (before the
+.B _AFTER
+rules), though this may change later.
 .PP
 (Aside: An attempt to connect to a remote host may not be a hopeless failure,
 even if a real IP socket is denied:
@@ -144,7 +178,7 @@ servers.)
 .PP
 An
 .I acl-entry
-has this format:
+is a comma-separated list of entries of the form:
 .IP
 .BR + | \-
 .IR address \c
diff --git a/noip.c b/noip.c
index 735a58a7995f9033d86217b2c124508f37244036..2f7fd148800057910f2cce63154760b96887acc2 100644 (file)
--- a/noip.c
+++ b/noip.c
@@ -533,60 +533,65 @@ static void parse_acl_line(char **pp, aclnode ***tail)
   char *p = *pp;
   char *q;
 
-  SKIPSPC;
-  if (*p == '+') act = ALLOW;
-  else if (*p == '-') act = DENY;
-  else goto bad;
+  for (;;) {
+    SKIPSPC;
+    if (*p == '+') act = ALLOW;
+    else if (*p == '-') act = DENY;
+    else goto bad;
 
-  p++;
-  SKIPSPC;
-  if (KWMATCHP("any")) {
-    minaddr = 0;
-    maxaddr = 0xffffffff;
-    goto justone;
-  } else if (KWMATCHP("local")) {
-    parse_ports(&p, &minport, &maxport);
-    ACLNODE(*tail, act, 0, 0, minport, maxport);
-    ACLNODE(*tail, act, 0xffffffff, 0xffffffff, minport, maxport);
-    for (i = 0; i < n_local_ipaddrs; i++) {
-      minaddr = ntohl(local_ipaddrs[i].s_addr);
-      ACLNODE(*tail, act, minaddr, minaddr, minport, maxport);
-    }
-  } else {
-    if (*p == ':') {
+    p++;
+    SKIPSPC;
+    if (KWMATCHP("any")) {
       minaddr = 0;
       maxaddr = 0xffffffff;
+      goto justone;
+    } else if (KWMATCHP("local")) {
+      parse_ports(&p, &minport, &maxport);
+      ACLNODE(*tail, act, 0, 0, minport, maxport);
+      ACLNODE(*tail, act, 0xffffffff, 0xffffffff, minport, maxport);
+      for (i = 0; i < n_local_ipaddrs; i++) {
+       minaddr = ntohl(local_ipaddrs[i].s_addr);
+       ACLNODE(*tail, act, minaddr, minaddr, minport, maxport);
+      }
     } else {
-      NEXTADDR(q, del);
-      if (inet_pton(AF_INET, q, &addr) <= 0) goto bad;
-      minaddr = ntohl(addr.s_addr);
-      RESCAN(del);
-      SKIPSPC;
-      if (*p == '-') {
-       p++;
+      if (*p == ':') {
+       minaddr = 0;
+       maxaddr = 0xffffffff;
+      } else {
        NEXTADDR(q, del);
        if (inet_pton(AF_INET, q, &addr) <= 0) goto bad;
+       minaddr = ntohl(addr.s_addr);
        RESCAN(del);
-       maxaddr = ntohl(addr.s_addr);
-      } else if (*p == '/') {
-       p++;
-       NEXTADDR(q, del);
-       if (strchr(q, '.')) {
+       SKIPSPC;
+       if (*p == '-') {
+         p++;
+         NEXTADDR(q, del);
          if (inet_pton(AF_INET, q, &addr) <= 0) goto bad;
-         mask = ntohl(addr.s_addr);
-       } else {
-         n = atoi(q);
-         mask = (~0ul << (32 - n)) & 0xffffffff;
-       }
-       RESCAN(del);
-       minaddr &= mask;
-       maxaddr = minaddr | (mask ^ 0xffffffff);
-      } else
-       maxaddr = minaddr;
+         RESCAN(del);
+         maxaddr = ntohl(addr.s_addr);
+       } else if (*p == '/') {
+         p++;
+         NEXTADDR(q, del);
+         if (strchr(q, '.')) {
+           if (inet_pton(AF_INET, q, &addr) <= 0) goto bad;
+           mask = ntohl(addr.s_addr);
+         } else {
+           n = atoi(q);
+           mask = (~0ul << (32 - n)) & 0xffffffff;
+         }
+         RESCAN(del);
+         minaddr &= mask;
+         maxaddr = minaddr | (mask ^ 0xffffffff);
+       } else
+         maxaddr = minaddr;
+      }
+    justone:
+      parse_ports(&p, &minport, &maxport);
+      ACLNODE(*tail, act, minaddr, maxaddr, minport, maxport);
     }
-  justone:
-    parse_ports(&p, &minport, &maxport);
-    ACLNODE(*tail, act, minaddr, maxaddr, minport, maxport);
+    SKIPSPC;
+    if (*p != ',') break;
+    p++;
   }
   return;
 
@@ -595,6 +600,17 @@ bad:
   return;
 }
 
+static void parse_acl_env(const char *var, aclnode ***tail)
+{
+  char *p;
+
+  if ((p = getenv(var)) != 0) {
+    p = xstrdup(p);
+    parse_acl_line(&p, tail);
+    free(p);
+  }
+}
+
 static void readconfig(void)
 {
   FILE *fp;
@@ -608,6 +624,8 @@ static void readconfig(void)
   if ((fp = fopen(p, "r")) == 0)
     goto done;
 
+  parse_acl_env("NOIP_REALBIND_BEFORE", &bind_tail);
+  parse_acl_env("NOIP_REALCONNECT_BEFORE", &connect_tail);
   while (fgets(buf, sizeof(buf), fp)) {
     n = strlen(buf);
     p = buf;
@@ -633,8 +651,13 @@ static void readconfig(void)
   fclose(fp);
 
 done:
+  parse_acl_env("NOIP_REALBIND", &bind_tail);
+  parse_acl_env("NOIP_REALCONNECT", &connect_tail);
+  parse_acl_env("NOIP_REALBIND_AFTER", &bind_tail);
+  parse_acl_env("NOIP_REALCONNECT_AFTER", &connect_tail);
   *bind_tail = 0;
   *connect_tail = 0;
+  if (!sockdir) sockdir = getenv("NOIP_SOCKETDIR");
   if (!sockdir) {
     snprintf(buf, sizeof(buf), "%s/noip-%s", tmpdir(), user());
     sockdir = xstrdup(buf);