From: Armin Novak Date: Fri, 30 Nov 2018 10:04:20 +0000 (+0100) Subject: Added new default certificate callbacks with extended information. X-Git-Tag: 2.0.0~603^2~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e04c319d212706b51500e586db0548583308154f;p=platform%2Fupstream%2Ffreerdp.git Added new default certificate callbacks with extended information. The extended information provided by VerifyCertificateEx and VerifyChangedCertificateEx is now exploited by the new functions client_cli_verify_certificate_ex and client_cli_verify_changed_certificate_ex. The old callbacks now print out deprecation warnings to inform the user and developer about this deprecation. --- diff --git a/client/Sample/tf_freerdp.c b/client/Sample/tf_freerdp.c index 05eb9ed..5549cb0 100644 --- a/client/Sample/tf_freerdp.c +++ b/client/Sample/tf_freerdp.c @@ -107,11 +107,9 @@ static BOOL tf_pre_connect(freerdp* instance) /* Optional OS identifier sent to server */ settings->OsMajorType = OSMAJORTYPE_UNIX; settings->OsMinorType = OSMINORTYPE_NATIVE_XSERVER; - /* settings->OrderSupport is initialized at this point. * Only override it if you plan to implement custom order * callbacks or deactiveate certain features. */ - /* Register the channel listeners. * They are required to set up / tear down channels if they are loaded. */ PubSub_SubscribeChannelConnected(instance->context->pubSub, @@ -262,8 +260,8 @@ static BOOL tf_client_new(freerdp* instance, rdpContext* context) instance->PostDisconnect = tf_post_disconnect; instance->Authenticate = client_cli_authenticate; instance->GatewayAuthenticate = client_cli_gw_authenticate; - instance->VerifyCertificate = client_cli_verify_certificate; - instance->VerifyChangedCertificate = client_cli_verify_changed_certificate; + instance->VerifyCertificateEx = client_cli_verify_certificate_ex; + instance->VerifyChangedCertificateEx = client_cli_verify_changed_certificate_ex; instance->LogonErrorInfo = tf_logon_error_info; /* TODO: Client display set up */ return TRUE; diff --git a/client/Wayland/wlfreerdp.c b/client/Wayland/wlfreerdp.c index 00614cf..04a9c68 100644 --- a/client/Wayland/wlfreerdp.c +++ b/client/Wayland/wlfreerdp.c @@ -386,8 +386,8 @@ static BOOL wlf_client_new(freerdp* instance, rdpContext* context) instance->PostDisconnect = wl_post_disconnect; instance->Authenticate = client_cli_authenticate; instance->GatewayAuthenticate = client_cli_gw_authenticate; - instance->VerifyCertificate = client_cli_verify_certificate; - instance->VerifyChangedCertificate = client_cli_verify_changed_certificate; + instance->VerifyCertificateEx = client_cli_verify_certificate_ex; + instance->VerifyChangedCertificateEx = client_cli_verify_changed_certificate_ex; instance->LogonErrorInfo = wlf_logon_error_info; wfl->display = UwacOpenDisplay(NULL, &status); diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index 8930cc9..8323c78 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -1763,8 +1763,8 @@ static BOOL xfreerdp_client_new(freerdp* instance, rdpContext* context) instance->PostDisconnect = xf_post_disconnect; instance->Authenticate = client_cli_authenticate; instance->GatewayAuthenticate = client_cli_gw_authenticate; - instance->VerifyCertificate = client_cli_verify_certificate; - instance->VerifyChangedCertificate = client_cli_verify_changed_certificate; + instance->VerifyCertificateEx = client_cli_verify_certificate_ex; + instance->VerifyChangedCertificateEx = client_cli_verify_changed_certificate_ex; instance->LogonErrorInfo = xf_logon_error_info; PubSub_SubscribeTerminate(context->pubSub, xf_TerminateEventHandler); diff --git a/client/common/client.c b/client/common/client.c index 7423811..7b2c54d 100644 --- a/client/common/client.c +++ b/client/common/client.c @@ -506,6 +506,7 @@ static DWORD client_cli_accept_certificate(rdpSettings* settings) * when the connection requires it. * This function will actually be called by tls_verify_certificate(). * @see rdp_client_connect() and tls_connect() + * @deprecated Use client_cli_verify_certificate_ex * @param instance - pointer to the rdp_freerdp structure that contains the connection settings * @param common_name * @param subject @@ -518,6 +519,7 @@ DWORD client_cli_verify_certificate(freerdp* instance, const char* common_name, const char* subject, const char* issuer, const char* fingerprint, BOOL host_mismatch) { + printf("WARNING: This callback is deprecated, migrate to client_cli_verify_certificate_ex\n"); printf("Certificate details:\n"); printf("\tSubject: %s\n", subject); printf("\tIssuer: %s\n", issuer); @@ -529,9 +531,49 @@ DWORD client_cli_verify_certificate(freerdp* instance, const char* common_name, } /** Callback set in the rdp_freerdp structure, and used to make a certificate validation + * when the connection requires it. + * This function will actually be called by tls_verify_certificate(). + * @see rdp_client_connect() and tls_connect() + * @param instance pointer to the rdp_freerdp structure that contains the connection settings + * @param host The host currently connecting to + * @param port The port currently connecting to + * @param common_name The common name of the certificate, should match host or an alias of it + * @param subject The subject of the certificate + * @param issuer The certificate issuer name + * @param fingerprint The fingerprint of the certificate + * @param flags See VERIFY_CERT_FLAG_* for possible values. + * + * @return 1 if the certificate is trusted, 2 if temporary trusted, 0 otherwise. + */ +DWORD client_cli_verify_certificate_ex(freerdp* instance, const char* host, UINT16 port, + const char* common_name, + const char* subject, const char* issuer, + const char* fingerprint, DWORD flags) +{ + const char* type = "RDP-Server"; + + if (flags & VERIFY_CERT_FLAG_GATEWAY) + type = "RDP-Gateway"; + + if (flags & VERIFY_CERT_FLAG_REDIRECT) + type = "RDP-Redirect"; + + printf("Certificate details for %s:%"PRIu16" (%s):\n", host, port, type); + printf("\tCommon Name: %s\n", common_name); + printf("\tSubject: %s\n", subject); + printf("\tIssuer: %s\n", issuer); + printf("\tThumbprint: %s\n", fingerprint); + printf("The above X.509 certificate could not be verified, possibly because you do not have\n" + "the CA certificate in your certificate store, or the certificate has expired.\n" + "Please look at the OpenSSL documentation on how to add a private CA to the store.\n"); + return client_cli_accept_certificate(instance->settings); +} + +/** Callback set in the rdp_freerdp structure, and used to make a certificate validation * when a stored certificate does not match the remote counterpart. * This function will actually be called by tls_verify_certificate(). * @see rdp_client_connect() and tls_connect() + * @deprecated Use client_cli_verify_changed_certificate_ex * @param instance - pointer to the rdp_freerdp structure that contains the connection settings * @param common_name * @param subject @@ -549,6 +591,7 @@ DWORD client_cli_verify_changed_certificate(freerdp* instance, const char* old_subject, const char* old_issuer, const char* old_fingerprint) { + printf("WARNING: This callback is deprecated, migrate to client_cli_verify_changed_certificate_ex\n"); printf("!!! Certificate has changed !!!\n"); printf("\n"); printf("New Certificate details:\n"); @@ -567,6 +610,59 @@ DWORD client_cli_verify_changed_certificate(freerdp* instance, return client_cli_accept_certificate(instance->settings); } +/** Callback set in the rdp_freerdp structure, and used to make a certificate validation + * when a stored certificate does not match the remote counterpart. + * This function will actually be called by tls_verify_certificate(). + * @see rdp_client_connect() and tls_connect() + * @param instance pointer to the rdp_freerdp structure that contains the connection settings + * @param host The host currently connecting to + * @param port The port currently connecting to + * @param common_name The common name of the certificate, should match host or an alias of it + * @param subject The subject of the certificate + * @param issuer The certificate issuer name + * @param fingerprint The fingerprint of the certificate + * @param old_subject The subject of the previous certificate + * @param old_issuer The previous certificate issuer name + * @param old_fingerprint The fingerprint of the previous certificate + * @param flags See VERIFY_CERT_FLAG_* for possible values. + * + * @return 1 if the certificate is trusted, 2 if temporary trusted, 0 otherwise. + */ +DWORD client_cli_verify_changed_certificate_ex(freerdp* instance, + const char* host, UINT16 port, + const char* common_name, + const char* subject, const char* issuer, + const char* fingerprint, + const char* old_subject, const char* old_issuer, + const char* old_fingerprint, DWORD flags) +{ + const char* type = "RDP-Server"; + + if (flags & VERIFY_CERT_FLAG_GATEWAY) + type = "RDP-Gateway"; + + if (flags & VERIFY_CERT_FLAG_REDIRECT) + type = "RDP-Redirect"; + + printf("!!!Certificate for %s:%"PRIu16" (%s) has changed!!!\n", host, port, type); + printf("\n"); + printf("New Certificate details:\n"); + printf("\tCommon Name: %s\n", common_name); + printf("\tSubject: %s\n", subject); + printf("\tIssuer: %s\n", issuer); + printf("\tThumbprint: %s\n", fingerprint); + printf("\n"); + printf("Old Certificate details:\n"); + printf("\tSubject: %s\n", old_subject); + printf("\tIssuer: %s\n", old_issuer); + printf("\tThumbprint: %s\n", old_fingerprint); + printf("\n"); + printf("The above X.509 certificate does not match the certificate used for previous connections.\n" + "This may indicate that the certificate has been tampered with.\n" + "Please contact the administrator of the RDP server and clarify.\n"); + return client_cli_accept_certificate(instance->settings); +} + BOOL client_auto_reconnect(freerdp* instance) { return client_auto_reconnect_ex(instance, NULL); diff --git a/include/freerdp/client.h b/include/freerdp/client.h index 25049c0..8ade211 100644 --- a/include/freerdp/client.h +++ b/include/freerdp/client.h @@ -107,11 +107,25 @@ FREERDP_API DWORD client_cli_verify_certificate(freerdp* instance, const char* c const char* subject, const char* issuer, const char* fingerprint, BOOL host_mismatch); +FREERDP_API DWORD client_cli_verify_certificate_ex(freerdp* instance, + const char* host, UINT16 port, + const char* common_name, + const char* subject, const char* issuer, + const char* fingerprint, DWORD flags); + FREERDP_API DWORD client_cli_verify_changed_certificate(freerdp* instance, const char* common_name, const char* subject, const char* issuer, const char* fingerprint, const char* old_subject, const char* old_issuer, const char* old_fingerprint); + +FREERDP_API DWORD client_cli_verify_changed_certificate_ex(freerdp* instance, + const char* host, UINT16 port, + const char* common_name, + const char* subject, const char* issuer, + const char* fingerprint, + const char* old_subject, const char* old_issuer, + const char* old_fingerprint, DWORD flags); FREERDP_API BOOL client_auto_reconnect(freerdp* instance); FREERDP_API BOOL client_auto_reconnect_ex(freerdp* instance, BOOL(*window_events)(freerdp* instance)); diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index 632962b..31d5fda 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -1461,6 +1461,8 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, const char* hostname, } else if (instance->VerifyCertificate) { + WLog_WARN(TAG, + "The VerifyCertificate callback is deprecated, migrate your application to VerifyCertificateEx"); accept_certificate = instance->VerifyCertificate( instance, common_name, subject, issuer, @@ -1503,6 +1505,8 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, const char* hostname, } else if (instance->VerifyChangedCertificate) { + WLog_WARN(TAG, + "The VerifyChangedCertificate callback is deprecated, migrate your application to VerifyChangedCertificateEx"); accept_certificate = instance->VerifyChangedCertificate( instance, common_name, subject, issuer, fingerprint, old_subject, old_issuer,