Index: remoting/protocol/negotiating_authenticator.h |
diff --git a/remoting/protocol/negotiating_authenticator.h b/remoting/protocol/negotiating_authenticator.h |
index a87d543e3ca98606ea4265013c0e39cff0056f50..7166cf517e15d617056b7544a50b1c495bfa0ee8 100644 |
--- a/remoting/protocol/negotiating_authenticator.h |
+++ b/remoting/protocol/negotiating_authenticator.h |
@@ -11,6 +11,7 @@ |
#include "base/basictypes.h" |
#include "base/memory/ref_counted.h" |
#include "base/memory/scoped_ptr.h" |
+#include "base/memory/weak_ptr.h" |
#include "remoting/protocol/authenticator.h" |
#include "remoting/protocol/authentication_method.h" |
@@ -20,16 +21,57 @@ class RsaKeyPair; |
namespace protocol { |
+typedef base::Callback<void(const std::string& secret)> SecretFetchedCallback; |
+typedef base::Callback<void( |
+ const SecretFetchedCallback& secret_fetched_callback)> FetchSecretCallback; |
+ |
+// This class provides a meta-authenticator that allows clients and hosts that |
+// support multiple authentication methods to negotiate a method to use. |
+// |
+// The typical flow is: |
+// * Client sends a message to host with its supported methods. |
+// (clients may additionally pick a method and send its first message). |
+// * Host picks a method and sends its first message (if any). |
+// (if a message for that method was sent by the client, it is processed). |
+// * Client creates the authenticator selected by the host. If the method |
+// starts with a message from the host, it is processed. |
+// * Client and host exchange messages until the authentication is ACCEPTED or |
+// REJECTED. |
+// |
+// The details: |
+// * CreateAuthenticator() may be asynchronous (i.e. require user interaction |
+// to determine initial parameters, like PIN). This happens inside |
+// ProcessMessage, so to the outside this behaves like any asynchronous |
+// message processing. Internally, CreateAuthenticator() receives a |
+// callback, that will resume the authentication once the authenticator is |
+// created. If there is already a message to be processed by the new |
+// authenticator, this callback includes a call to the underlying |
+// ProcessMessage(). |
+// * Some authentication methods may have a specific starting direction (e.g. |
+// host always sends the first message), while others are versatile (e.g. |
+// SPAKE, where either side can send the first message). When an |
+// authenticator is created, it is given a preferred initial state, which |
+// the authenticator may ignore. |
+// * If the new authenticator state doesn't match the preferred one, |
+// the NegotiatingAuthenticator deals with that, by sending an empty |
+// <authenticator> stanza if the method has no message to send, and |
+// ignoring such empty messages on the receiving end. |
+// * The client may optimistically pick a method on its first message (assuming |
+// it doesn't require user interaction to start). If the host doesn't |
+// support that method, it will just discard that message, and choose |
+// another method from the client's supported methods list. |
+// * The host never sends its own supported methods back to the client, so once |
+// the host picks a method from the client's list, it's final. |
+// * Any change in this class must maintain compatibility between any version |
+// mix of webapp, client plugin and host, for both Me2Me and IT2Me. |
class NegotiatingAuthenticator : public Authenticator { |
public: |
virtual ~NegotiatingAuthenticator(); |
- static bool IsNegotiableMessage(const buzz::XmlElement* message); |
- |
// Creates a client authenticator for the given methods. |
static scoped_ptr<Authenticator> CreateForClient( |
const std::string& authentication_tag, |
- const std::string& shared_secret, |
+ const FetchSecretCallback& fetch_secret_callback, |
const std::vector<AuthenticationMethod>& methods); |
// Creates a host authenticator, using a fixed shared secret/PIN hash. |
@@ -49,12 +91,33 @@ class NegotiatingAuthenticator : public Authenticator { |
CreateChannelAuthenticator() const OVERRIDE; |
private: |
- NegotiatingAuthenticator(Authenticator::State initial_state); |
+ explicit NegotiatingAuthenticator(Authenticator::State initial_state); |
void AddMethod(const AuthenticationMethod& method); |
- void CreateAuthenticator(State initial_state); |
+ |
+ // (Asynchronously) creates an authenticator, and stores it in |
+ // |current_authenticator_|. Authenticators that can be started in either |
+ // state will be created in |preferred_initial_state|. |
+ // |resume_callback| is called after |current_authenticator_| is set. |
+ void CreateAuthenticator(Authenticator::State preferred_initial_state, |
+ const base::Closure& resume_callback); |
+ |
+ // Calls |current_authenticator_| to process |message|, passing the supplied |
+ // |resume_callback|. |
+ void ProcessMessageInternal(const buzz::XmlElement* message, |
+ const base::Closure& resume_callback); |
+ |
+ // Updates |state_| to reflect the current underlying authenticator state. |
+ // |resume_callback| is called after the state is updated. |
void UpdateState(const base::Closure& resume_callback); |
+ // Creates a V2Authenticator in state |initial_state| with the given |
+ // |shared_secret|, then runs |resume_callback|. |
+ void CreateV2AuthenticatorWithSecret( |
+ Authenticator::State initial_state, |
+ const base::Closure& resume_callback, |
+ const std::string& shared_secret); |
+ |
bool is_host_side() const; |
// Used only for host authenticators. |
@@ -64,7 +127,7 @@ class NegotiatingAuthenticator : public Authenticator { |
// Used only for client authenticators. |
std::string authentication_tag_; |
- std::string shared_secret_; |
+ FetchSecretCallback fetch_secret_callback_; |
// Used for both host and client authenticators. |
std::vector<AuthenticationMethod> methods_; |
@@ -73,6 +136,8 @@ class NegotiatingAuthenticator : public Authenticator { |
State state_; |
RejectionReason rejection_reason_; |
+ base::WeakPtrFactory<NegotiatingAuthenticator> weak_factory_; |
+ |
DISALLOW_COPY_AND_ASSIGN(NegotiatingAuthenticator); |
}; |