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 rejection reason. Can be called only when in REJECTED state. 93 virtual RejectionReason rejection_reason() const = 0; 94 95 // Called in response to incoming message received from the peer. 96 // Should only be called when in WAITING_MESSAGE state. Caller retains 97 // ownership of |message|. |resume_callback| will be called when processing is 98 // finished. The implementation must guarantee that |resume_callback| is not 99 // called after the Authenticator is destroyed. 100 virtual void ProcessMessage(const buzz::XmlElement* message, 101 const base::Closure& resume_callback) = 0; 102 103 // Must be called when in MESSAGE_READY state. Returns next 104 // authentication message that needs to be sent to the peer. 105 virtual scoped_ptr<buzz::XmlElement> GetNextMessage() = 0; 106 107 // Creates new authenticator for a channel. Can be called only in 108 // the ACCEPTED state. 109 virtual scoped_ptr<ChannelAuthenticator> 110 CreateChannelAuthenticator() const = 0; 111 }; 112 113 // Factory for Authenticator instances. 114 class AuthenticatorFactory { 115 public: 116 AuthenticatorFactory() {} 117 virtual ~AuthenticatorFactory() {} 118 119 // Called when session-initiate stanza is received to create 120 // authenticator for the new session. |first_message| specifies 121 // authentication part of the session-initiate stanza so that 122 // appropriate type of Authenticator can be chosen for the session 123 // (useful when multiple authenticators is supported). Returns NULL 124 // if the |first_message| is invalid and the session should be 125 // rejected. ProcessMessage() should be called with |first_message| 126 // for the result of this method. 127 virtual scoped_ptr<Authenticator> CreateAuthenticator( 128 const std::string& local_jid, 129 const std::string& remote_jid, 130 const buzz::XmlElement* first_message) = 0; 131 }; 132 133 } // namespace protocol 134 } // namespace remoting 135 136 #endif // REMOTING_PROTOCOL_AUTHENTICATOR_H_ 137