AcquireCredentialsHandle(SSPIInterface SecModule, string package, CredentialUse intent, SChannelCred scc ) { GlobalLog.Print("SSPIWrapper::AcquireCredentialsHandle#3(): using " + package); CredentialsHandle credentialsHandle = new CredentialsHandle(SecModule); GCHandle pinnedCertificateArray = new GCHandle(); if (scc.certContextArray != IntPtr.Zero) { // // We hide the fact that this array must be marshalled // and Pinned, we convert the single value into a pined array // for the Unmanaged call // IntPtr [] certContextArray = new IntPtr[1] { scc.certContextArray }; pinnedCertificateArray = GCHandle.Alloc(certContextArray, GCHandleType.Pinned); // // Its now pinned, so get a ptr to its base // this is needed because the Common Language Runtime doesn't support this natively // scc.certContextArray = pinnedCertificateArray.AddrOfPinnedObject(); } int errorCode = SecModule.AcquireCredentialsHandle( null, package, (int)intent, 0, ref scc, 0, 0, ref credentialsHandle.Handle, ref credentialsHandle.TimeStamp ); if (pinnedCertificateArray.IsAllocated) { pinnedCertificateArray.Free(); } if (errorCode != 0) { #if TRAVE GlobalLog.Print("SSPIWrapper::AcquireCredentialsHandle#3(): error " + SecureChannel.MapSecurityStatus((uint)errorCode)); #endif throw new Win32Exception(errorCode); } GlobalLog.Print("SSPIWrapper::AcquireCredentialsHandle#3(): cred handle = 0x" + String.Format("{0:x}", credentialsHandle.Handle)); return(credentialsHandle); }
AcquireCredentialsHandle(SSPIInterface SecModule, string package, CredentialUse intent, AuthIdentity authdata ) { GlobalLog.Print("SSPIWrapper::AcquireCredentialsHandle#2(): using " + package); CredentialsHandle credentialsHandle = new CredentialsHandle(SecModule); int errorCode = SecModule.AcquireCredentialsHandle(null, package, (int)intent, 0, authdata, 0, 0, ref credentialsHandle.Handle, ref credentialsHandle.TimeStamp ); if (errorCode != 0) { #if TRAVE GlobalLog.Print("SSPIWrapper::AcquireCredentialsHandle#2(): error " + SecureChannel.MapSecurityStatus((uint)errorCode)); #endif throw new Win32Exception(errorCode); } return(credentialsHandle); }
// // NTAuthentication::NTAuthentication() // Created: 12-01-1999: L.M. // Parameters: // package - security package to use (kerberos/ntlm/negotiate) // networkCredential - credentials we're using for authentication // remotePeerId - for a server session: // ignored (except when delegating, in which case this has the same rules as the client session.) // for a client session: // for kerberos: specifies the expected account under which the server // is supposed to be running (KDC). If the server runs under a // different account an exception is thrown during the blob // exchange. (this allows mutual authentication.) // One can specify a fully qualified account name (domain\userName) // or just a username, in which case the domain is assumed // to be the same as the client. // for ntlm: ignored // // Description: Initializes SSPI // public NTAuthentication(string package, NetworkCredential networkCredential, string remotePeerId, DelegationFix delegationFix) { GlobalLog.Print("NTAuthentication::.ctor() package:" + package); #if SERVER_SIDE_SSPI m_SecureSessionType = SecureSessionType.ClientSession; #endif m_RemotePeerId = remotePeerId; // only needed for Kerberos, it's the KDC m_Endianness = Endianness.Network; m_SecurityContext = new SecurityContext(GlobalSSPI.SSPIAuth); bool found = false; GlobalLog.Print("NTAuthentication::.ctor() searching for name: " + package); if (m_SupportedSecurityPackages != null) { for (int i = 0; i < m_SupportedSecurityPackages.Length; i++) { GlobalLog.Print("NTAuthentication::.ctor() supported name: " + m_SupportedSecurityPackages[i].Name); if (string.Compare(m_SupportedSecurityPackages[i].Name, package, true, CultureInfo.InvariantCulture) == 0) { GlobalLog.Print("NTAuthentication::.ctor(): found SecurityPackage(" + package + ")"); m_TokenSize = m_SupportedSecurityPackages[i].MaxToken; m_Capabilities = m_SupportedSecurityPackages[i].Capabilities; found = true; break; } } } if (!found) { GlobalLog.Print("NTAuthentication::.ctor(): initialization failed: SecurityPackage(" + package + ") NOT FOUND"); throw new WebException(SR.GetString(SR.net_securitypackagesupport), WebExceptionStatus.SecureChannelFailure); } // // In order to prevent a race condition where one request could // steal a connection from another request, before a handshake is // complete, we create a new Group for each authentication request. // if (package == NtlmClient.AuthType || package == NegotiateClient.AuthType) { m_UniqueUserId = (Interlocked.Increment(ref s_UniqueGroupId)).ToString(); } // // check if we're using DefaultCredentials // if (networkCredential is SystemNetworkCredential) { // // we're using DefaultCredentials // GlobalLog.Print("NTAuthentication::.ctor(): using DefaultCredentials"); m_UniqueUserId += "/S"; // save off for unique connection marking // DELEGATION: // The fix is implemented in cooperation with HttpWebRequest class // Remove from both places and change the constructor of NTAuthentication class // once the Common Language Runtime will start propagating the Thread token with their stack // compression stuff. // GlobalLog.Assert(delegationFix != null, "DelegationFix ==NULL -> request Credentials has been changed after the request submission!", ""); if (delegationFix != null) { delegationFix.SetToken(); } GlobalLog.Print("DELEGATION for peer-> '" + m_RemotePeerId + "', SetToken = " + delegationFix.Token.ToString()); try { m_CredentialsHandle = SSPIWrapper.AcquireCredentialsHandle( GlobalSSPI.SSPIAuth, package, CredentialUse.Outgoing); } finally { if (delegationFix != null) { delegationFix.RevertToken(); } GlobalLog.Print("DELEGATION for peer-> '" + m_RemotePeerId + "', UNSetToken = " + delegationFix.Token.ToString()); } return; } // // we're not using DefaultCredentials, we need a // AuthIdentity struct to contain credentials // SECREVIEW: // we'll save username/domain in temp strings, to avoid decrypting multiple times. // password is only used once // string username = networkCredential.UserName; string domain = networkCredential.Domain; m_UniqueUserId += domain + "/" + username + "/U"; // save off for unique connection marking AuthIdentity authIdentity = new AuthIdentity(username, networkCredential.Password, domain); GlobalLog.Print("NTAuthentication::.ctor(): using authIdentity:" + authIdentity.ToString()); m_CredentialsHandle = SSPIWrapper.AcquireCredentialsHandle( GlobalSSPI.SSPIAuth, package, CredentialUse.Outgoing, authIdentity ); }