freerdp: add restricted admin option

This commit is contained in:
Marc-André Moreau 2013-11-06 01:51:55 -05:00
parent f38c73b6c1
commit a3d0e271b5
8 changed files with 65 additions and 3 deletions

View File

@ -51,6 +51,7 @@ COMMAND_LINE_ARGUMENT_A args[] =
{ "kbd-subtype", COMMAND_LINE_VALUE_REQUIRED, "<subtype id>", NULL, NULL, -1, NULL, "Keyboard subtype" },
{ "kbd-fn-key", COMMAND_LINE_VALUE_REQUIRED, "<function key count>", NULL, NULL, -1, NULL, "Keyboard function key count" },
{ "admin", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, "console", "Admin (or console) session" },
{ "restricted-admin", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, "restrictedAdmin", "Restricted admin mode" },
{ "multimon", COMMAND_LINE_VALUE_OPTIONAL, NULL, NULL, NULL, -1, NULL, "Use multiple monitors" },
{ "workarea", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "Use available work area" },
{ "monitors", COMMAND_LINE_VALUE_REQUIRED, "<0,1,2...>", NULL, NULL, -1, NULL, "Select monitors to use" },
@ -1231,6 +1232,11 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
{
settings->ConsoleSession = TRUE;
}
CommandLineSwitchCase(arg, "restricted-admin")
{
settings->ConsoleSession = TRUE;
settings->RestrictedAdminModeRequired = TRUE;
}
CommandLineSwitchCase(arg, "kbd")
{
int id;

View File

@ -562,6 +562,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL;
#define FreeRDP_SelectedProtocol 1094
#define FreeRDP_NegotiationFlags 1095
#define FreeRDP_NegotiateSecurityLayer 1096
#define FreeRDP_RestrictedAdminModeRequired 1097
#define FreeRDP_MstscCookieMode 1152
#define FreeRDP_CookieMaxLength 1153
#define FreeRDP_PreconnectionId 1154
@ -907,7 +908,8 @@ struct rdp_settings
ALIGN64 UINT32 SelectedProtocol; /* 1094 */
ALIGN64 UINT32 NegotiationFlags; /* 1095 */
ALIGN64 BOOL NegotiateSecurityLayer; /* 1096 */
UINT64 padding1152[1152 - 1097]; /* 1097 */
ALIGN64 BOOL RestrictedAdminModeRequired; /* 1097 */
UINT64 padding1152[1152 - 1098]; /* 1098 */
/* Connection Cookie */
ALIGN64 BOOL MstscCookieMode; /* 1152 */

View File

@ -649,6 +649,10 @@ BOOL freerdp_get_param_bool(rdpSettings* settings, int id)
return settings->NegotiateSecurityLayer;
break;
case FreeRDP_RestrictedAdminModeRequired:
return settings->RestrictedAdminModeRequired;
break;
case FreeRDP_MstscCookieMode:
return settings->MstscCookieMode;
break;
@ -1109,6 +1113,10 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param)
settings->NegotiateSecurityLayer = param;
break;
case FreeRDP_RestrictedAdminModeRequired:
settings->RestrictedAdminModeRequired = param;
break;
case FreeRDP_MstscCookieMode:
settings->MstscCookieMode = param;
break;

View File

@ -228,6 +228,7 @@ BOOL rdp_client_connect(rdpRdp* rdp)
nego_set_preconnection_blob(rdp->nego, settings->PreconnectionBlob);
nego_set_negotiation_enabled(rdp->nego, settings->NegotiateSecurityLayer);
nego_set_restricted_admin_mode_required(rdp->nego, settings->RestrictedAdminModeRequired);
nego_enable_rdp(rdp->nego, settings->RdpSecurity);
nego_enable_tls(rdp->nego, settings->TlsSecurity);

View File

