FreeRDP
nla.c File Reference
#include <freerdp/config.h>
#include "settings.h"
#include <time.h>
#include <ctype.h>
#include <freerdp/log.h>
#include <freerdp/build-config.h>
#include <winpr/crt.h>
#include <winpr/assert.h>
#include <winpr/sam.h>
#include <winpr/sspi.h>
#include <winpr/print.h>
#include <winpr/tchar.h>
#include <winpr/ncrypt.h>
#include <winpr/cred.h>
#include <winpr/debug.h>
#include <winpr/asn1.h>
#include <winpr/secapi.h>
#include "../crypto/tls.h"
#include "nego.h"
#include "rdp.h"
#include "nla.h"
#include "utils.h"
#include "credssp_auth.h"
#include <freerdp/utils/smartcardlogon.h>

Macros

#define TAG   FREERDP_TAG("core.nla")
 
#define SERVER_KEY   "Software\\" FREERDP_VENDOR_STRING "\\" FREERDP_PRODUCT_STRING "\\Server"
 
#define NLA_AUTH_PKG   NEGO_SSP_NAME
 
#define NLA_PKG_NAME   CREDSSP_AUTH_PKG_SPNEGO
 

Enumerations

enum  AUTHZ_RESULT { AUTHZ_SUCCESS = 0x00000000 , AUTHZ_ACCESS_DENIED = 0x00000005 }
 
enum  RemoteGuardPackageCredType { RCG_TYPE_KERB , RCG_TYPE_NTLM }
 kind of RCG credentials More...
 
enum  TsCredentialsType { TSCREDS_INVALID = 0 , TSCREDS_USER_PASSWD = 1 , TSCREDS_SMARTCARD = 2 , TSCREDS_REMOTEGUARD = 6 }
 kind of TSCreds More...
 

Functions

static BOOL nla_send (rdpNla *nla)
 
static int nla_server_recv (rdpNla *nla)
 
static BOOL nla_encrypt_public_key_echo (rdpNla *nla)
 
static BOOL nla_encrypt_public_key_hash (rdpNla *nla)
 
static BOOL nla_decrypt_public_key_echo (rdpNla *nla)
 
static BOOL nla_decrypt_public_key_hash (rdpNla *nla)
 
static BOOL nla_encrypt_ts_credentials (rdpNla *nla)
 
static BOOL nla_decrypt_ts_credentials (rdpNla *nla)
 
void nla_set_early_user_auth (rdpNla *nla, BOOL earlyUserAuth)
 
static void nla_buffer_free (rdpNla *nla)
 
static BOOL nla_Digest_Update_From_SecBuffer (WINPR_DIGEST_CTX *ctx, const SecBuffer *buffer)
 
static BOOL nla_sec_buffer_alloc (SecBuffer *buffer, size_t size)
 
static BOOL nla_sec_buffer_alloc_from_data (SecBuffer *buffer, const BYTE *data, size_t offset, size_t size)
 
static BOOL nla_adjust_settings_from_smartcard (rdpNla *nla)
 
static BOOL nla_client_setup_identity (rdpNla *nla)
 
static int nla_client_init (rdpNla *nla)
 
int nla_client_begin (rdpNla *nla)
 
static int nla_client_recv_nego_token (rdpNla *nla)
 
static int nla_client_recv_pub_key_auth (rdpNla *nla)
 
static int nla_client_recv_early_user_auth (rdpNla *nla)
 
static int nla_client_recv (rdpNla *nla)
 
static int nla_client_authenticate (rdpNla *nla)
 
static int nla_server_init (rdpNla *nla)
 
static wStreamnla_server_recv_stream (rdpNla *nla)
 
static BOOL nla_server_recv_credentials (rdpNla *nla)
 
static int nla_server_authenticate (rdpNla *nla)
 
int nla_authenticate (rdpNla *nla)
 
static void ap_integer_increment_le (BYTE *number, size_t size)
 
static void ap_integer_decrement_le (BYTE *number, size_t size)
 
static BOOL set_creds_octetstring_to_settings (WinPrAsn1Decoder *dec, WinPrAsn1_tagId tagId, BOOL optional, FreeRDP_Settings_Keys_String settingId, rdpSettings *settings)
 
static BOOL nla_read_TSCspDataDetail (WinPrAsn1Decoder *dec, rdpSettings *settings)
 
static BOOL nla_read_KERB_TICKET_LOGON (rdpNla *nla, wStream *s, KERB_TICKET_LOGON *ticket)
 
