Allow explicit specification of email protocol (plain/STARTTLS/SSL). v2.13.138
authorCarl Hetherington <cth@carlh.net>
Thu, 28 Mar 2019 23:10:56 +0000 (23:10 +0000)
committerCarl Hetherington <cth@carlh.net>
Thu, 28 Mar 2019 23:10:56 +0000 (23:10 +0000)
13 files changed:
src/lib/cinema_kdms.cc
src/lib/config.cc
src/lib/config.h
src/lib/emailer.cc
src/lib/emailer.h
src/lib/ffmpeg_subtitle_stream.h
src/lib/player_video.h
src/lib/send_notification_email_job.cc
src/lib/send_problem_report_job.cc
src/lib/types.h
src/lib/upload_job.cc
src/tools/dcpomatic.cc
src/wx/full_config_dialog.cc

index 558aee504bca2998aee932681b2b04b4cf7047e2..7952b7ab22e3f22e3b75f7bb03ea084791234721 100644 (file)
@@ -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);
index b742756b7eb55197205a85fe6a69acbbdb0cf2ce..c71f3acd3a561f8f728b5f6e2bf15893b2cbe6fc 100644 (file)
@@ -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<Protocol> (f.optional_number_child<int> ("TMSProtocol").get_value_or (static_cast<int> (PROTOCOL_SCP)));
+       _tms_protocol = static_cast<FileTransferProtocol>(f.optional_number_child<int>("TMSProtocol").get_value_or(static_cast<int>(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<int> ("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<string> (_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. */
index 7d21964a42df051125ce084150c3171018a3041d..a982c9727623783a48b0f7cfc5659480c630613e 100644 (file)
@@ -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<std::string> _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<boost::shared_ptr<Cinema> > _cinemas;
        std::string _mail_server;
        int _mail_port;
+       EmailProtocol _mail_protocol;
        std::string _mail_user;
        std::string _mail_password;
        std::string _kdm_subject;
index 57b06ed616663cc05e4b2cecb38a2ad3d9e20567..dc216e90cc087c30d5f553703786f34566e07bc1 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2015-2019 Carl Hetherington <cth@carlh.net>
 
     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);
index 0309b134d17c16fca408fc8daecbb680a4133900..4ceedb9beade87a0426dbf61e9d0deb6ea0d4eeb 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2015-2019 Carl Hetherington <cth@carlh.net>
 
     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;
index 85c4df889bdcf7a88165c28200180fd952c1d851..5d5048b1097ea77c431c4b8f1ca97215b7d5bf8f 100644 (file)
@@ -21,6 +21,7 @@
 #include "dcpomatic_time.h"
 #include "rgba.h"
 #include "ffmpeg_stream.h"
+#include <boost/thread/mutex.hpp>
 #include <map>
 
 class FFmpegSubtitleStream : public FFmpegStream
index 6275c5113c758bf18563e0475e8aaf38fb50fd27..928dfc690a9f3aea0c82fc4334837e5923bd8c2e 100644 (file)
@@ -31,6 +31,7 @@ extern "C" {
 }
 #include <boost/shared_ptr.hpp>
 #include <boost/weak_ptr.hpp>
+#include <boost/thread/mutex.hpp>
 
 class Image;
 class ImageProxy;
index 6d7882e71974a5ec15a3df06d7b10ca0f3a8c93c..abbb844e2f5c2fe6b2a5b72ba3607d94dbd4f7ab 100644 (file)
@@ -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);
index aac2b6e66645cfb8ef5e0520a346adc882b6e7fe..11f700de077490751550913257e8991df05f4d8a 100644 (file)
@@ -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);
index 14840d5a678a1ba9c40d676687c2848501429ad1..94e101a3d682a43127eec28667c54bbe1ffb24bc 100644 (file)
@@ -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
index cbcb8dfc622ce3261175fafec32df5311116ae5e..b229fddbe217f8d5926a4e94633c33103753dee0 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2019 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -65,10 +65,10 @@ UploadJob::run ()
 
        scoped_ptr<Uploader> 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;
        }
index dcf6d7f4909d0f826b369654935197e5170c4f88..1b46e2292298534a2613d0cdb1747de1b76bb58b 100644 (file)
@@ -1031,7 +1031,7 @@ private:
                        list<string> 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 ();
index 3d6a11864e1de709e344ee383d4ea38cd74ceaed..e6147c3eab706dfbfcfc62111362a3c3758c3875 100644 (file)
@@ -695,7 +695,7 @@ private:
 
        void tms_protocol_changed ()
        {
-               Config::instance()->set_tms_protocol (static_cast<Protocol> (_tms_protocol->GetSelection ()));
+               Config::instance()->set_tms_protocol(static_cast<FileTransferProtocol>(_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;
 };