我有适用于 Windows 和 Linux 守护程序的 Qt C++ 应用程序。Windows 机器在域中(2008 R2 作为 AD 控制器)。我需要实现 Windows 登录用户对 Linux 守护程序的透明身份验证。
我发现 Kerberos 5 是 Windows 中使用的现代安全机制,而 GSS API 是 Kerberos 5(和其他一些安全协议)的便捷 API。
我在 Windows 上将此库用于 C++ 应用程序:http ://web.mit.edu/kerberos/kfw-4.0/kfw-4.0.html
我理解的过程如下:
- 使用 GSS API 在客户端获取一些字节
- 以我的消息格式包装这些字节并发送到服务器
- 服务器以某种方式检查该令牌并获取用户名并检查此信息是否可信。
我在第 1 步。但是,GSS API 存在以下错误:
未找到凭据缓存
下面是实现:
std::string GSSApiHelper::GetErrorMessage(OM_uint32 code, int type)
{
std::string res;
OM_uint32 maj_stat, min_stat;
gss_buffer_desc msg = GSS_C_EMPTY_BUFFER;
OM_uint32 msg_ctx;
msg_ctx = 0;
while (true)
{
maj_stat = gss_display_status(&min_stat, code, type, GSS_C_NULL_OID, &msg_ctx, &msg);
if (!res.empty())
res.append("\n");
if (maj_stat != GSS_S_COMPLETE)
{
res.append("Error in GetErrorMessage");
break;
}
else
{
res.append((char*)msg.value);
}
if (msg.length != 0)
(void)gss_release_buffer(&min_stat, &msg);
if (!msg_ctx)
break;
}
return res;
}
std::string GSSApiHelper::GetErrorMessage(OM_uint32 maj_stat, OM_uint32 min_stat)
{
std::string res;
res.append(GetErrorMessage(maj_stat, GSS_C_GSS_CODE));
res.append("\n");
res.append(GetErrorMessage(min_stat, GSS_C_MECH_CODE));
return res;
}
void GSSApiHelper::Init()
{
OM_uint32 maj_stat, min_stat;
gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
gss_buffer_desc outputToken = GSS_C_EMPTY_BUFFER;
OM_uint32 retFlags, validSeconds;
gss_OID actualMechType;
gss_name_t targetName = 0;
gss_buffer_desc name;
name.value = (void*)"nfs@vm-ad.domain.com";
name.length = strlen((char*)name.value) + 1;
maj_stat = gss_import_name(&min_stat, &name, GSS_C_NT_HOSTBASED_SERVICE, &targetName);
qDebug() << "GSSApiHelper::Init(), gss_import_name result:" << GetErrorMessage(maj_stat, min_stat).c_str();
maj_stat = gss_init_sec_context(&min_stat, GSS_C_NO_CREDENTIAL, &ctx, targetName,
GSS_C_NO_OID,
0/* flags */, 0/* validity time, in seconds*/,
GSS_C_NO_CHANNEL_BINDINGS, GSS_C_NO_BUFFER/* or pointer to GSS_C_EMPTY_BUFFER*/,
&actualMechType, &outputToken, &retFlags, &validSeconds);
qDebug() << "GSSApiHelper::Init() result:" << GetErrorMessage(maj_stat, min_stat).c_str();
}
Linux上的相同代码给了我
没有可用的 Kerberos 凭据
那么,有没有办法获取属于当前登录用户的内容并可以发送到服务器?
我不想使用一些 Kerberos MIT 应用程序来生成一些东西等等(我试过了,想)。只是在域中干净的 XP/Win7 系统上进行简单的透明身份验证。我到处都能看到它——它不是那么具体。只是想知道实施起来有多难!