Validation of certificate chains will fail before dcpomatic_setup()
[dcpomatic.git] / src / lib / config.cc
index c71f3acd3a561f8f728b5f6e2bf15893b2cbe6fc..74f916b21e49e52fa26ba224ccdb9b062e2f4059 100644 (file)
@@ -69,8 +69,7 @@ Config* Config::_instance = 0;
 int const Config::_current_version = 3;
 boost::signals2::signal<void ()> Config::FailedToLoad;
 boost::signals2::signal<void (string)> Config::Warning;
-boost::signals2::signal<bool (void)> Config::BadSignerChain;
-boost::optional<boost::filesystem::path> Config::override_path;
+boost::signals2::signal<bool (Config::BadReason)> Config::Bad;
 
 /** Construct default configuration */
 Config::Config ()
@@ -103,7 +102,7 @@ Config::set_defaults ()
        _default_scale_to = 0;
        _default_dcp_content_type = DCPContentType::from_isdcf_name ("FTR");
        _default_dcp_audio_channels = 6;
-       _default_j2k_bandwidth = 100000000;
+       _default_j2k_bandwidth = 150000000;
        _default_audio_delay = 0;
        _default_interop = true;
        _default_upload_after_make_dcp = false;
@@ -442,30 +441,6 @@ try
        }
 #endif
 
-       /* These must be done before we call BadSignerChain as that might set one
-          of the nags.
-       */
-       BOOST_FOREACH (cxml::NodePtr i, f.node_children("Nagged")) {
-               int const id = i->number_attribute<int>("Id");
-               if (id >= 0 && id < NAG_COUNT) {
-                       _nagged[id] = raw_convert<int>(i->content());
-               }
-       }
-
-       bool bad_signer_chain = false;
-       BOOST_FOREACH (dcp::Certificate const & i, _signer_chain->unordered()) {
-               if (i.has_utf8_strings()) {
-                       bad_signer_chain = true;
-               }
-       }
-
-       if (bad_signer_chain) {
-               optional<bool> const remake = BadSignerChain();
-               if (remake && *remake) {
-                       _signer_chain = create_certificate_chain ();
-               }
-       }
-
        cxml::NodePtr decryption = f.optional_node_child ("Decryption");
 #ifdef DCPOMATIC_VARIANT_SWAROOP
        if (decryption && decryption->node_children().size() == 1) {
@@ -493,6 +468,48 @@ try
                _decryption_chain = create_certificate_chain ();
        }
 #endif
+
+       /* These must be done before we call Bad as that might set one
+          of the nags.
+       */
+       BOOST_FOREACH (cxml::NodePtr i, f.node_children("Nagged")) {
+               int const id = i->number_attribute<int>("Id");
+               if (id >= 0 && id < NAG_COUNT) {
+                       _nagged[id] = raw_convert<int>(i->content());
+               }
+       }
+
+       optional<BadReason> bad;
+
+       BOOST_FOREACH (dcp::Certificate const & i, _signer_chain->unordered()) {
+               if (i.has_utf8_strings()) {
+                       bad = BAD_SIGNER_UTF8_STRINGS;
+               }
+       }
+
+       if (!_signer_chain->chain_valid() || !_signer_chain->private_key_valid()) {
+               bad = BAD_SIGNER_INCONSISTENT;
+       }
+
+       if (!_decryption_chain->chain_valid() || !_decryption_chain->private_key_valid()) {
+               bad = BAD_DECRYPTION_INCONSISTENT;
+       }
+
+       if (bad) {
+               optional<bool> const remake = Bad(*bad);
+               if (remake && *remake) {
+                       switch (*bad) {
+                       case BAD_SIGNER_UTF8_STRINGS:
+                       case BAD_SIGNER_INCONSISTENT:
+                               _signer_chain = create_certificate_chain ();
+                               break;
+                       case BAD_DECRYPTION_INCONSISTENT:
+                               _decryption_chain = create_certificate_chain ();
+                               break;
+                       }
+               }
+       }
+
        if (f.optional_node_child("DKDMGroup")) {
                /* New-style: all DKDMs in a group */
                _dkdms = dynamic_pointer_cast<DKDMGroup> (DKDMBase::read (f.node_child("DKDMGroup")));
@@ -609,33 +626,6 @@ catch (...) {
        write ();
 }
 
-/** @return Filename to write configuration to */
-boost::filesystem::path
-Config::path (string file, bool create_directories)
-{
-       boost::filesystem::path p;
-       if (override_path) {
-               p = *override_path;
-       } else {
-#ifdef DCPOMATIC_OSX
-               p /= g_get_home_dir ();
-               p /= "Library";
-               p /= "Preferences";
-               p /= "com.dcpomatic";
-               p /= "2";
-#else
-               p /= g_get_user_config_dir ();
-               p /= "dcpomatic2";
-#endif
-       }
-       boost::system::error_code ec;
-       if (create_directories) {
-               boost::filesystem::create_directories (p, ec);
-       }
-       p /= file;
-       return p;
-}
-
 /** @return Singleton instance */
 Config *
 Config::instance ()
@@ -663,7 +653,7 @@ Config::write_config () const
        xmlpp::Element* root = doc.create_root_node ("Config");
 
        /* [XML] Version The version number of the configuration file format. */
-       root->add_child("Version")->add_child_text (String::compose ("%1", _current_version));
+       root->add_child("Version")->add_child_text (raw_convert<string>(_current_version));
        /* [XML] MasterEncodingThreads Number of encoding threads to use when running as master. */
        root->add_child("MasterEncodingThreads")->add_child_text (raw_convert<string> (_master_encoding_threads));
        /* [XML] ServerEncodingThreads Number of encoding threads to use when running as server. */