static BOOL nla_read_TSRemoteGuardPackageCred (rdpNla *nla, WinPrAsn1Decoder *dec, RemoteGuardPackageCredType *credsType, wStream *payload)
 
static BOOL nla_read_ts_credentials (rdpNla *nla, SecBuffer *data)
 
static BOOL nla_encode_ts_credentials (rdpNla *nla)
 
static BOOL nla_write_octet_string (WinPrAsn1Encoder *enc, const SecBuffer *buffer, WinPrAsn1_tagId tagId, const char *msg)
 
static BOOL nla_write_octet_string_free (WinPrAsn1Encoder *enc, SecBuffer *buffer, WinPrAsn1_tagId tagId, const char *msg)
 
static int nla_decode_ts_request (rdpNla *nla, wStream *s)
 
int nla_recv_pdu (rdpNla *nla, wStream *s)
 
rdpNla * nla_new (rdpContext *context, rdpTransport *transport)
 
void nla_free (rdpNla *nla)
 
SEC_WINNT_AUTH_IDENTITYnla_get_identity (rdpNla *nla)
 
NLA_STATE nla_get_state (rdpNla *nla)
 
BOOL nla_set_state (rdpNla *nla, NLA_STATE state)
 
BOOL nla_set_service_principal (rdpNla *nla, const char *service, const char *hostname)
 
BOOL nla_impersonate (rdpNla *nla)
 
BOOL nla_revert_to_self (rdpNla *nla)
 
const char * nla_get_state_str (NLA_STATE state)
 
DWORD nla_get_error (rdpNla *nla)
 
UINT32 nla_get_sspi_error (rdpNla *nla)
 

Variables

static const BYTE ClientServerHashMagic []
 
static const BYTE ServerClientHashMagic []
 
static const UINT32 NonceLength = 32
 

Macro Definition Documentation

◆ NLA_AUTH_PKG

#define NLA_AUTH_PKG   NEGO_SSP_NAME

◆ NLA_PKG_NAME

#define NLA_PKG_NAME   CREDSSP_AUTH_PKG_SPNEGO

TSRequest ::= SEQUENCE { version [0] INTEGER, negoTokens [1] NegoData OPTIONAL, authInfo [2] OCTET STRING OPTIONAL, pubKeyAuth [3] OCTET STRING OPTIONAL, errorCode [4] INTEGER OPTIONAL }

NegoData ::= SEQUENCE OF NegoDataItem

NegoDataItem ::= SEQUENCE { negoToken [0] OCTET STRING }

TSCredentials ::= SEQUENCE { credType [0] INTEGER, credentials [1] OCTET STRING }

TSPasswordCreds ::= SEQUENCE { domainName [0] OCTET STRING, userName [1] OCTET STRING, password [2] OCTET STRING }

TSSmartCardCreds ::= SEQUENCE { pin [0] OCTET STRING, cspData [1] TSCspDataDetail, userHint [2] OCTET STRING OPTIONAL, domainHint [3] OCTET STRING OPTIONAL }

TSCspDataDetail ::= SEQUENCE { keySpec [0] INTEGER, cardName [1] OCTET STRING OPTIONAL, readerName [2] OCTET STRING OPTIONAL, containerName [3] OCTET STRING OPTIONAL, cspName [4] OCTET STRING OPTIONAL }

◆ SERVER_KEY

#define SERVER_KEY   "Software\\" FREERDP_VENDOR_STRING "\\" FREERDP_PRODUCT_STRING "\\Server"

◆ TAG

#define TAG   FREERDP_TAG("core.nla")

FreeRDP: A Remote Desktop Protocol Implementation Network Level Authentication (NLA)

Copyright 2010-2012 Marc-Andre Moreau marca.nosp@m.ndre.nosp@m..more.nosp@m.au@g.nosp@m.mail..nosp@m.com Copyright 2015 Thincast Technologies GmbH Copyright 2015 DI (FH) Martin Haimberger marti.nosp@m.n.ha.nosp@m.imber.nosp@m.ger@.nosp@m.thinc.nosp@m.ast..nosp@m.com Copyright 2016 Martin Fleisz marti.nosp@m.n.fl.nosp@m.eisz@.nosp@m.thin.nosp@m.cast..nosp@m.com Copyright 2017 Dorian Ducournau doria.nosp@m.n.du.nosp@m.courn.nosp@m.au@g.nosp@m.mail..nosp@m.com Copyright 2022 David Fort conta.nosp@m.ct@h.nosp@m.arden.nosp@m.ing-.nosp@m.consu.nosp@m.ltin.nosp@m.g.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.

