summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudius 'keldu' Holeksa <mail@keldu.de>2024-10-21 16:21:35 +0200
committerClaudius 'keldu' Holeksa <mail@keldu.de>2024-10-21 16:21:35 +0200
commit545abfe5eb973c83ee38a799add02605c05af26d (patch)
treefa71c90868317ab75800e2695709d1939dfa31e7
parentab8371327296d3435308b21b463fbdb4569d8763 (diff)
Compiles now, but tls server broken
-rw-r--r--modules/io-tls/c++/tls.tmpl.hpp42
-rw-r--r--modules/io-tls/examples/SConscript4
-rw-r--r--modules/io-tls/examples/tls_echo.hpp16
-rw-r--r--modules/io-tls/examples/tls_echo_server.cpp182
4 files changed, 229 insertions, 15 deletions
diff --git a/modules/io-tls/c++/tls.tmpl.hpp b/modules/io-tls/c++/tls.tmpl.hpp
index 46b00d4..62cfe59 100644
--- a/modules/io-tls/c++/tls.tmpl.hpp
+++ b/modules/io-tls/c++/tls.tmpl.hpp
@@ -107,9 +107,25 @@ private:
gnutls_certificate_credentials_t xcred_;
gnutls_session_t session_handle_;
+ std::string key_file_;
+ std::string cert_file_;
+ std::string crl_file_;
+ std::string ca_file_;
public:
- tls_server(own<server<T>> internal__, gnutls_certificate_credentials_t xcred__):
- internal_{std::move(internal__)}
+ tls_server(
+ own<server<T>> internal__,
+ gnutls_certificate_credentials_t xcred__,
+ std::string key_f__,
+ std::string cert_f__,
+ std::string crl_f__,
+ std::string ca_f__
+ ):
+ internal_{std::move(internal__)},
+ xcred_{xcred__},
+ key_file_{std::move(key_f__)},
+ cert_file_{std::move(cert_f__)},
+ crl_file_{std::move(crl_f__)},
+ ca_file_{std::move(ca_f__)}
{}
~tls_server() {
@@ -206,17 +222,29 @@ error_or<own<server<net::Tls<T>>>> tls_network<T>::listen(network_address<net::T
gnutls_certificate_credentials_t x509_cred;
gnutls_certificate_allocate_credentials(&x509_cred);
- std::string OCSP_STATUS_FILE = "ocsp-status.der";
+ static std::string OCSP_STATUS_FILE = "ocsp-status.der";
+
+ std::string key_f = key_file;
+ std::string cert_f = cert_file;
+ std::string crl_f = crl_file;
+ std::string ca_f = ca_file;
- gnutls_certificate_set_x509_trust_file(x509_cred, ca_file.c_str(), GNUTLS_X509_FMT_PEM);
- gnutls_certificate_set_x509_crl_file(x509_cred, crl_file.c_str(), GNUTLS_X509_FMT_PEM);
- gnutls_certificate_set_x509_key_file(x509_cred, cert_file.c_str(), key_file.c_str(), GNUTLS_X509_FMT_PEM);
+ gnutls_certificate_set_x509_trust_file(x509_cred, ca_f.c_str(), GNUTLS_X509_FMT_PEM);
+ gnutls_certificate_set_x509_crl_file(x509_cred, crl_f.c_str(), GNUTLS_X509_FMT_PEM);
+ gnutls_certificate_set_x509_key_file(x509_cred, cert_f.c_str(), key_f.c_str(), GNUTLS_X509_FMT_PEM);
gnutls_certificate_set_ocsp_status_request_file(x509_cred, OCSP_STATUS_FILE.c_str(), 0);
auto int_srv = internal_().listen(address.get_handle());
- own<server<net::Tls<T>>> tls_srv = heap<tls_server<T>>(std::move(int_srv), x509_cred, key_file, cert_file, crl_file, ca_file);
+ own<server<net::Tls<T>>> tls_srv = heap<tls_server<T>>(
+ std::move(int_srv),
+ x509_cred,
+ std::move(key_f),
+ std::move(cert_f),
+ std::move(crl_f),
+ std::move(ca_f)
+ );
return tls_srv;
}
diff --git a/modules/io-tls/examples/SConscript b/modules/io-tls/examples/SConscript
index d904d96..3024e7c 100644
--- a/modules/io-tls/examples/SConscript
+++ b/modules/io-tls/examples/SConscript
@@ -20,12 +20,12 @@ env.headers += examples_env.headers;
objects_static = []
examples_env.tls_client = examples_env.Program('#bin/tls_client_https_keldu_de', ['tls_client.cpp', env.library_static]);
-#examples_env.tls_server = examples_env.Program('#bin/tls_server', ['tls_server.cpp', env.library_static]);
+examples_env.tls_echo_server = examples_env.Program('#bin/tls_echo_server', ['tls_echo_server.cpp', env.library_static]);
# Set Alias
env.examples = [
examples_env.tls_client
-#, examples_env.tls_server
+, examples_env.tls_echo_server
];
env.Alias('examples', env.examples);
diff --git a/modules/io-tls/examples/tls_echo.hpp b/modules/io-tls/examples/tls_echo.hpp
new file mode 100644
index 0000000..8ecd5cc
--- /dev/null
+++ b/modules/io-tls/examples/tls_echo.hpp
@@ -0,0 +1,16 @@
+#pragma once
+
+#include <string>
+#include <cstdint>
+
+namespace saw {
+struct message {
+ std::array<uint8_t,256> data;
+ uint64_t already_read = 0;
+ uint64_t already_written = 0;
+};
+
+constexpr std::string echo_address = "::1";
+constexpr uint16_t echo_port = 4332;
+
+}
diff --git a/modules/io-tls/examples/tls_echo_server.cpp b/modules/io-tls/examples/tls_echo_server.cpp
index 7ceacb5..b491af6 100644
--- a/modules/io-tls/examples/tls_echo_server.cpp
+++ b/modules/io-tls/examples/tls_echo_server.cpp
@@ -2,13 +2,10 @@
#include "../c++/tls.hpp"
-saw::error_or<void> real_main(){
- using namespace saw;
-
+#include <iostream>
+#include "tls_echo.hpp"
-
- return make_void();
-}
+saw::error_or<void> real_main();
int main(){
auto eov = real_main();
@@ -19,3 +16,176 @@ int main(){
}
return 0;
}
+
+saw::error_or<void> handle_echo_write(saw::io_stream<saw::net::Tls<saw::net::Os>>& rmt_clt, saw::message& state, uint64_t tbw){
+ auto eov = rmt_clt.write(&state.data[state.already_written], tbw);
+ if(eov.is_error()){
+ return std::move(eov.get_error());
+ }
+
+ auto val = eov.get_value();
+ state.already_written += val;
+ if(state.already_written > state.already_read){
+ exit(-1);
+ }
+
+ return saw::void_t{};
+}
+
+void handle_echo_message(saw::io_stream<saw::net::Tls<saw::net::Os>>& rmt_clt, bool& keep_running, saw::message& state){
+ rmt_clt.read_ready().then([&](){
+ for(;;){
+ uint64_t tbr = state.data.size() < state.already_read ? 0: state.data.size() - state.already_read;
+ if(tbr == 0){
+ exit(-1);
+ }
+ auto eov = rmt_clt.read(&state.data[state.already_read], tbr);
+
+ if(eov.is_error()){
+ auto& err = eov.get_error();
+ if(err.is_critical()){
+ std::cerr<<err.get_category()<<std::endl;
+ exit(err.get_id());
+ }else{
+ break;
+ }
+ }
+ auto& read_bytes = eov.get_value();
+
+ std::cout<<"Read "<<read_bytes<<" bytes"<<std::endl;
+
+ if(read_bytes == 0u){
+ exit(-1);
+ }
+
+ bool trigger_write = (state.already_read == state.already_written);
+
+ state.already_read += read_bytes;
+ if(state.already_read > state.data.size()){
+ state.already_read = state.data.size();
+ }
+ if(trigger_write){
+ auto eov = handle_echo_write(rmt_clt, state, state.already_read - state.already_written);
+ if(eov.is_error()){
+ auto& err = eov.get_error();
+ if(err.is_critical()){
+ std::cerr<<"After triggered write: "<<err.get_category()<<std::endl;
+ exit(err.get_id());
+ }else {
+ break;
+ }
+ }
+ }
+ }
+ }).detach();
+
+ rmt_clt.write_ready().then([&](){
+ for(;;){
+ if(state.already_read < state.already_written){
+ exit(-1);
+ }
+ uint64_t tbw = state.already_read - state.already_written;
+ if(tbw == 0){
+ break;
+ }
+
+ auto eov = handle_echo_write(rmt_clt, state, tbw);
+ if(eov.is_error()){
+ auto& err = eov.get_error();
+ if(err.is_critical()){
+ std::cerr<<err.get_category()<<std::endl;
+ exit(err.get_id());
+ }else {
+ break;
+ }
+ }
+ }
+ }).detach();
+
+ rmt_clt.on_read_disconnected().then([&](){
+ keep_running = false;
+ }).detach();
+}
+
+saw::error_or<void> real_main(){
+ using namespace saw;
+
+ auto eo_aio = saw::setup_async_io();
+ if(eo_aio.is_error()){
+ auto& err = eo_aio.get_error();
+ return std::move(err);
+ }
+ auto& aio = eo_aio.get_value();
+ /**
+ * Make the event loop the current event loop on this thread
+ */
+ saw::wait_scope wait_scope{aio.event_loop};
+
+ bool keep_running = true;
+ aio.event_port.on_signal(saw::Signal::Terminate).then([&keep_running](){
+ keep_running = false;
+ }).detach();
+
+ auto& int_network = aio.io->get_network();
+
+ auto eo_tls_net = saw::setup_tls_network(int_network);
+ if(eo_tls_net.is_error()){
+ return std::move(eo_tls_net.get_error());
+ }
+
+ auto& tls_net = eo_tls_net.get_value();
+ auto& network = *tls_net;
+ saw::own<saw::network_address<saw::net::Tls<saw::net::Os>>> addr = nullptr;
+ saw::own<saw::server<saw::net::Tls<saw::net::Os>>> srv = nullptr;
+ saw::own<saw::io_stream<saw::net::Tls<saw::net::Os>>> remote_client = nullptr;
+
+ saw::message msg_state;
+
+ std::cout<<"Starting to resolve address"<<std::endl;
+ /**
+ * Try to resolve address. If resolved
+ */
+ network.resolve_address(saw::echo_address, saw::echo_port).then([&](auto net_addr) -> error_or<void> {
+ std::cout<<"Resolved address"<<std::endl;
+ addr = std::move(net_addr);
+ auto eo_srv = network.listen(*addr, "key.pem", "cert.pem", "crl.pem", "/etc/ssl/ca-certificates.txt");
+ if(eo_srv.is_error()){
+ return std::move(eo_srv.get_error());
+ }
+ auto& srv = eo_srv.get_value();
+ if(srv){
+ srv->accept().then([&](auto client) -> saw::error_or<void>{
+
+ if(!remote_client){
+ std::cout<<"Accepted client"<<std::endl;
+ remote_client = std::move(client);
+
+ if(remote_client){
+ std::cout<<"Spinning up handler"<<std::endl;
+ handle_echo_message(*remote_client, keep_running, msg_state);
+ }else{
+ keep_running = false;
+ }
+ }
+ return saw::make_error<saw::err::critical>();
+ }).detach();
+ }else{
+ keep_running = false;
+ }
+ }).detach([&](auto err) {
+ std::cout<<"Failed to resolve address: "<<err.get_category()<<":"<<err.get_message()<<std::endl;
+ keep_running = false;
+ return err;
+ });
+
+ std::cout<<"Entering waiting loop"<<std::endl;
+
+ wait_scope.poll();
+ while(keep_running){
+ wait_scope.wait_for(1*1000*1000);
+ }
+
+ std::cout<<"\n\nShutting down echo server"<<std::endl;
+
+ return make_void();
+}