@ -669,6 +669,7 @@ BOOL nego_send_negotiation_request(rdpNego* nego)
wStream* s;
int length;
int bm, em;
BYTE flags = 0;
int cookie_length;
s = Stream_New(NULL, 512);
@ -703,8 +704,12 @@ BOOL nego_send_negotiation_request(rdpNego* nego)
if ((nego->requested_protocols > PROTOCOL_RDP) || (nego->sendNegoData))
{
/* RDP_NEG_DATA must be present for TLS and NLA */
if (nego->RestrictedAdminModeRequired)
flags |= RESTRICTED_ADMIN_MODE_REQUIRED;
Stream_Write_UINT8(s, TYPE_RDP_NEG_REQ);
Stream_Write_UINT8(s, 0); /* flags, must be set to zero */
Stream_Write_UINT8(s, flags);
Stream_Write_UINT16(s, 8); /* RDP_NEG_DATA length (8) */
Stream_Write_UINT32(s, nego->requested_protocols); /* requestedProtocols */
length += 8;
@ -1016,6 +1021,18 @@ void nego_set_negotiation_enabled(rdpNego* nego, BOOL NegotiateSecurityLayer)
nego->NegotiateSecurityLayer = NegotiateSecurityLayer;
}
/**
* Enable restricted admin mode.
* @param nego pointer to the negotiation structure
* @param enable_restricted whether to enable security layer negotiation (TRUE for enabled, FALSE for disabled)
*/
void nego_set_restricted_admin_mode_required(rdpNego* nego, BOOL RestrictedAdminModeRequired)
{
DEBUG_NEGO("Enabling restricted admin mode: %s", RestrictedAdminModeRequired ? "TRUE" : "FALSE");
nego->RestrictedAdminModeRequired = RestrictedAdminModeRequired;
}
/**
* Enable RDP security protocol.
* @param nego pointer to the negotiation structure
@ -1033,13 +1050,13 @@ void nego_enable_rdp(rdpNego* nego, BOOL enable_rdp)
* @param nego pointer to the negotiation structure
* @param enable_tls whether to enable TLS + RDP protocol (TRUE for enabled, FALSE for disabled)
*/
void nego_enable_tls(rdpNego* nego, BOOL enable_tls)
{
DEBUG_NEGO("Enabling TLS security: %s", enable_tls ? "TRUE" : "FALSE");
nego->enabled_protocols[PROTOCOL_TLS] = enable_tls;
}
/**
* Enable NLA security protocol.
* @param nego pointer to the negotiation structure

View File

@ -84,6 +84,9 @@ enum RDP_NEG_MSG
#define PRECONNECTION_PDU_V1 1
#define PRECONNECTION_PDU_V2 2
#define RESTRICTED_ADMIN_MODE_REQUIRED 0x01
#define CORRELATION_INFO_PRESENT 0x08
struct rdp_nego
{
int port;
@ -106,6 +109,7 @@ struct rdp_nego
UINT32 requested_protocols;
BOOL NegotiateSecurityLayer;
BYTE enabled_protocols[16];
BOOL RestrictedAdminModeRequired;
rdpTransport* transport;
};
@ -137,6 +141,7 @@ void nego_free(rdpNego* nego);
void nego_init(rdpNego* nego);
void nego_set_target(rdpNego* nego, char* hostname, int port);
void nego_set_negotiation_enabled(rdpNego* nego, BOOL NegotiateSecurityLayer_enabled);
void nego_set_restricted_admin_mode_required(rdpNego* nego, BOOL RestrictedAdminModeRequired);
void nego_enable_rdp(rdpNego* nego, BOOL enable_rdp);
void nego_enable_tls(rdpNego* nego, BOOL enable_tls);
void nego_enable_nla(rdpNego* nego, BOOL enable_nla);

View File

@ -939,6 +939,20 @@ void credssp_encode_ts_credentials(rdpCredssp* credssp)
{
wStream* s;
int length;
int DomainLength;
int UserLength;
int PasswordLength;
DomainLength = credssp->identity.DomainLength;
UserLength = credssp->identity.UserLength;
PasswordLength = credssp->identity.PasswordLength;
if (credssp->settings->RestrictedAdminModeRequired)
{
credssp->identity.DomainLength = 0;
credssp->identity.UserLength = 0;
credssp->identity.PasswordLength = 0;
}
length = ber_sizeof_sequence(credssp_sizeof_ts_credentials(credssp));
sspi_SecBufferAlloc(&credssp->ts_credentials, length);
@ -946,6 +960,13 @@ void credssp_encode_ts_credentials(rdpCredssp* credssp)
s = Stream_New(credssp->ts_credentials.pvBuffer, length);
credssp_write_ts_credentials(credssp, s);
if (credssp->settings->RestrictedAdminModeRequired)
{
credssp->identity.DomainLength = DomainLength;
credssp->identity.UserLength = UserLength;
credssp->identity.PasswordLength = PasswordLength;
}
Stream_Free(s, FALSE);
}

View File

@ -223,6 +223,7 @@ rdpSettings* freerdp_settings_new(DWORD flags)
settings->TlsSecurity = TRUE;
settings->RdpSecurity = TRUE;
settings->NegotiateSecurityLayer = TRUE;
settings->RestrictedAdminModeRequired = FALSE;
settings->MstscCookieMode = FALSE;
settings->CookieMaxLength = DEFAULT_COOKIE_MAX_LENGTH;
settings->ClientBuild = 2600;
@ -614,6 +615,7 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings)
_settings->ExtSecurity = settings->ExtSecurity; /* 1091 */
_settings->Authentication = settings->Authentication; /* 1092 */
_settings->NegotiateSecurityLayer = settings->NegotiateSecurityLayer; /* 1096 */
_settings->RestrictedAdminModeRequired = settings->RestrictedAdminModeRequired; /* 1097 */
_settings->MstscCookieMode = settings->MstscCookieMode; /* 1152 */
_settings->SendPreconnectionPdu = settings->SendPreconnectionPdu; /* 1156 */
_settings->IgnoreCertificate = settings->IgnoreCertificate; /* 1408 */