#include "packets.h"
#include "poll-loop.h"
#include "socket-util.h"
-#include "socket-util.h"
#include "util.h"
#include "stream-provider.h"
#include "stream.h"
static struct ssl_config_file certificate;
static struct ssl_config_file ca_cert;
+/* Ordinarily, the SSL client and server verify each other's certificates using
+ * a CA certificate. Setting this to false disables this behavior. (This is a
+ * security risk.) */
+static bool verify_peer_cert = true;
+
/* Ordinarily, we require a CA certificate for the peer to be locally
* available. We can, however, bootstrap the CA certificate from the peer at
* the beginning of our first connection then use that certificate on all
VLOG_ERR("Certificate must be configured to use SSL");
retval = ENOPROTOOPT;
}
- if (!ca_cert.read && !bootstrap_ca_cert) {
+ if (!ca_cert.read && verify_peer_cert && !bootstrap_ca_cert) {
VLOG_ERR("CA certificate must be configured to use SSL");
retval = ENOPROTOOPT;
}
retval = ENOPROTOOPT;
goto error;
}
- if (bootstrap_ca_cert && type == CLIENT) {
+ if (!verify_peer_cert || (bootstrap_ca_cert && type == CLIENT)) {
SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
}
}
} else if (bootstrap_ca_cert) {
return do_ca_cert_bootstrap(stream);
- } else if ((SSL_get_verify_mode(sslv->ssl)
- & (SSL_VERIFY_NONE | SSL_VERIFY_PEER))
- != SSL_VERIFY_PEER) {
+ } else if (verify_peer_cert
+ && ((SSL_get_verify_mode(sslv->ssl)
+ & (SSL_VERIFY_NONE | SSL_VERIFY_PEER))
+ != SSL_VERIFY_PEER)) {
/* Two or more SSL connections completed at the same time while we
* were in bootstrap mode. Only one of these can finish the
* bootstrap successfully. The other one(s) must be rejected
return private_key.file_name || certificate.file_name || ca_cert.file_name;
}
-static void
-get_mtime(const char *file_name, struct timespec *mtime)
-{
- struct stat s;
-
- if (!stat(file_name, &s)) {
- mtime->tv_sec = s.st_mtime;
-
-#if HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
- mtime->tv_nsec = s.st_mtim.tv_nsec;
-#elif HAVE_STRUCT_STAT_ST_MTIMENSEC
- mtime->tv_nsec = s.st_mtimensec;
-#else
- mtime->tv_nsec = 0;
-#endif
- } else {
- mtime->tv_sec = mtime->tv_nsec = 0;
- }
-}
-
static bool
update_ssl_config(struct ssl_config_file *config, const char *file_name)
{
return false;
}
+ /* Update 'config'. */
config->mtime = mtime;
- free(config->file_name);
- config->file_name = xstrdup(file_name);
+ if (file_name != config->file_name) {
+ free(config->file_name);
+ config->file_name = xstrdup(file_name);
+ }
return true;
}
size_t n_certs;
struct stat s;
- if (bootstrap && stat(file_name, &s) && errno == ENOENT) {
+ if (!strcmp(file_name, "none")) {
+ verify_peer_cert = false;
+ VLOG_WARN("Peer certificate validation disabled "
+ "(this is a security risk)");
+ } else if (bootstrap && stat(file_name, &s) && errno == ENOENT) {
bootstrap_ca_cert = true;
} else if (!read_cert_file(file_name, &certs, &n_certs)) {
size_t i;