0

I'm trying to use SSPI authentication to connect to Sql Server. There is working (I hope) C example with FreeTds sspi.c that using InitializeSecurityContext.
The problem is it calling InitializeSecurityContext twice. At first (tds_sspi_get_auth) function called to make auth to put it into login packet. There Service principal name (SPN) created as (Project JEDI JwaSspi used)

FSPN := WideString(Format('MSSQLSvc/%s:%d', [FHostName, FPort]));

status := InitializeSecurityContext(@FCred, nil, PSecWChar(FSPN),
  ISC_REQ_CONFIDENTIALITY or ISC_REQ_REPLAY_DETECT or ISC_REQ_CONNECTION,
  0, SECURITY_NETWORK_DREP, nil, 0, @FCredCtx, @desc, attrs, @ts);

where FSPN: WideString;

Second call (tds_sspi_handle_next) to InitializeSecurityContext uses same FSPN and response from server

status := InitializeSecurityContext(@FCred, @FCredCtx, PSecWChar(FSPN),
  ISC_REQ_CONFIDENTIALITY or ISC_REQ_REPLAY_DETECT or ISC_REQ_CONNECTION,
  0, SECURITY_NETWORK_DREP, @in_desc,   0, @FCredCtx, @out_desc, attrs, @ts);

Now hard part: on C SPN created with asprintf, after first call to InitializeSecurityContext it changed (was $4D $00 $53 $00 $53 $00 ... , after $08 $04 $01 $00 $4E ...) and I guess replaced by Digest or similar. By using like that I have Access Violation somewhere in oleaut32.dll.

user2091150
  • 978
  • 12
  • 25
  • I have it. The problem is InitializeSecurityContext changing memory around FSPN (I guess C style memory management), so I have or access violations or broken memory header with FastMM4 if using AllocMem and FSPN as pointer instead of WideString. – user2091150 Nov 11 '15 at 16:10
  • Ah ok, now I get it. Deleting comments. Anyway can you provide a complete example so we can help verify it? – whosrdaddy Nov 11 '15 at 16:13
  • Update: it is 64-bit only error, it works properly under 32 bit (FSPN value and pointer remains the same after InitializeSecurityContext, under 64-bit FSPN changed like from $2A65E0 to $217B940). Tried even HeapAlloc. – user2091150 Nov 11 '15 at 21:06

1 Answers1

1

It is "Project JEDI" bug. SecHandle declared as

  _SecHandle = record
    dwLower: ULONG_PTR;
    dwUpper: ULONG_PTR;
  end;

where

  INT_PTR = Integer;
  {$EXTERNALSYM INT_PTR}
  PINT_PTR = ^INT_PTR;
  {$EXTERNALSYM PINT_PTR}
  UINT_PTR = Longword;
  {$EXTERNALSYM UINT_PTR}
  PUINT_PTR = ^UINT_PTR;
  {$EXTERNALSYM PUINT_PTR}
  LONG_PTR = Longint;
  {$EXTERNALSYM LONG_PTR}
  PLONG_PTR = ^LONG_PTR;
  {$EXTERNALSYM PLONG_PTR}
  ULONG_PTR = Longword;
  {$EXTERNALSYM ULONG_PTR}
  PULONG_PTR = ^ULONG_PTR;
  {$EXTERNALSYM PULONG_PTR}

by Microsoft ULONG_PTR is

typedef unsigned __int3264 ULONG_PTR;

and

2.2.1 __int3264

An alias that is resolved to either: An __int32 in a 32-bit translation and execution environment, or An __int64 in a 64-bit translation and execution environment. For backward compatibility, it is 32-bit on the wire. The higher 4 bytes MUST be truncated on the sender side during marshaling and MUST be extended appropriately (signed or unsigned), as specified in [C706] section 14.2.5, on the receiving side during unmarshaling.

So when I declared in my class

  private
    FCred: CredHandle;
    FCredCtx: CtxtHandle;
    FSPN: WideString;

InitializeSecurityContext with 64 bit executable smashed my class variables by writing larger structure into FCredCtx ruining FSPN. Using NativeInt or NativeUInt instead of Integer/Longword etc fixed issue.

user2091150
  • 978
  • 12
  • 25
  • Hi, do you have a complete example? I am trying to implement kerberos with a delphi service and MSSQL authentication ... – rimes Oct 08 '18 at 17:02
  • More at https://stackoverflow.com/questions/33829755/sspi-and-sql-server-windows-authentication . We sort of authenticated with SQL Server with NT authentication, but despite user in server log looks the same as authenticated with microsoft's dll had restricted rights. So we abandoned our attempts due to SQL Server authentication was enough. – user2091150 Oct 09 '18 at 19:30