01/11/2012 11:35 PM, intrigeri:
>
> anonym wrote (11 Jan 2012 20:54:21 GMT) :
>
>> 2. Fetch configuration from email service provider: Disabled when
>> ssl_only == true.
>
>> It would be easy to make it try https first, and then fallback to http
>> only if ssl_only == false, but a comment in the code makes me unsure if
>> I want to do so:
>
>>> To support domain hosters, we cannot use SSL. That means we
>>> rely on insecure DNS and http, which means the results may be
>>> forged when under attack. The same is true for guessConfig(), >though.
>
>> Any one that understands the issue?
>
> I don't think there's anything more to understand than "they're aware
> than fetching over HTTP is deeply insecure, they even know some
> reasons why it's insecure, but they do it nevertheless because most
> crappy ISP's don't bother to serve their autoconfig file over HTTPS".
Ok... it just seems weird they didn't implement this from the beginning
(OTOH, that code was a complete mess... I refactored it to a sane state).
> I think the change you're hesitating to make would be consistent with
> the way ssl_only works.
Right, implemented (PATCH 4/6)
>> Issues I'd like input on:
>
>> * ssl_only really does two separate things:
>
>> 1. It forces SSL for *fetching* configs.
>> 2. It forces SSL or STARTTLS in the *resulting* configuration when
>> *guessing* the config.
>
>> Is this confusing?
>
> Anything else would look strongly inconsistent to me, at least in the
> threat model I think we're considering. So I don't find it confusing.
>
> OTOH, I don't understand what exactly "*resulting*" means above, so
> I may very well be entirely confused wrt. how ssl_only behaves in
> GuessConfig city.
With resulting I just meant the fetched config after it has been parsed.
>> * ssl_only does not check whether any fetched config (like in step
>> 1 and 3) uses plaintext smtp, pop or imap. Do we want this?
>> I wouldn't ask if it was a trivial change, but this code is
>> a complete mess and would need a complete reorganization for this
>> feature. It would make the above point less confusing. But can we
>> live without it?
>
> If things are kept as is, it seems to me ssl_only makes things more
> secure *only* for a given user if her email provider:
>
> - serves the email protocols over SSL;
> - does not serve an autoconfig file pointing her MUA to non-SSL.
>
> I'm not sure how we can possibly help other users: suddenly denying
> them access to their email does not look that appalling to me.
>
> OTOH, I would find it great if we could make it clear to them what
> risk they are taking. How hard would it be to implement this? (This
> would be a low-priority enhancement: I don't think our current Claws
> Mail setup has anything to say against SSL.)
Turned out to be easier than I initially thought (thanks, exceptions!).
> In any case, the current situation makes the "Only use secure
> protocols" checkbox a wrong statement, isn't it?
You're right. Implemented (PATCH 6/6).
Unless I've missed something my work here is done, see attached patches.
Well there is one more issue: if the email provider's http server that
serves the config is using a self-signed certificate (like my test
server), the user just gets an error prompt with no chance to manually
verify it and accept it. Hmm. We'll see if I care about looking into
this. Anyone think it's really important?
Since we have no icedove repo to push to I post my current work here in
case my primary hard drive + backup drive would fail :). Also, perhaps
someone with more javascript skills than me could spot some bug I've
missed (?). The patches are against commit aab48e6 in the Debian Mozilla
team's git repo:
http://anonscm.debian.org/gitweb/?p=pkg-mozilla/icedove.git
Cheers!
From 0651e1f6e2c4f76fc444969f7fc6600670b302da Mon Sep 17 00:00:00 2001
From: Tails developers <amnesia@???>
Date: Wed, 4 Jan 2012 14:48:02 +0100
Subject: [PATCH 1/6] Optionally skip probing for plaintext protocols.
Setting mailnews.auto_config_ssl_only to True prevents detecting
plaintext protocols through autoconfiguration during account creation.
---
.../prefs/content/accountcreation/guessConfig.js | 68 +++++++++++++-------
1 files changed, 44 insertions(+), 24 deletions(-)
diff --git a/mailnews/base/prefs/content/accountcreation/guessConfig.js b/mailnews/base/prefs/content/accountcreation/guessConfig.js
index 02acf3c..a183ad3 100644
--- a/mailnews/base/prefs/content/accountcreation/guessConfig.js
+++ b/mailnews/base/prefs/content/accountcreation/guessConfig.js
@@ -802,22 +802,32 @@ function getIncomingTryOrder(host, protocol, ssl, port)
else if (protocol == UNKNOWN && !lowerCaseHost.indexOf("imap."))
protocol = IMAP;
+ var prefs = Cc["@mozilla.org/preferences-service;1"]
+ .getService(Ci.nsIPrefBranch);
+ var ssl_only = prefs.getBoolPref("mailnews.auto_config_ssl_only");
+
if (protocol != UNKNOWN) {
- if (ssl == UNKNOWN)
- return [getHostEntry(protocol, TLS, port),
- getHostEntry(protocol, SSL, port),
- getHostEntry(protocol, NONE, port)];
- return [getHostEntry(protocol, ssl, port)];
- }
- if (ssl == UNKNOWN)
- return [getHostEntry(IMAP, TLS, port),
- getHostEntry(IMAP, SSL, port),
- getHostEntry(POP, TLS, port),
- getHostEntry(POP, SSL, port),
- getHostEntry(IMAP, NONE, port),
- getHostEntry(POP, NONE, port)];
- return [getHostEntry(IMAP, ssl, port),
- getHostEntry(POP, ssl, port)];
+ if (ssl == UNKNOWN) {
+ var order = [getHostEntry(protocol, TLS, port),
+ getHostEntry(protocol, SSL, port)];
+ if (!ssl_only)
+ order.push(getHostEntry(protocol, NONE, port));
+ return order;
+ } else {
+ return [getHostEntry(protocol, ssl, port)];
+ }
+ } else if (ssl == UNKNOWN) {
+ var order = [getHostEntry(IMAP, TLS, port),
+ getHostEntry(IMAP, SSL, port),
+ getHostEntry(POP, TLS, port),
+ getHostEntry(POP, SSL, port)];
+ if (!ssl_only)
+ order.push(getHostEntry(IMAP, NONE, port),
+ getHostEntry(POP, NONE, port));
+ return order;
+ } else
+ return [getHostEntry(IMAP, ssl, port),
+ getHostEntry(POP, ssl, port)];
};
/**
@@ -826,19 +836,29 @@ function getIncomingTryOrder(host, protocol, ssl, port)
function getOutgoingTryOrder(host, protocol, ssl, port)
{
assert(protocol == SMTP, "need SMTP as protocol for outgoing");
+ var prefs = Cc["@mozilla.org/preferences-service;1"]
+ .getService(Ci.nsIPrefBranch);
+ var ssl_only = prefs.getBoolPref("mailnews.auto_config_ssl_only");
+
if (ssl == UNKNOWN)
{
- if (port == UNKNOWN)
+ if (port == UNKNOWN) {
// neither SSL nor port known
- return [getHostEntry(SMTP, TLS, UNKNOWN),
- getHostEntry(SMTP, TLS, 25),
- getHostEntry(SMTP, SSL, UNKNOWN),
- getHostEntry(SMTP, NONE, UNKNOWN),
- getHostEntry(SMTP, NONE, 25)];
+ var order = [getHostEntry(SMTP, TLS, UNKNOWN),
+ getHostEntry(SMTP, TLS, 25),
+ getHostEntry(SMTP, SSL, UNKNOWN)];
+ if (!ssl_only)
+ order.push(getHostEntry(SMTP, NONE, UNKNOWN),
+ getHostEntry(SMTP, NONE, 25));
+ return order;
+ } else {
// port known, SSL not
- return [getHostEntry(SMTP, TLS, port),
- getHostEntry(SMTP, SSL, port),
- getHostEntry(SMTP, NONE, port)];
+ var order = [getHostEntry(SMTP, TLS, port),
+ getHostEntry(SMTP, SSL, port)];
+ if (!ssl_only)
+ order.push(getHostEntry(SMTP, NONE, port));
+ return order;
+ }
}
// SSL known, port not
if (port == UNKNOWN)
--
1.7.7.3
From 1de630482dadcef4ae5c751e152abdc05660f0a8 Mon Sep 17 00:00:00 2001
From: Tails developers <amnesia@???>
Date: Wed, 4 Jan 2012 14:51:21 +0100
Subject: [PATCH 2/6] Optionally skip insecure database autoconfiguration
lookup.
Setting mailnews.auto_config_ssl_only to True makes autoconfiguration
skip database lookup during autoconfiguration if
mailnews.auto_config_url isn't HTTPS.
---
.../prefs/content/accountcreation/fetchConfig.js | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/mailnews/base/prefs/content/accountcreation/fetchConfig.js b/mailnews/base/prefs/content/accountcreation/fetchConfig.js
index c4c43e9..5026892 100644
--- a/mailnews/base/prefs/content/accountcreation/fetchConfig.js
+++ b/mailnews/base/prefs/content/accountcreation/fetchConfig.js
@@ -142,6 +142,12 @@ function fetchConfigFromDB(domain, successCallback, errorCallback)
let pref = Cc["@mozilla.org/preferences-service;1"]
.getService(Ci.nsIPrefBranch);
let url = pref.getCharPref("mailnews.auto_config_url");
+ if (pref.getBoolPref("mailnews.auto_config_ssl_only") &&
+ url.indexOf("https://") != 0) {
+ errorCallback("Skipping insecure autoconfiguration method: " +
+ "non-SSL HTTP database lookup");
+ return;
+ }
domain = sanitize.hostname(domain);
// If we don't specify a place to put the domain, put it at the end.
--
1.7.7.3
From 00abc97618060972e29c31b4ffa4a75b8ef087e8 Mon Sep 17 00:00:00 2001
From: Tails developers <amnesia@???>
Date: Wed, 4 Jan 2012 14:59:54 +0100
Subject: [PATCH 3/6] Optionally skip insecure DNS MX autoconfiguration
lookup.
Setting mailnews.auto_config_ssl_only to True makes autoconfiguration
skip DNS MX lookup during autoconfiguration.
---
.../prefs/content/accountcreation/fetchConfig.js | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/mailnews/base/prefs/content/accountcreation/fetchConfig.js b/mailnews/base/prefs/content/accountcreation/fetchConfig.js
index 5026892..daa508b 100644
--- a/mailnews/base/prefs/content/accountcreation/fetchConfig.js
+++ b/mailnews/base/prefs/content/accountcreation/fetchConfig.js
@@ -194,6 +194,15 @@ function fetchConfigFromDB(domain, successCallback, errorCallback)
*/
function fetchConfigForMX(domain, successCallback, errorCallback)
{
+ var prefs = Cc["@mozilla.org/preferences-service;1"]
+ .getService(Ci.nsIPrefBranch);
+ if (prefs.getBoolPref("mailnews.auto_config_ssl_only")) {
+ // XXX We may not have to skip this method if we're using DNSSEC
+ errorCallback("Skipping insecure autoconfiguration method: " +
+ "DNS MX lookup");
+ return;
+ }
+
domain = sanitize.hostname(domain);
var sucAbortable = new SuccessiveAbortable();
--
1.7.7.3
From 8e8ae6cc51055edad7b104c309869e2d1a56389f Mon Sep 17 00:00:00 2001
From: Tails developers <amnesia@???>
Date: Tue, 10 Jan 2012 20:49:20 +0100
Subject: [PATCH 4/6] Make ISP autoconfiguration lookup first try https, then
http.
Setting mailnews.auto_config_ssl_only to True makes autoconfiguration
use only https for ISP lookup.
---
.../prefs/content/accountcreation/fetchConfig.js | 74 ++++++++++---------
1 files changed, 39 insertions(+), 35 deletions(-)
diff --git a/mailnews/base/prefs/content/accountcreation/fetchConfig.js b/mailnews/base/prefs/content/accountcreation/fetchConfig.js
index daa508b..a064ef5 100644
--- a/mailnews/base/prefs/content/accountcreation/fetchConfig.js
+++ b/mailnews/base/prefs/content/accountcreation/fetchConfig.js
@@ -85,49 +85,53 @@ function fetchConfigFromDisk(domain, successCallback, errorCallback)
function fetchConfigFromISP(domain, emailAddress, successCallback,
errorCallback)
{
- let url1 = "http://autoconfig." + sanitize.hostname(domain) +
- "/mail/config-v1.1.xml";
+ let conf1 = "autoconfig." + sanitize.hostname(domain) +
+ "/mail/config-v1.1.xml";
// .well-known/ <http://tools.ietf.org/html/draft-nottingham-site-meta-04>
- let url2 = "http://" + sanitize.hostname(domain) +
- "/.well-known/autoconfig/mail/config-v1.1.xml";
+ let conf2 = sanitize.hostname(domain) +
+ "/.well-known/autoconfig/mail/config-v1.1.xml";
+ let url0 = "https://" + conf1;
+ let url1 = "https://" + conf2;
+ let url2 = "http://" + conf1;
+ let url3 = "http://" + conf2;
+ let prefs = Cc["@mozilla.org/preferences-service;1"]
+ .getService(Ci.nsIPrefBranch);
+ if (prefs.getBoolPref("mailnews.auto_config_ssl_only")) {
+ var urls = [url0, url1];
+ } else {
+ var urls = [url0, url1, url2, url3];
+ }
let sucAbortable = new SuccessiveAbortable();
- var time = Date.now();
- let fetch1 = new FetchHTTP(
- url1, { emailaddress: emailAddress }, false,
- function(result)
+ let time;
+
+ let success = function(result)
{
successCallback(readFromXML(result));
- },
- function(e1) // fetch1 failed
+ };
+
+ let error = function(i, e)
{
- ddump("fetchisp 1 <" + url1 + "> took " + (Date.now() - time) +
- "ms and failed with " + e1);
- time = Date.now();
- if (e1 instanceof CancelledException)
- {
- errorCallback(e1);
+ ddump("fetchisp " + i + " <" + urls[i] + "> took " +
+ (Date.now() - time) + "ms and failed with " + e);
+
+ if (i == urls.length - 1 || // implies all fetches failed
+ e instanceof CancelledException) {
+ errorCallback(e);
return;
}
+ let fetch = new FetchHTTP(urls[i + 1], { emailaddress: emailAddress },
+ false, success,
+ function(e) { error(i + 1, e) });
+ sucAbortable.current = fetch;
+ time = Date.now();
+ fetch.start();
+ };
- let fetch2 = new FetchHTTP(
- url2, { emailaddress: emailAddress }, false,
- function(result)
- {
- successCallback(readFromXML(result));
- },
- function(e2)
- {
- ddump("fetchisp 2 <" + url2 + "> took " + (Date.now() - time) +
- "ms and failed with " + e2);
- // return the error for the primary call,
- // unless the fetch was cancelled
- errorCallback(e2 instanceof CancelledException ? e2 : e1);
- });
- sucAbortable.current = fetch2;
- fetch2.start();
- });
- sucAbortable.current = fetch1;
- fetch1.start();
+ let fetch = new FetchHTTP(urls[0], { emailaddress: emailAddress }, false,
+ success, function(e) { error(0, e) });
+ sucAbortable.current = fetch;
+ time = Date.now();
+ fetch.start();
return sucAbortable;
}
--
1.7.7.3
From 8d0c3c29dbc2cbf4fbda8d2829737ada33fa6e70 Mon Sep 17 00:00:00 2001
From: Tails developers <amnesia@???>
Date: Wed, 11 Jan 2012 15:09:57 +0100
Subject: [PATCH 5/6] Add checkbox for toggling mailnews.auto_config_ssl_only.
---
.../en-US/chrome/messenger/accountCreation.dtd | 2 ++
.../prefs/content/accountcreation/emailWizard.js | 14 ++++++++++++++
.../prefs/content/accountcreation/emailWizard.xul | 7 +++++++
3 files changed, 23 insertions(+), 0 deletions(-)
diff --git a/mail/locales/en-US/chrome/messenger/accountCreation.dtd b/mail/locales/en-US/chrome/messenger/accountCreation.dtd
index 21693e5..a2849d8 100644
--- a/mail/locales/en-US/chrome/messenger/accountCreation.dtd
+++ b/mail/locales/en-US/chrome/messenger/accountCreation.dtd
@@ -12,6 +12,8 @@
<!ENTITY password.text "Optional, will only be used to validate the username">
<!ENTITY rememberPassword.label "Remember password">
<!ENTITY rememberPassword.accesskey "m">
+<!ENTITY secureProtocols.label "Only use secure protocols">
+<!ENTITY secureProtocols.accesskey "s">
<!ENTITY imapLong.label "IMAP (remote folders)">
<!ENTITY pop3Long.label "POP3 (keep mail on your computer)">
diff --git a/mailnews/base/prefs/content/accountcreation/emailWizard.js b/mailnews/base/prefs/content/accountcreation/emailWizard.js
index 55409d3..ae41c1e 100644
--- a/mailnews/base/prefs/content/accountcreation/emailWizard.js
+++ b/mailnews/base/prefs/content/accountcreation/emailWizard.js
@@ -240,6 +240,9 @@ EmailConfigWizard.prototype =
rememberPasswordE.disabled = true;
}
+ e("only_secure_protocols").checked =
+ Application.prefs.getValue("mailnews.auto_config_ssl_only", false);
+
// First, unhide the main window areas, and store the width,
// so that we don't resize wildly when we unhide areas.
// switchToMode() will then hide the unneeded parts again.
@@ -288,6 +291,7 @@ EmailConfigWizard.prototype =
//_show("initialSettings"); always visible
//_show("cancel_button"); always visible
if (modename == "start") {
+ _show("only_secure_protocols");
_hide("status_area");
_hide("result_area");
_hide("manual-edit_area");
@@ -325,6 +329,7 @@ EmailConfigWizard.prototype =
_show("manual-edit_button");
_hide("advanced-setup_button");
} else if (modename == "manual-edit") {
+ _hide("only_secure_protocols");
_show("status_area");
_hide("result_area");
_show("manual-edit_area");
@@ -339,6 +344,7 @@ EmailConfigWizard.prototype =
_show("advanced-setup_button");
_disable("advanced-setup_button");
} else if (modename == "manual-edit-have-hostname") {
+ _hide("only_secure_protocols");
_show("status_area");
_hide("result_area");
_show("manual-edit_area");
@@ -353,6 +359,7 @@ EmailConfigWizard.prototype =
_show("advanced-setup_button");
_disable("advanced-setup_button");
} else if (modename == "manual-edit-testing") {
+ _hide("only_secure_protocols");
_show("status_area");
_hide("result_area");
_show("manual-edit_area");
@@ -368,6 +375,7 @@ EmailConfigWizard.prototype =
_show("advanced-setup_button");
_disable("advanced-setup_button");
} else if (modename == "manual-edit-complete") {
+ _hide("only_secure_protocols");
_show("status_area");
_hide("result_area");
_show("manual-edit_area");
@@ -529,6 +537,12 @@ EmailConfigWizard.prototype =
e("password").type = "password";
},
+ toggleSecureProtocols : function()
+ {
+ Application.prefs.setValue("mailnews.auto_config_ssl_only",
+ e("only_secure_protocols").checked);
+ },
+
/**
* Check whether the user entered the minimum of information
* needed to leave the "start" mode (entering of name, email, pw)
diff --git a/mailnews/base/prefs/content/accountcreation/emailWizard.xul b/mailnews/base/prefs/content/accountcreation/emailWizard.xul
index 282edc5..8a618e0 100644
--- a/mailnews/base/prefs/content/accountcreation/emailWizard.xul
+++ b/mailnews/base/prefs/content/accountcreation/emailWizard.xul
@@ -214,6 +214,13 @@
accesskey="&rememberPassword.accesskey;"
checked="true"/>
</hbox>
+ <hbox align="center" pack="start">
+ <label class="autoconfigLabel"/>
+ <checkbox id="only_secure_protocols"
+ label="&secureProtocols.label;"
+ accesskey="&secureProtocols.accesskey;"
+ oncommand="gEmailConfigWizard.toggleSecureProtocols();"/>
+ </hbox>
</groupbox>
<spacer flex="1" />
--
1.7.7.3
From cdfe6a543094e172524c50f1766b8a08a22581df Mon Sep 17 00:00:00 2001
From: Tails developers <amnesia@???>
Date: Thu, 12 Jan 2012 15:38:55 +0100
Subject: [PATCH 6/6] Optionally skip fetched configs using plaintext
protocols.
Setting mailnews.auto_config_ssl_only to True completely discards
fetched configurations that are using plaintext protocols during
autoconfiguration.
---
.../prefs/content/accountcreation/readFromXML.js | 21 ++++++++++++++++++-
1 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/mailnews/base/prefs/content/accountcreation/readFromXML.js b/mailnews/base/prefs/content/accountcreation/readFromXML.js
index 5bcf09f..2ac6a3f 100644
--- a/mailnews/base/prefs/content/accountcreation/readFromXML.js
+++ b/mailnews/base/prefs/content/accountcreation/readFromXML.js
@@ -51,6 +51,9 @@
*/
function readFromXML(clientConfigXML)
{
+ var prefs = Cc["@mozilla.org/preferences-service;1"]
+ .getService(Ci.nsIPrefBranch);
+ var ssl_only = prefs.getBoolPref("mailnews.auto_config_ssl_only");
var exception;
if (typeof(clientConfigXML) != "xml" ||
!("emailProvider" in clientConfigXML))
@@ -96,13 +99,20 @@ function readFromXML(clientConfigXML)
try {
iO.socketType = sanitize.translate(iXsocketType,
{ plain : 1, SSL: 2, STARTTLS: 3 });
- break; // take first that we support
+
+ if (iO.socketType != 1) {
+ // pick first non-plaintext protocol, if available
+ break;
+ }
} catch (e) { exception = e; }
}
if (!iO.socketType)
throw exception ? exception : "need proper <socketType> in XML";
exception = null;
+ if (iO.socketType == 1 && ssl_only)
+ continue; // skip this configuration since we force ssl
+
for each (let iXauth in iX.authentication)
{
try {
@@ -170,13 +180,20 @@ function readFromXML(clientConfigXML)
try {
oO.socketType = sanitize.translate(oXsocketType,
{ plain : 1, SSL: 2, STARTTLS: 3 });
- break; // take first that we support
+
+ if (oO.socketType != 1) {
+ // pick first non-plaintext protocol, if available
+ break;
+ }
} catch (e) { exception = e; }
}
if (!oO.socketType)
throw exception ? exception : "need proper <socketType> in XML";
exception = null;
+ if (oO.socketType == 1 && ssl_only)
+ continue; // skip this configuration since we force ssl
+
for each (let oXauth in oX.authentication)
{
try {
--
1.7.7.3