aboutsummaryrefslogtreecommitdiffstats
path: root/src/cli
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2017-12-23 07:54:12 -0500
committerJack Lloyd <[email protected]>2017-12-23 07:57:20 -0500
commit2d719e51266408bd08f14880d2399c671cbc8a7b (patch)
tree5d323a2a7119c218e6b683052ae6f8ab3470a356 /src/cli
parentf40f25f17a2965ca03d42a17599ced5d5f6d46ab (diff)
Convert TLS server to new style TLS interface (GH #1350)
Diffstat (limited to 'src/cli')
-rw-r--r--src/cli/tls_server.cpp149
1 files changed, 71 insertions, 78 deletions
diff --git a/src/cli/tls_server.cpp b/src/cli/tls_server.cpp
index 6c0b049a2..44c69bf17 100644
--- a/src/cli/tls_server.cpp
+++ b/src/cli/tls_server.cpp
@@ -23,7 +23,7 @@
namespace Botan_CLI {
-class TLS_Server final : public Command
+class TLS_Server final : public Command, public Botan::TLS::Callbacks
{
public:
TLS_Server() : Command("tls_server cert key --port=443 --type=tcp --policy= --dump-traces=")
@@ -49,7 +49,7 @@ class TLS_Server final : public Command
throw CLI_Usage_Error("Invalid transport type '" + transport + "' for TLS");
}
- const bool is_tcp = (transport == "tcp");
+ m_is_tcp = (transport == "tcp");
std::unique_ptr<Botan::TLS::Policy> policy;
const std::string policy_file = get_arg("policy");
@@ -73,23 +73,15 @@ class TLS_Server final : public Command
Basic_Credentials_Manager creds(rng(), server_crt, server_key);
- auto protocol_chooser = [](const std::vector<std::string>&) -> std::string
- {
- // we ignore whatever the client sends here
- return "echo/1.0";
- };
-
output() << "Listening for new connections on " << transport << " port " << port << std::endl;
- int server_fd = make_server_socket(is_tcp, port);
+ int server_fd = make_server_socket(port);
while(true)
{
- int fd;
-
- if(is_tcp)
+ if(m_is_tcp)
{
- fd = ::accept(server_fd, nullptr, nullptr);
+ m_socket = ::accept(server_fd, nullptr, nullptr);
}
else
{
@@ -105,43 +97,16 @@ class TLS_Server final : public Command
{
throw CLI_Error("Could not connect UDP socket");
}
- fd = server_fd;
+ m_socket = server_fd;
}
- using namespace std::placeholders;
-
- auto socket_write = is_tcp ?
- std::bind(&TLS_Server::stream_socket_write, this, fd, _1, _2) :
- std::bind(&TLS_Server::dgram_socket_write, this, fd, _1, _2);
-
- std::string s;
- std::list<std::string> pending_output;
-
- auto proc_fn = [&](const uint8_t input[], size_t input_len)
- {
- for(size_t i = 0; i != input_len; ++i)
- {
- const char c = static_cast<char>(input[i]);
- s += c;
- if(c == '\n')
- {
- pending_output.push_back(s);
- s.clear();
- }
- }
- };
-
Botan::TLS::Server server(
- socket_write,
- proc_fn,
- std::bind(&TLS_Server::alert_received, this, _1, _2, _3),
- std::bind(&TLS_Server::handshake_complete, this, _1),
+ *this,
session_manager,
creds,
*policy,
rng(),
- protocol_chooser,
- !is_tcp);
+ m_is_tcp == false);
std::unique_ptr<std::ostream> dump_stream;
@@ -160,7 +125,7 @@ class TLS_Server final : public Command
try
{
uint8_t buf[4 * 1024] = { 0 };
- ssize_t got = ::read(fd, buf, sizeof(buf));
+ ssize_t got = ::read(m_socket, buf, sizeof(buf));
if(got == -1)
{
@@ -181,10 +146,10 @@ class TLS_Server final : public Command
server.received_data(buf, got);
- while(server.is_active() && !pending_output.empty())
+ while(server.is_active() && !m_pending_output.empty())
{
- std::string output = pending_output.front();
- pending_output.pop_front();
+ std::string output = m_pending_output.front();
+ m_pending_output.pop_front();
server.send(output);
if(output == "quit\n")
@@ -196,9 +161,10 @@ class TLS_Server final : public Command
catch(std::exception& e)
{
error_output() << "Connection problem: " << e.what() << std::endl;
- if(is_tcp)
+ if(m_is_tcp)
{
- ::close(fd);
+ ::close(m_socket);
+ m_socket = -1;
}
}
}
@@ -208,16 +174,17 @@ class TLS_Server final : public Command
error_output() << "Connection failed: " << e.what() << "\n";
}
- if(is_tcp)
+ if(m_is_tcp)
{
- ::close(fd);
+ ::close(m_socket);
+ m_socket = -1;
}
}
}
private:
- int make_server_socket(bool is_tcp, uint16_t port)
+ int make_server_socket(uint16_t port)
{
- const int type = is_tcp ? SOCK_STREAM : SOCK_DGRAM;
+ const int type = m_is_tcp ? SOCK_STREAM : SOCK_DGRAM;
int fd = ::socket(PF_INET, type, 0);
if(fd == -1)
@@ -239,7 +206,7 @@ class TLS_Server final : public Command
throw CLI_Error("server bind failed");
}
- if(is_tcp)
+ if(m_is_tcp)
{
if(::listen(fd, 100) != 0)
{
@@ -250,7 +217,7 @@ class TLS_Server final : public Command
return fd;
}
- bool handshake_complete(const Botan::TLS::Session& session)
+ bool tls_session_established(const Botan::TLS::Session& session) override
{
output() << "Handshake complete, " << session.version().to_string()
<< " using " << session.ciphersuite().to_string() << std::endl;
@@ -268,48 +235,74 @@ class TLS_Server final : public Command
return true;
}
- void dgram_socket_write(int sockfd, const uint8_t buf[], size_t length)
+ void tls_record_received(uint64_t, const uint8_t input[], size_t input_len) override
{
- ssize_t sent = ::send(sockfd, buf, length, MSG_NOSIGNAL);
-
- if(sent == -1)
+ for(size_t i = 0; i != input_len; ++i)
{
- error_output() << "Error writing to socket - " << std::strerror(errno) << std::endl;
- }
- else if(sent != static_cast<ssize_t>(length))
- {
- error_output() << "Packet of length " << length << " truncated to " << sent << std::endl;
+ const char c = static_cast<char>(input[i]);
+ m_line_buf += c;
+ if(c == '\n')
+ {
+ m_pending_output.push_back(m_line_buf);
+ m_line_buf.clear();
+ }
}
- }
+ };
- void stream_socket_write(int sockfd, const uint8_t buf[], size_t length)
+ void tls_emit_data(const uint8_t buf[], size_t length) override
{
- while(length)
+ if(m_is_tcp)
{
- ssize_t sent = ::send(sockfd, buf, length, MSG_NOSIGNAL);
+ ssize_t sent = ::send(m_socket, buf, length, MSG_NOSIGNAL);
if(sent == -1)
{
- if(errno == EINTR)
- {
- sent = 0;
- }
- else
+ error_output() << "Error writing to socket - " << std::strerror(errno) << std::endl;
+ }
+ else if(sent != static_cast<ssize_t>(length))
+ {
+ error_output() << "Packet of length " << length << " truncated to " << sent << std::endl;
+ }
+ }
+ else
+ {
+ while(length)
+ {
+ ssize_t sent = ::send(m_socket, buf, length, MSG_NOSIGNAL);
+
+ if(sent == -1)
{
- throw CLI_Error("Socket write failed");
+ if(errno == EINTR)
+ {
+ sent = 0;
+ }
+ else
+ {
+ throw CLI_Error("Socket write failed");
+ }
}
- }
- buf += sent;
- length -= sent;
+ buf += sent;
+ length -= sent;
+ }
}
}
- void alert_received(Botan::TLS::Alert alert, const uint8_t[], size_t)
+ void tls_alert(Botan::TLS::Alert alert) override
{
output() << "Alert: " << alert.type_string() << std::endl;
}
+ std::string tls_server_choose_app_protocol(const std::vector<std::string>&) override
+ {
+ // we ignore whatever the client sends here
+ return "echo/0.1";
+ }
+
+ int m_socket = -1;
+ bool m_is_tcp = false;
+ std::string m_line_buf;
+ std::list<std::string> m_pending_output;
};
BOTAN_REGISTER_COMMAND("tls_server", TLS_Server);