| Index: remoting/protocol/secure_channel_factory.cc | 
| diff --git a/remoting/protocol/secure_channel_factory.cc b/remoting/protocol/secure_channel_factory.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..df98378afc8fdb155371b275e5111e4928d21364 | 
| --- /dev/null | 
| +++ b/remoting/protocol/secure_channel_factory.cc | 
| @@ -0,0 +1,83 @@ | 
| +// Copyright 2014 The Chromium Authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +#include "remoting/protocol/secure_channel_factory.h" | 
| + | 
| +#include "base/bind.h" | 
| +#include "net/socket/stream_socket.h" | 
| +#include "remoting/protocol/authenticator.h" | 
| +#include "remoting/protocol/channel_authenticator.h" | 
| + | 
| +namespace remoting { | 
| +namespace protocol { | 
| + | 
| +SecureChannelFactory::SecureChannelFactory( | 
| +    StreamChannelFactory* channel_factory, | 
| +    Authenticator* authenticator) | 
| +    : channel_factory_(channel_factory), | 
| +      authenticator_(authenticator) { | 
| +  DCHECK_EQ(authenticator_->state(), Authenticator::ACCEPTED); | 
| +} | 
| + | 
| +SecureChannelFactory::~SecureChannelFactory() { | 
| +  // CancelChannelCreation() is expected to be called before destruction. | 
| +  DCHECK(channel_authenticators_.empty()); | 
| +} | 
| + | 
| +void SecureChannelFactory::CreateChannel( | 
| +    const std::string& name, | 
| +    const ChannelCreatedCallback& callback) { | 
| +  DCHECK(!callback.is_null()); | 
| +  channel_factory_->CreateChannel( | 
| +      name, | 
| +      base::Bind(&SecureChannelFactory::OnBaseChannelCreated, | 
| +                 base::Unretained(this), name, callback)); | 
| +} | 
| + | 
| +void SecureChannelFactory::CancelChannelCreation( | 
| +    const std::string& name) { | 
| +  AuthenticatorMap::iterator it = channel_authenticators_.find(name); | 
| +  if (it == channel_authenticators_.end()) { | 
| +    channel_factory_->CancelChannelCreation(name); | 
| +  } else { | 
| +    delete it->second; | 
| +    channel_authenticators_.erase(it); | 
| +  } | 
| +} | 
| + | 
| +void SecureChannelFactory::OnBaseChannelCreated( | 
| +    const std::string& name, | 
| +    const ChannelCreatedCallback& callback, | 
| +    scoped_ptr<net::StreamSocket> socket) { | 
| +  if (!socket) { | 
| +    callback.Run(scoped_ptr<net::StreamSocket>()); | 
| +    return; | 
| +  } | 
| + | 
| +  ChannelAuthenticator* channel_authenticator = | 
| +      authenticator_->CreateChannelAuthenticator().release(); | 
| +  channel_authenticators_[name] = channel_authenticator; | 
| +  channel_authenticator->SecureAndAuthenticate( | 
| +      socket.Pass(), | 
| +      base::Bind(&SecureChannelFactory::OnSecureChannelCreated, | 
| +                 base::Unretained(this), name, callback)); | 
| +} | 
| + | 
| +void SecureChannelFactory::OnSecureChannelCreated( | 
| +    const std::string& name, | 
| +    const ChannelCreatedCallback& callback, | 
| +    int error, | 
| +    scoped_ptr<net::StreamSocket> socket) { | 
| +  DCHECK((socket && error == net::OK) || (!socket && error != net::OK)); | 
| + | 
| +  AuthenticatorMap::iterator it = channel_authenticators_.find(name); | 
| +  DCHECK(it != channel_authenticators_.end()); | 
| +  delete it->second; | 
| +  channel_authenticators_.erase(it); | 
| + | 
| +  callback.Run(socket.Pass()); | 
| +} | 
| + | 
| +}  // namespace protocol | 
| +}  // namespace remoting | 
|  |