mirror of
https://github.com/FreeRDP/FreeRDP.git
synced 2024-11-27 11:54:44 +08:00
libfreerdp-core: send Access Denied TLS alert when server-side NLA fails
This commit is contained in:
parent
652dbfd50d
commit
51ad85e0ee
@ -34,6 +34,35 @@
|
||||
|
||||
#include <winpr/stream.h>
|
||||
|
||||
#define TLS_ALERT_LEVEL_WARNING 1
|
||||
#define TLS_ALERT_LEVEL_FATAL 2
|
||||
|
||||
#define TLS_ALERT_DESCRIPTION_CLOSE_NOTIFY 0
|
||||
#define TLS_ALERT_DESCRIPTION_UNEXPECTED_MESSAGE 10
|
||||
#define TLS_ALERT_DESCRIPTION_BAD_RECORD_MAC 20
|
||||
#define TLS_ALERT_DESCRIPTION_DECRYPTION_FAILED 21
|
||||
#define TLS_ALERT_DESCRIPTION_RECORD_OVERFLOW 22
|
||||
#define TLS_ALERT_DESCRIPTION_DECOMPRESSION_FAILURE 30
|
||||
#define TLS_ALERT_DESCRIPTION_HANSHAKE_FAILURE 40
|
||||
#define TLS_ALERT_DESCRIPTION_NO_CERTIFICATE 41
|
||||
#define TLS_ALERT_DESCRIPTION_BAD_CERTIFICATE 42
|
||||
#define TLS_ALERT_DESCRIPTION_UNSUPPORTED_CERTIFICATE 43
|
||||
#define TLS_ALERT_DESCRIPTION_CERTIFICATE_REVOKED 44
|
||||
#define TLS_ALERT_DESCRIPTION_CERTIFICATE_EXPIRED 45
|
||||
#define TLS_ALERT_DESCRIPTION_CERTIFICATE_UNKNOWN 46
|
||||
#define TLS_ALERT_DESCRIPTION_ILLEGAL_PARAMETER 47
|
||||
#define TLS_ALERT_DESCRIPTION_UNKNOWN_CA 48
|
||||
#define TLS_ALERT_DESCRIPTION_ACCESS_DENIED 49
|
||||
#define TLS_ALERT_DESCRIPTION_DECODE_ERROR 50
|
||||
#define TLS_ALERT_DESCRIPTION_DECRYPT_ERROR 51
|
||||
#define TLS_ALERT_DESCRIPTION_EXPORT_RESTRICTION 60
|
||||
#define TLS_ALERT_DESCRIPTION_PROTOCOL_VERSION 70
|
||||
#define TLS_ALERT_DESCRIPTION_INSUFFICIENT_SECURITY 71
|
||||
#define TLS_ALERT_DESCRIPTION_INTERNAL_ERROR 80
|
||||
#define TLS_ALERT_DESCRIPTION_USER_CANCELED 90
|
||||
#define TLS_ALERT_DESCRIPTION_NO_RENEGOTIATION 100
|
||||
#define TLS_ALERT_DESCRIPTION_UNSUPPORTED_EXTENSION 110
|
||||
|
||||
typedef struct rdp_tls rdpTls;
|
||||
|
||||
struct rdp_tls
|
||||
@ -51,6 +80,8 @@ struct rdp_tls
|
||||
rdpCertificateStore* certificate_store;
|
||||
char* hostname;
|
||||
int port;
|
||||
int alertLevel;
|
||||
int alertDescription;
|
||||
};
|
||||
|
||||
FREERDP_API BOOL tls_connect(rdpTls* tls);
|
||||
@ -65,6 +96,8 @@ FREERDP_API int tls_write_all(rdpTls* tls, BYTE* data, int length);
|
||||
FREERDP_API int tls_wait_read(rdpTls* tls);
|
||||
FREERDP_API int tls_wait_write(rdpTls* tls);
|
||||
|
||||
FREERDP_API int tls_set_alert_code(rdpTls* tls, int level, int description);
|
||||
|
||||
FREERDP_API BOOL tls_match_hostname(char *pattern, int pattern_length, char *hostname);
|
||||
FREERDP_API BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int port);
|
||||
FREERDP_API void tls_print_certificate_error(char* hostname, char* fingerprint, char* hosts_file);
|
||||
|
@ -623,7 +623,7 @@ int credssp_server_authenticate(rdpCredssp* credssp)
|
||||
if ((status != SEC_E_OK) && (status != SEC_I_CONTINUE_NEEDED))
|
||||
{
|
||||
fprintf(stderr, "AcceptSecurityContext status: 0x%08X\n", status);
|
||||
return -1;
|
||||
return -1; /* Access Denied */
|
||||
}
|
||||
|
||||
/* send authentication token */
|
||||
|
@ -452,6 +452,9 @@ BOOL transport_accept_nla(rdpTransport* transport)
|
||||
fprintf(stderr, "client authentication failure\n");
|
||||
credssp_free(transport->credssp);
|
||||
transport->credssp = NULL;
|
||||
|
||||
tls_set_alert_code(transport->TlsIn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DESCRIPTION_ACCESS_DENIED);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -110,8 +110,6 @@ BOOL tls_connect(rdpTls* tls)
|
||||
CryptoCert cert;
|
||||
long options = 0;
|
||||
int connection_status;
|
||||
char *hostname;
|
||||
int port;
|
||||
|
||||
tls->ctx = SSL_CTX_new(TLSv1_client_method());
|
||||
|
||||
@ -360,7 +358,38 @@ BOOL tls_disconnect(rdpTls* tls)
|
||||
return FALSE;
|
||||
|
||||
if (tls->ssl)
|
||||
SSL_shutdown(tls->ssl);
|
||||
{
|
||||
if (tls->alertDescription != TLS_ALERT_DESCRIPTION_CLOSE_NOTIFY)
|
||||
{
|
||||
/**
|
||||
* OpenSSL doesn't really expose an API for sending a TLS alert manually.
|
||||
*
|
||||
* The following code disables the sending of the default "close notify"
|
||||
* and then proceeds to force sending a custom TLS alert before shutting down.
|
||||
*
|
||||
* Manually sending a TLS alert is necessary in certain cases,
|
||||
* like when server-side NLA results in an authentication failure.
|
||||
*/
|
||||
|
||||
SSL_set_quiet_shutdown(tls->ssl, 1);
|
||||
|
||||
if ((tls->alertLevel == TLS_ALERT_LEVEL_FATAL) && (tls->ssl->session))
|
||||
SSL_CTX_remove_session(tls->ssl->ctx, tls->ssl->session);
|
||||
|
||||
tls->ssl->s3->alert_dispatch = 1;
|
||||
tls->ssl->s3->send_alert[0] = tls->alertLevel;
|
||||
tls->ssl->s3->send_alert[1] = tls->alertDescription;
|
||||
|
||||
if (tls->ssl->s3->wbuf.left == 0)
|
||||
tls->ssl->method->ssl_dispatch_alert(tls->ssl);
|
||||
|
||||
SSL_shutdown(tls->ssl);
|
||||
}
|
||||
else
|
||||
{
|
||||
SSL_shutdown(tls->ssl);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -549,6 +578,14 @@ BOOL tls_print_error(char* func, SSL* connection, int value)
|
||||
}
|
||||
}
|
||||
|
||||
int tls_set_alert_code(rdpTls* tls, int level, int description)
|
||||
{
|
||||
tls->alertLevel = level;
|
||||
tls->alertDescription = description;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL tls_match_hostname(char *pattern, int pattern_length, char *hostname)
|
||||
{
|
||||
if (strlen(hostname) == pattern_length)
|
||||
@ -868,6 +905,9 @@ rdpTls* tls_new(rdpSettings* settings)
|
||||
|
||||
tls->settings = settings;
|
||||
tls->certificate_store = certificate_store_new(settings);
|
||||
|
||||
tls->alertLevel = TLS_ALERT_LEVEL_WARNING;
|
||||
tls->alertDescription = TLS_ALERT_DESCRIPTION_CLOSE_NOTIFY;
|
||||
}
|
||||
|
||||
return tls;
|
||||
|
Loading…
Reference in New Issue
Block a user