从Windows桌面应用程序到Linux守护程序的透明身份验证

时间:2015-11-13 21:36:57

标签: authentication kerberos gssapi mit-kerberos

我有适用于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. 服务器以某种方式检查该令牌并获取用户名并检查此信息是否值得信任。
  4. 我在第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系统上进行简单的透明身份验证。我到处都看到它 - 它不是那么具体。只是想知道实施有多难!

0 个答案:

没有答案