mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-14 00:14:11 +09:00
Merge pull request #11947 from akallabeth/cert-warn-improve
[crypto,tls] make cert warning more accurate
This commit is contained in:
@@ -93,7 +93,7 @@ static void tls_print_certificate_name_mismatch_error(const char* hostname, UINT
|
||||
const char* common_name, char** alt_names,
|
||||
size_t alt_names_count);
|
||||
static void tls_print_new_certificate_warn(rdpCertificateStore* store, const char* hostname,
|
||||
UINT16 port, const char* fingerprint);
|
||||
UINT16 port, const char* type, const char* fingerprint);
|
||||
static void tls_print_certificate_error(rdpCertificateStore* store, rdpCertificateData* stored_data,
|
||||
const char* hostname, UINT16 port, const char* fingerprint);
|
||||
|
||||
@@ -1650,12 +1650,17 @@ int tls_verify_certificate(rdpTls* tls, const rdpCertificate* cert, const char*
|
||||
DWORD flags = VERIFY_CERT_FLAG_NONE;
|
||||
|
||||
WINPR_ASSERT(tls);
|
||||
WINPR_ASSERT(tls->context);
|
||||
|
||||
freerdp* instance = tls->context->instance;
|
||||
rdpContext* context = tls->context;
|
||||
WINPR_ASSERT(context);
|
||||
|
||||
freerdp* instance = context->instance;
|
||||
WINPR_ASSERT(instance);
|
||||
|
||||
if (freerdp_shall_disconnect_context(instance->context))
|
||||
const rdpSettings* settings = context->settings;
|
||||
WINPR_ASSERT(settings);
|
||||
|
||||
if (freerdp_shall_disconnect_context(context))
|
||||
return -1;
|
||||
|
||||
if (!tls_extract_full_pem(cert, &pemCert, &length))
|
||||
@@ -1668,7 +1673,7 @@ int tls_verify_certificate(rdpTls* tls, const rdpCertificate* cert, const char*
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (is_accepted_fingerprint(cert, tls->context->settings->CertificateAcceptedFingerprints))
|
||||
if (is_accepted_fingerprint(cert, settings->CertificateAcceptedFingerprints))
|
||||
{
|
||||
verification_status = 1;
|
||||
goto end;
|
||||
@@ -1684,7 +1689,7 @@ int tls_verify_certificate(rdpTls* tls, const rdpCertificate* cert, const char*
|
||||
flags |= VERIFY_CERT_FLAG_REDIRECT;
|
||||
|
||||
/* Certificate management is done by the application */
|
||||
if (tls->context->settings->ExternalCertificateManagement)
|
||||
if (settings->ExternalCertificateManagement)
|
||||
{
|
||||
if (instance->VerifyX509Certificate)
|
||||
verification_status =
|
||||
@@ -1702,7 +1707,7 @@ int tls_verify_certificate(rdpTls* tls, const rdpCertificate* cert, const char*
|
||||
}
|
||||
}
|
||||
/* ignore certificate verification if user explicitly required it (discouraged) */
|
||||
else if (freerdp_settings_get_bool(tls->context->settings, FreeRDP_IgnoreCertificate))
|
||||
else if (freerdp_settings_get_bool(settings, FreeRDP_IgnoreCertificate))
|
||||
{
|
||||
WLog_WARN(TAG, "[DANGER] Certificate not checked, /cert:ignore in use.");
|
||||
WLog_WARN(TAG, "[DANGER] This prevents MITM attacks from being detected!");
|
||||
@@ -1710,13 +1715,13 @@ int tls_verify_certificate(rdpTls* tls, const rdpCertificate* cert, const char*
|
||||
"[DANGER] Avoid using this unless in a secure LAN (=no internet) environment");
|
||||
verification_status = 1; /* success! */
|
||||
}
|
||||
else if (!tls->isGatewayTransport && (tls->context->settings->AuthenticationLevel == 0))
|
||||
else if (!tls->isGatewayTransport && (settings->AuthenticationLevel == 0))
|
||||
verification_status = 1; /* success! */
|
||||
else
|
||||
{
|
||||
/* if user explicitly specified a certificate name, use it instead of the hostname */
|
||||
if (!tls->isGatewayTransport && tls->context->settings->CertificateName)
|
||||
hostname = tls->context->settings->CertificateName;
|
||||
if (!tls->isGatewayTransport && settings->CertificateName)
|
||||
hostname = settings->CertificateName;
|
||||
|
||||
/* attempt verification using OpenSSL and the ~/.freerdp/certs certificate store */
|
||||
certificate_status = freerdp_certificate_verify(
|
||||
@@ -1789,18 +1794,29 @@ int tls_verify_certificate(rdpTls* tls, const rdpCertificate* cert, const char*
|
||||
dns_names, dns_names_count);
|
||||
|
||||
{
|
||||
const char* type = "";
|
||||
if (freerdp_settings_get_bool(settings, FreeRDP_AutoAcceptCertificate))
|
||||
type = "tofo (auto-accept)";
|
||||
|
||||
if (freerdp_settings_get_bool(settings, FreeRDP_AutoDenyCertificate))
|
||||
type = "strict (auto-deny)";
|
||||
|
||||
if (freerdp_settings_get_bool(settings, FreeRDP_IgnoreCertificate))
|
||||
type = "ignore (no check)";
|
||||
|
||||
char* efp = freerdp_certificate_get_fingerprint(cert);
|
||||
tls_print_new_certificate_warn(tls->certificate_store, hostname, port, efp);
|
||||
tls_print_new_certificate_warn(tls->certificate_store, hostname, port, type,
|
||||
efp);
|
||||
free(efp);
|
||||
}
|
||||
|
||||
/* Automatically accept certificate on first use */
|
||||
if (tls->context->settings->AutoAcceptCertificate)
|
||||
if (settings->AutoAcceptCertificate)
|
||||
{
|
||||
WLog_INFO(TAG, "No certificate stored, automatically accepting.");
|
||||
accept_certificate = 1;
|
||||
}
|
||||
else if (tls->context->settings->AutoDenyCertificate)
|
||||
else if (settings->AutoDenyCertificate)
|
||||
{
|
||||
WLog_INFO(TAG, "No certificate stored, automatically denying.");
|
||||
accept_certificate = 0;
|
||||
@@ -1819,8 +1835,8 @@ int tls_verify_certificate(rdpTls* tls, const rdpCertificate* cert, const char*
|
||||
}
|
||||
else if (instance->VerifyCertificateEx)
|
||||
{
|
||||
const BOOL use_pem = freerdp_settings_get_bool(
|
||||
tls->context->settings, FreeRDP_CertificateCallbackPreferPEM);
|
||||
const BOOL use_pem =
|
||||
freerdp_settings_get_bool(settings, FreeRDP_CertificateCallbackPreferPEM);
|
||||
char* fp = NULL;
|
||||
DWORD cflags = flags;
|
||||
if (use_pem)
|
||||
@@ -1865,7 +1881,7 @@ int tls_verify_certificate(rdpTls* tls, const rdpCertificate* cert, const char*
|
||||
WLog_WARN(TAG, "Failed to get certificate entry for %s:%" PRIu16 "", hostname,
|
||||
port);
|
||||
|
||||
if (tls->context->settings->AutoDenyCertificate)
|
||||
if (settings->AutoDenyCertificate)
|
||||
{
|
||||
WLog_INFO(TAG, "No certificate stored, automatically denying.");
|
||||
accept_certificate = 0;
|
||||
@@ -1892,8 +1908,7 @@ int tls_verify_certificate(rdpTls* tls, const rdpCertificate* cert, const char*
|
||||
const char* old_pem = freerdp_certificate_data_get_pem(stored_data);
|
||||
const BOOL fpIsAllocated =
|
||||
!old_pem ||
|
||||
!freerdp_settings_get_bool(tls->context->settings,
|
||||
FreeRDP_CertificateCallbackPreferPEM);
|
||||
!freerdp_settings_get_bool(settings, FreeRDP_CertificateCallbackPreferPEM);
|
||||
char* fp = NULL;
|
||||
if (!fpIsAllocated)
|
||||
{
|
||||
@@ -1975,7 +1990,7 @@ end:
|
||||
}
|
||||
|
||||
void tls_print_new_certificate_warn(rdpCertificateStore* store, const char* hostname, UINT16 port,
|
||||
const char* fingerprint)
|
||||
const char* type, const char* fingerprint)
|
||||
{
|
||||
char* path = freerdp_certificate_store_get_cert_path(store, hostname, port);
|
||||
|
||||
@@ -1989,7 +2004,8 @@ void tls_print_new_certificate_warn(rdpCertificateStore* store, const char* host
|
||||
WLog_ERR(TAG, "The fingerprint for the host key sent by the remote host is %s", fingerprint);
|
||||
WLog_ERR(TAG, "Please contact your system administrator.");
|
||||
WLog_ERR(TAG, "Add correct host key in %s to get rid of this message.", path);
|
||||
WLog_ERR(TAG, "Host key for %s has changed and you have requested strict checking.", hostname);
|
||||
WLog_ERR(TAG, "Host key for %s has changed and you have requested %s checking.", hostname,
|
||||
type);
|
||||
WLog_ERR(TAG, "Host key verification failed.");
|
||||
|
||||
free(path);
|
||||
|
||||
Reference in New Issue
Block a user