From 6d770c4c8c79569871edc20253f29f9ea00539e6 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 9 Mar 2018 00:55:49 +0000 Subject: [PATCH] Check for signer chains containing UTF8-marked strings and offer to fix them on startup (#1218). --- src/lib/config.cc | 31 ++++++++++++++++---- src/lib/config.h | 5 ++++ src/tools/dcpomatic.cc | 15 ++++++++++ src/wx/recreate_chain_dialog.cc | 52 +++++++++++++++++++++++++++++++++ src/wx/recreate_chain_dialog.h | 32 ++++++++++++++++++++ src/wx/wscript | 1 + 6 files changed, 130 insertions(+), 6 deletions(-) create mode 100644 src/wx/recreate_chain_dialog.cc create mode 100644 src/wx/recreate_chain_dialog.h diff --git a/src/lib/config.cc b/src/lib/config.cc index ec5b05afa..2ae7939a9 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -67,6 +67,7 @@ Config* Config::_instance = 0; int const Config::_current_version = 3; boost::signals2::signal Config::FailedToLoad; boost::signals2::signal Config::Warning; +boost::signals2::signal Config::BadSignerChain; boost::optional Config::test_path; /** Construct default configuration */ @@ -349,6 +350,30 @@ try _signer_chain = create_certificate_chain (); } + /* 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("Id"); + if (id >= 0 && id < NAG_COUNT) { + _nagged[id] = raw_convert(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 const remake = BadSignerChain(); + if (remake && *remake) { + _signer_chain = create_certificate_chain (); + } + } + cxml::NodePtr decryption = f.optional_node_child ("Decryption"); if (decryption) { shared_ptr c (new dcp::CertificateChain ()); @@ -379,12 +404,6 @@ try _dcp_metadata_filename_format = dcp::NameFormat (f.optional_string_child("DCPMetadataFilenameFormat").get_value_or ("%t")); _dcp_asset_filename_format = dcp::NameFormat (f.optional_string_child("DCPAssetFilenameFormat").get_value_or ("%t")); _jump_to_selected = f.optional_bool_child("JumpToSelected").get_value_or (true); - BOOST_FOREACH (cxml::NodePtr i, f.node_children("Nagged")) { - int const id = i->number_attribute("Id"); - if (id >= 0 && id < NAG_COUNT) { - _nagged[id] = raw_convert(i->content()); - } - } /* The variable was renamed but not the XML tag */ _sound = f.optional_bool_child("PreviewSound").get_value_or (true); _sound_output = f.optional_string_child("PreviewSoundOutput"); diff --git a/src/lib/config.h b/src/lib/config.h index 90ebb0b33..2fca9699c 100644 --- a/src/lib/config.h +++ b/src/lib/config.h @@ -330,6 +330,7 @@ public: NAG_DKDM_CONFIG, NAG_ENCRYPTED_METADATA, NAG_REMAKE_DECRYPTION_CHAIN, + NAG_BAD_SIGNER_CHAIN, NAG_COUNT }; @@ -696,6 +697,10 @@ public: static boost::signals2::signal FailedToLoad; /** Emitted if read() issued a warning which the user might want to know about */ static boost::signals2::signal Warning; + /** Emitted if there is a bad certificate in the signer chain. Handler can call + * true to ask Config to re-create the chain. + */ + static boost::signals2::signal BadSignerChain; void write () const; void write_config () const; diff --git a/src/tools/dcpomatic.cc b/src/tools/dcpomatic.cc index b22120143..1e6c49d7b 100644 --- a/src/tools/dcpomatic.cc +++ b/src/tools/dcpomatic.cc @@ -29,6 +29,7 @@ #include "wx/wx_util.h" #include "wx/film_name_location_dialog.h" #include "wx/wx_signal_manager.h" +#include "wx/recreate_chain_dialog.h" #include "wx/about_dialog.h" #include "wx/kdm_dialog.h" #include "wx/self_dkdm_dialog.h" @@ -1281,6 +1282,8 @@ private: */ Config::drop (); + Config::BadSignerChain.connect (boost::bind (&App::config_bad_signer_chain, this)); + _frame = new DOMFrame (_("DCP-o-matic")); SetTopWindow (_frame); _frame->Maximize (); @@ -1420,6 +1423,18 @@ private: message_dialog (_frame, std_to_wx (m)); } + bool config_bad_signer_chain () + { + if (Config::instance()->nagged(Config::NAG_BAD_SIGNER_CHAIN)) { + return false; + } + + RecreateChainDialog* d = new RecreateChainDialog (_frame); + int const r = d->ShowModal (); + d->Destroy (); + return r == wxID_OK; + } + DOMFrame* _frame; shared_ptr _timer; string _film_to_load; diff --git a/src/wx/recreate_chain_dialog.cc b/src/wx/recreate_chain_dialog.cc new file mode 100644 index 000000000..b59e99ddc --- /dev/null +++ b/src/wx/recreate_chain_dialog.cc @@ -0,0 +1,52 @@ +/* + Copyright (C) 2018 Carl Hetherington + + This file is part of DCP-o-matic. + + DCP-o-matic is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + DCP-o-matic is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DCP-o-matic. If not, see . + +*/ + +#include "recreate_chain_dialog.h" +#include "wx_util.h" +#include "lib/config.h" +#include "lib/cinema_kdms.h" +#include + +using std::list; +using std::string; + +RecreateChainDialog::RecreateChainDialog (wxWindow* parent) + : QuestionDialog (parent, _("Certificate chain"), _("Recreate signing certificates"), _("Do nothing")) +{ + 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 wxStaticText (this, wxID_ANY, message), 1, wxEXPAND | wxALL, DCPOMATIC_DIALOG_BORDER); + + wxCheckBox* shut_up = new wxCheckBox (this, wxID_ANY, _("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 (); +} + +void +RecreateChainDialog::shut_up (wxCommandEvent& ev) +{ + std::cout << "set nagged " << ev.IsChecked() << "\n"; + Config::instance()->set_nagged (Config::NAG_BAD_SIGNER_CHAIN, ev.IsChecked()); +} diff --git a/src/wx/recreate_chain_dialog.h b/src/wx/recreate_chain_dialog.h new file mode 100644 index 000000000..287e65767 --- /dev/null +++ b/src/wx/recreate_chain_dialog.h @@ -0,0 +1,32 @@ +/* + Copyright (C) 2018 Carl Hetherington + + This file is part of DCP-o-matic. + + DCP-o-matic is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + DCP-o-matic is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DCP-o-matic. If not, see . + +*/ + +#include "question_dialog.h" +#include +#include + +class RecreateChainDialog : public QuestionDialog +{ +public: + RecreateChainDialog (wxWindow* parent); + +private: + void shut_up (wxCommandEvent& ev); +}; diff --git a/src/wx/wscript b/src/wx/wscript index 86065731c..227691be1 100644 --- a/src/wx/wscript +++ b/src/wx/wscript @@ -82,6 +82,7 @@ sources = """ playhead_to_timecode_dialog.cc playhead_to_frame_dialog.cc question_dialog.cc + recreate_chain_dialog.cc repeat_dialog.cc report_problem_dialog.cc rename_template_dialog.cc -- 2.30.2