- Timestamp:
- Aug 15, 2016 2:02:31 PM (8 years ago)
- Location:
- trunk/src/VBox/Additions/WINNT/VBoxCredProv
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/VBoxCredProv/VBoxCredProvCredential.cpp
r63473 r63476 155 155 156 156 157 HRESULT VBoxCredProvCredential::AllocateLogonPackage(const KERB_INTERACTIVE_UNLOCK_LOGON &rUnlockLogon, PBYTE *ppPackage, DWORD *pcbPackage) 158 { 159 AssertPtrReturn(ppPackage, E_INVALIDARG); 157 HRESULT VBoxCredProvCredential::kerberosLogonInit(KERB_INTERACTIVE_LOGON *pLogonIn, 158 CREDENTIAL_PROVIDER_USAGE_SCENARIO enmUsage, 159 PRTUTF16 pwszUser, PRTUTF16 pwszPassword, PRTUTF16 pwszDomain) 160 { 161 AssertPtrReturn(pLogonIn, E_INVALIDARG); 162 AssertPtrReturn(pwszUser, E_INVALIDARG); 163 AssertPtrReturn(pwszPassword, E_INVALIDARG); 164 /* pwszDomain is optional. */ 165 166 HRESULT hr; 167 168 /* Do we have a domain name set? */ 169 if ( pwszDomain 170 && RTUtf16Len(pwszDomain)) 171 { 172 hr = RTUTF16ToUnicode(&pLogonIn->LogonDomainName, pwszDomain, true /* fCopy */); 173 } 174 else /* No domain (FQDN) given, try local computer name. */ 175 { 176 WCHAR wszComputerName[MAX_COMPUTERNAME_LENGTH + 1]; 177 DWORD cch = ARRAYSIZE(wszComputerName); 178 if (GetComputerNameW(wszComputerName, &cch)) 179 { 180 /* Is a domain name missing? Then use the name of the local computer. */ 181 hr = RTUTF16ToUnicode(&pLogonIn->LogonDomainName, wszComputerName, true /* fCopy */); 182 183 VBoxCredProvVerbose(0, "VBoxCredProvCredential::kerberosLogonInit: Local computer name=%ls\n", 184 wszComputerName); 185 } 186 else 187 hr = HRESULT_FROM_WIN32(GetLastError()); 188 } 189 190 /* Fill in the username and password. */ 191 if (SUCCEEDED(hr)) 192 { 193 hr = RTUTF16ToUnicode(&pLogonIn->UserName, pwszUser, true /* fCopy */); 194 if (SUCCEEDED(hr)) 195 { 196 hr = RTUTF16ToUnicode(&pLogonIn->Password, pwszPassword, true /* fCopy */); 197 if (SUCCEEDED(hr)) 198 { 199 /* Set credential type according to current usage scenario. */ 200 switch (enmUsage) 201 { 202 case CPUS_UNLOCK_WORKSTATION: 203 pLogonIn->MessageType = KerbWorkstationUnlockLogon; 204 break; 205 206 case CPUS_LOGON: 207 pLogonIn->MessageType = KerbInteractiveLogon; 208 break; 209 210 case CPUS_CREDUI: 211 pLogonIn->MessageType = (KERB_LOGON_SUBMIT_TYPE)0; /* No message type required here. */ 212 break; 213 214 default: 215 VBoxCredProvVerbose(0, "VBoxCredProvCredential::kerberosLogonInit: Unknown usage scenario=%ld\n", 216 enmUsage); 217 hr = E_FAIL; 218 break; 219 } 220 } 221 } 222 } 223 224 return hr; 225 } 226 227 228 HRESULT VBoxCredProvCredential::kerberosLogonSerialize(const KERB_INTERACTIVE_LOGON *pLogonIn, 229 PBYTE *ppPackage, DWORD *pcbPackage) 230 { 231 AssertPtrReturn(pLogonIn, E_INVALIDARG); 232 AssertPtrReturn(ppPackage, E_INVALIDARG); 160 233 AssertPtrReturn(pcbPackage, E_INVALIDARG); 161 162 const KERB_INTERACTIVE_LOGON *pLogonIn = &rUnlockLogon.Logon;163 234 164 235 /* … … 836 907 837 908 /* Save a pointer to the interactive logon struct. */ 838 KERB_INTERACTIVE_LOGON *pKerberosLogon = &KerberosUnlockLogon.Logon; 839 AssertPtr(pKerberosLogon); 840 841 HRESULT hr; 842 843 #ifdef DEBUG 909 KERB_INTERACTIVE_LOGON *pLogon = &KerberosUnlockLogon.Logon; 910 AssertPtr(pLogon); 911 912 #ifdef DEBUG /* Note: NEVER print this in release mode! */ 844 913 VBoxCredProvVerbose(0, "VBoxCredProvCredential::GetSerialization: Username=%ls, Password=%ls, Domain=%ls\n", 845 914 m_apwszCredentials[VBOXCREDPROV_FIELDID_USERNAME], … … 848 917 #endif 849 918 850 /* Do we have a domain name set? */ 851 if ( m_apwszCredentials[VBOXCREDPROV_FIELDID_DOMAINNAME] 852 && RTUtf16Len(m_apwszCredentials[VBOXCREDPROV_FIELDID_DOMAINNAME])) 853 { 854 hr = RTUTF16ToUnicode(&pKerberosLogon->LogonDomainName, 855 m_apwszCredentials[VBOXCREDPROV_FIELDID_DOMAINNAME], 856 false /* Just assign, no copy */); 857 } 858 else /* No domain (FQDN) given, try local computer name. */ 859 { 860 WCHAR wszComputerName[MAX_COMPUTERNAME_LENGTH + 1]; 861 DWORD cch = ARRAYSIZE(wszComputerName); 862 if (GetComputerNameW(wszComputerName, &cch)) 863 { 864 /* Is a domain name missing? Then use the name of the local computer. */ 865 hr = RTUTF16ToUnicode(&pKerberosLogon->LogonDomainName, 866 wszComputerName, 867 false /* Just assign, no copy */); 868 869 VBoxCredProvVerbose(0, "VBoxCredProvCredential::GetSerialization: Local computer name=%ls\n", 870 wszComputerName); 871 } 872 else 873 hr = HRESULT_FROM_WIN32(GetLastError()); 874 } 875 876 /* Fill in the username and password. */ 919 HRESULT hr = kerberosLogonInit(pLogon, 920 m_enmUsageScenario, 921 m_apwszCredentials[VBOXCREDPROV_FIELDID_USERNAME], 922 m_apwszCredentials[VBOXCREDPROV_FIELDID_PASSWORD], 923 m_apwszCredentials[VBOXCREDPROV_FIELDID_DOMAINNAME]); 877 924 if (SUCCEEDED(hr)) 878 925 { 879 hr = RTUTF16ToUnicode(&pKerberosLogon->UserName,880 m_apwszCredentials[VBOXCREDPROV_FIELDID_USERNAME],881 false /* Just assign, no copy */);926 hr = kerberosLogonSerialize(pLogon, 927 &pcpCredentialSerialization->rgbSerialization, 928 &pcpCredentialSerialization->cbSerialization); 882 929 if (SUCCEEDED(hr)) 883 930 { 884 hr = RTUTF16ToUnicode(&pKerberosLogon->Password, 885 m_apwszCredentials[VBOXCREDPROV_FIELDID_PASSWORD], 886 false /* Just assign, no copy */); 931 HANDLE hLSA; 932 NTSTATUS s = LsaConnectUntrusted(&hLSA); 933 hr = HRESULT_FROM_NT(s); 934 887 935 if (SUCCEEDED(hr)) 888 936 { 889 /* Set credential type according to current usage scenario. */ 890 AssertPtr(pKerberosLogon); 891 switch (m_enmUsageScenario) 892 { 893 case CPUS_UNLOCK_WORKSTATION: 894 pKerberosLogon->MessageType = KerbWorkstationUnlockLogon; 895 break; 896 897 case CPUS_LOGON: 898 pKerberosLogon->MessageType = KerbInteractiveLogon; 899 break; 900 901 case CPUS_CREDUI: 902 pKerberosLogon->MessageType = (KERB_LOGON_SUBMIT_TYPE)0; /* No message type required here. */ 903 break; 904 905 default: 906 hr = E_FAIL; 907 break; 908 } 909 910 if (FAILED(hr)) 911 VBoxCredProvVerbose(0, "VBoxCredProvCredential::GetSerialization: Unknown usage scenario=%ld\n", m_enmUsageScenario); 912 913 if (SUCCEEDED(hr)) /* Build the logon package. */ 914 { 915 hr = AllocateLogonPackage(KerberosUnlockLogon, 916 &pcpCredentialSerialization->rgbSerialization, 917 &pcpCredentialSerialization->cbSerialization); 918 if (FAILED(hr)) 919 VBoxCredProvVerbose(0, "VBoxCredProvCredential::GetSerialization: Failed to allocate logon package, hr=0x%08x\n", hr); 920 } 921 937 LSA_STRING lsaszKerberosName; 938 size_t cchKerberosName; 939 hr = StringCchLengthA(NEGOSSP_NAME_A, USHORT_MAX, &cchKerberosName); 922 940 if (SUCCEEDED(hr)) 923 941 { 924 ULONG ulAuthPackage = 0; 925 /** @todo r=bird: The code flow here looks wrong. The fact that ulAuthPackage 926 * wasn't initialized if LsaConnectUntrusted fails, but still used and 927 * we seemingly even succeed the operation as a whole. Unfortunately, 928 * the code does not have any comments what-so-family-ever to 929 * enlighten us as to wtf (f == family) this Lsa stuff is doing and 930 * why it appear to be kind of optional... 931 * 932 * I'm pretty sure this code if broken. And if it is, it's because the 933 * stupid, stupid, code structure where you repeat state checks to avoid 934 * hugging the right margin. The function is too long already, so the 935 * right way to deal with that is to split up the work into several 936 * functions with simplier control flow. 937 */ 938 #pragma message("TODO: Investigate code flow around ulAuthPackage!") 939 #ifdef DEBUG_andy 940 # error "fix this ASAP, it's been here since the r76490 rewrite" 941 #endif 942 943 HANDLE hLsa; 944 NTSTATUS s = LsaConnectUntrusted(&hLsa); 945 if (SUCCEEDED(HRESULT_FROM_NT(s))) 942 USHORT usLength; 943 hr = SizeTToUShort(cchKerberosName, &usLength); 944 if (SUCCEEDED(hr)) 946 945 { 947 LSA_STRING lsaszKerberosName; 948 size_t cchKerberosName; 949 hr = StringCchLengthA(NEGOSSP_NAME_A, USHORT_MAX, &cchKerberosName); 946 lsaszKerberosName.Buffer = (PCHAR)NEGOSSP_NAME_A; 947 lsaszKerberosName.Length = usLength; 948 lsaszKerberosName.MaximumLength = lsaszKerberosName.Length + 1; 949 950 ULONG ulAuthPackage = 0; 951 952 s = LsaLookupAuthenticationPackage(hLSA, &lsaszKerberosName, &ulAuthPackage); 953 hr = HRESULT_FROM_NT(s); 954 950 955 if (SUCCEEDED(hr)) 951 956 { 952 USHORT usLength; 953 hr = SizeTToUShort(cchKerberosName, &usLength); 954 if (SUCCEEDED(hr)) 955 { 956 lsaszKerberosName.Buffer = (PCHAR)NEGOSSP_NAME_A; 957 lsaszKerberosName.Length = usLength; 958 lsaszKerberosName.MaximumLength = lsaszKerberosName.Length + 1; 959 960 } 957 pcpCredentialSerialization->ulAuthenticationPackage = ulAuthPackage; 958 pcpCredentialSerialization->clsidCredentialProvider = CLSID_VBoxCredProvider; 959 960 /* We're done -- let the logon UI know. */ 961 *pcpGetSerializationResponse = CPGSR_RETURN_CREDENTIAL_FINISHED; 961 962 } 962 963 if (SUCCEEDED(hr)) 964 { 965 s = LsaLookupAuthenticationPackage(hLsa, &lsaszKerberosName, &ulAuthPackage); 966 if (FAILED(HRESULT_FROM_NT(s))) 967 { 968 hr = HRESULT_FROM_NT(s); 969 VBoxCredProvVerbose(0, "VBoxCredProvCredential::GetSerialization: Failed looking up authentication package, hr=0x%08x\n", hr); 970 } 971 } 972 973 LsaDeregisterLogonProcess(hLsa); 974 } 975 976 if (SUCCEEDED(hr)) 977 { 978 pcpCredentialSerialization->ulAuthenticationPackage = ulAuthPackage; 979 pcpCredentialSerialization->clsidCredentialProvider = CLSID_VBoxCredProvider; 980 981 /* We're done -- let the logon UI know. */ 982 *pcpGetSerializationResponse = CPGSR_RETURN_CREDENTIAL_FINISHED; 963 else 964 VBoxCredProvVerbose(1, "VBoxCredProvCredential::GetSerialization: LsaLookupAuthenticationPackage failed with ntStatus=%ld\n", s); 983 965 } 984 966 } 967 968 LsaDeregisterLogonProcess(hLSA); 985 969 } 986 970 else 987 VBoxCredProvVerbose( 0, "VBoxCredProvCredential::GetSerialization: Error copying password, hr=0x%08x\n", hr);971 VBoxCredProvVerbose(1, "VBoxCredProvCredential::GetSerialization: LsaConnectUntrusted failed with ntStatus=%ld\n", s); 988 972 } 989 973 else 990 VBoxCredProvVerbose(0, "VBoxCredProvCredential::GetSerialization: Error copying user name, hr=0x%08x\n", hr); 991 } 974 VBoxCredProvVerbose(1, "VBoxCredProvCredential::GetSerialization: kerberosLogonSerialize failed with hr=0x%08x\n", hr); 975 } 976 else 977 VBoxCredProvVerbose(1, "VBoxCredProvCredential::GetSerialization: kerberosLogonInit failed with hr=0x%08x\n", hr); 992 978 993 979 VBoxCredProvVerbose(0, "VBoxCredProvCredential::GetSerialization returned hr=0x%08x\n", hr); -
trunk/src/VBox/Additions/WINNT/VBoxCredProv/VBoxCredProvCredential.h
r63070 r63476 95 95 protected: 96 96 HRESULT RTUTF16ToUnicode(PUNICODE_STRING pUnicodeDest, PRTUTF16 pwszSource, bool fCopy); 97 HRESULT AllocateLogonPackage(const KERB_INTERACTIVE_UNLOCK_LOGON &rUnlockLogon, 98 BYTE **ppPackage, DWORD *pcbPackage); 97 HRESULT kerberosLogonInit(KERB_INTERACTIVE_LOGON *pLogonIn, 98 CREDENTIAL_PROVIDER_USAGE_SCENARIO enmUsage, 99 PRTUTF16 pwszUser, PRTUTF16 pwszPassword, PRTUTF16 pwszDomain); 100 HRESULT kerberosLogonSerialize(const KERB_INTERACTIVE_LOGON *pLogon, PBYTE *ppPackage, DWORD *pcbPackage); 99 101 100 102 private:
Note:
See TracChangeset
for help on using the changeset viewer.