X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fconfig.cc;h=9dd6f638e7c6e16ba29545f942dc1388ed887378;hb=e6c52dcb012b441f2b0d3ba2345d91f2658644d2;hp=e61eea3a6f89f7cd916be30b9cb8a54aa595dc95;hpb=5ab0c3bc04e4aa5acd883bb8126fc6b185c6c5d6;p=dcpomatic.git diff --git a/src/lib/config.cc b/src/lib/config.cc index e61eea3a6..9dd6f638e 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -32,6 +32,7 @@ #include "film.h" #include "dkdm_wrapper.h" #include "compose.hpp" +#include "crypto.h" #include #include #include @@ -61,6 +62,7 @@ using boost::shared_ptr; using boost::optional; using boost::dynamic_pointer_cast; using boost::algorithm::trim; +using boost::shared_array; using dcp::raw_convert; Config* Config::_instance = 0; @@ -435,7 +437,19 @@ try BOOST_FOREACH (cxml::NodePtr i, decryption->node_children ("Certificate")) { c->add (dcp::Certificate (i->content ())); } - c->set_key (decryption->string_child ("PrivateKey")); + optional key = decryption->optional_string_child ("PrivateKey"); +#ifdef DCPOMATIC_VARIANT_SWAROOP + if (key) { + c->set_key (*key); + } else { + dcp::Data encrypted_key (path("private")); + dcp::Data iv (path("iv")); + c->set_key (dcpomatic::decrypt (encrypted_key, key_from_uuid(), iv)); + } +#else + DCPOMATIC_ASSERT (key); + c->set_key (*key); +#endif _decryption_chain = c; } else { _decryption_chain = create_certificate_chain (); @@ -599,6 +613,19 @@ Config::write () const write_cinemas (); } +#ifdef DCPOMATIC_VARIANT_SWAROOP +/* Make up a key from the machine UUID */ +dcp::Data +Config::key_from_uuid () const +{ + dcp::Data key (dcpomatic::crypto_key_length()); + memset (key.data().get(), 0, key.size()); + string const magic = command_and_read ("dcpomatic2_uuid"); + strncpy ((char *) key.data().get(), magic.c_str(), dcpomatic::crypto_key_length()); + return key; +} +#endif + void Config::write_config () const { @@ -771,18 +798,7 @@ Config::write_config () const BOOST_FOREACH (dcp::Certificate const & i, _signer_chain->unordered()) { signer->add_child("Certificate")->add_child_text (i.certificate (true)); } -#ifdef DCPOMATIC_SWAROOP - FILE* f = fopen_boost (path("private"), "wb"); - if (!f) { - throw FileError ("Could not open file for writing", path("private")); - } - shared_array iv = dcpomatic::random_iv (); - dcp::Data encrypted_key = dcpomatic::encrypt (_signer_chain->key().get(), key, iv); - fwrite (encrypted_key.data().get(), encrypted_key.data().size(), 1, f); - fclose (f); -#else signer->add_child("PrivateKey")->add_child_text (_signer_chain->key().get ()); -#endif /* [XML] Decryption Certificate chain and private key to use when decrypting KDMs */ xmlpp::Element* decryption = root->add_child ("Decryption"); @@ -790,7 +806,14 @@ Config::write_config () const BOOST_FOREACH (dcp::Certificate const & i, _decryption_chain->unordered()) { decryption->add_child("Certificate")->add_child_text (i.certificate (true)); } +#ifdef DCPOMATIC_VARIANT_SWAROOP + dcp::Data iv = dcpomatic::random_iv (); + dcp::Data encrypted_key = dcpomatic::encrypt (_decryption_chain->key().get(), key_from_uuid(), iv); + encrypted_key.write (path("private")); + iv.write (path("iv")); +#else decryption->add_child("PrivateKey")->add_child_text (_decryption_chain->key().get ()); +#endif /* [XML] History Filename of DCP to present in the File menu of the GUI; there can be more than one of these tags. @@ -959,17 +982,15 @@ Config::write_config () const try { string const s = doc.write_to_string_formatted (); - boost::filesystem::path const cf = config_file (); - FILE* f = fopen_boost (cf, "w"); + boost::filesystem::path tmp (string(config_file().string()).append(".tmp")); + FILE* f = fopen_boost (tmp, "w"); if (!f) { - throw FileError (_("Could not open file for writing"), cf); - } - size_t const w = fwrite (s.c_str(), 1, s.length(), f); - if (w != s.length()) { - fclose (f); - throw FileError (_("Could not write whole file"), cf); + throw FileError (_("Could not open file for writing"), tmp); } + checked_fwrite (s.c_str(), s.length(), f, tmp); fclose (f); + boost::filesystem::remove (config_file()); + boost::filesystem::rename (tmp, config_file()); } catch (xmlpp::exception& e) { string s = e.what (); trim (s); @@ -989,7 +1010,9 @@ Config::write_cinemas () const } try { - doc.write_to_file_formatted (_cinemas_file.string ()); + doc.write_to_file_formatted (_cinemas_file.string() + ".tmp"); + boost::filesystem::remove (_cinemas_file); + boost::filesystem::rename (_cinemas_file.string() + ".tmp", _cinemas_file); } catch (xmlpp::exception& e) { string s = e.what (); trim (s); @@ -1214,10 +1237,16 @@ Config::config_file () } /* See if there's a link */ - f.read_file (main); - optional link = f.optional_string_child("Link"); - if (link) { - return *link; + try { + f.read_file (main); + optional link = f.optional_string_child("Link"); + if (link) { + return *link; + } + } catch (xmlpp::exception& e) { + /* There as a problem reading the main configuration file, + so there can't be a link. + */ } return main;