From e075012124424b77044b5d61885ed2646d3781cd Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 28 Mar 2019 23:10:56 +0000 Subject: [PATCH] Allow explicit specification of email protocol (plain/STARTTLS/SSL). --- src/lib/cinema_kdms.cc | 2 +- src/lib/config.cc | 35 ++++++++++++++++++-- src/lib/config.h | 15 +++++++-- src/lib/emailer.cc | 16 ++++++---- src/lib/emailer.h | 4 +-- src/lib/ffmpeg_subtitle_stream.h | 1 + src/lib/player_video.h | 1 + src/lib/send_notification_email_job.cc | 2 +- src/lib/send_problem_report_job.cc | 2 +- src/lib/types.h | 13 ++++++-- src/lib/upload_job.cc | 6 ++-- src/tools/dcpomatic.cc | 2 +- src/wx/full_config_dialog.cc | 44 +++++++++++++++++++++++++- 13 files changed, 118 insertions(+), 25 deletions(-) diff --git a/src/lib/cinema_kdms.cc b/src/lib/cinema_kdms.cc index 558aee504..7952b7ab2 100644 --- a/src/lib/cinema_kdms.cc +++ b/src/lib/cinema_kdms.cc @@ -249,7 +249,7 @@ CinemaKDMs::email ( Config* c = Config::instance (); try { - email.send (c->mail_server(), c->mail_port(), c->mail_user(), c->mail_password()); + email.send (c->mail_server(), c->mail_port(), c->mail_protocol(), c->mail_user(), c->mail_password()); } catch (...) { boost::filesystem::remove (zip_file); dcpomatic_log->log ("Email content follows", LogEntry::TYPE_DEBUG_EMAIL); diff --git a/src/lib/config.cc b/src/lib/config.cc index b742756b7..c71f3acd3 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -89,7 +89,7 @@ Config::set_defaults () _use_any_servers = true; _servers.clear (); _only_servers_encode = false; - _tms_protocol = PROTOCOL_SCP; + _tms_protocol = FILE_TRANSFER_PROTOCOL_SCP; _tms_ip = ""; _tms_path = "."; _tms_user = ""; @@ -109,6 +109,7 @@ Config::set_defaults () _default_upload_after_make_dcp = false; _mail_server = ""; _mail_port = 25; + _mail_protocol = EMAIL_PROTOCOL_AUTO; _mail_user = ""; _mail_password = ""; _kdm_from = ""; @@ -286,7 +287,7 @@ try } _only_servers_encode = f.optional_bool_child ("OnlyServersEncode").get_value_or (false); - _tms_protocol = static_cast (f.optional_number_child ("TMSProtocol").get_value_or (static_cast (PROTOCOL_SCP))); + _tms_protocol = static_cast(f.optional_number_child("TMSProtocol").get_value_or(static_cast(FILE_TRANSFER_PROTOCOL_SCP))); _tms_ip = f.string_child ("TMSIP"); _tms_path = f.string_child ("TMSPath"); _tms_user = f.string_child ("TMSUser"); @@ -348,6 +349,21 @@ try _mail_server = f.string_child ("MailServer"); _mail_port = f.optional_number_child ("MailPort").get_value_or (25); + + { + /* Make sure this matches the code in write_config */ + string const protocol = f.optional_string_child("MailProtocol").get_value_or("Auto"); + if (protocol == "Auto") { + _mail_protocol = EMAIL_PROTOCOL_AUTO; + } else if (protocol == "Plain") { + _mail_protocol = EMAIL_PROTOCOL_PLAIN; + } else if (protocol == "STARTTLS") { + _mail_protocol = EMAIL_PROTOCOL_STARTTLS; + } else if (protocol == "SSL") { + _mail_protocol = EMAIL_PROTOCOL_SSL; + } + } + _mail_user = f.optional_string_child("MailUser").get_value_or (""); _mail_password = f.optional_string_child("MailPassword").get_value_or (""); @@ -747,6 +763,21 @@ Config::write_config () const root->add_child("MailServer")->add_child_text (_mail_server); /* [XML] MailPort Port number to use on SMTP server. */ root->add_child("MailPort")->add_child_text (raw_convert (_mail_port)); + /* [XML] MailProtocol Protocol to use on SMTP server (Auto, Plain, STARTTLS or SSL) */ + switch (_mail_protocol) { + case EMAIL_PROTOCOL_AUTO: + root->add_child("MailProtocol")->add_child_text("Auto"); + break; + case EMAIL_PROTOCOL_PLAIN: + root->add_child("MailProtocol")->add_child_text("Plain"); + break; + case EMAIL_PROTOCOL_STARTTLS: + root->add_child("MailProtocol")->add_child_text("STARTTLS"); + break; + case EMAIL_PROTOCOL_SSL: + root->add_child("MailProtocol")->add_child_text("SSL"); + break; + } /* [XML] MailUser Username to use on SMTP server. */ root->add_child("MailUser")->add_child_text (_mail_user); /* [XML] MailPassword Password to use on SMTP server. */ diff --git a/src/lib/config.h b/src/lib/config.h index 7d21964a4..a982c9727 100644 --- a/src/lib/config.h +++ b/src/lib/config.h @@ -116,7 +116,7 @@ public: return _only_servers_encode; } - Protocol tms_protocol () const { + FileTransferProtocol tms_protocol () const { return _tms_protocol; } @@ -229,6 +229,10 @@ public: return _mail_port; } + EmailProtocol mail_protocol () const { + return _mail_protocol; + } + std::string mail_user () const { return _mail_user; } @@ -563,7 +567,7 @@ public: maybe_set (_only_servers_encode, o); } - void set_tms_protocol (Protocol p) { + void set_tms_protocol (FileTransferProtocol p) { maybe_set (_tms_protocol, p); } @@ -682,6 +686,10 @@ public: maybe_set (_mail_port, p); } + void set_mail_protocol (EmailProtocol p) { + maybe_set (_mail_protocol, p); + } + void set_mail_user (std::string u) { maybe_set (_mail_user, u); } @@ -1138,7 +1146,7 @@ private: /** J2K encoding servers that should definitely be used */ std::vector _servers; bool _only_servers_encode; - Protocol _tms_protocol; + FileTransferProtocol _tms_protocol; /** The IP address of a TMS that we can copy DCPs to */ std::string _tms_ip; /** The path on a TMS that we should write DCPs to */ @@ -1180,6 +1188,7 @@ private: std::list > _cinemas; std::string _mail_server; int _mail_port; + EmailProtocol _mail_protocol; std::string _mail_user; std::string _mail_password; std::string _kdm_subject; diff --git a/src/lib/emailer.cc b/src/lib/emailer.cc index 57b06ed61..dc216e90c 100644 --- a/src/lib/emailer.cc +++ b/src/lib/emailer.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2015 Carl Hetherington + Copyright (C) 2015-2019 Carl Hetherington This file is part of DCP-o-matic. @@ -99,7 +99,7 @@ Emailer::get_data (void* ptr, size_t size, size_t nmemb) } void -Emailer::send (string server, int port, string user, string password) +Emailer::send (string server, int port, EmailProtocol protocol, string user, string password) { char date_buffer[128]; time_t now = time (0); @@ -177,11 +177,11 @@ Emailer::send (string server, int port, string user, string password) throw NetworkError ("Could not initialise libcurl"); } - if (port == 465) { - /* "Implicit TLS"; I think curl wants us to use smtps here */ - curl_easy_setopt (curl, CURLOPT_URL, String::compose ("smtps://%1:465", server).c_str()); + if ((protocol == EMAIL_PROTOCOL_AUTO && port == 465) || protocol == EMAIL_PROTOCOL_SSL) { + /* "SSL" or "Implicit TLS"; I think curl wants us to use smtps here */ + curl_easy_setopt (curl, CURLOPT_URL, String::compose("smtps://%1:%2", server, port).c_str()); } else { - curl_easy_setopt (curl, CURLOPT_URL, String::compose ("smtp://%1:%2", server, port).c_str()); + curl_easy_setopt (curl, CURLOPT_URL, String::compose("smtp://%1:%2", server, port).c_str()); } if (!user.empty ()) { @@ -210,7 +210,9 @@ Emailer::send (string server, int port, string user, string password) curl_easy_setopt (curl, CURLOPT_READDATA, this); curl_easy_setopt (curl, CURLOPT_UPLOAD, 1L); - curl_easy_setopt (curl, CURLOPT_USE_SSL, (long) CURLUSESSL_TRY); + if (protocol == EMAIL_PROTOCOL_AUTO || protocol == EMAIL_PROTOCOL_STARTTLS) { + curl_easy_setopt (curl, CURLOPT_USE_SSL, (long) CURLUSESSL_TRY); + } curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, 0L); curl_easy_setopt (curl, CURLOPT_VERBOSE, 1L); diff --git a/src/lib/emailer.h b/src/lib/emailer.h index 0309b134d..4ceedb9be 100644 --- a/src/lib/emailer.h +++ b/src/lib/emailer.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2015 Carl Hetherington + Copyright (C) 2015-2019 Carl Hetherington This file is part of DCP-o-matic. @@ -30,7 +30,7 @@ public: void add_bcc (std::string bcc); void add_attachment (boost::filesystem::path file, std::string name, std::string mime_type); - void send (std::string server, int port, std::string user = "", std::string password = ""); + void send (std::string server, int port, EmailProtocol protocol, std::string user = "", std::string password = ""); std::string notes () const { return _notes; diff --git a/src/lib/ffmpeg_subtitle_stream.h b/src/lib/ffmpeg_subtitle_stream.h index 85c4df889..5d5048b10 100644 --- a/src/lib/ffmpeg_subtitle_stream.h +++ b/src/lib/ffmpeg_subtitle_stream.h @@ -21,6 +21,7 @@ #include "dcpomatic_time.h" #include "rgba.h" #include "ffmpeg_stream.h" +#include #include class FFmpegSubtitleStream : public FFmpegStream diff --git a/src/lib/player_video.h b/src/lib/player_video.h index 6275c5113..928dfc690 100644 --- a/src/lib/player_video.h +++ b/src/lib/player_video.h @@ -31,6 +31,7 @@ extern "C" { } #include #include +#include class Image; class ImageProxy; diff --git a/src/lib/send_notification_email_job.cc b/src/lib/send_notification_email_job.cc index 6d7882e71..abbb844e2 100644 --- a/src/lib/send_notification_email_job.cc +++ b/src/lib/send_notification_email_job.cc @@ -72,7 +72,7 @@ SendNotificationEmailJob::run () email.add_bcc (config->notification_bcc ()); } - email.send (config->mail_server(), config->mail_port(), config->mail_user(), config->mail_password()); + email.send (config->mail_server(), config->mail_port(), config->mail_protocol(), config->mail_user(), config->mail_password()); set_progress (1); set_state (FINISHED_OK); diff --git a/src/lib/send_problem_report_job.cc b/src/lib/send_problem_report_job.cc index aac2b6e66..11f700de0 100644 --- a/src/lib/send_problem_report_job.cc +++ b/src/lib/send_problem_report_job.cc @@ -101,7 +101,7 @@ SendProblemReportJob::run () to.push_back ("carl@dcpomatic.com"); Emailer emailer (_from, to, "DCP-o-matic problem report", body); - emailer.send ("main.carlh.net", 2525); + emailer.send ("main.carlh.net", 2525, EMAIL_PROTOCOL_STARTTLS); set_progress (1); set_state (FINISHED_OK); diff --git a/src/lib/types.h b/src/lib/types.h index 14840d5a6..94e101a3d 100644 --- a/src/lib/types.h +++ b/src/lib/types.h @@ -236,9 +236,16 @@ enum Resolution { std::string resolution_to_string (Resolution); Resolution string_to_resolution (std::string); -enum Protocol { - PROTOCOL_SCP, - PROTOCOL_FTP +enum FileTransferProtocol { + FILE_TRANSFER_PROTOCOL_SCP, + FILE_TRANSFER_PROTOCOL_FTP +}; + +enum EmailProtocol { + EMAIL_PROTOCOL_AUTO, + EMAIL_PROTOCOL_PLAIN, + EMAIL_PROTOCOL_STARTTLS, + EMAIL_PROTOCOL_SSL }; #endif diff --git a/src/lib/upload_job.cc b/src/lib/upload_job.cc index cbcb8dfc6..b229fddbe 100644 --- a/src/lib/upload_job.cc +++ b/src/lib/upload_job.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2015 Carl Hetherington + Copyright (C) 2012-2019 Carl Hetherington This file is part of DCP-o-matic. @@ -65,10 +65,10 @@ UploadJob::run () scoped_ptr uploader; switch (Config::instance()->tms_protocol ()) { - case PROTOCOL_SCP: + case FILE_TRANSFER_PROTOCOL_SCP: uploader.reset (new SCPUploader (bind (&UploadJob::set_status, this, _1), bind (&UploadJob::set_progress, this, _1, false))); break; - case PROTOCOL_FTP: + case FILE_TRANSFER_PROTOCOL_FTP: uploader.reset (new CurlUploader (bind (&UploadJob::set_status, this, _1), bind (&UploadJob::set_progress, this, _1, false))); break; } diff --git a/src/tools/dcpomatic.cc b/src/tools/dcpomatic.cc index dcf6d7f49..1b46e2292 100644 --- a/src/tools/dcpomatic.cc +++ b/src/tools/dcpomatic.cc @@ -1031,7 +1031,7 @@ private: list to; to.push_back ("carl@dcpomatic.com"); Emailer emailer (d->email(), to, "DCP-o-matic translations", body); - emailer.send ("main.carlh.net", 2525); + emailer.send ("main.carlh.net", 2525, EMAIL_PROTOCOL_STARTTLS); } d->Destroy (); diff --git a/src/wx/full_config_dialog.cc b/src/wx/full_config_dialog.cc index 3d6a11864..e6147c3ea 100644 --- a/src/wx/full_config_dialog.cc +++ b/src/wx/full_config_dialog.cc @@ -695,7 +695,7 @@ private: void tms_protocol_changed () { - Config::instance()->set_tms_protocol (static_cast (_tms_protocol->GetSelection ())); + Config::instance()->set_tms_protocol(static_cast(_tms_protocol->GetSelection())); } void tms_ip_changed () @@ -766,6 +766,14 @@ private: _port = new wxSpinCtrl (_panel, wxID_ANY); _port->SetRange (0, 65535); s->Add (_port); + add_label_to_sizer (s, _panel, _("protocol"), false); + _protocol = new wxChoice (_panel, wxID_ANY); + /* Make sure this matches the switches in config_changed and port_changed below */ + _protocol->Append (_("Auto")); + _protocol->Append (_("Plain")); + _protocol->Append (_("STARTTLS")); + _protocol->Append (_("SSL")); + s->Add (_protocol); table->Add (s, 1, wxEXPAND | wxALL); } @@ -779,6 +787,7 @@ private: _server->Bind (wxEVT_TEXT, boost::bind (&EmailPage::server_changed, this)); _port->Bind (wxEVT_SPINCTRL, boost::bind (&EmailPage::port_changed, this)); + _protocol->Bind (wxEVT_CHOICE, boost::bind (&EmailPage::protocol_changed, this)); _user->Bind (wxEVT_TEXT, boost::bind (&EmailPage::user_changed, this)); _password->Bind (wxEVT_TEXT, boost::bind (&EmailPage::password_changed, this)); } @@ -789,6 +798,20 @@ private: checked_set (_server, config->mail_server ()); checked_set (_port, config->mail_port ()); + switch (config->mail_protocol()) { + case EMAIL_PROTOCOL_AUTO: + checked_set (_protocol, 0); + break; + case EMAIL_PROTOCOL_PLAIN: + checked_set (_protocol, 1); + break; + case EMAIL_PROTOCOL_STARTTLS: + checked_set (_protocol, 2); + break; + case EMAIL_PROTOCOL_SSL: + checked_set (_protocol, 3); + break; + } checked_set (_user, config->mail_user ()); checked_set (_password, config->mail_password ()); } @@ -803,6 +826,24 @@ private: Config::instance()->set_mail_port (_port->GetValue ()); } + void protocol_changed () + { + switch (_protocol->GetSelection()) { + case 0: + Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_AUTO); + break; + case 1: + Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_PLAIN); + break; + case 2: + Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_STARTTLS); + break; + case 3: + Config::instance()->set_mail_protocol(EMAIL_PROTOCOL_SSL); + break; + } + } + void user_changed () { Config::instance()->set_mail_user (wx_to_std (_user->GetValue ())); @@ -815,6 +856,7 @@ private: wxTextCtrl* _server; wxSpinCtrl* _port; + wxChoice* _protocol; wxTextCtrl* _user; wxTextCtrl* _password; }; -- 2.30.2