Re: [UPDATE] net/i2pd: update to 2.61.0

Andrew Kloet <[email protected]> Wed, 22 Jul 2026 12:26:49 -0400
Newsgroups gmane.os.openbsd.ports
Message-ID <[email protected]>
On Wed Jul 22, 2026 at 10:57 AM EDT, Stuart Henderson wrote:
> the revised pledge still feels like shoehorning it into a program
> which has not been designed to actually work with it. big clue
> is having file access and network access in the same process.
> (sure, there's worse in ports, and it's not a total blocker, but
> it does make me wonder how well tested it's been, because clearly
> there hasn't been too much careful thought about how to use this
> prior to it being committed uptream..)

I've replaced upstream's pledge/unveil with what I had been drafting but
never finished a few months ago. Looking for feedback before I submit it
to upstream.  Unfortunately i2pd doesn't have a test suite as far as I
can tell so I find it difficult to make sure all bases have been covered
across pledge/unveil. I ran it for a few minutes and saw no EPERM.

Doesn't resolve the issue of simul net/file access but I think this
design actually has some thought put into it :p

Andrew


commit f2d7f170ad404eec631c71cda706ad79e252af2c
Author: Andrew Kloet <[email protected]>
Date:   Wed Jul 22 08:40:12 2026 -0400

    daemon: redo pledge/unveil

diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp
index ecb73965..022b59f2 100644
--- a/daemon/Daemon.cpp
+++ b/daemon/Daemon.cpp
@@ -10,10 +10,6 @@
 #include <memory>
 #include <regex>
 
-#ifdef __OpenBSD__
-#	include<unistd.h>
-#endif
-
 #include "Daemon.h"
 
 #include "Config.h"
@@ -107,84 +103,6 @@ namespace util
 		i2p::config::ParseConfig(config);
 		i2p::config::Finalize();
 
-#ifdef __OpenBSD__
-		auto init_pledge = []() {
-			std::string pledge_file; i2p::config::GetOption("openbsd.pledge_file", pledge_file);
-			if (pledge_file == "")
-			{
-				LogPrint(eLogDebug, "Use default pledge values");
-				// TODO: remove that not need
-				pledge("stdio rpath wpath cpath inet dns unix recvfd sendfd proc error mcast chown flock",nullptr);
-			} else {
-				std::ifstream f(pledge_file);
-				if(!f) {
-					std::cerr << "Can't open pledge file " << pledge_file<<std::endl;
-					exit(1);
-				}
-				std::string line;
-				std::vector<std::string> rules;
-				while(std::getline(f, line)){
-					rules.push_back(line);
-				}
-				if(f.bad()) {
-					std::cerr << "IO error with pledge file" << std::endl;
-				}
-				std::ostringstream out;
-				for(auto r : rules)
-					out << r << " ";
-				pledge(out.str().c_str(), nullptr);
-			}		
-
-
-		};
-		auto init_unevil = []() {
-			unveil("/usr/lib", "r");
-			unveil("/usr/local/lib", "r"); 
-			unveil("/usr/libexec/ld.so", "r"); 
-			unveil("/dev/urandom", "r");
-			unveil("/tmp", "rw");
-			unveil("/etc/i2pd", "r"); // ваще не нужно вроде на весь прям каталог
-			
-			#define UNVEIL_DIR(dir) unveil(dir.c_str(), "rwc")
-			
-			std::string unevil_file; i2p::config::GetOption("openbsd.unevil_file",unevil_file);
-			UNVEIL_DIR(unevil_file);
-			std::string tunnelsdir, certsdir, logfile, datadir, reseed_file, openbsd_pledge_file;
-			i2p::config::GetOption("tunnelsdir", tunnelsdir);
-			UNVEIL_DIR(tunnelsdir);
-			i2p::config::GetOption("certsdir", certsdir);
-			UNVEIL_DIR(certsdir);
-			i2p::config::GetOption("datadir", datadir);
-			UNVEIL_DIR(datadir);
-			i2p::config::GetOption("reseed.file", reseed_file);
-			unveil(reseed_file.c_str(), "r");
-			i2p::config::GetOption("openbsd.pledge_file", openbsd_pledge_file);
-			unveil(openbsd_pledge_file.c_str(), "r");
-			std::string tunconf ;i2p::config::GetOption("tunconf", tunconf); unveil(tunconf.c_str(), "r");
-			std::string conf ;i2p::config::GetOption("tunconf", conf); unveil(conf.c_str(), "r");
-			std::string pidfile ;i2p::config::GetOption("pidfile", pidfile); unveil(pidfile.c_str(), "rwc");
-			i2p::config::GetOption("logfile", logfile); unveil(logfile.c_str(), "rwc");
-			if(unevil_file != "")
-			{
-				std::ifstream f(unevil_file);
-				if (!f) {
-					std::cerr << "Can't open unevil file" << std::endl;
-					exit(1);
-				}
-				std::string line;
-				while(std::getline(f, line)){
-						UNVEIL_DIR(line);
-				}
-			}
-			#undef UNVEIL_DIR
-			unveil(NULL, NULL); 
-		};
-		bool openbsd_unevil_enabled; i2p::config::GetOption("openbsd.unevil_enabled", openbsd_unevil_enabled);
-		bool openbsd_pledge_enabled; i2p::config::GetOption("openbsd.pledge_enabled", openbsd_pledge_enabled);
-		if(openbsd_unevil_enabled) init_unevil();
-		if(openbsd_pledge_enabled) init_pledge();
-#endif
-
 		i2p::config::GetOption("daemon", isDaemon);
 
 		std::string certsdir; i2p::config::GetOption("certsdir", certsdir);
