On Tue, May 08, 2018 at 12:39:12PM -0600, Theo de Raadt wrote:
> >On Tue, May 08, 2018 at 05:06:19PM +0200, Jeremie Courreges-Anglas wrote:
> >> hitch and isync would be the first programs to use this pattern.
> >> I'm not sure it makes it easier to *think* about promises made in
> >> a program, and I don't see a reason to go down that road.
> >drop_promises() was introduced to simplify scenarios such as
> >
> > if (a)
> > if (b)
> > pledge("w")
> > else
> > pledge("x")
> > else
> > if (b)
> > pledge("y")
> > else
> > pledge("z")
> >
> >Pledge's semantics forgid dropping a single promise while keeping
> >everything else. drop_promise() aids in keeping track of pledge mainly
> >for programs that weren't designed with priviledge separation in mind.
> >
> >After all it's just a string so why not working with it? It's far away
> >from being a dirty hack. And even if it's unusual or new, it gets the
> >job done.
>
> You may think it is easier in one respect.
>
> But later, if you look at your last invocation, how do you tell what
> pledges remain?
>
> Well, you don't.
>
> By making it very clear what are dropping, you make it vague *what remains*.
Yes, that's the (obvious) trade-off I made.
> And *what remains* is the meat of the matter, because that's the kernel
> featureset the program may play again.
So here's a diff for pledging isync the same way as before but without
drop_promises.
Index: Makefile
===================================================================
RCS file: /cvs/ports/mail/isync/Makefile,v
retrieving revision 1.33
diff -u -p -r1.33 Makefile
--- Makefile 17 Nov 2017 00:22:39 -0000 1.33
+++ Makefile 8 May 2018 20:02:51 -0000
@@ -3,14 +3,19 @@
COMMENT= synchronize IMAP4 and maildir mailboxes
DISTNAME= isync-1.3.0
+REVISION= 0
+
CATEGORIES= mail
MASTER_SITES= ${MASTER_SITE_SOURCEFORGE:=isync/}
HOMEPAGE= http://isync.sourceforge.net/
-# GPLv2
+MAINTAINER= Klemens Nanni <[email protected]>
+
+# GPLv2+
PERMIT_PACKAGE_CDROM= Yes
+# uses pledge()
WANTLIB= c crypto db sasl2 ssl z
COMPILER= base-clang ports-clang ports-gcc
@@ -20,7 +25,7 @@ LIB_DEPENDS= databases/db/v4 \
SEPARATE_BUILD= Yes
CONFIGURE_STYLE= gnu
-CONFIGURE_ENV+= CFLAGS="${CFLAGS} -I${LOCALBASE}/include/db4
-g" \
+CONFIGURE_ENV+= CFLAGS="${CFLAGS} -I${LOCALBASE}/include/db4" \
CPPFLAGS="-I${LOCALBASE}/include" \
LDFLAGS="-L${LOCALBASE}/lib"
Index: patches/patch-src_drv_imap_c
===================================================================
RCS file: patches/patch-src_drv_imap_c
diff -N patches/patch-src_drv_imap_c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-src_drv_imap_c 8 May 2018 20:02:51 -0000
@@ -0,0 +1,23 @@
+$OpenBSD$
+
+Index: src/drv_imap.c
+--- src/drv_imap.c.orig
++++ src/drv_imap.c
+@@ -41,6 +41,8 @@
+ # include <sasl/saslutil.h>
+ #endif
+
++extern int needs_proc_exec;
++
+ #ifdef HAVE_LIBSSL
+ enum { SSL_None, SSL_STARTTLS, SSL_IMAPS };
+ #endif
+@@ -3267,6 +3269,8 @@ imap_parse_store( conffile_t *cfg, store_conf_t **stor
+ }
+ acc_opt = 1;
+ }
++ if (server->sconf.tunnel || server->pass_cmd)
++ needs_proc_exec = 1;
+ if (store)
+ type = "IMAP store", name = store->gen.name;
+ else
Index: patches/patch-src_main_c
===================================================================
RCS file: patches/patch-src_main_c
diff -N patches/patch-src_main_c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-src_main_c 8 May 2018 20:02:51 -0000
@@ -0,0 +1,44 @@
+$OpenBSD$
+
+Index: src/main.c
+--- src/main.c.orig
++++ src/main.c
+@@ -120,6 +120,8 @@ PACKAGE " " VERSION " - mailbox synchronizer\n"
+ exit( code );
+ }
+
++int needs_proc_exec = 0;
++
+ static void ATTR_PRINTFLIKE(1, 2)
+ debug( const char *msg, ... )
+ {
+@@ -716,6 +718,29 @@ main( int argc, char **argv )
+
+ if (load_config( config, pseudo ))
+ return 1;
++
++ if (mvars->list) {
++ if (needs_proc_exec) {
++ if (pledge("stdio rpath inet flock dns getpw proc exec"
++ " prot_exec", NULL) == -1)
++ sys_error("pledge\n");
++ } else {
++ if (pledge("stdio rpath inet flock dns getpw"
++ " prot_exec",
++ NULL) == -1)
++ sys_error("pledge\n");
++ }
++ } else {
++ if (needs_proc_exec) {
++ if (pledge("stdio rpath wpath cpath inet flock dns"
++ " getpw proc exec prot_exec", NULL) == -1)
++ sys_error("pledge\n");
++ } else {
++ if (pledge("stdio rpath wpath cpath inet flock dns"
++ " getpw prot_exec", NULL) == -1)
++ sys_error("pledge\n");
++ }
++ }
+
+ if (!channels) {
+ fputs( "No channels defined. Try 'man " EXE "'\n", stderr );