mirror of
https://github.com/sudo-project/sudo.git
synced 2025-08-22 01:49:11 +00:00
Use port 30343 for plaintext and port 30344 for TLS.
For TLS connections we now do the TLS handshake immediately before the ServerHello message. This lets the client recieve an alert from the server is there is a handshake error after the TLS connect has succeeded. It also means that the contents of the ServerHello are protected from a man-in-the-middle attack.
This commit is contained in:
parent
b5a317aeb9
commit
1659d96c55
@ -16,7 +16,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.TH "SUDO_LOGSRV.PROTO" "@mansectform@" "April 20, 2020" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.TH "SUDO_LOGSRV.PROTO" "@mansectform@" "April 30, 2020" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.nh
|
||||
.if n .ad l
|
||||
.SH "NAME"
|
||||
@ -438,9 +438,6 @@ message ServerHello {
|
||||
string server_id = 1;
|
||||
string redirect = 2;
|
||||
repeated string servers = 3;
|
||||
bool tls = 4;
|
||||
bool tls_server_auth = 5;
|
||||
bool tls_reqcert = 6;
|
||||
}
|
||||
.RE
|
||||
.fi
|
||||
@ -475,22 +472,6 @@ This can be used to implement log server redundancy and allows the
|
||||
client to discover all other log servers simply by connecting to
|
||||
one known server.
|
||||
This member may be omitted when there is only a single log server.
|
||||
.TP 8n
|
||||
tls
|
||||
If set to true, the connection between the client and the server
|
||||
must be secured via Transport Layer Security (TLS) version 1.2 or
|
||||
higher.
|
||||
.TP 8n
|
||||
tls_server_auth
|
||||
If set to true, the client should validate the server's certificate
|
||||
and only proceed if the certificate can be verified.
|
||||
.TP 8n
|
||||
tls_reqcert
|
||||
If set to true, the client must present its own certificate to the server.
|
||||
If the server is unable to verify the client's certificate, the TLS
|
||||
handshake will fail.
|
||||
This can be used by the server to only allow connections from authorized
|
||||
clients.
|
||||
.SS "TimeSpec commit_point"
|
||||
A periodic time stamp sent by the server to indicate when I/O log
|
||||
buffers have been committed to storage.
|
||||
@ -529,7 +510,9 @@ message.
|
||||
The expected protocol flow is as follows:
|
||||
.TP 5n
|
||||
1.\&
|
||||
Client connect to server.
|
||||
Client connects to the first available server.
|
||||
If the client is configured to use TLS, a TLS handshake will be
|
||||
attempted.
|
||||
.TP 5n
|
||||
2.\&
|
||||
Server sends
|
||||
@ -573,6 +556,14 @@ if one is pending.
|
||||
.TP 5n
|
||||
9.\&
|
||||
Server closes the connection.
|
||||
After receiving the final
|
||||
\fIcommit_point\fR,
|
||||
the client client shuts down its side of the TLS connection if TLS
|
||||
is in use, and closes the connection.
|
||||
.TP 5n
|
||||
10.\&
|
||||
Server shuts down its side of the TLS connection if TLS is in use,
|
||||
and closes the connection.
|
||||
.PP
|
||||
At any point, the server may send an
|
||||
\fIerror\fR
|
||||
|
@ -15,7 +15,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd April 20, 2020
|
||||
.Dd April 30, 2020
|
||||
.Dt SUDO_LOGSRV.PROTO @mansectform@
|
||||
.Os Sudo @PACKAGE_VERSION@
|
||||
.Sh NAME
|
||||
@ -404,9 +404,6 @@ message ServerHello {
|
||||
string server_id = 1;
|
||||
string redirect = 2;
|
||||
repeated string servers = 3;
|
||||
bool tls = 4;
|
||||
bool tls_server_auth = 5;
|
||||
bool tls_reqcert = 6;
|
||||
}
|
||||
.Ed
|
||||
.Pp
|
||||
@ -437,19 +434,6 @@ This can be used to implement log server redundancy and allows the
|
||||
client to discover all other log servers simply by connecting to
|
||||
one known server.
|
||||
This member may be omitted when there is only a single log server.
|
||||
.It tls
|
||||
If set to true, the connection between the client and the server
|
||||
must be secured via Transport Layer Security (TLS) version 1.2 or
|
||||
higher.
|
||||
.It tls_server_auth
|
||||
If set to true, the client should validate the server's certificate
|
||||
and only proceed if the certificate can be verified.
|
||||
.It tls_reqcert
|
||||
If set to true, the client must present its own certificate to the server.
|
||||
If the server is unable to verify the client's certificate, the TLS
|
||||
handshake will fail.
|
||||
This can be used by the server to only allow connections from authorized
|
||||
clients.
|
||||
.El
|
||||
.Ss TimeSpec commit_point
|
||||
A periodic time stamp sent by the server to indicate when I/O log
|
||||
@ -489,7 +473,9 @@ message.
|
||||
The expected protocol flow is as follows:
|
||||
.Bl -enum
|
||||
.It
|
||||
Client connect to server.
|
||||
Client connects to the first available server.
|
||||
If the client is configured to use TLS, a TLS handshake will be
|
||||
attempted.
|
||||
.It
|
||||
Server sends
|
||||
.Em ServerHello .
|
||||
@ -525,6 +511,13 @@ Server sends the final
|
||||
if one is pending.
|
||||
.It
|
||||
Server closes the connection.
|
||||
After receiving the final
|
||||
.Em commit_point ,
|
||||
the client client shuts down its side of the TLS connection if TLS
|
||||
is in use, and closes the connection.
|
||||
.It
|
||||
Server shuts down its side of the TLS connection if TLS is in use,
|
||||
and closes the connection.
|
||||
.El
|
||||
.Pp
|
||||
At any point, the server may send an
|
||||
|
@ -16,7 +16,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.TH "SUDO_LOGSRVD.CONF" "@mansectform@" "March 28, 2020" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.TH "SUDO_LOGSRVD.CONF" "@mansectform@" "April 30, 2020" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.nh
|
||||
.if n .ad l
|
||||
.SH "NAME"
|
||||
@ -84,9 +84,10 @@ The
|
||||
section configures the address and port the server will listen on.
|
||||
The following keys are recognized:
|
||||
.TP 10n
|
||||
listen_address = host[:port]
|
||||
The host name or IP address and optional port to listen on.
|
||||
If no port is specified, port 30344 will be used.
|
||||
listen_address = host[:port][(tls)]
|
||||
The host name or IP address, optional port to listen on and
|
||||
an optional Transport Layer Security (TLS) flag in parentheses.
|
||||
.sp
|
||||
The host may be a host name, an IPv4 address, an IPv6 address
|
||||
in square brackets or the wild card entry
|
||||
\(oq*\(cq.
|
||||
@ -96,14 +97,33 @@ will cause
|
||||
\fBsudo_logsrvd\fR
|
||||
to listen on all configured network interfaces.
|
||||
.sp
|
||||
If the tls flag is set,
|
||||
\fBsudo_logsrvd\fR
|
||||
will secure the connection with TLS version 1.2 or 1.3.
|
||||
Versions of TLS prior to 1.2 are not supported.
|
||||
See
|
||||
sudo_logsrvd(8)
|
||||
for details on generating TLS keys and certificates.
|
||||
.sp
|
||||
If a port is specified, it may either be a port number or a known
|
||||
service name as defined by the system service name database.
|
||||
The default value is
|
||||
\fRlisten_address = *:30344\fR
|
||||
which will listen on all configured network interfaces.
|
||||
If no port is specified, port 30343 will be used for plaintext
|
||||
connections and port 30344 will be used for TLS connections.
|
||||
.sp
|
||||
The default value is:
|
||||
.nf
|
||||
.RS 16n
|
||||
listen_address = *:30343
|
||||
listen_address = *:30344(tls)
|
||||
.RE
|
||||
.fi
|
||||
.RS 10n
|
||||
which will listen on all configured network interfaces for both
|
||||
plaintext and TLS connections.
|
||||
Multiple
|
||||
\fIlisten_address\fR
|
||||
lines may be specified to listen on more than one interface.
|
||||
lines may be specified to listen on more than one port or interface.
|
||||
.RE
|
||||
.TP 10n
|
||||
pid_file = path
|
||||
The path to the file containing the process ID of the running
|
||||
@ -130,17 +150,6 @@ will wait for the client to respond.
|
||||
A value of 0 will disable the timeout.
|
||||
The default value is 30.
|
||||
.TP 10n
|
||||
tls = boolean
|
||||
If true,
|
||||
\fBsudo_logsrvd\fR
|
||||
will secure network connections with Transport Layer Security (TLS)
|
||||
version 1.2 or 1.3.
|
||||
Versions of TLS prior to 1.2 are not supported.
|
||||
See
|
||||
sudo_logsrvd(8)
|
||||
for details on generating TLS keys and certificates.
|
||||
The default value is false.
|
||||
.TP 10n
|
||||
tls_cacert = path
|
||||
The path to a certificate authority bundle file, in PEM format,
|
||||
to use instead of the system's default certificate authority database
|
||||
@ -552,19 +561,23 @@ Sudo log server configuration file
|
||||
#
|
||||
|
||||
[server]
|
||||
# The host name or IP address and port to listen on. If no port is
|
||||
# specified, port 30344 will be used.
|
||||
# The host name or IP address and port to listen on with an optional TLS
|
||||
# flag. If no port is specified, port 30343 will be used for plaintext
|
||||
# connections and port 30344 will be used to TLS connections.
|
||||
# The following forms are accepted:
|
||||
# listen_address = hostname
|
||||
# listen_address = hostname:port
|
||||
# listen_address = IPv4_address
|
||||
# listen_address = IPv4_address:port
|
||||
# listen_address = [IPv6_address]
|
||||
# listen_address = [IPv6_address]:port
|
||||
# listen_address = hostname(tls)
|
||||
# listen_address = hostname:port(tls)
|
||||
# listen_address = IPv4_address(tls)
|
||||
# listen_address = IPv4_address:port(tls)
|
||||
# listen_address = [IPv6_address](tls)
|
||||
# listen_address = [IPv6_address]:port(tls)
|
||||
#
|
||||
# The (tls) suffix should be omitted for plaintext connections.
|
||||
#
|
||||
# Multiple listen_address settings may be specified.
|
||||
# The default is to listen on all addresses.
|
||||
#listen_address = *:30344
|
||||
#listen_address = *:30343
|
||||
#listen_address = *:30344(tls)
|
||||
|
||||
# The file containing the ID of the running sudo_logsrvd process.
|
||||
#pid_file = @rundir@/sudo_logsrvd.pid
|
||||
@ -576,10 +589,6 @@ Sudo log server configuration file
|
||||
# respond. A value of 0 will disable the timeout. The default value is 30.
|
||||
#timeout = 30
|
||||
|
||||
# If set, secure connections with TLS 1.2 or 1.3.
|
||||
# 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.
|
||||
|
@ -15,7 +15,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd March 28, 2020
|
||||
.Dd April 30, 2020
|
||||
.Dt SUDO_LOGSRVD.CONF @mansectform@
|
||||
.Os Sudo @PACKAGE_VERSION@
|
||||
.Sh NAME
|
||||
@ -76,9 +76,10 @@ The
|
||||
section configures the address and port the server will listen on.
|
||||
The following keys are recognized:
|
||||
.Bl -tag -width 8n
|
||||
.It listen_address = host Ns Op : Ns port
|
||||
The host name or IP address and optional port to listen on.
|
||||
If no port is specified, port 30344 will be used.
|
||||
.It listen_address = host Ns Oo : Ns port Oc Ns Op (tls)
|
||||
The host name or IP address, optional port to listen on and
|
||||
an optional Transport Layer Security (TLS) flag in parentheses.
|
||||
.Pp
|
||||
The host may be a host name, an IPv4 address, an IPv6 address
|
||||
in square brackets or the wild card entry
|
||||
.Ql * .
|
||||
@ -88,14 +89,29 @@ will cause
|
||||
.Nm sudo_logsrvd
|
||||
to listen on all configured network interfaces.
|
||||
.Pp
|
||||
If the tls flag is set,
|
||||
.Nm sudo_logsrvd
|
||||
will secure the connection with TLS version 1.2 or 1.3.
|
||||
Versions of TLS prior to 1.2 are not supported.
|
||||
See
|
||||
.Xr sudo_logsrvd @mansectsu@
|
||||
for details on generating TLS keys and certificates.
|
||||
.Pp
|
||||
If a port is specified, it may either be a port number or a known
|
||||
service name as defined by the system service name database.
|
||||
The default value is
|
||||
.Li listen_address = *:30344
|
||||
which will listen on all configured network interfaces.
|
||||
If no port is specified, port 30343 will be used for plaintext
|
||||
connections and port 30344 will be used for TLS connections.
|
||||
.Pp
|
||||
The default value is:
|
||||
.Bd -literal -compact -offset indent
|
||||
listen_address = *:30343
|
||||
listen_address = *:30344(tls)
|
||||
.Ed
|
||||
which will listen on all configured network interfaces for both
|
||||
plaintext and TLS connections.
|
||||
Multiple
|
||||
.Em listen_address
|
||||
lines may be specified to listen on more than one interface.
|
||||
lines may be specified to listen on more than one port or interface.
|
||||
.It pid_file = path
|
||||
The path to the file containing the process ID of the running
|
||||
.Nm sudo_logsrvd .
|
||||
@ -118,16 +134,6 @@ The amount of time, in seconds,
|
||||
will wait for the client to respond.
|
||||
A value of 0 will disable the timeout.
|
||||
The default value is 30.
|
||||
.It tls = boolean
|
||||
If true,
|
||||
.Nm sudo_logsrvd
|
||||
will secure network connections with Transport Layer Security (TLS)
|
||||
version 1.2 or 1.3.
|
||||
Versions of TLS prior to 1.2 are not supported.
|
||||
See
|
||||
.Xr sudo_logsrvd @mansectsu@
|
||||
for details on generating TLS keys and certificates.
|
||||
The default value is false.
|
||||
.It tls_cacert = path
|
||||
The path to a certificate authority bundle file, in PEM format,
|
||||
to use instead of the system's default certificate authority database
|
||||
@ -500,19 +506,23 @@ Sudo log server configuration file
|
||||
#
|
||||
|
||||
[server]
|
||||
# The host name or IP address and port to listen on. If no port is
|
||||
# specified, port 30344 will be used.
|
||||
# The host name or IP address and port to listen on with an optional TLS
|
||||
# flag. If no port is specified, port 30343 will be used for plaintext
|
||||
# connections and port 30344 will be used to TLS connections.
|
||||
# The following forms are accepted:
|
||||
# listen_address = hostname
|
||||
# listen_address = hostname:port
|
||||
# listen_address = IPv4_address
|
||||
# listen_address = IPv4_address:port
|
||||
# listen_address = [IPv6_address]
|
||||
# listen_address = [IPv6_address]:port
|
||||
# listen_address = hostname(tls)
|
||||
# listen_address = hostname:port(tls)
|
||||
# listen_address = IPv4_address(tls)
|
||||
# listen_address = IPv4_address:port(tls)
|
||||
# listen_address = [IPv6_address](tls)
|
||||
# listen_address = [IPv6_address]:port(tls)
|
||||
#
|
||||
# The (tls) suffix should be omitted for plaintext connections.
|
||||
#
|
||||
# Multiple listen_address settings may be specified.
|
||||
# The default is to listen on all addresses.
|
||||
#listen_address = *:30344
|
||||
#listen_address = *:30343
|
||||
#listen_address = *:30344(tls)
|
||||
|
||||
# The file containing the ID of the running sudo_logsrvd process.
|
||||
#pid_file = @rundir@/sudo_logsrvd.pid
|
||||
@ -524,10 +534,6 @@ Sudo log server configuration file
|
||||
# respond. A value of 0 will disable the timeout. The default value is 30.
|
||||
#timeout = 30
|
||||
|
||||
# If set, secure connections with TLS 1.2 or 1.3.
|
||||
# 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.
|
||||
|
@ -3,19 +3,23 @@
|
||||
#
|
||||
|
||||
[server]
|
||||
# The host name or IP address and port to listen on. If no port is
|
||||
# specified, port 30344 will be used.
|
||||
# The host name or IP address and port to listen on with an optional TLS
|
||||
# flag. If no port is specified, port 30343 will be used for plaintext
|
||||
# connections and port 30344 will be used to TLS connections.
|
||||
# The following forms are accepted:
|
||||
# listen_address = hostname
|
||||
# listen_address = hostname:port
|
||||
# listen_address = IPv4_address
|
||||
# listen_address = IPv4_address:port
|
||||
# listen_address = [IPv6_address]
|
||||
# listen_address = [IPv6_address]:port
|
||||
# listen_address = hostname(tls)
|
||||
# listen_address = hostname:port(tls)
|
||||
# listen_address = IPv4_address(tls)
|
||||
# listen_address = IPv4_address:port(tls)
|
||||
# listen_address = [IPv6_address](tls)
|
||||
# listen_address = [IPv6_address]:port(tls)
|
||||
#
|
||||
# The (tls) suffix should be omitted for plaintext connections.
|
||||
#
|
||||
# Multiple listen_address settings may be specified.
|
||||
# The default is to listen on all addresses.
|
||||
#listen_address = *:30344
|
||||
#listen_address = *:30343
|
||||
#listen_address = *:30344(tls)
|
||||
|
||||
# The file containing the ID of the running sudo_logsrvd process.
|
||||
#pid_file = /var/run/sudo/sudo_logsrvd.pid
|
||||
@ -27,10 +31,6 @@
|
||||
# respond. A value of 0 will disable the timeout. The default value is 30.
|
||||
#timeout = 30
|
||||
|
||||
# If set, secure connections with TLS 1.2 or 1.3.
|
||||
# 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.
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: ISC
|
||||
*
|
||||
* Copyright (c) 2019 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
* Copyright (c) 2019-2020 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -19,8 +19,9 @@
|
||||
#ifndef SUDO_LOGSRV_UTIL_H
|
||||
#define SUDO_LOGSRV_UTIL_H
|
||||
|
||||
/* Default port to listen on */
|
||||
#define DEFAULT_PORT_STR "30344"
|
||||
/* Default ports to listen on */
|
||||
#define DEFAULT_PORT "30343"
|
||||
#define DEFAULT_PORT_TLS "30344"
|
||||
|
||||
/* Maximum message size (2Mb) */
|
||||
#define MESSAGE_SIZE_MAX (2 * 1024 * 1024)
|
||||
|
@ -102,13 +102,13 @@ connection_closure_free(struct connection_closure *closure)
|
||||
bool shutting_down = closure->state == SHUTDOWN;
|
||||
struct sudo_event_base *evbase = closure->evbase;
|
||||
|
||||
#if defined(HAVE_OPENSSL)
|
||||
if (logsrvd_conf_get_tls_opt()) {
|
||||
SSL_shutdown(closure->ssl);
|
||||
SSL_free(closure->ssl);
|
||||
}
|
||||
#endif
|
||||
TAILQ_REMOVE(&connections, closure, entries);
|
||||
#if defined(HAVE_OPENSSL)
|
||||
if (closure->tls) {
|
||||
SSL_shutdown(closure->ssl);
|
||||
SSL_free(closure->ssl);
|
||||
}
|
||||
#endif
|
||||
close(closure->sock);
|
||||
iolog_close_all(closure);
|
||||
sudo_ev_free(closure->commit_ev);
|
||||
@ -149,6 +149,7 @@ fmt_server_message(struct connection_buffer *buf, ServerMessage *msg)
|
||||
"server message too large: %zu", len);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Wire message size is used for length encoding, precedes message. */
|
||||
msg_len = htonl((uint32_t)len);
|
||||
len += sizeof(msg_len);
|
||||
@ -164,6 +165,8 @@ fmt_server_message(struct connection_buffer *buf, ServerMessage *msg)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
||||
"size + server message %zu bytes", len);
|
||||
|
||||
memcpy(buf->data, &msg_len, sizeof(msg_len));
|
||||
server_message__pack(msg, buf->data + sizeof(msg_len));
|
||||
@ -175,7 +178,7 @@ done:
|
||||
}
|
||||
|
||||
static bool
|
||||
fmt_hello_message(struct connection_buffer *buf)
|
||||
fmt_hello_message(struct connection_buffer *buf, bool tls)
|
||||
{
|
||||
ServerMessage msg = SERVER_MESSAGE__INIT;
|
||||
ServerHello hello = SERVER_HELLO__INIT;
|
||||
@ -184,14 +187,17 @@ fmt_hello_message(struct connection_buffer *buf)
|
||||
/* TODO: implement redirect and servers array. */
|
||||
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;
|
||||
if (tls) {
|
||||
hello.tls = true;
|
||||
hello.tls_server_auth = logsrvd_get_tls_config()->verify;
|
||||
hello.tls_reqcert = logsrvd_get_tls_config()->check_peer;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
hello.tls = false;
|
||||
hello.tls_server_auth = false;
|
||||
hello.tls_reqcert = false;
|
||||
}
|
||||
msg.hello = &hello;
|
||||
msg.type_case = SERVER_MESSAGE__TYPE_HELLO;
|
||||
|
||||
@ -601,8 +607,9 @@ shutdown_cb(int unused, int what, void *v)
|
||||
|
||||
#if defined(HAVE_OPENSSL)
|
||||
/* deallocate server's SSL context object */
|
||||
if (logsrvd_conf_get_tls_opt()) {
|
||||
SSL_CTX_free(logsrvd_get_tls_runtime()->ssl_ctx);
|
||||
struct logsrvd_tls_runtime *tls_runtime = logsrvd_get_tls_runtime();
|
||||
if (tls_runtime != NULL) {
|
||||
SSL_CTX_free(tls_runtime->ssl_ctx);
|
||||
}
|
||||
#endif
|
||||
sudo_ev_loopbreak(base);
|
||||
@ -682,9 +689,9 @@ server_msg_cb(int fd, int what, void *v)
|
||||
__func__, buf->len - buf->off);
|
||||
|
||||
#if defined(HAVE_OPENSSL)
|
||||
/* The initial ServerHello msg is not encrypted */
|
||||
if ((closure->ssl) != NULL && (closure->state != INITIAL)) {
|
||||
nwritten = SSL_write(closure->ssl, buf->data + buf->off, buf->len - buf->off);
|
||||
if (closure->tls) {
|
||||
nwritten = SSL_write(closure->ssl, buf->data + buf->off,
|
||||
buf->len - buf->off);
|
||||
if (nwritten <= 0) {
|
||||
int err = SSL_get_error(closure->ssl, nwritten);
|
||||
switch (err) {
|
||||
@ -700,19 +707,23 @@ server_msg_cb(int fd, int what, void *v)
|
||||
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
||||
"SSL_write returns SSL_ERROR_WANT_WRITE");
|
||||
debug_return;
|
||||
case SSL_ERROR_SYSCALL:
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unexpected error during SSL_write(): %d (%s)",
|
||||
err, strerror(errno));
|
||||
goto finished;
|
||||
default:
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unexpected error during SSL_write(). SSL error=%d (%s)",
|
||||
"unexpected error during SSL_write(): %d (%s)",
|
||||
err, ERR_error_string(ERR_get_error(), NULL));
|
||||
goto finished;
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
nwritten = send(fd, buf->data + buf->off, buf->len - buf->off, 0);
|
||||
}
|
||||
#else
|
||||
nwritten = send(fd, buf->data + buf->off, buf->len - buf->off, 0);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
nwritten = send(fd, buf->data + buf->off, buf->len - buf->off, 0);
|
||||
}
|
||||
|
||||
if (nwritten == -1) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||
@ -765,7 +776,7 @@ client_msg_cb(int fd, int what, void *v)
|
||||
}
|
||||
|
||||
#if defined(HAVE_OPENSSL)
|
||||
if (closure->ssl != NULL) {
|
||||
if (closure->tls) {
|
||||
nread = SSL_read(closure->ssl, buf->data + buf->len, buf->size);
|
||||
if (nread <= 0) {
|
||||
int err = SSL_get_error(closure->ssl, nread);
|
||||
@ -797,19 +808,23 @@ client_msg_cb(int fd, int what, void *v)
|
||||
/* Redirect write event to finish SSL_read() */
|
||||
closure->read_instead_of_write = true;
|
||||
debug_return;
|
||||
case SSL_ERROR_SYSCALL:
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unexpected error during SSL_read(): %d (%s)",
|
||||
err, strerror(errno));
|
||||
goto finished;
|
||||
default:
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unexpected error during SSL_read(). SSL error=%d (%s)",
|
||||
"unexpected error during SSL_read(): %d (%s)",
|
||||
err, ERR_error_string(ERR_get_error(), NULL));
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
nread = recv(fd, buf->data + buf->len, buf->size - buf->len, 0);
|
||||
}
|
||||
#else
|
||||
nread = recv(fd, buf->data + buf->len, buf->size - buf->len, 0);
|
||||
#endif
|
||||
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: received %zd bytes from client",
|
||||
__func__, nread);
|
||||
@ -920,6 +935,30 @@ bad:
|
||||
debug_return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Begin the sudo logserver protocol.
|
||||
* When we enter the event loop the ServerHello message will be written
|
||||
* and any pending ClientMessage will be read.
|
||||
*/
|
||||
static bool
|
||||
start_protocol(struct connection_closure *closure)
|
||||
{
|
||||
const struct timespec *timeout = logsrvd_conf_get_sock_timeout();
|
||||
debug_decl(start_protocol, SUDO_DEBUG_UTIL);
|
||||
|
||||
if (!fmt_hello_message(&closure->write_buf, closure->tls))
|
||||
debug_return_bool(false);
|
||||
|
||||
if (sudo_ev_add(closure->evbase, closure->write_ev, timeout, false) == -1)
|
||||
debug_return_bool(false);
|
||||
|
||||
/* No read timeout, client messages may happen at arbitrary times. */
|
||||
if (sudo_ev_add(closure->evbase, closure->read_ev, NULL, false) == -1)
|
||||
debug_return_bool(false);
|
||||
|
||||
debug_return_bool(true);
|
||||
}
|
||||
|
||||
#if defined(HAVE_OPENSSL)
|
||||
static int
|
||||
verify_peer_identity(int preverify_ok, X509_STORE_CTX *ctx)
|
||||
@ -1238,7 +1277,6 @@ static void
|
||||
tls_handshake_cb(int fd, int what, void *v)
|
||||
{
|
||||
struct connection_closure *closure = v;
|
||||
|
||||
debug_decl(tls_handshake_cb, SUDO_DEBUG_UTIL);
|
||||
|
||||
if (what == SUDO_EV_TIMEOUT) {
|
||||
@ -1293,6 +1331,11 @@ tls_handshake_cb(int fd, int what, void *v)
|
||||
goto bad;
|
||||
}
|
||||
debug_return;
|
||||
case SSL_ERROR_SYSCALL:
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unexpected error during TLS handshake: %d (%s)",
|
||||
err, strerror(errno));
|
||||
goto bad;
|
||||
default:
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unexpected error during TLS handshake: %d (%s)",
|
||||
@ -1300,16 +1343,15 @@ tls_handshake_cb(int fd, int what, void *v)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* Enable reader for ClientMessage */
|
||||
if (sudo_ev_add(closure->evbase, closure->read_ev, NULL, false) == -1) {
|
||||
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));
|
||||
|
||||
/* Start the actual protocol now that the TLS handshake is complete. */
|
||||
if (!start_protocol(closure))
|
||||
goto bad;
|
||||
|
||||
debug_return;
|
||||
bad:
|
||||
connection_closure_free(closure);
|
||||
@ -1321,7 +1363,7 @@ bad:
|
||||
* Allocate a new connection closure.
|
||||
*/
|
||||
static struct connection_closure *
|
||||
connection_closure_alloc(int sock, struct sudo_event_base *base)
|
||||
connection_closure_alloc(int sock, bool tls, struct sudo_event_base *base)
|
||||
{
|
||||
struct connection_closure *closure;
|
||||
debug_decl(connection_closure_alloc, SUDO_DEBUG_UTIL);
|
||||
@ -1331,6 +1373,7 @@ connection_closure_alloc(int sock, struct sudo_event_base *base)
|
||||
|
||||
closure->iolog_dir_fd = -1;
|
||||
closure->sock = sock;
|
||||
closure->tls = tls;
|
||||
closure->evbase = base;
|
||||
|
||||
TAILQ_INSERT_TAIL(&connections, closure, entries);
|
||||
@ -1356,10 +1399,12 @@ connection_closure_alloc(int sock, struct sudo_event_base *base)
|
||||
goto bad;
|
||||
|
||||
#if defined(HAVE_OPENSSL)
|
||||
closure->ssl_accept_ev = sudo_ev_alloc(sock, SUDO_EV_READ,
|
||||
tls_handshake_cb, closure);
|
||||
if (closure->ssl_accept_ev == NULL)
|
||||
goto bad;
|
||||
if (tls) {
|
||||
closure->ssl_accept_ev = sudo_ev_alloc(sock, SUDO_EV_READ,
|
||||
tls_handshake_cb, closure);
|
||||
if (closure->ssl_accept_ev == NULL)
|
||||
goto bad;
|
||||
}
|
||||
#endif
|
||||
|
||||
debug_return_ptr(closure);
|
||||
@ -1370,32 +1415,40 @@ bad:
|
||||
|
||||
/*
|
||||
* New connection.
|
||||
* Allocate a connection closure and send a server hello message.
|
||||
* Allocate a connection closure and optionally perform TLS handshake.
|
||||
*/
|
||||
static bool
|
||||
new_connection(int sock, const struct sockaddr *sa, struct sudo_event_base *base)
|
||||
new_connection(int sock, bool tls, const struct sockaddr *sa,
|
||||
struct sudo_event_base *evbase)
|
||||
{
|
||||
struct connection_closure *closure;
|
||||
|
||||
debug_decl(new_connection, SUDO_DEBUG_UTIL);
|
||||
|
||||
if ((closure = connection_closure_alloc(sock, base)) == NULL)
|
||||
if ((closure = connection_closure_alloc(sock, tls, evbase)) == NULL)
|
||||
goto bad;
|
||||
|
||||
/* Format and write ServerHello message. */
|
||||
if (!fmt_hello_message(&closure->write_buf))
|
||||
goto bad;
|
||||
if (sudo_ev_add(base, closure->write_ev,
|
||||
logsrvd_conf_get_sock_timeout(), false) == -1)
|
||||
/* store the peer's IP address in the closure object */
|
||||
if (sa->sa_family == AF_INET) {
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
|
||||
inet_ntop(AF_INET, &sin->sin_addr, closure->ipaddr,
|
||||
sizeof(closure->ipaddr));
|
||||
#if defined(HAVE_STRUCT_IN6_ADDR)
|
||||
} else if (sa->sa_family == AF_INET6) {
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
|
||||
inet_ntop(AF_INET6, &sin6->sin6_addr, closure->ipaddr,
|
||||
sizeof(closure->ipaddr));
|
||||
#endif /* HAVE_STRUCT_IN6_ADDR */
|
||||
} else {
|
||||
sudo_fatal(U_("unable to get remote IP addr"));
|
||||
goto bad;
|
||||
}
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
||||
"connection from %s", closure->ipaddr);
|
||||
|
||||
#if defined(HAVE_OPENSSL)
|
||||
/* if TLS is ON, first we need to do handshake with client,
|
||||
* otherwise just enable the reader
|
||||
*/
|
||||
if (logsrvd_conf_get_tls_opt()) {
|
||||
|
||||
/* create the SSL object for the closure and attach it to the socket */
|
||||
/* If TLS is enabled, perform the TLS handshake first. */
|
||||
if (tls) {
|
||||
/* Create the SSL object for the closure and attach it to the socket */
|
||||
if ((closure->ssl = SSL_new(logsrvd_get_tls_runtime()->ssl_ctx)) == NULL) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unable to create new ssl object: %s",
|
||||
@ -1419,39 +1472,18 @@ new_connection(int sock, const struct sockaddr *sa, struct sudo_event_base *base
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* enable SSL_accept to begin handshake with client */
|
||||
if (sudo_ev_add(base, closure->ssl_accept_ev,
|
||||
/* Enable SSL_accept to begin handshake with client. */
|
||||
if (sudo_ev_add(evbase, closure->ssl_accept_ev,
|
||||
logsrvd_conf_get_sock_timeout(), false) == -1) {
|
||||
sudo_fatal(U_("unable to add event to queue"));
|
||||
goto bad;
|
||||
}
|
||||
} else {
|
||||
/* Enable reader for ClientMessage*/
|
||||
if (sudo_ev_add(base, closure->read_ev, NULL, false) == -1)
|
||||
goto bad;
|
||||
}
|
||||
#else
|
||||
/* Enable reader for ClientMessage*/
|
||||
if (sudo_ev_add(base, closure->read_ev, NULL, false) == -1)
|
||||
goto bad;
|
||||
#endif
|
||||
|
||||
/* store the peer's IP address in the closure object*/
|
||||
if (sa->sa_family == AF_INET) {
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
|
||||
inet_ntop(AF_INET, &sin->sin_addr, closure->ipaddr,
|
||||
sizeof(closure->ipaddr));
|
||||
}
|
||||
#if defined(HAVE_STRUCT_IN6_ADDR)
|
||||
else if (sa->sa_family == AF_INET6){
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
|
||||
inet_ntop(AF_INET6, &sin6->sin6_addr, closure->ipaddr,
|
||||
sizeof(closure->ipaddr));
|
||||
}
|
||||
#endif /* HAVE_STRUCT_IN6_ADDR */
|
||||
else {
|
||||
sudo_fatal(U_("unable to get remote IP addr"));
|
||||
goto bad;
|
||||
/* If no TLS handshake, start the protocol immediately. */
|
||||
if (!tls) {
|
||||
if (!start_protocol(closure))
|
||||
goto bad;
|
||||
}
|
||||
|
||||
debug_return_bool(true);
|
||||
@ -1464,6 +1496,7 @@ static int
|
||||
create_listener(struct listen_address *addr)
|
||||
{
|
||||
int flags, on, sock;
|
||||
const char *family = "inet4";
|
||||
debug_decl(create_listener, SUDO_DEBUG_UTIL);
|
||||
|
||||
if ((sock = socket(addr->sa_un.sa.sa_family, SOCK_STREAM, 0)) == -1) {
|
||||
@ -1471,17 +1504,21 @@ create_listener(struct listen_address *addr)
|
||||
goto bad;
|
||||
}
|
||||
on = 1;
|
||||
#ifdef IPV6_V6ONLY
|
||||
#ifdef HAVE_STRUCT_IN6_ADDR
|
||||
if (addr->sa_un.sa.sa_family == AF_INET6) {
|
||||
family = "inet6";
|
||||
# ifdef IPV6_V6ONLY
|
||||
/* Disable IPv4-mapped IPv6 addresses. */
|
||||
if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) == -1)
|
||||
sudo_warn("IPV6_V6ONLY");
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)
|
||||
sudo_warn("SO_REUSEADDR");
|
||||
if (bind(sock, &addr->sa_un.sa, addr->sa_len) == -1) {
|
||||
sudo_warn("%s", addr->sa_str);
|
||||
/* TODO: only warn once for IPv4 and IPv6 or disambiguate */
|
||||
sudo_warn("%s (%s)", addr->sa_str, family);
|
||||
goto bad;
|
||||
}
|
||||
if (listen(sock, SOMAXCONN) == -1) {
|
||||
@ -1493,8 +1530,8 @@ create_listener(struct listen_address *addr)
|
||||
sudo_warn("fcntl(O_NONBLOCK)");
|
||||
goto bad;
|
||||
}
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO, "listening on %s (AF_INET%s)",
|
||||
addr->sa_str, addr->sa_un.sa.sa_family == AF_INET6 ? "6" : "");
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO, "listening on %s (%s)", addr->sa_str,
|
||||
family);
|
||||
|
||||
debug_return_int(sock);
|
||||
bad:
|
||||
@ -1506,7 +1543,8 @@ bad:
|
||||
static void
|
||||
listener_cb(int fd, int what, void *v)
|
||||
{
|
||||
struct sudo_event_base *base = v;
|
||||
struct listener *l = v;
|
||||
struct sudo_event_base *evbase = sudo_ev_get_base(l->ev);
|
||||
union sockaddr_union s_un;
|
||||
socklen_t salen = sizeof(s_un);
|
||||
int sock;
|
||||
@ -1523,7 +1561,7 @@ listener_cb(int fd, int what, void *v)
|
||||
"unable to set SO_KEEPALIVE option");
|
||||
}
|
||||
}
|
||||
if (!new_connection(sock, &s_un.sa, base)) {
|
||||
if (!new_connection(sock, l->tls, &s_un.sa, evbase)) {
|
||||
/* TODO: pause accepting on ENOMEM */
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
"unable to start new connection");
|
||||
@ -1540,10 +1578,9 @@ listener_cb(int fd, int what, void *v)
|
||||
}
|
||||
|
||||
static bool
|
||||
register_listener(struct listen_address *addr, struct sudo_event_base *base)
|
||||
register_listener(struct listen_address *addr, struct sudo_event_base *evbase)
|
||||
{
|
||||
struct listener *l;
|
||||
struct sudo_event *ev;
|
||||
int sock;
|
||||
debug_decl(register_listener, SUDO_DEBUG_UTIL);
|
||||
|
||||
@ -1552,15 +1589,15 @@ register_listener(struct listen_address *addr, struct sudo_event_base *base)
|
||||
debug_return_bool(false);
|
||||
|
||||
/* TODO: make non-fatal */
|
||||
ev = sudo_ev_alloc(sock, SUDO_EV_READ|SUDO_EV_PERSIST, listener_cb, base);
|
||||
if (ev == NULL)
|
||||
sudo_fatal(NULL);
|
||||
if (sudo_ev_add(base, ev, NULL, false) == -1)
|
||||
sudo_fatal(U_("unable to add event to queue"));
|
||||
if ((l = malloc(sizeof(*l))) == NULL)
|
||||
sudo_fatal(NULL);
|
||||
l->sock = sock;
|
||||
l->ev = ev;
|
||||
l->tls = addr->tls;
|
||||
l->ev = sudo_ev_alloc(sock, SUDO_EV_READ|SUDO_EV_PERSIST, listener_cb, l);
|
||||
if (l->ev == NULL)
|
||||
sudo_fatal(NULL);
|
||||
if (sudo_ev_add(evbase, l->ev, NULL, false) == -1)
|
||||
sudo_fatal(U_("unable to add event to queue"));
|
||||
TAILQ_INSERT_TAIL(&listeners, l, entries);
|
||||
|
||||
debug_return_bool(true);
|
||||
@ -1575,6 +1612,7 @@ server_setup(struct sudo_event_base *base)
|
||||
struct listen_address *addr;
|
||||
struct listener *l;
|
||||
int nlisteners = 0;
|
||||
bool config_tls = false;
|
||||
debug_decl(server_setup, SUDO_DEBUG_UTIL);
|
||||
|
||||
/* Free old listeners (if any) and register new ones. */
|
||||
@ -1586,14 +1624,16 @@ server_setup(struct sudo_event_base *base)
|
||||
}
|
||||
TAILQ_FOREACH(addr, logsrvd_conf_listen_address(), entries) {
|
||||
nlisteners += register_listener(addr, base);
|
||||
if (addr->tls)
|
||||
config_tls = true;
|
||||
}
|
||||
|
||||
if (config_tls) {
|
||||
#if defined(HAVE_OPENSSL)
|
||||
if (logsrvd_conf_get_tls_opt()) {
|
||||
if (!init_tls_server_context())
|
||||
sudo_fatal(NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
debug_return_bool(nlisteners > 0);
|
||||
}
|
||||
|
@ -31,9 +31,6 @@
|
||||
|
||||
#include "logsrv_util.h"
|
||||
|
||||
/* Default listen address (port 30344 on all interfaces). */
|
||||
#define DEFAULT_LISTEN_ADDR "*:" DEFAULT_PORT_STR
|
||||
|
||||
/* Default timeout value for server socket */
|
||||
#define DEFAULT_SOCKET_TIMEOUT_SEC 30
|
||||
|
||||
@ -102,6 +99,7 @@ struct connection_closure {
|
||||
#endif
|
||||
const char *errstr;
|
||||
struct iolog_file iolog_files[IOFD_MAX];
|
||||
bool tls;
|
||||
bool read_instead_of_write;
|
||||
bool write_instead_of_read;
|
||||
bool temporary_write_event;
|
||||
@ -131,6 +129,7 @@ struct listen_address {
|
||||
char *sa_str;
|
||||
union sockaddr_union sa_un;
|
||||
socklen_t sa_len;
|
||||
bool tls;
|
||||
};
|
||||
TAILQ_HEAD(listen_address_list, listen_address);
|
||||
|
||||
@ -141,6 +140,7 @@ struct listener {
|
||||
TAILQ_ENTRY(listener) entries;
|
||||
struct sudo_event *ev;
|
||||
int sock;
|
||||
bool tls;
|
||||
};
|
||||
TAILQ_HEAD(listener_list, listener);
|
||||
|
||||
@ -199,7 +199,6 @@ bool logsrvd_conf_tcp_keepalive(void);
|
||||
const char *logsrvd_conf_pid_file(void);
|
||||
struct timespec *logsrvd_conf_get_sock_timeout(void);
|
||||
#if defined(HAVE_OPENSSL)
|
||||
bool logsrvd_conf_get_tls_opt(void);
|
||||
const struct logsrvd_tls_config *logsrvd_get_tls_config(void);
|
||||
struct logsrvd_tls_runtime *logsrvd_get_tls_runtime(void);
|
||||
#endif
|
||||
|
@ -164,12 +164,6 @@ logsrvd_conf_get_sock_timeout(void)
|
||||
}
|
||||
|
||||
#if defined(HAVE_OPENSSL)
|
||||
bool
|
||||
logsrvd_conf_get_tls_opt(void)
|
||||
{
|
||||
return logsrvd_config->server.tls;
|
||||
}
|
||||
|
||||
const struct logsrvd_tls_config *
|
||||
logsrvd_get_tls_config(void)
|
||||
{
|
||||
@ -373,7 +367,6 @@ cb_iolog_maxseq(struct logsrvd_config *config, const char *str)
|
||||
}
|
||||
|
||||
/* Server callbacks */
|
||||
/* TODO: unit test */
|
||||
static bool
|
||||
cb_listen_address(struct logsrvd_config *config, const char *str)
|
||||
{
|
||||
@ -389,12 +382,19 @@ cb_listen_address(struct logsrvd_config *config, const char *str)
|
||||
}
|
||||
|
||||
/* Parse host[:port] */
|
||||
if (!sudo_parse_host_port(copy, &host, &port, &tls, DEFAULT_PORT_STR,
|
||||
DEFAULT_PORT_STR))
|
||||
if (!sudo_parse_host_port(copy, &host, &port, &tls, DEFAULT_PORT,
|
||||
DEFAULT_PORT_TLS))
|
||||
goto done;
|
||||
if (host[0] == '*' && host[1] == '\0')
|
||||
host = NULL;
|
||||
|
||||
#if !defined(HAVE_OPENSSL)
|
||||
if (tls) {
|
||||
sudo_warn("%s", U_("TLS not supported"));
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Resolve host (and port if it is a service). */
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
@ -402,7 +402,7 @@ cb_listen_address(struct logsrvd_config *config, const char *str)
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
error = getaddrinfo(host, port, &hints, &res0);
|
||||
if (error != 0) {
|
||||
sudo_warnx("%s", gai_strerror(error));
|
||||
sudo_gai_warn(error, U_("%s:%s"), host ? host : "*", port);
|
||||
goto done;
|
||||
}
|
||||
for (res = res0; res != NULL; res = res->ai_next) {
|
||||
@ -419,6 +419,7 @@ cb_listen_address(struct logsrvd_config *config, const char *str)
|
||||
}
|
||||
memcpy(&addr->sa_un, res->ai_addr, res->ai_addrlen);
|
||||
addr->sa_len = res->ai_addrlen;
|
||||
addr->tls = tls;
|
||||
TAILQ_INSERT_TAIL(&config->server.addresses, addr, entries);
|
||||
}
|
||||
|
||||
@ -482,19 +483,6 @@ cb_pid_file(struct logsrvd_config *config, const char *str)
|
||||
}
|
||||
|
||||
#if defined(HAVE_OPENSSL)
|
||||
static bool
|
||||
cb_tls_opt(struct logsrvd_config *config, const char *str)
|
||||
{
|
||||
int val;
|
||||
debug_decl(cb_tls_opt, SUDO_DEBUG_UTIL);
|
||||
|
||||
if ((val = sudo_strtobool(str)) == -1)
|
||||
debug_return_bool(false);
|
||||
|
||||
config->server.tls = val;
|
||||
debug_return_bool(true);
|
||||
}
|
||||
|
||||
static bool
|
||||
cb_tls_key(struct logsrvd_config *config, const char *path)
|
||||
{
|
||||
@ -761,7 +749,6 @@ static struct logsrvd_config_entry server_conf_entries[] = {
|
||||
{ "tcp_keepalive", cb_keepalive },
|
||||
{ "pid_file", cb_pid_file },
|
||||
#if defined(HAVE_OPENSSL)
|
||||
{ "tls", cb_tls_opt },
|
||||
{ "tls_key", cb_tls_key },
|
||||
{ "tls_cacert", cb_tls_cacert },
|
||||
{ "tls_cert", cb_tls_cert },
|
||||
@ -1069,8 +1056,12 @@ logsrvd_conf_apply(struct logsrvd_config *config)
|
||||
|
||||
/* There can be multiple addresses so we can't set a default earlier. */
|
||||
if (TAILQ_EMPTY(&config->server.addresses)) {
|
||||
if (!cb_listen_address(config, "*:30344"))
|
||||
if (!cb_listen_address(config, "*:" DEFAULT_PORT))
|
||||
debug_return_bool(false);
|
||||
#if defined(HAVE_OPENSSL)
|
||||
if (!cb_listen_address(config, "*:" DEFAULT_PORT_TLS "(tls)"))
|
||||
debug_return_bool(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Open event log if specified. */
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <sys/time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
@ -54,6 +55,7 @@
|
||||
#include "sudo_event.h"
|
||||
#include "sudo_fatal.h"
|
||||
#include "sudo_iolog.h"
|
||||
#include "hostcheck.h"
|
||||
#include "sendlog.h"
|
||||
|
||||
#if defined(HAVE_OPENSSL)
|
||||
@ -77,19 +79,23 @@
|
||||
TAILQ_HEAD(connection_list, client_closure);
|
||||
static struct connection_list connections = TAILQ_HEAD_INITIALIZER(connections);
|
||||
|
||||
static const char *server_name = "localhost";
|
||||
#if defined(HAVE_STRUCT_IN6_ADDR)
|
||||
static char server_ip[INET6_ADDRSTRLEN];
|
||||
#else
|
||||
static char server_ip[INET_ADDRSTRLEN];
|
||||
#endif
|
||||
static char *iolog_dir;
|
||||
static bool testrun = false;
|
||||
static int nr_of_conns = 1;
|
||||
static int finished_transmissions = 0;
|
||||
|
||||
#if defined(HAVE_OPENSSL)
|
||||
static bool tls = false;
|
||||
static bool tls_reqcert = false;
|
||||
static bool tls_server_auth = false;
|
||||
static SSL_CTX *ssl_ctx = NULL;
|
||||
const char *ca_bundle = NULL;
|
||||
const char *cert = NULL;
|
||||
const char *key = NULL;
|
||||
static const char *server_cert_error = NULL;
|
||||
static const char *ca_bundle = NULL;
|
||||
static const char *cert = NULL;
|
||||
static const char *key = NULL;
|
||||
#endif
|
||||
|
||||
/* Server callback may redirect to client callback for TLS. */
|
||||
@ -132,6 +138,44 @@ help(void)
|
||||
}
|
||||
|
||||
#if defined(HAVE_OPENSSL)
|
||||
/*
|
||||
* Check the server's certificate. If there is a problem, stores an error
|
||||
* string in server_cert_error. The TLS handshake is allowed to proceed
|
||||
* even if the server's cert does not validate. Checking of the server's
|
||||
* cert status is deferred until after the ServerHello message is parsed.
|
||||
*/
|
||||
static int
|
||||
verify_peer_identity(int preverify_ok, X509_STORE_CTX *ctx)
|
||||
{
|
||||
HostnameValidationResult result;
|
||||
X509 *current_cert;
|
||||
X509 *peer_cert;
|
||||
debug_decl(verify_peer_identity, SUDO_DEBUG_UTIL);
|
||||
|
||||
/* if pre-verification of the cert failed, store the error string. */
|
||||
if (preverify_ok != 1) {
|
||||
int err = X509_STORE_CTX_get_error(ctx);
|
||||
server_cert_error = X509_verify_cert_error_string(err);
|
||||
debug_return_int(1);
|
||||
}
|
||||
|
||||
/* since this callback is called for each cert in the chain,
|
||||
* check that current cert is the peer's certificate
|
||||
*/
|
||||
current_cert = X509_STORE_CTX_get_current_cert(ctx);
|
||||
peer_cert = X509_STORE_CTX_get0_cert(ctx);
|
||||
if (current_cert != peer_cert) {
|
||||
debug_return_int(1);
|
||||
}
|
||||
|
||||
result = validate_hostname(peer_cert, server_name, server_ip, 0);
|
||||
if (result != MatchFound) {
|
||||
server_cert_error = "server certificate does not match host name";
|
||||
}
|
||||
|
||||
debug_return_int(1);
|
||||
}
|
||||
|
||||
static SSL_CTX *
|
||||
init_tls_client_context(const char *ca_bundle_file, const char *cert_file, const char *key_file)
|
||||
{
|
||||
@ -182,7 +226,7 @@ init_tls_client_context(const char *ca_bundle_file, const char *cert_file, const
|
||||
}
|
||||
}
|
||||
|
||||
if (tls_server_auth) {
|
||||
if (ca_bundle_file != NULL) {
|
||||
/* sets the location of the CA bundle file for verification purposes */
|
||||
if (SSL_CTX_load_verify_locations(ctx, ca_bundle_file, NULL) <= 0) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
@ -190,11 +234,11 @@ init_tls_client_context(const char *ca_bundle_file, const char *cert_file, const
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* set verify server cert during the handshake */
|
||||
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
|
||||
}
|
||||
|
||||
/* verify server cert during the handshake */
|
||||
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_peer_identity);
|
||||
|
||||
goto exit;
|
||||
|
||||
bad:
|
||||
@ -208,11 +252,10 @@ static void
|
||||
tls_connect_cb(int sock, int what, void *v)
|
||||
{
|
||||
struct client_closure *closure = v;
|
||||
struct sudo_event_base *evbase = closure->tls_connect_ev->base;
|
||||
struct sudo_event_base *evbase = closure->evbase;
|
||||
struct timespec timeo = { TLS_HANDSHAKE_TIMEO_SEC, 0 };
|
||||
const char *errstr;
|
||||
int con_stat, err;
|
||||
|
||||
debug_decl(tls_connect_cb, SUDO_DEBUG_UTIL);
|
||||
|
||||
if (what == SUDO_EV_TIMEOUT) {
|
||||
@ -223,11 +266,15 @@ tls_connect_cb(int sock, int what, void *v)
|
||||
con_stat = SSL_connect(closure->ssl);
|
||||
|
||||
if (con_stat == 1) {
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
||||
"SSL_connect successful");
|
||||
closure->tls_connect_state = true;
|
||||
} else {
|
||||
switch ((err = SSL_get_error(closure->ssl, con_stat))) {
|
||||
/* TLS connect successful */
|
||||
case SSL_ERROR_NONE:
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
||||
"SSL_connect successful");
|
||||
closure->tls_connect_state = true;
|
||||
break;
|
||||
/* TLS handshake is not finished, reschedule event */
|
||||
@ -269,6 +316,19 @@ tls_connect_cb(int sock, int what, void *v)
|
||||
}
|
||||
}
|
||||
|
||||
if (closure->tls_connect_state) {
|
||||
if (!testrun) {
|
||||
printf("Negotiated protocol version: %s\n", SSL_get_version(closure->ssl));
|
||||
printf("Negotiated ciphersuite: %s\n", SSL_get_cipher(closure->ssl));
|
||||
}
|
||||
|
||||
/* Done with TLS connect, read ServerHello */
|
||||
sudo_ev_free(closure->tls_connect_ev);
|
||||
closure->tls_connect_ev = NULL;
|
||||
if (sudo_ev_add(evbase, closure->read_ev, NULL, false) == -1)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
debug_return;
|
||||
|
||||
bad:
|
||||
@ -277,50 +337,15 @@ bad:
|
||||
}
|
||||
|
||||
static bool
|
||||
tls_connect_async(struct client_closure *closure)
|
||||
{
|
||||
struct sudo_event_base *evbase;
|
||||
debug_decl(tls_connect_async, SUDO_DEBUG_UTIL);
|
||||
|
||||
closure->tls_connect_state = false;
|
||||
evbase = sudo_ev_base_alloc();
|
||||
closure->tls_connect_ev = sudo_ev_alloc(closure->sock, SUDO_EV_WRITE,
|
||||
tls_connect_cb, closure);
|
||||
if (evbase == NULL || closure->tls_connect_ev == NULL) {
|
||||
sudo_warnx(U_("unable to allocate memory"));
|
||||
goto done;
|
||||
}
|
||||
if (sudo_ev_add(evbase, closure->tls_connect_ev, NULL, false) == -1) {
|
||||
sudo_warnx(U_("unable to add event to queue"));
|
||||
goto done;
|
||||
}
|
||||
if (sudo_ev_dispatch(evbase) == -1 || sudo_ev_got_break(evbase)) {
|
||||
sudo_warn(U_("error in event loop"));
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
sudo_ev_base_free(evbase);
|
||||
sudo_ev_free(closure->tls_connect_ev);
|
||||
closure->tls_connect_ev = NULL;
|
||||
|
||||
debug_return_int(closure->tls_connect_state);
|
||||
}
|
||||
|
||||
static bool
|
||||
do_tls_handshake(struct client_closure *closure)
|
||||
tls_setup(struct client_closure *closure)
|
||||
{
|
||||
const char *errstr;
|
||||
debug_decl(do_tls_handshake, SUDO_DEBUG_UTIL);
|
||||
debug_decl(tls_setup, SUDO_DEBUG_UTIL);
|
||||
|
||||
if (ca_bundle == NULL) {
|
||||
sudo_warnx("%s", U_("CA bundle file was not specified"));
|
||||
goto bad;
|
||||
}
|
||||
if (tls_reqcert && (cert == NULL)) {
|
||||
sudo_warnx("%s", U_("Client certificate was not specified"));
|
||||
goto bad;
|
||||
}
|
||||
if ((ssl_ctx = init_tls_client_context(ca_bundle, cert, key)) == NULL) {
|
||||
errstr = ERR_reason_error_string(ERR_get_error());
|
||||
sudo_warnx(U_("Unable to initialize ssl context: %s"), errstr);
|
||||
@ -338,12 +363,9 @@ do_tls_handshake(struct client_closure *closure)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!tls_connect_async(closure))
|
||||
goto bad;
|
||||
|
||||
if (!testrun) {
|
||||
printf("Negotiated protocol version: %s\n", SSL_get_version(closure->ssl));
|
||||
printf("Negotiated ciphersuite: %s\n", SSL_get_cipher(closure->ssl));
|
||||
if (sudo_ev_add(closure->evbase, closure->tls_connect_ev, NULL, false) == -1) {
|
||||
sudo_warnx(U_("unable to add event to queue"));
|
||||
goto bad;
|
||||
}
|
||||
|
||||
debug_return_bool(true);
|
||||
@ -391,8 +413,16 @@ connect_server(const char *host, const char *port)
|
||||
sock = -1;
|
||||
continue;
|
||||
}
|
||||
if (*server_ip == '\0') {
|
||||
if (inet_ntop(res->ai_family, res->ai_addr, server_ip,
|
||||
sizeof(server_ip)) == NULL) {
|
||||
sudo_warnx(U_("unable to get server IP addr"));
|
||||
}
|
||||
}
|
||||
break; /* success */
|
||||
}
|
||||
freeaddrinfo(res0);
|
||||
|
||||
if (sock != -1) {
|
||||
int flags = fcntl(sock, F_GETFL, 0);
|
||||
if (flags == -1 || fcntl(sock, F_SETFL, flags | O_NONBLOCK) == -1) {
|
||||
@ -403,10 +433,8 @@ connect_server(const char *host, const char *port)
|
||||
sock = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (sock == -1)
|
||||
sudo_warn("%s", cause);
|
||||
freeaddrinfo(res0);
|
||||
|
||||
debug_return_int(sock);
|
||||
}
|
||||
@ -420,22 +448,20 @@ client_closure_free(struct client_closure *closure)
|
||||
debug_decl(connection_closure_free, SUDO_DEBUG_UTIL);
|
||||
|
||||
if (closure != NULL) {
|
||||
TAILQ_REMOVE(&connections, closure, entries);
|
||||
#if defined(HAVE_OPENSSL)
|
||||
if (closure->ssl != NULL) {
|
||||
SSL_shutdown(closure->ssl);
|
||||
SSL_free(closure->ssl);
|
||||
}
|
||||
sudo_ev_free(closure->tls_connect_ev);
|
||||
#endif
|
||||
TAILQ_REMOVE(&connections, closure, entries);
|
||||
close(closure->sock);
|
||||
sudo_ev_free(closure->read_ev);
|
||||
sudo_ev_free(closure->write_ev);
|
||||
#if defined(HAVE_OPENSSL)
|
||||
sudo_ev_free(closure->tls_connect_ev);
|
||||
#endif
|
||||
free(closure->read_buf.data);
|
||||
free(closure->write_buf.data);
|
||||
free(closure->buf);
|
||||
close(closure->sock);
|
||||
free(closure);
|
||||
}
|
||||
|
||||
@ -487,10 +513,12 @@ client_closure_alloc(int sock, struct sudo_event_base *base,
|
||||
goto bad;
|
||||
|
||||
#if defined(HAVE_OPENSSL)
|
||||
closure->tls_connect_ev = sudo_ev_alloc(sock, SUDO_EV_WRITE,
|
||||
tls_connect_cb, closure);
|
||||
if (closure->tls_connect_ev == NULL)
|
||||
goto bad;
|
||||
if (cert != NULL) {
|
||||
closure->tls_connect_ev = sudo_ev_alloc(sock, SUDO_EV_WRITE,
|
||||
tls_connect_cb, closure);
|
||||
if (closure->tls_connect_ev == NULL)
|
||||
goto bad;
|
||||
}
|
||||
#endif
|
||||
|
||||
debug_return_ptr(closure);
|
||||
@ -1062,25 +1090,31 @@ handle_server_hello(ServerHello *msg, struct client_closure *closure)
|
||||
}
|
||||
|
||||
#if defined(HAVE_OPENSSL)
|
||||
tls = msg->tls;
|
||||
tls_reqcert = msg->tls_reqcert;
|
||||
tls_server_auth = msg->tls_server_auth;
|
||||
if (msg->tls_reqcert && cert == NULL) {
|
||||
sudo_warnx("%s", U_("Client certificate was not specified"));
|
||||
debug_return_bool(false);
|
||||
}
|
||||
|
||||
if (msg->tls_server_auth && server_cert_error != NULL) {
|
||||
sudo_warnx("%s", server_cert_error);
|
||||
debug_return_bool(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!testrun) {
|
||||
printf("server ID: %s\n", msg->server_id);
|
||||
printf("Server ID: %s\n", msg->server_id);
|
||||
/* TODO: handle redirect */
|
||||
if (msg->redirect != NULL && msg->redirect[0] != '\0')
|
||||
printf("redirect: %s\n", msg->redirect);
|
||||
printf("Redirect: %s\n", msg->redirect);
|
||||
for (n = 0; n < msg->n_servers; n++) {
|
||||
printf("server %zu: %s\n", n + 1, msg->servers[n]);
|
||||
printf("Server %zu: %s\n", n + 1, msg->servers[n]);
|
||||
}
|
||||
|
||||
#if defined(HAVE_OPENSSL)
|
||||
if (tls) {
|
||||
if (msg->tls) {
|
||||
printf("Requested protocol: TLS\n");
|
||||
printf("Server authentication: %s\n", tls_server_auth ? "Required":"Not Required");
|
||||
printf("Client authentication: %s\n", tls_reqcert ? "Required":"Not Required");
|
||||
printf("Server authentication: %s\n", msg->tls_server_auth ? "Required":"Not Required");
|
||||
printf("Client authentication: %s\n", msg->tls_reqcert ? "Required":"Not Required");
|
||||
} else {
|
||||
printf("Requested protocol: ClearText\n");
|
||||
}
|
||||
@ -1123,7 +1157,7 @@ handle_log_id(char *id, struct client_closure *closure)
|
||||
debug_decl(handle_log_id, SUDO_DEBUG_UTIL);
|
||||
|
||||
if (!testrun)
|
||||
printf("remote log ID: %s\n", id);
|
||||
printf("Remote log ID: %s\n", id);
|
||||
|
||||
debug_return_bool(true);
|
||||
}
|
||||
@ -1176,20 +1210,12 @@ handle_server_message(uint8_t *buf, size_t len,
|
||||
switch (msg->type_case) {
|
||||
case SERVER_MESSAGE__TYPE_HELLO:
|
||||
if ((ret = handle_server_hello(msg->hello, closure))) {
|
||||
/* if server wants to communicate over TLS,
|
||||
* we have to initialize tls context and do
|
||||
* a tls connection to the server
|
||||
*/
|
||||
#if defined(HAVE_OPENSSL)
|
||||
if (tls && !do_tls_handshake(closure))
|
||||
debug_return_bool(false);
|
||||
#endif
|
||||
if (sudo_timespecisset(&closure->restart)) {
|
||||
closure->state = SEND_RESTART;
|
||||
ret = fmt_restart_message(closure);
|
||||
closure->state = SEND_RESTART;
|
||||
ret = fmt_restart_message(closure);
|
||||
} else {
|
||||
closure->state = SEND_ACCEPT;
|
||||
ret = fmt_accept_message(closure);
|
||||
closure->state = SEND_ACCEPT;
|
||||
ret = fmt_accept_message(closure);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1247,9 +1273,9 @@ server_msg_cb(int fd, int what, void *v)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: reading ServerMessage", __func__);
|
||||
#if defined(HAVE_OPENSSL)
|
||||
if (tls && closure->state != RECV_HELLO) {
|
||||
if (cert != NULL) {
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: reading ServerMessage (TLS)", __func__);
|
||||
nread = SSL_read(closure->ssl, buf->data + buf->len, buf->size - buf->len);
|
||||
if (nread <= 0) {
|
||||
int read_status = SSL_get_error(closure->ssl, nread);
|
||||
@ -1282,12 +1308,12 @@ server_msg_cb(int fd, int what, void *v)
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
nread = recv(fd, buf->data + buf->len, buf->size - buf->len, 0);
|
||||
}
|
||||
#else
|
||||
nread = recv(fd, buf->data + buf->len, buf->size - buf->len, 0);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: reading ServerMessage", __func__);
|
||||
nread = recv(fd, buf->data + buf->len, buf->size - buf->len, 0);
|
||||
}
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: received %zd bytes from server",
|
||||
__func__, nread);
|
||||
switch (nread) {
|
||||
@ -1369,7 +1395,7 @@ client_msg_cb(int fd, int what, void *v)
|
||||
"%s: sending %u bytes to server", __func__, buf->len - buf->off);
|
||||
|
||||
#if defined(HAVE_OPENSSL)
|
||||
if (tls) {
|
||||
if (cert != NULL) {
|
||||
nwritten = SSL_write(closure->ssl, buf->data + buf->off, buf->len - buf->off);
|
||||
if (nwritten <= 0) {
|
||||
int write_status = SSL_get_error(closure->ssl, nwritten);
|
||||
@ -1390,12 +1416,11 @@ client_msg_cb(int fd, int what, void *v)
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
nwritten = send(fd, buf->data + buf->off, buf->len - buf->off, 0);
|
||||
}
|
||||
#else
|
||||
nwritten = send(fd, buf->data + buf->off, buf->len - buf->off, 0);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
nwritten = send(fd, buf->data + buf->off, buf->len - buf->off, 0);
|
||||
}
|
||||
if (nwritten == -1) {
|
||||
sudo_warn("send");
|
||||
goto bad;
|
||||
@ -1481,8 +1506,7 @@ main(int argc, char *argv[])
|
||||
struct client_closure *closure = NULL;
|
||||
struct sudo_event_base *evbase;
|
||||
struct iolog_info *log_info;
|
||||
const char *host = "localhost";
|
||||
const char *port = DEFAULT_PORT_STR;
|
||||
const char *port = NULL;
|
||||
struct timespec restart = { 0, 0 };
|
||||
struct timespec elapsed = { 0, 0 };
|
||||
const char *iolog_id = NULL;
|
||||
@ -1517,7 +1541,7 @@ main(int argc, char *argv[])
|
||||
while ((ch = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
host = optarg;
|
||||
server_name = optarg;
|
||||
break;
|
||||
case 'i':
|
||||
iolog_id = optarg;
|
||||
@ -1565,10 +1589,15 @@ main(int argc, char *argv[])
|
||||
|
||||
#if defined(HAVE_OPENSSL)
|
||||
/* if no key file is given explicitly, try to load the key from the cert */
|
||||
if (cert && !key) {
|
||||
key = cert;
|
||||
if (cert != NULL) {
|
||||
if (key == NULL)
|
||||
key = cert;
|
||||
if (port == NULL)
|
||||
port = DEFAULT_PORT_TLS;
|
||||
}
|
||||
#endif
|
||||
if (port == NULL)
|
||||
port = DEFAULT_PORT;
|
||||
|
||||
if (sudo_timespecisset(&restart) != (iolog_id != NULL)) {
|
||||
sudo_warnx("%s", U_("both restart point and iolog ID must be specified"));
|
||||
@ -1595,12 +1624,12 @@ main(int argc, char *argv[])
|
||||
printf("connecting clients...\n");
|
||||
|
||||
for (int i = 0; i < nr_of_conns; i++) {
|
||||
sock = connect_server(host, port);
|
||||
sock = connect_server(server_name, port);
|
||||
if (sock == -1)
|
||||
goto bad;
|
||||
|
||||
if (!testrun)
|
||||
printf("Connected to %s:%s\n", host, port);
|
||||
printf("Connected to %s:%s\n", server_name, port);
|
||||
|
||||
closure = client_closure_alloc(sock, evbase, &elapsed, &restart,
|
||||
iolog_id, log_info);
|
||||
@ -1616,8 +1645,17 @@ main(int argc, char *argv[])
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (sudo_ev_add(evbase, closure->read_ev, NULL, false) == -1)
|
||||
goto bad;
|
||||
#if defined(HAVE_OPENSSL)
|
||||
if (cert != NULL) {
|
||||
if (!tls_setup(closure))
|
||||
goto bad;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
/* No TLS, read ServerHello */
|
||||
if (sudo_ev_add(evbase, closure->read_ev, NULL, false) == -1)
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
|
||||
if (testrun)
|
||||
|
Loading…
x
Reference in New Issue
Block a user