Merge pull request #4441 from akallabeth/paa

[cleanup] Support for gatewayaccesstoken / PAA
This commit is contained in:
Martin Fleisz 2018-02-19 17:28:32 +01:00 committed by GitHub
commit 3cfa837b0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 213 additions and 66 deletions

View File

@ -1898,6 +1898,13 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
settings->GatewayHttpTransport = TRUE; settings->GatewayHttpTransport = TRUE;
} }
} }
CommandLineSwitchCase(arg, "gat")
{
free(settings->GatewayAccessToken);
if (!(settings->GatewayAccessToken = _strdup(arg->Value)))
return COMMAND_LINE_ERROR_MEMORY;
}
CommandLineSwitchCase(arg, "gateway-usage-method") CommandLineSwitchCase(arg, "gateway-usage-method")
{ {
long type; long type;

View File

@ -92,6 +92,7 @@ static COMMAND_LINE_ARGUMENT_A args[] =
{ "grab-keyboard", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Grab keyboard" }, { "grab-keyboard", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Grab keyboard" },
{ "gt", COMMAND_LINE_VALUE_REQUIRED, "rpc|http|auto", NULL, NULL, -1, NULL, "Gateway transport type" }, { "gt", COMMAND_LINE_VALUE_REQUIRED, "rpc|http|auto", NULL, NULL, -1, NULL, "Gateway transport type" },
{ "gu", COMMAND_LINE_VALUE_REQUIRED, "[<domain>\\]<user> or <user>[@<domain>]", NULL, NULL, -1, NULL, "Gateway username" }, { "gu", COMMAND_LINE_VALUE_REQUIRED, "[<domain>\\]<user> or <user>[@<domain>]", NULL, NULL, -1, NULL, "Gateway username" },
{ "gat", COMMAND_LINE_VALUE_REQUIRED, "<access token>", NULL, NULL, -1, NULL, "Gateway Access Token" },
{ "h", COMMAND_LINE_VALUE_REQUIRED, "<height>", "768", NULL, -1, NULL, "Height" }, { "h", COMMAND_LINE_VALUE_REQUIRED, "<height>", "768", NULL, -1, NULL, "Height" },
{ "heartbeat", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Support heartbeat PDUs" }, { "heartbeat", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Support heartbeat PDUs" },
{ "help", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP, NULL, NULL, NULL, -1, "?", "Print help" }, { "help", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP, NULL, NULL, NULL, -1, "?", "Print help" },
@ -171,7 +172,7 @@ static COMMAND_LINE_ARGUMENT_A args[] =
{ "v", COMMAND_LINE_VALUE_REQUIRED, "<server>[:port]", NULL, NULL, -1, NULL, "Server hostname" }, { "v", COMMAND_LINE_VALUE_REQUIRED, "<server>[:port]", NULL, NULL, -1, NULL, "Server hostname" },
{ "vc", COMMAND_LINE_VALUE_REQUIRED, "<channel>[,<options>]", NULL, NULL, -1, NULL, "Static virtual channel" }, { "vc", COMMAND_LINE_VALUE_REQUIRED, "<channel>[,<options>]", NULL, NULL, -1, NULL, "Static virtual channel" },
{ "version", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_VERSION, NULL, NULL, NULL, -1, NULL, "Print version" }, { "version", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_VERSION, NULL, NULL, NULL, -1, NULL, "Print version" },
{ "video", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "Video optimized remoting channel" }, { "video", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "Video optimized remoting channel" },
{ "vmconnect", COMMAND_LINE_VALUE_OPTIONAL, "<vmid>", NULL, NULL, -1, NULL, "Hyper-V console (use port 2179, disable negotiation)" }, { "vmconnect", COMMAND_LINE_VALUE_OPTIONAL, "<vmid>", NULL, NULL, -1, NULL, "Hyper-V console (use port 2179, disable negotiation)" },
{ "w", COMMAND_LINE_VALUE_REQUIRED, "<width>", "1024", NULL, -1, NULL, "Width" }, { "w", COMMAND_LINE_VALUE_REQUIRED, "<width>", "1024", NULL, -1, NULL, "Width" },
{ "wallpaper", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Enable wallpaper" }, { "wallpaper", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Enable wallpaper" },

View File

@ -288,6 +288,8 @@ static int freerdp_client_rdp_file_set_string(rdpFile* file, const char* name, c
tmp = &file->ShellWorkingDirectory; tmp = &file->ShellWorkingDirectory;
else if (_stricmp(name, "gatewayhostname") == 0) else if (_stricmp(name, "gatewayhostname") == 0)
tmp = &file->GatewayHostname; tmp = &file->GatewayHostname;
else if (_stricmp(name, "gatewayaccesstoken") == 0)
tmp = &file->GatewayAccessToken;
else if (_stricmp(name, "kdcproxyname") == 0) else if (_stricmp(name, "kdcproxyname") == 0)
tmp = &file->KdcProxyName; tmp = &file->KdcProxyName;
else if (_stricmp(name, "drivestoredirect") == 0) else if (_stricmp(name, "drivestoredirect") == 0)
@ -598,6 +600,7 @@ BOOL freerdp_client_populate_rdp_file_from_settings(rdpFile* file, const rdpSett
} }
SETTING_MODIFIED_SET_STRING(file->GatewayHostname, settings, GatewayHostname); SETTING_MODIFIED_SET_STRING(file->GatewayHostname, settings, GatewayHostname);
SETTING_MODIFIED_SET_STRING(file->GatewayAccessToken, settings, GatewayAccessToken);
SETTING_MODIFIED_SET(file->GatewayUsageMethod, settings, GatewayUsageMethod); SETTING_MODIFIED_SET(file->GatewayUsageMethod, settings, GatewayUsageMethod);
SETTING_MODIFIED_SET(file->PromptCredentialOnce, settings, GatewayUseSameCredentials); SETTING_MODIFIED_SET(file->PromptCredentialOnce, settings, GatewayUseSameCredentials);
SETTING_MODIFIED_SET(file->RemoteApplicationMode, settings, RemoteApplicationMode); SETTING_MODIFIED_SET(file->RemoteApplicationMode, settings, RemoteApplicationMode);
@ -893,6 +896,12 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings*
free(host); free(host);
} }
if (~((size_t) file->GatewayAccessToken))
{
if (freerdp_set_param_string(settings, FreeRDP_GatewayAccessToken, file->GatewayAccessToken) != 0)
return FALSE;
}
if (~file->GatewayUsageMethod) if (~file->GatewayUsageMethod)
freerdp_set_gateway_usage_method(settings, file->GatewayUsageMethod); freerdp_set_gateway_usage_method(settings, file->GatewayUsageMethod);
@ -1314,6 +1323,7 @@ void freerdp_client_rdp_file_free(rdpFile* file)
freerdp_client_file_string_check_free(file->AlternateShell); freerdp_client_file_string_check_free(file->AlternateShell);
freerdp_client_file_string_check_free(file->ShellWorkingDirectory); freerdp_client_file_string_check_free(file->ShellWorkingDirectory);
freerdp_client_file_string_check_free(file->GatewayHostname); freerdp_client_file_string_check_free(file->GatewayHostname);
freerdp_client_file_string_check_free(file->GatewayAccessToken);
freerdp_client_file_string_check_free(file->KdcProxyName); freerdp_client_file_string_check_free(file->KdcProxyName);
freerdp_client_file_string_check_free(file->DrivesToRedirect); freerdp_client_file_string_check_free(file->DrivesToRedirect);
freerdp_client_file_string_check_free(file->DevicesToRedirect); freerdp_client_file_string_check_free(file->DevicesToRedirect);

