summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2019-04-01 00:31:22 +0100
committerCarl Hetherington <cth@carlh.net>2019-04-08 00:22:40 +0100
commitf2ea67132cd165955db4e91dc634c97d3c42dec1 (patch)
tree1b9e26d7abfc5aa5f07fde05ba2ae6fa0b0ab9a1
parente12f036eb5e724ca79ebef08aebfa62b6e7a4f9c (diff)
Complain on startup if signer or decryption chains are inconsistent (#1520).
-rw-r--r--src/lib/config.cc68
-rw-r--r--src/lib/config.h12
-rw-r--r--src/tools/dcpomatic.cc89
-rw-r--r--src/wx/recreate_chain_dialog.cc23
-rw-r--r--src/wx/recreate_chain_dialog.h6
5 files changed, 139 insertions, 59 deletions
diff --git a/src/lib/config.cc b/src/lib/config.cc
index c71f3acd3..0bacc96ba 100644
--- a/src/lib/config.cc
+++ b/src/lib/config.cc
@@ -69,7 +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::signals2::signal<bool (Config::BadReason)> Config::Bad;
boost::optional<boost::filesystem::path> Config::override_path;
/** Construct default configuration */
@@ -442,30 +442,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 +469,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->private_key_valid() || !_signer_chain->chain_valid()) {
+ bad = BAD_SIGNER_INCONSISTENT;
+ }
+
+ if (!_decryption_chain->private_key_valid() || !_decryption_chain->chain_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")));
diff --git a/src/lib/config.h b/src/lib/config.h
index 5018f7a4f..d54cc17be 100644
--- a/src/lib/config.h
+++ b/src/lib/config.h
@@ -1071,10 +1071,16 @@ public:
static boost::signals2::signal<void ()> FailedToLoad;
/** Emitted if read() issued a warning which the user might want to know about */
static boost::signals2::signal<void (std::string)> Warning;
- /** Emitted if there is a bad certificate in the signer chain. Handler can call
- * true to ask Config to re-create the chain.
+ /** Emitted if there is a something wrong the contents of our config. Handler can call
+ * true to ask Config to solve the problem (by discarding and recreating the bad thing)
*/
- static boost::signals2::signal<bool (void)> BadSignerChain;
+ enum BadReason {
+ BAD_SIGNER_UTF8_STRINGS, ///< signer chain contains UTF-8 strings (not PRINTABLESTRING)
+ BAD_SIGNER_INCONSISTENT, ///< signer chain is somehow inconsistent
+ BAD_DECRYPTION_INCONSISTENT, ///< KDM decryption chain is somehow inconsistent
+ };
+
+ static boost::signals2::signal<bool (BadReason)> Bad;
void write () const;
void write_config () const;
diff --git a/src/tools/dcpomatic.cc b/src/tools/dcpomatic.cc
index 7d3723cb2..4bbd6838d 100644
--- a/src/tools/dcpomatic.cc
+++ b/src/tools/dcpomatic.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2012-2018 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2019 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
@@ -1439,20 +1439,20 @@ public:
App ()
: wxApp ()
, _frame (0)
+ , _splash (0)
{}
private:
bool OnInit ()
{
- wxSplashScreen* splash = 0;
try {
wxInitAllImageHandlers ();
Config::FailedToLoad.connect (boost::bind (&App::config_failed_to_load, this));
Config::Warning.connect (boost::bind (&App::config_warning, this, _1));
- splash = maybe_show_splash ();
+ _splash = maybe_show_splash ();
SetAppName (_("DCP-o-matic"));
@@ -1490,14 +1490,14 @@ private:
*/
Config::drop ();
- Config::BadSignerChain.connect (boost::bind (&App::config_bad_signer_chain, this));
+ Config::Bad.connect (boost::bind(&App::config_bad, this, _1));
_frame = new DOMFrame (_("DCP-o-matic"));
SetTopWindow (_frame);
_frame->Maximize ();
- if (splash) {
- splash->Destroy ();
- splash = 0;
+ if (_splash) {
+ _splash->Destroy ();
+ _splash = 0;
}
if (!Config::instance()->nagged(Config::NAG_INITIAL_SETUP)) {
@@ -1542,8 +1542,9 @@ private:
}
catch (exception& e)
{
- if (splash) {
- splash->Destroy ();
+ if (_splash) {
+ _splash->Destroy ();
+ _splash = 0;
}
error_dialog (0, wxString::Format ("DCP-o-matic could not start."), std_to_wx(e.what()));
}
@@ -1643,19 +1644,73 @@ private:
message_dialog (_frame, std_to_wx (m));
}
- bool config_bad_signer_chain ()
+ bool config_bad (Config::BadReason reason)
{
- if (Config::instance()->nagged(Config::NAG_BAD_SIGNER_CHAIN)) {
- return false;
- }
+ /* Destroy the splash screen here, as otherwise bad things seem to happen (for reasons unknown)
+ when we open our recreate dialog, close it, *then* try to Destroy the splash (the Destroy fails).
+ */
+ _splash->Destroy ();
+ _splash = 0;
- RecreateChainDialog* d = new RecreateChainDialog (_frame);
- int const r = d->ShowModal ();
- d->Destroy ();
- return r == wxID_OK;
+ Config* config = Config::instance();
+ switch (reason) {
+ case Config::BAD_SIGNER_UTF8_STRINGS:
+ {
+ if (config->nagged(Config::NAG_BAD_SIGNER_CHAIN)) {
+ return false;
+ }
+ RecreateChainDialog* d = new RecreateChainDialog (
+ _frame, _("Recreate signing certificates"),
+ _("The certificate chain that DCP-o-matic uses for signing DCPs and KDMs contains a small error\n"
+ "which will prevent DCPs from being validated correctly on some systems. Do you want to re-create\n"
+ "the certificate chain for signing DCPs and KDMs?"),
+ _("Do nothing"),
+ Config::NAG_BAD_SIGNER_CHAIN
+ );
+ int const r = d->ShowModal ();
+ d->Destroy ();
+ return r == wxID_OK;
+ }
+ case Config::BAD_SIGNER_INCONSISTENT:
+ {
+ RecreateChainDialog* d = new RecreateChainDialog (
+ _frame, _("Recreate signing certificates"),
+ _("The certificate chain that DCP-o-matic uses for signing DCPs and KDMs is inconsistent and\n"
+ "cannot be used. DCP-o-matic cannot start unless you re-create it. Do you want to re-create\n"
+ "the certificate chain for signing DCPs and KDMs?"),
+ _("Close DCP-o-matic")
+ );
+ int const r = d->ShowModal ();
+ d->Destroy ();
+ if (r != wxID_OK) {
+ exit (EXIT_FAILURE);
+ }
+ return true;
+ }
+ case Config::BAD_DECRYPTION_INCONSISTENT:
+ {
+ RecreateChainDialog* d = new RecreateChainDialog (
+ _frame, _("Recreate KDM decryption chain"),
+ _("The certificate chain that DCP-o-matic uses for decrypting KDMs is inconsistent and\n"
+ "cannot be used. DCP-o-matic cannot start unless you re-create it. Do you want to re-create\n"
+ "the certificate chain for decrypting KDMs? You may want to say \"No\" here and back up your\n"
+ "configuration before continuing."),
+ _("Close DCP-o-matic")
+ );
+ int const r = d->ShowModal ();
+ d->Destroy ();
+ if (r != wxID_OK) {
+ exit (EXIT_FAILURE);
+ }
+ return true;
+ }
+ default:
+ DCPOMATIC_ASSERT (false);
+ }
}
DOMFrame* _frame;
+ wxSplashScreen* _splash;
shared_ptr<wxTimer> _timer;
string _film_to_load;
string _film_to_create;
diff --git a/src/wx/recreate_chain_dialog.cc b/src/wx/recreate_chain_dialog.cc
index 1dd14e0c8..e477cdc1f 100644
--- a/src/wx/recreate_chain_dialog.cc
+++ b/src/wx/recreate_chain_dialog.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2018-2019 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
@@ -28,20 +28,19 @@
using std::list;
using std::string;
+using boost::optional;
-RecreateChainDialog::RecreateChainDialog (wxWindow* parent)
- : QuestionDialog (parent, _("Certificate chain"), _("Recreate signing certificates"), _("Do nothing"))
+RecreateChainDialog::RecreateChainDialog (wxWindow* parent, wxString title, wxString message, wxString cancel, optional<Config::Nag> nag)
+ : QuestionDialog (parent, _("Certificate chain"), title, cancel)
+ , _nag (nag)
{
- wxString const message = _("The certificate chain that DCP-o-matic uses for signing DCPs and KDMs contains a small error\n"
- "which will prevent DCPs from being validated correctly on some systems. Do you want to re-create\n"
- "the certificate chain for signing DCPs and KDMs?");
-
_sizer->Add (new StaticText (this, message), 1, wxEXPAND | wxALL, DCPOMATIC_DIALOG_BORDER);
- wxCheckBox* shut_up = new CheckBox (this, _("Don't ask this again"));
- _sizer->Add (shut_up, 0, wxALL, DCPOMATIC_DIALOG_BORDER);
-
- shut_up->Bind (wxEVT_CHECKBOX, bind (&RecreateChainDialog::shut_up, this, _1));
+ if (nag) {
+ wxCheckBox* shut_up = new CheckBox (this, _("Don't ask this again"));
+ _sizer->Add (shut_up, 0, wxALL, DCPOMATIC_DIALOG_BORDER);
+ shut_up->Bind (wxEVT_CHECKBOX, bind (&RecreateChainDialog::shut_up, this, _1));
+ }
layout ();
}
@@ -49,5 +48,5 @@ RecreateChainDialog::RecreateChainDialog (wxWindow* parent)
void
RecreateChainDialog::shut_up (wxCommandEvent& ev)
{
- Config::instance()->set_nagged (Config::NAG_BAD_SIGNER_CHAIN, ev.IsChecked());
+ Config::instance()->set_nagged(*_nag, ev.IsChecked());
}
diff --git a/src/wx/recreate_chain_dialog.h b/src/wx/recreate_chain_dialog.h
index 287e65767..10086be86 100644
--- a/src/wx/recreate_chain_dialog.h
+++ b/src/wx/recreate_chain_dialog.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2018-2019 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
@@ -19,14 +19,16 @@
*/
#include "question_dialog.h"
+#include "lib/config.h"
#include <wx/wx.h>
#include <list>
class RecreateChainDialog : public QuestionDialog
{
public:
- RecreateChainDialog (wxWindow* parent);
+ RecreateChainDialog (wxWindow* parent, wxString title, wxString message, wxString cancel, boost::optional<Config::Nag> nag = boost::optional<Config::Nag>());
private:
void shut_up (wxCommandEvent& ev);
+ boost::optional<Config::Nag> _nag;
};