mirror of
https://github.com/sudo-project/sudo.git
synced 2025-08-22 09:57:41 +00:00
logserver option to disable certificate verification on server side and server authentication on client side
This commit is contained in:
parent
9935a7e2ff
commit
24c9438486
@ -28,16 +28,26 @@
|
||||
# By default, server connections are not encrypted.
|
||||
#tls = true
|
||||
|
||||
# If set, server certificate will be verified at server startup and
|
||||
# also connecting clients will perform server authentication by
|
||||
# verifying the server's certificate and identity.
|
||||
#tls_verify = true
|
||||
|
||||
# Whether to verify client certificates for TLS connections.
|
||||
# By default client certs are not checked.
|
||||
#tls_checkpeer = false
|
||||
|
||||
# Path to the certificate authority bundle file in PEM format.
|
||||
# Required if 'tls_verify' or 'tls_checkpeer' is set.
|
||||
#tls_cacert = /etc/ssl/sudo/cacert.pem
|
||||
|
||||
# Path to the server's certificate file in PEM format.
|
||||
# Required for TLS connections.
|
||||
#tls_cert = /etc/ssl/sudo/logsrvd_cert.pem
|
||||
|
||||
# Whether to verify client certificates for TLS connections.
|
||||
# By default client certs are not checked.
|
||||
#tls_checkpeer = false
|
||||
# Path to the server's private key file in PEM format.
|
||||
# Required for TLS connections.
|
||||
#tls_key = /etc/ssl/sudo/private/logsrvd_key.pem
|
||||
|
||||
# TLS cipher list (see "CIPHER LIST FORMAT" in the openssl-ciphers manual).
|
||||
# NOTE that this setting is only effective if the negotiated protocol
|
||||
@ -53,10 +63,6 @@
|
||||
# If not set, the server will use the OpenSSL defaults.
|
||||
#tls_dhparams = /etc/ssl/sudo/logsrvd_dhparams.pem
|
||||
|
||||
# Path to the server's private key file in PEM format.
|
||||
# Required for TLS connections.
|
||||
#tls_key = /etc/ssl/sudo/private/logsrvd_key.pem
|
||||
|
||||
[iolog]
|
||||
# The top-level directory to use when constructing the path name for the
|
||||
# I/O log directory. The session sequence number, if any, is stored here.
|
||||
|
@ -409,6 +409,10 @@ struct _ServerHello
|
||||
* true if server uses tls protocol
|
||||
*/
|
||||
protobuf_c_boolean tls;
|
||||
/*
|
||||
* true if server auth has to be performed
|
||||
*/
|
||||
protobuf_c_boolean tls_server_auth;
|
||||
/*
|
||||
* true if client auth is required with signed cert
|
||||
*/
|
||||
@ -416,7 +420,7 @@ struct _ServerHello
|
||||
};
|
||||
#define SERVER_HELLO__INIT \
|
||||
{ PROTOBUF_C_MESSAGE_INIT (&server_hello__descriptor) \
|
||||
, (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string, 0,NULL, 0, 0 }
|
||||
, (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string, 0,NULL, 0, 0, 0 }
|
||||
|
||||
|
||||
/* ClientMessage methods */
|
||||
|
@ -1578,7 +1578,7 @@ const ProtobufCMessageDescriptor server_message__descriptor =
|
||||
(ProtobufCMessageInit) server_message__init,
|
||||
NULL,NULL,NULL /* reserved[123] */
|
||||
};
|
||||
static const ProtobufCFieldDescriptor server_hello__field_descriptors[5] =
|
||||
static const ProtobufCFieldDescriptor server_hello__field_descriptors[6] =
|
||||
{
|
||||
{
|
||||
"server_id",
|
||||
@ -1629,11 +1629,23 @@ static const ProtobufCFieldDescriptor server_hello__field_descriptors[5] =
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"tls_reqcert",
|
||||
"tls_server_auth",
|
||||
5,
|
||||
PROTOBUF_C_LABEL_NONE,
|
||||
PROTOBUF_C_TYPE_BOOL,
|
||||
0, /* quantifier_offset */
|
||||
offsetof(ServerHello, tls_server_auth),
|
||||
NULL,
|
||||
NULL,
|
||||
0, /* flags */
|
||||
0,NULL,NULL /* reserved1,reserved2, etc */
|
||||
},
|
||||
{
|
||||
"tls_reqcert",
|
||||
6,
|
||||
PROTOBUF_C_LABEL_NONE,
|
||||
PROTOBUF_C_TYPE_BOOL,
|
||||
0, /* quantifier_offset */
|
||||
offsetof(ServerHello, tls_reqcert),
|
||||
NULL,
|
||||
NULL,
|
||||
@ -1646,12 +1658,13 @@ static const unsigned server_hello__field_indices_by_name[] = {
|
||||
0, /* field[0] = server_id */
|
||||
2, /* field[2] = servers */
|
||||
3, /* field[3] = tls */
|
||||
4, /* field[4] = tls_reqcert */
|
||||
5, /* field[5] = tls_reqcert */
|
||||
4, /* field[4] = tls_server_auth */
|
||||
};
|
||||
static const ProtobufCIntRange server_hello__number_ranges[1 + 1] =
|
||||
{
|
||||
{ 1, 0 },
|
||||
{ 0, 5 }
|
||||
{ 0, 6 }
|
||||
};
|
||||
const ProtobufCMessageDescriptor server_hello__descriptor =
|
||||
{
|
||||
@ -1661,7 +1674,7 @@ const ProtobufCMessageDescriptor server_hello__descriptor =
|
||||
"ServerHello",
|
||||
"",
|
||||
sizeof(ServerHello),
|
||||
5,
|
||||
6,
|
||||
server_hello__field_descriptors,
|
||||
server_hello__field_indices_by_name,
|
||||
1, server_hello__number_ranges,
|
||||
|
@ -126,5 +126,6 @@ message ServerHello {
|
||||
string redirect = 2; /* optional redirect if busy */
|
||||
repeated string servers = 3; /* optional list of known servers */
|
||||
bool tls = 4; /* true if server uses tls protocol */
|
||||
bool tls_reqcert = 5; /* true if client auth is required with signed cert */
|
||||
bool tls_server_auth = 5; /* true if server auth has to be performed */
|
||||
bool tls_reqcert = 6; /* true if client auth is required with signed cert */
|
||||
}
|
||||
|
@ -178,9 +178,11 @@ fmt_hello_message(struct connection_buffer *buf)
|
||||
hello.server_id = (char *)server_id;
|
||||
#if defined(HAVE_OPENSSL)
|
||||
hello.tls = logsrvd_conf_get_tls_opt();
|
||||
hello.tls_server_auth = logsrvd_get_tls_config()->verify;
|
||||
hello.tls_reqcert = logsrvd_get_tls_config()->check_peer;
|
||||
#else
|
||||
hello.tls = false;
|
||||
hello.tls_server_auth = false;
|
||||
hello.tls_reqcert = false;
|
||||
#endif
|
||||
msg.hello = &hello;
|
||||
@ -970,9 +972,11 @@ verify_peer_identity(int preverify_ok, X509_STORE_CTX *ctx)
|
||||
switch(result)
|
||||
{
|
||||
case MatchFound:
|
||||
debug_return_int(1);
|
||||
debug_return_int(1);
|
||||
default:
|
||||
debug_return_int(0);
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
||||
"hostname validation failed");
|
||||
debug_return_int(0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1101,6 +1105,7 @@ init_tls_server_context(void)
|
||||
const SSL_METHOD *method;
|
||||
SSL_CTX *ctx = NULL;
|
||||
const struct logsrvd_tls_config *tls_config = logsrvd_get_tls_config();
|
||||
bool ca_bundle_required = tls_config->verify | tls_config->check_peer;
|
||||
debug_decl(init_tls_server_context, SUDO_DEBUG_UTIL);
|
||||
|
||||
SSL_library_init();
|
||||
@ -1127,29 +1132,39 @@ init_tls_server_context(void)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (tls_config->cacert_path != NULL) {
|
||||
STACK_OF(X509_NAME) *cacerts =
|
||||
SSL_load_client_CA_file(tls_config->cacert_path);
|
||||
if (cacerts == NULL) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"calling SSL_load_client_CA_file() failed: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
goto bad;
|
||||
} else {
|
||||
SSL_CTX_set_client_CA_list(ctx, cacerts);
|
||||
|
||||
/* set the location of the CA bundle file for verification */
|
||||
if (SSL_CTX_load_verify_locations(ctx, tls_config->cacert_path, NULL) <= 0) {
|
||||
/* if server or client authentication is required, CA bundle file has to be prepared */
|
||||
if (ca_bundle_required) {
|
||||
if (tls_config->cacert_path != NULL) {
|
||||
STACK_OF(X509_NAME) *cacerts =
|
||||
SSL_load_client_CA_file(tls_config->cacert_path);
|
||||
if (cacerts == NULL) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"calling SSL_CTX_load_verify_locations() failed: %s",
|
||||
"calling SSL_load_client_CA_file() failed: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
goto bad;
|
||||
} else {
|
||||
SSL_CTX_set_client_CA_list(ctx, cacerts);
|
||||
|
||||
/* set the location of the CA bundle file for verification */
|
||||
if (SSL_CTX_load_verify_locations(ctx, tls_config->cacert_path, NULL) <= 0) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"calling SSL_CTX_load_verify_locations() failed: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!verify_server_cert(ctx, tls_config)) {
|
||||
goto bad;
|
||||
/* only verify server cert if it is set in the configuration */
|
||||
if (tls_config->verify) {
|
||||
|
||||
if (!verify_server_cert(ctx, tls_config)) {
|
||||
goto bad;
|
||||
}
|
||||
} else {
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
||||
"skipping server cert check");
|
||||
}
|
||||
}
|
||||
|
||||
/* if peer authentication is enabled, verify client cert during TLS handshake
|
||||
@ -1303,6 +1318,11 @@ tls_handshake_cb(int fd, int what, void *v)
|
||||
sudo_warn(U_("unable to add event to queue"));
|
||||
}
|
||||
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
||||
"TLS version: %s, negotiated cipher suite: %s",
|
||||
SSL_get_version(closure->ssl),
|
||||
SSL_get_cipher(closure->ssl));
|
||||
|
||||
debug_return;
|
||||
bad:
|
||||
connection_closure_free(closure);
|
||||
|
@ -136,6 +136,7 @@ struct logsrvd_tls_config {
|
||||
char *dhparams_path;
|
||||
char *ciphers_v12;
|
||||
char *ciphers_v13;
|
||||
bool verify;
|
||||
bool check_peer;
|
||||
};
|
||||
|
||||
|
@ -526,6 +526,19 @@ cb_tls_ciphers13(struct logsrvd_config *config, const char *str)
|
||||
debug_return_bool(true);
|
||||
}
|
||||
|
||||
static bool
|
||||
cb_tls_verify(struct logsrvd_config *config, const char *str)
|
||||
{
|
||||
int val;
|
||||
debug_decl(cb_tls_verify, SUDO_DEBUG_UTIL);
|
||||
|
||||
if ((val = sudo_strtobool(str)) == -1)
|
||||
debug_return_bool(false);
|
||||
|
||||
config->server.tls_config.verify = val;
|
||||
debug_return_bool(true);
|
||||
}
|
||||
|
||||
static bool
|
||||
cb_tls_checkpeer(struct logsrvd_config *config, const char *str)
|
||||
{
|
||||
@ -706,6 +719,7 @@ static struct logsrvd_config_entry server_conf_entries[] = {
|
||||
{ "tls_ciphers_v12", cb_tls_ciphers12 },
|
||||
{ "tls_ciphers_v13", cb_tls_ciphers13 },
|
||||
{ "tls_checkpeer", cb_tls_checkpeer },
|
||||
{ "tls_verify", cb_tls_verify },
|
||||
#endif
|
||||
{ NULL }
|
||||
};
|
||||
@ -882,6 +896,8 @@ logsrvd_conf_alloc(void)
|
||||
#if defined(HAVE_OPENSSL)
|
||||
config->server.tls_config.cacert_path = strdup(DEFAULT_CA_CERT_PATH);
|
||||
config->server.tls_config.cert_path = strdup(DEFAULT_SERVER_CERT_PATH);
|
||||
config->server.tls_config.verify = true;
|
||||
config->server.tls_config.check_peer = false;
|
||||
#endif
|
||||
|
||||
/* I/O log defaults */
|
||||
|
@ -281,15 +281,10 @@ verify_peer_identity(int preverify_ok, X509_STORE_CTX *ctx)
|
||||
}
|
||||
|
||||
static bool
|
||||
tls_init(struct client_closure *closure, bool cert_required)
|
||||
tls_init(struct client_closure *closure, bool verify, bool cert_required)
|
||||
{
|
||||
debug_decl(tls_init, SUDOERS_DEBUG_PLUGIN);
|
||||
|
||||
if (closure->log_details->ca_bundle == NULL) {
|
||||
sudo_warnx(U_("CA bundle file is not set in sudoers"));
|
||||
goto bad;
|
||||
}
|
||||
|
||||
SSL_library_init();
|
||||
OpenSSL_add_all_algorithms();
|
||||
SSL_load_error_strings();
|
||||
@ -312,18 +307,27 @@ tls_init(struct client_closure *closure, bool cert_required)
|
||||
SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1);
|
||||
#endif
|
||||
|
||||
/* sets the location of the CA bundle file for verification purposes */
|
||||
if (SSL_CTX_load_verify_locations(closure->ssl_ctx,
|
||||
closure->log_details->ca_bundle, NULL) <= 0) {
|
||||
sudo_warnx(U_("Calling SSL_CTX_load_verify_locations() failed: %s"),
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* turn on server cert verification during the handshake.
|
||||
hostname matching will be done in a custom callback (verify_peer_identity).
|
||||
/* if server explicitly requests it, turn on server cert verification
|
||||
during the handshake. Hostname matching will be done in a custom
|
||||
callback (verify_peer_identity).
|
||||
*/
|
||||
SSL_CTX_set_verify(closure->ssl_ctx, SSL_VERIFY_PEER, verify_peer_identity);
|
||||
if (verify) {
|
||||
if (closure->log_details->ca_bundle == NULL) {
|
||||
sudo_warnx(U_("CA bundle file is not set in sudoers"));
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* sets the location of the CA bundle file for verification purposes */
|
||||
if (SSL_CTX_load_verify_locations(closure->ssl_ctx,
|
||||
closure->log_details->ca_bundle, NULL) <= 0) {
|
||||
sudo_warnx(U_("Calling SSL_CTX_load_verify_locations() failed: %s"),
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
goto bad;
|
||||
}
|
||||
|
||||
SSL_CTX_set_verify(closure->ssl_ctx, SSL_VERIFY_PEER, verify_peer_identity);
|
||||
}
|
||||
|
||||
/* if the server requests client authentication with signed certificate */
|
||||
if (cert_required) {
|
||||
@ -1057,7 +1061,7 @@ handle_server_hello(ServerHello *msg, struct client_closure *closure)
|
||||
#if defined(HAVE_OPENSSL)
|
||||
/* if server requested TLS */
|
||||
if (msg->tls) {
|
||||
if (!tls_init(closure, msg->tls_reqcert)) {
|
||||
if (!tls_init(closure, msg->tls_server_auth, msg->tls_reqcert)) {
|
||||
sudo_warnx(U_("TLS initialization was unsuccessful"));
|
||||
debug_return_bool(false);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user