diff --git a/Changelog.md b/Changelog.md
index f998c6af..95ecf0c3 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -4,6 +4,8 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/)
## Unreleased
+## [v1.3.x] Emma (beta since 2020-08-05)
+
### Added
* GODT-633 Persistent anonymous API cookies for better load balancing and abuse detection.
@@ -41,6 +43,7 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/)
## [v1.3.x] Emma (beta 2020-07-XXX)
### Added
+* GODT-554 Detect and notify about "bad certificate" IMAP TLS error.
* IMAP mailbox info update when new mailbox is created.
* GODT-72 Use ISO-8859-1 encoding if charset is not specified and it isn't UTF-8.
@@ -103,6 +106,7 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/)
* GODT-321 Changing address ordering would cause all messages to disappear in combined mode.
* GODT-129 Fix custom message PGP by using template.
* GODT-280 Don't assume contact keys are stored armored.
+* GODT-427 Fix race condition in auth refresh that could cause user to be logged out.
## [v1.2.8] Donghai-fix-append (beta 2020-06-XXX)
diff --git a/Makefile b/Makefile
index 98f23366..c7e43342 100644
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,7 @@ TARGET_OS?=${GOOS}
## Build
.PHONY: build build-nogui check-has-go
-BRIDGE_VERSION?=1.2.7-git
+BRIDGE_VERSION?=$(shell git describe --abbrev=0 --tags)-git
REVISION:=$(shell git rev-parse --short=10 HEAD)
BUILD_TIME:=$(shell date +%FT%T%z)
diff --git a/go.mod b/go.mod
index ad73dc6b..d0e4bfed 100644
--- a/go.mod
+++ b/go.mod
@@ -71,6 +71,7 @@ require (
replace (
github.com/docker/docker-credential-helpers => github.com/ProtonMail/docker-credential-helpers v1.1.0
+ github.com/emersion/go-imap => github.com/jameshoulahan/go-imap v0.0.0-20200728140727-d57327f48843
github.com/emersion/go-smtp => github.com/ProtonMail/go-smtp v0.0.0-20181206232543-8261df20d309
github.com/jameskeane/bcrypt => github.com/ProtonMail/bcrypt v0.0.0-20170924085257-7509ea014998
golang.org/x/crypto => github.com/ProtonMail/crypto v0.0.0-20200416114516-1fa7f403fb9c
diff --git a/go.sum b/go.sum
index 27ca5581..c4bd7bcc 100644
--- a/go.sum
+++ b/go.sum
@@ -49,8 +49,6 @@ github.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7h
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/emersion/go-imap v1.0.6-0.20200708083111-011063d6c9df h1:Vlwnsd5P5s+ek+wzEXbZ/g9tUBndVQAb3E1/+/ya3UQ=
-github.com/emersion/go-imap v1.0.6-0.20200708083111-011063d6c9df/go.mod h1:yKASt+C3ZiDAiCSssxg9caIckWF/JG7ZQTO7GAmvicU=
github.com/emersion/go-imap-appendlimit v0.0.0-20190308131241-25671c986a6a h1:bMdSPm6sssuOFpIaveu3XGAijMS3Tq2S3EqFZmZxidc=
github.com/emersion/go-imap-appendlimit v0.0.0-20190308131241-25671c986a6a/go.mod h1:ikgISoP7pRAolqsVP64yMteJa2FIpS6ju88eBT6K1yQ=
github.com/emersion/go-imap-idle v0.0.0-20200601154248-f05f54664cc4 h1:/JIALzmCduf5o8TWJSiOBzTb9+R0SChwElUrJLlp2po=
@@ -98,6 +96,8 @@ github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/U
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI=
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
+github.com/jameshoulahan/go-imap v0.0.0-20200728140727-d57327f48843 h1:suxlO4AC4E4bjueAsL0m+qp8kmkxRWMGj+5bBU/KJ8g=
+github.com/jameshoulahan/go-imap v0.0.0-20200728140727-d57327f48843/go.mod h1:yKASt+C3ZiDAiCSssxg9caIckWF/JG7ZQTO7GAmvicU=
github.com/jaytaylor/html2text v0.0.0-20190408195923-01ec452cbe43/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk=
github.com/jaytaylor/html2text v0.0.0-20200412013138-3577fbdbcff7 h1:g0fAGBisHaEQ0TRq1iBvemFRf+8AEWEmBESSiWB3Vsc=
github.com/jaytaylor/html2text v0.0.0-20200412013138-3577fbdbcff7/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk=
diff --git a/internal/bridge/release_notes.go b/internal/bridge/release_notes.go
index a5f4e263..c3f9a024 100644
--- a/internal/bridge/release_notes.go
+++ b/internal/bridge/release_notes.go
@@ -15,12 +15,17 @@
// You should have received a copy of the GNU General Public License
// along with ProtonMail Bridge. If not, see .
-// Code generated by ./release-notes.sh at Wed 12 Aug 2020 12:25:26 PM CEST. DO NOT EDIT.
+// Code generated by ./release-notes.sh at Wed 29 Jul 2020 07:07:28 AM CEST. DO NOT EDIT.
package bridge
-const ReleaseNotes = `
+const ReleaseNotes = `• Improvements to Alternative Routing: Version two of this feature is now more resilient to unstable internet connections, which results in a smoother experience using this feature. Also includes fixes to previous implementation of Alternative Routing when first starting the application or when turning it off.
+• Email parsing improvements: Improved detection of email encodings embedded in html/xml in addition to message header; add a fallback option if encoding is not specified and decoding as UTF8 fails (ISO-8859-1) ; tweaked logic of parsing "References" header.
+• User interaction improvements: Some smaller improvements in specific cases to make the interaction with Proton Bridge clearer for the user
+• Code updates & maintenance: Migrated to GopenPGP v2, updates to GoIMAPv1, increased bbolt version to 1.3.5 and various improvements regarding extensibility and maintainability for upcoming work.
+• General stability improvements: Improvements to the behavior of the application under various unstable internet conditions.
`
-const ReleaseFixedBugs = `• Fixed ignored import to Sent folder
+const ReleaseFixedBugs = `• Fixed a slew of smaller bugs and some conditions which could cause the application to crash.
+• The full changelog can be found at https://github.com/ProtonMail/proton-bridge/blob/master/Changelog.md
`
diff --git a/internal/events/events.go b/internal/events/events.go
index 773b61a6..f4c8411c 100644
--- a/internal/events/events.go
+++ b/internal/events/events.go
@@ -40,6 +40,7 @@ const (
NoActiveKeyForRecipientEvent = "noActiveKeyForRecipient"
UpgradeApplicationEvent = "upgradeApplication"
TLSCertIssue = "tlsCertPinningIssue"
+ IMAPTLSBadCert = "imapTLSBadCert"
// LogoutEventTimeout is the minimum time to permit between logout events being sent.
LogoutEventTimeout = 3 * time.Minute
diff --git a/internal/frontend/qml/Gui.qml b/internal/frontend/qml/Gui.qml
index 6e387ad3..82b2743e 100644
--- a/internal/frontend/qml/Gui.qml
+++ b/internal/frontend/qml/Gui.qml
@@ -237,6 +237,14 @@ Item {
winMain.tlsBarState="notOK"
}
+ onShowIMAPCertTroubleshoot : {
+ go.notifyBubble(1, qsTr(
+ "Bridge was unable to establish a connection with your Email client.
Learn more
",
+ "notification message"
+ ))
+ }
+
+
}
Timer {
diff --git a/internal/frontend/qml/tst_Gui.qml b/internal/frontend/qml/tst_Gui.qml
index 5b790aaf..464cad92 100644
--- a/internal/frontend/qml/tst_Gui.qml
+++ b/internal/frontend/qml/tst_Gui.qml
@@ -110,7 +110,7 @@ Window {
ListElement { title: "Internet off" }
ListElement { title: "NeedUpdate" }
ListElement { title: "UpToDate" }
- ListElement { title: "ForceUpdate" }
+ ListElement { title: "ForceUpdate" }
ListElement { title: "Linux" }
ListElement { title: "Windows" }
ListElement { title: "Macos" }
@@ -122,6 +122,7 @@ Window {
ListElement { title: "Minimize this" }
ListElement { title: "SendAlertPopup" }
ListElement { title: "TLSCertError" }
+ ListElement { title: "IMAPCertError" }
}
ListView {
@@ -208,6 +209,9 @@ Window {
case "TLSCertError" :
go.showCertIssue()
break;
+ case "IMAPCertError" :
+ go.showIMAPCertTroubleshoot()
+ break;
default :
console.log("Not implemented " + data)
}
@@ -310,6 +314,7 @@ Window {
signal failedAutostartCode(string code)
signal showCertIssue()
+ signal showIMAPCertTroubleshoot()
signal updateFinished(bool hasError)
diff --git a/internal/frontend/qt/frontend.go b/internal/frontend/qt/frontend.go
index bcf8d439..f4d84d91 100644
--- a/internal/frontend/qt/frontend.go
+++ b/internal/frontend/qt/frontend.go
@@ -188,6 +188,7 @@ func (s *FrontendQt) watchEvents() {
updateApplicationCh := s.getEventChannel(events.UpgradeApplicationEvent)
newUserCh := s.getEventChannel(events.UserRefreshEvent)
certIssue := s.getEventChannel(events.TLSCertIssue)
+ imapCertIssue := s.getEventChannel(events.IMAPTLSBadCert)
for {
select {
case errorDetails := <-errorCh:
@@ -227,6 +228,8 @@ func (s *FrontendQt) watchEvents() {
s.Qml.LoadAccounts()
case <-certIssue:
s.Qml.ShowCertIssue()
+ case <-imapCertIssue:
+ s.Qml.ShowIMAPCertTroubleshoot()
}
}
}
diff --git a/internal/frontend/qt/ui.go b/internal/frontend/qt/ui.go
index 124c1e9a..bd8a0b4e 100644
--- a/internal/frontend/qt/ui.go
+++ b/internal/frontend/qt/ui.go
@@ -135,6 +135,7 @@ type GoQMLInterface struct {
_ func(x, y float32) `slot:"saveOutgoingNoEncPopupCoord"`
_ func(recipient string) `signal:"showNoActiveKeyForRecipient"`
_ func() `signal:"showCertIssue"`
+ _ func() `signal:"ShowIMAPCertTroubleshoot"`
_ func() `slot:"startUpdate"`
_ func(hasError bool) `signal:"updateFinished"`
diff --git a/internal/imap/backend.go b/internal/imap/backend.go
index 3652199a..0e300fdb 100644
--- a/internal/imap/backend.go
+++ b/internal/imap/backend.go
@@ -29,6 +29,7 @@ import (
"github.com/ProtonMail/proton-bridge/pkg/listener"
"github.com/emersion/go-imap"
goIMAPBackend "github.com/emersion/go-imap/backend"
+ "github.com/sirupsen/logrus"
)
type panicHandler interface {
@@ -219,3 +220,11 @@ func (ib *imapBackend) monitorDisconnectedUsers() {
ib.deleteUser(address)
}
}
+
+func (ib *imapBackend) upgradeError(err error) {
+ logrus.WithError(err).Error("IMAP connection couldn't be upgraded to TLS during STARTTLS")
+
+ if strings.Contains(err.Error(), "remote error: tls: bad certificate") {
+ ib.eventListener.Emit(events.IMAPTLSBadCert, err.Error())
+ }
+}
diff --git a/internal/imap/server.go b/internal/imap/server.go
index 34a45fc0..3aac8ada 100644
--- a/internal/imap/server.go
+++ b/internal/imap/server.go
@@ -57,6 +57,7 @@ func NewIMAPServer(debugClient, debugServer bool, port int, tls *tls.Config, ima
s.AllowInsecureAuth = true
s.ErrorLog = newServerErrorLogger("server-imap")
s.AutoLogout = 30 * time.Minute
+ s.UpgradeError = imapBackend.upgradeError
serverID := imapid.ID{
imapid.FieldName: "ProtonMail",
diff --git a/pkg/pmapi/auth.go b/pkg/pmapi/auth.go
index 29fef42b..6232c6d9 100644
--- a/pkg/pmapi/auth.go
+++ b/pkg/pmapi/auth.go
@@ -357,6 +357,9 @@ func (c *client) Auth2FA(twoFactorCode string, auth *Auth) (*Auth2FA, error) {
// AuthRefresh will refresh an expired access token.
func (c *client) AuthRefresh(uidAndRefreshToken string) (auth *Auth, err error) {
+ c.refreshLocker.Lock()
+ defer c.refreshLocker.Unlock()
+
// If we don't yet have a saved access token, save this one in case the refresh fails!
// That way we can try again later (see handleUnauthorizedStatus).
c.cm.setTokenIfUnset(c.userID, uidAndRefreshToken)
diff --git a/pkg/pmapi/client.go b/pkg/pmapi/client.go
index 8c76658e..42f5e862 100644
--- a/pkg/pmapi/client.go
+++ b/pkg/pmapi/client.go
@@ -113,6 +113,7 @@ type client struct {
accessToken string
userID string
requestLocker sync.Locker
+ refreshLocker sync.Locker
user *User
addresses AddressList
@@ -130,6 +131,7 @@ func newClient(cm *ClientManager, userID string) *client {
hc: getHTTPClient(cm.config, cm.roundTripper, cm.cookieJar),
userID: userID,
requestLocker: &sync.Mutex{},
+ refreshLocker: &sync.Mutex{},
keyRingLock: &sync.Mutex{},
addrKeyRing: make(map[string]*crypto.KeyRing),
log: logrus.WithField("pkg", "pmapi").WithField("userID", userID),
diff --git a/release-notes/bugs.txt b/release-notes/bugs.txt
index 3387c026..57c2f374 100644
--- a/release-notes/bugs.txt
+++ b/release-notes/bugs.txt
@@ -1 +1,2 @@
-• Fixed ignored import to Sent folder
+• Fixed a slew of smaller bugs and some conditions which could cause the application to crash.
+• The full changelog can be found at https://github.com/ProtonMail/proton-bridge/blob/master/Changelog.md
diff --git a/release-notes/notes.txt b/release-notes/notes.txt
index e69de29b..ebe7beea 100644
--- a/release-notes/notes.txt
+++ b/release-notes/notes.txt
@@ -0,0 +1,5 @@
+• Improvements to Alternative Routing: Version two of this feature is now more resilient to unstable internet connections, which results in a smoother experience using this feature. Also includes fixes to previous implementation of Alternative Routing when first starting the application or when turning it off.
+• Email parsing improvements: Improved detection of email encodings embedded in html/xml in addition to message header; add a fallback option if encoding is not specified and decoding as UTF8 fails (ISO-8859-1) ; tweaked logic of parsing "References" header.
+• User interaction improvements: Some smaller improvements in specific cases to make the interaction with Proton Bridge clearer for the user
+• Code updates & maintenance: Migrated to GopenPGP v2, updates to GoIMAPv1, increased bbolt version to 1.3.5 and various improvements regarding extensibility and maintainability for upcoming work.
+• General stability improvements: Improvements to the behavior of the application under various unstable internet conditions.
diff --git a/test/Makefile b/test/Makefile
index 82758c9e..be965951 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,7 +1,7 @@
.PHONY: check-has-go install-godog test test-live test-debug test-live-debug
export GO111MODULE=on
-export BRIDGE_VERSION:=1.2.7-integrationtests
+export BRIDGE_VERSION:=1.3.0-integrationtests
export VERBOSITY?=fatal
export TEST_DATA=testdata