diff --git a/luprex/core/Makefile b/luprex/core/Makefile index 4127305a..b019627c 100644 --- a/luprex/core/Makefile +++ b/luprex/core/Makefile @@ -1,16 +1,15 @@ - ifeq ($(OS),mingw) EXE=main.exe - LIBS=-L ../mingwlib -lssl -lcrypto -lws2_32 -lcrypt32 -lcryptui - INCS=-I ../mingwlib + LIBS=-L../mingwlib -lssl -lcrypto -lws2_32 -lcrypt32 -lcryptui + INCS=-I../mingwlib LUAFLAGS=-DLUA_COMPAT_ALL OPT=-g -O1 DRIVER=driver-mingw else ifeq ($(OS),linux) EXE=main - LIBS=-lssl -lcrypto - INCS= + LIBS=-L../linuxlib -lssl -lcrypto + INCS=-I../linuxlib LUAFLAGS=-DLUA_USE_POSIX OPT=-g -O1 DRIVER=driver-linux @@ -68,6 +67,7 @@ CORE_OBJ_FILES=\ obj/spookyv2.o\ obj/debugcollector.o\ obj/drivenengine.o\ + obj/dummycert.o\ obj/util.o\ obj/luastack.o\ obj/traceback.o\ diff --git a/luprex/core/cpp/driver-linux.cpp b/luprex/core/cpp/driver-linux.cpp index ada98534..cab66669 100644 --- a/luprex/core/cpp/driver-linux.cpp +++ b/luprex/core/cpp/driver-linux.cpp @@ -1,5 +1,8 @@ #include "driver.hpp" +#include "util.hpp" +#include "drivenengine.hpp" +#include "dummycert.hpp" #include #include #include @@ -25,7 +28,6 @@ using SOCKET=int; const int INVALID_SOCKET = -1; -using SocketVector = std::vector; using PollVector = std::vector; struct termios orig_termios; @@ -55,13 +57,17 @@ static void enableRawMode() { assert(status >= 0); } +static std::string strerror_str(int err) { + char errbuf[256]; + return strerror_r(errno, errbuf, 256); +} + SOCKET open_connection(const std::string &target, std::string &err) { struct addrinfo *addrs = nullptr; struct addrinfo *goodaddr = nullptr; struct addrinfo hints; SOCKET sock = INVALID_SOCKET; std::string host, port; - char errbuf[1024]; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; @@ -69,7 +75,7 @@ SOCKET open_connection(const std::string &target, std::string &err) { hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_NUMERICSERV; - err = ""; + err.clear(); util::split_host_port(target, host, port); int status = getaddrinfo(host.c_str(), port.c_str(), &hints, &addrs); if (status != 0) { @@ -95,7 +101,7 @@ SOCKET open_connection(const std::string &target, std::string &err) { return sock; error_errno: - err = strerror_r(errno, errbuf, 1024); + err = strerror_str(errno); error: if (sock != INVALID_SOCKET) close(sock); if (addrs != nullptr) freeaddrinfo(addrs); @@ -104,7 +110,7 @@ error: SOCKET listen_on_port(int port, std::string &err) { int status; - err = ""; + err.clear(); SOCKET sock = socket(AF_INET, SOCK_STREAM, 0); assert(sock > 0); @@ -125,25 +131,17 @@ SOCKET listen_on_port(int port, std::string &err) { return sock; } -SocketVector accept_on_socket(SOCKET listen_socket) { - SocketVector result; - while (true) { - SOCKET chsock = accept(listen_socket, nullptr, nullptr); - if (chsock >= 0) { - set_nonblocking(chsock); - result.push_back(chsock); - } else { - if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { - // Normal completion - we're out of incoming sockets. - return result; - } else if (errno == ECONNABORTED) { - // The remote disconnected before we had a chance to accept. - // Just pretend it never happened. - } else { - // Unexpected error. - assert(false); - } +SOCKET accept_on_socket(SOCKET listen_socket, std::string &err) { + err.clear(); + SOCKET chsock = accept(listen_socket, nullptr, nullptr); + if (chsock >= 0) { + set_nonblocking(chsock); + return chsock; + } else { + if ((errno != EAGAIN) && (errno != EWOULDBLOCK) && (errno != ECONNABORTED)) { + err = strerror_str(errno); } + return INVALID_SOCKET; } } @@ -161,6 +159,46 @@ SSL_CTX *new_ssl_context(bool server_cert, bool root_certs, const std::string &r return ctx; } +std::string err_print_errors_str() { + BIO *bio = BIO_new(BIO_s_mem()); + ERR_print_errors(bio); + char *buf; + size_t len = BIO_get_mem_data(bio, &buf); + std::string ret(buf, len); + BIO_free(bio); + return ret; +} +#include +#include +#include + +int ssl_ctx_use_certificate_str(SSL_CTX *ctx, const char *str) { + BIO *bio = BIO_new(BIO_s_mem()); + BIO_puts(bio, str); + X509 *certificate = PEM_read_bio_X509(bio, NULL, NULL, NULL); + BIO_free(bio); + int status = SSL_CTX_use_certificate(ctx, certificate); + X509_free(certificate); + return status; +} + +int ssl_ctx_use_privatekey_str(SSL_CTX *ctx, const char *str) { + BIO *bio = BIO_new(BIO_s_mem()); + BIO_puts(bio, str); + EVP_PKEY *pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL); + BIO_free(bio); + int status = SSL_CTX_use_PrivateKey(ctx, pkey); + EVP_PKEY_free(pkey); + return status; +} + +static void print_error_and_exit(const std::string &str) { + if (!str.empty()) { + std::cerr << "error: " << str << std::endl; + exit(1); + } +} + class MonoClock { private: struct timespec base_; @@ -195,12 +233,10 @@ public: CHAN_SSL_CONNECTING, CHAN_SSL_ACCEPTING, CHAN_SSL_READWRITE, - CHAN_SSL_SHUTDOWN }; struct ChanInfo { int chid; SOCKET socket; - SSL_CTX *ssl_ctx; SSL *ssl; ChanState state; @@ -212,11 +248,11 @@ public: bool ready_on_pollin; bool ready_on_pollout; bool ready_on_outgoing; + int last_write_nbytes; }; DrivenEngine *driven_; std::vector chans_; - bool any_inactive_; std::map listen_sockets_; std::unique_ptr chbuf; @@ -231,9 +267,9 @@ public: if (listen_sockets_.find(port) == listen_sockets_.end()) { std::string err; SOCKET sock = listen_on_port(port, err); - if (sock != INVALID_SOCKET) { - listen_sockets_[port] = sock; - } + print_error_and_exit(err); + assert(sock != INVALID_SOCKET); + listen_sockets_[port] = sock; } } } @@ -252,11 +288,6 @@ public: SSL_free(chan.ssl); chan.ssl = nullptr; } - // Close the SSL_CTX - if (chan.ssl_ctx != nullptr) { - SSL_CTX_free(chan.ssl_ctx); - chan.ssl_ctx = nullptr; - } // Close the socket. assert(chan.socket != INVALID_SOCKET); assert(close(chan.socket) == 0); @@ -273,21 +304,17 @@ public: chan.ready_on_pollin = false; chan.ready_on_pollout = false; chan.ready_on_outgoing = false; - // Set global variables. - any_inactive_ = true; + chan.last_write_nbytes = 0; } void cleanup_channels() { - if (any_inactive_) { - for (int i = 0; i < int(chans_.size()); ) { - if (chans_[i].state == CHAN_INACTIVE) { - chans_[i] = chans_.back(); - chans_.pop_back(); - } else { - i += 1; - } + for (int i = 0; i < int(chans_.size()); ) { + if (chans_[i].state == CHAN_INACTIVE) { + chans_[i] = chans_.back(); + chans_.pop_back(); + } else { + i += 1; } - any_inactive_ = false; } } @@ -312,22 +339,25 @@ public: } } - ChanInfo make_channel(SOCKET sock, int chid, SSL_CTX *ctx, SSL *ssl, ChanState state) { + void make_channel(SOCKET sock, int chid, SSL_CTX *ctx, ChanState state) { ChanInfo newchan; newchan.chid = chid; newchan.socket = sock; - newchan.ssl_ctx = ctx; - newchan.ssl = ssl; + newchan.ssl = SSL_new(ctx); newchan.state = state; newchan.nbytes = 0; newchan.bytes = 0; newchan.released = false; newchan.just_released = false; - newchan.ready_now = true; + newchan.ready_now = false; newchan.ready_on_pollin = false; - newchan.ready_on_pollout = false; + newchan.ready_on_pollout = true; newchan.ready_on_outgoing = false; - return newchan; + newchan.last_write_nbytes = 0; + SSL_set_fd(newchan.ssl, newchan.socket); + // SSL_set_msg_callback(newchan.ssl, SSL_trace); + // SSL_set_msg_callback_arg(newchan.ssl, BIO_new_fp(stderr,0)); + chans_.push_back(newchan); } void handle_new_outgoing_sockets() { @@ -340,21 +370,19 @@ public: driven_->drv_notify_close(chid, err); } else { //std::cerr << "Opening channel " << chid << std::endl; - SSL_CTX *ctx = nullptr; - SSL *ssl = SSL_new(ssl_ctx_with_no_certs_); - chans_.push_back(make_channel(sock, chid, ctx, ssl, CHAN_PLAINTEXT)); + make_channel(sock, chid, ssl_ctx_with_no_certs_, CHAN_SSL_CONNECTING); } } } void accept_connections(int port, SOCKET sock) { - SocketVector sockets = accept_on_socket(sock); - for (SOCKET sock : sockets) { + std::string err; + SOCKET socket = accept_on_socket(sock, err); + print_error_and_exit(err); + if (socket != INVALID_SOCKET) { int chid = driven_->drv_notify_accept(port); // std::cerr << "Accepted channel " << chid << std::endl; - SSL_CTX *ctx = nullptr; - SSL *ssl = SSL_new(ssl_ctx_with_server_certs_); - chans_.push_back(make_channel(sock, chid, ctx, ssl, CHAN_PLAINTEXT)); + make_channel(socket, chid, ssl_ctx_with_server_certs_, CHAN_SSL_ACCEPTING); } } @@ -405,20 +433,80 @@ public: chan.ready_on_pollin = true; } + void process_ssl_error(ChanInfo &chan, int retval) { + int error = SSL_get_error(chan.ssl, retval); + // std::cerr << "SSL error code = " << error << " "; + if (error == SSL_ERROR_WANT_READ) { + chan.ready_on_pollin = true; + } else if (error == SSL_ERROR_WANT_WRITE) { + chan.ready_on_pollout = true; + } else { + close_channel(chan, err_print_errors_str()); + } + } + void advance_ssl_connecting(ChanInfo &chan) { - assert(false); + // std::cerr << "In advance_ssl_connecting" << std::endl; + int retval = SSL_connect(chan.ssl); + if (retval == 1) { + // Connection successful. + chan.state = CHAN_SSL_READWRITE; + chan.ready_now = true; + } else { + // std::cerr << "ssl_connect_error"; + process_ssl_error(chan, retval); + } } void advance_ssl_accepting(ChanInfo &chan) { - assert(false); + // std::cerr << "In advance_ssl_accepting" << std::endl; + int retval = SSL_accept(chan.ssl); + if (retval == 1) { + // Connection successful. + chan.state = CHAN_SSL_READWRITE; + chan.ready_now = true; + } else { + process_ssl_error(chan, retval); + } } void advance_ssl_readwrite(ChanInfo &chan) { - assert(false); - } - - void advance_ssl_shutdown(ChanInfo &chan) { - assert(false); + // std::cerr << "In advance_ssl_readwrite" << std::endl; + // Try to read data. + int read_result = SSL_read(chan.ssl, chbuf.get(), 65536); + if (read_result > 0) { + driven_->drv_recv_incoming(chan.chid, read_result, chbuf.get()); + chan.ready_now = true; + } else { + process_ssl_error(chan, read_result); + if (chan.state == CHAN_INACTIVE) return; + } + + // Try to write data. + int wbytes; + if (chan.last_write_nbytes > 0) { + wbytes = chan.last_write_nbytes; + assert(wbytes < chan.nbytes); + } else { + wbytes = chan.nbytes; + if (wbytes > 65536) wbytes = 65536; + } + if (wbytes > 0) { + int write_result = SSL_write(chan.ssl, chan.bytes, wbytes); + if (write_result > 0) { + driven_->drv_sent_outgoing(chan.chid, write_result); + chan.last_write_nbytes = 0; + chan.ready_on_outgoing = true; + } else { + chan.last_write_nbytes = wbytes; + process_ssl_error(chan, write_result); + if (chan.state == CHAN_INACTIVE) return; + } + } else { + chan.ready_on_outgoing = true; + } + + // std::cerr << "rpi=" << chan.ready_on_pollin << ".rpo=" << chan.ready_on_pollout << ".rn=" << chan.ready_now << ".rog=" << chan.ready_on_outgoing << " "; } void advance_channel(ChanInfo &chan) { @@ -435,9 +523,6 @@ public: case CHAN_SSL_READWRITE: advance_ssl_readwrite(chan); break; - case CHAN_SSL_SHUTDOWN: - advance_ssl_shutdown(chan); - break; default: assert(false); break; @@ -477,7 +562,7 @@ public: if (chan.ready_on_pollin) pfd.events |= POLLIN; if (chan.ready_on_pollout) pfd.events |= POLLOUT; if (chan.ready_on_outgoing && (chan.nbytes > 0)) pfd.events |= POLLOUT; - // std::cerr << "evt=" << pfd.events << " "; + // std::cerr << "evt=" << pfd.events << ".nb=" << chan.nbytes << " "; } struct pollfd &stdiopoll = pollvec[index++]; stdiopoll.fd = 0; @@ -521,13 +606,25 @@ public: } void drive(DrivenEngine *de, int argc, char *argv[]) { + SSL_load_error_strings(); + ERR_load_crypto_strings(); enableRawMode(); driven_ = de; - any_inactive_ = false; chbuf.reset(new char[65536]); ssl_ctx_with_root_certs_ = new_ssl_context(false, true, ""); ssl_ctx_with_server_certs_ = new_ssl_context(true, false, ""); ssl_ctx_with_no_certs_ = new_ssl_context(false, false, ""); + + if (ssl_ctx_use_certificate_str(ssl_ctx_with_server_certs_, dummycert::certificate) <= 0) { + ERR_print_errors_fp(stderr); + exit(1); + } + + if (ssl_ctx_use_privatekey_str(ssl_ctx_with_server_certs_, dummycert::privatekey) <= 0 ) { + ERR_print_errors_fp(stderr); + exit(1); + } + DrivenEngine::set(de); driven_->drv_set_lua_source(util::read_lua_source("lua")); driven_->drv_invoke_event_init(argc, argv); diff --git a/luprex/core/cpp/driver-mingw.cpp b/luprex/core/cpp/driver-mingw.cpp index 5c5694a9..5a2986c7 100644 --- a/luprex/core/cpp/driver-mingw.cpp +++ b/luprex/core/cpp/driver-mingw.cpp @@ -1,5 +1,8 @@ #include "driver.hpp" +#include "util.hpp" +#include "drivenengine.hpp" +#include "dummycert.hpp" #include #include #include diff --git a/luprex/core/cpp/driver.hpp b/luprex/core/cpp/driver.hpp index 4cc7bda7..f1d053c0 100644 --- a/luprex/core/cpp/driver.hpp +++ b/luprex/core/cpp/driver.hpp @@ -1,7 +1,7 @@ #ifndef DRIVER_HPP #define DRIVER_HPP -#include "drivenengine.hpp" +class DrivenEngine; void driver_drive(DrivenEngine *de, int argc, char *argv[]); diff --git a/luprex/core/cpp/dummycert.cpp b/luprex/core/cpp/dummycert.cpp new file mode 100644 index 00000000..ae07fafb --- /dev/null +++ b/luprex/core/cpp/dummycert.cpp @@ -0,0 +1,93 @@ +#include "dummycert.hpp" + +namespace dummycert { + +const char *certificate = + "-----BEGIN CERTIFICATE-----\n" + "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\n" + "-----END CERTIFICATE-----\n"; + +const char *privatekey = + "-----BEGIN PRIVATE KEY-----\n" + "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\n" + "b9q6zNCtp38aGjLBwZTRa+VXUJtTB5w=\n" + "-----END PRIVATE KEY-----\n"; + +} // namespace dummycert diff --git a/luprex/core/cpp/dummycert.hpp b/luprex/core/cpp/dummycert.hpp new file mode 100644 index 00000000..38a00012 --- /dev/null +++ b/luprex/core/cpp/dummycert.hpp @@ -0,0 +1,16 @@ +// The Dummy Certificate +// +// This contains a fake certificate which can be used for +// SSL transactions, when security is not important. +// Generally, that's only the case during debugging. +// + +#ifndef DUMMYCERT_HPP +#define DUMMYCERT_HPP + +namespace dummycert { +extern const char *certificate; +extern const char *privatekey; +} + +#endif // DUMMYCERT_HPP