From: Carl Hetherington Date: Fri, 21 Jan 2022 22:39:03 +0000 (+0100) Subject: Display the filename / URL that a screen certificate was obtained from (#1894). X-Git-Tag: v2.16.6~19 X-Git-Url: https://git.carlh.net/gitweb/?p=dcpomatic.git;a=commitdiff_plain;h=2fd641547b5fb795fc17e98e47f489fa82e8ff42 Display the filename / URL that a screen certificate was obtained from (#1894). --- diff --git a/src/lib/dkdm_recipient.h b/src/lib/dkdm_recipient.h index d08f82daa..50f2f3e15 100644 --- a/src/lib/dkdm_recipient.h +++ b/src/lib/dkdm_recipient.h @@ -37,7 +37,7 @@ public: int utc_offset_hour_, int utc_offset_minute_ ) - : KDMRecipient (name_, notes_, recipient_) + : KDMRecipient (name_, notes_, recipient_, boost::none) , emails (emails_) , utc_offset_hour (utc_offset_hour_) , utc_offset_minute (utc_offset_minute_) diff --git a/src/lib/internet.cc b/src/lib/internet.cc index 4fb6c7cb3..121d3524c 100644 --- a/src/lib/internet.cc +++ b/src/lib/internet.cc @@ -126,14 +126,14 @@ get_from_url (string url, bool pasv, bool skip_pasv_ip, ScopedTemporary& temp) optional -get_from_url (string url, bool pasv, bool skip_pasv_ip, function (boost::filesystem::path)> load) +get_from_url (string url, bool pasv, bool skip_pasv_ip, function (boost::filesystem::path, string)> load) { ScopedTemporary temp; auto e = get_from_url (url, pasv, skip_pasv_ip, temp); if (e) { return e; } - return load (temp.file()); + return load (temp.file(), url); } @@ -142,7 +142,7 @@ get_from_url (string url, bool pasv, bool skip_pasv_ip, function -get_from_zip_url (string url, string file, bool pasv, bool skip_pasv_ip, function (boost::filesystem::path)> load) +get_from_zip_url (string url, string file, bool pasv, bool skip_pasv_ip, function (boost::filesystem::path, string)> load) { /* Download the ZIP file to temp_zip */ ScopedTemporary temp_zip; @@ -199,5 +199,5 @@ get_from_zip_url (string url, string file, bool pasv, bool skip_pasv_ip, functio zip_close (zip); temp_cert.close (); - return load (temp_cert.file()); + return load (temp_cert.file(), url); } diff --git a/src/lib/internet.h b/src/lib/internet.h index f3cd2c6b4..041bb1bb1 100644 --- a/src/lib/internet.h +++ b/src/lib/internet.h @@ -27,6 +27,20 @@ class ScopedTemporary; boost::optional get_from_url (std::string url, bool pasv, bool skip_pasv_ip, ScopedTemporary& temp); -boost::optional get_from_url (std::string url, bool pasv, bool skip_pasv_ip, std::function (boost::filesystem::path)> load); -boost::optional get_from_zip_url (std::string url, std::string file, bool pasv, bool skip_pasv_ip, std::function (boost::filesystem::path)> load); + +boost::optional get_from_url ( + std::string url, + bool pasv, + bool skip_pasv_ip, + std::function (boost::filesystem::path, std::string)> load + ); + +boost::optional get_from_zip_url ( + std::string url, + std::string file, + bool pasv, + bool skip_pasv_ip, + std::function (boost::filesystem::path, std::string)> load + ); + std::list ls_url (std::string url); diff --git a/src/lib/kdm_cli.cc b/src/lib/kdm_cli.cc index e6ba600f4..0ec648e04 100644 --- a/src/lib/kdm_cli.cc +++ b/src/lib/kdm_cli.cc @@ -540,7 +540,7 @@ try { /* Make a new screen and add it to the current cinema */ dcp::CertificateChain chain (dcp::file_to_string(optarg)); - auto screen = make_shared(screen_description, "", chain.leaf(), vector()); + auto screen = std::make_shared(screen_description, "", chain.leaf(), boost::none, vector()); if (cinema) { cinema->add_screen (screen); } diff --git a/src/lib/kdm_recipient.cc b/src/lib/kdm_recipient.cc index cde41e22d..671e9797c 100644 --- a/src/lib/kdm_recipient.cc +++ b/src/lib/kdm_recipient.cc @@ -31,6 +31,8 @@ KDMRecipient::KDMRecipient (cxml::ConstNodePtr node) } else if (node->optional_string_child("Recipient")) { recipient = dcp::Certificate (node->string_child("Recipient")); } + + recipient_file = node->optional_string_child("RecipientFile"); } @@ -41,6 +43,9 @@ KDMRecipient::as_xml (xmlpp::Element* parent) const if (recipient) { parent->add_child("Recipient")->add_child_text(recipient->certificate(true)); } + if (recipient_file) { + parent->add_child("RecipientFile")->add_child_text(*recipient_file); + } parent->add_child("Notes")->add_child_text(notes); } diff --git a/src/lib/kdm_recipient.h b/src/lib/kdm_recipient.h index 85352f0ee..90e9fd16d 100644 --- a/src/lib/kdm_recipient.h +++ b/src/lib/kdm_recipient.h @@ -36,10 +36,11 @@ DCPOMATIC_ENABLE_WARNINGS class KDMRecipient { public: - KDMRecipient (std::string const& name_, std::string const& notes_, boost::optional recipient_) + KDMRecipient (std::string const& name_, std::string const& notes_, boost::optional recipient_, boost::optional recipient_file_) : name (name_) , notes (notes_) , recipient (recipient_) + , recipient_file (recipient_file_) {} explicit KDMRecipient (cxml::ConstNodePtr); @@ -51,6 +52,10 @@ public: std::string name; std::string notes; boost::optional recipient; + /** The pathname or URL that the recipient certificate was obtained from; purely + * to inform the user. + */ + boost::optional recipient_file; }; diff --git a/src/lib/screen.h b/src/lib/screen.h index 15a0785d5..6103d207d 100644 --- a/src/lib/screen.h +++ b/src/lib/screen.h @@ -49,8 +49,14 @@ namespace dcpomatic { class Screen : public KDMRecipient { public: - Screen (std::string const & name_, std::string const & notes_, boost::optional recipient_, std::vector trusted_devices_) - : KDMRecipient (name_, notes_, recipient_) + Screen ( + std::string const & name_, + std::string const & notes_, + boost::optional recipient_, + boost::optional recipient_file_, + std::vector trusted_devices_ + ) + : KDMRecipient (name_, notes_, recipient_, recipient_file_) , trusted_devices (trusted_devices_) {} diff --git a/src/wx/barco_alchemy_certificate_panel.cc b/src/wx/barco_alchemy_certificate_panel.cc index a1d6167aa..981efee1f 100644 --- a/src/wx/barco_alchemy_certificate_panel.cc +++ b/src/wx/barco_alchemy_certificate_panel.cc @@ -64,7 +64,7 @@ BarcoAlchemyCertificatePanel::do_download () serial ); - optional error = get_from_url (url, true, false, boost::bind (&DownloadCertificatePanel::load_certificate, this, _1)); + auto error = get_from_url (url, true, false, boost::bind (&DownloadCertificatePanel::load_certificate, this, _1, _2)); if (error) { _dialog->message()->SetLabel(wxT("")); error_dialog (this, std_to_wx(*error)); diff --git a/src/wx/christie_certificate_panel.cc b/src/wx/christie_certificate_panel.cc index 4d9b1fcb7..77516fb82 100644 --- a/src/wx/christie_certificate_panel.cc +++ b/src/wx/christie_certificate_panel.cc @@ -64,13 +64,13 @@ ChristieCertificatePanel::do_download () optional all_errors; bool ok = true; - optional error = get_from_url (url, true, false, boost::bind(&DownloadCertificatePanel::load_certificate_from_chain, this, _1)); + auto error = get_from_url (url, true, false, boost::bind(&DownloadCertificatePanel::load_certificate_from_chain, this, _1, _2)); if (error) { all_errors = *error; auto const url = String::compose ("%1IMB-S2/IMB-S2_%2_sha256.pem", prefix, serial); - error = get_from_url (url, true, false, boost::bind(&DownloadCertificatePanel::load_certificate_from_chain, this, _1)); + error = get_from_url (url, true, false, boost::bind(&DownloadCertificatePanel::load_certificate_from_chain, this, _1, _2)); if (error) { *all_errors += "\n" + *error; ok = false; diff --git a/src/wx/dolby_doremi_certificate_panel.cc b/src/wx/dolby_doremi_certificate_panel.cc index 817867cc1..db4cd9f67 100644 --- a/src/wx/dolby_doremi_certificate_panel.cc +++ b/src/wx/dolby_doremi_certificate_panel.cc @@ -199,7 +199,7 @@ DolbyDoremiCertificatePanel::do_download () auto i = urls.begin (); auto j = files.begin (); while (!ok && i != urls.end ()) { - auto error = get_from_zip_url (*i++, *j++, true, true, boost::bind(&DownloadCertificatePanel::load_certificate, this, _1)); + auto error = get_from_zip_url (*i++, *j++, true, true, boost::bind(&DownloadCertificatePanel::load_certificate, this, _1, _2)); if (error) { errors.push_back (error.get ()); } else { diff --git a/src/wx/download_certificate_dialog.cc b/src/wx/download_certificate_dialog.cc index 4a80dc9c0..8f4720252 100644 --- a/src/wx/download_certificate_dialog.cc +++ b/src/wx/download_certificate_dialog.cc @@ -30,6 +30,7 @@ #include "wx_util.h" +using std::string; using boost::optional; @@ -102,6 +103,16 @@ DownloadCertificateDialog::certificate () const return *c; } + +string +DownloadCertificateDialog::url () const +{ + auto u = _pages[_notebook->GetSelection()]->url(); + DCPOMATIC_ASSERT (u); + return *u; +} + + void DownloadCertificateDialog::setup_sensitivity () { diff --git a/src/wx/download_certificate_dialog.h b/src/wx/download_certificate_dialog.h index ef241a0ca..a5085e174 100644 --- a/src/wx/download_certificate_dialog.h +++ b/src/wx/download_certificate_dialog.h @@ -34,6 +34,7 @@ public: ~DownloadCertificateDialog (); dcp::Certificate certificate () const; + std::string url () const; void setup_sensitivity (); diff --git a/src/wx/download_certificate_panel.cc b/src/wx/download_certificate_panel.cc index c30b05008..b3de4ca2c 100644 --- a/src/wx/download_certificate_panel.cc +++ b/src/wx/download_certificate_panel.cc @@ -58,10 +58,11 @@ DownloadCertificatePanel::DownloadCertificatePanel (DownloadCertificateDialog* d optional -DownloadCertificatePanel::load_certificate (boost::filesystem::path file) +DownloadCertificatePanel::load_certificate (boost::filesystem::path file, string url) { try { _certificate = dcp::Certificate (dcp::file_to_string(file)); + _url = url; } catch (dcp::MiscError& e) { return String::compose(wx_to_std(_("Could not read certificate file (%1)")), e.what()); } @@ -70,10 +71,11 @@ DownloadCertificatePanel::load_certificate (boost::filesystem::path file) optional -DownloadCertificatePanel::load_certificate_from_chain (boost::filesystem::path file) +DownloadCertificatePanel::load_certificate_from_chain (boost::filesystem::path file, string url) { try { _certificate = dcp::CertificateChain (dcp::file_to_string(file)).leaf(); + _url = url; } catch (dcp::MiscError& e) { return String::compose(wx_to_std(_("Could not read certificate file (%1)")), e.what()); } @@ -88,6 +90,14 @@ DownloadCertificatePanel::certificate () const } + +optional +DownloadCertificatePanel::url () const +{ + return _url; + +} + void DownloadCertificatePanel::download () { diff --git a/src/wx/download_certificate_panel.h b/src/wx/download_certificate_panel.h index 25271c770..0e7b2ab71 100644 --- a/src/wx/download_certificate_panel.h +++ b/src/wx/download_certificate_panel.h @@ -44,9 +44,10 @@ public: virtual bool ready_to_download () const; void download (); - boost::optional load_certificate (boost::filesystem::path); - boost::optional load_certificate_from_chain (boost::filesystem::path); + boost::optional load_certificate (boost::filesystem::path, std::string url); + boost::optional load_certificate_from_chain (boost::filesystem::path, std::string url); boost::optional certificate () const; + boost::optional url () const; protected: DownloadCertificateDialog* _dialog; @@ -56,6 +57,7 @@ protected: private: boost::optional _certificate; + boost::optional _url; }; diff --git a/src/wx/gdc_certificate_panel.cc b/src/wx/gdc_certificate_panel.cc index f7f86895d..e670f01eb 100644 --- a/src/wx/gdc_certificate_panel.cc +++ b/src/wx/gdc_certificate_panel.cc @@ -61,7 +61,7 @@ GDCCertificatePanel::do_download () serial ); - optional error = get_from_url (url, true, false, boost::bind(&DownloadCertificatePanel::load_certificate, this, _1)); + auto error = get_from_url (url, true, false, boost::bind(&DownloadCertificatePanel::load_certificate, this, _1, _2)); if (error) { _dialog->message()->SetLabel(wxT("")); diff --git a/src/wx/qube_certificate_panel.cc b/src/wx/qube_certificate_panel.cc index e1c6bfb41..8e9662e7d 100644 --- a/src/wx/qube_certificate_panel.cc +++ b/src/wx/qube_certificate_panel.cc @@ -71,7 +71,7 @@ QubeCertificatePanel::do_download () return; } - auto error = get_from_url (String::compose("%1SMPTE-%2/%3", base, _type, *name), true, false, boost::bind(&DownloadCertificatePanel::load_certificate, this, _1)); + auto error = get_from_url (String::compose("%1SMPTE-%2/%3", base, _type, *name), true, false, boost::bind(&DownloadCertificatePanel::load_certificate, this, _1, _2)); if (error) { _dialog->message()->SetLabel(wxT("")); diff --git a/src/wx/screen_dialog.cc b/src/wx/screen_dialog.cc index 3148d09d9..af5e25f47 100644 --- a/src/wx/screen_dialog.cc +++ b/src/wx/screen_dialog.cc @@ -102,7 +102,13 @@ private: ScreenDialog::ScreenDialog ( - wxWindow* parent, wxString title, string name, string notes, optional recipient, vector trusted_devices + wxWindow* parent, + wxString title, + string name, + string notes, + optional recipient, + optional recipient_file, + vector trusted_devices ) : wxDialog (parent, wxID_ANY, title) , _recipient (recipient) @@ -136,15 +142,31 @@ ScreenDialog::ScreenDialog ( _recipient_thumbprint = new StaticText (this, wxT (""), wxDefaultPosition, size); _recipient_thumbprint->SetFont (font); set_recipient (recipient); + _get_recipient_from_file = new Button (this, _("Get from file...")); _download_recipient = new Button (this, _("Download...")); - s->Add (_recipient_thumbprint, 1, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, DCPOMATIC_SIZER_X_GAP); + s->Add (_recipient_thumbprint, 1, wxRIGHT | wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT, DCPOMATIC_SIZER_X_GAP); s->Add (_get_recipient_from_file, 0, wxLEFT | wxRIGHT | wxEXPAND, DCPOMATIC_SIZER_X_GAP); s->Add (_download_recipient, 0, wxLEFT | wxRIGHT | wxEXPAND, DCPOMATIC_SIZER_X_GAP); _sizer->Add (s, wxGBPosition (r, 1)); ++r; - add_label_to_sizer (_sizer, this, _("Other trusted devices"), true, wxGBPosition (r, 0)); + add_label_to_sizer (_sizer, this, _("Filename"), true, wxGBPosition(r, 0)); + _recipient_file = new wxStaticText (this, wxID_ANY, wxT("")); + checked_set (_recipient_file, recipient_file.get_value_or("")); + _sizer->Add (_recipient_file, wxGBPosition(r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL, DCPOMATIC_SIZER_Y_GAP); + ++r; + + { + int flags = wxALIGN_CENTER_VERTICAL | wxTOP; +#ifdef __WXOSX__ + flags |= wxALIGN_RIGHT; + auto m = new StaticText (this, _("Other trusted devices") + wxT(":")); +#else + auto m = new StaticText (this, _("Other trusted devices")); +#endif + _sizer->Add (m, wxGBPosition(r, 0), wxDefaultSpan, flags, DCPOMATIC_SIZER_Y_GAP); + } ++r; vector columns; @@ -202,6 +224,17 @@ ScreenDialog::recipient () const } +optional +ScreenDialog::recipient_file () const +{ + auto const f = wx_to_std(_recipient_file->GetLabel()); + if (f.empty()) { + return {}; + } + return f; +} + + void ScreenDialog::load_recipient (boost::filesystem::path file) { @@ -213,6 +246,7 @@ ScreenDialog::load_recipient (boost::filesystem::path file) return; } set_recipient (c.leaf ()); + checked_set (_recipient_file, file.string()); } catch (dcp::MiscError& e) { error_dialog (this, _("Could not read certificate file."), std_to_wx(e.what())); } @@ -238,6 +272,7 @@ ScreenDialog::download_recipient () auto d = new DownloadCertificateDialog (this); if (d->ShowModal() == wxID_OK) { set_recipient (d->certificate()); + checked_set (_recipient_file, d->url()); } d->Destroy (); setup_sensitivity (); diff --git a/src/wx/screen_dialog.h b/src/wx/screen_dialog.h index 49e4d092a..fcb3fba5d 100644 --- a/src/wx/screen_dialog.h +++ b/src/wx/screen_dialog.h @@ -38,13 +38,15 @@ public: wxString, std::string name = "", std::string notes = "", - boost::optional c = boost::optional(), - std::vector d = std::vector() + boost::optional c = {}, + boost::optional f = {}, + std::vector d = {} ); std::string name () const; std::string notes () const; boost::optional recipient () const; + boost::optional recipient_file () const; std::vector trusted_devices () { return _trusted_devices; } @@ -64,6 +66,7 @@ private: wxTextCtrl* _name; wxTextCtrl* _notes; wxStaticText* _recipient_thumbprint; + wxStaticText* _recipient_file; wxButton* _get_recipient_from_file; wxButton* _download_recipient; EditableList* _trusted_device_list; diff --git a/src/wx/screens_panel.cc b/src/wx/screens_panel.cc index 8d631ce90..3c8d51931 100644 --- a/src/wx/screens_panel.cc +++ b/src/wx/screens_panel.cc @@ -261,7 +261,7 @@ ScreensPanel::add_screen_clicked () } } - auto s = std::make_shared(d->name(), d->notes(), d->recipient(), d->trusted_devices()); + auto s = std::make_shared(d->name(), d->notes(), d->recipient(), d->recipient_file(), d->trusted_devices()); c->add_screen (s); auto id = add_screen (c, s); if (id) { @@ -283,7 +283,7 @@ ScreensPanel::edit_screen_clicked () auto s = *_selected_screens.begin(); - auto d = new ScreenDialog (GetParent(), _("Edit screen"), s.second->name, s.second->notes, s.second->recipient, s.second->trusted_devices); + auto d = new ScreenDialog (GetParent(), _("Edit screen"), s.second->name, s.second->notes, s.second->recipient, s.second->recipient_file, s.second->trusted_devices); if (d->ShowModal() != wxID_OK) { d->Destroy (); return; @@ -306,6 +306,7 @@ ScreensPanel::edit_screen_clicked () s.second->name = d->name (); s.second->notes = d->notes (); s.second->recipient = d->recipient (); + s.second->recipient_file = d->recipient_file (); s.second->trusted_devices = d->trusted_devices (); _targets->SetItemText (s.first, std_to_wx (d->name())); Config::instance()->changed (Config::CINEMAS); diff --git a/test/kdm_naming_test.cc b/test/kdm_naming_test.cc index 4e1f81b1c..c41d5c315 100644 --- a/test/kdm_naming_test.cc +++ b/test/kdm_naming_test.cc @@ -61,19 +61,19 @@ BOOST_AUTO_TEST_CASE (single_kdm_naming_test) /* Cinema A: UTC +4:30 */ auto cinema_a = make_shared("Cinema A", list(), "", 4, 30); - cinema_a_screen_1 = make_shared("Screen 1", "", crypt_cert, vector()); + cinema_a_screen_1 = std::make_shared("Screen 1", "", crypt_cert, boost::none, vector()); cinema_a->add_screen (cinema_a_screen_1); - cinema_a_screen_2 = make_shared("Screen 2", "", crypt_cert, vector()); + cinema_a_screen_2 = std::make_shared("Screen 2", "", crypt_cert, boost::none, vector()); cinema_a->add_screen (cinema_a_screen_2); c->add_cinema (cinema_a); /* Cinema B: UTC -1:00 */ auto cinema_b = make_shared("Cinema B", list(), "", -1, 0); - cinema_b_screen_x = make_shared("Screen X", "", crypt_cert, vector()); + cinema_b_screen_x = std::make_shared("Screen X", "", crypt_cert, boost::none, vector()); cinema_b->add_screen (cinema_b_screen_x); - cinema_b_screen_y = make_shared("Screen Y", "", crypt_cert, vector()); + cinema_b_screen_y = std::make_shared("Screen Y", "", crypt_cert, boost::none, vector()); cinema_b->add_screen (cinema_b_screen_y); - cinema_b_screen_z = make_shared("Screen Z", "", crypt_cert, vector()); + cinema_b_screen_z = std::make_shared("Screen Z", "", crypt_cert, boost::none, vector()); cinema_b->add_screen (cinema_b_screen_z); c->add_cinema (cinema_a);