freerdp: add restricted admin option
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Wed, 6 Nov 2013 06:51:55 +0000 (01:51 -0500)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Wed, 6 Nov 2013 06:51:55 +0000 (01:51 -0500)
client/common/cmdline.c
include/freerdp/settings.h
libfreerdp/common/settings.c
libfreerdp/core/connection.c
libfreerdp/core/nego.c
libfreerdp/core/nego.h
libfreerdp/core/nla.c
libfreerdp/core/settings.c

index 6c28fdf..c38d6a9 100644 (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;
index 153dcbd..3844404 100644 (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 */
index e97a5b0..8341980 100644 (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;
index 220c135..e84bb8e 100644 (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);
index b2562b0..9c4f913 100644 (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;
@@ -1017,6 +1022,18 @@ void nego_set_negotiation_enabled(rdpNego* nego, BOOL 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
  * @param enable_rdp whether to enable normal RDP protocol (TRUE for enabled, FALSE for disabled)
@@ -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
index 7d3e08b..d82257f 100644 (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);
index 9fa35b4..56a3e51 100644 (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);
 }
 
index 700b0f2..9dbaf83 100644 (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 */