我尝试使用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中的某处访问冲突。
答案 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等修复了问题。