Merge pull request #155 from mfleisz/certcallback
core: Added ui callback to verify certificates
This commit is contained in:
commit
c03de9aeea
@ -218,6 +218,35 @@ static int df_process_plugin_args(rdpSettings* settings, const char* name,
|
||||
return 1;
|
||||
}
|
||||
|
||||
boolean df_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint)
|
||||
{
|
||||
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");
|
||||
|
||||
char answer;
|
||||
while (1)
|
||||
{
|
||||
printf("Do you trust the above certificate? (Y/N) ");
|
||||
answer = fgetc(stdin);
|
||||
|
||||
if (answer == 'y' || answer == 'Y')
|
||||
{
|
||||
return True;
|
||||
}
|
||||
else if (answer == 'n' || answer == 'N')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
static int
|
||||
df_receive_channel_data(freerdp* instance, int channelId, uint8* data, int size, int flags, int total_size)
|
||||
{
|
||||
@ -408,6 +437,7 @@ int main(int argc, char* argv[])
|
||||
instance = freerdp_new();
|
||||
instance->PreConnect = df_pre_connect;
|
||||
instance->PostConnect = df_post_connect;
|
||||
instance->VerifyCertificate = df_verify_certificate;
|
||||
instance->ReceiveChannelData = df_receive_channel_data;
|
||||
|
||||
instance->ContextSize = (pcContextSize) df_context_size;
|
||||
|
@ -392,6 +392,12 @@ boolean wf_post_connect(freerdp* instance)
|
||||
return True;
|
||||
}
|
||||
|
||||
boolean wf_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint)
|
||||
{
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
int wf_receive_channel_data(freerdp* instance, int channelId, uint8* data, int size, int flags, int total_size)
|
||||
{
|
||||
return freerdp_channels_data(instance, channelId, data, size, flags, total_size);
|
||||
@ -636,6 +642,7 @@ INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
instance = freerdp_new();
|
||||
instance->PreConnect = wf_pre_connect;
|
||||
instance->PostConnect = wf_post_connect;
|
||||
instance->VerifyCertificate = wf_verify_certificate;
|
||||
instance->ReceiveChannelData = wf_receive_channel_data;
|
||||
|
||||
instance->ContextSize = (pcContextSize) wf_context_size;
|
||||
|
@ -771,6 +771,36 @@ boolean xf_authenticate(freerdp* instance, char** username, char** password, cha
|
||||
return True;
|
||||
}
|
||||
|
||||
boolean xf_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint)
|
||||
{
|
||||
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");
|
||||
|
||||
char answer;
|
||||
while (1)
|
||||
{
|
||||
printf("Do you trust the above certificate? (Y/N) ");
|
||||
answer = fgetc(stdin);
|
||||
|
||||
if (answer == 'y' || answer == 'Y')
|
||||
{
|
||||
return True;
|
||||
}
|
||||
else if (answer == 'n' || answer == 'N')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
|
||||
int xf_process_client_args(rdpSettings* settings, const char* opt, const char* val, void* user_data)
|
||||
{
|
||||
int argc = 0;
|
||||
@ -1049,6 +1079,7 @@ int main(int argc, char* argv[])
|
||||
instance->PreConnect = xf_pre_connect;
|
||||
instance->PostConnect = xf_post_connect;
|
||||
instance->Authenticate = xf_authenticate;
|
||||
instance->VerifyCertificate = xf_verify_certificate;
|
||||
instance->ReceiveChannelData = xf_receive_channel_data;
|
||||
|
||||
instance->ContextSize = (pcContextSize) xf_context_size;
|
||||
|
@ -49,6 +49,7 @@ typedef void (*pcContextFree)(freerdp* instance, rdpContext* context);
|
||||
typedef boolean (*pcPreConnect)(freerdp* instance);
|
||||
typedef boolean (*pcPostConnect)(freerdp* instance);
|
||||
typedef boolean (*pcAuthenticate)(freerdp* instance, char** username, char** password, char** domain);
|
||||
typedef boolean (*pcVerifyCertificate)(freerdp* instance, char* subject, char* issuer, char* fingerprint);
|
||||
|
||||
typedef int (*pcSendChannelData)(freerdp* instance, int channelId, uint8* data, int size);
|
||||
typedef int (*pcReceiveChannelData)(freerdp* instance, int channelId, uint8* data, int size, int flags, int total_size);
|
||||
@ -85,6 +86,7 @@ struct rdp_freerdp
|
||||
pcPreConnect PreConnect;
|
||||
pcPostConnect PostConnect;
|
||||
pcAuthenticate Authenticate;
|
||||
pcVerifyCertificate VerifyCertificate;
|
||||
|
||||
pcSendChannelData SendChannelData;
|
||||
pcReceiveChannelData ReceiveChannelData;
|
||||
|
@ -279,6 +279,34 @@ char* crypto_cert_fingerprint(X509* xcert)
|
||||
return fp_buffer;
|
||||
}
|
||||
|
||||
char* crypto_print_name(X509_NAME* name)
|
||||
{
|
||||
char* buffer = NULL;
|
||||
BIO* outBIO = BIO_new(BIO_s_mem());
|
||||
|
||||
if(X509_NAME_print_ex(outBIO, name, 0, XN_FLAG_ONELINE) > 0)
|
||||
{
|
||||
unsigned long size = BIO_number_written(outBIO);
|
||||
char* buffer = xzalloc(size);
|
||||
memset(buffer, 0, size);
|
||||
BIO_read(outBIO, buffer, size);
|
||||
}
|
||||
|
||||
BIO_free(outBIO);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
char* crypto_cert_subject(X509* xcert)
|
||||
{
|
||||
return crypto_print_name(X509_get_subject_name(xcert));
|
||||
}
|
||||
|
||||
char* crypto_cert_issuer(X509* xcert)
|
||||
{
|
||||
return crypto_print_name(X509_get_issuer_name(xcert));
|
||||
}
|
||||
|
||||
boolean x509_verify_cert(CryptoCert cert, rdpSettings* settings)
|
||||
{
|
||||
char* cert_loc;
|
||||
@ -351,8 +379,8 @@ void crypto_cert_print_info(X509* xcert)
|
||||
char* issuer;
|
||||
char* subject;
|
||||
|
||||
subject = X509_NAME_oneline(X509_get_subject_name(xcert), NULL, 0);
|
||||
issuer = X509_NAME_oneline(X509_get_issuer_name(xcert), NULL, 0);
|
||||
subject = crypto_cert_subject(xcert);
|
||||
issuer = crypto_cert_issuer(xcert);
|
||||
fp = crypto_cert_fingerprint(xcert);
|
||||
|
||||
printf("Certificate details:\n");
|
||||
@ -363,5 +391,8 @@ void crypto_cert_print_info(X509* xcert)
|
||||
"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");
|
||||
|
||||
xfree(subject);
|
||||
xfree(issuer);
|
||||
xfree(fp);
|
||||
}
|
||||
|
||||
|
@ -109,7 +109,9 @@ void crypto_hmac_free(CryptoHmac hmac);
|
||||
|
||||
typedef struct crypto_cert_struct* CryptoCert;
|
||||
CryptoCert crypto_cert_read(uint8* data, uint32 length);
|
||||
char* cypto_cert_fingerprint(X509* xcert);
|
||||
char* crypto_cert_fingerprint(X509* xcert);
|
||||
char* crypto_cert_subject(X509* xcert);
|
||||
char* crypto_cert_issuer(X509* xcert);
|
||||
void crypto_cert_print_info(X509* xcert);
|
||||
void crypto_cert_free(CryptoCert cert);
|
||||
boolean x509_verify_cert(CryptoCert cert, rdpSettings* settings);
|
||||
|
@ -259,27 +259,22 @@ int tls_verify_certificate(CryptoCert cert, rdpSettings* settings, char* hostnam
|
||||
|
||||
if (certstore->match == 1)
|
||||
{
|
||||
char answer;
|
||||
crypto_cert_print_info(cert->px509);
|
||||
char* issuer = crypto_cert_issuer(cert->px509);
|
||||
char* subject = crypto_cert_subject(cert->px509);
|
||||
char* fingerprint = crypto_cert_fingerprint(cert->px509);
|
||||
|
||||
#ifndef _WIN32
|
||||
while (1)
|
||||
{
|
||||
printf("Do you trust the above certificate? (Y/N) ");
|
||||
answer = fgetc(stdin);
|
||||
boolean accept_certificate = False;
|
||||
freerdp* instance = (freerdp*)settings->instance;
|
||||
|
||||
if (answer == 'y' || answer == 'Y')
|
||||
{
|
||||
cert_data_print(certstore);
|
||||
break;
|
||||
}
|
||||
else if (answer == 'n' || answer == 'N')
|
||||
{
|
||||
certstore_free(certstore);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if(instance->VerifyCertificate)
|
||||
accept_certificate = instance->VerifyCertificate(instance, subject, issuer, fingerprint);
|
||||
|
||||
xfree(issuer);
|
||||
xfree(subject);
|
||||
xfree(fingerprint);
|
||||
|
||||
if(!accept_certificate)
|
||||
return 1;
|
||||
}
|
||||
else if (certstore->match == -1)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user