FreeRDP
nla.c File Reference
#include <time.h>
#include <winpr/debug.h>
#include <freerdp/log.h>
#include <freerdp/crypto/tls.h>
#include <freerdp/build-config.h>
#include <freerdp/peer.h>
#include <winpr/crt.h>
#include <winpr/sam.h>
#include <winpr/sspi.h>
#include <winpr/print.h>
#include <winpr/tchar.h>
#include <winpr/dsparse.h>
#include <winpr/library.h>
#include <winpr/registry.h>
#include "nla.h"
#include "utils.h"

Macros

#define TAG   FREERDP_TAG("core.nla")
 
#define SERVER_KEY   "Software\\" FREERDP_VENDOR_STRING "\\" FREERDP_PRODUCT_STRING "\\Server"
 
#define NLA_PKG_NAME   NEGO_SSP_NAME
 
#define TERMSRV_SPN_PREFIX   "TERMSRV/"
 

Functions

static BOOL nla_send (rdpNla *nla)
 
static int nla_server_recv (rdpNla *nla)
 
static void nla_buffer_free (rdpNla *nla)
 
static SECURITY_STATUS nla_encrypt_public_key_echo (rdpNla *nla)
 
static SECURITY_STATUS nla_encrypt_public_key_hash (rdpNla *nla)
 
static SECURITY_STATUS nla_decrypt_public_key_echo (rdpNla *nla)
 
static SECURITY_STATUS nla_decrypt_public_key_hash (rdpNla *nla)
 
static SECURITY_STATUS nla_encrypt_ts_credentials (rdpNla *nla)
 
static SECURITY_STATUS nla_decrypt_ts_credentials (rdpNla *nla)
 
static BOOL nla_read_ts_password_creds (rdpNla *nla, wStream *s)
 
static void nla_identity_free (SEC_WINNT_AUTH_IDENTITY *identity)
 
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_sec_buffer_alloc_from_buffer (SecBuffer *buffer, const SecBuffer *data, size_t offset)
 
static BOOL nla_decode_to_buffer (wStream *s, SecBuffer *buffer)
 
static BOOL nla_set_package_name (rdpNla *nla, const TCHAR *name)
 
static SECURITY_STATUS nla_update_package_name (rdpNla *nla)
 
static SECURITY_STATUS nla_query_context_sizes (rdpNla *nla)
 
static SECURITY_STATUS nla_initialize_security_context (rdpNla *nla, BOOL initial, SecBufferDesc *pInputBufferDesc, SecBufferDesc *pOutputBufferDesc)
 
static BOOL nla_complete_auth (rdpNla *nla, PSecBufferDesc pOutputBufferDesc)
 
static SECURITY_STATUS nla_decrypt (rdpNla *nla, SecBuffer *buffer, size_t headerLength)
 
static SECURITY_STATUS nla_encrypt (rdpNla *nla, SecBuffer *buffer, size_t headerLength)
 
static size_t ber_sizeof_sequence_octet_string (size_t length)
 
static size_t ber_write_sequence_octet_string (wStream *stream, BYTE context, const BYTE *value, size_t length)
 
static size_t ber_write_sequence_octet_string_from_secbuffer (wStream *stream, BYTE context, const SecBuffer *buffer)
 
static int nla_client_init (rdpNla *nla)
 
static BOOL nla_client_send_token (rdpNla *nla, SecBufferDesc *token)
 
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 (rdpNla *nla)
 
static int nla_client_authenticate (rdpNla *nla)
 
static int nla_server_init (rdpNla *nla)
 
static wStream * nla_server_recv_stream (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 size_t nla_sizeof_ts_password_creds (rdpNla *nla)
 
static size_t nla_sizeof_ts_credentials (rdpNla *nla)
 
static size_t nla_write_ts_password_creds (rdpNla *nla, wStream *s)
 
static BOOL nla_read_ts_credentials (rdpNla *nla, SecBuffer *data, size_t offset)
 
static size_t nla_write_ts_credentials (rdpNla *nla, wStream *s)
 
static BOOL nla_encode_ts_credentials (rdpNla *nla)
 
static size_t nla_sizeof_nego_token (size_t length)
 
static size_t nla_sizeof_nego_tokens (const SecBuffer *buffer)
 
static size_t nla_sizeof_pub_key_auth (const SecBuffer *buffer)
 
static size_t nla_sizeof_auth_info (const SecBuffer *buffer)
 
static size_t nla_sizeof_client_nonce (const SecBuffer *buffer)
 
static size_t nla_sizeof_ts_request (size_t length)
 
static BOOL nla_client_write_nego_token (wStream *s, const SecBuffer *negoToken)
 
static int nla_decode_ts_request (rdpNla *nla, wStream *s)
 
int nla_recv_pdu (rdpNla *nla, wStream *s)
 
LPTSTR nla_make_spn (const char *ServiceClass, const char *hostname)
 
rdpNla * nla_new (freerdp *instance, rdpTransport *transport, rdpSettings *settings)
 
void nla_free (rdpNla *nla)
 
SEC_WINNT_AUTH_IDENTITY * nla_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, LPTSTR principal)
 
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)
 