Enumeration Type Documentation

◆ AUTHZ_RESULT

Enumerator
AUTHZ_SUCCESS 
AUTHZ_ACCESS_DENIED 

◆ RemoteGuardPackageCredType

kind of RCG credentials

Enumerator
RCG_TYPE_KERB 
RCG_TYPE_NTLM 

◆ TsCredentialsType

kind of TSCreds

Enumerator
TSCREDS_INVALID 
TSCREDS_USER_PASSWD 
TSCREDS_SMARTCARD 
TSCREDS_REMOTEGUARD 

Function Documentation

◆ ap_integer_decrement_le()

static void ap_integer_decrement_le ( BYTE number,
size_t  size 
)
static
Here is the caller graph for this function:

◆ ap_integer_increment_le()

static void ap_integer_increment_le ( BYTE number,
size_t  size 
)
static
Here is the caller graph for this function:

◆ nla_adjust_settings_from_smartcard()

static BOOL nla_adjust_settings_from_smartcard ( rdpNla *  nla)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_authenticate()

int nla_authenticate ( rdpNla *  nla)

Authenticate using CredSSP.

Parameters
nlaThe NLA instance to use
Returns
1 if authentication is successful
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_buffer_free()

static void nla_buffer_free ( rdpNla *  nla)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_client_authenticate()

static int nla_client_authenticate ( rdpNla *  nla)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_client_begin()

int nla_client_begin ( rdpNla *  nla)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_client_init()

static int nla_client_init ( rdpNla *  nla)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_client_recv()

static int nla_client_recv ( rdpNla *  nla)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_client_recv_early_user_auth()

static int nla_client_recv_early_user_auth ( rdpNla *  nla)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_client_recv_nego_token()

static int nla_client_recv_nego_token ( rdpNla *  nla)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_client_recv_pub_key_auth()

static int nla_client_recv_pub_key_auth ( rdpNla *  nla)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_client_setup_identity()

static BOOL nla_client_setup_identity ( rdpNla *  nla)
static

The user could be found in SAM database. Use entry in SAM database later instead of prompt

Increase password hash length by LB_PASSWORD_MAX_LENGTH to obtain a length exceeding the maximum (LB_PASSWORD_MAX_LENGTH) and use it this for hash identification in WinPR.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_decode_ts_request()

static int nla_decode_ts_request ( rdpNla *  nla,
wStream s 
)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_decrypt_public_key_echo()

BOOL nla_decrypt_public_key_echo ( rdpNla *  nla)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_decrypt_public_key_hash()

BOOL nla_decrypt_public_key_hash ( rdpNla *  nla)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_decrypt_ts_credentials()

static BOOL nla_decrypt_ts_credentials ( rdpNla *  nla)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_Digest_Update_From_SecBuffer()

static BOOL nla_Digest_Update_From_SecBuffer ( WINPR_DIGEST_CTX *  ctx,
const SecBuffer buffer 
)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_encode_ts_credentials()

static BOOL nla_encode_ts_credentials ( rdpNla *  nla)
static

Encode TSCredentials structure.

Parameters
nlaA pointer to the NLA to use
Returns
TRUE for success, FALSE otherwise
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_encrypt_public_key_echo()

BOOL nla_encrypt_public_key_echo ( rdpNla *  nla)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_encrypt_public_key_hash()

BOOL nla_encrypt_public_key_hash ( rdpNla *  nla)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_encrypt_ts_credentials()

static BOOL nla_encrypt_ts_credentials ( rdpNla *  nla)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_free()

void nla_free ( rdpNla *  nla)

Free CredSSP state machine.

Parameters
nlaThe NLA instance to free
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_get_error()

DWORD nla_get_error ( rdpNla *  nla)
Here is the caller graph for this function:

◆ nla_get_identity()

SEC_WINNT_AUTH_IDENTITY* nla_get_identity ( rdpNla *  nla)
Here is the caller graph for this function:

◆ nla_get_sspi_error()

UINT32 nla_get_sspi_error ( rdpNla *  nla)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_get_state()

NLA_STATE nla_get_state ( rdpNla *  nla)
Here is the caller graph for this function:

◆ nla_get_state_str()

const char* nla_get_state_str ( NLA_STATE  state)
Here is the caller graph for this function:

◆ nla_impersonate()

BOOL nla_impersonate ( rdpNla *  nla)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_new()

rdpNla* nla_new ( rdpContext *  context,
rdpTransport *  transport 
)

Create new CredSSP state machine.

Parameters
contextA pointer to the rdp context to use
transportA pointer to the transport to use
Returns
new CredSSP state machine.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_read_KERB_TICKET_LOGON()

static BOOL nla_read_KERB_TICKET_LOGON ( rdpNla *  nla,
wStream s,
KERB_TICKET_LOGON ticket 
)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_read_ts_credentials()

static BOOL nla_read_ts_credentials ( rdpNla *  nla,
SecBuffer data 
)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_read_TSCspDataDetail()

static BOOL nla_read_TSCspDataDetail ( WinPrAsn1Decoder dec,
rdpSettings *  settings 
)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_read_TSRemoteGuardPackageCred()

static BOOL nla_read_TSRemoteGuardPackageCred ( rdpNla *  nla,
WinPrAsn1Decoder dec,
RemoteGuardPackageCredType credsType,
wStream payload 
)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_recv_pdu()

int nla_recv_pdu ( rdpNla *  nla,
wStream s 
)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_revert_to_self()

BOOL nla_revert_to_self ( rdpNla *  nla)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_sec_buffer_alloc()

static BOOL nla_sec_buffer_alloc ( SecBuffer buffer,
size_t  size 
)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_sec_buffer_alloc_from_data()

static BOOL nla_sec_buffer_alloc_from_data ( SecBuffer buffer,
const BYTE data,
size_t  offset,
size_t  size 
)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_send()

BOOL nla_send ( rdpNla *  nla)
static

Send CredSSP message.

Parameters
nlaA pointer to the NLA to use
Returns
TRUE for success, FALSE otherwise
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_server_authenticate()

static int nla_server_authenticate ( rdpNla *  nla)
static

Authenticate with client using CredSSP (server).

Parameters
nlaThe NLA instance to use
Returns
1 if authentication is successful
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_server_init()

static int nla_server_init ( rdpNla *  nla)
static

Initialize NTLMSSP authentication module (server).

Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_server_recv()

int nla_server_recv ( rdpNla *  nla)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_server_recv_credentials()

static BOOL nla_server_recv_credentials ( rdpNla *  nla)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_server_recv_stream()

static wStream* nla_server_recv_stream ( rdpNla *  nla)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_set_early_user_auth()

void nla_set_early_user_auth ( rdpNla *  nla,
BOOL  earlyUserAuth 
)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_set_service_principal()

BOOL nla_set_service_principal ( rdpNla *  nla,
const char *  service,
const char *  hostname 
)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_set_state()

BOOL nla_set_state ( rdpNla *  nla,
NLA_STATE  state 
)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_write_octet_string()

static BOOL nla_write_octet_string ( WinPrAsn1Encoder *  enc,
const SecBuffer buffer,
WinPrAsn1_tagId  tagId,
const char *  msg 
)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_write_octet_string_free()

static BOOL nla_write_octet_string_free ( WinPrAsn1Encoder *  enc,
SecBuffer buffer,
WinPrAsn1_tagId  tagId,
const char *  msg 
)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_creds_octetstring_to_settings()

static BOOL set_creds_octetstring_to_settings ( WinPrAsn1Decoder dec,
WinPrAsn1_tagId  tagId,
BOOL  optional,
FreeRDP_Settings_Keys_String  settingId,
rdpSettings *  settings 
)
static
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ ClientServerHashMagic

const BYTE ClientServerHashMagic[]
static
Initial value:
= { 0x43, 0x72, 0x65, 0x64, 0x53, 0x53, 0x50, 0x20,
0x43, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x2D, 0x54,
0x6F, 0x2D, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
0x20, 0x42, 0x69, 0x6E, 0x64, 0x69, 0x6E, 0x67,
0x20, 0x48, 0x61, 0x73, 0x68, 0x00 }

◆ NonceLength

const UINT32 NonceLength = 32
static

◆ ServerClientHashMagic

const BYTE ServerClientHashMagic[]
static
Initial value:
= { 0x43, 0x72, 0x65, 0x64, 0x53, 0x53, 0x50, 0x20,
0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2D, 0x54,
0x6F, 0x2D, 0x43, 0x6C, 0x69, 0x65, 0x6E, 0x74,
0x20, 0x42, 0x69, 0x6E, 0x64, 0x69, 0x6E, 0x67,
0x20, 0x48, 0x61, 0x73, 0x68, 0x00 }