summaryrefslogtreecommitdiff
path: root/network/emailrelay/patches/4b0a67b55cec24f99d4842fe8ac980327beed0cb.patch
diff options
context:
space:
mode:
Diffstat (limited to 'network/emailrelay/patches/4b0a67b55cec24f99d4842fe8ac980327beed0cb.patch')
-rw-r--r--network/emailrelay/patches/4b0a67b55cec24f99d4842fe8ac980327beed0cb.patch130
1 files changed, 130 insertions, 0 deletions
diff --git a/network/emailrelay/patches/4b0a67b55cec24f99d4842fe8ac980327beed0cb.patch b/network/emailrelay/patches/4b0a67b55cec24f99d4842fe8ac980327beed0cb.patch
new file mode 100644
index 0000000000..08cbd27dbe
--- /dev/null
+++ b/network/emailrelay/patches/4b0a67b55cec24f99d4842fe8ac980327beed0cb.patch
@@ -0,0 +1,130 @@
+From 4b0a67b55cec24f99d4842fe8ac980327beed0cb Mon Sep 17 00:00:00 2001
+From: Andrew Clemons <andrew.clemons@gmail.com>
+Date: Wed, 2 Aug 2017 21:22:53 +1200
+Subject: [PATCH] Add support for XOAUTH2 auth
+
+I have thus far only tested this with gmail and using node-xoauth2 for
+generating the tokens.
+
+Emailrelay still requires a client auth configuration file with four
+values. The id value here can be anything since it is ignored.
+
+I am using:
+
+client XOAUTH2 ignored <generated token>
+---
+ src/gauth/gsaslclient.h | 5 +++++
+ src/gauth/gsaslclient_native.cpp | 32 +++++++++++++++++++++++++++++++-
+ src/gsmtp/gclientprotocol.cpp | 18 ++++++++++++++++--
+ 3 files changed, 52 insertions(+), 3 deletions(-)
+
+diff --git a/src/gauth/gsaslclient.h b/src/gauth/gsaslclient.h
+index ea12e05..d74b56d 100644
+--- a/src/gauth/gsaslclient.h
++++ b/src/gauth/gsaslclient.h
+@@ -67,6 +67,11 @@ class GAuth::SaslClient
+ ///< Returns true if the constructor's secrets object
+ ///< is valid.
+
++ std::string initial_response( const std::string & mechanism ,
++ bool & done , bool & error , bool & sensitive ) const ;
++ ///< Returns an initial_response for authentication.
++ ///< Returns various boolean flags by reference.
++
+ std::string response( const std::string & mechanism , const std::string & challenge ,
+ bool & done , bool & error , bool & sensitive ) const ;
+ ///< Returns a response to the given challenge.
+diff --git a/src/gauth/gsaslclient_native.cpp b/src/gauth/gsaslclient_native.cpp
+index d0bded2..924772a 100644
+--- a/src/gauth/gsaslclient_native.cpp
++++ b/src/gauth/gsaslclient_native.cpp
+@@ -101,6 +101,33 @@ bool GAuth::SaslClient::active() const
+ return m_imp->m_secrets.valid() ;
+ }
+
++std::string GAuth::SaslClient::initial_response( const std::string & mechanism , bool & done ,
++ bool & error , bool & sensitive ) const
++{
++ done = false ;
++ error = false ;
++ sensitive = false ;
++
++ std::string auth("AUTH") ;
++ std::string sep(" ") ;
++
++ std::string rsp ;
++ if( mechanism == "XOAUTH2" )
++ {
++ std::string secret = m_imp->m_secrets.secret(mechanism) ;
++ rsp = auth + sep + mechanism + sep + secret ;
++ error = secret.empty() ;
++ done = true ;
++ sensitive = true ;
++ }
++ else
++ {
++ rsp = auth + sep + mechanism ;
++ }
++
++ return rsp ;
++}
++
+ std::string GAuth::SaslClient::response( const std::string & mechanism , const std::string & challenge ,
+ bool & done , bool & error , bool & sensitive ) const
+ {
+@@ -175,6 +202,7 @@ std::string GAuth::SaslClient::preferred( const G::Strings & mechanism_list ) co
+
+ const std::string login( "LOGIN" ) ;
+ const std::string plain( "PLAIN" ) ;
++ const std::string xoauth2( "XOAUTH2" ) ;
+ const std::string cram( "CRAM-MD5" ) ;
+
+ // create a them set
+@@ -186,15 +214,17 @@ std::string GAuth::SaslClient::preferred( const G::Strings & mechanism_list ) co
+ std::set<std::string> us ;
+ if( !m_imp->m_secrets.id(login).empty() ) us.insert(login) ;
+ if( !m_imp->m_secrets.id(plain).empty() ) us.insert(plain) ;
++ if( !m_imp->m_secrets.id(xoauth2).empty() ) us.insert(xoauth2) ;
+ if( !m_imp->m_secrets.id(cram).empty() ) us.insert(cram) ;
+
+ // get the intersection
+ std::set<std::string> both ;
+ std::set_intersection( them.begin() , them.end() , us.begin() , us.end() , std::inserter(both,both.end()) ) ;
+
+- // preferred order: cram, plain, login
++ // preferred order: cram, xoauth2, plain, login
+ std::string m ;
+ if( m.empty() && both.find(cram) != both.end() ) m = cram ;
++ if( m.empty() && both.find(xoauth2) != both.end() ) m = xoauth2 ;
+ if( m.empty() && both.find(plain) != both.end() ) m = plain ;
+ if( m.empty() && both.find(login) != both.end() ) m = login ;
+ G_DEBUG( "GAuth::SaslClient::preferred: we prefer \"" << m << "\"" ) ;
+diff --git a/src/gsmtp/gclientprotocol.cpp b/src/gsmtp/gclientprotocol.cpp
+index 3ebc0c7..bbd8aca 100644
+--- a/src/gsmtp/gclientprotocol.cpp
++++ b/src/gsmtp/gclientprotocol.cpp
+@@ -303,8 +303,22 @@ bool GSmtp::ClientProtocol::applyEvent( const Reply & reply , bool is_start_even
+ }
+ else if( m_server_has_auth && m_sasl->active() )
+ {
+- m_state = sAuth1 ;
+- send( "AUTH " , m_auth_mechanism ) ;
++ bool done = true ;
++ bool error = false ;
++ bool sensitive = false ;
++ std::string rsp = m_sasl->initial_response( m_auth_mechanism ,
++ done , error , sensitive ) ;
++
++ if( error )
++ {
++ m_state = sAuth2 ;
++ send( "*" ) ; // ie. cancel authentication
++ }
++ else
++ {
++ m_state = done ? sAuth2 : sAuth1 ;
++ send( rsp , false , sensitive ) ;
++ }
+ }
+ else if( !m_server_has_auth && m_sasl->active() && m_must_authenticate )
+ {