谁有通过代理的NTLM身份认证的程序实现代码,请发给我一份吧email:[email protected],万分感谢!

解决方案 »

  1.   

    SCODE ParseAuthorityUserArgs(BSTR & AuthArg, BSTR & UserArg,BSTR & Authority,BSTR & User)
    {    // Determine the connection type by examining the Authority string    if(!(Authority == NULL || wcslen(Authority) == 0 || !_wcsnicmp(Authority, L"NTLMDOMAIN:",11)))
            return E_INVALIDARG;    // The ntlm case is more complex.  There are four cases
        // 1)  Authority = NTLMDOMAIN:name" and User = "User"
        // 2)  Authority = NULL and User = "User"
        // 3)  Authority = "NTLMDOMAIN:" User = "domain\user"
        // 4)  Authority = NULL and User = "domain\user"    // first step is to determine if there is a backslash in the user name somewhere between the
        // second and second to last character    WCHAR * pSlashInUser = NULL;
        if(User)
        {
            WCHAR * pEnd = User + wcslen(User) - 1;
            for(pSlashInUser = User; pSlashInUser <= pEnd; pSlashInUser++)
                if(*pSlashInUser == L'\\')      // do not think forward slash is allowed!
                    break;
            if(pSlashInUser > pEnd)
                pSlashInUser = NULL;
        }    if(Authority && wcslen(Authority) > 11) 
        {
            if(pSlashInUser)
                return E_INVALIDARG;        AuthArg = SysAllocString(Authority + 11);
            if(User) UserArg = SysAllocString(User);
            return S_OK;
        }
        else if(pSlashInUser)
        {
            int iDomLen = pSlashInUser-User;
            WCHAR cTemp[MAX_PATH];
            wcsncpy(cTemp, User, iDomLen);
            cTemp[iDomLen] = 0;
            AuthArg = SysAllocString(cTemp);
            if(wcslen(pSlashInUser+1))
                UserArg = SysAllocString(pSlashInUser+1);
        }
        else
            if(User) UserArg = SysAllocString(User);    return S_OK;
    }
    //
    HRESULT SetInterfaceSecurity(IUnknown * pInterface, LPWSTR pAuthority, LPWSTR pUser, 
                                 LPWSTR pPassword, bool bAuthenticate)
    {
        
        SCODE sc;
        if(pInterface == NULL)
            return E_INVALIDARG;    // If we are lowering the security, no need to deal with the identification info
        
        if(!bAuthenticate)
            return CoSetProxyBlanket(pInterface, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
                           RPC_C_AUTHN_LEVEL_NONE, RPC_C_IMP_LEVEL_IDENTIFY, NULL, EOAC_NONE);    // If we are doing trivial case, just pass in a null authentication structure which is used
        // if the current logged in user's credentials are OK.    if((pAuthority == NULL || wcslen(pAuthority) < 1) && 
            (pUser == NULL || wcslen(pUser) < 1) && 
            (pPassword == NULL || wcslen(pPassword) < 1))
                return CoSetProxyBlanket(pInterface, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
                           RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IDENTIFY, NULL, EOAC_NONE);    // If user, or Authority was passed in, the we need to create an authority argument for the login
        
        COAUTHIDENTITY  authident;
        BSTR AuthArg = NULL, UserArg = NULL;
        sc = ParseAuthorityUserArgs(AuthArg, UserArg, pAuthority, pUser);
        if(sc != S_OK)
            return sc;    memset((void *)&authident,0,sizeof(COAUTHIDENTITY));
        if(bIsNT())
        {
            if(UserArg)
            {
                authident.UserLength = wcslen(UserArg);
                authident.User = (LPWSTR)UserArg;
            }
            if(AuthArg)
            {
                authident.DomainLength = wcslen(AuthArg);
                authident.Domain = (LPWSTR)AuthArg;
            }
            if(pPassword)
            {
                authident.PasswordLength = wcslen(pPassword);
                authident.Password = (LPWSTR)pPassword;
            }
            authident.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
        }
        else
        {
            char szUser[MAX_PATH], szAuthority[MAX_PATH], szPassword[MAX_PATH];        // Fill in the identity structure        if(UserArg)
            {
                wcstombs(szUser, UserArg, MAX_PATH);
                authident.UserLength = strlen(szUser);
                authident.User = (LPWSTR)szUser;
            }
            if(AuthArg)
            {
                wcstombs(szAuthority, AuthArg, MAX_PATH);
                authident.DomainLength = strlen(szAuthority);
                authident.Domain = (LPWSTR)szAuthority;
            }
            if(pPassword)
            {
                wcstombs(szPassword, pPassword, MAX_PATH);
                authident.PasswordLength = strlen(szPassword);
                authident.Password = (LPWSTR)szPassword;
            }
            authident.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
        } HRESULT hr;
    DWORD dwAuthnSvc, dwAuthzSvc, dwAuthLvl, dwCaps; // Get the current proxy settings
    hr = CoQueryProxyBlanket(pInterface, &dwAuthnSvc, &dwAuthzSvc, NULL, &dwAuthLvl,
    NULL, NULL, &dwCaps); if(SUCCEEDED(hr))
    {
    hr = CoSetProxyBlanket(pInterface, dwAuthnSvc, dwAuthzSvc, NULL, dwAuthLvl,
    RPC_C_IMP_LEVEL_IMPERSONATE, &authident, dwCaps);
    } // old method
        /*hr = CoSetProxyBlanket(pInterface, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
                           RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IDENTIFY, &authident, EOAC_NONE);*/    if(UserArg)
            SysFreeString(UserArg);
        if(AuthArg)
            SysFreeString(AuthArg);
        return hr;
    }