/* -*-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 <ctype.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-
-#include <mLib/alloc.h>
-#include <mLib/dstr.h>
-#include <mLib/fdflags.h>
-#include <mLib/report.h>
-#include <mLib/sub.h>
-
-#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 ---------------------------------------------------*/
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 =
{
inet_targopts *io = CREATE(inet_targopts);
*io = inet_globaltarg;
+ io->ipriv = -1;
return (&io->io.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 {
/* --- Find the netmask, if any --- */
if (sc->t != '/')
- m.s_addr = ~0ul;
+ m.s_addr = (in_addr_t)~0ul;
else {
token(sc);
DRESET(&d);
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;
}
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)
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 --- */
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) {
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 -------------------------------------------------*/