• 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 #include "remoting/protocol/fake_authenticator.h"
6 
7 #include "base/message_loop/message_loop.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "net/base/io_buffer.h"
10 #include "net/socket/stream_socket.h"
11 #include "remoting/base/constants.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h"
14 
15 namespace remoting {
16 namespace protocol {
17 
FakeChannelAuthenticator(bool accept,bool async)18 FakeChannelAuthenticator::FakeChannelAuthenticator(bool accept, bool async)
19     : result_(accept ? net::OK : net::ERR_FAILED),
20       async_(async),
21       did_read_bytes_(false),
22       did_write_bytes_(false),
23       weak_factory_(this) {
24 }
25 
~FakeChannelAuthenticator()26 FakeChannelAuthenticator::~FakeChannelAuthenticator() {
27 }
28 
SecureAndAuthenticate(scoped_ptr<net::StreamSocket> socket,const DoneCallback & done_callback)29 void FakeChannelAuthenticator::SecureAndAuthenticate(
30     scoped_ptr<net::StreamSocket> socket,
31     const DoneCallback& done_callback) {
32   socket_ = socket.Pass();
33 
34   if (async_) {
35     done_callback_ = done_callback;
36 
37     scoped_refptr<net::IOBuffer> write_buf = new net::IOBuffer(1);
38     write_buf->data()[0] = 0;
39     int result =
40         socket_->Write(write_buf.get(),
41                        1,
42                        base::Bind(&FakeChannelAuthenticator::OnAuthBytesWritten,
43                                   weak_factory_.GetWeakPtr()));
44     if (result != net::ERR_IO_PENDING) {
45       // This will not call the callback because |did_read_bytes_| is
46       // still set to false.
47       OnAuthBytesWritten(result);
48     }
49 
50     scoped_refptr<net::IOBuffer> read_buf = new net::IOBuffer(1);
51     result =
52         socket_->Read(read_buf.get(),
53                       1,
54                       base::Bind(&FakeChannelAuthenticator::OnAuthBytesRead,
55                                  weak_factory_.GetWeakPtr()));
56     if (result != net::ERR_IO_PENDING)
57       OnAuthBytesRead(result);
58   } else {
59     if (result_ != net::OK)
60       socket_.reset();
61     done_callback.Run(result_, socket_.Pass());
62   }
63 }
64 
OnAuthBytesWritten(int result)65 void FakeChannelAuthenticator::OnAuthBytesWritten(int result) {
66   EXPECT_EQ(1, result);
67   EXPECT_FALSE(did_write_bytes_);
68   did_write_bytes_ = true;
69   if (did_read_bytes_)
70     done_callback_.Run(result_, socket_.Pass());
71 }
72 
OnAuthBytesRead(int result)73 void FakeChannelAuthenticator::OnAuthBytesRead(int result) {
74   EXPECT_EQ(1, result);
75   EXPECT_FALSE(did_read_bytes_);
76   did_read_bytes_ = true;
77   if (did_write_bytes_)
78     done_callback_.Run(result_, socket_.Pass());
79 }
80 
FakeAuthenticator(Type type,int round_trips,Action action,bool async)81 FakeAuthenticator::FakeAuthenticator(
82     Type type, int round_trips, Action action, bool async)
83     : type_(type),
84       round_trips_(round_trips),
85       action_(action),
86       async_(async),
87       messages_(0),
88       messages_till_started_(0) {
89 }
90 
~FakeAuthenticator()91 FakeAuthenticator::~FakeAuthenticator() {
92 }
93 
set_messages_till_started(int messages)94 void FakeAuthenticator::set_messages_till_started(int messages) {
95   messages_till_started_ = messages;
96 }
97 
state() const98 Authenticator::State FakeAuthenticator::state() const {
99   EXPECT_LE(messages_, round_trips_ * 2);
100   if (messages_ >= round_trips_ * 2) {
101     if (action_ == REJECT) {
102       return REJECTED;
103     } else {
104       return ACCEPTED;
105     }
106   }
107 
108   // Don't send the last message if this is a host that wants to
109   // reject a connection.
110   if (messages_ == round_trips_ * 2 - 1 &&
111       type_ == HOST && action_ == REJECT) {
112     return REJECTED;
113   }
114 
115   // We are not done yet. process next message.
116   if ((messages_ % 2 == 0 && type_ == CLIENT) ||
117       (messages_ % 2 == 1 && type_ == HOST)) {
118     return MESSAGE_READY;
119   } else {
120     return WAITING_MESSAGE;
121   }
122 }
123 
started() const124 bool FakeAuthenticator::started() const {
125   return messages_ > messages_till_started_;
126 }
127 
rejection_reason() const128 Authenticator::RejectionReason FakeAuthenticator::rejection_reason() const {
129   EXPECT_EQ(REJECTED, state());
130   return INVALID_CREDENTIALS;
131 }
132 
ProcessMessage(const buzz::XmlElement * message,const base::Closure & resume_callback)133 void FakeAuthenticator::ProcessMessage(const buzz::XmlElement* message,
134                                        const base::Closure& resume_callback) {
135   EXPECT_EQ(WAITING_MESSAGE, state());
136   std::string id =
137       message->TextNamed(buzz::QName(kChromotingXmlNamespace, "id"));
138   EXPECT_EQ(id, base::IntToString(messages_));
139   ++messages_;
140   resume_callback.Run();
141 }
142 
GetNextMessage()143 scoped_ptr<buzz::XmlElement> FakeAuthenticator::GetNextMessage() {
144   EXPECT_EQ(MESSAGE_READY, state());
145 
146   scoped_ptr<buzz::XmlElement> result(new buzz::XmlElement(
147       buzz::QName(kChromotingXmlNamespace, "authentication")));
148   buzz::XmlElement* id = new buzz::XmlElement(
149       buzz::QName(kChromotingXmlNamespace, "id"));
150   id->AddText(base::IntToString(messages_));
151   result->AddElement(id);
152 
153   ++messages_;
154   return result.Pass();
155 }
156 
157 scoped_ptr<ChannelAuthenticator>
CreateChannelAuthenticator() const158 FakeAuthenticator::CreateChannelAuthenticator() const {
159   EXPECT_EQ(ACCEPTED, state());
160   return scoped_ptr<ChannelAuthenticator>(
161       new FakeChannelAuthenticator(action_ != REJECT_CHANNEL, async_));
162 }
163 
FakeHostAuthenticatorFactory(int round_trips,int messages_till_started,FakeAuthenticator::Action action,bool async)164 FakeHostAuthenticatorFactory::FakeHostAuthenticatorFactory(
165     int round_trips, int messages_till_started,
166     FakeAuthenticator::Action action, bool async)
167     : round_trips_(round_trips),
168       messages_till_started_(messages_till_started),
169       action_(action), async_(async) {
170 }
171 
~FakeHostAuthenticatorFactory()172 FakeHostAuthenticatorFactory::~FakeHostAuthenticatorFactory() {
173 }
174 
CreateAuthenticator(const std::string & local_jid,const std::string & remote_jid,const buzz::XmlElement * first_message)175 scoped_ptr<Authenticator> FakeHostAuthenticatorFactory::CreateAuthenticator(
176     const std::string& local_jid,
177     const std::string& remote_jid,
178     const buzz::XmlElement* first_message) {
179   FakeAuthenticator* authenticator = new FakeAuthenticator(
180       FakeAuthenticator::HOST, round_trips_, action_, async_);
181   authenticator->set_messages_till_started(messages_till_started_);
182 
183   scoped_ptr<Authenticator> result(authenticator);
184   return result.Pass();
185 }
186 
187 }  // namespace protocol
188 }  // namespace remoting
189