// Copyright (c) 2012 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 "ipc/ipc_channel_win.h"

#include <windows.h>
#include <stddef.h>
#include <stdint.h>

#include "base/auto_reset.h"
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/pickle.h"
#include "base/process/process_handle.h"
#include "base/rand_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_checker.h"
#include "base/win/scoped_handle.h"
#include "ipc/attachment_broker.h"
#include "ipc/ipc_listener.h"
#include "ipc/ipc_logging.h"
#include "ipc/ipc_message_attachment_set.h"
#include "ipc/ipc_message_utils.h"

namespace IPC {

ChannelWin::State::State(ChannelWin* channel) : is_pending(false) {
  memset(&context.overlapped, 0, sizeof(context.overlapped));
  context.handler = channel;
}

ChannelWin::State::~State() {
  static_assert(offsetof(ChannelWin::State, context) == 0,
                "ChannelWin::State should have context as its first data"
                "member.");
}

ChannelWin::ChannelWin(const IPC::ChannelHandle& channel_handle,
                       Mode mode,
                       Listener* listener)
    : ChannelReader(listener),
      input_state_(this),
      output_state_(this),
      peer_pid_(base::kNullProcessId),
      waiting_connect_(mode & MODE_SERVER_FLAG),
      processing_incoming_(false),
      validate_client_(false),
      client_secret_(0),
      weak_factory_(this) {
  CreatePipe(channel_handle, mode);
}

ChannelWin::~ChannelWin() {
  CleanUp();
  Close();
}

void ChannelWin::Close() {
  if (thread_check_.get())
    DCHECK(thread_check_->CalledOnValidThread());

  if (input_state_.is_pending || output_state_.is_pending)
    CancelIo(pipe_.Get());

  // Closing the handle at this point prevents us from issuing more requests
  // form OnIOCompleted().
  if (pipe_.IsValid())
    pipe_.Close();

  // Make sure all IO has completed.
  while (input_state_.is_pending || output_state_.is_pending) {
    base::MessageLoopForIO::current()->WaitForIOCompletion(INFINITE, this);
  }

  while (!output_queue_.empty()) {
    OutputElement* element = output_queue_.front();
    output_queue_.pop();
    delete element;
  }
}

bool ChannelWin::Send(Message* message) {
  DCHECK(thread_check_->CalledOnValidThread());
  DVLOG(2) << "sending message @" << message << " on channel @" << this
           << " with type " << message->type()
           << " (" << output_queue_.size() << " in queue)";

  if (!prelim_queue_.empty()) {
    prelim_queue_.push(message);
    return true;
  }

  if (message->HasBrokerableAttachments() &&
      peer_pid_ == base::kNullProcessId) {
    prelim_queue_.push(message);
    return true;
  }

  return ProcessMessageForDelivery(message);
}

bool ChannelWin::ProcessMessageForDelivery(Message* message) {
  // Sending a brokerable attachment requires a call to Channel::Send(), so
  // both Send() and ProcessMessageForDelivery() may be re-entrant.
  if (message->HasBrokerableAttachments()) {
    DCHECK(GetAttachmentBroker());
    DCHECK(peer_pid_ != base::kNullProcessId);
    for (const scoped_refptr<IPC::BrokerableAttachment>& attachment :
         message->attachment_set()->GetBrokerableAttachments()) {
      if (!GetAttachmentBroker()->SendAttachmentToProcess(attachment,
                                                          peer_pid_)) {
        delete message;
        return false;
      }
    }
  }

#ifdef IPC_MESSAGE_LOG_ENABLED
  Logging::GetInstance()->OnSendMessage(message, "");
#endif

  TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("ipc.flow"),
                         "ChannelWin::ProcessMessageForDelivery",
                         message->flags(),
                         TRACE_EVENT_FLAG_FLOW_OUT);

  // |output_queue_| takes ownership of |message|.
  OutputElement* element = new OutputElement(message);
  output_queue_.push(element);

#if USE_ATTACHMENT_BROKER
  if (message->HasBrokerableAttachments()) {
    // |output_queue_| takes ownership of |ids.buffer|.
    Message::SerializedAttachmentIds ids =
        message->SerializedIdsOfBrokerableAttachments();
    output_queue_.push(new OutputElement(ids.buffer, ids.size));
  }
#endif

  // ensure waiting to write
  if (!waiting_connect_) {
    if (!output_state_.is_pending) {
      if (!ProcessOutgoingMessages(NULL, 0))
        return false;
    }
  }

  return true;
}

void ChannelWin::FlushPrelimQueue() {
  DCHECK_NE(peer_pid_, base::kNullProcessId);

  // Due to the possibly re-entrant nature of ProcessMessageForDelivery(), it
  // is critical that |prelim_queue_| appears empty.
  std::queue<Message*> prelim_queue;
  prelim_queue_.swap(prelim_queue);

  while (!prelim_queue.empty()) {
    Message* m = prelim_queue.front();
    bool success = ProcessMessageForDelivery(m);
    prelim_queue.pop();

    if (!success)
      break;
  }

  // Delete any unprocessed messages.
  while (!prelim_queue.empty()) {
    Message* m = prelim_queue.front();
    delete m;
    prelim_queue.pop();
  }
}

AttachmentBroker* ChannelWin::GetAttachmentBroker() {
  return AttachmentBroker::GetGlobal();
}

base::ProcessId ChannelWin::GetPeerPID() const {
  return peer_pid_;
}

base::ProcessId ChannelWin::GetSelfPID() const {
  return GetCurrentProcessId();
}

// static
bool ChannelWin::IsNamedServerInitialized(
    const std::string& channel_id) {
  if (WaitNamedPipe(PipeName(channel_id, NULL).c_str(), 1))
    return true;
  // If ERROR_SEM_TIMEOUT occurred, the pipe exists but is handling another
  // connection.
  return GetLastError() == ERROR_SEM_TIMEOUT;
}

ChannelWin::ReadState ChannelWin::ReadData(
    char* buffer,
    int buffer_len,
    int* /* bytes_read */) {
  if (!pipe_.IsValid())
    return READ_FAILED;

  DWORD bytes_read = 0;
  BOOL ok = ReadFile(pipe_.Get(), buffer, buffer_len,
                     &bytes_read, &input_state_.context.overlapped);
  if (!ok) {
    DWORD err = GetLastError();
    if (err == ERROR_IO_PENDING) {
      input_state_.is_pending = true;
      return READ_PENDING;
    }
    LOG(ERROR) << "pipe error: " << err;
    return READ_FAILED;
  }

  // We could return READ_SUCCEEDED here. But the way that this code is
  // structured we instead go back to the message loop. Our completion port
  // will be signalled even in the "synchronously completed" state.
  //
  // This allows us to potentially process some outgoing messages and
  // interleave other work on this thread when we're getting hammered with
  // input messages. Potentially, this could be tuned to be more efficient
  // with some testing.
  input_state_.is_pending = true;
  return READ_PENDING;
}

bool ChannelWin::ShouldDispatchInputMessage(Message* msg) {
  // Make sure we get a hello when client validation is required.
  if (validate_client_)
    return IsHelloMessage(*msg);
  return true;
}

bool ChannelWin::GetNonBrokeredAttachments(Message* msg) {
  return true;
}

void ChannelWin::HandleInternalMessage(const Message& msg) {
  DCHECK_EQ(msg.type(), static_cast<unsigned>(Channel::HELLO_MESSAGE_TYPE));
  // The hello message contains one parameter containing the PID.
  base::PickleIterator it(msg);
  int32_t claimed_pid;
  bool failed = !it.ReadInt(&claimed_pid);

  if (!failed && validate_client_) {
    int32_t secret;
    failed = it.ReadInt(&secret) ? (secret != client_secret_) : true;
  }

  if (failed) {
    NOTREACHED();
    Close();
    listener()->OnChannelError();
    return;
  }

  peer_pid_ = claimed_pid;
  // Validation completed.
  validate_client_ = false;

  listener()->OnChannelConnected(claimed_pid);

  FlushPrelimQueue();
}

base::ProcessId ChannelWin::GetSenderPID() {
  return GetPeerPID();
}

bool ChannelWin::IsAttachmentBrokerEndpoint() {
  return is_attachment_broker_endpoint();
}

bool ChannelWin::DidEmptyInputBuffers() {
  // We don't need to do anything here.
  return true;
}

// static
const base::string16 ChannelWin::PipeName(const std::string& channel_id,
                                          int32_t* secret) {
  std::string name("\\\\.\\pipe\\chrome.");

  // Prevent the shared secret from ending up in the pipe name.
  size_t index = channel_id.find_first_of('\\');
  if (index != std::string::npos) {
    if (secret)  // Retrieve the secret if asked for.
      base::StringToInt(channel_id.substr(index + 1), secret);
    return base::ASCIIToUTF16(name.append(channel_id.substr(0, index - 1)));
  }

  // This case is here to support predictable named pipes in tests.
  if (secret)
    *secret = 0;
  return base::ASCIIToUTF16(name.append(channel_id));
}

bool ChannelWin::CreatePipe(const IPC::ChannelHandle &channel_handle,
                            Mode mode) {
  DCHECK(!pipe_.IsValid());
  base::string16 pipe_name;
  // If we already have a valid pipe for channel just copy it.
  if (channel_handle.pipe.handle) {
    // TODO(rvargas) crbug.com/415294: ChannelHandle should either go away in
    // favor of two independent entities (name/file), or it should be a move-
    // only type with a base::File member. In any case, this code should not
    // call DuplicateHandle.
    DCHECK(channel_handle.name.empty());
    pipe_name = L"Not Available";  // Just used for LOG
    // Check that the given pipe confirms to the specified mode.  We can
    // only check for PIPE_TYPE_MESSAGE & PIPE_SERVER_END flags since the
    // other flags (PIPE_TYPE_BYTE, and PIPE_CLIENT_END) are defined as 0.
    DWORD flags = 0;
    GetNamedPipeInfo(channel_handle.pipe.handle, &flags, NULL, NULL, NULL);
    DCHECK(!(flags & PIPE_TYPE_MESSAGE));
    if (((mode & MODE_SERVER_FLAG) && !(flags & PIPE_SERVER_END)) ||
        ((mode & MODE_CLIENT_FLAG) && (flags & PIPE_SERVER_END))) {
      LOG(WARNING) << "Inconsistent open mode. Mode :" << mode;
      return false;
    }
    HANDLE local_handle;
    if (!DuplicateHandle(GetCurrentProcess(),
                         channel_handle.pipe.handle,
                         GetCurrentProcess(),
                         &local_handle,
                         0,
                         FALSE,
                         DUPLICATE_SAME_ACCESS)) {
      LOG(WARNING) << "DuplicateHandle failed. Error :" << GetLastError();
      return false;
    }
    pipe_.Set(local_handle);
  } else if (mode & MODE_SERVER_FLAG) {
    DCHECK(!channel_handle.pipe.handle);
    const DWORD open_mode = PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED |
                            FILE_FLAG_FIRST_PIPE_INSTANCE;
    pipe_name = PipeName(channel_handle.name, &client_secret_);
    validate_client_ = !!client_secret_;
    pipe_.Set(CreateNamedPipeW(pipe_name.c_str(),
                               open_mode,
                               PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
                               1,
                               Channel::kReadBufferSize,
                               Channel::kReadBufferSize,
                               5000,
                               NULL));
  } else if (mode & MODE_CLIENT_FLAG) {
    DCHECK(!channel_handle.pipe.handle);
    pipe_name = PipeName(channel_handle.name, &client_secret_);
    pipe_.Set(CreateFileW(pipe_name.c_str(),
                          GENERIC_READ | GENERIC_WRITE,
                          0,
                          NULL,
                          OPEN_EXISTING,
                          SECURITY_SQOS_PRESENT | SECURITY_ANONYMOUS |
                              FILE_FLAG_OVERLAPPED,
                          NULL));
  } else {
    NOTREACHED();
  }

  if (!pipe_.IsValid()) {
    // If this process is being closed, the pipe may be gone already.
    PLOG(WARNING) << "Unable to create pipe \"" << pipe_name << "\" in "
                  << (mode & MODE_SERVER_FLAG ? "server" : "client") << " mode";
    return false;
  }

  // Create the Hello message to be sent when Connect is called
  scoped_ptr<Message> m(new Message(MSG_ROUTING_NONE,
                                    HELLO_MESSAGE_TYPE,
                                    IPC::Message::PRIORITY_NORMAL));

  // Don't send the secret to the untrusted process, and don't send a secret
  // if the value is zero (for IPC backwards compatability).
  int32_t secret = validate_client_ ? 0 : client_secret_;
  if (!m->WriteInt(GetCurrentProcessId()) ||
      (secret && !m->WriteUInt32(secret))) {
    pipe_.Close();
    return false;
  }

  OutputElement* element = new OutputElement(m.release());
  output_queue_.push(element);
  return true;
}

bool ChannelWin::Connect() {
  DLOG_IF(WARNING, thread_check_.get()) << "Connect called more than once";

  if (!thread_check_.get())
    thread_check_.reset(new base::ThreadChecker());

  if (!pipe_.IsValid())
    return false;

  base::MessageLoopForIO::current()->RegisterIOHandler(pipe_.Get(), this);

  // Check to see if there is a client connected to our pipe...
  if (waiting_connect_)
    ProcessConnection();

  if (!input_state_.is_pending) {
    // Complete setup asynchronously. By not setting input_state_.is_pending
    // to true, we indicate to OnIOCompleted that this is the special
    // initialization signal.
    base::MessageLoopForIO::current()->PostTask(
        FROM_HERE,
        base::Bind(&ChannelWin::OnIOCompleted,
                   weak_factory_.GetWeakPtr(),
                   &input_state_.context,
                   0,
                   0));
  }

  if (!waiting_connect_)
    ProcessOutgoingMessages(NULL, 0);
  return true;
}

bool ChannelWin::ProcessConnection() {
  DCHECK(thread_check_->CalledOnValidThread());
  if (input_state_.is_pending)
    input_state_.is_pending = false;

  // Do we have a client connected to our pipe?
  if (!pipe_.IsValid())
    return false;

  BOOL ok = ConnectNamedPipe(pipe_.Get(), &input_state_.context.overlapped);
  DWORD err = GetLastError();
  if (ok) {
    // Uhm, the API documentation says that this function should never
    // return success when used in overlapped mode.
    NOTREACHED();
    return false;
  }

  switch (err) {
  case ERROR_IO_PENDING:
    input_state_.is_pending = true;
    break;
  case ERROR_PIPE_CONNECTED:
    waiting_connect_ = false;
    break;
  case ERROR_NO_DATA:
    // The pipe is being closed.
    return false;
  default:
    NOTREACHED();
    return false;
  }

  return true;
}

bool ChannelWin::ProcessOutgoingMessages(
    base::MessageLoopForIO::IOContext* context,
    DWORD bytes_written) {
  DCHECK(!waiting_connect_);  // Why are we trying to send messages if there's
                              // no connection?
  DCHECK(thread_check_->CalledOnValidThread());

  if (output_state_.is_pending) {
    DCHECK(context);
    output_state_.is_pending = false;
    if (!context || bytes_written == 0) {
      DWORD err = GetLastError();
      LOG(ERROR) << "pipe error: " << err;
      return false;
    }
    // Message was sent.
    CHECK(!output_queue_.empty());
    OutputElement* element = output_queue_.front();
    output_queue_.pop();
    delete element;
  }

  if (output_queue_.empty())
    return true;

  if (!pipe_.IsValid())
    return false;

  // Write to pipe...
  OutputElement* element = output_queue_.front();
  DCHECK(element->size() <= INT_MAX);
  BOOL ok = WriteFile(pipe_.Get(),
                      element->data(),
                      static_cast<uint32_t>(element->size()),
                      NULL,
                      &output_state_.context.overlapped);
  if (!ok) {
    DWORD write_error = GetLastError();
    if (write_error == ERROR_IO_PENDING) {
      output_state_.is_pending = true;

      const Message* m = element->get_message();
      if (m) {
        DVLOG(2) << "sent pending message @" << m << " on channel @" << this
                 << " with type " << m->type();
      }

      return true;
    }
    LOG(ERROR) << "pipe error: " << write_error;
    return false;
  }

  const Message* m = element->get_message();
  if (m) {
    DVLOG(2) << "sent message @" << m << " on channel @" << this
             << " with type " << m->type();
  }

  output_state_.is_pending = true;
  return true;
}

void ChannelWin::OnIOCompleted(
    base::MessageLoopForIO::IOContext* context,
    DWORD bytes_transfered,
    DWORD error) {
  bool ok = true;
  DCHECK(thread_check_->CalledOnValidThread());
  if (context == &input_state_.context) {
    if (waiting_connect_) {
      if (!ProcessConnection())
        return;
      // We may have some messages queued up to send...
      if (!output_queue_.empty() && !output_state_.is_pending)
        ProcessOutgoingMessages(NULL, 0);
      if (input_state_.is_pending)
        return;
      // else, fall-through and look for incoming messages...
    }

    // We don't support recursion through OnMessageReceived yet!
    DCHECK(!processing_incoming_);
    base::AutoReset<bool> auto_reset_processing_incoming(
        &processing_incoming_, true);

    // Process the new data.
    if (input_state_.is_pending) {
      // This is the normal case for everything except the initialization step.
      input_state_.is_pending = false;
      if (!bytes_transfered) {
        ok = false;
      } else if (pipe_.IsValid()) {
        ok = (AsyncReadComplete(bytes_transfered) != DISPATCH_ERROR);
      }
    } else {
      DCHECK(!bytes_transfered);
    }

    // Request more data.
    if (ok)
      ok = (ProcessIncomingMessages() != DISPATCH_ERROR);
  } else {
    DCHECK(context == &output_state_.context);
    CHECK(output_state_.is_pending);
    ok = ProcessOutgoingMessages(context, bytes_transfered);
  }
  if (!ok && pipe_.IsValid()) {
    // We don't want to re-enter Close().
    Close();
    listener()->OnChannelError();
  }
}

//------------------------------------------------------------------------------
// Channel's methods

// static
scoped_ptr<Channel> Channel::Create(const IPC::ChannelHandle& channel_handle,
                                    Mode mode,
                                    Listener* listener) {
  return scoped_ptr<Channel>(new ChannelWin(channel_handle, mode, listener));
}

// static
bool Channel::IsNamedServerInitialized(const std::string& channel_id) {
  return ChannelWin::IsNamedServerInitialized(channel_id);
}

// static
std::string Channel::GenerateVerifiedChannelID(const std::string& prefix) {
  // Windows pipes can be enumerated by low-privileged processes. So, we
  // append a strong random value after the \ character. This value is not
  // included in the pipe name, but sent as part of the client hello, to
  // hijacking the pipe name to spoof the client.

  std::string id = prefix;
  if (!id.empty())
    id.append(".");

  int secret;
  do {  // Guarantee we get a non-zero value.
    secret = base::RandInt(0, std::numeric_limits<int>::max());
  } while (secret == 0);

  id.append(GenerateUniqueRandomChannelID());
  return id.append(base::StringPrintf("\\%d", secret));
}

}  // namespace IPC
