libfreerdp-core: add spn-class option

This commit is contained in:
Marc-André Moreau 2014-02-12 00:43:02 -05:00
parent 0a2af868ef
commit 8a44b2baa6
8 changed files with 86 additions and 5 deletions

View File

@ -124,6 +124,7 @@ COMMAND_LINE_ARGUMENT_A args[] =
{ "cert-ignore", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "ignore certificate" },
{ "pcb", COMMAND_LINE_VALUE_REQUIRED, "<blob>", NULL, NULL, -1, NULL, "Preconnection Blob" },
{ "pcid", COMMAND_LINE_VALUE_REQUIRED, "<id>", NULL, NULL, -1, NULL, "Preconnection Id" },
{ "spn-class", COMMAND_LINE_VALUE_REQUIRED, "<service class>", NULL, NULL, -1, NULL, "SPN authentication service class" },
{ "vmconnect", COMMAND_LINE_VALUE_OPTIONAL, "<vmid>", NULL, NULL, -1, NULL, "Hyper-V console (use port 2179, disable negotiation)" },
{ "authentication", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "authentication (hack!)" },
{ "encryption", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "encryption (hack!)" },
@ -1138,6 +1139,10 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
settings->ServerHostname = _strdup(arg->Value);
}
}
CommandLineSwitchCase(arg, "spn-class")
{
settings->AuthenticationServiceClass = _strdup(arg->Value);
}
CommandLineSwitchCase(arg, "vmconnect")
{
settings->ServerPort = 2179;

View File

@ -597,6 +597,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL;
#define FreeRDP_NegotiationFlags 1095
#define FreeRDP_NegotiateSecurityLayer 1096
#define FreeRDP_RestrictedAdminModeRequired 1097
#define FreeRDP_AuthenticationServiceClass 1098
#define FreeRDP_MstscCookieMode 1152
#define FreeRDP_CookieMaxLength 1153
#define FreeRDP_PreconnectionId 1154
@ -948,7 +949,8 @@ struct rdp_settings
ALIGN64 UINT32 NegotiationFlags; /* 1095 */
ALIGN64 BOOL NegotiateSecurityLayer; /* 1096 */
ALIGN64 BOOL RestrictedAdminModeRequired; /* 1097 */
UINT64 padding1152[1152 - 1098]; /* 1098 */
ALIGN64 char* AuthenticationServiceClass; /* 1098 */
UINT64 padding1152[1152 - 1099]; /* 1099 */
/* Connection Cookie */
ALIGN64 BOOL MstscCookieMode; /* 1152 */

View File

@ -2137,6 +2137,10 @@ char* freerdp_get_param_string(rdpSettings* settings, int id)
return settings->DynamicDSTTimeZoneKeyName;
break;
case FreeRDP_AuthenticationServiceClass:
return settings->AuthenticationServiceClass;
break;
case FreeRDP_PreconnectionBlob:
return settings->PreconnectionBlob;
break;
@ -2317,6 +2321,11 @@ int freerdp_set_param_string(rdpSettings* settings, int id, const char* param)
settings->DynamicDSTTimeZoneKeyName = _strdup(param);
break;
case FreeRDP_AuthenticationServiceClass:
free(settings->AuthenticationServiceClass);
settings->AuthenticationServiceClass = _strdup(param);
break;
case FreeRDP_PreconnectionBlob:
free(settings->PreconnectionBlob);
settings->PreconnectionBlob = _strdup(param);

View File

@ -161,7 +161,6 @@ int rpc_ncacn_http_ntlm_init(rdpRpc* rpc, TSG_CHANNEL channel)
return 0;
}
//ntlm_client_make_spn(ntlm, NULL, settings->GatewayHostname);
if (!ntlm_client_make_spn(ntlm, _T("HTTP"), settings->GatewayHostname))
{
return 0;

View File

@ -33,6 +33,7 @@
#include <winpr/sspi.h>
#include <winpr/print.h>
#include <winpr/tchar.h>
#include <winpr/dsparse.h>
#include <winpr/library.h>
#include <winpr/registry.h>
@ -1315,6 +1316,59 @@ void credssp_buffer_free(rdpCredssp* credssp)
sspi_SecBufferFree(&credssp->authInfo);
}
LPTSTR credssp_make_spn(const char* ServiceClass, const char* hostname)
{
DWORD status;
DWORD SpnLength;
LPTSTR hostnameX = NULL;
LPTSTR ServiceClassX = NULL;
LPTSTR ServicePrincipalName = NULL;
#ifdef UNICODE
ConvertToUnicode(CP_UTF8, 0, hostname, -1, &hostnameX, 0);
ConvertToUnicode(CP_UTF8, 0, ServiceClass, -1, &ServiceClassX, 0);
#else
hostnameX = _strdup(hostname);
ServiceClassX = _strdup(ServiceClass);
#endif
if (!ServiceClass)
{
ServicePrincipalName = (LPTSTR) _tcsdup(hostnameX);
free(ServiceClassX);
free(hostnameX);
return ServicePrincipalName;
}
SpnLength = 0;
status = DsMakeSpn(ServiceClassX, hostnameX, NULL, 0, NULL, &SpnLength, NULL);
if (status != ERROR_BUFFER_OVERFLOW)
{
free(ServiceClassX);
free(hostnameX);
return NULL;
}
ServicePrincipalName = (LPTSTR) malloc(SpnLength * sizeof(TCHAR));
status = DsMakeSpn(ServiceClassX, hostnameX, NULL, 0, NULL, &SpnLength, ServicePrincipalName);
if (status != ERROR_SUCCESS)
{
free(ServicePrincipalName);
free(ServiceClassX);
free(hostnameX);
return NULL;
}
free(ServiceClassX);
free(hostnameX);
return ServicePrincipalName;
}
/**
* Create new CredSSP state machine.
* @param transport
@ -1326,15 +1380,16 @@ rdpCredssp* credssp_new(freerdp* instance, rdpTransport* transport, rdpSettings*
rdpCredssp* credssp;
credssp = (rdpCredssp*) malloc(sizeof(rdpCredssp));
ZeroMemory(credssp, sizeof(rdpCredssp));
if (credssp != NULL)
if (credssp)
{
HKEY hKey;
LONG status;
DWORD dwType;
DWORD dwSize;
ZeroMemory(credssp, sizeof(rdpCredssp));
credssp->instance = instance;
credssp->settings = settings;
credssp->server = settings->ServerMode;
@ -1382,7 +1437,7 @@ rdpCredssp* credssp_new(freerdp* instance, rdpTransport* transport, rdpSettings*
void credssp_free(rdpCredssp* credssp)
{
if (credssp != NULL)
if (credssp)
{
if (credssp->table)
credssp->table->DeleteSecurityContext(&credssp->context);

View File

@ -58,6 +58,7 @@ struct rdp_credssp
};
int credssp_authenticate(rdpCredssp* credssp);
LPTSTR credssp_make_spn(const char* ServiceClass, const char* hostname);
rdpCredssp* credssp_new(freerdp* instance, rdpTransport* transport, rdpSettings* settings);
void credssp_free(rdpCredssp* credssp);

View File

@ -453,6 +453,7 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings)
_settings->ClientAddress = _strdup(settings->ClientAddress); /* 769 */
_settings->ClientDir = _strdup(settings->ClientDir); /* 770 */
_settings->DynamicDSTTimeZoneKeyName = _strdup(settings->DynamicDSTTimeZoneKeyName); /* 897 */
_settings->AuthenticationServiceClass = _strdup(settings->AuthenticationServiceClass); /* 1098 */
_settings->PreconnectionBlob = _strdup(settings->PreconnectionBlob); /* 1155 */
_settings->KerberosKdc = _strdup(settings->KerberosKdc); /* 1344 */
_settings->KerberosRealm = _strdup(settings->KerberosRealm); /* 1345 */
@ -820,6 +821,7 @@ void freerdp_settings_free(rdpSettings* settings)
free(settings->RedirectionDomain);
free(settings->RedirectionPassword);
free(settings->RedirectionTsvUrl);
free(settings->AuthenticationServiceClass);
freerdp_target_net_addresses_free(settings);
freerdp_device_collection_free(settings);
freerdp_static_channel_collection_free(settings);

View File

@ -292,8 +292,16 @@ BOOL transport_connect_nla(rdpTransport* transport)
return TRUE;
if (!transport->credssp)
{
transport->credssp = credssp_new(instance, transport, settings);
if (settings->AuthenticationServiceClass)
{
transport->credssp->ServicePrincipalName =
credssp_make_spn(settings->AuthenticationServiceClass, settings->ServerHostname);
}
}
if (credssp_authenticate(transport->credssp) < 0)
{
if (!connectErrorCode)