InitializeSecurityContext and Delphi



我正在尝试使用SSPI身份验证连接到Sql Server。有一个使用InitializeSecurityContext的FreeTdssspi.C的C示例(我希望如此)
问题是它调用InitializeSecurityContext两次。首先调用(tds_sspi_get_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后,它发生了变化(在$08 $04 $01 $00 $4E ...之后是$4D $00 $53 $00 $53 $00 ...),我想它被Digest或类似的东西取代了。通过这样使用,我在oleaut32.dll中的某个位置有访问违规。

这是"绝地计划"的错误。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等修复了问题。

最新更新