InitializeSecurityContext和Delphi

时间:2015-11-11 14:38:36

标签: delphi

我尝试使用SSPI身份验证连接到Sql Server。使用InitializeSecurityContext的FreeTds sspi.c有一个工作(我希望)C的例子 问题是它调用InitializeSecurityContext两次。首先调用(tds_sspi_get_auth)函数使auth将其置于登录数据包中。有服务主体名称(SPN)创建为(项目JEDI JwaSspi使用)

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);

其中FSPN: WideString;

对InitializeSecurityContext的第二次调用(tds_sspi_handle_next)使用相同的FSPN和来自服务器的响应

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);

现在很难:在使用asprintf创建的C SPN上,在第一次调用InitializeSecurityContext之后,它发生了变化(在$4D $00 $53 $00 $53 $00 ...之后变为$08 $04 $01 $00 $4E ...),我想用Digest或类似代替。通过使用类似我在oleaut32.dll中的某处访问冲突。

1 个答案:

答案 0 :(得分:1)

这是“Project JEDI”的错误。 SecHandle声明为

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

,其中

  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}

由Microsoft ULONG_PTR

typedef unsigned __int3264 ULONG_PTR;

  

2.2.1 __int3264

     

解析为以下任一项的别名:      32位转换和执行环境中的__int32,或      64位转换和执行环境中的__int64。为了向后兼容,它在线上是32位。在编组期间必须在发送方侧截断较高的4个字节,并且必须在解密期间在[C706]第14.2.5节中规定的接收方适当扩展(有符号或无符号)。

所以当我在课堂上宣布时

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

具有64位可执行文件的InitializeSecurityContext通过将更大的结构写入FCredCtx破坏FSPN来破坏我的类变量。使用NativeInt或NativeUInt而不是Integer / Longword等修复了问题。