Variables

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

Macro Definition Documentation

◆ NLA_PKG_NAME

#define NLA_PKG_NAME   NEGO_SSP_NAME

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

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.

◆ TERMSRV_SPN_PREFIX

#define TERMSRV_SPN_PREFIX   "TERMSRV/"

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:

◆ ber_sizeof_sequence_octet_string()

static size_t ber_sizeof_sequence_octet_string ( size_t  length)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ber_write_sequence_octet_string()

static size_t ber_write_sequence_octet_string ( wStream *  stream,
BYTE  context,
const BYTE value,
size_t  length 
)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ber_write_sequence_octet_string_from_secbuffer()

static size_t ber_write_sequence_octet_string_from_secbuffer ( wStream *  stream,
BYTE  context,
const SecBuffer *  buffer 
)
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
credssp
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()

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

Initialize NTLM/Kerberos SSP authentication module (client).

Parameters
credssp

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_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_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_send_token()

static BOOL nla_client_send_token ( rdpNla *  nla,
SecBufferDesc *  token 
)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_client_write_nego_token()

static BOOL nla_client_write_nego_token ( wStream *  s,
const SecBuffer *  negoToken 
)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_complete_auth()

static BOOL nla_complete_auth ( rdpNla *  nla,
PSecBufferDesc  pOutputBufferDesc 
)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_decode_to_buffer()

static BOOL nla_decode_to_buffer ( wStream *  s,
SecBuffer *  buffer 
)
static
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()

static SECURITY_STATUS nla_decrypt ( rdpNla *  nla,
SecBuffer *  buffer,
size_t  headerLength 
)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_decrypt_public_key_echo()

SECURITY_STATUS 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()

SECURITY_STATUS 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 SECURITY_STATUS 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
credssp
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_encrypt()

static SECURITY_STATUS nla_encrypt ( rdpNla *  nla,
SecBuffer *  buffer,
size_t  headerLength 
)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_encrypt_public_key_echo()

SECURITY_STATUS 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()

SECURITY_STATUS 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 SECURITY_STATUS 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
credssp
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_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_identity_free()

void nla_identity_free ( SEC_WINNT_AUTH_IDENTITY *  identity)
static
Here is the caller graph for this function:

◆ nla_impersonate()

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

◆ nla_initialize_security_context()

static SECURITY_STATUS nla_initialize_security_context ( rdpNla *  nla,
BOOL  initial,
SecBufferDesc *  pInputBufferDesc,
SecBufferDesc *  pOutputBufferDesc 
)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_make_spn()

LPTSTR nla_make_spn ( const char *  ServiceClass,
const char *  hostname 
)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_new()

rdpNla* nla_new ( freerdp *  instance,
rdpTransport *  transport,
rdpSettings *  settings 
)

Create new CredSSP state machine.

Parameters
transport
Returns
new CredSSP state machine.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_query_context_sizes()

static SECURITY_STATUS nla_query_context_sizes ( rdpNla *  nla)
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,
size_t  offset 
)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_read_ts_password_creds()

BOOL nla_read_ts_password_creds ( rdpNla *  nla,
wStream *  s 
)
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 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_buffer()

static BOOL nla_sec_buffer_alloc_from_buffer ( SecBuffer *  buffer,
const SecBuffer *  data,
size_t  offset 
)
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
credssp
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
credssp
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).

Parameters
credssp
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_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_package_name()

static BOOL nla_set_package_name ( rdpNla *  nla,
const TCHAR name 
)
static
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,
LPTSTR  principal 
)
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_sizeof_auth_info()

static size_t nla_sizeof_auth_info ( const SecBuffer *  buffer)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_sizeof_client_nonce()

static size_t nla_sizeof_client_nonce ( const SecBuffer *  buffer)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_sizeof_nego_token()

static size_t nla_sizeof_nego_token ( size_t  length)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_sizeof_nego_tokens()

static size_t nla_sizeof_nego_tokens ( const SecBuffer *  buffer)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_sizeof_pub_key_auth()

static size_t nla_sizeof_pub_key_auth ( const SecBuffer *  buffer)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_sizeof_ts_credentials()

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

◆ nla_sizeof_ts_password_creds()

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

◆ nla_sizeof_ts_request()

static size_t nla_sizeof_ts_request ( size_t  length)
static
Here is the call graph for this function:
Here is the caller graph for this function:

◆ nla_update_package_name()

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

◆ nla_write_ts_credentials()

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

◆ nla_write_ts_password_creds()

static size_t nla_write_ts_password_creds ( rdpNla *  nla,
wStream *  s 
)
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 }