19 #if !defined(_SCL_SECURE_NO_WARNINGS)
20 #define _SCL_SECURE_NO_WARNINGS
33 #include <sys/types.h>
35 #if !defined(OPENSSL_WINDOWS)
36 #include <arpa/inet.h>
39 #include <netinet/in.h>
40 #include <sys/select.h>
41 #include <sys/socket.h>
45 #include <condition_variable>
65 #include "../crypto/internal.h"
70 #if defined(OPENSSL_WINDOWS)
80 #if defined(OPENSSL_WINDOWS)
82 int err = WSAStartup(MAKEWORD(2, 2), &wsaData);
84 fprintf(
stderr,
"WSAStartup failed with error %d\n",
err);
93 size_t colon_offset = hostname_and_port.find_last_of(
':');
94 const size_t bracket_offset = hostname_and_port.find_last_of(
']');
98 if (bracket_offset != std::string::npos &&
99 colon_offset != std::string::npos && bracket_offset > colon_offset) {
100 colon_offset = std::string::npos;
103 if (colon_offset == std::string::npos) {
104 *out_hostname = hostname_and_port;
107 *out_hostname = hostname_and_port.substr(0, colon_offset);
108 *out_port = hostname_and_port.substr(colon_offset + 1);
113 #if defined(OPENSSL_WINDOWS)
114 int error = WSAGetLastError();
116 DWORD
len = FormatMessageA(
117 FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, 0,
error, 0,
118 reinterpret_cast<char *
>(&
buffer), 0,
nullptr);
121 snprintf(
buf,
sizeof(
buf),
"unknown error (0x%x)",
error);
128 return strerror(errno);
136 fprintf(
stderr,
"%s: %s\n",
function,
error.c_str());
147 if (hostname.size() >= 2 && hostname[0] ==
'[' &&
148 hostname[hostname.size() - 1] ==
']') {
149 hostname = hostname.substr(1, hostname.size() - 2);
157 int ret = getaddrinfo(hostname.c_str(),
port.c_str(), &hint, &
result);
159 #if defined(OPENSSL_WINDOWS)
160 const char *
error = gai_strerrorA(
ret);
162 const char *
error = gai_strerror(
ret);
164 fprintf(
stderr,
"getaddrinfo returned: %s\n",
error);
178 switch (
result->ai_family) {
180 struct sockaddr_in *sin =
181 reinterpret_cast<struct sockaddr_in *
>(
result->ai_addr);
182 fprintf(
stderr,
"Connecting to %s:%d\n",
183 inet_ntop(
result->ai_family, &sin->sin_addr,
buf,
sizeof(
buf)),
184 ntohs(sin->sin_port));
190 fprintf(
stderr,
"Connecting to [%s]:%d\n",
197 if (connect(*out_sock,
result->ai_addr,
result->ai_addrlen) != 0) {
226 #if defined(OPENSSL_WINDOWS)
227 addr.sin6_addr = in6addr_any;
229 addr.sin6_addr = IN6ADDR_ANY_INIT;
231 addr.sin6_port = htons(atoi(
port.c_str()));
233 #if defined(OPENSSL_WINDOWS)
236 const int enable = 1;
245 if (setsockopt(
server_sock_, SOL_SOCKET, SO_REUSEADDR, (
const char *)&enable,
246 sizeof(enable)) < 0) {
262 socklen_t addr_len =
sizeof(
addr);
264 return *out_sock >= 0;
271 }
else if (
version ==
"tls1.1") {
274 }
else if (
version ==
"tls1.2") {
277 }
else if (
version ==
"tls1.3") {
301 BIO_printf(bio,
" Secure renegotiation: %s\n",
303 BIO_printf(bio,
" Extended master secret: %s\n",
307 unsigned next_proto_len;
309 BIO_printf(bio,
" Next protocol negotiated: %.*s\n", next_proto_len,
315 BIO_printf(bio,
" ALPN protocol: %.*s\n", alpn_len, alpn);
319 BIO_printf(bio,
" Client sent SNI: %s\n", host_name);
324 size_t ocsp_staple_len;
326 BIO_printf(bio,
" OCSP staple: %s\n", ocsp_staple_len > 0 ?
"yes" :
"no");
331 BIO_printf(bio,
" SCT list: %s\n", sct_list_len > 0 ?
"yes" :
"no");
335 bio,
" Early data: %s\n",
338 BIO_printf(bio,
" Encrypted ClientHello: %s\n",
343 if (peer !=
nullptr) {
357 #if defined(OPENSSL_WINDOWS)
358 u_long
arg = is_non_blocking;
359 ok = 0 == ioctlsocket(sock, FIONBIO, &
arg);
361 int flags = fcntl(sock, F_GETFL, 0);
365 if (is_non_blocking) {
368 flags &= ~O_NONBLOCK;
370 ok = 0 == fcntl(sock, F_SETFL,
flags);
383 #if !defined(OPENSSL_WINDOWS)
402 *socket_ready =
true;
403 *stdin_ready =
false;
405 fd_set read_fds, write_fds;
409 FD_SET(
sock_, &write_fds);
411 FD_SET(STDIN_FILENO, &read_fds);
413 FD_SET(
sock_, &read_fds);
414 if (select(
sock_ + 1, &read_fds, &write_fds, NULL, NULL) <= 0) {
419 if (FD_ISSET(STDIN_FILENO, &read_fds) || FD_ISSET(
sock_, &write_fds)) {
422 if (FD_ISSET(
sock_, &read_fds)) {
423 *socket_ready =
true;
436 n =
read(STDIN_FILENO,
out, max_out);
437 }
while (
n == -1 && errno == EINTR);
442 perror(
"read from stdin");
445 *out_len =
static_cast<size_t>(
n);
454 #else // OPENSSL_WINDOWs
456 class ScopedWSAEVENT {
458 ScopedWSAEVENT() =
default;
459 ScopedWSAEVENT(WSAEVENT event) { reset(event); }
460 ScopedWSAEVENT(
const ScopedWSAEVENT &) =
delete;
461 ScopedWSAEVENT(ScopedWSAEVENT &&other) { *
this =
std::move(other); }
463 ~ScopedWSAEVENT() { reset(); }
465 ScopedWSAEVENT &operator=(
const ScopedWSAEVENT &) =
delete;
466 ScopedWSAEVENT &operator=(ScopedWSAEVENT &&other) {
467 reset(other.release());
471 explicit operator bool()
const {
return event_ != WSA_INVALID_EVENT; }
472 WSAEVENT
get()
const {
return event_; }
475 WSAEVENT
ret = event_;
476 event_ = WSA_INVALID_EVENT;
480 void reset(WSAEVENT event = WSA_INVALID_EVENT) {
481 if (event_ != WSA_INVALID_EVENT) {
482 WSACloseEvent(event_);
488 WSAEVENT event_ = WSA_INVALID_EVENT;
506 stdin_ = std::make_shared<StdinState>();
507 stdin_->event.reset(WSACreateEvent());
508 if (!stdin_->event) {
514 std::shared_ptr<StdinState>
state = stdin_;
521 perror(
"read from stdin");
524 std::lock_guard<std::mutex> lock(
state->lock);
527 WSASetEvent(
state->event.get());
531 size_t len =
static_cast<size_t>(
ret);
533 while (written <
len) {
534 std::unique_lock<std::mutex> lock(
state->lock);
536 state->cond.wait(lock, [&] {
return !
state->buffer_full(); });
543 WSASetEvent(
state->event.get());
551 bool Wait(
StdinWait stdin_wait,
bool *socket_ready,
bool *stdin_ready) {
552 *socket_ready =
true;
553 *stdin_ready =
false;
555 ScopedWSAEVENT sock_read_event(WSACreateEvent());
556 if (!sock_read_event ||
557 WSAEventSelect(
sock_, sock_read_event.get(), FD_READ | FD_CLOSE) != 0) {
563 WSAEVENT events[3] = {sock_read_event.get(), WSA_INVALID_EVENT};
564 ScopedWSAEVENT sock_write_event;
566 sock_write_event.reset(WSACreateEvent());
567 if (!sock_write_event || WSAEventSelect(
sock_, sock_write_event.get(),
568 FD_WRITE | FD_CLOSE) != 0) {
572 events[1] = sock_write_event.get();
574 }
else if (listen_stdin_) {
575 events[1] = stdin_->event.get();
579 switch (WSAWaitForMultipleEvents(
count, events,
FALSE ,
580 WSA_INFINITE,
FALSE )) {
581 case WSA_WAIT_EVENT_0 + 0:
582 *socket_ready =
true;
584 case WSA_WAIT_EVENT_0 + 1:
587 case WSA_WAIT_TIMEOUT:
595 bool ReadStdin(
void *
out,
size_t *out_len,
size_t max_out) {
596 std::lock_guard<std::mutex> locked(stdin_->lock);
598 if (stdin_->buffer.empty()) {
601 assert(!stdin_->open);
602 listen_stdin_ =
false;
610 bool was_full = stdin_->buffer_full();
612 *out_len =
std::min(max_out, stdin_->buffer.size());
613 auto begin = stdin_->buffer.begin();
614 auto end = stdin_->buffer.begin() + *out_len;
618 if (was_full && !stdin_->buffer_full()) {
619 stdin_->cond.notify_one();
622 if (stdin_->buffer.empty() && stdin_->open) {
623 WSAResetEvent(stdin_->event.get());
630 static constexpr
size_t kMaxBuffer = 1024;
632 StdinState() =
default;
633 StdinState(
const StdinState &) =
delete;
634 StdinState &
operator=(
const StdinState &) =
delete;
636 size_t buffer_remaining()
const {
return kMaxBuffer -
buffer.size(); }
637 bool buffer_full()
const {
return buffer_remaining() == 0; }
639 ScopedWSAEVENT event;
643 std::condition_variable
cond;
644 std::deque<uint8_t>
buffer;
650 std::shared_ptr<StdinState> stdin_;
654 bool listen_stdin_ =
true;
657 #endif // OPENSSL_WINDOWS
666 fprintf(
file,
"%s: peer closed connection\n",
msg);
673 fprintf(
file,
"%s: received close_notify\n",
msg);
676 fprintf(
file,
"%s: unexpected error: %s\n",
msg,
688 if (!waiter.
Init()) {
693 size_t pending_write_len = 0;
695 bool socket_ready =
false;
696 bool stdin_ready =
false;
699 &socket_ready, &stdin_ready)) {
704 if (pending_write_len == 0) {
705 if (!waiter.
ReadStdin(pending_write, &pending_write_len,
706 sizeof(pending_write))) {
709 if (pending_write_len == 0) {
710 #if !defined(OPENSSL_WINDOWS)
711 shutdown(sock, SHUT_WR);
713 shutdown(sock, SD_SEND);
720 SSL_write(ssl, pending_write,
static_cast<int>(pending_write_len));
729 if (ssl_ret !=
static_cast<int>(pending_write_len)) {
730 fprintf(
stderr,
"Short write from SSL_write.\n");
733 pending_write_len = 0;
748 }
else if (ssl_ret == 0) {
754 fprintf(
stderr,
"Error writing to stdout.\n");
758 if (
n !=
static_cast<size_t>(ssl_ret)) {
759 fprintf(
stderr,
"Short write to stderr.\n");
779 if (
buf_[
i] !=
'\n') {
784 if (
i > 0 &&
buf_[
i - 1] ==
'\r') {
796 fprintf(
stderr,
"Received line too long!\n");
803 }
while (
n == -1 && errno == EINTR);
806 fprintf(
stderr,
"Read error from socket\n");
821 out_content->clear();
825 static const unsigned kMaxLines = 512;
826 for (
unsigned i = 0;
i < kMaxLines;
i++) {
832 if (
line.size() < 4) {
833 fprintf(
stderr,
"Short line from SMTP server: %s\n",
line.c_str());
839 const unsigned long code = strtoul(code_str.c_str(), &endptr, 10);
840 if (*endptr ||
code > UINT_MAX) {
841 fprintf(
stderr,
"Failed to parse code from line: %s\n",
line.c_str());
847 }
else if (
code != *out_code) {
849 "Reply code varied within a single reply: was %u, now %u\n",
850 *out_code,
static_cast<unsigned>(
code));
854 if (
line[3] ==
' ') {
856 *out_content +=
line.substr(4, std::string::npos);
858 }
else if (
line[3] ==
'-') {
860 *out_content +=
line.substr(4, std::string::npos);
861 out_content->push_back(
'\n');
863 fprintf(
stderr,
"Bad character after code in SMTP reply: %s\n",
869 fprintf(
stderr,
"Rejected SMTP reply of more then %u lines\n", kMaxLines);
881 static bool SendAll(
int sock,
const char *
data,
size_t data_len) {
884 while (
done < data_len) {
888 }
while (
n == -1 && errno == EINTR);
891 fprintf(
stderr,
"Error while writing to socket\n");
904 unsigned code_220 = 0;
910 if (code_220 != 220) {
911 fprintf(
stderr,
"Expected 220 line from SMTP server but got code %u\n",
916 static const char kHelloLine[] =
"EHLO BoringSSL\r\n";
917 if (!
SendAll(sock, kHelloLine,
sizeof(kHelloLine) - 1)) {
921 unsigned code_250 = 0;
927 if (code_250 != 250) {
928 fprintf(
stderr,
"Expected 250 line after EHLO but got code %u\n", code_250);
933 if ((
"\n" + reply_250 +
"\n").
find(
"\nSTARTTLS\n") == std::string::npos) {
934 fprintf(
stderr,
"Server does not support STARTTLS\n");
938 static const char kSTARTTLSLine[] =
"STARTTLS\r\n";
939 if (!
SendAll(sock, kSTARTTLSLine,
sizeof(kSTARTTLSLine) - 1)) {
947 if (code_220 != 220) {
950 "Expected 220 line from SMTP server after STARTTLS, but got code %u\n",
962 fprintf(
stderr,
"Establishing HTTP tunnel to %s:%s.\n", hostname.c_str(),
965 snprintf(
buf,
sizeof(
buf),
"CONNECT %s:%s HTTP/1.0\r\n\r\n", hostname.c_str(),