View File

@ -140,6 +140,7 @@ struct rdp_file
DWORD GatewayUsageMethod; /* gatewayusagemethod */ DWORD GatewayUsageMethod; /* gatewayusagemethod */
DWORD GatewayProfileUsageMethod; /* gatewayprofileusagemethod */ DWORD GatewayProfileUsageMethod; /* gatewayprofileusagemethod */
DWORD GatewayCredentialsSource; /* gatewaycredentialssource */ DWORD GatewayCredentialsSource; /* gatewaycredentialssource */
LPSTR GatewayAccessToken; /* gatewayaccesstoken */
DWORD UseRedirectionServerName; /* use redirection server name */ DWORD UseRedirectionServerName; /* use redirection server name */

View File

@ -691,6 +691,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL;
#define FreeRDP_GatewayRpcTransport 1994 #define FreeRDP_GatewayRpcTransport 1994
#define FreeRDP_GatewayHttpTransport 1995 #define FreeRDP_GatewayHttpTransport 1995
#define FreeRDP_GatewayUdpTransport 1996 #define FreeRDP_GatewayUdpTransport 1996
#define FreeRDP_GatewayAccessToken 1997
#define FreeRDP_ProxyType 2015 #define FreeRDP_ProxyType 2015
#define FreeRDP_ProxyHostname 2016 #define FreeRDP_ProxyHostname 2016
#define FreeRDP_ProxyPort 2017 #define FreeRDP_ProxyPort 2017
@ -1156,7 +1157,8 @@ struct rdp_settings
ALIGN64 BOOL GatewayRpcTransport; /* 1994 */ ALIGN64 BOOL GatewayRpcTransport; /* 1994 */
ALIGN64 BOOL GatewayHttpTransport; /* 1995 */ ALIGN64 BOOL GatewayHttpTransport; /* 1995 */
ALIGN64 BOOL GatewayUdpTransport; /* 1996 */ ALIGN64 BOOL GatewayUdpTransport; /* 1996 */
UINT64 padding2048[2015 - 1997]; /* 1997 */ ALIGN64 char* GatewayAccessToken; /* 1997 */
UINT64 padding2015[2015 - 1998]; /* 1998 */
/* Proxy */ /* Proxy */
ALIGN64 UINT32 ProxyType; /* 2015 */ ALIGN64 UINT32 ProxyType; /* 2015 */
@ -1449,6 +1451,7 @@ struct rdp_settings
ALIGN64 BYTE* ALIGN64 BYTE*
SettingsModified; /* byte array marking fields that have been modified from their default value */ SettingsModified; /* byte array marking fields that have been modified from their default value */
ALIGN64 char* ActionScript; ALIGN64 char* ActionScript;
}; };
typedef struct rdp_settings rdpSettings; typedef struct rdp_settings rdpSettings;

