/* -*-c-*-
*
- * $Id: inet.c,v 1.5 2003/11/25 14:08:23 mdw Exp $
+ * $Id: inet.c,v 1.7 2004/04/08 01:36:25 mdw Exp $
*
* Protocol specific definitions for IPv4 sockets
*
* 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 "fw.h"
#include "identify.h"
#include "inet.h"
+#include "privconn.h"
#include "reffd.h"
#include "scan.h"
#include "socket.h"
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 {
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_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