Subject: bin/15692: there is no way to specify the ipsec policy for the mountd socket
To: None <gnats-bugs@gnats.netbsd.org>
From: None <lha@stacken.kth.se>
List: netbsd-bugs
Date: 02/21/2002 23:37:14
>Number:         15692
>Category:       bin
>Synopsis:       no way to specify the IPsec policy for mountd (patch)
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Feb 21 14:38:00 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     Love
>Release:        NetBSD 1.5ZA
>Organization:
	Stacken Computer Club
>Environment:
System: NetBSD nutcracker.stacken.kth.se 1.5ZA NetBSD 1.5ZA (NUTCRACKER) #0: Sun Feb 3 14:54:01 CET 2002 lha@nutcracker.stacken.kth.se:/usr/src/sys/arch/i386/compile/NUTCRACKER i386
Architecture: i386
Machine: i386
>Description:
	
	There is no way to specify the IPsec policy for mountd
	since mountd binds to the sockets with
	bindresvport() then you can't insert the policy in
	ipsec.conf.

>How-To-Repeat:

	Try to use mountd with ipsec and find it impossible.

	I used the ipsec thingy in inetd that uses
	ipsec_set_policy(3).

	Mountd is still broken since its not possible to specify
	authorization. Just because you are allowed to connect a IPsec
	connection to host, it doesn't mean that you should be allowed
	to do a showmount/mount.

>Fix:

Index: Makefile
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/mountd/Makefile,v
retrieving revision 1.15
diff -w -u -r1.15 Makefile
--- Makefile	1998/10/29 12:57:02	1.15
+++ Makefile	2002/02/21 22:26:36
@@ -2,8 +2,17 @@
 #	@(#)Makefile	8.3 (Berkeley) 1/25/94
 
 PROG=	mountd
+SRCS=	mountd.c ipsec.c
 MAN=	exports.5 mountd.8
-LDADD+=-lutil
-DPADD+=${LIBUTIL}
 
+INETDDIR= ${.CURDIR}/../inetd
+
+CPPFLAGS+= -I${INETDDIR} -DIPSEC
+LDADD+=	-lipsec -lutil
+DPADD+=	${LIBIPSEC} ${LIBUTIL}
+
+
+
 .include <bsd.prog.mk>
+
+.PATH: ${INETDDIR}
Index: mountd.8
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/mountd/mountd.8,v
retrieving revision 1.22
diff -w -u -r1.22 mountd.8
--- mountd.8	2000/07/03 10:06:26	1.22
+++ mountd.8	2002/02/21 22:26:36
@@ -43,6 +43,7 @@
 mount requests
 .Sh SYNOPSIS
 .Nm
+.Op Fl P Ar policy
 .Op Fl dn
 .Op Ar exportsfile
 .Sh DESCRIPTION
@@ -62,6 +63,17 @@
 Options and operands available for
 .Nm mountd :
 .Bl -tag -width Ds
+.It Fl P Ar policy
+IPsec 
+.Ar policy
+string,
+as described in
+.Xr ipsec_set_policy 3 .
+Multiple IPsec policy strings may be specified by using a semicolon as
+a separator. If conflicting policy strings are found in a single line,
+the last string will take effect. If an invalid IPsec policy string is used
+.Nm
+logs an error message and terminates itself.
 .It Fl d
 Enable debugging mode.
 .Nm
Index: mountd.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/mountd/mountd.c,v
retrieving revision 1.79
diff -w -u -r1.79 mountd.c
--- mountd.c	2001/11/29 21:23:38	1.79
+++ mountd.c	2002/02/21 22:26:38
@@ -102,6 +102,14 @@
 #include "kuid.h"
 #endif
 
+#ifdef IPSEC
+#include <netinet6/ipsec.h>
+#ifndef IPSEC_POLICY_IPSEC	/* no ipsec support on old ipsec */
+#undef IPSEC
+#endif
+#include "ipsec.h"
+#endif
+
 #include <stdarg.h>
 
 /*
@@ -287,9 +295,31 @@
 	int udpsock, tcpsock, udp6sock, tcp6sock;
 	int xcreated = 0, s;
 	int c, one = 1;
+#ifdef IPSEC
+	char *policy = NULL;
+#endif
 
-	while ((c = getopt(argc, argv, "dnr")) != -1)
+#ifdef IPSEC
+#define ADDOPTS "P:"
+#else
+#define ADDOPTS
+#endif
+
+	while ((c = getopt(argc, argv, "dnr" ADDOPTS)) != -1)
 		switch (c) {
+#ifdef IPSEC
+		case 'P':
+			if ((policy = strdup(optarg)) == NULL) {
+				fprintf(stderr, "strdup\n");
+				exit(1);
+			}
+			if (ipsecsetup_test(policy)) {
+				fprintf(stderr,"invalid ipsec policy \"%s\"\n",
+				    policy);
+				exit(1);
+			}
+			break;
+#endif
 		case 'd':
 			debug = 1;
 			break;
@@ -298,7 +328,11 @@
 		case 'r':
 			break;
 		default:
-			fprintf(stderr, "Usage: mountd [-d] [export_file]\n");
+			fprintf(stderr, "Usage: mountd [-d]"
+#ifdef IPSEC
+			    " [-P ipsec policy]"
+#endif
+			    " [export_file]\n");
 			exit(1);
 		};
 	argc -= optind;
@@ -366,6 +400,10 @@
 
 	if (udpsock != -1 && udpconf != NULL) {
 		bindresvport(udpsock, NULL);
+#ifdef IPSEC
+		if (policy)
+			ipsecsetup(AF_INET, udpsock, policy);
+#endif
 		udptransp = svc_dg_create(udpsock, 0, 0);
 		if (udptransp != NULL) {
 			if (!svc_reg(udptransp, RPCPROG_MNT, RPCMNT_VER1,
@@ -382,6 +420,10 @@
 
 	if (tcpsock != -1 && tcpconf != NULL) {
 		bindresvport(tcpsock, NULL);
+#ifdef IPSEC
+		if (policy)
+			ipsecsetup(AF_INET, tcpsock, policy);
+#endif
 		listen(tcpsock, SOMAXCONN);
 		tcptransp = svc_vc_create(tcpsock, 0, 0);
 		if (tcptransp != NULL) {
@@ -399,6 +441,10 @@
 
 	if (udp6sock != -1 && udp6conf != NULL) {
 		bindresvport(udp6sock, NULL);
+#ifdef IPSEC
+		if (policy)
+			ipsecsetup(AF_INET6, tcpsock, policy);
+#endif
 		udp6transp = svc_dg_create(udp6sock, 0, 0);
 		if (udp6transp != NULL) {
 			if (!svc_reg(udp6transp, RPCPROG_MNT, RPCMNT_VER1,
@@ -415,6 +461,10 @@
 
 	if (tcp6sock != -1 && tcp6conf != NULL) {
 		bindresvport(tcp6sock, NULL);
+#ifdef IPSEC
+		if (policy)
+			ipsecsetup(AF_INET6, tcpsock, policy);
+#endif
 		listen(tcp6sock, SOMAXCONN);
 		tcp6transp = svc_vc_create(tcp6sock, 0, 0);
 		if (tcp6transp != NULL) {

>Release-Note:
>Audit-Trail:
>Unformatted: