/* Copyright (c) 2014, Google Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

// Suppress MSVC's STL warnings. It flags |std::copy| calls with a raw output
// pointer, on grounds that MSVC cannot check them. Unfortunately, there is no
// way to suppress the warning just on one line. The warning is flagged inside
// the STL itself, so suppressing at the |std::copy| call does not work.
#if !defined(_SCL_SECURE_NO_WARNINGS)
#define _SCL_SECURE_NO_WARNINGS
#endif

#include <openssl/base.h>

#include <string>
#include <vector>

#include <errno.h>
#include <limits.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>

#if !defined(OPENSSL_WINDOWS)
#include <arpa/inet.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <unistd.h>
#else
#include <algorithm>
#include <condition_variable>
#include <deque>
#include <memory>
#include <mutex>
#include <thread>
#include <utility>

#include <io.h>
OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <winsock2.h>
#include <ws2tcpip.h>
OPENSSL_MSVC_PRAGMA(warning(pop))

OPENSSL_MSVC_PRAGMA(comment(lib, "Ws2_32.lib"))
#endif

#include <openssl/err.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>

#include "../crypto/internal.h"
#include "internal.h"
#include "transport_common.h"


#if defined(OPENSSL_WINDOWS)
using socket_result_t = int;
#else
using socket_result_t = ssize_t;
static int closesocket(int sock) {
  return close(sock);
}
#endif

bool InitSocketLibrary() {
#if defined(OPENSSL_WINDOWS)
  WSADATA wsaData;
  int err = WSAStartup(MAKEWORD(2, 2), &wsaData);
  if (err != 0) {
    fprintf(stderr, "WSAStartup failed with error %d\n", err);
    return false;
  }
#endif
  return true;
}

static void SplitHostPort(std::string *out_hostname, std::string *out_port,
                          const std::string &hostname_and_port) {
  size_t colon_offset = hostname_and_port.find_last_of(':');
  const size_t bracket_offset = hostname_and_port.find_last_of(']');
  std::string hostname, port;

  // An IPv6 literal may have colons internally, guarded by square brackets.
  if (bracket_offset != std::string::npos &&
      colon_offset != std::string::npos && bracket_offset > colon_offset) {
    colon_offset = std::string::npos;
  }

  if (colon_offset == std::string::npos) {
    *out_hostname = hostname_and_port;
    *out_port = "443";
  } else {
    *out_hostname = hostname_and_port.substr(0, colon_offset);
    *out_port = hostname_and_port.substr(colon_offset + 1);
  }
}

static std::string GetLastSocketErrorString() {
#if defined(OPENSSL_WINDOWS)
  int error = WSAGetLastError();
  char *buffer;
  DWORD len = FormatMessageA(
      FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, 0, error, 0,
      reinterpret_cast<char *>(&buffer), 0, nullptr);
  if (len == 0) {
    char buf[256];
    snprintf(buf, sizeof(buf), "unknown error (0x%x)", error);
    return buf;
  }
  std::string ret(buffer, len);
  LocalFree(buffer);
  return ret;
#else
  return strerror(errno);
#endif
}

static void PrintSocketError(const char *function) {
  // On Windows, |perror| and |errno| are part of the C runtime, while sockets
  // are separate, so we must print errors manually.
  std::string error = GetLastSocketErrorString();
  fprintf(stderr, "%s: %s\n", function, error.c_str());
}

// Connect sets |*out_sock| to be a socket connected to the destination given
// in |hostname_and_port|, which should be of the form "www.example.com:123".
// It returns true on success and false otherwise.
bool Connect(int *out_sock, const std::string &hostname_and_port) {
  std::string hostname, port;
  SplitHostPort(&hostname, &port, hostname_and_port);

  // Handle IPv6 literals.
  if (hostname.size() >= 2 && hostname[0] == '[' &&
      hostname[hostname.size() - 1] == ']') {
    hostname = hostname.substr(1, hostname.size() - 2);
  }

  struct addrinfo hint, *result;
  OPENSSL_memset(&hint, 0, sizeof(hint));
  hint.ai_family = AF_UNSPEC;
  hint.ai_socktype = SOCK_STREAM;

  int ret = getaddrinfo(hostname.c_str(), port.c_str(), &hint, &result);
  if (ret != 0) {
#if defined(OPENSSL_WINDOWS)
    const char *error = gai_strerrorA(ret);
#else
    const char *error = gai_strerror(ret);
#endif
    fprintf(stderr, "getaddrinfo returned: %s\n", error);
    return false;
  }

  bool ok = false;
  char buf[256];

  *out_sock =
      socket(result->ai_family, result->ai_socktype, result->ai_protocol);
  if (*out_sock < 0) {
    PrintSocketError("socket");
    goto out;
  }

  switch (result->ai_family) {
    case AF_INET: {
      struct sockaddr_in *sin =
          reinterpret_cast<struct sockaddr_in *>(result->ai_addr);
      fprintf(stderr, "Connecting to %s:%d\n",
              inet_ntop(result->ai_family, &sin->sin_addr, buf, sizeof(buf)),
              ntohs(sin->sin_port));
      break;
    }
    case AF_INET6: {
      struct sockaddr_in6 *sin6 =
          reinterpret_cast<struct sockaddr_in6 *>(result->ai_addr);
      fprintf(stderr, "Connecting to [%s]:%d\n",
              inet_ntop(result->ai_family, &sin6->sin6_addr, buf, sizeof(buf)),
              ntohs(sin6->sin6_port));
      break;
    }
  }

  if (connect(*out_sock, result->ai_addr, result->ai_addrlen) != 0) {
    PrintSocketError("connect");
    goto out;
  }
  ok = true;

out:
  freeaddrinfo(result);
  return ok;
}

Listener::~Listener() {
  if (server_sock_ >= 0) {
    closesocket(server_sock_);
  }
}

bool Listener::Init(const std::string &port) {
  if (server_sock_ >= 0) {
    return false;
  }

  struct sockaddr_in6 addr;
  OPENSSL_memset(&addr, 0, sizeof(addr));

  addr.sin6_family = AF_INET6;
  // Windows' IN6ADDR_ANY_INIT does not have enough curly braces for clang-cl
  // (https://crbug.com/772108), while other platforms like NaCl are missing
  // in6addr_any, so use a mix of both.
#if defined(OPENSSL_WINDOWS)
  addr.sin6_addr = in6addr_any;
#else
  addr.sin6_addr = IN6ADDR_ANY_INIT;
#endif
  addr.sin6_port = htons(atoi(port.c_str()));

#if defined(OPENSSL_WINDOWS)
  const BOOL enable = TRUE;
#else
  const int enable = 1;
#endif

  server_sock_ = socket(addr.sin6_family, SOCK_STREAM, 0);
  if (server_sock_ < 0) {
    PrintSocketError("socket");
    return false;
  }

  if (setsockopt(server_sock_, SOL_SOCKET, SO_REUSEADDR, (const char *)&enable,
                 sizeof(enable)) < 0) {
    PrintSocketError("setsockopt");
    return false;
  }

  if (bind(server_sock_, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
    PrintSocketError("connect");
    return false;
  }

  listen(server_sock_, SOMAXCONN);
  return true;
}

bool Listener::Accept(int *out_sock) {
  struct sockaddr_in6 addr;
  socklen_t addr_len = sizeof(addr);
  *out_sock = accept(server_sock_, (struct sockaddr *)&addr, &addr_len);
  return *out_sock >= 0;
}

bool VersionFromString(uint16_t *out_version, const std::string &version) {
  if (version == "tls1" || version == "tls1.0") {
    *out_version = TLS1_VERSION;
    return true;
  } else if (version == "tls1.1") {
    *out_version = TLS1_1_VERSION;
    return true;
  } else if (version == "tls1.2") {
    *out_version = TLS1_2_VERSION;
    return true;
  } else if (version == "tls1.3") {
    *out_version = TLS1_3_VERSION;
    return true;
  }
  return false;
}

void PrintConnectionInfo(BIO *bio, const SSL *ssl) {
  const SSL_CIPHER *cipher = SSL_get_current_cipher(ssl);

  BIO_printf(bio, "  Version: %s\n", SSL_get_version(ssl));
  BIO_printf(bio, "  Resumed session: %s\n",
             SSL_session_reused(ssl) ? "yes" : "no");
  BIO_printf(bio, "  Cipher: %s\n", SSL_CIPHER_standard_name(cipher));
  uint16_t curve = SSL_get_curve_id(ssl);
  if (curve != 0) {
    BIO_printf(bio, "  ECDHE curve: %s\n", SSL_get_curve_name(curve));
  }
  uint16_t sigalg = SSL_get_peer_signature_algorithm(ssl);
  if (sigalg != 0) {
    BIO_printf(bio, "  Signature algorithm: %s\n",
               SSL_get_signature_algorithm_name(
                   sigalg, SSL_version(ssl) != TLS1_2_VERSION));
  }
  BIO_printf(bio, "  Secure renegotiation: %s\n",
             SSL_get_secure_renegotiation_support(ssl) ? "yes" : "no");
  BIO_printf(bio, "  Extended master secret: %s\n",
             SSL_get_extms_support(ssl) ? "yes" : "no");

  const uint8_t *next_proto;
  unsigned next_proto_len;
  SSL_get0_next_proto_negotiated(ssl, &next_proto, &next_proto_len);
  BIO_printf(bio, "  Next protocol negotiated: %.*s\n", next_proto_len,
             next_proto);

  const uint8_t *alpn;
  unsigned alpn_len;
  SSL_get0_alpn_selected(ssl, &alpn, &alpn_len);
  BIO_printf(bio, "  ALPN protocol: %.*s\n", alpn_len, alpn);

  const char *host_name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
  if (host_name != nullptr && SSL_is_server(ssl)) {
    BIO_printf(bio, "  Client sent SNI: %s\n", host_name);
  }

  if (!SSL_is_server(ssl)) {
    const uint8_t *ocsp_staple;
    size_t ocsp_staple_len;
    SSL_get0_ocsp_response(ssl, &ocsp_staple, &ocsp_staple_len);
    BIO_printf(bio, "  OCSP staple: %s\n", ocsp_staple_len > 0 ? "yes" : "no");

    const uint8_t *sct_list;
    size_t sct_list_len;
    SSL_get0_signed_cert_timestamp_list(ssl, &sct_list, &sct_list_len);
    BIO_printf(bio, "  SCT list: %s\n", sct_list_len > 0 ? "yes" : "no");
  }

  BIO_printf(
      bio, "  Early data: %s\n",
      (SSL_early_data_accepted(ssl) || SSL_in_early_data(ssl)) ? "yes" : "no");

  // Print the server cert subject and issuer names.
  bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(ssl));
  if (peer != nullptr) {
    BIO_printf(bio, "  Cert subject: ");
    X509_NAME_print_ex(bio, X509_get_subject_name(peer.get()), 0,
                       XN_FLAG_ONELINE);
    BIO_printf(bio, "\n  Cert issuer: ");
    X509_NAME_print_ex(bio, X509_get_issuer_name(peer.get()), 0,
                       XN_FLAG_ONELINE);
    BIO_printf(bio, "\n");
  }
}

bool SocketSetNonBlocking(int sock, bool is_non_blocking) {
  bool ok;

#if defined(OPENSSL_WINDOWS)
  u_long arg = is_non_blocking;
  ok = 0 == ioctlsocket(sock, FIONBIO, &arg);
#else
  int flags = fcntl(sock, F_GETFL, 0);
  if (flags < 0) {
    return false;
  }
  if (is_non_blocking) {
    flags |= O_NONBLOCK;
  } else {
    flags &= ~O_NONBLOCK;
  }
  ok = 0 == fcntl(sock, F_SETFL, flags);
#endif
  if (!ok) {
    PrintSocketError("Failed to set socket non-blocking");
  }
  return ok;
}

enum class StdinWait {
  kStdinRead,
  kSocketWrite,
};

#if !defined(OPENSSL_WINDOWS)

// SocketWaiter abstracts waiting for either the socket or stdin to be readable
// between Windows and POSIX.
class SocketWaiter {
 public:
  explicit SocketWaiter(int sock) : sock_(sock) {}
  SocketWaiter(const SocketWaiter &) = delete;
  SocketWaiter &operator=(const SocketWaiter &) = delete;

  // Init initializes the SocketWaiter. It returns whether it succeeded.
  bool Init() { return true; }

  // Wait waits for at least on of the socket or stdin or be ready. On success,
  // it sets |*socket_ready| and |*stdin_ready| to whether the respective
  // objects are readable and returns true. On error, it returns false. stdin's
  // readiness may either be the socket being writable or stdin being readable,
  // depending on |stdin_wait|.
  bool Wait(StdinWait stdin_wait, bool *socket_ready, bool *stdin_ready) {
    *socket_ready = true;
    *stdin_ready = false;

    fd_set read_fds, write_fds;
    FD_ZERO(&read_fds);
    FD_ZERO(&write_fds);
    if (stdin_wait == StdinWait::kSocketWrite) {
      FD_SET(sock_, &write_fds);
    } else if (stdin_open_) {
      FD_SET(STDIN_FILENO, &read_fds);
    }
    FD_SET(sock_, &read_fds);
    if (select(sock_ + 1, &read_fds, &write_fds, NULL, NULL) <= 0) {
      perror("select");
      return false;
    }

    if (FD_ISSET(STDIN_FILENO, &read_fds) || FD_ISSET(sock_, &write_fds)) {
      *stdin_ready = true;
    }
    if (FD_ISSET(sock_, &read_fds)) {
      *socket_ready = true;
    }

    return true;
  }

  // ReadStdin reads at most |max_out| bytes from stdin. On success, it writes
  // them to |out| and sets |*out_len| to the number of bytes written. On error,
  // it returns false. This method may only be called after |Wait| returned
  // stdin was ready.
  bool ReadStdin(void *out, size_t *out_len, size_t max_out) {
    ssize_t n;
    do {
      n = read(STDIN_FILENO, out, max_out);
    } while (n == -1 && errno == EINTR);
    if (n <= 0) {
      stdin_open_ = false;
    }
    if (n < 0) {
      perror("read from stdin");
      return false;
    }
    *out_len = static_cast<size_t>(n);
    return true;
  }

 private:
   bool stdin_open_ = true;
   int sock_;
};

#else // OPENSSL_WINDOWs

class ScopedWSAEVENT {
 public:
  ScopedWSAEVENT() = default;
  ScopedWSAEVENT(WSAEVENT event) { reset(event); }
  ScopedWSAEVENT(const ScopedWSAEVENT &) = delete;
  ScopedWSAEVENT(ScopedWSAEVENT &&other) { *this = std::move(other); }

  ~ScopedWSAEVENT() { reset(); }

  ScopedWSAEVENT &operator=(const ScopedWSAEVENT &) = delete;
  ScopedWSAEVENT &operator=(ScopedWSAEVENT &&other) {
    reset(other.release());
    return *this;
  }

  explicit operator bool() const { return event_ != WSA_INVALID_EVENT; }
  WSAEVENT get() const { return event_; }

  WSAEVENT release() {
    WSAEVENT ret = event_;
    event_ = WSA_INVALID_EVENT;
    return ret;
  }

  void reset(WSAEVENT event = WSA_INVALID_EVENT) {
    if (event_ != WSA_INVALID_EVENT) {
      WSACloseEvent(event_);
    }
    event_ = event;
  }

 private:
  WSAEVENT event_ = WSA_INVALID_EVENT;
};

// SocketWaiter, on Windows, is more complicated. While |WaitForMultipleObjects|
// works for both sockets and stdin, the latter is often a line-buffered
// console. The |HANDLE| is considered readable if there are any console events
// available, but reading blocks until a full line is available.
//
// So that |Wait| reflects final stdin read, we spawn a stdin reader thread that
// writes to an in-memory buffer and signals a |WSAEVENT| to coordinate with the
// socket.
class SocketWaiter {
 public:
  explicit SocketWaiter(int sock) : sock_(sock) {}
  SocketWaiter(const SocketWaiter &) = delete;
  SocketWaiter &operator=(const SocketWaiter &) = delete;

  bool Init() {
    stdin_ = std::make_shared<StdinState>();
    stdin_->event.reset(WSACreateEvent());
    if (!stdin_->event) {
      PrintSocketError("Error in WSACreateEvent");
      return false;
    }

    // Spawn a thread to block on stdin.
    std::shared_ptr<StdinState> state = stdin_;
    std::thread thread([state]() {
      for (;;) {
        uint8_t buf[512];
        int ret = _read(0 /* stdin */, buf, sizeof(buf));
        if (ret <= 0) {
          if (ret < 0) {
            perror("read from stdin");
          }
          // Report the error or EOF to the caller.
          std::lock_guard<std::mutex> lock(state->lock);
          state->error = ret < 0;
          state->open = false;
          WSASetEvent(state->event.get());
          return;
        }

        size_t len = static_cast<size_t>(ret);
        size_t written = 0;
        while (written < len) {
          std::unique_lock<std::mutex> lock(state->lock);
          // Wait for there to be room in the buffer.
          state->cond.wait(lock, [&] { return !state->buffer_full(); });

          // Copy what we can and signal to the caller.
          size_t todo = std::min(len - written, state->buffer_remaining());
          state->buffer.insert(state->buffer.end(), buf + written,
                               buf + written + todo);
          written += todo;
          WSASetEvent(state->event.get());
        }
      }
    });
    thread.detach();
    return true;
  }

  bool Wait(StdinWait stdin_wait, bool *socket_ready, bool *stdin_ready) {
    *socket_ready = true;
    *stdin_ready = false;

    ScopedWSAEVENT sock_read_event(WSACreateEvent());
    if (!sock_read_event ||
        WSAEventSelect(sock_, sock_read_event.get(), FD_READ | FD_CLOSE) != 0) {
      PrintSocketError("Error waiting for socket read");
      return false;
    }

    DWORD count = 1;
    WSAEVENT events[3] = {sock_read_event.get(), WSA_INVALID_EVENT};
    ScopedWSAEVENT sock_write_event;
    if (stdin_wait == StdinWait::kSocketWrite) {
      sock_write_event.reset(WSACreateEvent());
      if (!sock_write_event || WSAEventSelect(sock_, sock_write_event.get(),
                                              FD_WRITE | FD_CLOSE) != 0) {
        PrintSocketError("Error waiting for socket write");
        return false;
      }
      events[1] = sock_write_event.get();
      count++;
    } else if (listen_stdin_) {
      events[1] = stdin_->event.get();
      count++;
    }

    switch (WSAWaitForMultipleEvents(count, events, FALSE /* wait all */,
                                     WSA_INFINITE, FALSE /* alertable */)) {
      case WSA_WAIT_EVENT_0 + 0:
        *socket_ready = true;
        return true;
      case WSA_WAIT_EVENT_0 + 1:
        *stdin_ready = true;
        return true;
      case WSA_WAIT_TIMEOUT:
        return true;
      default:
        PrintSocketError("Error waiting for events");
        return false;
    }
  }

  bool ReadStdin(void *out, size_t *out_len, size_t max_out) {
    std::lock_guard<std::mutex> locked(stdin_->lock);

    if (stdin_->buffer.empty()) {
      // |ReadStdin| may only be called when |Wait| signals it is ready, so
      // stdin must have reached EOF or error.
      assert(!stdin_->open);
      listen_stdin_ = false;
      if (stdin_->error) {
        return false;
      }
      *out_len = 0;
      return true;
    }

    bool was_full = stdin_->buffer_full();
    // Copy as many bytes as well fit.
    *out_len = std::min(max_out, stdin_->buffer.size());
    auto begin = stdin_->buffer.begin();
    auto end = stdin_->buffer.begin() + *out_len;
    std::copy(begin, end, static_cast<uint8_t *>(out));
    stdin_->buffer.erase(begin, end);
    // Notify the stdin thread if there is more space.
    if (was_full && !stdin_->buffer_full()) {
      stdin_->cond.notify_one();
    }
    // If stdin is now waiting for input, clear the event.
    if (stdin_->buffer.empty() && stdin_->open) {
      WSAResetEvent(stdin_->event.get());
    }
    return true;
  }

 private:
  struct StdinState {
    static constexpr size_t kMaxBuffer = 1024;

    StdinState() = default;
    StdinState(const StdinState &) = delete;
    StdinState &operator=(const StdinState &) = delete;

    size_t buffer_remaining() const { return kMaxBuffer - buffer.size(); }
    bool buffer_full() const { return buffer_remaining() == 0; }

    ScopedWSAEVENT event;
    // lock protects the following fields.
    std::mutex lock;
    // cond notifies the stdin thread that |buffer| is no longer full.
    std::condition_variable cond;
    std::deque<uint8_t> buffer;
    bool open = true;
    bool error = false;
  };

  int sock_;
  std::shared_ptr<StdinState> stdin_;
  // listen_stdin_ is set to false when we have consumed an EOF or error from
  // |stdin_|. This is separate from |stdin_->open| because the signal may not
  // have been consumed yet.
  bool listen_stdin_ = true;
};

#endif  // OPENSSL_WINDOWS

void PrintSSLError(FILE *file, const char *msg, int ssl_err, int ret) {
  switch (ssl_err) {
    case SSL_ERROR_SSL:
      fprintf(file, "%s: %s\n", msg, ERR_reason_error_string(ERR_peek_error()));
      break;
    case SSL_ERROR_SYSCALL:
      if (ret == 0) {
        fprintf(file, "%s: peer closed connection\n", msg);
      } else {
        std::string error = GetLastSocketErrorString();
        fprintf(file, "%s: %s\n", msg, error.c_str());
      }
      break;
    case SSL_ERROR_ZERO_RETURN:
      fprintf(file, "%s: received close_notify\n", msg);
      break;
    default:
      fprintf(file, "%s: unexpected error: %s\n", msg,
              SSL_error_description(ssl_err));
  }
  ERR_print_errors_fp(file);
}

bool TransferData(SSL *ssl, int sock) {
  if (!SocketSetNonBlocking(sock, true)) {
    return false;
  }

  SocketWaiter waiter(sock);
  if (!waiter.Init()) {
    return false;
  }

  uint8_t pending_write[512];
  size_t pending_write_len = 0;
  for (;;) {
    bool socket_ready = false;
    bool stdin_ready = false;
    if (!waiter.Wait(pending_write_len == 0 ? StdinWait::kStdinRead
                                            : StdinWait::kSocketWrite,
                     &socket_ready, &stdin_ready)) {
      return false;
    }

    if (stdin_ready) {
      if (pending_write_len == 0) {
        if (!waiter.ReadStdin(pending_write, &pending_write_len,
                              sizeof(pending_write))) {
          return false;
        }
        if (pending_write_len == 0) {
  #if !defined(OPENSSL_WINDOWS)
          shutdown(sock, SHUT_WR);
  #else
          shutdown(sock, SD_SEND);
  #endif
          continue;
        }
      }

      int ssl_ret =
          SSL_write(ssl, pending_write, static_cast<int>(pending_write_len));
      if (ssl_ret <= 0) {
        int ssl_err = SSL_get_error(ssl, ssl_ret);
        if (ssl_err == SSL_ERROR_WANT_WRITE) {
          continue;
        }
        PrintSSLError(stderr, "Error while writing", ssl_err, ssl_ret);
        return false;
      }
      if (ssl_ret != static_cast<int>(pending_write_len)) {
        fprintf(stderr, "Short write from SSL_write.\n");
        return false;
      }
      pending_write_len = 0;
    }

    if (socket_ready) {
      for (;;) {
        uint8_t buffer[512];
        int ssl_ret = SSL_read(ssl, buffer, sizeof(buffer));

        if (ssl_ret < 0) {
          int ssl_err = SSL_get_error(ssl, ssl_ret);
          if (ssl_err == SSL_ERROR_WANT_READ) {
            break;
          }
          PrintSSLError(stderr, "Error while reading", ssl_err, ssl_ret);
          return false;
        } else if (ssl_ret == 0) {
          return true;
        }

        size_t n;
        if (!WriteToFD(1, &n, buffer, ssl_ret)) {
          fprintf(stderr, "Error writing to stdout.\n");
          return false;
        }

        if (n != static_cast<size_t>(ssl_ret)) {
          fprintf(stderr, "Short write to stderr.\n");
          return false;
        }
      }
    }
  }
}

