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 Authenticator()86 Authenticator() {} ~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: AuthenticatorFactory()121 AuthenticatorFactory() {} ~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