0

我有适用于 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

我理解的过程如下:

  1. 使用 GSS API 在客户端获取一些字节
  2. 以我的消息格式包装这些字节并发送到服务器
  3. 服务器以某种方式检查该令牌并获取用户名并检查此信息是否可信。

我在第 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 系统上进行简单的透明身份验证。我到处都能看到它——它不是那么具体。只是想知道实施起来有多难!

4

0 回答 0