// SocketLineReader wraps a small buffer around a socket for line-orientated
// protocols.
class SocketLineReader {
 public:
  explicit SocketLineReader(int sock) : sock_(sock) {}

  // Next reads a '\n'- or '\r\n'-terminated line from the socket and, on
  // success, sets |*out_line| to it and returns true. Otherwise it returns
  // false.
  bool Next(std::string *out_line) {
    for (;;) {
      for (size_t i = 0; i < buf_len_; i++) {
        if (buf_[i] != '\n') {
          continue;
        }

        size_t length = i;
        if (i > 0 && buf_[i - 1] == '\r') {
          length--;
        }

        out_line->assign(buf_, length);
        buf_len_ -= i + 1;
        OPENSSL_memmove(buf_, &buf_[i + 1], buf_len_);

        return true;
      }

      if (buf_len_ == sizeof(buf_)) {
        fprintf(stderr, "Received line too long!\n");
        return false;
      }

      socket_result_t n;
      do {
        n = recv(sock_, &buf_[buf_len_], sizeof(buf_) - buf_len_, 0);
      } while (n == -1 && errno == EINTR);

      if (n < 0) {
        fprintf(stderr, "Read error from socket\n");
        return false;
      }

      buf_len_ += n;
    }
  }

  // ReadSMTPReply reads one or more lines that make up an SMTP reply. On
  // success, it sets |*out_code| to the reply's code (e.g. 250) and
  // |*out_content| to the body of the reply (e.g. "OK") and returns true.
  // Otherwise it returns false.
  //
  // See https://tools.ietf.org/html/rfc821#page-48
  bool ReadSMTPReply(unsigned *out_code, std::string *out_content) {
    out_content->clear();

    // kMaxLines is the maximum number of lines that we'll accept in an SMTP
    // reply.
    static const unsigned kMaxLines = 512;
    for (unsigned i = 0; i < kMaxLines; i++) {
      std::string line;
      if (!Next(&line)) {
        return false;
      }

      if (line.size() < 4) {
        fprintf(stderr, "Short line from SMTP server: %s\n", line.c_str());
        return false;
      }

      const std::string code_str = line.substr(0, 3);
      char *endptr;
      const unsigned long code = strtoul(code_str.c_str(), &endptr, 10);
      if (*endptr || code > UINT_MAX) {
        fprintf(stderr, "Failed to parse code from line: %s\n", line.c_str());
        return false;
      }

      if (i == 0) {
        *out_code = code;
      } else if (code != *out_code) {
        fprintf(stderr,
                "Reply code varied within a single reply: was %u, now %u\n",
                *out_code, static_cast<unsigned>(code));
        return false;
      }

      if (line[3] == ' ') {
        // End of reply.
        *out_content += line.substr(4, std::string::npos);
        return true;
      } else if (line[3] == '-') {
        // Another line of reply will follow this one.
        *out_content += line.substr(4, std::string::npos);
        out_content->push_back('\n');
      } else {
        fprintf(stderr, "Bad character after code in SMTP reply: %s\n",
                line.c_str());
        return false;
      }
    }

    fprintf(stderr, "Rejected SMTP reply of more then %u lines\n", kMaxLines);
    return false;
  }

 private:
  const int sock_;
  char buf_[512];
  size_t buf_len_ = 0;
};

// SendAll writes |data_len| bytes from |data| to |sock|. It returns true on
// success and false otherwise.
static bool SendAll(int sock, const char *data, size_t data_len) {
  size_t done = 0;

  while (done < data_len) {
    socket_result_t n;
    do {
      n = send(sock, &data[done], data_len - done, 0);
    } while (n == -1 && errno == EINTR);

    if (n < 0) {
      fprintf(stderr, "Error while writing to socket\n");
      return false;
    }

    done += n;
  }

  return true;
}

bool DoSMTPStartTLS(int sock) {
  SocketLineReader line_reader(sock);

  unsigned code_220 = 0;
  std::string reply_220;
  if (!line_reader.ReadSMTPReply(&code_220, &reply_220)) {
    return false;
  }

  if (code_220 != 220) {
    fprintf(stderr, "Expected 220 line from SMTP server but got code %u\n",
            code_220);
    return false;
  }

  static const char kHelloLine[] = "EHLO BoringSSL\r\n";
  if (!SendAll(sock, kHelloLine, sizeof(kHelloLine) - 1)) {
    return false;
  }

  unsigned code_250 = 0;
  std::string reply_250;
  if (!line_reader.ReadSMTPReply(&code_250, &reply_250)) {
    return false;
  }

  if (code_250 != 250) {
    fprintf(stderr, "Expected 250 line after EHLO but got code %u\n", code_250);
    return false;
  }

  // https://tools.ietf.org/html/rfc1869#section-4.3
  if (("\n" + reply_250 + "\n").find("\nSTARTTLS\n") == std::string::npos) {
    fprintf(stderr, "Server does not support STARTTLS\n");
    return false;
  }

  static const char kSTARTTLSLine[] = "STARTTLS\r\n";
  if (!SendAll(sock, kSTARTTLSLine, sizeof(kSTARTTLSLine) - 1)) {
    return false;
  }

  if (!line_reader.ReadSMTPReply(&code_220, &reply_220)) {
    return false;
  }

  if (code_220 != 220) {
    fprintf(
        stderr,
        "Expected 220 line from SMTP server after STARTTLS, but got code %u\n",
        code_220);
    return false;
  }

  return true;
}

bool DoHTTPTunnel(int sock, const std::string &hostname_and_port) {
  std::string hostname, port;
  SplitHostPort(&hostname, &port, hostname_and_port);

  fprintf(stderr, "Establishing HTTP tunnel to %s:%s.\n", hostname.c_str(),
          port.c_str());
  char buf[1024];
  snprintf(buf, sizeof(buf), "CONNECT %s:%s HTTP/1.0\r\n\r\n", hostname.c_str(),
           port.c_str());
  if (!SendAll(sock, buf, strlen(buf))) {
    return false;
  }

  SocketLineReader line_reader(sock);

  // Read until an empty line, signaling the end of the HTTP response.
  std::string line;
  for (;;) {
    if (!line_reader.Next(&line)) {
      return false;
    }
    if (line.empty()) {
      return true;
    }
    fprintf(stderr, "%s\n", line.c_str());
  }
}
