diff --git a/pdns/dnspcap.cc b/pdns/dnspcap.cc index d0d07450211d..0842ad351e3e 100644 --- a/pdns/dnspcap.cc +++ b/pdns/dnspcap.cc @@ -235,8 +235,7 @@ PcapPacketWriter::PcapPacketWriter(const string& fname, const PcapPacketReader& PcapPacketWriter::PcapPacketWriter(const string& fname) : d_fname(fname) { - d_fp = pdns::UniqueFilePtr(fopen(fname.c_str(),"w")); - + d_fp = pdns::openFileForWriting(fname, 0600, true, false); if (!d_fp) { unixDie("Unable to open file"); } diff --git a/pdns/dnspcap2protobuf.cc b/pdns/dnspcap2protobuf.cc index 063fbee87095..00eed1deef28 100644 --- a/pdns/dnspcap2protobuf.cc +++ b/pdns/dnspcap2protobuf.cc @@ -63,9 +63,10 @@ try { PcapPacketReader pr(argv[1]); - auto filePtr = pdns::UniqueFilePtr(fopen(argv[2], "w")); + auto filePtr = pdns::openFileForWriting(argv[2], 0600, true, false); if (!filePtr) { - cerr<<"Error opening output file "<& ctx, const std::string& logFile) { #ifdef HAVE_SSL_CTX_SET_KEYLOG_CALLBACK - int fd = open(logFile.c_str(), O_WRONLY | O_CREAT | O_APPEND, 0600); - if (fd == -1) { - unixDie("Error opening TLS log file '" + logFile + "'"); - } - auto filePtr = pdns::UniqueFilePtr(fdopen(fd, "a")); + auto filePtr = pdns::openFileForWriting(logFile, 0600, false, true); if (!filePtr) { - int error = errno; // close might clobber errno - close(fd); - throw std::runtime_error("Error opening TLS log file '" + logFile + "': " + stringerror(error)); + auto error = errno; + throw std::runtime_error("Error opening file " + logFile + " for writing: " + stringerror(error)); } - SSL_CTX_set_ex_data(ctx.get(), s_keyLogIndex, filePtr.get()); SSL_CTX_set_keylog_callback(ctx.get(), &libssl_key_log_file_callback); - return filePtr; #else return pdns::UniqueFilePtr(nullptr); diff --git a/pdns/misc.cc b/pdns/misc.cc index c1cc532d7d0d..7d2f68366437 100644 --- a/pdns/misc.cc +++ b/pdns/misc.cc @@ -1777,4 +1777,28 @@ std::optional visit_directory(const std::string& directory, const s return std::nullopt; } + +UniqueFilePtr openFileForWriting(const std::string& filePath, mode_t permissions, bool mustNotExist, bool appendIfExists) +{ + int flags = O_WRONLY | O_CREAT; + if (mustNotExist) { + flags |= O_EXCL; + } + else if (appendIfExists) { + flags |= O_APPEND; + } + int fileDesc = open(filePath.c_str(), flags, permissions); + if (fileDesc == -1) { + return UniqueFilePtr(nullptr); + } + auto filePtr = pdns::UniqueFilePtr(fdopen(fileDesc, appendIfExists ? "a" : "w")); + if (!filePtr) { + auto error = errno; + close(fileDesc); + errno = error; + return UniqueFilePtr(nullptr); + } + return filePtr; +} + } diff --git a/pdns/misc.hh b/pdns/misc.hh index 00667dcf8500..cd7e607ef1c7 100644 --- a/pdns/misc.hh +++ b/pdns/misc.hh @@ -852,4 +852,6 @@ struct FilePtrDeleter }; using UniqueFilePtr = std::unique_ptr; + +UniqueFilePtr openFileForWriting(const std::string& filePath, mode_t permissions, bool mustNotExist = true, bool appendIfExists = false); }