tls: add an option to dump tls secrets for wireshark decoding (#8120)

This new option /tls-secret-file:<file> allows to dump TLS secrets in a file with
the SSLKEYLOGFILE format. So this way you can setup the TLS dissector of wireshark
(Pre-Master-Secret log filename) and see the traffic in clear in wireshark.
It also add some more PFS ciphers to remove for netmon captures.
This commit is contained in:
David Fort 2022-08-16 10:40:32 +02:00 committed by GitHub
parent 8f44b9cf87
commit 942273e9cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 64 additions and 2 deletions

View File

@ -2867,7 +2867,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
if (strcmp(arg->Value, "netmon") == 0)
{
ciphers = "ALL:!ECDH";
ciphers = "ALL:!ECDH:!ADH:!DHE";
}
else if (strcmp(arg->Value, "ma") == 0)
{
@ -2890,6 +2890,14 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
settings->TlsSecLevel = (UINT32)val;
}
CommandLineSwitchCase(arg, "tls-secrets-file")
{
if (!arg->Value)
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
if (!freerdp_settings_set_string(settings, FreeRDP_TlsSecretsFile, arg->Value))
return COMMAND_LINE_ERROR_MEMORY;
}
CommandLineSwitchCase(arg, "enforce-tlsv1_2")
{
if (!(freerdp_settings_set_uint16(settings, FreeRDP_TLSMinVersion, TLS1_2_VERSION) &&

View File

@ -369,6 +369,8 @@ static const COMMAND_LINE_ARGUMENT_A global_cmd_args[] = {
"Allowed TLS ciphers" },
{ "tls-seclevel", COMMAND_LINE_VALUE_REQUIRED, "<level>", "1", NULL, -1, NULL,
"TLS security level - defaults to 1" },
{ "tls-secrets-file", COMMAND_LINE_VALUE_REQUIRED, "<filename>", NULL, NULL, -1, NULL,
"File were TLS secrets will be stored in the SSLKEYLOGFILE format" },
{ "enforce-tlsv1_2", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL,
"Force use of TLS1.2 for connection. Some servers have a buggy TLS version negotiation and "
"might fail without this" },

View File

@ -639,6 +639,7 @@ typedef struct
#define FreeRDP_SspiModule (1106)
#define FreeRDP_TLSMinVersion (1107)
#define FreeRDP_TLSMaxVersion (1108)
#define FreeRDP_TlsSecretsFile (1109)
#define FreeRDP_MstscCookieMode (1152)
#define FreeRDP_CookieMaxLength (1153)
#define FreeRDP_PreconnectionId (1154)
@ -1126,7 +1127,8 @@ struct rdp_settings
ALIGN64 char* SspiModule; /* 1106 */
ALIGN64 UINT16 TLSMinVersion; /* 1107 */
ALIGN64 UINT16 TLSMaxVersion; /* 1108 */
UINT64 padding1152[1152 - 1109]; /* 1109 */
ALIGN64 char* TlsSecretsFile; /* 1109 */
UINT64 padding1152[1152 - 1110]; /* 1110 */
/* Connection Cookie */
ALIGN64 BOOL MstscCookieMode; /* 1152 */

View File

@ -2594,6 +2594,9 @@ const char* freerdp_settings_get_string(const rdpSettings* settings, size_t id)
case FreeRDP_TargetNetAddress:
return settings->TargetNetAddress;
case FreeRDP_TlsSecretsFile:
return settings->TlsSecretsFile;
case FreeRDP_TransportDumpFile:
return settings->TransportDumpFile;
@ -2855,6 +2858,9 @@ char* freerdp_settings_get_string_writable(rdpSettings* settings, size_t id)
case FreeRDP_TargetNetAddress:
return settings->TargetNetAddress;
case FreeRDP_TlsSecretsFile:
return settings->TlsSecretsFile;
case FreeRDP_TransportDumpFile:
return settings->TransportDumpFile;
@ -3126,6 +3132,9 @@ BOOL freerdp_settings_set_string_(rdpSettings* settings, size_t id, const char*
case FreeRDP_TargetNetAddress:
return update_string(&settings->TargetNetAddress, cnv.cc, len, cleanup);
case FreeRDP_TlsSecretsFile:
return update_string(&settings->TlsSecretsFile, cnv.cc, len, cleanup);
case FreeRDP_TransportDumpFile:
return update_string(&settings->TransportDumpFile, cnv.cc, len, cleanup);

View File

@ -391,6 +391,7 @@ static const struct settings_str_entry settings_map[] = {
{ FreeRDP_SmartcardPrivateKey, 7, "FreeRDP_SmartcardPrivateKey" },
{ FreeRDP_SspiModule, 7, "FreeRDP_SspiModule" },
{ FreeRDP_TargetNetAddress, 7, "FreeRDP_TargetNetAddress" },
{ FreeRDP_TlsSecretsFile, 7, "FreeRDP_TlsSecretsFile" },
{ FreeRDP_TransportDumpFile, 7, "FreeRDP_TransportDumpFile" },
{ FreeRDP_Username, 7, "FreeRDP_Username" },
{ FreeRDP_WindowTitle, 7, "FreeRDP_WindowTitle" },

View File

@ -400,6 +400,7 @@ static const size_t string_list_indices[] = {
FreeRDP_SmartcardPrivateKey,
FreeRDP_SspiModule,
FreeRDP_TargetNetAddress,
FreeRDP_TlsSecretsFile,
FreeRDP_TransportDumpFile,
FreeRDP_Username,
FreeRDP_WindowTitle,

View File

@ -646,6 +646,33 @@ out_free:
return NULL;
}
static INIT_ONCE secrets_file_idx_once = INIT_ONCE_STATIC_INIT;
static int secrets_file_idx = -1;
static BOOL CALLBACK secrets_file_init_cb(PINIT_ONCE once, PVOID param, PVOID* context)
{
secrets_file_idx = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
return (secrets_file_idx != -1);
}
static void SSLCTX_keylog_cb(const SSL* ssl, const char* line)
{
char* dfile;
if (secrets_file_idx == -1)
return;
dfile = SSL_get_ex_data(ssl, secrets_file_idx);
if (dfile)
{
FILE* f = fopen(dfile, "a+");
fwrite(line, strlen(line), 1, f);
fwrite("\n", 1, 1, f);
fclose(f);
}
}
#if OPENSSL_VERSION_NUMBER >= 0x010000000L
static BOOL tls_prepare(rdpTls* tls, BIO* underlying, const SSL_METHOD* method, int options,
BOOL clientMode)
@ -656,6 +683,7 @@ static BOOL tls_prepare(rdpTls* tls, BIO* underlying, SSL_METHOD* method, int op
{
rdpSettings* settings = tls->settings;
tls->ctx = SSL_CTX_new(method);
tls->underlying = underlying;
if (!tls->ctx)
@ -702,6 +730,17 @@ static BOOL tls_prepare(rdpTls* tls, BIO* underlying, SSL_METHOD* method, int op
return FALSE;
}
if (settings->TlsSecretsFile)
{
InitOnceExecuteOnce(&secrets_file_idx_once, secrets_file_init_cb, NULL, NULL);
if (secrets_file_idx != -1)
{
SSL_set_ex_data(tls->ssl, secrets_file_idx, settings->TlsSecretsFile);
SSL_CTX_set_keylog_callback(tls->ctx, SSLCTX_keylog_cb);
}
}
BIO_push(tls->bio, underlying);
return TRUE;
}