diff --git a/daemon/UnixDaemon.cpp b/daemon/UnixDaemon.cpp
index 43c3c9de..e74bb57b 100644
--- a/daemon/UnixDaemon.cpp
+++ b/daemon/UnixDaemon.cpp
@@ -210,6 +210,44 @@ namespace i2p
 				sigaction(SIGCONT, &sa, 0);
 			}
 
+#ifdef __OpenBSD__
+			std::string dataDir = i2p::fs::GetDataDir();
+			if (!dataDir.empty())
+				if (unveil(dataDir.c_str(), "rwc") == -1)
+					LogPrint(eLogError, "Daemon: Unveil failed for dataDir (", dataDir, "): ", std::strerror(errno));
+
+			auto unveilConfigOption = [](const std::string& key, const char* mask) {
+				std::string path;
+				if (i2p::config::GetOption(key, path) && !path.empty())
+					if (unveil(path.c_str(), mask) == -1)
+						LogPrint(eLogError, "Daemon: Unveil failed for ", key, " (", path, "): ", std::strerror(errno));
+			};
+
+			const std::vector<std::pair<std::string, const char*>> unveilRules = {
+				{"conf",           "r"},
+				{"certsdir",       "r"},
+				{"tunconf",        "r"},
+				{"tunnelsdir",     "r"},
+				{"pidfile",        "rwc"},
+				{"logfile",        "rwc"},
+				{"reseed.file",    "r"},
+				{"reseed.zipfile", "r"}
+			};
+
+			for (const auto& rule : unveilRules)
+				unveilConfigOption(rule.first, rule.second);
+
+			if (unveil(NULL, NULL) == -1) {
+				LogPrint(eLogError, "Daemon: unveil lock failed: ", std::strerror(errno));
+				exit(1);
+			}
+
+			if (pledge("stdio inet dns flock rpath wpath cpath proc", NULL) == -1) {
+				LogPrint(eLogError, "Daemon: pledge failed: ", std::strerror(errno));
+				exit(1);
+			}
+#endif
+
 			return Daemon_Singleton::start();
 		}
 
diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp
index fe406b13..ea137597 100644
--- a/libi2pd/Config.cpp
+++ b/libi2pd/Config.cpp
@@ -396,16 +396,6 @@ namespace config {
 		;
 #endif
 
-#ifdef __OpenBSD__
-		options_description openbsd_specific("OpenBSD specific options");
-		openbsd_specific.add_options()
-			("openbsd.pledge_file", value<std::string>()->default_value(""), "OpenbSD file with pledge rules")
-			("openbsd.unevil_file", value<std::string>()->default_value(""), "OpenBSD file with unevil rules")
-			("openbsd.unevil_enabled", value<bool>()->default_value(true),     "use unevil rues")
-			("openbsd.pledge_enabled", value<bool>()->default_value(true),     "use pledge rules")
-			;
-#endif
-
 		m_OptionsDesc
 			.add(general)
 			.add(limits)
signature.asc (application/pgp-signature, 228 B)
-----BEGIN PGP SIGNATURE-----

iHUEABYKAB0WIQQDYAWAj/Md1ZRJrhK0H7x/oPHhDgUCamDvSgAKCRC0H7x/oPHh
Dt09AP4lou13AMdB/DOvZZ2Vx8+McOVN7IthAPJWR1vI60ohEAEAjkvyiHCkw9UL
gVDrLTXoxEzqTc9Wyyyy4xeHGksU/AM=
=TT1T
-----END PGP SIGNATURE-----