From cbf2892cccbd1052a45c41c5023c088100403164 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 14 Dec 2015 14:02:49 +0100 Subject: [PATCH] Implemented temporary certificate accept. Certificates can now be accepted temporarily. The callbacks for certificate validation have been modified to extend the information presented to the user. --- client/Android/android_jni_callback.c | 48 +++++++++++++ client/Android/android_jni_callback.h | 1 + client/Wayland/wlfreerdp.c | 77 +++++++++++++++------ client/Windows/wf_client.c | 26 ++++++++ client/X11/xf_client.c | 122 ++++++++++++++++++++++++---------- client/iOS/FreeRDP/ios_freerdp_ui.h | 11 ++- client/iOS/FreeRDP/ios_freerdp_ui.m | 54 ++++++++------- include/freerdp/freerdp.h | 56 ++++++++++++++-- libfreerdp/crypto/tls.c | 72 +++++++++----------- server/shadow/Win/win_rdp.c | 6 +- 10 files changed, 345 insertions(+), 128 deletions(-) diff --git a/client/Android/android_jni_callback.c b/client/Android/android_jni_callback.c index ee48696..d103b80 100644 --- a/client/Android/android_jni_callback.c +++ b/client/Android/android_jni_callback.c @@ -172,6 +172,45 @@ finish: return res; } +/* callback with int result */ +jint java_callback_int(jobject obj, const char * callback, const char* signature, va_list args) +{ + jclass jObjClass; + jmethodID jCallback; + jboolean attached; + jint res = -1; + JNIEnv *env; + + DEBUG_ANDROID("java_callback: %s (%s)", callback, signature); + + attached = jni_attach_thread(&env); + + jObjClass = (*env)->GetObjectClass(env, obj); + + if (!jObjClass) + { + WLog_ERR(TAG, "android_java_callback: failed to get class reference"); + goto finish; + } + + jCallback = (*env)->GetStaticMethodID(env, jObjClass, callback, signature); + + if (!jCallback) + { + WLog_ERR(TAG, "android_java_callback: failed to get method id"); + goto finish; + } + + res = (*env)->CallStaticIntMethodV(env, jObjClass, jCallback, args); + +finish: + if(attached == JNI_TRUE) + jni_detach_thread(); + + return res; +} + + /* callback to freerdp class */ void freerdp_callback(const char * callback, const char * signature, ...) { @@ -189,3 +228,12 @@ jboolean freerdp_callback_bool_result(const char * callback, const char * signat va_end(vl); return res; } + +jint freerdp_callback_int_result(const char * callback, const char * signature, ...) +{ + va_list vl; + va_start(vl, signature); + jint res = java_callback_int(jLibFreeRDPObject, callback, signature, vl); + va_end(vl); + return res; +} diff --git a/client/Android/android_jni_callback.h b/client/Android/android_jni_callback.h index dbe172e..95d0336 100644 --- a/client/Android/android_jni_callback.h +++ b/client/Android/android_jni_callback.h @@ -21,6 +21,7 @@ jboolean jni_attach_thread(JNIEnv** env); void jni_detach_thread(void); void freerdp_callback(const char * callback, const char * signature, ...); jboolean freerdp_callback_bool_result(const char * callback, const char * signature, ...); +jint freerdp_callback_int_result(const char * callback, const char * signature, ...); #endif /* FREERDP_ANDROID_JNI_CALLBACK_H */ diff --git a/client/Wayland/wlfreerdp.c b/client/Wayland/wlfreerdp.c index 456e64a..2cc7597 100644 --- a/client/Wayland/wlfreerdp.c +++ b/client/Wayland/wlfreerdp.c @@ -172,44 +172,82 @@ static void wl_post_disconnect(freerdp* instance) wlf_DestroyWindow(context, context->window); } -static BOOL wl_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint) +static DWORD wl_accept_certificate(rdpSettings* settings) { char answer; - printf("Certificate details:\n"); - 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 " - "the CA certificate in your certificate store, or the certificate has expired. " - "Please look at the documentation on how to create local certificate store for a private CA.\n"); - while (1) { - printf("Do you trust the above certificate? (Y/N) "); + printf("Do you trust the above certificate? (Y/T/N) "); answer = fgetc(stdin); if (feof(stdin)) { printf("\nError: Could not read answer from stdin."); - if (instance->settings->CredentialsFromStdin) + if (settings->CredentialsFromStdin) printf(" - Run without parameter \"--from-stdin\" to set trust."); printf("\n"); - return FALSE; + return 0; } - if (answer == 'y' || answer == 'Y') + switch(answer) { - return TRUE; - } - else if (answer == 'n' || answer == 'N') - { - break; + case 'y': + case 'Y': + return 1; + case 't': + case 'T': + return 2; + case 'n': + case 'N': + return 0; + default: + break; } printf("\n"); } - return FALSE; + return 0; +} + +static DWORD wl_verify_certificate(freerdp* instance, const char* common_name, + const char* subject, const char* issuer, + const char* fingerprint, BOOL host_mismatch) +{ + printf("Certificate details:\n"); + 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 documentation on how to create local certificate store for a private CA.\n"); + + return wl_accept_certificate(instance->settings); +} + +static DWORD wl_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) +{ + printf("!!! Certificate has changed !!!\n"); + printf("\n"); + printf("New Certificate details:\n"); + 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 wl_accept_certificate(instance->settings); } static int wlfreerdp_run(freerdp* instance) @@ -263,6 +301,7 @@ int main(int argc, char* argv[]) instance->PostConnect = wl_post_connect; instance->PostDisconnect = wl_post_disconnect; instance->VerifyCertificate = wl_verify_certificate; + instance->VerifyChangedCertificate = wl_verify_changed_certificate; instance->ContextSize = sizeof(wlfContext); instance->ContextNew = wl_context_new; diff --git a/client/Windows/wf_client.c b/client/Windows/wf_client.c index e9af71f..eb80961 100644 --- a/client/Windows/wf_client.c +++ b/client/Windows/wf_client.c @@ -608,6 +608,31 @@ BOOL wf_verify_certificate(freerdp* instance, char* subject, char* issuer, char* return TRUE; } +static DWORD wf_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) +{ + char answer; + + WLog_ERR(TAG, "!!! Certificate has changed !!!"); + WLog_ERR(TAG, "New Certificate details:"); + WLog_ERR(TAG, "\tSubject: %s", subject); + WLog_ERR(TAG, "\tIssuer: %s", issuer); + WLog_ERR(TAG, "\tThumbprint: %s", fingerprint); + WLog_ERR(TAG, "Old Certificate details:"); + WLog_ERR(TAG, "\tSubject: %s", old_subject); + WLog_ERR(TAG, "\tIssuer: %s", old_issuer); + WLog_ERR(TAG, "\tThumbprint: %s", old_fingerprint); + WLog_ERR(TAG, "The above X.509 certificate does not match the certificate used for previous connections. " + "This may indicate that the certificate has been tampered with." + "Please contact the administrator of the RDP server and clarify."); + + return 0; +} + + static BOOL wf_auto_reconnect(freerdp* instance) { wfContext* wfc = (wfContext *)instance->context; @@ -1081,6 +1106,7 @@ BOOL wfreerdp_client_new(freerdp* instance, rdpContext* context) instance->Authenticate = wf_authenticate; instance->GatewayAuthenticate = wf_gw_authenticate; instance->VerifyCertificate = wf_verify_certificate; + instance->VerifyChangedCertificate = wf_verify_changed_certificate; wfc->instance = instance; wfc->settings = instance->settings; diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index 8a885cf..cfdd2f7 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -1458,55 +1458,108 @@ static BOOL xf_gw_authenticate(freerdp* instance, char** username, char** passwo return xf_authenticate_raw(instance, TRUE, username, password, domain); } -/** 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 subject - * @param issuer - * @param fingerprint - * @return TRUE if the certificate is trusted. FALSE otherwise. - */ -BOOL xf_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint) +static DWORD xf_accept_certificate(rdpSettings* settings) { char answer; - WLog_INFO(TAG, "Certificate details:"); - WLog_INFO(TAG, "\tSubject: %s", subject); - WLog_INFO(TAG, "\tIssuer: %s", issuer); - WLog_INFO(TAG, "\tThumbprint: %s", fingerprint); - WLog_INFO(TAG, "The above X.509 certificate could not be verified, possibly because you do not have " - "the CA certificate in your certificate store, or the certificate has expired. " - "Please look at the documentation on how to create local certificate store for a private CA."); - while (1) { - WLog_INFO(TAG, "Do you trust the above certificate? (Y/N) "); + printf("Do you trust the above certificate? (Y/T/N) "); answer = fgetc(stdin); if (feof(stdin)) { - WLog_INFO(TAG, "Error: Could not read answer from stdin."); - if (instance->settings->CredentialsFromStdin) - WLog_INFO(TAG, " - Run without parameter \"--from-stdin\" to set trust."); - WLog_INFO(TAG, ""); - return FALSE; + printf("\nError: Could not read answer from stdin."); + if (settings->CredentialsFromStdin) + printf(" - Run without parameter \"--from-stdin\" to set trust."); + printf("\n"); + return 0; } - if (answer == 'y' || answer == 'Y') + switch(answer) { - return TRUE; - } - else if (answer == 'n' || answer == 'N') - { - break; + case 'y': + case 'Y': + return 1; + case 't': + case 'T': + return 2; + case 'n': + case 'N': + return 0; + default: + break; } - - WLog_INFO(TAG, ""); + printf("\n"); } - return FALSE; + return 0; +} + +/** 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 common_name + * @param subject + * @param issuer + * @param fingerprint + * @param host_mismatch Indicates the certificate host does not match. + * @return 1 if the certificate is trusted, 2 if temporary trusted, 0 otherwise. + */ +static DWORD xf_verify_certificate(freerdp* instance, const char* common_name, + const char* subject, const char* issuer, + const char* fingerprint, BOOL host_mismatch) +{ + printf("Certificate details:\n"); + 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 documentation on how to create local certificate store for a private CA.\n"); + + return xf_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 common_name + * @param subject + * @param issuer + * @param fingerprint + * @param old_subject + * @param old_issuer + * @param old_fingerprint + * @return 1 if the certificate is trusted, 2 if temporary trusted, 0 otherwise. + */ +static DWORD xf_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) +{ + printf("!!! Certificate has changed !!!\n"); + printf("\n"); + printf("New Certificate details:\n"); + 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 xf_accept_certificate(instance->settings); } int xf_logon_error_info(freerdp* instance, UINT32 data, UINT32 type) @@ -1959,6 +2012,7 @@ static BOOL xfreerdp_client_new(freerdp* instance, rdpContext* context) instance->Authenticate = xf_authenticate; instance->GatewayAuthenticate = xf_gw_authenticate; instance->VerifyCertificate = xf_verify_certificate; + instance->VerifyChangedCertificate = xf_verify_changed_certificate; instance->LogonErrorInfo = xf_logon_error_info; settings = instance->settings; diff --git a/client/iOS/FreeRDP/ios_freerdp_ui.h b/client/iOS/FreeRDP/ios_freerdp_ui.h index 9da8748..91389dd 100644 --- a/client/iOS/FreeRDP/ios_freerdp_ui.h +++ b/client/iOS/FreeRDP/ios_freerdp_ui.h @@ -14,8 +14,15 @@ BOOL ios_ui_end_paint(rdpContext * context); BOOL ios_ui_resize_window(rdpContext * context); BOOL ios_ui_authenticate(freerdp * instance, char** username, char** password, char** domain); -BOOL ios_ui_check_certificate(freerdp * instance, char * subject, char * issuer, char * fingerprint); -BOOL ios_ui_check_changed_certificate(freerdp * instance, char * subject, char * issuer, char * new_fingerprint, char * old_fingerprint); +DWORD ios_ui_check_certificate(freerdp * instance, const char* common_name, + const char * subject, const char * issuer, + const char * fingerprint, BOOL host_mismatch); +DWORD ios_ui_check_changed_certificate(freerdp * instance, + const char* common_name, + const char * subject, + const char * issuer, + const char * new_fingerprint, + const char * old_fingerprint); void ios_allocate_display_buffer(mfInfo* mfi); void ios_resize_display_buffer(mfInfo* mfi); diff --git a/client/iOS/FreeRDP/ios_freerdp_ui.m b/client/iOS/FreeRDP/ios_freerdp_ui.m index 191b25e..cd17da0 100644 --- a/client/iOS/FreeRDP/ios_freerdp_ui.m +++ b/client/iOS/FreeRDP/ios_freerdp_ui.m @@ -63,39 +63,47 @@ BOOL ios_ui_authenticate(freerdp * instance, char** username, char** password, c return TRUE; } -BOOL ios_ui_check_certificate(freerdp * instance, char * subject, char * issuer, char * fingerprint) +DWORD ios_ui_check_certificate(freerdp * instance, const char* common_name, + const char * subject, const char * issuer, + const char * fingerprint, BOOL host_mismatch) { - // check whether we accept all certificates - if ([[NSUserDefaults standardUserDefaults] boolForKey:@"security.accept_certificates"] == YES) - return TRUE; - + // check whether we accept all certificates + if ([[NSUserDefaults standardUserDefaults] boolForKey:@"security.accept_certificates"] == YES) + return 2; + mfInfo* mfi = MFI_FROM_INSTANCE(instance); NSMutableDictionary* params = [NSMutableDictionary dictionaryWithObjectsAndKeys: - (subject) ? [NSString stringWithUTF8String:subject] : @"", @"subject", - (issuer) ? [NSString stringWithUTF8String:issuer] : @"", @"issuer", - (fingerprint) ? [NSString stringWithUTF8String:subject] : @"", @"fingerprint", - nil]; - - // request certificate verification UI - [mfi->session performSelectorOnMainThread:@selector(sessionVerifyCertificateWithParams:) withObject:params waitUntilDone:YES]; - - // wait for UI request to be completed - [[mfi->session uiRequestCompleted] lock]; - [[mfi->session uiRequestCompleted] wait]; - [[mfi->session uiRequestCompleted] unlock]; - + (subject) ? [NSString stringWithUTF8String:subject] : @"", @"subject", + (issuer) ? [NSString stringWithUTF8String:issuer] : @"", @"issuer", + (fingerprint) ? [NSString stringWithUTF8String:subject] : @"", @"fingerprint", + nil]; + + // request certificate verification UI + [mfi->session performSelectorOnMainThread:@selector(sessionVerifyCertificateWithParams:) withObject:params waitUntilDone:YES]; + + // wait for UI request to be completed + [[mfi->session uiRequestCompleted] lock]; + [[mfi->session uiRequestCompleted] wait]; + [[mfi->session uiRequestCompleted] unlock]; + if (![[params valueForKey:@"result"] boolValue]) { mfi->unwanted = YES; - return FALSE; + return 0; } - - return TRUE; + + return 1; } -BOOL ios_ui_check_changed_certificate(freerdp * instance, char * subject, char * issuer, char * new_fingerprint, char * old_fingerprint) +DWORD ios_ui_check_changed_certificate(freerdp * instance, + const char * common_name, + const char * subject, + const char * issuer, + const char * new_fingerprint, + const char * old_fingerprint) { - return ios_ui_check_certificate(instance, subject, issuer, new_fingerprint); + return ios_ui_check_certificate(instance, common_name, subject, issuer, + new_fingerprint, FALSE); } diff --git a/include/freerdp/freerdp.h b/include/freerdp/freerdp.h index cbc5398..22b2b35 100644 --- a/include/freerdp/freerdp.h +++ b/include/freerdp/freerdp.h @@ -65,13 +65,55 @@ typedef void (*pContextFree)(freerdp* instance, rdpContext* context); typedef BOOL (*pPreConnect)(freerdp* instance); typedef BOOL (*pPostConnect)(freerdp* instance); typedef void (*pPostDisconnect)(freerdp* instance); -typedef BOOL (*pAuthenticate)(freerdp* instance, char** username, char** password, char** domain); -typedef BOOL (*pVerifyCertificate)(freerdp* instance, char* subject, char* issuer, char* fingerprint); -typedef BOOL (*pVerifyChangedCertificate)(freerdp* instance, char* subject, - char* issuer, char* new_fingerprint, - char* old_subject, char* old_issuer, - char* old_fingerprint); -typedef int (*pVerifyX509Certificate)(freerdp* instance, BYTE* data, int length, const char* hostname, int port, DWORD flags); +typedef BOOL (*pAuthenticate)(freerdp* instance, char** username, + char** password, char** domain); + +/** @brief Callback used if user interaction is required to accept + * an unknown certificate. + * + * @param common_name The certificate registered hostname. + * @param subject The common name of the certificate. + * @param issuer The issuer of the certificate. + * @param fingerprint The fingerprint of the certificate. + * @param host_mismatch A flag indicating the certificate + * subject does not match the host connecting to. + * + * @return 1 to accept and store a certificate, 2 to accept + * a certificate only for this session, 0 otherwise. + */ +typedef DWORD (*pVerifyCertificate)(freerdp* instance, + const char* common_name, + const char* subject, + const char* issuer, + const char* fingerprint, + BOOL host_mismatch); + +/** @brief Callback used if user interaction is required to accept + * a changed certificate. + * + * @param common_name The certificate registered hostname. + * @param subject The common name of the new certificate. + * @param issuer The issuer of the new certificate. + * @param fingerprint The fingerprint of the new certificate. + * @param old_subject The common name of the old certificate. + * @param old_issuer The issuer of the new certificate. + * @param old_fingerprint The fingerprint of the old certificate. + * + * @return 1 to accept and store a certificate, 2 to accept + * a certificate only for this session, 0 otherwise. + */ + +typedef DWORD (*pVerifyChangedCertificate)(freerdp* instance, + const char* common_name, + const char* subject, + const char* issuer, + const char* new_fingerprint, + const char* old_subject, + const char* old_issuer, + const char* old_fingerprint); +typedef int (*pVerifyX509Certificate)(freerdp* instance, BYTE* data, + int length, const char* hostname, + int port, DWORD flags); typedef int (*pLogonErrorInfo)(freerdp* instance, UINT32 data, UINT32 type); diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index e8627e4..6546115 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -1247,31 +1247,16 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por /* if the certificate is valid and the certificate name matches, verification succeeds */ if (certificate_status && hostname_match) - { - if (common_name) - { - free(common_name); - common_name = NULL; - } - verification_status = TRUE; /* success! */ - } - - /* if the certificate is valid but the certificate name does not match, warn user, do not accept */ - if (certificate_status && !hostname_match) - tls_print_certificate_name_mismatch_error(hostname, port, - common_name, alt_names, - alt_names_count); /* verification could not succeed with OpenSSL, use known_hosts file and prompt user for manual verification */ - - if (!certificate_status) + if (!certificate_status || !hostname_match) { char* issuer; char* subject; char* fingerprint; freerdp* instance = (freerdp*) tls->settings->instance; - BOOL accept_certificate = FALSE; + DWORD accept_certificate = 0; issuer = crypto_cert_issuer(cert->px509); subject = crypto_cert_subject(cert->px509); @@ -1290,19 +1275,23 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por alt_names_count); if (instance->VerifyCertificate) - { - accept_certificate = instance->VerifyCertificate(instance, subject, issuer, fingerprint); - } + accept_certificate = instance->VerifyCertificate(instance, common_name, + subject, issuer, fingerprint, !hostname_match); - if (!accept_certificate) + switch(accept_certificate) { - /* user did not accept, abort and do not add entry in known_hosts file */ - verification_status = FALSE; /* failure! */ - } - else - { - /* user accepted certificate, add entry in known_hosts file */ - verification_status = certificate_data_print(tls->certificate_store, certificate_data); + case 1: + /* user accepted certificate, add entry in known_hosts file */ + verification_status = certificate_data_print(tls->certificate_store, certificate_data); + break; + case 2: + /* user did accept temporaty, do not add to known hosts file */ + verification_status = TRUE; + break; + default: + /* user did not accept, abort and do not add entry in known_hosts file */ + verification_status = FALSE; /* failure! */ + break; } } else if (match == -1) @@ -1324,28 +1313,31 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por if (instance->VerifyChangedCertificate) { accept_certificate = instance->VerifyChangedCertificate( - instance, subject, issuer, + instance, common_name, subject, issuer, fingerprint, old_subject, old_issuer, old_fingerprint); } free(old_fingerprint); - if (!accept_certificate) - { - /* user did not accept, abort and do not change known_hosts file */ - verification_status = FALSE; /* failure! */ - } - else + switch(accept_certificate) { - /* user accepted new certificate, add replace fingerprint for this host in known_hosts file */ - verification_status = certificate_data_replace(tls->certificate_store, certificate_data); + case 1: + /* user accepted certificate, add entry in known_hosts file */ + verification_status = certificate_data_replace(tls->certificate_store, certificate_data); + break; + case 2: + /* user did accept temporaty, do not add to known hosts file */ + verification_status = TRUE; + break; + default: + /* user did not accept, abort and do not add entry in known_hosts file */ + verification_status = FALSE; /* failure! */ + break; } } else if (match == 0) - { verification_status = TRUE; /* success! */ - } free(issuer); free(subject); @@ -1354,9 +1346,7 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por certificate_data_free(certificate_data); -#ifndef _WIN32 free(common_name); -#endif if (alt_names) crypto_cert_subject_alt_name_free(alt_names_count, alt_names_lengths, diff --git a/server/shadow/Win/win_rdp.c b/server/shadow/Win/win_rdp.c index d9e0b34..b254f2a 100644 --- a/server/shadow/Win/win_rdp.c +++ b/server/shadow/Win/win_rdp.c @@ -99,9 +99,11 @@ BOOL shw_authenticate(freerdp* instance, char** username, char** password, char* return TRUE; } -BOOL shw_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint) +static DWORD shw_verify_certificate(freerdp* instance, const char* common_name, + const char* subject, const char* issuer, + const char* fingerprint, BOOL host_mismatch) { - return TRUE; + return 1; } int shw_verify_x509_certificate(freerdp* instance, BYTE* data, int length, const char* hostname, int port, DWORD flags) -- 2.7.4