libfreerdp-core: add external certificate management, pass X509 PEM certificate through client callback
This commit is contained in:
parent
fa64ca758d
commit
b0369cf284
@ -61,6 +61,7 @@ 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_fingerprint);
|
||||
typedef int (*pVerifyX509Certificate)(freerdp* instance, BYTE* data, int length, DWORD flags);
|
||||
|
||||
typedef int (*pLogonErrorInfo)(freerdp* instance, UINT32 data, UINT32 type);
|
||||
|
||||
@ -195,13 +196,15 @@ struct rdp_freerdp
|
||||
Used when a certificate differs from stored fingerprint.
|
||||
If returns TRUE, the new fingerprint will be trusted and old thrown out. */
|
||||
|
||||
ALIGN64 pLogonErrorInfo LogonErrorInfo; /**< (offset 53) Callback for logon error info, important for logon system messages with RemoteApp */
|
||||
ALIGN64 pVerifyX509Certificate VerifyX509Certificate; /**< (offset 53) Callback for X509 certificate verification (PEM format) */
|
||||
|
||||
ALIGN64 pPostDisconnect PostDisconnect; /**< (offset 54)
|
||||
ALIGN64 pLogonErrorInfo LogonErrorInfo; /**< (offset 54) Callback for logon error info, important for logon system messages with RemoteApp */
|
||||
|
||||
ALIGN64 pPostDisconnect PostDisconnect; /**< (offset 55)
|
||||
Callback for cleaning up resources allocated
|
||||
by connect callbacks. */
|
||||
|
||||
UINT64 paddingD[64 - 55]; /* 55 */
|
||||
UINT64 paddingD[64 - 56]; /* 56 */
|
||||
|
||||
ALIGN64 pSendChannelData SendChannelData; /* (offset 64)
|
||||
Callback for sending data to a channel.
|
||||
|
@ -594,6 +594,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL;
|
||||
#define FreeRDP_RdpKeyFile 1412
|
||||
#define FreeRDP_RdpServerRsaKey 1413
|
||||
#define FreeRDP_RdpServerCertificate 1414
|
||||
#define FreeRDP_ExternalCertificateManagement 1415
|
||||
#define FreeRDP_Workarea 1536
|
||||
#define FreeRDP_Fullscreen 1537
|
||||
#define FreeRDP_PercentScreen 1538
|
||||
@ -960,7 +961,8 @@ struct rdp_settings
|
||||
ALIGN64 char* RdpKeyFile; /* 1412 */
|
||||
ALIGN64 rdpRsaKey* RdpServerRsaKey; /* 1413 */
|
||||
ALIGN64 rdpCertificate* RdpServerCertificate; /* 1414 */
|
||||
UINT64 padding1472[1472 - 1350]; /* 1415 */
|
||||
ALIGN64 BOOL ExternalCertificateManagement; /* 1415 */
|
||||
UINT64 padding1472[1472 - 1416]; /* 1416 */
|
||||
UINT64 padding1536[1536 - 1472]; /* 1472 */
|
||||
|
||||
/**
|
||||
|
@ -665,6 +665,10 @@ BOOL freerdp_get_param_bool(rdpSettings* settings, int id)
|
||||
return settings->IgnoreCertificate;
|
||||
break;
|
||||
|
||||
case FreeRDP_ExternalCertificateManagement:
|
||||
return settings->ExternalCertificateManagement;
|
||||
break;
|
||||
|
||||
case FreeRDP_Workarea:
|
||||
return settings->Workarea;
|
||||
break;
|
||||
@ -1129,6 +1133,10 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param)
|
||||
settings->IgnoreCertificate = param;
|
||||
break;
|
||||
|
||||
case FreeRDP_ExternalCertificateManagement:
|
||||
settings->ExternalCertificateManagement = param;
|
||||
break;
|
||||
|
||||
case FreeRDP_Workarea:
|
||||
settings->Workarea = param;
|
||||
break;
|
||||
|
@ -620,6 +620,7 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings)
|
||||
_settings->MstscCookieMode = settings->MstscCookieMode; /* 1152 */
|
||||
_settings->SendPreconnectionPdu = settings->SendPreconnectionPdu; /* 1156 */
|
||||
_settings->IgnoreCertificate = settings->IgnoreCertificate; /* 1408 */
|
||||
_settings->ExternalCertificateManagement = settings->ExternalCertificateManagement; /* 1415 */
|
||||
_settings->Workarea = settings->Workarea; /* 1536 */
|
||||
_settings->Fullscreen = settings->Fullscreen; /* 1537 */
|
||||
_settings->GrabKeyboard = settings->GrabKeyboard; /* 1539 */
|
||||
|
@ -582,6 +582,58 @@ BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname)
|
||||
BOOL verification_status = FALSE;
|
||||
rdpCertificateData* certificate_data;
|
||||
|
||||
if (tls->settings->ExternalCertificateManagement)
|
||||
{
|
||||
BIO* bio;
|
||||
int status;
|
||||
int length;
|
||||
int offset;
|
||||
BYTE* pemCert;
|
||||
freerdp* instance = (freerdp*) tls->settings->instance;
|
||||
|
||||
/**
|
||||
* Don't manage certificates internally, leave it up entirely to the external client implementation
|
||||
*/
|
||||
|
||||
bio = BIO_new(BIO_s_mem());
|
||||
|
||||
status = PEM_write_bio_X509(bio, cert->px509);
|
||||
|
||||
offset = 0;
|
||||
length = 2048;
|
||||
pemCert = (BYTE*) malloc(length + 1);
|
||||
|
||||
status = BIO_read(bio, pemCert, length);
|
||||
offset += status;
|
||||
|
||||
while (offset >= length)
|
||||
{
|
||||
length *= 2;
|
||||
pemCert = (BYTE*) realloc(pemCert, length + 1);
|
||||
|
||||
status = BIO_read(bio, &pemCert[offset], length);
|
||||
|
||||
if (status < 0)
|
||||
break;
|
||||
|
||||
offset += status;
|
||||
}
|
||||
|
||||
length = offset;
|
||||
pemCert[length] = '\0';
|
||||
|
||||
status = -1;
|
||||
|
||||
if (instance->VerifyX509Certificate)
|
||||
{
|
||||
status = instance->VerifyX509Certificate(instance, pemCert, length, 0);
|
||||
}
|
||||
|
||||
free(pemCert);
|
||||
|
||||
return (status < 0) ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
/* ignore certificate verification if user explicitly required it (discouraged) */
|
||||
if (tls->settings->IgnoreCertificate)
|
||||
return TRUE; /* success! */
|
||||
|
Loading…
Reference in New Issue
Block a user