fgerlits commented on code in PR #1925:
URL: https://github.com/apache/nifi-minifi-cpp/pull/1925#discussion_r1977560842


##########
minifi_main/MiNiFiMain.cpp:
##########
@@ -183,6 +187,100 @@ void writeSchemaIfRequested(const 
argparse::ArgumentParser& parser, const std::s
   std::exit(0);
 }
 
+bool replaceMinifiHomeVariable(const std::filesystem::path& file_path, 
std::string minifi_home_path, const std::shared_ptr<core::logging::Logger>& 
logger) {
+  std::ifstream input_file(file_path);
+  if (!input_file) {
+    logger->log_error("Failed to open file: {}", file_path.string());
+    return false;
+  }
+
+  std::ostringstream buffer;
+  buffer << input_file.rdbuf();
+  std::string content = buffer.str();
+  input_file.close();
+
+  const std::string placeholder = "${MINIFI_HOME}";
+  size_t pos = content.find(placeholder, 0);
+  if (pos == std::string::npos) {
+    return true;
+  }
+
+  std::replace(minifi_home_path.begin(), minifi_home_path.end(), '\\', '/');

Review Comment:
   Instead of this, we could pass in `minifi_home` as a `const 
std::filesystem::path &`, and use `generic_string()`.



##########
minifi_main/MiNiFiMain.cpp:
##########
@@ -183,6 +187,100 @@ void writeSchemaIfRequested(const 
argparse::ArgumentParser& parser, const std::s
   std::exit(0);
 }
 
+bool replaceMinifiHomeVariable(const std::filesystem::path& file_path, 
std::string minifi_home_path, const std::shared_ptr<core::logging::Logger>& 
logger) {
+  std::ifstream input_file(file_path);
+  if (!input_file) {
+    logger->log_error("Failed to open file: {}", file_path.string());
+    return false;
+  }
+
+  std::ostringstream buffer;
+  buffer << input_file.rdbuf();
+  std::string content = buffer.str();
+  input_file.close();
+
+  const std::string placeholder = "${MINIFI_HOME}";
+  size_t pos = content.find(placeholder, 0);
+  if (pos == std::string::npos) {
+    return true;
+  }
+
+  std::replace(minifi_home_path.begin(), minifi_home_path.end(), '\\', '/');
+  do {
+    content.replace(pos, placeholder.length(), minifi_home_path);
+    pos += minifi_home_path.length();
+  } while((pos = content.find(placeholder, pos)) != std::string::npos);
+
+  std::ofstream output_file(file_path);
+  if (!output_file) {
+    logger->log_error("Failed to open file for writing: {}", 
file_path.string());
+    return false;
+  }
+
+  output_file << content;
+  output_file.close();
+  return true;
+}
+
+void initializeFipsMode(const std::shared_ptr<minifi::Configure>& configure, 
const std::filesystem::path& minifi_home, const 
std::shared_ptr<core::logging::Logger>& logger) {
+  if (!(configure->get(minifi::Configure::nifi_openssl_fips_support_enable) | 
utils::andThen(utils::string::toBool)).value_or(false)) {
+    return;
+  }
+
+#ifdef WIN32
+  static constexpr std::string_view FIPS_LIB = "fips.dll";
+#elif defined(__APPLE__)
+  static constexpr std::string_view FIPS_LIB = "fips.dylib";
+#else
+  static constexpr std::string_view FIPS_LIB = "fips.so";
+#endif
+
+  if (!std::filesystem::exists(minifi_home / "fips" / FIPS_LIB)) {
+    logger->log_error("FIPS mode is enabled, but {} is not available in 
MINIFI_HOME/fips directory", FIPS_LIB);
+    std::exit(1);
+  }
+
+  if (!std::filesystem::exists(minifi_home / "fips" / "fipsmodule.cnf")) {
+    logger->log_error("FIPS mode is enabled, but fipsmodule.cnf is not 
available in MINIFI_HOME/fips directory. "
+      "Run MINIFI_HOME/fips/openssl fipsinstall -out fipsmodule.cnf -module 
MINIFI_HOME/fips/{} command to generate the configuration file", FIPS_LIB);
+    std::exit(1);
+  }
+
+  if (!std::filesystem::exists(minifi_home / "fips" / "openssl.cnf")) {
+    logger->log_error("FIPS mode is enabled, but openssl.cnf is not available 
in MINIFI_HOME/fips directory");
+    std::exit(1);
+  }
+
+  if (!replaceMinifiHomeVariable(minifi_home / "fips" / "openssl.cnf", 
minifi_home.string(), logger)) {
+    logger->log_error("Failed to replace MINIFI_HOME variable in openssl.cnf");
+    std::exit(1);
+  }
+
+  utils::Environment::setEnvironmentVariable("OPENSSL_CONF", (minifi_home / 
"fips" / "openssl.cnf").string().c_str(), true);
+
+  if (!OSSL_PROVIDER_set_default_search_path(nullptr, (minifi_home / 
"fips").string().c_str())) {
+    logger->log_error("Failed to set FIPS module path: {}", (minifi_home / 
"fips").string());
+    std::exit(1);
+  }
+
+  if (OSSL_PROVIDER_available(nullptr, "fips") != 1) {
+    logger->log_error("FIPS provider not available in default search path");
+    std::exit(1);
+  }
+
+  if (!EVP_default_properties_enable_fips(nullptr, 1)) {
+    logger->log_error("Failed to enable FIPS mode");
+    std::exit(1);
+  }
+
+  if (!EVP_default_properties_is_fips_enabled(nullptr)) {
+    logger->log_error("FIPS mode is not enabled");
+    std::exit(1);
+  }

Review Comment:
   We should use `ERR_print_errors_fp()` to print the OpenSSL error(s) in these 
error cases.



##########
minifi_main/MiNiFiMain.cpp:
##########
@@ -333,6 +431,8 @@ int main(int argc, char **argv) {
     configure->loadConfigureFile(DEFAULT_NIFI_PROPERTIES_FILE);
     overridePropertiesFromCommandLine(argument_parser, configure);
 
+    initializeFipsMode(configure, minifiHome, logger);

Review Comment:
   Can this be moved after `dumpDocsIfRequested` and `writeSchemaIfRequested`? 
I don't think those need FIPS.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to