Home | History | Annotate | Download | only in protocol
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef REMOTING_PROTOCOL_AUTHENTICATOR_H_
      6 #define REMOTING_PROTOCOL_AUTHENTICATOR_H_
      7 
      8 #include <string>
      9 
     10 #include "base/callback.h"
     11 #include "base/memory/scoped_ptr.h"
     12 
     13 namespace buzz {
     14 class XmlElement;
     15 }  // namespace buzz
     16 
     17 namespace remoting {
     18 namespace protocol {
     19 
     20 class ChannelAuthenticator;
     21 
     22 typedef base::Callback<void(const std::string& secret)> SecretFetchedCallback;
     23 typedef base::Callback<void(
     24     bool pairing_supported,
     25     const SecretFetchedCallback& secret_fetched_callback)> FetchSecretCallback;
     26 
     27 // Authenticator is an abstract interface for authentication protocol
     28 // implementations. Different implementations of this interface may be
     29 // used on each side of the connection depending of type of the auth
     30 // protocol. Client and host will repeatedly call their Authenticators
     31 // and deliver the messages they generate, until successful
     32 // authentication is reported.
     33 //
     34 // Authenticator may exchange multiple messages before session is
     35 // authenticated. Each message sent/received by an Authenticator is
     36 // delivered either in a session description inside session-initiate
     37 // and session-accept messages or in a session-info
     38 // message. Session-info messages are used only if authenticators need
     39 // to exchange more than one message.
     40 class Authenticator {
     41  public:
     42   // Allowed state transitions:
     43   // When ProcessMessage() is called:
     44   //    WAITING_MESSAGE -> MESSAGE_READY
     45   //    WAITING_MESSAGE -> ACCEPTED
     46   //    WAITING_MESSAGE -> REJECTED
     47   //    WAITING_MESSAGE -> PROCESSING_MESSAGE
     48   // After asynchronous message processing finishes:
     49   ///   PROCESSING_MESSAGE -> MESSAGE_READY
     50   // When GetNextMessage() is called:
     51   //    MESSAGE_READY -> WAITING_MESSAGE
     52   //    MESSAGE_READY -> ACCEPTED
     53   enum State {
     54     // Waiting for the next message from the peer.
     55     WAITING_MESSAGE,
     56 
     57     // Next message is ready to be sent to the peer.
     58     MESSAGE_READY,
     59 
     60     // Session is authenticated successufully.
     61     ACCEPTED,
     62 
     63     // Session is rejected.
     64     REJECTED,
     65 
     66     // Asynchronously processing the last message from the peer.
     67     PROCESSING_MESSAGE,
     68   };
     69 
     70   enum RejectionReason {
     71     INVALID_CREDENTIALS,
     72     PROTOCOL_ERROR,
     73   };
     74 
     75   // Returns true if |message| is an Authenticator message.
     76   static bool IsAuthenticatorMessage(const buzz::XmlElement* message);
     77 
     78   // Creates an empty Authenticator message, owned by the caller.
     79   static scoped_ptr<buzz::XmlElement> CreateEmptyAuthenticatorMessage();
     80 
     81   // Finds Authenticator message among child elements of |message|, or
     82   // returns NULL otherwise.
     83   static const buzz::XmlElement* FindAuthenticatorMessage(
     84       const buzz::XmlElement* message);
     85 
     86   Authenticator() {}
     87   virtual ~Authenticator() {}
     88 
     89   // Returns current state of the authenticator.
     90   virtual State state() const = 0;
     91 
     92   // Returns whether authentication has started. The chromoting host uses this
     93   // method to starts the back off process to prevent malicious clients from
     94   // guessing the PIN by spamming the host with auth requests.
     95   virtual bool started() const = 0;
     96 
     97   // Returns rejection reason. Can be called only when in REJECTED state.
     98   virtual RejectionReason rejection_reason() const = 0;
     99 
    100   // Called in response to incoming message received from the peer.
    101   // Should only be called when in WAITING_MESSAGE state. Caller retains
    102   // ownership of |message|. |resume_callback| will be called when processing is
    103   // finished. The implementation must guarantee that |resume_callback| is not
    104   // called after the Authenticator is destroyed.
    105   virtual void ProcessMessage(const buzz::XmlElement* message,
    106                               const base::Closure& resume_callback) = 0;
    107 
    108   // Must be called when in MESSAGE_READY state. Returns next
    109   // authentication message that needs to be sent to the peer.
    110   virtual scoped_ptr<buzz::XmlElement> GetNextMessage() = 0;
    111 
    112   // Creates new authenticator for a channel. Can be called only in
    113   // the ACCEPTED state.
    114   virtual scoped_ptr<ChannelAuthenticator>
    115       CreateChannelAuthenticator() const = 0;
    116 };
    117 
    118 // Factory for Authenticator instances.
    119 class AuthenticatorFactory {
    120  public:
    121   AuthenticatorFactory() {}
    122   virtual ~AuthenticatorFactory() {}
    123 
    124   // Called when session-initiate stanza is received to create
    125   // authenticator for the new session. |first_message| specifies
    126   // authentication part of the session-initiate stanza so that
    127   // appropriate type of Authenticator can be chosen for the session
    128   // (useful when multiple authenticators is supported). Returns NULL
    129   // if the |first_message| is invalid and the session should be
    130   // rejected. ProcessMessage() should be called with |first_message|
    131   // for the result of this method.
    132   virtual scoped_ptr<Authenticator> CreateAuthenticator(
    133       const std::string& local_jid,
    134       const std::string& remote_jid,
    135       const buzz::XmlElement* first_message) = 0;
    136 };
    137 
    138 }  // namespace protocol
    139 }  // namespace remoting
    140 
    141 #endif  // REMOTING_PROTOCOL_AUTHENTICATOR_H_
    142