mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 19:07:35 +00:00
Userland: Convert TLS::TLSv12 to a Core::Stream::Socket
This commit converts TLS::TLSv12 to a Core::Stream object, and in the process allows TLS to now wrap other Core::Stream::Socket objects. As a large part of LibHTTP and LibGemini depend on LibTLS's interface, this also converts those to support Core::Stream, which leads to a simplification of LibHTTP (as there's no need to care about the underlying socket type anymore). Note that RequestServer now controls the TLS socket options, which is a better place anyway, as RS is the first receiver of the user-requested options (though this is currently not particularly useful).
This commit is contained in:
parent
7a95c451a3
commit
aafc451016
47 changed files with 841 additions and 1157 deletions
|
@ -10,20 +10,9 @@
|
|||
|
||||
namespace IMAP {
|
||||
|
||||
Client::Client(StringView host, u16 port, NonnullRefPtr<TLS::TLSv12> socket)
|
||||
: m_host(host)
|
||||
, m_port(port)
|
||||
, m_tls(true)
|
||||
, m_tls_socket(move(socket))
|
||||
, m_connect_pending(Promise<Empty>::construct())
|
||||
{
|
||||
setup_callbacks();
|
||||
}
|
||||
|
||||
Client::Client(StringView host, u16 port, NonnullOwnPtr<Core::Stream::Socket> socket)
|
||||
: m_host(host)
|
||||
, m_port(port)
|
||||
, m_tls(false)
|
||||
, m_socket(move(socket))
|
||||
, m_connect_pending(Promise<Empty>::construct())
|
||||
{
|
||||
|
@ -33,9 +22,7 @@ Client::Client(StringView host, u16 port, NonnullOwnPtr<Core::Stream::Socket> so
|
|||
Client::Client(Client&& other)
|
||||
: m_host(other.m_host)
|
||||
, m_port(other.m_port)
|
||||
, m_tls(other.m_tls)
|
||||
, m_socket(move(other.m_socket))
|
||||
, m_tls_socket(move(other.m_tls_socket))
|
||||
, m_connect_pending(move(other.m_connect_pending))
|
||||
{
|
||||
setup_callbacks();
|
||||
|
@ -43,42 +30,21 @@ Client::Client(Client&& other)
|
|||
|
||||
void Client::setup_callbacks()
|
||||
{
|
||||
if (m_tls) {
|
||||
m_tls_socket->on_tls_ready_to_read = [&](TLS::TLSv12&) {
|
||||
auto maybe_error = on_tls_ready_to_receive();
|
||||
if (maybe_error.is_error()) {
|
||||
dbgln("Error receiving from the socket: {}", maybe_error.error());
|
||||
close();
|
||||
}
|
||||
};
|
||||
|
||||
} else {
|
||||
m_socket->on_ready_to_read = [&] {
|
||||
auto maybe_error = on_ready_to_receive();
|
||||
if (maybe_error.is_error()) {
|
||||
dbgln("Error receiving from the socket: {}", maybe_error.error());
|
||||
close();
|
||||
}
|
||||
};
|
||||
}
|
||||
m_socket->on_ready_to_read = [&] {
|
||||
auto maybe_error = on_ready_to_receive();
|
||||
if (maybe_error.is_error()) {
|
||||
dbgln("Error receiving from the socket: {}", maybe_error.error());
|
||||
close();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
ErrorOr<NonnullOwnPtr<Client>> Client::connect_tls(StringView host, u16 port)
|
||||
{
|
||||
auto tls_socket = TLS::TLSv12::construct(nullptr);
|
||||
tls_socket->set_root_certificates(DefaultRootCACertificates::the().certificates());
|
||||
auto tls_socket = TRY(TLS::TLSv12::connect(host, port));
|
||||
dbgln("connecting to {}:{}", host, port);
|
||||
|
||||
tls_socket->on_tls_error = [&](TLS::AlertDescription alert) {
|
||||
dbgln("failed: {}", alert_name(alert));
|
||||
};
|
||||
tls_socket->on_tls_connected = [&] {
|
||||
dbgln("connected");
|
||||
};
|
||||
|
||||
auto success = tls_socket->connect(host, port);
|
||||
dbgln("connecting to {}:{} {}", host, port, success);
|
||||
|
||||
return adopt_nonnull_own_or_enomem(new (nothrow) Client(host, port, tls_socket));
|
||||
return adopt_nonnull_own_or_enomem(new (nothrow) Client(host, port, move(tls_socket)));
|
||||
}
|
||||
|
||||
ErrorOr<NonnullOwnPtr<Client>> Client::connect_plaintext(StringView host, u16 port)
|
||||
|
@ -88,34 +54,6 @@ ErrorOr<NonnullOwnPtr<Client>> Client::connect_plaintext(StringView host, u16 po
|
|||
return adopt_nonnull_own_or_enomem(new (nothrow) Client(host, port, move(socket)));
|
||||
}
|
||||
|
||||
ErrorOr<void> Client::on_tls_ready_to_receive()
|
||||
{
|
||||
if (!m_tls_socket->can_read())
|
||||
return {};
|
||||
auto data = m_tls_socket->read();
|
||||
// FIXME: Make TLSv12 return the actual error instead of returning a bogus
|
||||
// one here.
|
||||
if (!data.has_value())
|
||||
return Error::from_errno(EIO);
|
||||
|
||||
// Once we get server hello we can start sending
|
||||
if (m_connect_pending) {
|
||||
m_connect_pending->resolve({});
|
||||
m_connect_pending.clear();
|
||||
return {};
|
||||
}
|
||||
|
||||
m_buffer += data.value();
|
||||
if (m_buffer[m_buffer.size() - 1] == '\n') {
|
||||
// Don't try parsing until we have a complete line.
|
||||
auto response = m_parser.parse(move(m_buffer), m_expecting_response);
|
||||
MUST(handle_parsed_response(move(response)));
|
||||
m_buffer.clear();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<void> Client::on_ready_to_receive()
|
||||
{
|
||||
if (!TRY(m_socket->can_read_without_blocking()))
|
||||
|
@ -208,13 +146,8 @@ static ReadonlyBytes command_byte_buffer(CommandType command)
|
|||
|
||||
ErrorOr<void> Client::send_raw(StringView data)
|
||||
{
|
||||
if (m_tls) {
|
||||
m_tls_socket->write(data.bytes());
|
||||
m_tls_socket->write("\r\n"sv.bytes());
|
||||
} else {
|
||||
TRY(m_socket->write(data.bytes()));
|
||||
TRY(m_socket->write("\r\n"sv.bytes()));
|
||||
}
|
||||
TRY(m_socket->write(data.bytes()));
|
||||
TRY(m_socket->write("\r\n"sv.bytes()));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
@ -496,16 +429,12 @@ RefPtr<Promise<Optional<SolidResponse>>> Client::copy(Sequence sequence_set, Str
|
|||
|
||||
void Client::close()
|
||||
{
|
||||
if (m_tls) {
|
||||
m_tls_socket->close();
|
||||
} else {
|
||||
m_socket->close();
|
||||
}
|
||||
m_socket->close();
|
||||
}
|
||||
|
||||
bool Client::is_open()
|
||||
{
|
||||
return m_tls ? m_tls_socket->is_open() : m_socket->is_open();
|
||||
return m_socket->is_open();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue