X-Git-Url: https://git.distorted.org.uk/~mdw/fwd/blobdiff_plain/0ac54f22a766f068db98e1caecbc913cb0cfd191..bdbbfcd4eb2f6e15270f558342630d964cb9f418:/inet.c diff --git a/inet.c b/inet.c index 70e5c90..3a4dbd5 100644 --- a/inet.c +++ b/inet.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: inet.c,v 1.5 2003/11/25 14:08:23 mdw Exp $ + * $Id: inet.c,v 1.6 2003/11/29 20:36:07 mdw Exp $ * * Protocol specific definitions for IPv4 sockets * @@ -29,6 +29,9 @@ /*----- Revision history --------------------------------------------------* * * $Log: inet.c,v $ + * Revision 1.6 2003/11/29 20:36:07 mdw + * Privileged outgoing connections. + * * Revision 1.5 2003/11/25 14:08:23 mdw * Debianization. Socket target options. Internet binding. * @@ -77,6 +80,7 @@ #include "fw.h" #include "identify.h" #include "inet.h" +#include "privconn.h" #include "reffd.h" #include "scan.h" #include "socket.h" @@ -101,8 +105,11 @@ typedef struct inet_srcopts { typedef struct inet_targopts { inet_opts io; + int ipriv; } inet_targopts; +#define ADDRF_PRIVCONN 16u + static inet_srcopts inet_globalsrc = { { { 0 }, { INADDR_ANY } }, 0, &inet_globalsrc.acl }; static inet_targopts inet_globaltarg = @@ -201,6 +208,7 @@ static addr_opts *inet_inittargopts(void) { inet_targopts *io = CREATE(inet_targopts); *io = inet_globaltarg; + io->ipriv = -1; return (&io->io.ao); } @@ -261,7 +269,8 @@ static int srcopt(scanner *sc, addr_opts *ao) if (sc->t == CTOK_WORD && strcmp(sc->d.buf, "from") == 0) token(sc); - if (sc->t == CTOK_WORD && strcmp(sc->d.buf, "priv-port") == 0) { + if (sc->t == CTOK_WORD && (strcmp(sc->d.buf, "priv") == 0 || + strcmp(sc->d.buf, "priv-port") == 0)) { acl_addpriv(&io->acltail, act); token(sc); } else { @@ -327,6 +336,16 @@ static int targopt(scanner *sc, addr_opts *ao) addropt(sc, &io->io); CONF_ACCEPT; } + if (strcmp(sc->d.buf, "priv") == 0 || + strcmp(sc->d.buf, "priv-port") == 0) { + token(sc); + if (sc->t == '=') token(sc); + if (conf_enum(sc, "no,yes", ENUM_ABBREV, "privileged connection status")) + io->io.ao.f |= ADDRF_PRIVCONN; + else + io->io.ao.f &= ~ADDRF_PRIVCONN; + CONF_ACCEPT; + } CONF_END; } @@ -340,6 +359,23 @@ static int inet_option(scanner *sc, addr_opts *ao, unsigned type) CONF_END; } +/* --- @confirm@ --- */ + +static void inet_confirm(addr *a, unsigned type, addr_opts *ao) +{ + inet_addrx *ia = (inet_addrx *)a; + + switch (type) { + case ADDR_DEST: { + inet_targopts *io = (inet_targopts *)ao; + if ((io->io.ao.f & ADDRF_PRIVCONN) && + (io->ipriv = privconn_adddest(ia->sin.sin_addr, + ia->sin.sin_port)) < 0) + die(1, "couldn't add privileged connection target (too late)"); + } break; + } +} + /* --- @freeopts@ --- */ static void inet_freesrcopts(addr_opts *ao) @@ -431,6 +467,10 @@ static int inet_connect(addr *a, addr_opts *ao, conn *c, endpt *e) inet_targopts *io = (inet_targopts *)ao; int fd; + if (io->ipriv >= 0) { + return (privconn_connect(c, sel, io->ipriv, io->io.bind, + starget_connected, e)); + } if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) goto fail_0; if (io->io.bind.s_addr != INADDR_ANY) { @@ -456,7 +496,7 @@ fail_0: addr_ops inet_ops = { "inet", inet_read, inet_destroy, inet_print, - inet_initsrcopts, inet_option, inet_freesrcopts, + inet_initsrcopts, inet_option, inet_confirm, inet_freesrcopts, inet_bind, 0, inet_accept, inet_inittargopts, inet_freetargopts, inet_connect