[client,win32] implement connection to child session
Under windows you can connect to a child session by requesting a named pipe to the local server, and then do some RDP on this named pipe. The protocol is like for /vmconnect with CredSSP, then Nego and then the "normal" workflow for a connection. For CredSSP we force the usage of NTLM for the Negociate SSPI, and the credentials are empty.
This commit is contained in:
parent
0638c382f9
commit
3c18a9980f
@ -1971,7 +1971,7 @@ static int parse_gfx_options(rdpSettings* settings, const COMMAND_LINE_ARGUMENT_
|
|||||||
WINPR_ASSERT(settings);
|
WINPR_ASSERT(settings);
|
||||||
WINPR_ASSERT(arg);
|
WINPR_ASSERT(arg);
|
||||||
|
|
||||||
if (!freerdp_settings_set_bool(settings, FreeRDP_SupportGraphicsPipeline, TRUE))
|
if (!freerdp_settings_set_bool(settings, FreeRDP_SupportGraphicsPipeline, (arg->Value != NULL)))
|
||||||
return COMMAND_LINE_ERROR;
|
return COMMAND_LINE_ERROR;
|
||||||
|
|
||||||
if (arg->Value)
|
if (arg->Value)
|
||||||
@ -3794,6 +3794,21 @@ static int freerdp_client_settings_parse_command_line_arguments_int(rdpSettings*
|
|||||||
settings->SendPreconnectionPdu = TRUE;
|
settings->SendPreconnectionPdu = TRUE;
|
||||||
settings->PreconnectionId = (UINT32)val;
|
settings->PreconnectionId = (UINT32)val;
|
||||||
}
|
}
|
||||||
|
#ifdef _WIN32
|
||||||
|
CommandLineSwitchCase(arg, "connect-child-session")
|
||||||
|
{
|
||||||
|
if (!freerdp_settings_set_string(settings, FreeRDP_AuthenticationServiceClass,
|
||||||
|
"vs-debug") ||
|
||||||
|
!freerdp_settings_set_string(settings, FreeRDP_ServerHostname, "localhost") ||
|
||||||
|
!freerdp_settings_set_string(settings, FreeRDP_AuthenticationPackageList, "ntlm") ||
|
||||||
|
!freerdp_settings_set_bool(settings, FreeRDP_NegotiateSecurityLayer, FALSE) ||
|
||||||
|
!freerdp_settings_set_bool(settings, FreeRDP_VmConnectMode, TRUE) ||
|
||||||
|
!freerdp_settings_set_bool(settings, FreeRDP_ConnectChildSession, TRUE) ||
|
||||||
|
!freerdp_settings_set_bool(settings, FreeRDP_NlaSecurity, TRUE) ||
|
||||||
|
!freerdp_settings_set_uint32(settings, FreeRDP_AuthenticationLevel, 0))
|
||||||
|
return COMMAND_LINE_ERROR_MEMORY;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
CommandLineSwitchCase(arg, "sec")
|
CommandLineSwitchCase(arg, "sec")
|
||||||
{
|
{
|
||||||
size_t count = 0, x;
|
size_t count = 0, x;
|
||||||
|
@ -111,6 +111,10 @@ static const COMMAND_LINE_ARGUMENT_A global_cmd_args[] = {
|
|||||||
"[DEPRECATED, use /cert:name:<name>] Certificate name" },
|
"[DEPRECATED, use /cert:name:<name>] Certificate name" },
|
||||||
{ "cert-tofu", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL,
|
{ "cert-tofu", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL,
|
||||||
"[DEPRECATED, use /cert:tofu] Automatically accept certificate on first connect" },
|
"[DEPRECATED, use /cert:tofu] Automatically accept certificate on first connect" },
|
||||||
|
#endif
|
||||||
|
#ifdef _WIN32
|
||||||
|
{ "connect-child-session", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, "",
|
||||||
|
"connect to child session (win32)" },
|
||||||
#endif
|
#endif
|
||||||
{ "client-build-number", COMMAND_LINE_VALUE_REQUIRED, "<number>", NULL, NULL, -1, NULL,
|
{ "client-build-number", COMMAND_LINE_VALUE_REQUIRED, "<number>", NULL, NULL, -1, NULL,
|
||||||
"Client Build Number sent to server (influences smartcard behaviour, see [MS-RDPESC])" },
|
"Client Build Number sent to server (influences smartcard behaviour, see [MS-RDPESC])" },
|
||||||
|
@ -485,12 +485,12 @@ extern "C"
|
|||||||
/* ThreadingFlags */
|
/* ThreadingFlags */
|
||||||
#define THREADING_FLAGS_DISABLE_THREADS 0x00000001
|
#define THREADING_FLAGS_DISABLE_THREADS 0x00000001
|
||||||
|
|
||||||
/* Settings */
|
/* Settings */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FreeRDP Settings Ids
|
* FreeRDP Settings Ids
|
||||||
* This is generated with a script parsing the rdpSettings data structure
|
* This is generated with a script parsing the rdpSettings data structure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define FreeRDP_instance (0)
|
#define FreeRDP_instance (0)
|
||||||
#define FreeRDP_ServerMode (16)
|
#define FreeRDP_ServerMode (16)
|
||||||
@ -737,6 +737,7 @@ extern "C"
|
|||||||
#define FreeRDP_OldLicenseBehaviour (1606)
|
#define FreeRDP_OldLicenseBehaviour (1606)
|
||||||
#define FreeRDP_MouseUseRelativeMove (1607)
|
#define FreeRDP_MouseUseRelativeMove (1607)
|
||||||
#define FreeRDP_UseCommonStdioCallbacks (1608)
|
#define FreeRDP_UseCommonStdioCallbacks (1608)
|
||||||
|
#define FreeRDP_ConnectChildSession (1609)
|
||||||
#define FreeRDP_ComputerName (1664)
|
#define FreeRDP_ComputerName (1664)
|
||||||
#define FreeRDP_ConnectionFile (1728)
|
#define FreeRDP_ConnectionFile (1728)
|
||||||
#define FreeRDP_AssistanceFile (1729)
|
#define FreeRDP_AssistanceFile (1729)
|
||||||
@ -941,9 +942,9 @@ extern "C"
|
|||||||
#define FreeRDP_Floatbar (5196)
|
#define FreeRDP_Floatbar (5196)
|
||||||
#define FreeRDP_TcpConnectTimeout (5197)
|
#define FreeRDP_TcpConnectTimeout (5197)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FreeRDP Settings Data Structure
|
* FreeRDP Settings Data Structure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define FreeRDP_Settings_StableAPI_MAX 5312
|
#define FreeRDP_Settings_StableAPI_MAX 5312
|
||||||
struct rdp_settings
|
struct rdp_settings
|
||||||
@ -1297,15 +1298,16 @@ extern "C"
|
|||||||
UINT64 padding1601[1601 - 1560]; /* 1560 */
|
UINT64 padding1601[1601 - 1560]; /* 1560 */
|
||||||
|
|
||||||
/* Miscellaneous */
|
/* Miscellaneous */
|
||||||
ALIGN64 BOOL SoftwareGdi; /* 1601 */
|
ALIGN64 BOOL SoftwareGdi; /* 1601 */
|
||||||
ALIGN64 BOOL LocalConnection; /* 1602 */
|
ALIGN64 BOOL LocalConnection; /* 1602 */
|
||||||
ALIGN64 BOOL AuthenticationOnly; /* 1603 */
|
ALIGN64 BOOL AuthenticationOnly; /* 1603 */
|
||||||
ALIGN64 BOOL CredentialsFromStdin; /* 1604 */
|
ALIGN64 BOOL CredentialsFromStdin; /* 1604 */
|
||||||
ALIGN64 BOOL UnmapButtons; /* 1605 */
|
ALIGN64 BOOL UnmapButtons; /* 1605 */
|
||||||
ALIGN64 BOOL OldLicenseBehaviour; /* 1606 */
|
ALIGN64 BOOL OldLicenseBehaviour; /* 1606 */
|
||||||
ALIGN64 BOOL MouseUseRelativeMove; /* 1607 */
|
ALIGN64 BOOL MouseUseRelativeMove; /* 1607 */
|
||||||
ALIGN64 BOOL UseCommonStdioCallbacks; /* 1608 */
|
ALIGN64 BOOL UseCommonStdioCallbacks; /* 1608 */
|
||||||
UINT64 padding1664[1664 - 1609]; /* 1609 */
|
ALIGN64 BOOL ConnectChildSession; /* 1609 */
|
||||||
|
UINT64 padding1664[1664 - 1610]; /* 1610 */
|
||||||
|
|
||||||
/* Names */
|
/* Names */
|
||||||
ALIGN64 char* ComputerName; /* 1664 */
|
ALIGN64 char* ComputerName; /* 1664 */
|
||||||
@ -1339,31 +1341,31 @@ extern "C"
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Gateway */
|
/* Gateway */
|
||||||
ALIGN64 UINT32 GatewayUsageMethod; /* 1984 */
|
ALIGN64 UINT32 GatewayUsageMethod; /* 1984 */
|
||||||
ALIGN64 UINT32 GatewayPort; /* 1985 */
|
ALIGN64 UINT32 GatewayPort; /* 1985 */
|
||||||
ALIGN64 char* GatewayHostname; /* 1986 */
|
ALIGN64 char* GatewayHostname; /* 1986 */
|
||||||
ALIGN64 char* GatewayUsername; /* 1987 */
|
ALIGN64 char* GatewayUsername; /* 1987 */
|
||||||
ALIGN64 char* GatewayPassword; /* 1988 */
|
ALIGN64 char* GatewayPassword; /* 1988 */
|
||||||
ALIGN64 char* GatewayDomain; /* 1989 */
|
ALIGN64 char* GatewayDomain; /* 1989 */
|
||||||
ALIGN64 UINT32 GatewayCredentialsSource; /* 1990 */
|
ALIGN64 UINT32 GatewayCredentialsSource; /* 1990 */
|
||||||
ALIGN64 BOOL GatewayUseSameCredentials; /* 1991 */
|
ALIGN64 BOOL GatewayUseSameCredentials; /* 1991 */
|
||||||
ALIGN64 BOOL GatewayEnabled; /* 1992 */
|
ALIGN64 BOOL GatewayEnabled; /* 1992 */
|
||||||
ALIGN64 BOOL GatewayBypassLocal; /* 1993 */
|
ALIGN64 BOOL GatewayBypassLocal; /* 1993 */
|
||||||
ALIGN64 BOOL GatewayRpcTransport; /* 1994 */
|
ALIGN64 BOOL GatewayRpcTransport; /* 1994 */
|
||||||
ALIGN64 BOOL GatewayHttpTransport; /* 1995 */
|
ALIGN64 BOOL GatewayHttpTransport; /* 1995 */
|
||||||
ALIGN64 BOOL GatewayUdpTransport; /* 1996 */
|
ALIGN64 BOOL GatewayUdpTransport; /* 1996 */
|
||||||
ALIGN64 char* GatewayAccessToken; /* 1997 */
|
ALIGN64 char* GatewayAccessToken; /* 1997 */
|
||||||
ALIGN64 char* GatewayAcceptedCert; /* 1998 */
|
ALIGN64 char* GatewayAcceptedCert; /* 1998 */
|
||||||
ALIGN64 UINT32 GatewayAcceptedCertLength; /* 1999 */
|
ALIGN64 UINT32 GatewayAcceptedCertLength; /* 1999 */
|
||||||
ALIGN64 BOOL GatewayHttpUseWebsockets; /* 2000 */
|
ALIGN64 BOOL GatewayHttpUseWebsockets; /* 2000 */
|
||||||
ALIGN64 BOOL GatewayHttpExtAuthSspiNtlm; /* 2001 */
|
ALIGN64 BOOL GatewayHttpExtAuthSspiNtlm; /* 2001 */
|
||||||
ALIGN64 char* GatewayHttpExtAuthBearer; /* 2002 */
|
ALIGN64 char* GatewayHttpExtAuthBearer; /* 2002 */
|
||||||
ALIGN64 char* GatewayUrl; /* 2003 */
|
ALIGN64 char* GatewayUrl; /* 2003 */
|
||||||
ALIGN64 BOOL GatewayArmTransport; /* 2004 */
|
ALIGN64 BOOL GatewayArmTransport; /* 2004 */
|
||||||
ALIGN64 char* GatewayAvdWvdEndpointPool; /* 2005 */
|
ALIGN64 char* GatewayAvdWvdEndpointPool; /* 2005 */
|
||||||
ALIGN64 char* GatewayAvdGeo; /* 2006 */
|
ALIGN64 char* GatewayAvdGeo; /* 2006 */
|
||||||
ALIGN64 char* GatewayAvdArmpath; /* 2007 */
|
ALIGN64 char* GatewayAvdArmpath; /* 2007 */
|
||||||
ALIGN64 char* GatewayAvdAadtenantid; /* 2008 */
|
ALIGN64 char* GatewayAvdAadtenantid; /* 2008 */
|
||||||
ALIGN64 char* GatewayAvdDiagnosticserviceurl; /* 2009 */
|
ALIGN64 char* GatewayAvdDiagnosticserviceurl; /* 2009 */
|
||||||
ALIGN64 char* GatewayAvdHubdiscoverygeourl; /* 2010 */
|
ALIGN64 char* GatewayAvdHubdiscoverygeourl; /* 2010 */
|
||||||
ALIGN64 char* GatewayAvdActivityhint; /* 2011 */
|
ALIGN64 char* GatewayAvdActivityhint; /* 2011 */
|
||||||
@ -1646,7 +1648,7 @@ extern "C"
|
|||||||
* Other Redirection
|
* Other Redirection
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ALIGN64 BOOL RedirectClipboard; /* 4800 */
|
ALIGN64 BOOL RedirectClipboard; /* 4800 */
|
||||||
ALIGN64 UINT32 ClipboardFeatureMask; /* 4801 */
|
ALIGN64 UINT32 ClipboardFeatureMask; /* 4801 */
|
||||||
UINT64 padding4928[4928 - 4802]; /* 4802 */
|
UINT64 padding4928[4928 - 4802]; /* 4802 */
|
||||||
|
|
||||||
|
@ -123,6 +123,9 @@ BOOL freerdp_settings_get_bool(const rdpSettings* settings, size_t id)
|
|||||||
case FreeRDP_CompressionEnabled:
|
case FreeRDP_CompressionEnabled:
|
||||||
return settings->CompressionEnabled;
|
return settings->CompressionEnabled;
|
||||||
|
|
||||||
|
case FreeRDP_ConnectChildSession:
|
||||||
|
return settings->ConnectChildSession;
|
||||||
|
|
||||||
case FreeRDP_ConsoleSession:
|
case FreeRDP_ConsoleSession:
|
||||||
return settings->ConsoleSession;
|
return settings->ConsoleSession;
|
||||||
|
|
||||||
@ -717,6 +720,10 @@ BOOL freerdp_settings_set_bool(rdpSettings* settings, size_t id, BOOL val)
|
|||||||
settings->CompressionEnabled = cnv.c;
|
settings->CompressionEnabled = cnv.c;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FreeRDP_ConnectChildSession:
|
||||||
|
settings->ConnectChildSession = cnv.c;
|
||||||
|
break;
|
||||||
|
|
||||||
case FreeRDP_ConsoleSession:
|
case FreeRDP_ConsoleSession:
|
||||||
settings->ConsoleSession = cnv.c;
|
settings->ConsoleSession = cnv.c;
|
||||||
break;
|
break;
|
||||||
|
@ -56,6 +56,7 @@ static const struct settings_str_entry settings_map[] = {
|
|||||||
{ FreeRDP_CertificateCallbackPreferPEM, FREERDP_SETTINGS_TYPE_BOOL,
|
{ FreeRDP_CertificateCallbackPreferPEM, FREERDP_SETTINGS_TYPE_BOOL,
|
||||||
"FreeRDP_CertificateCallbackPreferPEM" },
|
"FreeRDP_CertificateCallbackPreferPEM" },
|
||||||
{ FreeRDP_CompressionEnabled, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_CompressionEnabled" },
|
{ FreeRDP_CompressionEnabled, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_CompressionEnabled" },
|
||||||
|
{ FreeRDP_ConnectChildSession, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_ConnectChildSession" },
|
||||||
{ FreeRDP_ConsoleSession, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_ConsoleSession" },
|
{ FreeRDP_ConsoleSession, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_ConsoleSession" },
|
||||||
{ FreeRDP_CredentialsFromStdin, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_CredentialsFromStdin" },
|
{ FreeRDP_CredentialsFromStdin, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_CredentialsFromStdin" },
|
||||||
{ FreeRDP_DeactivateClientDecoding, FREERDP_SETTINGS_TYPE_BOOL,
|
{ FreeRDP_DeactivateClientDecoding, FREERDP_SETTINGS_TYPE_BOOL,
|
||||||
|
@ -107,6 +107,7 @@ set(${MODULE_PREFIX}_SRCS
|
|||||||
multitransport.h
|
multitransport.h
|
||||||
timezone.c
|
timezone.c
|
||||||
timezone.h
|
timezone.h
|
||||||
|
childsession.c
|
||||||
rdp.c
|
rdp.c
|
||||||
rdp.h
|
rdp.h
|
||||||
tcp.c
|
tcp.c
|
||||||
|
340
libfreerdp/core/childsession.c
Normal file
340
libfreerdp/core/childsession.c
Normal file
@ -0,0 +1,340 @@
|
|||||||
|
/**
|
||||||
|
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||||
|
* Named pipe transport
|
||||||
|
*
|
||||||
|
* Copyright 2023 David Fort <contact@hardening-consulting.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "tcp.h"
|
||||||
|
#include <winpr/library.h>
|
||||||
|
#include <winpr/assert.h>
|
||||||
|
#include "childsession.h"
|
||||||
|
|
||||||
|
#define TAG FREERDP_TAG("childsession")
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
HANDLE hFile;
|
||||||
|
} WINPR_BIO_NAMED;
|
||||||
|
|
||||||
|
static int transport_bio_named_uninit(BIO* bio);
|
||||||
|
|
||||||
|
static int transport_bio_named_write(BIO* bio, const char* buf, int size)
|
||||||
|
{
|
||||||
|
WINPR_ASSERT(bio);
|
||||||
|
WINPR_ASSERT(buf);
|
||||||
|
|
||||||
|
WINPR_BIO_NAMED* ptr = (WINPR_BIO_NAMED*)BIO_get_data(bio);
|
||||||
|
|
||||||
|
if (!buf)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
BIO_clear_flags(bio, BIO_FLAGS_WRITE);
|
||||||
|
DWORD written = 0;
|
||||||
|
|
||||||
|
BOOL ret = WriteFile(ptr->hFile, buf, size, &written, NULL);
|
||||||
|
WLog_VRB(TAG, "transport_bio_named_write(%d)=%d written=%d", size, ret, written);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (written == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return written;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int transport_bio_named_read(BIO* bio, char* buf, int size)
|
||||||
|
{
|
||||||
|
WINPR_ASSERT(bio);
|
||||||
|
WINPR_ASSERT(buf);
|
||||||
|
|
||||||
|
WINPR_BIO_NAMED* ptr = (WINPR_BIO_NAMED*)BIO_get_data(bio);
|
||||||
|
|
||||||
|
if (!buf)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
BIO_clear_flags(bio, BIO_FLAGS_READ);
|
||||||
|
|
||||||
|
DWORD readBytes;
|
||||||
|
BOOL ret = ReadFile(ptr->hFile, buf, size, &readBytes, NULL);
|
||||||
|
WLog_VRB(TAG, "transport_bio_named_read(%d)=%d read=%d", size, ret, readBytes);
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
if (GetLastError() == ERROR_NO_DATA)
|
||||||
|
BIO_set_flags(bio, (BIO_FLAGS_SHOULD_RETRY | BIO_FLAGS_READ));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readBytes == 0)
|
||||||
|
{
|
||||||
|
BIO_set_flags(bio, (BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return readBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int transport_bio_named_puts(BIO* bio, const char* str)
|
||||||
|
{
|
||||||
|
WINPR_ASSERT(bio);
|
||||||
|
WINPR_ASSERT(str);
|
||||||
|
|
||||||
|
return transport_bio_named_write(bio, str, strlen(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int transport_bio_named_gets(BIO* bio, char* str, int size)
|
||||||
|
{
|
||||||
|
WINPR_ASSERT(bio);
|
||||||
|
WINPR_ASSERT(str);
|
||||||
|
|
||||||
|
return transport_bio_named_write(bio, str, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static long transport_bio_named_ctrl(BIO* bio, int cmd, long arg1, void* arg2)
|
||||||
|
{
|
||||||
|
WINPR_ASSERT(bio);
|
||||||
|
|
||||||
|
int status = -1;
|
||||||
|
WINPR_BIO_NAMED* ptr = (WINPR_BIO_NAMED*)BIO_get_data(bio);
|
||||||
|
|
||||||
|
switch (cmd)
|
||||||
|
{
|
||||||
|
case BIO_C_SET_SOCKET:
|
||||||
|
case BIO_C_GET_SOCKET:
|
||||||
|
return -1;
|
||||||
|
case BIO_C_GET_EVENT:
|
||||||
|
if (!BIO_get_init(bio) || !arg2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
*((HANDLE*)arg2) = ptr->hFile;
|
||||||
|
return 1;
|
||||||
|
case BIO_C_SET_HANDLE:
|
||||||
|
BIO_set_init(bio, 1);
|
||||||
|
if (!BIO_get_init(bio) || !arg2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ptr->hFile = (HANDLE)arg2;
|
||||||
|
return 1;
|
||||||
|
case BIO_C_SET_NONBLOCK:
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
case BIO_C_WAIT_READ:
|
||||||
|
{
|
||||||
|
int timeout = (int)arg1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BIO_C_WAIT_WRITE:
|
||||||
|
{
|
||||||
|
int timeout = (int)arg1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (cmd)
|
||||||
|
{
|
||||||
|
case BIO_CTRL_GET_CLOSE:
|
||||||
|
status = BIO_get_shutdown(bio);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BIO_CTRL_SET_CLOSE:
|
||||||
|
BIO_set_shutdown(bio, (int)arg1);
|
||||||
|
status = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BIO_CTRL_DUP:
|
||||||
|
status = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BIO_CTRL_FLUSH:
|
||||||
|
status = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
status = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int transport_bio_named_uninit(BIO* bio)
|
||||||
|
{
|
||||||
|
WINPR_ASSERT(bio);
|
||||||
|
WINPR_BIO_NAMED* ptr = (WINPR_BIO_NAMED*)BIO_get_data(bio);
|
||||||
|
|
||||||
|
if (ptr && ptr->hFile)
|
||||||
|
{
|
||||||
|
CloseHandle(ptr->hFile);
|
||||||
|
ptr->hFile = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BIO_set_init(bio, 0);
|
||||||
|
BIO_set_flags(bio, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int transport_bio_named_new(BIO* bio)
|
||||||
|
{
|
||||||
|
WINPR_ASSERT(bio);
|
||||||
|
BIO_set_flags(bio, BIO_FLAGS_SHOULD_RETRY);
|
||||||
|
|
||||||
|
WINPR_BIO_NAMED* ptr = (WINPR_BIO_NAMED*)calloc(1, sizeof(WINPR_BIO_NAMED));
|
||||||
|
if (!ptr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
BIO_set_data(bio, ptr);
|
||||||
|
BIO_set_flags(bio, BIO_FLAGS_SHOULD_RETRY);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int transport_bio_named_free(BIO* bio)
|
||||||
|
{
|
||||||
|
WINPR_BIO_NAMED* ptr;
|
||||||
|
|
||||||
|
if (!bio)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
transport_bio_named_uninit(bio);
|
||||||
|
ptr = (WINPR_BIO_NAMED*)BIO_get_data(bio);
|
||||||
|
|
||||||
|
if (ptr)
|
||||||
|
{
|
||||||
|
BIO_set_data(bio, NULL);
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
BIO_METHOD* BIO_s_namedpipe(void)
|
||||||
|
{
|
||||||
|
static BIO_METHOD* bio_methods = NULL;
|
||||||
|
|
||||||
|
if (bio_methods == NULL)
|
||||||
|
{
|
||||||
|
if (!(bio_methods = BIO_meth_new(BIO_TYPE_NAMEDPIPE, "NamedPipe")))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
BIO_meth_set_write(bio_methods, transport_bio_named_write);
|
||||||
|
BIO_meth_set_read(bio_methods, transport_bio_named_read);
|
||||||
|
BIO_meth_set_puts(bio_methods, transport_bio_named_puts);
|
||||||
|
BIO_meth_set_gets(bio_methods, transport_bio_named_gets);
|
||||||
|
BIO_meth_set_ctrl(bio_methods, transport_bio_named_ctrl);
|
||||||
|
BIO_meth_set_create(bio_methods, transport_bio_named_new);
|
||||||
|
BIO_meth_set_destroy(bio_methods, transport_bio_named_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bio_methods;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef NTSTATUS (*WinStationCreateChildSessionTransportFn)(WCHAR* path, DWORD len);
|
||||||
|
BOOL createChildSessionTransport(HANDLE* pFile)
|
||||||
|
{
|
||||||
|
WINPR_ASSERT(pFile);
|
||||||
|
|
||||||
|
HANDLE hModule = NULL;
|
||||||
|
BOOL ret = FALSE;
|
||||||
|
*pFile = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
|
BOOL childEnabled;
|
||||||
|
if (!WTSIsChildSessionsEnabled(&childEnabled))
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "error when calling WTSIsChildSessionsEnabled");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!childEnabled)
|
||||||
|
{
|
||||||
|
WLog_INFO(TAG, "child sessions aren't enabled");
|
||||||
|
if (!WTSEnableChildSessions(TRUE))
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "error when calling WTSEnableChildSessions");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
WLog_INFO(TAG, "successfully enabled child sessions");
|
||||||
|
}
|
||||||
|
|
||||||
|
hModule = LoadLibraryA("winsta.dll");
|
||||||
|
if (!hModule)
|
||||||
|
return FALSE;
|
||||||
|
WCHAR pipePath[0x80] = { 0 };
|
||||||
|
char pipePathA[0x80] = { 0 };
|
||||||
|
|
||||||
|
WinStationCreateChildSessionTransportFn createChildSessionFn =
|
||||||
|
(WinStationCreateChildSessionTransportFn)GetProcAddress(
|
||||||
|
hModule, "WinStationCreateChildSessionTransport");
|
||||||
|
if (!createChildSessionFn)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "unable to retrieve WinStationCreateChildSessionTransport function");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT hStatus = createChildSessionFn(pipePath, 0x80);
|
||||||
|
if (!SUCCEEDED(hStatus))
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "error 0x%x when creating childSessionTransport", hStatus);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConvertWCharNToUtf8(pipePath, 0x80, pipePathA, sizeof(pipePathA));
|
||||||
|
WLog_DBG(TAG, "child session is at '%s'", pipePathA);
|
||||||
|
|
||||||
|
HANDLE f = CreateFileW(pipePath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
if (f == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "error when connecting to local named pipe");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pFile = f;
|
||||||
|
ret = TRUE;
|
||||||
|
|
||||||
|
out:
|
||||||
|
FreeLibrary(hModule);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
BIO* createChildSessionBio(void)
|
||||||
|
{
|
||||||
|
HANDLE f = INVALID_HANDLE_VALUE;
|
||||||
|
if (!createChildSessionTransport(&f))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
BIO* lowLevelBio = BIO_new(BIO_s_namedpipe());
|
||||||
|
if (!lowLevelBio)
|
||||||
|
{
|
||||||
|
CloseHandle(f);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BIO_set_handle(lowLevelBio, f);
|
||||||
|
BIO* bufferedBio = BIO_new(BIO_s_buffered_socket());
|
||||||
|
|
||||||
|
if (!bufferedBio)
|
||||||
|
{
|
||||||
|
BIO_free_all(lowLevelBio);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufferedBio = BIO_push(bufferedBio, lowLevelBio);
|
||||||
|
|
||||||
|
return bufferedBio;
|
||||||
|
}
|
27
libfreerdp/core/childsession.h
Normal file
27
libfreerdp/core/childsession.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||||
|
* Connecting to windows child session
|
||||||
|
*
|
||||||
|
* Copyright 2023 David Fort <contact@hardening-consulting.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FREERDP_LIB_CORE_CHILDSESSION_H
|
||||||
|
#define FREERDP_LIB_CORE_CHILDSESSION_H
|
||||||
|
|
||||||
|
#include <openssl/bio.h>
|
||||||
|
|
||||||
|
FREERDP_LOCAL BIO* createChildSessionBio(void);
|
||||||
|
|
||||||
|
#endif /* FREERDP_LIB_CORE_CHILDSESSION_H */
|
@ -393,6 +393,7 @@ BOOL rdp_client_connect(rdpRdp* rdp)
|
|||||||
if (!status)
|
if (!status)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
nego_set_childsession_enabled(rdp->nego, settings->ConnectChildSession);
|
||||||
nego_set_send_preconnection_pdu(rdp->nego, settings->SendPreconnectionPdu);
|
nego_set_send_preconnection_pdu(rdp->nego, settings->SendPreconnectionPdu);
|
||||||
nego_set_preconnection_id(rdp->nego, settings->PreconnectionId);
|
nego_set_preconnection_id(rdp->nego, settings->PreconnectionId);
|
||||||
nego_set_preconnection_blob(rdp->nego, settings->PreconnectionBlob);
|
nego_set_preconnection_blob(rdp->nego, settings->PreconnectionBlob);
|
||||||
@ -421,7 +422,6 @@ BOOL rdp_client_connect(rdpRdp* rdp)
|
|||||||
|
|
||||||
if (!freerdp_settings_get_bool(settings, FreeRDP_TransportDumpReplay))
|
if (!freerdp_settings_get_bool(settings, FreeRDP_TransportDumpReplay))
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_NEGO))
|
if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_NEGO))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -62,6 +62,7 @@ struct rdp_nego
|
|||||||
BOOL RestrictedAdminModeRequired;
|
BOOL RestrictedAdminModeRequired;
|
||||||
BOOL GatewayEnabled;
|
BOOL GatewayEnabled;
|
||||||
BOOL GatewayBypassLocal;
|
BOOL GatewayBypassLocal;
|
||||||
|
BOOL ConnectChildSession;
|
||||||
|
|
||||||
rdpTransport* transport;
|
rdpTransport* transport;
|
||||||
};
|
};
|
||||||
@ -89,6 +90,7 @@ static const char* protocol_security_string(UINT32 security)
|
|||||||
return PROTOCOL_SECURITY_STRINGS[security];
|
return PROTOCOL_SECURITY_STRINGS[security];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL nego_tcp_connect(rdpNego* nego);
|
||||||
static BOOL nego_transport_connect(rdpNego* nego);
|
static BOOL nego_transport_connect(rdpNego* nego);
|
||||||
static BOOL nego_transport_disconnect(rdpNego* nego);
|
static BOOL nego_transport_disconnect(rdpNego* nego);
|
||||||
static BOOL nego_security_connect(rdpNego* nego);
|
static BOOL nego_security_connect(rdpNego* nego);
|
||||||
@ -99,31 +101,6 @@ static BOOL nego_process_negotiation_request(rdpNego* nego, wStream* s);
|
|||||||
static BOOL nego_process_negotiation_response(rdpNego* nego, wStream* s);
|
static BOOL nego_process_negotiation_response(rdpNego* nego, wStream* s);
|
||||||
static BOOL nego_process_negotiation_failure(rdpNego* nego, wStream* s);
|
static BOOL nego_process_negotiation_failure(rdpNego* nego, wStream* s);
|
||||||
|
|
||||||
static UINT32 nego_get_next_selected_protocol(rdpNego* nego)
|
|
||||||
{
|
|
||||||
WINPR_ASSERT(nego);
|
|
||||||
|
|
||||||
if (nego->EnabledProtocols[PROTOCOL_RDSAAD])
|
|
||||||
return PROTOCOL_RDSAAD;
|
|
||||||
|
|
||||||
if (nego->EnabledProtocols[PROTOCOL_RDSTLS])
|
|
||||||
return PROTOCOL_RDSTLS;
|
|
||||||
|
|
||||||
if (nego->EnabledProtocols[PROTOCOL_HYBRID_EX] || nego->EnabledProtocols[PROTOCOL_HYBRID])
|
|
||||||
return PROTOCOL_HYBRID_EX;
|
|
||||||
|
|
||||||
if (nego->EnabledProtocols[PROTOCOL_HYBRID])
|
|
||||||
return PROTOCOL_HYBRID;
|
|
||||||
|
|
||||||
if (nego->EnabledProtocols[PROTOCOL_SSL])
|
|
||||||
return PROTOCOL_SSL;
|
|
||||||
|
|
||||||
if (nego->EnabledProtocols[PROTOCOL_RDP])
|
|
||||||
return PROTOCOL_RDP;
|
|
||||||
|
|
||||||
WLog_ERR(TAG, "Invalid NEGO state 0x%08" PRIx32, nego_get_state(nego));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Negotiate protocol security and connect.
|
* Negotiate protocol security and connect.
|
||||||
*
|
*
|
||||||
@ -222,6 +199,12 @@ BOOL nego_connect(rdpNego* nego)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!nego_tcp_connect(nego))
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "Failed to connect");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (nego->SendPreconnectionPdu)
|
if (nego->SendPreconnectionPdu)
|
||||||
{
|
{
|
||||||
if (!nego_send_preconnection_pdu(nego))
|
if (!nego_send_preconnection_pdu(nego))
|
||||||
@ -391,6 +374,10 @@ static BOOL nego_tcp_connect(rdpNego* nego)
|
|||||||
TcpConnectTimeout);
|
TcpConnectTimeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (nego->ConnectChildSession)
|
||||||
|
{
|
||||||
|
nego->TcpConnected = transport_connect_childsession(nego->transport);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nego->TcpConnected =
|
nego->TcpConnected =
|
||||||
@ -1661,6 +1648,12 @@ void nego_set_restricted_admin_mode_required(rdpNego* nego, BOOL RestrictedAdmin
|
|||||||
nego->RestrictedAdminModeRequired = RestrictedAdminModeRequired;
|
nego->RestrictedAdminModeRequired = RestrictedAdminModeRequired;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nego_set_childsession_enabled(rdpNego* nego, BOOL ChildSessionEnabled)
|
||||||
|
{
|
||||||
|
WINPR_ASSERT(nego);
|
||||||
|
nego->ConnectChildSession = ChildSessionEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
void nego_set_gateway_enabled(rdpNego* nego, BOOL GatewayEnabled)
|
void nego_set_gateway_enabled(rdpNego* nego, BOOL GatewayEnabled)
|
||||||
{
|
{
|
||||||
nego->GatewayEnabled = GatewayEnabled;
|
nego->GatewayEnabled = GatewayEnabled;
|
||||||
|
@ -114,6 +114,7 @@ FREERDP_LOCAL BOOL nego_set_target(rdpNego* nego, const char* hostname, UINT16 p
|
|||||||
FREERDP_LOCAL void nego_set_negotiation_enabled(rdpNego* nego, BOOL NegotiateSecurityLayer);
|
FREERDP_LOCAL void nego_set_negotiation_enabled(rdpNego* nego, BOOL NegotiateSecurityLayer);
|
||||||
FREERDP_LOCAL void nego_set_restricted_admin_mode_required(rdpNego* nego,
|
FREERDP_LOCAL void nego_set_restricted_admin_mode_required(rdpNego* nego,
|
||||||
BOOL RestrictedAdminModeRequired);
|
BOOL RestrictedAdminModeRequired);
|
||||||
|
FREERDP_LOCAL void nego_set_childsession_enabled(rdpNego* nego, BOOL ChildSessionEnabled);
|
||||||
FREERDP_LOCAL void nego_set_gateway_enabled(rdpNego* nego, BOOL GatewayEnabled);
|
FREERDP_LOCAL void nego_set_gateway_enabled(rdpNego* nego, BOOL GatewayEnabled);
|
||||||
FREERDP_LOCAL void nego_set_gateway_bypass_local(rdpNego* nego, BOOL GatewayBypassLocal);
|
FREERDP_LOCAL void nego_set_gateway_bypass_local(rdpNego* nego, BOOL GatewayBypassLocal);
|
||||||
FREERDP_LOCAL void nego_enable_rdp(rdpNego* nego, BOOL enable_rdp);
|
FREERDP_LOCAL void nego_enable_rdp(rdpNego* nego, BOOL enable_rdp);
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#define BIO_TYPE_TSG 65
|
#define BIO_TYPE_TSG 65
|
||||||
#define BIO_TYPE_SIMPLE 66
|
#define BIO_TYPE_SIMPLE 66
|
||||||
#define BIO_TYPE_BUFFERED 67
|
#define BIO_TYPE_BUFFERED 67
|
||||||
|
#define BIO_TYPE_NAMEDPIPE 69
|
||||||
|
|
||||||
#define BIO_C_SET_SOCKET 1101
|
#define BIO_C_SET_SOCKET 1101
|
||||||
#define BIO_C_GET_SOCKET 1102
|
#define BIO_C_GET_SOCKET 1102
|
||||||
@ -50,10 +51,12 @@
|
|||||||
#define BIO_C_WRITE_BLOCKED 1106
|
#define BIO_C_WRITE_BLOCKED 1106
|
||||||
#define BIO_C_WAIT_READ 1107
|
#define BIO_C_WAIT_READ 1107
|
||||||
#define BIO_C_WAIT_WRITE 1108
|
#define BIO_C_WAIT_WRITE 1108
|
||||||
|
#define BIO_C_SET_HANDLE 1109
|
||||||
|
|
||||||
#define BIO_set_socket(b, s, c) BIO_ctrl(b, BIO_C_SET_SOCKET, c, s);
|
#define BIO_set_socket(b, s, c) BIO_ctrl(b, BIO_C_SET_SOCKET, c, s);
|
||||||
#define BIO_get_socket(b, c) BIO_ctrl(b, BIO_C_GET_SOCKET, 0, (char*)c)
|
#define BIO_get_socket(b, c) BIO_ctrl(b, BIO_C_GET_SOCKET, 0, (char*)c)
|
||||||
#define BIO_get_event(b, c) BIO_ctrl(b, BIO_C_GET_EVENT, 0, (char*)c)
|
#define BIO_get_event(b, c) BIO_ctrl(b, BIO_C_GET_EVENT, 0, (char*)c)
|
||||||
|
#define BIO_set_handle(b, h) BIO_ctrl(b, BIO_C_SET_HANDLE, 0, h)
|
||||||
#define BIO_set_nonblock(b, c) BIO_ctrl(b, BIO_C_SET_NONBLOCK, c, NULL)
|
#define BIO_set_nonblock(b, c) BIO_ctrl(b, BIO_C_SET_NONBLOCK, c, NULL)
|
||||||
#define BIO_read_blocked(b) BIO_ctrl(b, BIO_C_READ_BLOCKED, 0, NULL)
|
#define BIO_read_blocked(b) BIO_ctrl(b, BIO_C_READ_BLOCKED, 0, NULL)
|
||||||
#define BIO_write_blocked(b) BIO_ctrl(b, BIO_C_WRITE_BLOCKED, 0, NULL)
|
#define BIO_write_blocked(b) BIO_ctrl(b, BIO_C_WRITE_BLOCKED, 0, NULL)
|
||||||
|
@ -25,6 +25,7 @@ static const size_t bool_list_indices[] = {
|
|||||||
FreeRDP_BitmapCompressionDisabled,
|
FreeRDP_BitmapCompressionDisabled,
|
||||||
FreeRDP_CertificateCallbackPreferPEM,
|
FreeRDP_CertificateCallbackPreferPEM,
|
||||||
FreeRDP_CompressionEnabled,
|
FreeRDP_CompressionEnabled,
|
||||||
|
FreeRDP_ConnectChildSession,
|
||||||
FreeRDP_ConsoleSession,
|
FreeRDP_ConsoleSession,
|
||||||
FreeRDP_CredentialsFromStdin,
|
FreeRDP_CredentialsFromStdin,
|
||||||
FreeRDP_DeactivateClientDecoding,
|
FreeRDP_DeactivateClientDecoding,
|
||||||
|
@ -53,6 +53,7 @@
|
|||||||
#include "proxy.h"
|
#include "proxy.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "state.h"
|
#include "state.h"
|
||||||
|
#include "childsession.h"
|
||||||
|
|
||||||
#include "gateway/rdg.h"
|
#include "gateway/rdg.h"
|
||||||
#include "gateway/wst.h"
|
#include "gateway/wst.h"
|
||||||
@ -578,6 +579,18 @@ BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 por
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL transport_connect_childsession(rdpTransport* transport)
|
||||||
|
{
|
||||||
|
WINPR_ASSERT(transport);
|
||||||
|
|
||||||
|
transport->frontBio = createChildSessionBio();
|
||||||
|
if (!transport->frontBio)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
transport->layer = TRANSPORT_LAYER_TSG;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL transport_accept_rdp(rdpTransport* transport)
|
BOOL transport_accept_rdp(rdpTransport* transport)
|
||||||
{
|
{
|
||||||
if (!transport)
|
if (!transport)
|
||||||
|
@ -24,6 +24,7 @@ typedef enum
|
|||||||
{
|
{
|
||||||
TRANSPORT_LAYER_TCP,
|
TRANSPORT_LAYER_TCP,
|
||||||
TRANSPORT_LAYER_TLS,
|
TRANSPORT_LAYER_TLS,
|
||||||
|
TRANSPORT_LAYER_NAMEDPIPE,
|
||||||
TRANSPORT_LAYER_TSG,
|
TRANSPORT_LAYER_TSG,
|
||||||
TRANSPORT_LAYER_TSG_TLS,
|
TRANSPORT_LAYER_TSG_TLS,
|
||||||
TRANSPORT_LAYER_CLOSED
|
TRANSPORT_LAYER_CLOSED
|
||||||
@ -56,6 +57,7 @@ typedef state_run_t (*TransportRecv)(rdpTransport* transport, wStream* stream, v
|
|||||||
FREERDP_LOCAL wStream* transport_send_stream_init(rdpTransport* transport, size_t size);
|
FREERDP_LOCAL wStream* transport_send_stream_init(rdpTransport* transport, size_t size);
|
||||||
FREERDP_LOCAL BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 port,
|
FREERDP_LOCAL BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 port,
|
||||||
DWORD timeout);
|
DWORD timeout);
|
||||||
|
FREERDP_LOCAL BOOL transport_connect_childsession(rdpTransport* transport);
|
||||||
FREERDP_LOCAL BOOL transport_attach(rdpTransport* transport, int sockfd);
|
FREERDP_LOCAL BOOL transport_attach(rdpTransport* transport, int sockfd);
|
||||||
FREERDP_LOCAL BOOL transport_disconnect(rdpTransport* transport);
|
FREERDP_LOCAL BOOL transport_disconnect(rdpTransport* transport);
|
||||||
FREERDP_LOCAL BOOL transport_connect_rdp(rdpTransport* transport);
|
FREERDP_LOCAL BOOL transport_connect_rdp(rdpTransport* transport);
|
||||||
|
@ -148,6 +148,9 @@ auth_status utils_authenticate(freerdp* instance, rdp_auth_reason reason, BOOL o
|
|||||||
if (freerdp_shall_disconnect_context(instance->context))
|
if (freerdp_shall_disconnect_context(instance->context))
|
||||||
return AUTH_FAILED;
|
return AUTH_FAILED;
|
||||||
|
|
||||||
|
if (settings->ConnectChildSession)
|
||||||
|
return AUTH_NO_CREDENTIALS;
|
||||||
|
|
||||||
/* Ask for auth data if no or an empty username was specified or no password was given */
|
/* Ask for auth data if no or an empty username was specified or no password was given */
|
||||||
if (utils_str_is_empty(freerdp_settings_get_string(settings, FreeRDP_Username)) ||
|
if (utils_str_is_empty(freerdp_settings_get_string(settings, FreeRDP_Username)) ||
|
||||||
(settings->Password == NULL && settings->RedirectionPassword == NULL))
|
(settings->Password == NULL && settings->RedirectionPassword == NULL))
|
||||||
|
Loading…
Reference in New Issue
Block a user