]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Add `pdns::openFileForWriting()` to control permissions when creating a file
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 18 Mar 2024 11:38:33 +0000 (12:38 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 18 Mar 2024 11:38:33 +0000 (12:38 +0100)
pdns/dnspcap.cc
pdns/dnspcap2protobuf.cc
pdns/libssl.cc
pdns/misc.cc
pdns/misc.hh

index d0d07450211d1c7b383bbd5f7363956ee7537048..0842ad351e3ef1ea3a9d9ffef3000a7ede1acc47 100644 (file)
@@ -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");
   }
index 063fbee87095cdf194377620ff028887a1c39b3f..00eed1deef28356870e18a6e5a11983770e2d0dd 100644 (file)
@@ -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 "<<argv[2]<<": "<<stringerror()<<endl;
+    auto error = errno;
+    cerr<<"Error opening output file "<<argv[2]<<": "<<stringerror(error)<<endl;
     exit(EXIT_FAILURE);
   }
 
index 051061468ea7734f27d6ebf64cdd38f6cf2c2180..fcc0d8259d9fb847e5650b514164b66193204192 100644 (file)
@@ -1053,20 +1053,13 @@ static void libssl_key_log_file_callback(const SSL* ssl, const char* line)
 pdns::UniqueFilePtr libssl_set_key_log_file(std::unique_ptr<SSL_CTX, decltype(&SSL_CTX_free)>& 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);
index c1cc532d7d0d4d0d6060b07197720dfa56cc9b45..7d2f683664375ac3796c56a2a237e022fd02a9f4 100644 (file)
@@ -1777,4 +1777,28 @@ std::optional<std::string> 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;
+}
+
 }
index 00667dcf850072f3f99154f297b80fae13bb3f41..cd7e607ef1c784fd6a087c1456f3c4f4e8d94d91 100644 (file)
@@ -852,4 +852,6 @@ struct FilePtrDeleter
 };
 
 using UniqueFilePtr = std::unique_ptr<FILE, FilePtrDeleter>;
+
+UniqueFilePtr openFileForWriting(const std::string& filePath, mode_t permissions, bool mustNotExist = true, bool appendIfExists = false);
 }