Better error handling for SSL
This commit is contained in:
@@ -278,7 +278,9 @@ class Driver {
|
|||||||
} else if (error == SSL_ERROR_WANT_WRITE) {
|
} else if (error == SSL_ERROR_WANT_WRITE) {
|
||||||
chan.ready_on_pollout = true;
|
chan.ready_on_pollout = true;
|
||||||
} else {
|
} else {
|
||||||
close_channel(chan, drvssl::errors_string());
|
std::string error = drvssl::error_string();
|
||||||
|
if (error == "") error = "unknown error";
|
||||||
|
close_channel(chan, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,7 +351,7 @@ class Driver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void advance_channel(ChanInfo &chan) {
|
void advance_channel(ChanInfo &chan) {
|
||||||
drvssl::assert_errors_empty();
|
drvssl::clear_all_errors();
|
||||||
switch (chan.state) {
|
switch (chan.state) {
|
||||||
case CHAN_PLAINTEXT:
|
case CHAN_PLAINTEXT:
|
||||||
advance_plaintext(chan);
|
advance_plaintext(chan);
|
||||||
@@ -367,7 +369,6 @@ class Driver {
|
|||||||
assert(false);
|
assert(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
drvssl::assert_errors_empty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_socket_input_output() {
|
void handle_socket_input_output() {
|
||||||
@@ -527,7 +528,6 @@ class Driver {
|
|||||||
ssl_client_insecure_ctx_.reset(drvssl::new_context(SSL_VERIFY_NONE));
|
ssl_client_insecure_ctx_.reset(drvssl::new_context(SSL_VERIFY_NONE));
|
||||||
ssl_load_certificate_authorities(ssl_client_secure_ctx_.get());
|
ssl_load_certificate_authorities(ssl_client_secure_ctx_.get());
|
||||||
drvssl::ctx_load_dummy_cert(ssl_server_ctx_.get());
|
drvssl::ctx_load_dummy_cert(ssl_server_ctx_.get());
|
||||||
drvssl::assert_errors_empty();
|
|
||||||
|
|
||||||
handle_lua_source();
|
handle_lua_source();
|
||||||
recorder_.drv_invoke_event_init(argc, argv);
|
recorder_.drv_invoke_event_init(argc, argv);
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ static SOCKET open_connection(const char *host, const char *port, std::string &e
|
|||||||
if (sock <= 0) goto error_errno;
|
if (sock <= 0) goto error_errno;
|
||||||
|
|
||||||
set_nonblocking(sock);
|
set_nonblocking(sock);
|
||||||
|
|
||||||
status = connect(sock, goodaddr->ai_addr, goodaddr->ai_addrlen);
|
status = connect(sock, goodaddr->ai_addr, goodaddr->ai_addrlen);
|
||||||
if ((status != 0) && (errno != EINPROGRESS)) goto error_errno;
|
if ((status != 0) && (errno != EINPROGRESS)) goto error_errno;
|
||||||
|
|
||||||
@@ -220,7 +221,7 @@ static int console_read(char *bytes, int nbytes) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void ssl_load_certificate_authorities(SSL_CTX *ctx) {
|
static void ssl_load_certificate_authorities(SSL_CTX *ctx) {
|
||||||
SSL_CTX_set_default_verify_paths(ctx);
|
assert(SSL_CTX_set_default_verify_paths(ctx) == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void disable_randomization(int argc, char *argv[]) {
|
static void disable_randomization(int argc, char *argv[]) {
|
||||||
@@ -259,7 +260,8 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
disable_randomization(argc, argv);
|
disable_randomization(argc, argv);
|
||||||
enable_tty_raw();
|
enable_tty_raw();
|
||||||
OPENSSL_init_ssl(0, NULL);
|
assert(OPENSSL_init_ssl(0, NULL) == 1);
|
||||||
|
drvssl::clear_all_errors();
|
||||||
SourceDB::register_lua_builtins();
|
SourceDB::register_lua_builtins();
|
||||||
Driver driver;
|
Driver driver;
|
||||||
return driver.drive(argc, argv);
|
return driver.drive(argc, argv);
|
||||||
|
|||||||
@@ -61,46 +61,36 @@ const char *dummy_key =
|
|||||||
"HcKc9a4WXhC7yu79e5BnKWltHXY=\n"
|
"HcKc9a4WXhC7yu79e5BnKWltHXY=\n"
|
||||||
"-----END PRIVATE KEY-----\n";
|
"-----END PRIVATE KEY-----\n";
|
||||||
|
|
||||||
std::string errors_string(bool lastonly) {
|
std::string error_string() {
|
||||||
std::string err;
|
// Get the last code.
|
||||||
const char *file, *data;
|
int code = 0;
|
||||||
int line, flags;
|
|
||||||
// const char *func;
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// Newer versions of the SSL API support this.
|
int icode = ERR_get_error();
|
||||||
// unsigned long code =
|
if (icode == 0) break;
|
||||||
// ERR_get_error_all(&file, &line, &func, &data, &flags);
|
code = icode;
|
||||||
// Older versions of the SSL API support this.
|
}
|
||||||
unsigned long code =
|
|
||||||
ERR_get_error_line_data(&file, &line, &data, &flags);
|
// Fetch and clear errno.
|
||||||
if (code == 0) break;
|
int terrno = errno;
|
||||||
std::string reason;
|
errno = 0;
|
||||||
|
|
||||||
|
if (code != 0) {
|
||||||
const char *rc = ERR_reason_error_string(code);
|
const char *rc = ERR_reason_error_string(code);
|
||||||
if (rc != nullptr) {
|
if (rc != nullptr) {
|
||||||
reason = rc;
|
return rc;
|
||||||
} else {
|
} else {
|
||||||
reason = "sys:" + strerror_str(ERR_GET_REASON(code));
|
return strerror_str(ERR_GET_REASON(code));
|
||||||
}
|
}
|
||||||
if (err.empty() || lastonly) {
|
} else if (terrno != 0) {
|
||||||
err = reason;
|
return strerror_str(terrno);
|
||||||
} else {
|
} else {
|
||||||
err = err + ", " + reason;
|
return "";
|
||||||
}
|
}
|
||||||
if ((data != nullptr) && (data[0] != 0)) {
|
|
||||||
err = err + " " + data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void assert_errors_empty() {
|
void clear_all_errors() {
|
||||||
int code = ERR_peek_error();
|
ERR_clear_error();
|
||||||
if (code != 0) {
|
errno = 0;
|
||||||
std::cerr << "SSL should not have errors at this point." << std::endl;
|
|
||||||
ERR_print_errors_fp(stderr);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SSL_CTX *new_context(int verify) {
|
SSL_CTX *new_context(int verify) {
|
||||||
|
|||||||
@@ -46,14 +46,14 @@ struct ErrClearErrorOnExit {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string errors_string(bool lastonly = true);
|
// Return the OpenSSL error as a string.
|
||||||
void assert_errors_empty();
|
std::string error_string();
|
||||||
|
void clear_all_errors();
|
||||||
SSL_CTX *new_context(int verify);
|
SSL_CTX *new_context(int verify);
|
||||||
void ctx_load_dummy_cert(SSL_CTX *ctx);
|
void ctx_load_dummy_cert(SSL_CTX *ctx);
|
||||||
void ctx_load_cert_from_directory(SSL_CTX *ctx, const std::string &dir);
|
void ctx_load_cert_from_directory(SSL_CTX *ctx, const std::string &dir);
|
||||||
|
|
||||||
} // namespace drvssl
|
} // namespace drvssl
|
||||||
|
|
||||||
|
|
||||||
#endif // DRIVER_SSL_HPP
|
#endif // DRIVER_SSL_HPP
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user