.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
.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
.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
.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:
.PP
An
.I acl-entry
-has this format:
+is a comma-separated list of entries of the form:
.IP
.BR + | \-
.IR address \c
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;
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;
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;
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);