X-Git-Url: https://git.distorted.org.uk/~mdw/fwd/blobdiff_plain/0ac54f22a766f068db98e1caecbc913cb0cfd191..755e6619263d316dc46fa504e0c333c963ec8eaa:/inet.c diff --git a/inet.c b/inet.c index 70e5c90..ad93beb 100644 --- a/inet.c +++ b/inet.c @@ -1,85 +1,30 @@ /* -*-c-*- * - * $Id: inet.c,v 1.5 2003/11/25 14:08:23 mdw Exp $ - * * Protocol specific definitions for IPv4 sockets * * (c) 1999 Straylight/Edgeware */ -/*----- Licensing notice --------------------------------------------------* +/*----- Licensing notice --------------------------------------------------* * - * This file is part of the `fw' port forwarder. + * This file is part of the `fwd' port forwarder. * - * `fw' is free software; you can redistribute it and/or modify + * `fwd' is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * - * `fw' is distributed in the hope that it will be useful, + * + * `fwd' is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License - * along with `fw'; if not, write to the Free Software Foundation, + * along with `fwd'; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/*----- Revision history --------------------------------------------------* - * - * $Log: inet.c,v $ - * Revision 1.5 2003/11/25 14:08:23 mdw - * Debianization. Socket target options. Internet binding. - * - * Revision 1.4 2002/01/13 14:49:56 mdw - * Conditional compilation for @getnetbyname@, since Cygwin doesn't have - * it. - * - * Revision 1.3 2000/08/01 17:59:56 mdw - * Switch over to using `size_t' for socket address lengths. - * - * Revision 1.2 1999/07/27 18:30:53 mdw - * Various minor portability fixes. - * - * Revision 1.1 1999/07/26 23:34:11 mdw - * New socket address types. - * - */ - -/*----- Header files ------------------------------------------------------*/ - -#include "config.h" - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "acl.h" -#include "addr.h" -#include "conf.h" -#include "fw.h" -#include "identify.h" -#include "inet.h" -#include "reffd.h" -#include "scan.h" -#include "socket.h" +#include "fwd.h" /*----- Data structures ---------------------------------------------------*/ @@ -101,8 +46,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 +149,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 +210,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 { @@ -284,7 +234,7 @@ static int srcopt(scanner *sc, addr_opts *ao) /* --- Find the netmask, if any --- */ if (sc->t != '/') - m.s_addr = ~0ul; + m.s_addr = (in_addr_t)~0ul; else { token(sc); DRESET(&d); @@ -327,6 +277,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 +300,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) @@ -388,7 +365,7 @@ static reffd *inet_accept(int fd, addr_opts *ao, const char *desc) inet_srcopts *io = (inet_srcopts *)ao; int nfd; id_req q; - size_t lsinsz = sizeof(q.lsin), rsinsz = sizeof(q.rsin); + socklen_t lsinsz = sizeof(q.lsin), rsinsz = sizeof(q.rsin); int act = ACL_ALLOW; /* --- Accept the new connection --- */ @@ -431,6 +408,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,10 +437,10 @@ 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 + inet_connect }; /*----- That's all, folks -------------------------------------------------*/