• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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