Improve OpenBSD support

This commit is contained in:
David Uhden Collado 2025-10-13 22:33:57 +02:00
parent d10a7fe8e5
commit 80840b761e
No known key found for this signature in database
GPG key ID: 1A47E8A7D51FB3DA
8 changed files with 149 additions and 22 deletions

View file

@ -16,6 +16,7 @@
#define BOOST_BIND_GLOBAL_PLACEHOLDERS #define BOOST_BIND_GLOBAL_PLACEHOLDERS
#include <boost/property_tree/json_parser.hpp> #include <boost/property_tree/json_parser.hpp>
#include "Crypto.h"
#include "FS.h" #include "FS.h"
#include "Log.h" #include "Log.h"
#include "Config.h" #include "Config.h"
@ -437,7 +438,7 @@ namespace client
void I2PControlService::CreateCertificate (const char *crt_path, const char *key_path) void I2PControlService::CreateCertificate (const char *crt_path, const char *key_path)
{ {
FILE *f = NULL; FILE *f = NULL;
#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 #if I2PD_OPENSSL_GE_3 // since 3.0.0
EVP_PKEY * pkey = EVP_RSA_gen(4096); // e = 65537 EVP_PKEY * pkey = EVP_RSA_gen(4096); // e = 65537
#else #else
EVP_PKEY * pkey = EVP_PKEY_new (); EVP_PKEY * pkey = EVP_PKEY_new ();

View file

@ -17,6 +17,11 @@
#include <fcntl.h> #include <fcntl.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <errno.h>
#if defined(__OpenBSD__)
#include <map>
#include <utility>
#endif
#include "Config.h" #include "Config.h"
#include "FS.h" #include "FS.h"
@ -27,6 +32,114 @@
#include "Transports.h" #include "Transports.h"
#include "util.h" #include "util.h"
#if defined(__OpenBSD__)
namespace
{
std::string ParentDirectory(const std::string& path)
{
if (path.empty())
return "";
auto pos = path.find_last_of('/');
if (pos == std::string::npos)
return "";
if (pos == 0)
return "/";
return path.substr(0, pos);
}
void AddRule(std::map<std::string, std::string>& rules, const std::string& path, const char* perms)
{
if (path.empty())
return;
std::string normalized = path;
while (normalized.size() > 1 && normalized.back() == '/')
normalized.pop_back();
auto it = rules.find(normalized);
if (it == rules.end())
rules.emplace(std::move(normalized), std::string(perms));
else
for (const char* p = perms; *p; ++p)
if (it->second.find(*p) == std::string::npos)
it->second.push_back(*p);
}
}
static bool ConfigureOpenBSDSandbox(const std::string& pidfile, bool isDaemon)
{
std::map<std::string, std::string> rules;
const auto& dataDir = i2p::fs::GetDataDir();
if (!dataDir.empty())
AddRule(rules, dataDir, "rwc");
const auto& certsDir = i2p::fs::GetCertsDir();
if (!certsDir.empty())
AddRule(rules, certsDir, "r");
AddRule(rules, "/etc", "r");
AddRule(rules, "/dev/null", "rw");
AddRule(rules, "/dev/urandom", "r");
AddRule(rules, "/dev/log", "rw");
auto allowWritablePath = [&rules](const std::string& path)
{
if (path.empty() || path.front() != '/')
return;
auto parent = ParentDirectory(path);
if (parent.empty() || parent == "/")
AddRule(rules, path, "rwc");
else
AddRule(rules, parent, "rwc");
};
allowWritablePath(pidfile);
std::string logsOption;
i2p::config::GetOption("log", logsOption);
bool logToFile = logsOption == "file";
if (!logToFile && logsOption != "syslog")
{
if (isDaemon && (logsOption.empty() || logsOption == "stdout"))
logToFile = true;
}
if (logToFile)
{
std::string logfile;
i2p::config::GetOption("logfile", logfile);
if (logfile.empty())
logfile = i2p::fs::DataDirPath("i2pd.log");
if (!logfile.empty())
{
if (logfile.front() != '/')
logfile = i2p::fs::DataDirPath(logfile);
allowWritablePath(logfile);
}
}
for (const auto& rule : rules)
{
if (unveil(rule.first.c_str(), rule.second.c_str()) == -1)
{
LogPrint(eLogError, "Daemon: unveil failed for ", rule.first, ": ", strerror(errno));
return false;
}
}
if (unveil(nullptr, nullptr) == -1)
{
LogPrint(eLogError, "Daemon: unveil lock failed: ", strerror(errno));
return false;
}
constexpr const char* promises = "stdio rpath wpath cpath inet dns proc fattr thread unix";
if (pledge(promises, nullptr) == -1)
{
LogPrint(eLogError, "Daemon: pledge(", promises, ") failed: ", strerror(errno));
return false;
}
return true;
}
#endif // __OpenBSD__
void handle_signal(int sig) void handle_signal(int sig)
{ {
switch (sig) switch (sig)
@ -152,6 +265,10 @@ namespace i2p
if (pidfile == "") { if (pidfile == "") {
pidfile = i2p::fs::DataDirPath("i2pd.pid"); pidfile = i2p::fs::DataDirPath("i2pd.pid");
} }
#if defined(__OpenBSD__)
if (!ConfigureOpenBSDSandbox(pidfile, isDaemon))
return false;
#endif
if (pidfile != "") { if (pidfile != "") {
pidFH = open(pidfile.c_str(), O_RDWR | O_CREAT, 0600); pidFH = open(pidfile.c_str(), O_RDWR | O_CREAT, 0600);
if (pidFH < 0) if (pidFH < 0)

View file

@ -11,18 +11,18 @@
#include <vector> #include <vector>
#include <mutex> #include <mutex>
#include <memory> #include <memory>
#include "Crypto.h"
#include <openssl/dh.h> #include <openssl/dh.h>
#include <openssl/md5.h> #include <openssl/md5.h>
#include <openssl/crypto.h> #include <openssl/crypto.h>
#include "TunnelBase.h" #include "TunnelBase.h"
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <openssl/kdf.h> #include <openssl/kdf.h>
#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 #if I2PD_OPENSSL_GE_3 // since 3.0.0
#include <openssl/param_build.h> #include <openssl/param_build.h>
#include <openssl/core_names.h> #include <openssl/core_names.h>
#endif #endif
#include "CPU.h" #include "CPU.h"
#include "Crypto.h"
#include "Ed25519.h" #include "Ed25519.h"
#include "I2PEndian.h" #include "I2PEndian.h"
#include "Log.h" #include "Log.h"
@ -148,7 +148,7 @@ namespace crypto
#define dsap GetCryptoConstants ().dsap #define dsap GetCryptoConstants ().dsap
#define dsaq GetCryptoConstants ().dsaq #define dsaq GetCryptoConstants ().dsaq
#define dsag GetCryptoConstants ().dsag #define dsag GetCryptoConstants ().dsag
#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 #if I2PD_OPENSSL_GE_3 // since 3.0.0
EVP_PKEY * CreateDSA (BIGNUM * pubKey, BIGNUM * privKey) EVP_PKEY * CreateDSA (BIGNUM * pubKey, BIGNUM * privKey)
{ {
EVP_PKEY * pkey = nullptr; EVP_PKEY * pkey = nullptr;

View file

@ -24,14 +24,22 @@
#include <openssl/rand.h> #include <openssl/rand.h>
#include <openssl/opensslv.h> #include <openssl/opensslv.h>
#if defined(LIBRESSL_VERSION_NUMBER)
#define I2PD_OPENSSL_GE_3 0
#define I2PD_OPENSSL_GE_3_5 0
#else
#define I2PD_OPENSSL_GE_3 (OPENSSL_VERSION_NUMBER >= 0x030000000L)
#define I2PD_OPENSSL_GE_3_5 (OPENSSL_VERSION_NUMBER >= 0x030500000L)
#endif
#include "Base.h" #include "Base.h"
#include "Tag.h" #include "Tag.h"
// recognize openssl version and features // recognize openssl version and features
#if (!defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER != 0x030000000)) // 3.0.0, regression in SipHash, not implemented in LibreSSL #if (!defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER != 0x030000000L)) // 3.0.0, regression in SipHash, not implemented in LibreSSL
# define OPENSSL_SIPHASH 1 # define OPENSSL_SIPHASH 1
#endif #endif
#if (OPENSSL_VERSION_NUMBER >= 0x030500000) // 3.5.0 #if I2PD_OPENSSL_GE_3_5
# define OPENSSL_PQ 1 # define OPENSSL_PQ 1
#endif #endif
@ -42,7 +50,7 @@ namespace crypto
bool bn2buf (const BIGNUM * bn, uint8_t * buf, size_t len); bool bn2buf (const BIGNUM * bn, uint8_t * buf, size_t len);
// DSA // DSA
#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 #if I2PD_OPENSSL_GE_3 // since 3.0.0
EVP_PKEY * CreateDSA (BIGNUM * pubKey = nullptr, BIGNUM * privKey = nullptr); EVP_PKEY * CreateDSA (BIGNUM * pubKey = nullptr, BIGNUM * privKey = nullptr);
#else #else
DSA * CreateDSA (); DSA * CreateDSA ();

View file

@ -52,7 +52,7 @@ namespace data
if (pkey) if (pkey)
{ {
int curve = 0; int curve = 0;
#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 #if I2PD_OPENSSL_GE_3 // since 3.0.0
char groupName[20]; char groupName[20];
if (EVP_PKEY_get_group_name(pkey, groupName, sizeof(groupName), NULL) == 1) if (EVP_PKEY_get_group_name(pkey, groupName, sizeof(groupName), NULL) == 1)
curve = OBJ_txt2nid (groupName); curve = OBJ_txt2nid (groupName);
@ -157,7 +157,7 @@ namespace data
SSL * ssl = SSL_new (ctx); SSL * ssl = SSL_new (ctx);
EVP_PKEY * pkey = SSL_get_privatekey (ssl); EVP_PKEY * pkey = SSL_get_privatekey (ssl);
int curve = 0; int curve = 0;
#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 #if I2PD_OPENSSL_GE_3 // since 3.0.0
char groupName[20]; char groupName[20];
if (EVP_PKEY_get_group_name(pkey, groupName, sizeof(groupName), NULL) == 1) if (EVP_PKEY_get_group_name(pkey, groupName, sizeof(groupName), NULL) == 1)
curve = OBJ_txt2nid (groupName); curve = OBJ_txt2nid (groupName);

View file

@ -14,12 +14,12 @@
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <openssl/err.h> #include <openssl/err.h>
#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 #include "Crypto.h"
#if I2PD_OPENSSL_GE_3 // since 3.0.0
#include <openssl/core_names.h> #include <openssl/core_names.h>
#endif #endif
#include <zlib.h> #include <zlib.h>
#include "Crypto.h"
#include "I2PEndian.h" #include "I2PEndian.h"
#include "Reseed.h" #include "Reseed.h"
#include "FS.h" #include "FS.h"
@ -485,7 +485,7 @@ namespace data
// extract RSA key (we need n only, e = 65537) // extract RSA key (we need n only, e = 65537)
EVP_PKEY * pubKey = X509_get_pubkey (cert); EVP_PKEY * pubKey = X509_get_pubkey (cert);
const BIGNUM * n = nullptr; const BIGNUM * n = nullptr;
#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 #if I2PD_OPENSSL_GE_3 // since 3.0.0
BIGNUM * n1 = BN_new (); BIGNUM * n1 = BN_new ();
if (EVP_PKEY_get_bn_param (pubKey, OSSL_PKEY_PARAM_RSA_N, &n1) > 0) if (EVP_PKEY_get_bn_param (pubKey, OSSL_PKEY_PARAM_RSA_N, &n1) > 0)
n = n1; n = n1;
@ -505,7 +505,7 @@ namespace data
} }
else else
LogPrint (eLogError, "Reseed: Can't extract RSA key from ", filename); LogPrint (eLogError, "Reseed: Can't extract RSA key from ", filename);
#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 #if I2PD_OPENSSL_GE_3 // since 3.0.0
BN_free (n1); BN_free (n1);
#endif #endif
} }

View file

@ -7,8 +7,9 @@
*/ */
#include <memory> #include <memory>
#include "Crypto.h"
#include <openssl/evp.h> #include <openssl/evp.h>
#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 #if I2PD_OPENSSL_GE_3 // since 3.0.0
#include <openssl/core_names.h> #include <openssl/core_names.h>
#include <openssl/param_build.h> #include <openssl/param_build.h>
#endif #endif
@ -19,7 +20,7 @@ namespace i2p
{ {
namespace crypto namespace crypto
{ {
#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 #if I2PD_OPENSSL_GE_3 // since 3.0.0
DSAVerifier::DSAVerifier (): DSAVerifier::DSAVerifier ():
m_PublicKey (nullptr) m_PublicKey (nullptr)
{ {
@ -172,7 +173,7 @@ namespace crypto
} }
#endif #endif
#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 #if I2PD_OPENSSL_GE_3 // since 3.0.0
ECDSAVerifier::ECDSAVerifier (int curve, size_t keyLen, const EVP_MD * hash): ECDSAVerifier::ECDSAVerifier (int curve, size_t keyLen, const EVP_MD * hash):
m_Curve(curve), m_KeyLen (keyLen), m_Hash (hash), m_PublicKey (nullptr) m_Curve(curve), m_KeyLen (keyLen), m_Hash (hash), m_PublicKey (nullptr)
{ {
@ -405,7 +406,7 @@ namespace crypto
LogPrint (eLogError, "EdDSA signing key is not set"); LogPrint (eLogError, "EdDSA signing key is not set");
} }
#if (OPENSSL_VERSION_NUMBER >= 0x030000000) #if I2PD_OPENSSL_GE_3
static const OSSL_PARAM EDDSA25519phParams[] = static const OSSL_PARAM EDDSA25519phParams[] =
{ {
OSSL_PARAM_utf8_string ("instance", (char *)"Ed25519ph", 9), OSSL_PARAM_utf8_string ("instance", (char *)"Ed25519ph", 9),

View file

@ -62,7 +62,7 @@ namespace crypto
private: private:
#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 #if I2PD_OPENSSL_GE_3 // since 3.0.0
EVP_PKEY * m_PublicKey; EVP_PKEY * m_PublicKey;
#else #else
DSA * m_PublicKey; DSA * m_PublicKey;
@ -82,7 +82,7 @@ namespace crypto
private: private:
#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 #if I2PD_OPENSSL_GE_3 // since 3.0.0
EVP_PKEY * m_PrivateKey; EVP_PKEY * m_PrivateKey;
#else #else
DSA * m_PrivateKey; DSA * m_PrivateKey;
@ -96,7 +96,7 @@ namespace crypto
constexpr size_t ECDSAP384_KEY_LENGTH = 96; constexpr size_t ECDSAP384_KEY_LENGTH = 96;
constexpr size_t ECDSAP521_KEY_LENGTH = 132; constexpr size_t ECDSAP521_KEY_LENGTH = 132;
#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 #if I2PD_OPENSSL_GE_3 // since 3.0.0
class ECDSAVerifier: public Verifier class ECDSAVerifier: public Verifier
{ {
public: public:
@ -377,7 +377,7 @@ namespace crypto
EVP_PKEY * GetPkey () const { return m_Pkey; }; EVP_PKEY * GetPkey () const { return m_Pkey; };
}; };
#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 #if I2PD_OPENSSL_GE_3 // since 3.0.0
class EDDSA25519phVerifier: public EDDSA25519Verifier class EDDSA25519phVerifier: public EDDSA25519Verifier
{ {
public: public:
@ -423,7 +423,7 @@ namespace crypto
EDDSA25519SignerCompat * m_Fallback; EDDSA25519SignerCompat * m_Fallback;
}; };
#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0 #if I2PD_OPENSSL_GE_3 // since 3.0.0
class EDDSA25519phSigner: public EDDSA25519Signer class EDDSA25519phSigner: public EDDSA25519Signer
{ {
public: public: