chan.c (chan_open): Actually initialize the error indicator.
[fwd] / inet.c
diff --git a/inet.c b/inet.c
index 70e5c90..ad93beb 100644 (file)
--- 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 <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 ---------------------------------------------------*/
 
@@ -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 -------------------------------------------------*/