View File

@ -2503,6 +2503,9 @@ char* freerdp_get_param_string(rdpSettings* settings, int id)
case FreeRDP_GatewayDomain: case FreeRDP_GatewayDomain:
return settings->GatewayDomain; return settings->GatewayDomain;
case FreeRDP_GatewayAccessToken:
return settings->GatewayAccessToken;
case FreeRDP_ProxyHostname: case FreeRDP_ProxyHostname:
return settings->ProxyHostname; return settings->ProxyHostname;
@ -2713,6 +2716,10 @@ int freerdp_set_param_string(rdpSettings* settings, int id, const char* param)
tmp = &settings->GatewayDomain; tmp = &settings->GatewayDomain;
break; break;
case FreeRDP_GatewayAccessToken:
tmp = &settings->GatewayAccessToken;
break;
case FreeRDP_ProxyHostname: case FreeRDP_ProxyHostname:
tmp = &settings->ProxyHostname; tmp = &settings->ProxyHostname;
break; break;

View File

@ -181,6 +181,13 @@ BOOL http_context_set_rdg_connection_id(HttpContext* context, const char* RdgCon
return TRUE; return TRUE;
} }
BOOL http_context_set_rdg_auth_scheme(HttpContext* context, const char* RdgAuthScheme)
{
free(context->RdgAuthScheme);
context->RdgAuthScheme = _strdup(RdgAuthScheme);
return context->RdgAuthScheme != NULL;
}
void http_context_free(HttpContext* context) void http_context_free(HttpContext* context)
{ {
if (context) if (context)
@ -194,6 +201,7 @@ void http_context_free(HttpContext* context)
free(context->Connection); free(context->Connection);
free(context->Pragma); free(context->Pragma);
free(context->RdgConnectionId); free(context->RdgConnectionId);
free(context->RdgAuthScheme);
free(context); free(context);
} }
} }
@ -332,9 +340,29 @@ wStream* http_request_write(HttpContext* context, HttpRequest* request)
lines[count++] = http_encode_body_line("Pragma", context->Pragma); lines[count++] = http_encode_body_line("Pragma", context->Pragma);
lines[count++] = http_encode_body_line("Accept", context->Accept); lines[count++] = http_encode_body_line("Accept", context->Accept);
lines[count++] = http_encode_body_line("User-Agent", context->UserAgent); lines[count++] = http_encode_body_line("User-Agent", context->UserAgent);
lines[count++] = http_encode_content_length_line(request->ContentLength);
lines[count++] = http_encode_body_line("Host", context->Host); lines[count++] = http_encode_body_line("Host", context->Host);
if (!context->RdgAuthScheme)
lines[count++] = http_encode_content_length_line(request->ContentLength);
if (context->RdgConnectionId)
lines[count++] = http_encode_body_line("RDG-Connection-Id", context->RdgConnectionId);
if (context->RdgAuthScheme)
lines[count++] = http_encode_body_line("RDG-Auth-Scheme", context->RdgAuthScheme);
if (request->TransferEncoding)
lines[count++] = http_encode_body_line("Transfer-Encoding", request->TransferEncoding);
if (request->Authorization)
{
lines[count++] = http_encode_body_line("Authorization", request->Authorization);
}
else if (request->AuthScheme && request->AuthParam)
{
lines[count++] = http_encode_authorization_line(request->AuthScheme, request->AuthParam);
}
/* check that everything went well */ /* check that everything went well */
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
@ -342,45 +370,6 @@ wStream* http_request_write(HttpContext* context, HttpRequest* request)
goto out_free; goto out_free;
} }
if (context->RdgConnectionId)
{
lines[count] = http_encode_body_line("RDG-Connection-Id", context->RdgConnectionId);
if (!lines[count])
goto out_free;
count++;
}
if (request->TransferEncoding)
{
lines[count] = http_encode_body_line("Transfer-Encoding", request->TransferEncoding);
if (!lines[count])
goto out_free;
count++;
}
if (request->Authorization)
{
lines[count] = http_encode_body_line("Authorization", request->Authorization);
if (!lines[count])
goto out_free;
count++;
}
else if (request->AuthScheme && request->AuthParam)
{
lines[count] = http_encode_authorization_line(request->AuthScheme, request->AuthParam);
if (!lines[count])
goto out_free;
count++;
}
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
length += (strlen(lines[i]) + 2); /* add +2 for each '\r\n' character */ length += (strlen(lines[i]) + 2); /* add +2 for each '\r\n' character */

