Merge master.
[dcpomatic.git] / src / lib / config.cc
index d4976676d574b5f34b93eb0b3a2d84a09f5ba88c..14539044d2eb53b11f2465ea4e753e75a0ab1f93 100644 (file)
@@ -25,6 +25,8 @@
 #include <boost/algorithm/string.hpp>
 #include <dcp/colour_matrix.h>
 #include <dcp/raw_convert.h>
+#include <dcp/signer.h>
+#include <dcp/certificate_chain.h>
 #include <libcxml/cxml.h>
 #include "config.h"
 #include "server.h"
@@ -36,6 +38,7 @@
 #include "colour_conversion.h"
 #include "cinema.h"
 #include "util.h"
+#include "cross.h"
 
 #include "i18n.h"
 
@@ -63,6 +66,7 @@ Config::Config ()
        , _cinema_sound_processor (CinemaSoundProcessor::from_id (N_("dolby_cp750")))
        , _allow_any_dcp_frame_rate (false)
        , _default_still_length (10)
+       , _default_scale (Ratio::from_id ("185"))
        , _default_container (Ratio::from_id ("185"))
        , _default_dcp_content_type (DCPContentType::from_isdcf_name ("TST"))
        , _default_j2k_bandwidth (100000000)
@@ -136,6 +140,11 @@ Config::read ()
 
        _language = f.optional_string_child ("Language");
 
+       c = f.optional_string_child ("DefaultScale");
+       if (c) {
+               _default_scale = Ratio::from_id (c.get ());
+       }
+
        c = f.optional_string_child ("DefaultContainer");
        if (c) {
                _default_container = Ratio::from_id (c.get ());
@@ -189,8 +198,10 @@ Config::read ()
        _mail_server = f.string_child ("MailServer");
        _mail_user = f.optional_string_child("MailUser").get_value_or ("");
        _mail_password = f.optional_string_child("MailPassword").get_value_or ("");
+       _kdm_subject = f.optional_string_child ("KDMSubject").get_value_or (_("KDM delivery: $CPL_NAME"));
        _kdm_from = f.string_child ("KDMFrom");
        _kdm_cc = f.optional_string_child ("KDMCC").get_value_or ("");
+       _kdm_bcc = f.optional_string_child ("KDMBCC").get_value_or ("");
        _kdm_email = f.string_child ("KDMEmail");
 
        _check_for_updates = f.optional_bool_child("CheckForUpdates").get_value_or (false);
@@ -200,6 +211,37 @@ Config::read ()
        _allow_any_dcp_frame_rate = f.optional_bool_child ("AllowAnyDCPFrameRate");
 
        _log_types = f.optional_number_child<int> ("LogTypes").get_value_or (Log::TYPE_GENERAL | Log::TYPE_WARNING | Log::TYPE_ERROR);
+
+       cxml::NodePtr signer = f.optional_node_child ("Signer");
+       dcp::CertificateChain signer_chain;
+       if (signer) {
+               /* Read the signing certificates and private key in from the config file */
+               list<cxml::NodePtr> certificates = signer->node_children ("Certificate");
+               for (list<cxml::NodePtr>::const_iterator i = certificates.begin(); i != certificates.end(); ++i) {
+                       signer_chain.add (dcp::Certificate ((*i)->content ()));
+               }
+
+               _signer.reset (new dcp::Signer (signer_chain, signer->string_child ("PrivateKey")));
+       } else {
+               /* Make a new set of signing certificates and key */
+               _signer.reset (new dcp::Signer (openssl_path ()));
+       }
+
+       if (f.optional_string_child ("DecryptionCertificate")) {
+               _decryption_certificate = dcp::Certificate (f.string_child ("DecryptionCertificate"));
+       }
+
+       if (f.optional_string_child ("DecryptionPrivateKey")) {
+               _decryption_private_key = f.string_child ("DecryptionPrivateKey");
+       }
+
+       if (!f.optional_string_child ("DecryptionCertificate") || !f.optional_string_child ("DecryptionPrivateKey")) {
+               /* Generate our own decryption certificate and key if either is not present in config */
+               boost::filesystem::path p = dcp::make_certificate_chain (openssl_path ());
+               _decryption_certificate = dcp::Certificate (dcp::file_to_string (p / "leaf.signed.pem"));
+               _decryption_private_key = dcp::file_to_string (p / "leaf.key");
+               boost::filesystem::remove_all (p);
+       }
 }
 
 /** @return Filename to write configuration to */
@@ -220,17 +262,6 @@ Config::file (bool old) const
        return p;
 }
 
-boost::filesystem::path
-Config::signer_chain_directory () const
-{
-       boost::filesystem::path p;
-       p /= g_get_user_config_dir ();
-       p /= "dcpomatic";
-       p /= "crypt";
-       boost::filesystem::create_directories (p);
-       return p;
-}
-
 /** @return Singleton instance */
 Config *
 Config::instance ()
@@ -279,6 +310,9 @@ Config::write () const
        if (_language) {
                root->add_child("Language")->add_child_text (_language.get());
        }
+       if (_default_scale) {
+               root->add_child("DefaultScale")->add_child_text (_default_scale->id ());
+       }
        if (_default_container) {
                root->add_child("DefaultContainer")->add_child_text (_default_container->id ());
        }
@@ -305,8 +339,10 @@ Config::write () const
        root->add_child("MailServer")->add_child_text (_mail_server);
        root->add_child("MailUser")->add_child_text (_mail_user);
        root->add_child("MailPassword")->add_child_text (_mail_password);
+       root->add_child("KDMSubject")->add_child_text (_kdm_subject);
        root->add_child("KDMFrom")->add_child_text (_kdm_from);
        root->add_child("KDMCC")->add_child_text (_kdm_cc);
+       root->add_child("KDMBCC")->add_child_text (_kdm_bcc);
        root->add_child("KDMEmail")->add_child_text (_kdm_email);
 
        root->add_child("CheckForUpdates")->add_child_text (_check_for_updates ? "1" : "0");
@@ -315,7 +351,17 @@ Config::write () const
        root->add_child("MaximumJ2KBandwidth")->add_child_text (raw_convert<string> (_maximum_j2k_bandwidth));
        root->add_child("AllowAnyDCPFrameRate")->add_child_text (_allow_any_dcp_frame_rate ? "1" : "0");
        root->add_child("LogTypes")->add_child_text (raw_convert<string> (_log_types));
-       
+
+       xmlpp::Element* signer = root->add_child ("Signer");
+       dcp::CertificateChain::List certs = _signer->certificates().root_to_leaf ();
+       for (dcp::CertificateChain::List::const_iterator i = certs.begin(); i != certs.end(); ++i) {
+               signer->add_child("Certificate")->add_child_text (i->certificate (true));
+       }
+       signer->add_child("PrivateKey")->add_child_text (_signer->key ());
+
+       root->add_child("DecryptionCertificate")->add_child_text (_decryption_certificate.certificate (true));
+       root->add_child("DecryptionPrivateKey")->add_child_text (_decryption_private_key);
+
        doc.write_to_file_formatted (file(false).string ());
 }