Merge pull request #4441 from akallabeth/paa
[cleanup] Support for gatewayaccesstoken / PAA
This commit is contained in:
commit
3cfa837b0c
@ -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;
|
||||||
|
@ -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" },
|
||||||
|
@ -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);
|
||||||
|
@ -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 */
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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 */
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user