View File

@ -42,6 +42,7 @@ struct _http_context
char* Connection; char* Connection;
char* Pragma; char* Pragma;
char* RdgConnectionId; char* RdgConnectionId;
char* RdgAuthScheme;
}; };
FREERDP_LOCAL BOOL http_context_set_method(HttpContext* context, FREERDP_LOCAL BOOL http_context_set_method(HttpContext* context,
@ -61,6 +62,8 @@ FREERDP_LOCAL BOOL http_context_set_pragma(HttpContext* context,
const char* Pragma); const char* Pragma);
FREERDP_LOCAL BOOL http_context_set_rdg_connection_id(HttpContext* context, FREERDP_LOCAL BOOL http_context_set_rdg_connection_id(HttpContext* context,
const char* RdgConnectionId); const char* RdgConnectionId);
FREERDP_LOCAL BOOL http_context_set_rdg_auth_scheme(HttpContext* context,
const char* RdgAuthScheme);
HttpContext* http_context_new(void); HttpContext* http_context_new(void);
void http_context_free(HttpContext* context); void http_context_free(HttpContext* context);

View File

@ -144,7 +144,7 @@ static BOOL rdg_send_handshake(rdpRdg* rdg)
Stream_Write_UINT8(s, 1); /* VersionMajor (1 byte) */ Stream_Write_UINT8(s, 1); /* VersionMajor (1 byte) */
Stream_Write_UINT8(s, 0); /* VersionMinor (1 byte) */ Stream_Write_UINT8(s, 0); /* VersionMinor (1 byte) */
Stream_Write_UINT16(s, 0); /* ClientVersion (2 bytes), must be 0 */ Stream_Write_UINT16(s, 0); /* ClientVersion (2 bytes), must be 0 */
Stream_Write_UINT16(s, 0); /* ExtendedAuthentication (2 bytes) */ Stream_Write_UINT16(s, rdg->extAuth); /* ExtendedAuthentication (2 bytes) */
Stream_SealLength(s); Stream_SealLength(s);
status = rdg_write_packet(rdg, s); status = rdg_write_packet(rdg, s);
Stream_Free(s, TRUE); Stream_Free(s, TRUE);
@ -161,20 +161,54 @@ static BOOL rdg_send_tunnel_request(rdpRdg* rdg)
{ {
wStream* s; wStream* s;
BOOL status; BOOL status;
s = Stream_New(NULL, 16); WCHAR* PAACookie = NULL;
UINT16 PAACookieLen = 0;
if (!s) if (rdg->extAuth == HTTP_EXTENDED_AUTH_PAA)
return FALSE; {
PAACookieLen = ConvertToUnicode(CP_UTF8, 0, rdg->settings->GatewayAccessToken, -1, &PAACookie, 0);
if (!PAACookie)
return FALSE;
s = Stream_New(NULL, 16 + 2 + 2 * PAACookieLen);
if (!s)
{
free(PAACookie);
return FALSE;
}
}
else
{
s = Stream_New(NULL, 16);
if (!s)
return FALSE;
}
Stream_Write_UINT16(s, PKT_TYPE_TUNNEL_CREATE); /* Type (2 bytes) */ Stream_Write_UINT16(s, PKT_TYPE_TUNNEL_CREATE); /* Type (2 bytes) */
Stream_Write_UINT16(s, 0); /* Reserved (2 bytes) */ Stream_Write_UINT16(s, 0); /* Reserved (2 bytes) */
Stream_Write_UINT32(s, 16); /* PacketLength (4 bytes) */ Stream_Write_UINT32(s, 16); /* PacketLength (4 bytes) */
Stream_Write_UINT32(s, HTTP_CAPABILITY_TYPE_QUAR_SOH); /* CapabilityFlags (4 bytes) */ Stream_Write_UINT32(s, HTTP_CAPABILITY_TYPE_QUAR_SOH); /* CapabilityFlags (4 bytes) */
Stream_Write_UINT16(s, 0); /* FieldsPresent (2 bytes) */
Stream_Write_UINT16(s, 0); /* Reserved (2 bytes), must be 0 */ if (rdg->extAuth == HTTP_EXTENDED_AUTH_PAA)
{
Stream_Write_UINT16(s, 1); /* FieldsPresent (2 bytes) */
Stream_Write_UINT16(s, 0); /* Reserved (2 bytes), must be 0 */
Stream_Write_UINT16(s, PAACookieLen * 2); /* PAA cookie string length */
Stream_Write_UTF16_String(s, PAACookie, PAACookieLen);
}
else
{
Stream_Write_UINT16(s, 0); /* FieldsPresent (2 bytes) */
Stream_Write_UINT16(s, 0); /* Reserved (2 bytes), must be 0 */
}
Stream_SealLength(s); Stream_SealLength(s);
status = rdg_write_packet(rdg, s); status = rdg_write_packet(rdg, s);
Stream_Free(s, TRUE); Stream_Free(s, TRUE);
free(PAACookie);
if (status) if (status)
{ {
@ -326,6 +360,36 @@ static BOOL rdg_process_out_channel_response(rdpRdg* rdg, HttpResponse* response
BYTE* ntlmTokenData = NULL; BYTE* ntlmTokenData = NULL;
rdpNtlm* ntlm = rdg->ntlm; rdpNtlm* ntlm = rdg->ntlm;
if (rdg->extAuth == HTTP_EXTENDED_AUTH_PAA)
{
if (response->StatusCode == HTTP_STATUS_OK)
{
rdg->state = RDG_CLIENT_STATE_OUT_CHANNEL_AUTHORIZED;
/*
packet trace shows additional 10 bytes with value 0xabcdabcdabcdabcdabcd
which is not a normal header + data format
can't find any documentation on how to handle, chose to just read an extra 10 bytes
*/
s = Stream_New(NULL, 10);
if (!s)
return FALSE;
status = BIO_read(rdg->tlsOut->bio, Stream_Pointer(s), 10);
Stream_Free(s, TRUE);
if (status <= 0)
return FALSE;
return TRUE;
}
else
{
/* fallback to regular authentication scheme */
rdg->extAuth = HTTP_EXTENDED_AUTH_NONE;
}
}
if (response->StatusCode != HTTP_STATUS_DENIED) if (response->StatusCode != HTTP_STATUS_DENIED)
{ {
WLog_DBG(TAG, "RDG not supported"); WLog_DBG(TAG, "RDG not supported");
@ -392,6 +456,32 @@ static BOOL rdg_process_in_channel_response(rdpRdg* rdg, HttpResponse* response)
int ntlmTokenLength = 0; int ntlmTokenLength = 0;
BYTE* ntlmTokenData = NULL; BYTE* ntlmTokenData = NULL;
rdpNtlm* ntlm = rdg->ntlm; rdpNtlm* ntlm = rdg->ntlm;
if (rdg->extAuth == HTTP_EXTENDED_AUTH_PAA)
{
if (response->StatusCode == HTTP_STATUS_OK)
{
rdg->state = RDG_CLIENT_STATE_IN_CHANNEL_AUTHORIZED;
/* send http headers again */
s = rdg_build_http_request(rdg, "RDG_IN_DATA");
if (!s)
return FALSE;
status = tls_write_all(rdg->tlsIn, Stream_Buffer(s), Stream_Length(s));
Stream_Free(s, TRUE);
if (status < 0)
return FALSE;
return TRUE;
}
else
{
rdg->extAuth = HTTP_EXTENDED_AUTH_NONE;
}
}
WLog_DBG(TAG, "In Channel authorization required"); WLog_DBG(TAG, "In Channel authorization required");
if (ListDictionary_Contains(response->Authenticates, "NTLM")) if (ListDictionary_Contains(response->Authenticates, "NTLM"))
@ -791,20 +881,25 @@ static BOOL rdg_send_out_channel_request(rdpRdg* rdg)
{ {
wStream* s = NULL; wStream* s = NULL;
int status; int status;
rdg->ntlm = ntlm_new(); rdg->ntlm = NULL;
if (!rdg->ntlm) if (rdg->extAuth == HTTP_EXTENDED_AUTH_NONE)
return FALSE; {
rdg->ntlm = ntlm_new();
status = rdg_ncacn_http_ntlm_init(rdg, rdg->tlsOut); if (!rdg->ntlm)
return FALSE;
if (!status) status = rdg_ncacn_http_ntlm_init(rdg, rdg->tlsOut);
return FALSE;
status = ntlm_authenticate(rdg->ntlm); if (!status)
return FALSE;
if (!status) status = ntlm_authenticate(rdg->ntlm);
return FALSE;
if (!status)
return FALSE;
}
s = rdg_build_http_request(rdg, "RDG_OUT_DATA"); s = rdg_build_http_request(rdg, "RDG_OUT_DATA");
@ -825,20 +920,25 @@ static BOOL rdg_send_in_channel_request(rdpRdg* rdg)
{ {
int status; int status;
wStream* s = NULL; wStream* s = NULL;
rdg->ntlm = ntlm_new(); rdg->ntlm = NULL;
if (!rdg->ntlm) if (rdg->extAuth == HTTP_EXTENDED_AUTH_NONE)
return FALSE; {
rdg->ntlm = ntlm_new();
status = rdg_ncacn_http_ntlm_init(rdg, rdg->tlsIn); if (!rdg->ntlm)
return FALSE;
if (!status) status = rdg_ncacn_http_ntlm_init(rdg, rdg->tlsIn);
return FALSE;
status = ntlm_authenticate(rdg->ntlm); if (!status)
return FALSE;
if (!status) status = ntlm_authenticate(rdg->ntlm);
return FALSE;
if (!status)
return FALSE;
}
s = rdg_build_http_request(rdg, "RDG_IN_DATA"); s = rdg_build_http_request(rdg, "RDG_IN_DATA");
@ -1501,6 +1601,11 @@ rdpRdg* rdg_new(rdpTransport* transport)
rdg->state = RDG_CLIENT_STATE_INITIAL; rdg->state = RDG_CLIENT_STATE_INITIAL;
rdg->context = transport->context; rdg->context = transport->context;
rdg->settings = rdg->context->settings; rdg->settings = rdg->context->settings;
rdg->extAuth = HTTP_EXTENDED_AUTH_NONE;
if (rdg->settings->GatewayAccessToken)
rdg->extAuth = HTTP_EXTENDED_AUTH_PAA;
UuidCreate(&rdg->guid); UuidCreate(&rdg->guid);
rpcStatus = UuidToStringA(&rdg->guid, &stringUuid); rpcStatus = UuidToStringA(&rdg->guid, &stringUuid);
@ -1540,6 +1645,23 @@ rdpRdg* rdg_new(rdpTransport* transport)
goto rdg_alloc_error; goto rdg_alloc_error;
} }
if (rdg->extAuth != HTTP_EXTENDED_AUTH_NONE)
{
switch (rdg->extAuth)
{
case HTTP_EXTENDED_AUTH_PAA:
http_context_set_rdg_auth_scheme(rdg->http, "PAA");
if (!rdg->http->RdgAuthScheme)
goto rdg_alloc_error;
break;
default:
WLog_DBG(TAG, "RDG extended authentication method %d not supported", rdg->extAuth);
}
}
rdg->frontBio = BIO_new(BIO_s_rdg()); rdg->frontBio = BIO_new(BIO_s_rdg());
if (!rdg->frontBio) if (!rdg->frontBio)

View File

@ -50,6 +50,7 @@ typedef struct rdp_rdg rdpRdg;
#define HTTP_EXTENDED_AUTH_NONE 0x0 #define HTTP_EXTENDED_AUTH_NONE 0x0
#define HTTP_EXTENDED_AUTH_SC 0x1 /* Smart card authentication. */ #define HTTP_EXTENDED_AUTH_SC 0x1 /* Smart card authentication. */
#define HTTP_EXTENDED_AUTH_PAA 0x02 /* Pluggable authentication. */ #define HTTP_EXTENDED_AUTH_PAA 0x02 /* Pluggable authentication. */
#define HTTP_EXTENDED_AUTH_SSPI_NTLM 0x04 /* NTLM extended authentication. */
/* HTTP packet types. */ /* HTTP packet types. */
#define PKT_TYPE_HANDSHAKE_REQUEST 0x1 #define PKT_TYPE_HANDSHAKE_REQUEST 0x1
@ -140,6 +141,7 @@ struct rdp_rdg
int state; int state;
UINT16 packetRemainingCount; UINT16 packetRemainingCount;
int timeout; int timeout;
UINT16 extAuth;
}; };

View File

@ -692,6 +692,7 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings)
CHECKED_STRDUP(GatewayUsername); /* 1987 */ CHECKED_STRDUP(GatewayUsername); /* 1987 */
CHECKED_STRDUP(GatewayPassword); /* 1988 */ CHECKED_STRDUP(GatewayPassword); /* 1988 */
CHECKED_STRDUP(GatewayDomain); /* 1989 */ CHECKED_STRDUP(GatewayDomain); /* 1989 */
CHECKED_STRDUP(GatewayAccessToken); /* 1997 */
CHECKED_STRDUP(ProxyHostname); /* 2016 */ CHECKED_STRDUP(ProxyHostname); /* 2016 */
CHECKED_STRDUP(RemoteApplicationName); /* 2113 */ CHECKED_STRDUP(RemoteApplicationName); /* 2113 */
CHECKED_STRDUP(RemoteApplicationIcon); /* 2114 */ CHECKED_STRDUP(RemoteApplicationIcon); /* 2114 */
@ -1085,6 +1086,7 @@ void freerdp_settings_free(rdpSettings* settings)
free(settings->GatewayUsername); free(settings->GatewayUsername);
free(settings->GatewayPassword); free(settings->GatewayPassword);
free(settings->GatewayDomain); free(settings->GatewayDomain);
free(settings->GatewayAccessToken);
free(settings->CertificateName); free(settings->CertificateName);
free(settings->DynamicDSTTimeZoneKeyName); free(settings->DynamicDSTTimeZoneKeyName);
free(settings->PreconnectionBlob); free(settings->PreconnectionBlob);