Remove WindowsAuth middleware package.
This commit is contained in:
parent
88da31af7c
commit
19b1db41de
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.21916.0
|
||||
VisualStudioVersion = 14.0.22115.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestClient", "samples\TestClient\TestClient.csproj", "{8B828433-B333-4C19-96AE-00BFFF9D8841}"
|
||||
EndProject
|
||||
|
|
@ -17,8 +17,6 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "HelloWorld", "samples\Hello
|
|||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "SelfHostServer", "samples\SelfHostServer\SelfHostServer.kproj", "{1236F93A-AC5C-4A77-9477-C88F040151CA}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Security.Windows", "src\Microsoft.AspNet.Security.Windows\Microsoft.AspNet.Security.Windows.kproj", "{EFC7538F-7AEB-4A3E-A1E6-6BDCCBD272BF}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.Net.WebSockets", "src\Microsoft.Net.WebSockets\Microsoft.Net.WebSockets.kproj", "{E788AEAE-2CB4-4BFA-8746-D0BB7E93A1BB}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Server.WebListener.FunctionalTests", "test\Microsoft.AspNet.Server.WebListener.FunctionalTests\Microsoft.AspNet.Server.WebListener.FunctionalTests.kproj", "{4492FF4C-9032-411D-853F-46B01755E504}"
|
||||
|
|
@ -82,16 +80,6 @@ Global
|
|||
{1236F93A-AC5C-4A77-9477-C88F040151CA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{1236F93A-AC5C-4A77-9477-C88F040151CA}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{1236F93A-AC5C-4A77-9477-C88F040151CA}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{EFC7538F-7AEB-4A3E-A1E6-6BDCCBD272BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EFC7538F-7AEB-4A3E-A1E6-6BDCCBD272BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EFC7538F-7AEB-4A3E-A1E6-6BDCCBD272BF}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{EFC7538F-7AEB-4A3E-A1E6-6BDCCBD272BF}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{EFC7538F-7AEB-4A3E-A1E6-6BDCCBD272BF}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{EFC7538F-7AEB-4A3E-A1E6-6BDCCBD272BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EFC7538F-7AEB-4A3E-A1E6-6BDCCBD272BF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{EFC7538F-7AEB-4A3E-A1E6-6BDCCBD272BF}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{EFC7538F-7AEB-4A3E-A1E6-6BDCCBD272BF}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{EFC7538F-7AEB-4A3E-A1E6-6BDCCBD272BF}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{E788AEAE-2CB4-4BFA-8746-D0BB7E93A1BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E788AEAE-2CB4-4BFA-8746-D0BB7E93A1BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E788AEAE-2CB4-4BFA-8746-D0BB7E93A1BB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
|
|
@ -141,7 +129,6 @@ Global
|
|||
{3F5212AA-E287-49DD-8CEC-44BF0A2AC9A1} = {99D5E5F3-88F5-4CCF-8D8C-717C8925DF09}
|
||||
{6DAF3E6B-8E1B-4E6E-B9FE-7B1E5FDB7DB4} = {3A1E31E3-2794-4CA3-B8E2-253E96BDE514}
|
||||
{1236F93A-AC5C-4A77-9477-C88F040151CA} = {3A1E31E3-2794-4CA3-B8E2-253E96BDE514}
|
||||
{EFC7538F-7AEB-4A3E-A1E6-6BDCCBD272BF} = {99D5E5F3-88F5-4CCF-8D8C-717C8925DF09}
|
||||
{E788AEAE-2CB4-4BFA-8746-D0BB7E93A1BB} = {99D5E5F3-88F5-4CCF-8D8C-717C8925DF09}
|
||||
{4492FF4C-9032-411D-853F-46B01755E504} = {E183C826-1360-4DFF-9994-F33CED5C8525}
|
||||
{B9F45F9D-D206-47F0-8E5F-54CE2F0BDF92} = {99D5E5F3-88F5-4CCF-8D8C-717C8925DF09}
|
||||
|
|
|
|||
|
|
@ -1,54 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="AuthTypes.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
/// <summary>
|
||||
/// Types of Windows Authentication supported.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum AuthTypes
|
||||
{
|
||||
/// <summary>
|
||||
/// Default
|
||||
/// </summary>
|
||||
None = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Digest authentication using Windows credentials
|
||||
/// </summary>
|
||||
Digest = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Negotiates Kerberos or NTLM
|
||||
/// </summary>
|
||||
Negotiate = 2,
|
||||
|
||||
/// <summary>
|
||||
/// NTLM Windows authentication
|
||||
/// </summary>
|
||||
Ntlm = 4,
|
||||
}
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="ComNetOS.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Security.Permissions;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
internal static class ComNetOS
|
||||
{
|
||||
// Minimum support for Windows 2008 is assumed.
|
||||
internal static readonly bool IsWin7orLater; // Is Windows 7 or later
|
||||
internal static readonly bool IsWin8orLater; // Is Windows 8 or later
|
||||
|
||||
// We use it safe so assert
|
||||
[EnvironmentPermission(SecurityAction.Assert, Unrestricted = true)]
|
||||
[ResourceExposure(ResourceScope.None)]
|
||||
[ResourceConsumption(ResourceScope.AppDomain, ResourceScope.AppDomain)]
|
||||
static ComNetOS()
|
||||
{
|
||||
OperatingSystem operatingSystem = Environment.OSVersion;
|
||||
|
||||
GlobalLog.Print("ComNetOS::.ctor(): " + operatingSystem.ToString());
|
||||
|
||||
Debug.Assert(operatingSystem.Platform != PlatformID.Win32Windows, "Windows 9x is not supported");
|
||||
|
||||
var Win7Version = new Version(6, 1);
|
||||
var Win8Version = new Version(6, 2);
|
||||
IsWin7orLater = (operatingSystem.Version >= Win7Version);
|
||||
IsWin8orLater = (operatingSystem.Version >= Win8Version);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="Constants.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
internal static class Constants
|
||||
{
|
||||
internal const string VersionKey = "owin.Version";
|
||||
internal const string OwinVersion = "1.0";
|
||||
|
||||
internal const string RequestBodyKey = "owin.RequestBody";
|
||||
internal const string RequestHeadersKey = "owin.RequestHeaders";
|
||||
internal const string RequestSchemeKey = "owin.RequestScheme";
|
||||
internal const string RequestMethodKey = "owin.RequestMethod";
|
||||
internal const string RequestPathBaseKey = "owin.RequestPathBase";
|
||||
internal const string RequestPathKey = "owin.RequestPath";
|
||||
internal const string RequestQueryStringKey = "owin.RequestQueryString";
|
||||
internal const string HttpRequestProtocolKey = "owin.RequestProtocol";
|
||||
|
||||
internal const string HttpResponseProtocolKey = "owin.ResponseProtocol";
|
||||
internal const string ResponseStatusCodeKey = "owin.ResponseStatusCode";
|
||||
internal const string ResponseReasonPhraseKey = "owin.ResponseReasonPhrase";
|
||||
internal const string ResponseHeadersKey = "owin.ResponseHeaders";
|
||||
internal const string ResponseBodyKey = "owin.ResponseBody";
|
||||
|
||||
internal const string ClientCertifiateKey = "ssl.ClientCertificate";
|
||||
internal const string SslSpnKey = "ssl.Spn";
|
||||
internal const string SslChannelBindingKey = "ssl.ChannelBinding";
|
||||
|
||||
internal const string RemoteIpAddressKey = "server.RemoteIpAddress";
|
||||
internal const string RemotePortKey = "server.RemotePort";
|
||||
internal const string LocalIpAddressKey = "server.LocalIpAddress";
|
||||
internal const string LocalPortKey = "server.LocalPort";
|
||||
internal const string IsLocalKey = "server.IsLocal";
|
||||
internal const string ServerOnSendingHeadersKey = "server.OnSendingHeaders";
|
||||
internal const string ServerUserKey = "server.User";
|
||||
internal const string ServerConnectionIdKey = "server.ConnectionId";
|
||||
internal const string ServerConnectionDisconnectKey = "server.ConnectionDisconnect";
|
||||
}
|
||||
}
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="DictionaryExtensions.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace System.Collections.Generic
|
||||
{
|
||||
internal static class DictionaryExtensions
|
||||
{
|
||||
internal static void Append(this IDictionary<string, string[]> dictionary, string key, string value)
|
||||
{
|
||||
string[] orriginalValues;
|
||||
if (dictionary.TryGetValue(key, out orriginalValues))
|
||||
{
|
||||
string[] newValues = new string[orriginalValues.Length + 1];
|
||||
orriginalValues.CopyTo(newValues, 0);
|
||||
newValues[newValues.Length - 1] = value;
|
||||
dictionary[key] = newValues;
|
||||
}
|
||||
else
|
||||
{
|
||||
dictionary[key] = new string[] { value };
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Append(this IDictionary<string, string[]> dictionary, string key, IList<string> values)
|
||||
{
|
||||
string[] orriginalValues;
|
||||
if (dictionary.TryGetValue(key, out orriginalValues))
|
||||
{
|
||||
string[] newValues = new string[orriginalValues.Length + values.Count];
|
||||
orriginalValues.CopyTo(newValues, 0);
|
||||
values.CopyTo(newValues, orriginalValues.Length);
|
||||
dictionary[key] = newValues;
|
||||
}
|
||||
else
|
||||
{
|
||||
dictionary[key] = values.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
internal static string Get(this IDictionary<string, string[]> dictionary, string key)
|
||||
{
|
||||
string[] values;
|
||||
if (dictionary.TryGetValue(key, out values))
|
||||
{
|
||||
return string.Join(", ", values);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static T Get<T>(this IDictionary<string, object> dictionary, string key, T fallback = default(T))
|
||||
{
|
||||
object values;
|
||||
if (dictionary.TryGetValue(key, out values))
|
||||
{
|
||||
return (T)values;
|
||||
}
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,170 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="DigestCache.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Threading;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
// Saves generated digest challenges so that they are still valid when the authenticated request arrives.
|
||||
internal class DigestCache : IDisposable
|
||||
{
|
||||
private const int DigestLifetimeSeconds = 300;
|
||||
private const int MaximumDigests = 1024; // Must be a power of two.
|
||||
private const int MinimumDigestLifetimeSeconds = 10;
|
||||
|
||||
private DigestContext[] _savedDigests;
|
||||
private ArrayList _extraSavedDigests;
|
||||
private ArrayList _extraSavedDigestsBaking;
|
||||
private int _extraSavedDigestsTimestamp;
|
||||
private int _newestContext;
|
||||
private int _oldestContext;
|
||||
|
||||
internal DigestCache()
|
||||
{
|
||||
}
|
||||
|
||||
internal void SaveDigestContext(NTAuthentication digestContext)
|
||||
{
|
||||
if (_savedDigests == null)
|
||||
{
|
||||
Interlocked.CompareExchange<DigestContext[]>(ref _savedDigests, new DigestContext[MaximumDigests], null);
|
||||
}
|
||||
|
||||
// We want to actually close the contexts outside the lock.
|
||||
NTAuthentication oldContext = null;
|
||||
ArrayList digestsToClose = null;
|
||||
lock (_savedDigests)
|
||||
{
|
||||
int now = ((now = Environment.TickCount) == 0 ? 1 : now);
|
||||
|
||||
_newestContext = (_newestContext + 1) & (MaximumDigests - 1);
|
||||
|
||||
int oldTimestamp = _savedDigests[_newestContext].timestamp;
|
||||
oldContext = _savedDigests[_newestContext].context;
|
||||
_savedDigests[_newestContext].timestamp = now;
|
||||
_savedDigests[_newestContext].context = digestContext;
|
||||
|
||||
// May need to move this up.
|
||||
if (_oldestContext == _newestContext)
|
||||
{
|
||||
_oldestContext = (_newestContext + 1) & (MaximumDigests - 1);
|
||||
}
|
||||
|
||||
// Delete additional contexts older than five minutes.
|
||||
while (unchecked(now - _savedDigests[_oldestContext].timestamp) >= DigestLifetimeSeconds && _savedDigests[_oldestContext].context != null)
|
||||
{
|
||||
if (digestsToClose == null)
|
||||
{
|
||||
digestsToClose = new ArrayList();
|
||||
}
|
||||
digestsToClose.Add(_savedDigests[_oldestContext].context);
|
||||
_savedDigests[_oldestContext].context = null;
|
||||
_oldestContext = (_oldestContext + 1) & (MaximumDigests - 1);
|
||||
}
|
||||
|
||||
// If the old context is younger than 10 seconds, put it in the backup pile.
|
||||
if (oldContext != null && unchecked(now - oldTimestamp) <= MinimumDigestLifetimeSeconds * 1000)
|
||||
{
|
||||
// Use a two-tier ArrayList system to guarantee each entry lives at least 10 seconds.
|
||||
if (_extraSavedDigests == null ||
|
||||
unchecked(now - _extraSavedDigestsTimestamp) > MinimumDigestLifetimeSeconds * 1000)
|
||||
{
|
||||
digestsToClose = _extraSavedDigestsBaking;
|
||||
_extraSavedDigestsBaking = _extraSavedDigests;
|
||||
_extraSavedDigestsTimestamp = now;
|
||||
_extraSavedDigests = new ArrayList();
|
||||
}
|
||||
_extraSavedDigests.Add(oldContext);
|
||||
oldContext = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (oldContext != null)
|
||||
{
|
||||
oldContext.CloseContext();
|
||||
}
|
||||
if (digestsToClose != null)
|
||||
{
|
||||
for (int i = 0; i < digestsToClose.Count; i++)
|
||||
{
|
||||
((NTAuthentication)digestsToClose[i]).CloseContext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearDigestCache()
|
||||
{
|
||||
if (_savedDigests == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayList[] toClose = new ArrayList[3];
|
||||
lock (_savedDigests)
|
||||
{
|
||||
toClose[0] = _extraSavedDigestsBaking;
|
||||
_extraSavedDigestsBaking = null;
|
||||
toClose[1] = _extraSavedDigests;
|
||||
_extraSavedDigests = null;
|
||||
|
||||
_newestContext = 0;
|
||||
_oldestContext = 0;
|
||||
|
||||
toClose[2] = new ArrayList();
|
||||
for (int i = 0; i < MaximumDigests; i++)
|
||||
{
|
||||
if (_savedDigests[i].context != null)
|
||||
{
|
||||
toClose[2].Add(_savedDigests[i].context);
|
||||
_savedDigests[i].context = null;
|
||||
}
|
||||
_savedDigests[i].timestamp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < toClose.Length; j++)
|
||||
{
|
||||
if (toClose[j] != null)
|
||||
{
|
||||
for (int k = 0; k < toClose[j].Count; k++)
|
||||
{
|
||||
((NTAuthentication)toClose[j][k]).CloseContext();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
ClearDigestCache();
|
||||
}
|
||||
|
||||
private struct DigestContext
|
||||
{
|
||||
internal NTAuthentication context;
|
||||
internal int timestamp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="DisconnectAsyncResult.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Security.Principal;
|
||||
using System.Threading;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
// Keeps NTLM/Negotiate auth contexts alive until the connection is broken.
|
||||
internal class DisconnectAsyncResult
|
||||
{
|
||||
private const string NTLM = "NTLM";
|
||||
|
||||
private object _connectionId;
|
||||
private WindowsAuthMiddleware _winAuth;
|
||||
private CancellationTokenRegistration _disconnectRegistration;
|
||||
|
||||
private WindowsPrincipal _authenticatedUser;
|
||||
private NTAuthentication _session;
|
||||
|
||||
internal DisconnectAsyncResult(WindowsAuthMiddleware winAuth, object connectionId, CancellationToken connectionDisconnect)
|
||||
{
|
||||
GlobalLog.Print("DisconnectAsyncResult#" + ValidationHelper.HashString(this) + "::.ctor() httpListener#" + ValidationHelper.HashString(winAuth) + " connectionId:" + connectionId);
|
||||
_winAuth = winAuth;
|
||||
_connectionId = connectionId;
|
||||
_winAuth.DisconnectResults[_connectionId] = this;
|
||||
|
||||
// Register with a connection specific CancellationToken. Without this notification, the contexts will leak indefinitely.
|
||||
// Alternatively we could attempt some kind of LRU storage, but this will either have to be larger than your expected connection limit,
|
||||
// or will fail at unexpected moments under stress.
|
||||
try
|
||||
{
|
||||
_disconnectRegistration = connectionDisconnect.Register(HandleDisconnect);
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
_winAuth.DisconnectResults.Remove(_connectionId);
|
||||
}
|
||||
}
|
||||
|
||||
internal WindowsPrincipal AuthenticatedUser
|
||||
{
|
||||
get
|
||||
{
|
||||
return _authenticatedUser;
|
||||
}
|
||||
set
|
||||
{
|
||||
// The previous value can't be disposed because it may be in use by the app.
|
||||
_authenticatedUser = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal NTAuthentication Session
|
||||
{
|
||||
get
|
||||
{
|
||||
return _session;
|
||||
}
|
||||
set
|
||||
{
|
||||
_session = value;
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleDisconnect()
|
||||
{
|
||||
GlobalLog.Print("DisconnectAsyncResult#" + ValidationHelper.HashString(this) + "::HandleDisconnect() DisconnectResults#" + ValidationHelper.HashString(_winAuth.DisconnectResults) + " removing for m_ConnectionId:" + _connectionId);
|
||||
_winAuth.DisconnectResults.Remove(_connectionId);
|
||||
if (_session != null)
|
||||
{
|
||||
_session.CloseContext();
|
||||
}
|
||||
|
||||
// Clean up the identity. This is for scenarios where identity was not cleaned up before due to
|
||||
// identity caching for unsafe ntlm authentication
|
||||
|
||||
IDisposable identity = _authenticatedUser == null ? null : _authenticatedUser.Identity as IDisposable;
|
||||
if ((identity != null) &&
|
||||
(NTLM.Equals(_authenticatedUser.Identity.AuthenticationType, StringComparison.OrdinalIgnoreCase)) &&
|
||||
(_winAuth.UnsafeConnectionNtlmAuthentication))
|
||||
{
|
||||
identity.Dispose();
|
||||
}
|
||||
|
||||
_disconnectRegistration.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,156 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="WebHeaderCollection.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
// we use this static class as a helper class to encode/decode HTTP headers.
|
||||
// what we need is a 1-1 correspondence between a char in the range U+0000-U+00FF
|
||||
// and a byte in the range 0x00-0xFF (which is the range that can hit the network).
|
||||
// The Latin-1 encoding (ISO-88591-1) (GetEncoding(28591)) works for byte[] to string, but is a little slow.
|
||||
// It doesn't work for string -> byte[] because of best-fit-mapping problems.
|
||||
internal static class HeaderEncoding
|
||||
{
|
||||
internal static unsafe string GetString(byte[] bytes, int byteIndex, int byteCount)
|
||||
{
|
||||
fixed (byte* pBytes = bytes)
|
||||
return GetString(pBytes + byteIndex, byteCount);
|
||||
}
|
||||
|
||||
internal static unsafe string GetString(byte* pBytes, int byteCount)
|
||||
{
|
||||
if (byteCount < 1)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
string s = new String('\0', byteCount);
|
||||
|
||||
fixed (char* pStr = s)
|
||||
{
|
||||
char* pString = pStr;
|
||||
while (byteCount >= 8)
|
||||
{
|
||||
pString[0] = (char)pBytes[0];
|
||||
pString[1] = (char)pBytes[1];
|
||||
pString[2] = (char)pBytes[2];
|
||||
pString[3] = (char)pBytes[3];
|
||||
pString[4] = (char)pBytes[4];
|
||||
pString[5] = (char)pBytes[5];
|
||||
pString[6] = (char)pBytes[6];
|
||||
pString[7] = (char)pBytes[7];
|
||||
pString += 8;
|
||||
pBytes += 8;
|
||||
byteCount -= 8;
|
||||
}
|
||||
for (int i = 0; i < byteCount; i++)
|
||||
{
|
||||
pString[i] = (char)pBytes[i];
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
internal static int GetByteCount(string myString)
|
||||
{
|
||||
return myString.Length;
|
||||
}
|
||||
internal static unsafe void GetBytes(string myString, int charIndex, int charCount, byte[] bytes, int byteIndex)
|
||||
{
|
||||
if (myString.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
fixed (byte* bufferPointer = bytes)
|
||||
{
|
||||
byte* newBufferPointer = bufferPointer + byteIndex;
|
||||
int finalIndex = charIndex + charCount;
|
||||
while (charIndex < finalIndex)
|
||||
{
|
||||
*newBufferPointer++ = (byte)myString[charIndex++];
|
||||
}
|
||||
}
|
||||
}
|
||||
internal static unsafe byte[] GetBytes(string myString)
|
||||
{
|
||||
byte[] bytes = new byte[myString.Length];
|
||||
if (myString.Length != 0)
|
||||
{
|
||||
GetBytes(myString, 0, myString.Length, bytes, 0);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
// The normal client header parser just casts bytes to chars (see GetString).
|
||||
// Check if those bytes were actually utf-8 instead of ASCII.
|
||||
// If not, just return the input value.
|
||||
|
||||
internal static string DecodeUtf8FromString(string input)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(input))
|
||||
{
|
||||
return input;
|
||||
}
|
||||
|
||||
bool possibleUtf8 = false;
|
||||
for (int i = 0; i < input.Length; i++)
|
||||
{
|
||||
if (input[i] > (char)255)
|
||||
{
|
||||
return input; // This couldn't have come from the wire, someone assigned it directly.
|
||||
}
|
||||
else if (input[i] > (char)127)
|
||||
{
|
||||
possibleUtf8 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (possibleUtf8)
|
||||
{
|
||||
byte[] rawBytes = new byte[input.Length];
|
||||
for (int i = 0; i < input.Length; i++)
|
||||
{
|
||||
if (input[i] > (char)255)
|
||||
{
|
||||
return input; // This couldn't have come from the wire, someone assigned it directly.
|
||||
}
|
||||
rawBytes[i] = (byte)input[i];
|
||||
}
|
||||
try
|
||||
{
|
||||
// We don't want '?' replacement characters, just fail.
|
||||
Encoding decoder = Encoding.GetEncoding("utf-8", EncoderFallback.ExceptionFallback,
|
||||
DecoderFallback.ExceptionFallback);
|
||||
return decoder.GetString(rawBytes);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
} // Not actually Utf-8
|
||||
}
|
||||
return input;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="HttpKnownHeaderNames.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
internal static class HttpKnownHeaderNames
|
||||
{
|
||||
public const string CacheControl = "Cache-Control";
|
||||
public const string Connection = "Connection";
|
||||
public const string Date = "Date";
|
||||
public const string KeepAlive = "Keep-Alive";
|
||||
public const string Pragma = "Pragma";
|
||||
public const string ProxyConnection = "Proxy-Connection";
|
||||
public const string Trailer = "Trailer";
|
||||
public const string TransferEncoding = "Transfer-Encoding";
|
||||
public const string Upgrade = "Upgrade";
|
||||
public const string Via = "Via";
|
||||
public const string Warning = "Warning";
|
||||
public const string ContentLength = "Content-Length";
|
||||
public const string ContentType = "Content-Type";
|
||||
public const string ContentDisposition = "Content-Disposition";
|
||||
public const string ContentEncoding = "Content-Encoding";
|
||||
public const string ContentLanguage = "Content-Language";
|
||||
public const string ContentLocation = "Content-Location";
|
||||
public const string ContentRange = "Content-Range";
|
||||
public const string Expires = "Expires";
|
||||
public const string LastModified = "Last-Modified";
|
||||
public const string Age = "Age";
|
||||
public const string Location = "Location";
|
||||
public const string ProxyAuthenticate = "Proxy-Authenticate";
|
||||
public const string RetryAfter = "Retry-After";
|
||||
public const string Server = "Server";
|
||||
public const string SetCookie = "Set-Cookie";
|
||||
public const string SetCookie2 = "Set-Cookie2";
|
||||
public const string Vary = "Vary";
|
||||
public const string WWWAuthenticate = "WWW-Authenticate";
|
||||
public const string Accept = "Accept";
|
||||
public const string AcceptCharset = "Accept-Charset";
|
||||
public const string AcceptEncoding = "Accept-Encoding";
|
||||
public const string AcceptLanguage = "Accept-Language";
|
||||
public const string Authorization = "Authorization";
|
||||
public const string Cookie = "Cookie";
|
||||
public const string Cookie2 = "Cookie2";
|
||||
public const string Expect = "Expect";
|
||||
public const string From = "From";
|
||||
public const string Host = "Host";
|
||||
public const string IfMatch = "If-Match";
|
||||
public const string IfModifiedSince = "If-Modified-Since";
|
||||
public const string IfNoneMatch = "If-None-Match";
|
||||
public const string IfRange = "If-Range";
|
||||
public const string IfUnmodifiedSince = "If-Unmodified-Since";
|
||||
public const string MaxForwards = "Max-Forwards";
|
||||
public const string ProxyAuthorization = "Proxy-Authorization";
|
||||
public const string Referer = "Referer";
|
||||
public const string Range = "Range";
|
||||
public const string UserAgent = "User-Agent";
|
||||
public const string ContentMD5 = "Content-MD5";
|
||||
public const string ETag = "ETag";
|
||||
public const string TE = "TE";
|
||||
public const string Allow = "Allow";
|
||||
public const string AcceptRanges = "Accept-Ranges";
|
||||
public const string P3P = "P3P";
|
||||
public const string XPoweredBy = "X-Powered-By";
|
||||
public const string XAspNetVersion = "X-AspNet-Version";
|
||||
public const string SecWebSocketKey = "Sec-WebSocket-Key";
|
||||
public const string SecWebSocketExtensions = "Sec-WebSocket-Extensions";
|
||||
public const string SecWebSocketAccept = "Sec-WebSocket-Accept";
|
||||
public const string Origin = "Origin";
|
||||
public const string SecWebSocketProtocol = "Sec-WebSocket-Protocol";
|
||||
public const string SecWebSocketVersion = "Sec-WebSocket-Version";
|
||||
}
|
||||
}
|
||||
|
|
@ -1,331 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="HttpStatusCode.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
// Redirect Status code numbers that need to be defined.
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Contains the values of status
|
||||
/// codes defined for the HTTP protocol.</para>
|
||||
/// </devdoc>
|
||||
// UEUE : Any int can be cast to a HttpStatusCode to allow checking for non http1.1 codes.
|
||||
internal enum HttpStatusCode
|
||||
{
|
||||
// Informational 1xx
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
Continue = 100,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
SwitchingProtocols = 101,
|
||||
|
||||
// Successful 2xx
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
OK = 200,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
Created = 201,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
Accepted = 202,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
NonAuthoritativeInformation = 203,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
NoContent = 204,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
ResetContent = 205,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
PartialContent = 206,
|
||||
|
||||
// Redirection 3xx
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
MultipleChoices = 300,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
Ambiguous = 300,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
MovedPermanently = 301,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
Moved = 301,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
Found = 302,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
Redirect = 302,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
SeeOther = 303,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
RedirectMethod = 303,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
NotModified = 304,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
UseProxy = 305,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
Unused = 306,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
TemporaryRedirect = 307,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
RedirectKeepVerb = 307,
|
||||
|
||||
// Client Error 4xx
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
BadRequest = 400,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
Unauthorized = 401,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
PaymentRequired = 402,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
Forbidden = 403,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
NotFound = 404,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
MethodNotAllowed = 405,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
NotAcceptable = 406,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
ProxyAuthenticationRequired = 407,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
RequestTimeout = 408,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
Conflict = 409,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
Gone = 410,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
LengthRequired = 411,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
PreconditionFailed = 412,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
RequestEntityTooLarge = 413,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
RequestUriTooLong = 414,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
UnsupportedMediaType = 415,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
RequestedRangeNotSatisfiable = 416,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
ExpectationFailed = 417,
|
||||
|
||||
UpgradeRequired = 426,
|
||||
|
||||
// Server Error 5xx
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
InternalServerError = 500,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
NotImplemented = 501,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
BadGateway = 502,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
ServiceUnavailable = 503,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
GatewayTimeout = 504,
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>[To be supplied.]</para>
|
||||
/// </devdoc>
|
||||
HttpVersionNotSupported = 505,
|
||||
} // enum HttpStatusCode
|
||||
|
||||
/*
|
||||
Fielding, et al. Standards Track [Page 3]
|
||||
|
||||
RFC 2616 HTTP/1.1 June 1999
|
||||
|
||||
|
||||
10.1 Informational 1xx ...........................................57
|
||||
10.1.1 100 Continue .............................................58
|
||||
10.1.2 101 Switching Protocols ..................................58
|
||||
10.2 Successful 2xx ..............................................58
|
||||
10.2.1 200 OK ...................................................58
|
||||
10.2.2 201 Created ..............................................59
|
||||
10.2.3 202 Accepted .............................................59
|
||||
10.2.4 203 Non-Authoritative Information ........................59
|
||||
10.2.5 204 No Content ...........................................60
|
||||
10.2.6 205 Reset Content ........................................60
|
||||
10.2.7 206 Partial Content ......................................60
|
||||
10.3 Redirection 3xx .............................................61
|
||||
10.3.1 300 Multiple Choices .....................................61
|
||||
10.3.2 301 Moved Permanently ....................................62
|
||||
10.3.3 302 Found ................................................62
|
||||
10.3.4 303 See Other ............................................63
|
||||
10.3.5 304 Not Modified .........................................63
|
||||
10.3.6 305 Use Proxy ............................................64
|
||||
10.3.7 306 (Unused) .............................................64
|
||||
10.3.8 307 Temporary Redirect ...................................65
|
||||
10.4 Client Error 4xx ............................................65
|
||||
10.4.1 400 Bad Request .........................................65
|
||||
10.4.2 401 Unauthorized ........................................66
|
||||
10.4.3 402 Payment Required ....................................66
|
||||
10.4.4 403 Forbidden ...........................................66
|
||||
10.4.5 404 Not Found ...........................................66
|
||||
10.4.6 405 Method Not Allowed ..................................66
|
||||
10.4.7 406 Not Acceptable ......................................67
|
||||
10.4.8 407 Proxy Authentication Required .......................67
|
||||
10.4.9 408 Request Timeout .....................................67
|
||||
10.4.10 409 Conflict ............................................67
|
||||
10.4.11 410 Gone ................................................68
|
||||
10.4.12 411 Length Required .....................................68
|
||||
10.4.13 412 Precondition Failed .................................68
|
||||
10.4.14 413 Request Entity Too Large ............................69
|
||||
10.4.15 414 Request-URI Too Long ................................69
|
||||
10.4.16 415 Unsupported Media Type ..............................69
|
||||
10.4.17 416 Requested Range Not Satisfiable .....................69
|
||||
10.4.18 417 Expectation Failed ..................................70
|
||||
10.5 Server Error 5xx ............................................70
|
||||
10.5.1 500 Internal Server Error ................................70
|
||||
10.5.2 501 Not Implemented ......................................70
|
||||
10.5.3 502 Bad Gateway ..........................................70
|
||||
10.5.4 503 Service Unavailable ..................................70
|
||||
10.5.5 504 Gateway Timeout ......................................71
|
||||
10.5.6 505 HTTP Version Not Supported ...........................71
|
||||
*/
|
||||
} // namespace System.Net
|
||||
|
|
@ -1,150 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="CaseInsensitiveAscii.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System.Collections;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
internal class CaseInsensitiveAscii : IEqualityComparer, IComparer
|
||||
{
|
||||
// ASCII char ToLower table
|
||||
internal static readonly byte[] AsciiToLower = new byte[]
|
||||
{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
|
||||
30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
|
||||
40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
|
||||
50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
|
||||
60, 61, 62, 63, 64, 97, 98, 99, 100, 101, // 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
|
||||
102, 103, 104, 105, 106, 107, 108, 109, 110, 111, // 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
|
||||
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, // 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
|
||||
122, 91, 92, 93, 94, 95, 96, 97, 98, 99, // 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
|
||||
100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
|
||||
110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
|
||||
120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
|
||||
130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
|
||||
140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
|
||||
150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
|
||||
160, 161, 162, 163, 164, 165, 166, 167, 168, 169,
|
||||
170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
|
||||
180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
|
||||
190, 191, 192, 193, 194, 195, 196, 197, 198, 199,
|
||||
200, 201, 202, 203, 204, 205, 206, 207, 208, 209,
|
||||
210, 211, 212, 213, 214, 215, 216, 217, 218, 219,
|
||||
220, 221, 222, 223, 224, 225, 226, 227, 228, 229,
|
||||
230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
|
||||
240, 241, 242, 243, 244, 245, 246, 247, 248, 249,
|
||||
250, 251, 252, 253, 254, 255
|
||||
};
|
||||
|
||||
// ASCII string case insensitive hash function
|
||||
public int GetHashCode(object myObject)
|
||||
{
|
||||
string myString = myObject as string;
|
||||
if (myObject == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int myHashCode = myString.Length;
|
||||
if (myHashCode == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
myHashCode ^= AsciiToLower[(byte)myString[0]] << 24 ^ AsciiToLower[(byte)myString[myHashCode - 1]] << 16;
|
||||
return myHashCode;
|
||||
}
|
||||
|
||||
// ASCII string case insensitive comparer
|
||||
public int Compare(object firstObject, object secondObject)
|
||||
{
|
||||
string firstString = firstObject as string;
|
||||
string secondString = secondObject as string;
|
||||
if (firstString == null)
|
||||
{
|
||||
return secondString == null ? 0 : -1;
|
||||
}
|
||||
if (secondString == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
int result = firstString.Length - secondString.Length;
|
||||
int comparisons = result > 0 ? secondString.Length : firstString.Length;
|
||||
int difference, index = 0;
|
||||
while (index < comparisons)
|
||||
{
|
||||
difference = (int)(AsciiToLower[firstString[index]] - AsciiToLower[secondString[index]]);
|
||||
if (difference != 0)
|
||||
{
|
||||
result = difference;
|
||||
break;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// ASCII string case insensitive hash function
|
||||
private int FastGetHashCode(string myString)
|
||||
{
|
||||
int myHashCode = myString.Length;
|
||||
if (myHashCode != 0)
|
||||
{
|
||||
myHashCode ^= AsciiToLower[(byte)myString[0]] << 24 ^ AsciiToLower[(byte)myString[myHashCode - 1]] << 16;
|
||||
}
|
||||
return myHashCode;
|
||||
}
|
||||
|
||||
// ASCII string case insensitive comparer
|
||||
public new bool Equals(object firstObject, object secondObject)
|
||||
{
|
||||
string firstString = firstObject as string;
|
||||
string secondString = secondObject as string;
|
||||
if (firstString == null)
|
||||
{
|
||||
return secondString == null;
|
||||
}
|
||||
if (secondString != null)
|
||||
{
|
||||
int index = firstString.Length;
|
||||
if (index == secondString.Length)
|
||||
{
|
||||
if (FastGetHashCode(firstString) == FastGetHashCode(secondString))
|
||||
{
|
||||
int comparisons = firstString.Length;
|
||||
while (index > 0)
|
||||
{
|
||||
index--;
|
||||
if (AsciiToLower[firstString[index]] != AsciiToLower[secondString[index]])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,706 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="GlobalLog.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Net;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Security.Permissions;
|
||||
using System.Threading;
|
||||
|
||||
/// <internalonly/>
|
||||
/// <devdoc>
|
||||
/// </devdoc>
|
||||
internal static class GlobalLog
|
||||
{
|
||||
// Logging Initalization - I need to disable Logging code, and limit
|
||||
// the effect it has when it is dissabled, so I use a bool here.
|
||||
//
|
||||
// This can only be set when the logging code is built and enabled.
|
||||
// By specifing the "CSC_DEFINES=/D:TRAVE" in the build environment,
|
||||
// this code will be built and then checks against an enviroment variable
|
||||
// and a BooleanSwitch to see if any of the two have enabled logging.
|
||||
|
||||
private static BaseLoggingObject Logobject = GlobalLog.LoggingInitialize();
|
||||
#if TRAVE
|
||||
internal static LocalDataStoreSlot s_ThreadIdSlot;
|
||||
internal static bool s_UseThreadId;
|
||||
internal static bool s_UseTimeSpan;
|
||||
internal static bool s_DumpWebData;
|
||||
internal static bool s_UsePerfCounter;
|
||||
internal static bool s_DebugCallNesting;
|
||||
internal static bool s_DumpToConsole;
|
||||
internal static int s_MaxDumpSize;
|
||||
internal static string s_RootDirectory;
|
||||
|
||||
//
|
||||
// Logging Config Variables - below are list of consts that can be used to config
|
||||
// the logging,
|
||||
//
|
||||
|
||||
// Max number of lines written into a buffer, before a save is invoked
|
||||
// s_DumpToConsole disables.
|
||||
public const int MaxLinesBeforeSave = 0;
|
||||
|
||||
#endif
|
||||
[ReliabilityContract(Consistency.MayCorruptAppDomain, Cer.None)]
|
||||
private static BaseLoggingObject LoggingInitialize()
|
||||
{
|
||||
#if DEBUG
|
||||
if (GetSwitchValue("SystemNetLogging", "System.Net logging module", false) &&
|
||||
GetSwitchValue("SystemNetLog_ConnectionMonitor", "System.Net connection monitor thread", false))
|
||||
{
|
||||
InitConnectionMonitor();
|
||||
}
|
||||
#endif // DEBUG
|
||||
#if TRAVE
|
||||
// by default we'll log to c:\temp\ so that non interactive services (like w3wp.exe) that don't have environment
|
||||
// variables can easily be debugged, note that the ACLs of the directory might need to be adjusted
|
||||
if (!GetSwitchValue("SystemNetLog_OverrideDefaults", "System.Net log override default settings", false)) {
|
||||
s_ThreadIdSlot = Thread.AllocateDataSlot();
|
||||
s_UseThreadId = true;
|
||||
s_UseTimeSpan = true;
|
||||
s_DumpWebData = true;
|
||||
s_MaxDumpSize = 256;
|
||||
s_UsePerfCounter = true;
|
||||
s_DebugCallNesting = true;
|
||||
s_DumpToConsole = false;
|
||||
s_RootDirectory = "C:\\Temp\\";
|
||||
return new LoggingObject();
|
||||
}
|
||||
if (GetSwitchValue("SystemNetLogging", "System.Net logging module", false)) {
|
||||
s_ThreadIdSlot = Thread.AllocateDataSlot();
|
||||
s_UseThreadId = GetSwitchValue("SystemNetLog_UseThreadId", "System.Net log display system thread id", false);
|
||||
s_UseTimeSpan = GetSwitchValue("SystemNetLog_UseTimeSpan", "System.Net log display ticks as TimeSpan", false);
|
||||
s_DumpWebData = GetSwitchValue("SystemNetLog_DumpWebData", "System.Net log display HTTP send/receive data", false);
|
||||
s_MaxDumpSize = GetSwitchValue("SystemNetLog_MaxDumpSize", "System.Net log max size of display data", 256);
|
||||
s_UsePerfCounter = GetSwitchValue("SystemNetLog_UsePerfCounter", "System.Net log use QueryPerformanceCounter() to get ticks ", false);
|
||||
s_DebugCallNesting = GetSwitchValue("SystemNetLog_DebugCallNesting", "System.Net used to debug call nesting", false);
|
||||
s_DumpToConsole = GetSwitchValue("SystemNetLog_DumpToConsole", "System.Net log to console", false);
|
||||
s_RootDirectory = GetSwitchValue("SystemNetLog_RootDirectory", "System.Net root directory of log file", string.Empty);
|
||||
return new LoggingObject();
|
||||
}
|
||||
#endif // TRAVE
|
||||
return new BaseLoggingObject();
|
||||
}
|
||||
|
||||
#if TRAVE
|
||||
private static string GetSwitchValue(string switchName, string switchDescription, string defaultValue) {
|
||||
new EnvironmentPermission(PermissionState.Unrestricted).Assert();
|
||||
try {
|
||||
defaultValue = Environment.GetEnvironmentVariable(switchName);
|
||||
}
|
||||
finally {
|
||||
EnvironmentPermission.RevertAssert();
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
private static int GetSwitchValue(string switchName, string switchDescription, int defaultValue) {
|
||||
IntegerSwitch theSwitch = new IntegerSwitch(switchName, switchDescription);
|
||||
if (theSwitch.Enabled) {
|
||||
return theSwitch.Value;
|
||||
}
|
||||
new EnvironmentPermission(PermissionState.Unrestricted).Assert();
|
||||
try {
|
||||
string environmentVar = Environment.GetEnvironmentVariable(switchName);
|
||||
if (environmentVar!=null) {
|
||||
defaultValue = Int32.Parse(environmentVar.Trim(), CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
EnvironmentPermission.RevertAssert();
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if TRAVE || DEBUG
|
||||
private static bool GetSwitchValue(string switchName, string switchDescription, bool defaultValue)
|
||||
{
|
||||
BooleanSwitch theSwitch = new BooleanSwitch(switchName, switchDescription);
|
||||
new EnvironmentPermission(PermissionState.Unrestricted).Assert();
|
||||
try
|
||||
{
|
||||
if (theSwitch.Enabled)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
string environmentVar = Environment.GetEnvironmentVariable(switchName);
|
||||
defaultValue = environmentVar != null && environmentVar.Trim() == "1";
|
||||
}
|
||||
catch (ConfigurationException)
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
EnvironmentPermission.RevertAssert();
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
#endif // TRAVE || DEBUG
|
||||
|
||||
// Enables thread tracing, detects mis-use of threads.
|
||||
#if DEBUG
|
||||
[ThreadStatic]
|
||||
private static Stack<ThreadKinds> t_ThreadKindStack;
|
||||
|
||||
private static Stack<ThreadKinds> ThreadKindStack
|
||||
{
|
||||
get
|
||||
{
|
||||
if (t_ThreadKindStack == null)
|
||||
{
|
||||
t_ThreadKindStack = new Stack<ThreadKinds>();
|
||||
}
|
||||
return t_ThreadKindStack;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
internal static ThreadKinds CurrentThreadKind
|
||||
{
|
||||
get
|
||||
{
|
||||
#if DEBUG
|
||||
return ThreadKindStack.Count > 0 ? ThreadKindStack.Peek() : ThreadKinds.Other;
|
||||
#else
|
||||
return ThreadKinds.Unknown;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
private static bool HasShutdownStarted
|
||||
{
|
||||
get
|
||||
{
|
||||
return Environment.HasShutdownStarted || AppDomain.CurrentDomain.IsFinalizingForUnload();
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
// ifdef'd instead of conditional since people are forced to handle the return value.
|
||||
// [Conditional("DEBUG")]
|
||||
[ReliabilityContract(Consistency.MayCorruptAppDomain, Cer.None)]
|
||||
internal static IDisposable SetThreadKind(ThreadKinds kind)
|
||||
{
|
||||
if ((kind & ThreadKinds.SourceMask) != ThreadKinds.Unknown)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
// Ignore during shutdown.
|
||||
if (HasShutdownStarted)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
ThreadKinds threadKind = CurrentThreadKind;
|
||||
ThreadKinds source = threadKind & ThreadKinds.SourceMask;
|
||||
|
||||
#if TRAVE
|
||||
// Special warnings when doing dangerous things on a thread.
|
||||
if ((threadKind & ThreadKinds.User) != 0 && (kind & ThreadKinds.System) != 0)
|
||||
{
|
||||
Print("WARNING: Thread changed from User to System; user's thread shouldn't be hijacked.");
|
||||
}
|
||||
|
||||
if ((threadKind & ThreadKinds.Async) != 0 && (kind & ThreadKinds.Sync) != 0)
|
||||
{
|
||||
Print("WARNING: Thread changed from Async to Sync, may block an Async thread.");
|
||||
}
|
||||
else if ((threadKind & (ThreadKinds.Other | ThreadKinds.CompletionPort)) == 0 && (kind & ThreadKinds.Sync) != 0)
|
||||
{
|
||||
Print("WARNING: Thread from a limited resource changed to Sync, may deadlock or bottleneck.");
|
||||
}
|
||||
#endif
|
||||
|
||||
ThreadKindStack.Push(
|
||||
(((kind & ThreadKinds.OwnerMask) == 0 ? threadKind : kind) & ThreadKinds.OwnerMask) |
|
||||
(((kind & ThreadKinds.SyncMask) == 0 ? threadKind : kind) & ThreadKinds.SyncMask) |
|
||||
(kind & ~(ThreadKinds.OwnerMask | ThreadKinds.SyncMask)) |
|
||||
source);
|
||||
|
||||
#if TRAVE
|
||||
if (CurrentThreadKind != threadKind)
|
||||
{
|
||||
Print("Thread becomes:(" + CurrentThreadKind.ToString() + ")");
|
||||
}
|
||||
#endif
|
||||
|
||||
return new ThreadKindFrame();
|
||||
}
|
||||
|
||||
private class ThreadKindFrame : IDisposable
|
||||
{
|
||||
private int m_FrameNumber;
|
||||
|
||||
internal ThreadKindFrame()
|
||||
{
|
||||
m_FrameNumber = ThreadKindStack.Count;
|
||||
}
|
||||
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
// Ignore during shutdown.
|
||||
if (GlobalLog.HasShutdownStarted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_FrameNumber != ThreadKindStack.Count)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
ThreadKinds previous = ThreadKindStack.Pop();
|
||||
|
||||
#if TRAVE
|
||||
if (CurrentThreadKind != previous)
|
||||
{
|
||||
Print("Thread reverts:(" + CurrentThreadKind.ToString() + ")");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
[ReliabilityContract(Consistency.MayCorruptAppDomain, Cer.None)]
|
||||
internal static void SetThreadSource(ThreadKinds source)
|
||||
{
|
||||
#if DEBUG
|
||||
if ((source & ThreadKinds.SourceMask) != source || source == ThreadKinds.Unknown)
|
||||
{
|
||||
throw new ArgumentException("Must specify the thread source.", "source");
|
||||
}
|
||||
|
||||
if (ThreadKindStack.Count == 0)
|
||||
{
|
||||
ThreadKindStack.Push(source);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ThreadKindStack.Count > 1)
|
||||
{
|
||||
Print("WARNING: SetThreadSource must be called at the base of the stack, or the stack has been corrupted.");
|
||||
while (ThreadKindStack.Count > 1)
|
||||
{
|
||||
ThreadKindStack.Pop();
|
||||
}
|
||||
}
|
||||
|
||||
if (ThreadKindStack.Peek() != source)
|
||||
{
|
||||
// SQL can fail to clean up the stack, leaving the default Other at the bottom. Replace it.
|
||||
Print("WARNING: The stack has been corrupted.");
|
||||
ThreadKinds last = ThreadKindStack.Pop() & ThreadKinds.SourceMask;
|
||||
Assert(last == source || last == ThreadKinds.Other, "Thread source changed.|Was:({0}) Now:({1})", last, source);
|
||||
ThreadKindStack.Push(source);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
[ReliabilityContract(Consistency.MayCorruptAppDomain, Cer.None)]
|
||||
internal static void ThreadContract(ThreadKinds kind, string errorMsg)
|
||||
{
|
||||
ThreadContract(kind, ThreadKinds.SafeSources, errorMsg);
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
[ReliabilityContract(Consistency.MayCorruptAppDomain, Cer.None)]
|
||||
internal static void ThreadContract(ThreadKinds kind, ThreadKinds allowedSources, string errorMsg)
|
||||
{
|
||||
if ((kind & ThreadKinds.SourceMask) != ThreadKinds.Unknown || (allowedSources & ThreadKinds.SourceMask) != allowedSources)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
ThreadKinds threadKind = CurrentThreadKind;
|
||||
Assert((threadKind & allowedSources) != 0, errorMsg, "Thread Contract Violation.|Expected source:({0}) Actual source:({1})", allowedSources, threadKind & ThreadKinds.SourceMask);
|
||||
Assert((threadKind & kind) == kind, errorMsg, "Thread Contract Violation.|Expected kind:({0}) Actual kind:({1})", kind, threadKind & ~ThreadKinds.SourceMask);
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
// Enables auto-hang detection, which will "snap" a log on hang
|
||||
internal static bool EnableMonitorThread = false;
|
||||
|
||||
// Default value for hang timer
|
||||
#if FEATURE_PAL // ROTORTODO - after speedups (like real JIT and GC) remove this
|
||||
public const int DefaultTickValue = 1000*60*5; // 5 minutes
|
||||
#else
|
||||
public const int DefaultTickValue = 1000 * 60; // 60 secs
|
||||
#endif // FEATURE_PAL
|
||||
#endif // DEBUG
|
||||
|
||||
[System.Diagnostics.Conditional("TRAVE")]
|
||||
public static void AddToArray(string msg)
|
||||
{
|
||||
#if TRAVE
|
||||
GlobalLog.Logobject.PrintLine(msg);
|
||||
#endif
|
||||
}
|
||||
|
||||
[System.Diagnostics.Conditional("TRAVE")]
|
||||
public static void Ignore(object msg)
|
||||
{
|
||||
}
|
||||
|
||||
[System.Diagnostics.Conditional("TRAVE")]
|
||||
[ReliabilityContract(Consistency.MayCorruptAppDomain, Cer.None)]
|
||||
public static void Print(string msg)
|
||||
{
|
||||
#if TRAVE
|
||||
GlobalLog.Logobject.PrintLine(msg);
|
||||
#endif
|
||||
}
|
||||
|
||||
[System.Diagnostics.Conditional("TRAVE")]
|
||||
public static void PrintHex(string msg, object value)
|
||||
{
|
||||
#if TRAVE
|
||||
GlobalLog.Logobject.PrintLine(msg+TraveHelper.ToHex(value));
|
||||
#endif
|
||||
}
|
||||
|
||||
[System.Diagnostics.Conditional("TRAVE")]
|
||||
public static void Enter(string func)
|
||||
{
|
||||
#if TRAVE
|
||||
GlobalLog.Logobject.EnterFunc(func + "(*none*)");
|
||||
#endif
|
||||
}
|
||||
|
||||
[System.Diagnostics.Conditional("TRAVE")]
|
||||
public static void Enter(string func, string parms)
|
||||
{
|
||||
#if TRAVE
|
||||
GlobalLog.Logobject.EnterFunc(func + "(" + parms + ")");
|
||||
#endif
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
[Conditional("_FORCE_ASSERTS")]
|
||||
[ReliabilityContract(Consistency.MayCorruptAppDomain, Cer.None)]
|
||||
public static void Assert(bool condition, string messageFormat, params object[] data)
|
||||
{
|
||||
if (!condition)
|
||||
{
|
||||
string fullMessage = string.Format(CultureInfo.InvariantCulture, messageFormat, data);
|
||||
int pipeIndex = fullMessage.IndexOf('|');
|
||||
if (pipeIndex == -1)
|
||||
{
|
||||
Assert(fullMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
int detailLength = fullMessage.Length - pipeIndex - 1;
|
||||
Assert(fullMessage.Substring(0, pipeIndex), detailLength > 0 ? fullMessage.Substring(pipeIndex + 1, detailLength) : null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
[Conditional("_FORCE_ASSERTS")]
|
||||
[ReliabilityContract(Consistency.MayCorruptAppDomain, Cer.None)]
|
||||
public static void Assert(string message)
|
||||
{
|
||||
Assert(message, null);
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
[Conditional("_FORCE_ASSERTS")]
|
||||
[ReliabilityContract(Consistency.MayCorruptAppDomain, Cer.None)]
|
||||
public static void Assert(string message, string detailMessage)
|
||||
{
|
||||
try
|
||||
{
|
||||
Print("Assert: " + message + (!string.IsNullOrEmpty(detailMessage) ? ": " + detailMessage : string.Empty));
|
||||
Print("*******");
|
||||
Logobject.DumpArray(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
#if DEBUG && !STRESS
|
||||
Debug.Assert(false, message, detailMessage);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
[System.Diagnostics.Conditional("TRAVE")]
|
||||
public static void LeaveException(string func, Exception exception)
|
||||
{
|
||||
#if TRAVE
|
||||
GlobalLog.Logobject.LeaveFunc(func + " exception " + ((exception!=null) ? exception.Message : String.Empty));
|
||||
#endif
|
||||
}
|
||||
|
||||
[System.Diagnostics.Conditional("TRAVE")]
|
||||
public static void Leave(string func)
|
||||
{
|
||||
#if TRAVE
|
||||
GlobalLog.Logobject.LeaveFunc(func + " returns ");
|
||||
#endif
|
||||
}
|
||||
|
||||
[System.Diagnostics.Conditional("TRAVE")]
|
||||
public static void Leave(string func, string result)
|
||||
{
|
||||
#if TRAVE
|
||||
GlobalLog.Logobject.LeaveFunc(func + " returns " + result);
|
||||
#endif
|
||||
}
|
||||
|
||||
[System.Diagnostics.Conditional("TRAVE")]
|
||||
public static void Leave(string func, int returnval)
|
||||
{
|
||||
#if TRAVE
|
||||
GlobalLog.Logobject.LeaveFunc(func + " returns " + returnval.ToString());
|
||||
#endif
|
||||
}
|
||||
|
||||
[System.Diagnostics.Conditional("TRAVE")]
|
||||
public static void Leave(string func, bool returnval)
|
||||
{
|
||||
#if TRAVE
|
||||
GlobalLog.Logobject.LeaveFunc(func + " returns " + returnval.ToString());
|
||||
#endif
|
||||
}
|
||||
|
||||
[System.Diagnostics.Conditional("TRAVE")]
|
||||
public static void DumpArray()
|
||||
{
|
||||
#if TRAVE
|
||||
GlobalLog.Logobject.DumpArray(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
[System.Diagnostics.Conditional("TRAVE")]
|
||||
public static void Dump(byte[] buffer)
|
||||
{
|
||||
#if TRAVE
|
||||
Logobject.Dump(buffer, 0, buffer!=null ? buffer.Length : -1);
|
||||
#endif
|
||||
}
|
||||
|
||||
[System.Diagnostics.Conditional("TRAVE")]
|
||||
public static void Dump(byte[] buffer, int length)
|
||||
{
|
||||
#if TRAVE
|
||||
Logobject.Dump(buffer, 0, length);
|
||||
#endif
|
||||
}
|
||||
|
||||
[System.Diagnostics.Conditional("TRAVE")]
|
||||
public static void Dump(byte[] buffer, int offset, int length)
|
||||
{
|
||||
#if TRAVE
|
||||
Logobject.Dump(buffer, offset, length);
|
||||
#endif
|
||||
}
|
||||
|
||||
[System.Diagnostics.Conditional("TRAVE")]
|
||||
public static void Dump(IntPtr buffer, int offset, int length)
|
||||
{
|
||||
#if TRAVE
|
||||
Logobject.Dump(buffer, offset, length);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
private class HttpWebRequestComparer : IComparer
|
||||
{
|
||||
public int Compare(
|
||||
object x1,
|
||||
object y1)
|
||||
{
|
||||
HttpWebRequest x = (HttpWebRequest)x1;
|
||||
HttpWebRequest y = (HttpWebRequest)y1;
|
||||
|
||||
if (x.GetHashCode() == y.GetHashCode())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (x.GetHashCode() < y.GetHashCode())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (x.GetHashCode() > y.GetHashCode())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*
|
||||
private class ConnectionMonitorEntry {
|
||||
public HttpWebRequest m_Request;
|
||||
public int m_Flags;
|
||||
public DateTime m_TimeAdded;
|
||||
public Connection m_Connection;
|
||||
|
||||
public ConnectionMonitorEntry(HttpWebRequest request, Connection connection, int flags) {
|
||||
m_Request = request;
|
||||
m_Connection = connection;
|
||||
m_Flags = flags;
|
||||
m_TimeAdded = DateTime.Now;
|
||||
}
|
||||
}
|
||||
*/
|
||||
private static volatile ManualResetEvent s_ShutdownEvent;
|
||||
private static volatile SortedList s_RequestList;
|
||||
|
||||
internal const int WaitingForReadDoneFlag = 0x1;
|
||||
#endif
|
||||
/*
|
||||
#if DEBUG
|
||||
private static void ConnectionMonitor() {
|
||||
while(! s_ShutdownEvent.WaitOne(DefaultTickValue, false)) {
|
||||
if (GlobalLog.EnableMonitorThread) {
|
||||
#if TRAVE
|
||||
GlobalLog.Logobject.LoggingMonitorTick();
|
||||
#endif
|
||||
}
|
||||
|
||||
int hungCount = 0;
|
||||
lock (s_RequestList) {
|
||||
DateTime dateNow = DateTime.Now;
|
||||
DateTime dateExpired = dateNow.AddSeconds(-DefaultTickValue);
|
||||
foreach (ConnectionMonitorEntry monitorEntry in s_RequestList.GetValueList() ) {
|
||||
if (monitorEntry != null &&
|
||||
(dateExpired > monitorEntry.m_TimeAdded))
|
||||
{
|
||||
hungCount++;
|
||||
#if TRAVE
|
||||
GlobalLog.Print("delay:" + (dateNow - monitorEntry.m_TimeAdded).TotalSeconds +
|
||||
" req#" + monitorEntry.m_Request.GetHashCode() +
|
||||
" cnt#" + monitorEntry.m_Connection.GetHashCode() +
|
||||
" flags:" + monitorEntry.m_Flags);
|
||||
|
||||
#endif
|
||||
monitorEntry.m_Connection.Debug(monitorEntry.m_Request.GetHashCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
Assert(hungCount == 0, "Warning: Hang Detected on Connection(s) of greater than {0} ms. {1} request(s) hung.|Please Dump System.Net.GlobalLog.s_RequestList for pending requests, make sure your streams are calling Close(), and that your destination server is up.", DefaultTickValue, hungCount);
|
||||
}
|
||||
}
|
||||
#endif // DEBUG
|
||||
**/
|
||||
#if DEBUG
|
||||
[ReliabilityContract(Consistency.MayCorruptAppDomain, Cer.None)]
|
||||
internal static void AppDomainUnloadEvent(object sender, EventArgs e)
|
||||
{
|
||||
s_ShutdownEvent.Set();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DEBUG
|
||||
[System.Diagnostics.Conditional("DEBUG")]
|
||||
private static void InitConnectionMonitor()
|
||||
{
|
||||
s_RequestList = new SortedList(new HttpWebRequestComparer(), 10);
|
||||
s_ShutdownEvent = new ManualResetEvent(false);
|
||||
AppDomain.CurrentDomain.DomainUnload += new EventHandler(AppDomainUnloadEvent);
|
||||
AppDomain.CurrentDomain.ProcessExit += new EventHandler(AppDomainUnloadEvent);
|
||||
// Thread threadMonitor = new Thread(new ThreadStart(ConnectionMonitor));
|
||||
// threadMonitor.IsBackground = true;
|
||||
// threadMonitor.Start();
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
[System.Diagnostics.Conditional("DEBUG")]
|
||||
internal static void DebugAddRequest(HttpWebRequest request, Connection connection, int flags) {
|
||||
#if DEBUG
|
||||
// null if the connection monitor is off
|
||||
if(s_RequestList == null)
|
||||
return;
|
||||
|
||||
lock(s_RequestList) {
|
||||
Assert(!s_RequestList.ContainsKey(request), "s_RequestList.ContainsKey(request)|A HttpWebRequest should not be submitted twice.");
|
||||
|
||||
ConnectionMonitorEntry requestEntry =
|
||||
new ConnectionMonitorEntry(request, connection, flags);
|
||||
|
||||
try {
|
||||
s_RequestList.Add(request, requestEntry);
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
/*
|
||||
[System.Diagnostics.Conditional("DEBUG")]
|
||||
internal static void DebugRemoveRequest(HttpWebRequest request) {
|
||||
#if DEBUG
|
||||
// null if the connection monitor is off
|
||||
if(s_RequestList == null)
|
||||
return;
|
||||
|
||||
lock(s_RequestList) {
|
||||
Assert(s_RequestList.ContainsKey(request), "!s_RequestList.ContainsKey(request)|A HttpWebRequest should not be removed twice.");
|
||||
|
||||
try {
|
||||
s_RequestList.Remove(request);
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
/*
|
||||
[System.Diagnostics.Conditional("DEBUG")]
|
||||
internal static void DebugUpdateRequest(HttpWebRequest request, Connection connection, int flags) {
|
||||
#if DEBUG
|
||||
// null if the connection monitor is off
|
||||
if(s_RequestList == null)
|
||||
return;
|
||||
|
||||
lock(s_RequestList) {
|
||||
if(!s_RequestList.ContainsKey(request)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConnectionMonitorEntry requestEntry =
|
||||
new ConnectionMonitorEntry(request, connection, flags);
|
||||
|
||||
try {
|
||||
s_RequestList.Remove(request);
|
||||
s_RequestList.Add(request, requestEntry);
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="HttpListenerContext.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Security.Principal;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
// TODO: At what point does a user need to be cleaned up?
|
||||
internal sealed class HttpListenerContext
|
||||
{
|
||||
private WindowsAuthMiddleware _winAuth;
|
||||
private IPrincipal _user = null;
|
||||
|
||||
internal const string NTLM = "NTLM";
|
||||
|
||||
internal HttpListenerContext(WindowsAuthMiddleware httpListener)
|
||||
{
|
||||
_winAuth = httpListener;
|
||||
}
|
||||
|
||||
internal void Close()
|
||||
{
|
||||
if (Logging.On)
|
||||
{
|
||||
Logging.Enter(Logging.HttpListener, this, "Close()", string.Empty);
|
||||
}
|
||||
|
||||
IDisposable user = _user == null ? null : _user.Identity as IDisposable;
|
||||
|
||||
// TODO: At what point does a user need to be cleaned up?
|
||||
|
||||
// For unsafe connection ntlm auth we dont dispose this identity as yet since its cached
|
||||
if ((user != null) &&
|
||||
(_user.Identity.AuthenticationType != NTLM) &&
|
||||
(!_winAuth.UnsafeConnectionNtlmAuthentication))
|
||||
{
|
||||
user.Dispose();
|
||||
}
|
||||
if (Logging.On)
|
||||
{
|
||||
Logging.Exit(Logging.HttpListener, this, "Close", string.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
internal void Abort()
|
||||
{
|
||||
if (Logging.On)
|
||||
{
|
||||
Logging.Enter(Logging.HttpListener, this, "Abort", string.Empty);
|
||||
}
|
||||
|
||||
IDisposable user = _user == null ? null : _user.Identity as IDisposable;
|
||||
if (user != null)
|
||||
{
|
||||
user.Dispose();
|
||||
}
|
||||
if (Logging.On)
|
||||
{
|
||||
Logging.Exit(Logging.HttpListener, this, "Abort", string.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,303 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="Internal.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Net.Security;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Security.Authentication.ExtendedProtection;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Security.Permissions;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
internal enum SecurityStatus
|
||||
{
|
||||
// Success / Informational
|
||||
OK = 0x00000000,
|
||||
ContinueNeeded = unchecked((int)0x00090312),
|
||||
CompleteNeeded = unchecked((int)0x00090313),
|
||||
CompAndContinue = unchecked((int)0x00090314),
|
||||
ContextExpired = unchecked((int)0x00090317),
|
||||
CredentialsNeeded = unchecked((int)0x00090320),
|
||||
Renegotiate = unchecked((int)0x00090321),
|
||||
|
||||
// Errors
|
||||
OutOfMemory = unchecked((int)0x80090300),
|
||||
InvalidHandle = unchecked((int)0x80090301),
|
||||
Unsupported = unchecked((int)0x80090302),
|
||||
TargetUnknown = unchecked((int)0x80090303),
|
||||
InternalError = unchecked((int)0x80090304),
|
||||
PackageNotFound = unchecked((int)0x80090305),
|
||||
NotOwner = unchecked((int)0x80090306),
|
||||
CannotInstall = unchecked((int)0x80090307),
|
||||
InvalidToken = unchecked((int)0x80090308),
|
||||
CannotPack = unchecked((int)0x80090309),
|
||||
QopNotSupported = unchecked((int)0x8009030A),
|
||||
NoImpersonation = unchecked((int)0x8009030B),
|
||||
LogonDenied = unchecked((int)0x8009030C),
|
||||
UnknownCredentials = unchecked((int)0x8009030D),
|
||||
NoCredentials = unchecked((int)0x8009030E),
|
||||
MessageAltered = unchecked((int)0x8009030F),
|
||||
OutOfSequence = unchecked((int)0x80090310),
|
||||
NoAuthenticatingAuthority = unchecked((int)0x80090311),
|
||||
IncompleteMessage = unchecked((int)0x80090318),
|
||||
IncompleteCredentials = unchecked((int)0x80090320),
|
||||
BufferNotEnough = unchecked((int)0x80090321),
|
||||
WrongPrincipal = unchecked((int)0x80090322),
|
||||
TimeSkew = unchecked((int)0x80090324),
|
||||
UntrustedRoot = unchecked((int)0x80090325),
|
||||
IllegalMessage = unchecked((int)0x80090326),
|
||||
CertUnknown = unchecked((int)0x80090327),
|
||||
CertExpired = unchecked((int)0x80090328),
|
||||
AlgorithmMismatch = unchecked((int)0x80090331),
|
||||
SecurityQosFailed = unchecked((int)0x80090332),
|
||||
SmartcardLogonRequired = unchecked((int)0x8009033E),
|
||||
UnsupportedPreauth = unchecked((int)0x80090343),
|
||||
BadBinding = unchecked((int)0x80090346)
|
||||
}
|
||||
|
||||
internal enum ContextAttribute
|
||||
{
|
||||
// look into <sspi.h> and <schannel.h>
|
||||
Sizes = 0x00,
|
||||
Names = 0x01,
|
||||
Lifespan = 0x02,
|
||||
DceInfo = 0x03,
|
||||
StreamSizes = 0x04,
|
||||
// KeyInfo = 0x05, must not be used, see ConnectionInfo instead
|
||||
Authority = 0x06,
|
||||
// SECPKG_ATTR_PROTO_INFO = 7,
|
||||
// SECPKG_ATTR_PASSWORD_EXPIRY = 8,
|
||||
// SECPKG_ATTR_SESSION_KEY = 9,
|
||||
PackageInfo = 0x0A,
|
||||
// SECPKG_ATTR_USER_FLAGS = 11,
|
||||
NegotiationInfo = 0x0C,
|
||||
// SECPKG_ATTR_NATIVE_NAMES = 13,
|
||||
// SECPKG_ATTR_FLAGS = 14,
|
||||
// SECPKG_ATTR_USE_VALIDATED = 15,
|
||||
// SECPKG_ATTR_CREDENTIAL_NAME = 16,
|
||||
// SECPKG_ATTR_TARGET_INFORMATION = 17,
|
||||
// SECPKG_ATTR_ACCESS_TOKEN = 18,
|
||||
// SECPKG_ATTR_TARGET = 19,
|
||||
// SECPKG_ATTR_AUTHENTICATION_ID = 20,
|
||||
UniqueBindings = 0x19,
|
||||
EndpointBindings = 0x1A,
|
||||
ClientSpecifiedSpn = 0x1B, // SECPKG_ATTR_CLIENT_SPECIFIED_TARGET = 27
|
||||
RemoteCertificate = 0x53,
|
||||
LocalCertificate = 0x54,
|
||||
RootStore = 0x55,
|
||||
IssuerListInfoEx = 0x59,
|
||||
ConnectionInfo = 0x5A,
|
||||
// SECPKG_ATTR_EAP_KEY_BLOCK 0x5b // returns SecPkgContext_EapKeyBlock
|
||||
// SECPKG_ATTR_MAPPED_CRED_ATTR 0x5c // returns SecPkgContext_MappedCredAttr
|
||||
// SECPKG_ATTR_SESSION_INFO 0x5d // returns SecPkgContext_SessionInfo
|
||||
// SECPKG_ATTR_APP_DATA 0x5e // sets/returns SecPkgContext_SessionAppData
|
||||
// SECPKG_ATTR_REMOTE_CERTIFICATES 0x5F // returns SecPkgContext_Certificates
|
||||
// SECPKG_ATTR_CLIENT_CERT_POLICY 0x60 // sets SecPkgCred_ClientCertCtlPolicy
|
||||
// SECPKG_ATTR_CC_POLICY_RESULT 0x61 // returns SecPkgContext_ClientCertPolicyResult
|
||||
// SECPKG_ATTR_USE_NCRYPT 0x62 // Sets the CRED_FLAG_USE_NCRYPT_PROVIDER FLAG on cred group
|
||||
// SECPKG_ATTR_LOCAL_CERT_INFO 0x63 // returns SecPkgContext_CertInfo
|
||||
// SECPKG_ATTR_CIPHER_INFO 0x64 // returns new CNG SecPkgContext_CipherInfo
|
||||
// SECPKG_ATTR_EAP_PRF_INFO 0x65 // sets SecPkgContext_EapPrfInfo
|
||||
// SECPKG_ATTR_SUPPORTED_SIGNATURES 0x66 // returns SecPkgContext_SupportedSignatures
|
||||
// SECPKG_ATTR_REMOTE_CERT_CHAIN 0x67 // returns PCCERT_CONTEXT
|
||||
UiInfo = 0x68, // sets SEcPkgContext_UiInfo
|
||||
}
|
||||
|
||||
internal enum Endianness
|
||||
{
|
||||
Network = 0x00,
|
||||
Native = 0x10,
|
||||
}
|
||||
|
||||
internal enum CredentialUse
|
||||
{
|
||||
Inbound = 0x1,
|
||||
Outbound = 0x2,
|
||||
Both = 0x3,
|
||||
}
|
||||
|
||||
internal enum BufferType
|
||||
{
|
||||
Empty = 0x00,
|
||||
Data = 0x01,
|
||||
Token = 0x02,
|
||||
Parameters = 0x03,
|
||||
Missing = 0x04,
|
||||
Extra = 0x05,
|
||||
Trailer = 0x06,
|
||||
Header = 0x07,
|
||||
Padding = 0x09, // non-data padding
|
||||
Stream = 0x0A,
|
||||
ChannelBindings = 0x0E,
|
||||
TargetHost = 0x10,
|
||||
ReadOnlyFlag = unchecked((int)0x80000000),
|
||||
ReadOnlyWithChecksum = 0x10000000
|
||||
}
|
||||
|
||||
// SecPkgContext_IssuerListInfoEx
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct IssuerListInfoEx
|
||||
{
|
||||
public SafeHandle aIssuers;
|
||||
public uint cIssuers;
|
||||
|
||||
public unsafe IssuerListInfoEx(SafeHandle handle, byte[] nativeBuffer)
|
||||
{
|
||||
aIssuers = handle;
|
||||
fixed (byte* voidPtr = nativeBuffer)
|
||||
{
|
||||
// if this breaks on 64 bit, do the sizeof(IntPtr) trick
|
||||
cIssuers = *((uint*)(voidPtr + IntPtr.Size));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct SecureCredential
|
||||
{
|
||||
/*
|
||||
typedef struct _SCHANNEL_CRED
|
||||
{
|
||||
DWORD dwVersion; // always SCHANNEL_CRED_VERSION
|
||||
DWORD cCreds;
|
||||
PCCERT_CONTEXT *paCred;
|
||||
HCERTSTORE hRootStore;
|
||||
|
||||
DWORD cMappers;
|
||||
struct _HMAPPER **aphMappers;
|
||||
|
||||
DWORD cSupportedAlgs;
|
||||
ALG_ID * palgSupportedAlgs;
|
||||
|
||||
DWORD grbitEnabledProtocols;
|
||||
DWORD dwMinimumCipherStrength;
|
||||
DWORD dwMaximumCipherStrength;
|
||||
DWORD dwSessionLifespan;
|
||||
DWORD dwFlags;
|
||||
DWORD reserved;
|
||||
} SCHANNEL_CRED, *PSCHANNEL_CRED;
|
||||
*/
|
||||
|
||||
public const int CurrentVersion = 0x4;
|
||||
|
||||
public int version;
|
||||
public int cCreds;
|
||||
|
||||
// ptr to an array of pointers
|
||||
// There is a hack done with this field. AcquireCredentialsHandle requires an array of
|
||||
// certificate handles; we only ever use one. In order to avoid pinning a one element array,
|
||||
// we copy this value onto the stack, create a pointer on the stack to the copied value,
|
||||
// and replace this field with the pointer, during the call to AcquireCredentialsHandle.
|
||||
// Then we fix it up afterwards. Fine as long as all the SSPI credentials are not
|
||||
// supposed to be threadsafe.
|
||||
public IntPtr certContextArray;
|
||||
|
||||
private readonly IntPtr rootStore; // == always null, OTHERWISE NOT RELIABLE
|
||||
public int cMappers;
|
||||
private readonly IntPtr phMappers; // == always null, OTHERWISE NOT RELIABLE
|
||||
public int cSupportedAlgs;
|
||||
private readonly IntPtr palgSupportedAlgs; // == always null, OTHERWISE NOT RELIABLE
|
||||
public SchProtocols grbitEnabledProtocols;
|
||||
public int dwMinimumCipherStrength;
|
||||
public int dwMaximumCipherStrength;
|
||||
public int dwSessionLifespan;
|
||||
public SecureCredential.Flags dwFlags;
|
||||
public int reserved;
|
||||
|
||||
public SecureCredential(int version, X509Certificate certificate, SecureCredential.Flags flags, SchProtocols protocols, EncryptionPolicy policy)
|
||||
{
|
||||
// default values required for a struct
|
||||
rootStore = phMappers = palgSupportedAlgs = certContextArray = IntPtr.Zero;
|
||||
cCreds = cMappers = cSupportedAlgs = 0;
|
||||
|
||||
if (policy == EncryptionPolicy.RequireEncryption)
|
||||
{
|
||||
// Prohibit null encryption cipher
|
||||
dwMinimumCipherStrength = 0;
|
||||
dwMaximumCipherStrength = 0;
|
||||
}
|
||||
else if (policy == EncryptionPolicy.AllowNoEncryption)
|
||||
{
|
||||
// Allow null encryption cipher in addition to other ciphers
|
||||
dwMinimumCipherStrength = -1;
|
||||
dwMaximumCipherStrength = 0;
|
||||
}
|
||||
else if (policy == EncryptionPolicy.NoEncryption)
|
||||
{
|
||||
// Suppress all encryption and require null encryption cipher only
|
||||
dwMinimumCipherStrength = -1;
|
||||
dwMaximumCipherStrength = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException(SR.GetString(SR.net_invalid_enum, "EncryptionPolicy"), "policy");
|
||||
}
|
||||
|
||||
dwSessionLifespan = reserved = 0;
|
||||
this.version = version;
|
||||
dwFlags = flags;
|
||||
grbitEnabledProtocols = protocols;
|
||||
if (certificate != null)
|
||||
{
|
||||
certContextArray = certificate.Handle;
|
||||
cCreds = 1;
|
||||
}
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum Flags
|
||||
{
|
||||
Zero = 0,
|
||||
NoSystemMapper = 0x02,
|
||||
NoNameCheck = 0x04,
|
||||
ValidateManual = 0x08,
|
||||
NoDefaultCred = 0x10,
|
||||
ValidateAuto = 0x20
|
||||
}
|
||||
} // SecureCredential
|
||||
|
||||
[SuppressMessage("Microsoft.Design", "CA1049:TypesThatOwnNativeResourcesShouldBeDisposable",
|
||||
Justification = "This structure does not own the native resource.")]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal unsafe struct SecurityBufferStruct
|
||||
{
|
||||
public int count;
|
||||
public BufferType type;
|
||||
public IntPtr token;
|
||||
|
||||
public static readonly int Size = sizeof(SecurityBufferStruct);
|
||||
}
|
||||
|
||||
internal static class IntPtrHelper
|
||||
{
|
||||
internal static IntPtr Add(IntPtr a, int b)
|
||||
{
|
||||
return (IntPtr)((long)a + (long)b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,674 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="Logging.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Threading;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
internal class Logging
|
||||
{
|
||||
private const string AttributeNameMaxSize = "maxdatasize";
|
||||
private const string AttributeNameTraceMode = "tracemode";
|
||||
private const string AttributeValueProtocolOnly = "protocolonly";
|
||||
// private const string AttributeValueIncludeHex = "includehex";
|
||||
|
||||
private const int DefaultMaxDumpSize = 1024;
|
||||
private const bool DefaultUseProtocolTextOnly = false;
|
||||
|
||||
private const string TraceSourceWebName = "System.Net";
|
||||
private const string TraceSourceHttpListenerName = "System.Net.HttpListener";
|
||||
|
||||
private static readonly string[] SupportedAttributes = new string[] { AttributeNameMaxSize, AttributeNameTraceMode };
|
||||
|
||||
private static volatile bool s_LoggingEnabled = true;
|
||||
private static volatile bool s_LoggingInitialized;
|
||||
private static volatile bool s_AppDomainShutdown;
|
||||
|
||||
private static TraceSource s_WebTraceSource;
|
||||
private static TraceSource s_HttpListenerTraceSource;
|
||||
|
||||
private static object s_InternalSyncObject;
|
||||
|
||||
private Logging()
|
||||
{
|
||||
}
|
||||
|
||||
private static object InternalSyncObject
|
||||
{
|
||||
get
|
||||
{
|
||||
if (s_InternalSyncObject == null)
|
||||
{
|
||||
object o = new Object();
|
||||
Interlocked.CompareExchange(ref s_InternalSyncObject, o, null);
|
||||
}
|
||||
return s_InternalSyncObject;
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool On
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!s_LoggingInitialized)
|
||||
{
|
||||
InitializeLogging();
|
||||
}
|
||||
return s_LoggingEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool IsVerbose(TraceSource traceSource)
|
||||
{
|
||||
return ValidateSettings(traceSource, TraceEventType.Verbose);
|
||||
}
|
||||
|
||||
internal static TraceSource Web
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!s_LoggingInitialized)
|
||||
{
|
||||
InitializeLogging();
|
||||
}
|
||||
if (!s_LoggingEnabled)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return s_WebTraceSource;
|
||||
}
|
||||
}
|
||||
|
||||
internal static TraceSource HttpListener
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!s_LoggingInitialized)
|
||||
{
|
||||
InitializeLogging();
|
||||
}
|
||||
if (!s_LoggingEnabled)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return s_HttpListenerTraceSource;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool GetUseProtocolTextSetting(TraceSource traceSource)
|
||||
{
|
||||
bool useProtocolTextOnly = DefaultUseProtocolTextOnly;
|
||||
if (traceSource.Attributes[AttributeNameTraceMode] == AttributeValueProtocolOnly)
|
||||
{
|
||||
useProtocolTextOnly = true;
|
||||
}
|
||||
return useProtocolTextOnly;
|
||||
}
|
||||
|
||||
private static int GetMaxDumpSizeSetting(TraceSource traceSource)
|
||||
{
|
||||
int maxDumpSize = DefaultMaxDumpSize;
|
||||
if (traceSource.Attributes.ContainsKey(AttributeNameMaxSize))
|
||||
{
|
||||
try
|
||||
{
|
||||
maxDumpSize = Int32.Parse(traceSource.Attributes[AttributeNameMaxSize], NumberFormatInfo.InvariantInfo);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
traceSource.Attributes[AttributeNameMaxSize] = maxDumpSize.ToString(NumberFormatInfo.InvariantInfo);
|
||||
}
|
||||
}
|
||||
return maxDumpSize;
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Sets up internal config settings for logging. (MUST be called under critsec) </para>
|
||||
/// </devdoc>
|
||||
private static void InitializeLogging()
|
||||
{
|
||||
lock (InternalSyncObject)
|
||||
{
|
||||
if (!s_LoggingInitialized)
|
||||
{
|
||||
bool loggingEnabled = false;
|
||||
s_WebTraceSource = new NclTraceSource(TraceSourceWebName);
|
||||
s_HttpListenerTraceSource = new NclTraceSource(TraceSourceHttpListenerName);
|
||||
|
||||
GlobalLog.Print("Initalizating tracing");
|
||||
|
||||
try
|
||||
{
|
||||
loggingEnabled = (s_WebTraceSource.Switch.ShouldTrace(TraceEventType.Critical) ||
|
||||
s_HttpListenerTraceSource.Switch.ShouldTrace(TraceEventType.Critical));
|
||||
}
|
||||
catch (SecurityException)
|
||||
{
|
||||
// These may throw if the caller does not have permission to hook up trace listeners.
|
||||
// We treat this case as though logging were disabled.
|
||||
Close();
|
||||
loggingEnabled = false;
|
||||
}
|
||||
if (loggingEnabled)
|
||||
{
|
||||
AppDomain currentDomain = AppDomain.CurrentDomain;
|
||||
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler);
|
||||
currentDomain.DomainUnload += new EventHandler(AppDomainUnloadEvent);
|
||||
currentDomain.ProcessExit += new EventHandler(ProcessExitEvent);
|
||||
}
|
||||
s_LoggingEnabled = loggingEnabled;
|
||||
s_LoggingInitialized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Logging functions must work in partial trust mode")]
|
||||
private static void Close()
|
||||
{
|
||||
if (s_WebTraceSource != null)
|
||||
{
|
||||
s_WebTraceSource.Close();
|
||||
}
|
||||
if (s_HttpListenerTraceSource != null)
|
||||
{
|
||||
s_HttpListenerTraceSource.Close();
|
||||
}
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Logs any unhandled exception through this event handler</para>
|
||||
/// </devdoc>
|
||||
private static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args)
|
||||
{
|
||||
Exception e = (Exception)args.ExceptionObject;
|
||||
Exception(Web, sender, "UnhandledExceptionHandler", e);
|
||||
}
|
||||
|
||||
private static void ProcessExitEvent(object sender, EventArgs e)
|
||||
{
|
||||
Close();
|
||||
s_AppDomainShutdown = true;
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Called when the system is shutting down, used to prevent additional logging post-shutdown</para>
|
||||
/// </devdoc>
|
||||
private static void AppDomainUnloadEvent(object sender, EventArgs e)
|
||||
{
|
||||
Close();
|
||||
s_AppDomainShutdown = true;
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Confirms logging is enabled, given current logging settings</para>
|
||||
/// </devdoc>
|
||||
private static bool ValidateSettings(TraceSource traceSource, TraceEventType traceLevel)
|
||||
{
|
||||
if (!s_LoggingEnabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!s_LoggingInitialized)
|
||||
{
|
||||
InitializeLogging();
|
||||
}
|
||||
if (traceSource == null || !traceSource.Switch.ShouldTrace(traceLevel))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (s_AppDomainShutdown)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Converts an object to a normalized string that can be printed
|
||||
/// takes System.Net.ObjectNamedFoo and coverts to ObjectNamedFoo,
|
||||
/// except IPAddress, IPEndPoint, and Uri, which return ToString()
|
||||
/// </para>
|
||||
/// </devdoc>
|
||||
private static string GetObjectName(object obj)
|
||||
{
|
||||
if (obj is Uri || obj is System.Net.IPAddress || obj is System.Net.IPEndPoint)
|
||||
{
|
||||
return obj.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return obj.GetType().Name;
|
||||
}
|
||||
}
|
||||
|
||||
internal static uint GetThreadId()
|
||||
{
|
||||
uint threadId = UnsafeNclNativeMethods.GetCurrentThreadId();
|
||||
if (threadId == 0)
|
||||
{
|
||||
threadId = (uint)Thread.CurrentThread.GetHashCode();
|
||||
}
|
||||
return threadId;
|
||||
}
|
||||
|
||||
internal static void PrintLine(TraceSource traceSource, TraceEventType eventType, int id, string msg)
|
||||
{
|
||||
string logHeader = "[" + GetThreadId().ToString("d4", CultureInfo.InvariantCulture) + "] ";
|
||||
traceSource.TraceEvent(eventType, id, logHeader + msg);
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Indicates that two objects are getting used with one another</para>
|
||||
/// </devdoc>
|
||||
internal static void Associate(TraceSource traceSource, object objA, object objB)
|
||||
{
|
||||
if (!ValidateSettings(traceSource, TraceEventType.Information))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string lineA = GetObjectName(objA) + "#" + ValidationHelper.HashString(objA);
|
||||
string lineB = GetObjectName(objB) + "#" + ValidationHelper.HashString(objB);
|
||||
|
||||
PrintLine(traceSource, TraceEventType.Information, 0, "Associating " + lineA + " with " + lineB);
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Logs entrance to a function</para>
|
||||
/// </devdoc>
|
||||
internal static void Enter(TraceSource traceSource, object obj, string method, string param)
|
||||
{
|
||||
if (!ValidateSettings(traceSource, TraceEventType.Information))
|
||||
{
|
||||
return;
|
||||
}
|
||||
Enter(traceSource, GetObjectName(obj) + "#" + ValidationHelper.HashString(obj), method, param);
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Logs entrance to a function</para>
|
||||
/// </devdoc>
|
||||
internal static void Enter(TraceSource traceSource, object obj, string method, object paramObject)
|
||||
{
|
||||
if (!ValidateSettings(traceSource, TraceEventType.Information))
|
||||
{
|
||||
return;
|
||||
}
|
||||
Enter(traceSource, GetObjectName(obj) + "#" + ValidationHelper.HashString(obj), method, paramObject);
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Logs entrance to a function</para>
|
||||
/// </devdoc>
|
||||
internal static void Enter(TraceSource traceSource, string obj, string method, string param)
|
||||
{
|
||||
if (!ValidateSettings(traceSource, TraceEventType.Information))
|
||||
{
|
||||
return;
|
||||
}
|
||||
Enter(traceSource, obj + "::" + method + "(" + param + ")");
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Logs entrance to a function</para>
|
||||
/// </devdoc>
|
||||
internal static void Enter(TraceSource traceSource, string obj, string method, object paramObject)
|
||||
{
|
||||
if (!ValidateSettings(traceSource, TraceEventType.Information))
|
||||
{
|
||||
return;
|
||||
}
|
||||
string paramObjectValue = string.Empty;
|
||||
if (paramObject != null)
|
||||
{
|
||||
paramObjectValue = GetObjectName(paramObject) + "#" + ValidationHelper.HashString(paramObject);
|
||||
}
|
||||
Enter(traceSource, obj + "::" + method + "(" + paramObjectValue + ")");
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Logs entrance to a function, indents and points that out</para>
|
||||
/// </devdoc>
|
||||
internal static void Enter(TraceSource traceSource, string method, string parameters)
|
||||
{
|
||||
if (!ValidateSettings(traceSource, TraceEventType.Information))
|
||||
{
|
||||
return;
|
||||
}
|
||||
Enter(traceSource, method + "(" + parameters + ")");
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Logs entrance to a function, indents and points that out</para>
|
||||
/// </devdoc>
|
||||
internal static void Enter(TraceSource traceSource, string msg)
|
||||
{
|
||||
if (!ValidateSettings(traceSource, TraceEventType.Information))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Trace.CorrelationManager.StartLogicalOperation();
|
||||
PrintLine(traceSource, TraceEventType.Verbose, 0, msg);
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Logs exit from a function</para>
|
||||
/// </devdoc>
|
||||
internal static void Exit(TraceSource traceSource, object obj, string method, object retObject)
|
||||
{
|
||||
if (!ValidateSettings(traceSource, TraceEventType.Information))
|
||||
{
|
||||
return;
|
||||
}
|
||||
string retValue = string.Empty;
|
||||
if (retObject != null)
|
||||
{
|
||||
retValue = GetObjectName(retObject) + "#" + ValidationHelper.HashString(retObject);
|
||||
}
|
||||
Exit(traceSource, obj, method, retValue);
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Logs exit from a function</para>
|
||||
/// </devdoc>
|
||||
internal static void Exit(TraceSource traceSource, string obj, string method, object retObject)
|
||||
{
|
||||
if (!ValidateSettings(traceSource, TraceEventType.Information))
|
||||
{
|
||||
return;
|
||||
}
|
||||
string retValue = string.Empty;
|
||||
if (retObject != null)
|
||||
{
|
||||
retValue = GetObjectName(retObject) + "#" + ValidationHelper.HashString(retObject);
|
||||
}
|
||||
Exit(traceSource, obj, method, retValue);
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Logs exit from a function</para>
|
||||
/// </devdoc>
|
||||
internal static void Exit(TraceSource traceSource, object obj, string method, string retValue)
|
||||
{
|
||||
if (!ValidateSettings(traceSource, TraceEventType.Information))
|
||||
{
|
||||
return;
|
||||
}
|
||||
Exit(traceSource, GetObjectName(obj) + "#" + ValidationHelper.HashString(obj), method, retValue);
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Logs exit from a function</para>
|
||||
/// </devdoc>
|
||||
internal static void Exit(TraceSource traceSource, string obj, string method, string retValue)
|
||||
{
|
||||
if (!ValidateSettings(traceSource, TraceEventType.Information))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(retValue))
|
||||
{
|
||||
retValue = "\t-> " + retValue;
|
||||
}
|
||||
Exit(traceSource, obj + "::" + method + "() " + retValue);
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Logs exit from a function</para>
|
||||
/// </devdoc>
|
||||
internal static void Exit(TraceSource traceSource, string method, string parameters)
|
||||
{
|
||||
if (!ValidateSettings(traceSource, TraceEventType.Information))
|
||||
{
|
||||
return;
|
||||
}
|
||||
Exit(traceSource, method + "() " + parameters);
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Logs exit from a function</para>
|
||||
/// </devdoc>
|
||||
internal static void Exit(TraceSource traceSource, string msg)
|
||||
{
|
||||
if (!ValidateSettings(traceSource, TraceEventType.Information))
|
||||
{
|
||||
return;
|
||||
}
|
||||
PrintLine(traceSource, TraceEventType.Verbose, 0, "Exiting " + msg);
|
||||
// Trace.CorrelationManager.StopLogicalOperation();
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Logs Exception, restores indenting</para>
|
||||
/// </devdoc>
|
||||
internal static void Exception(TraceSource traceSource, object obj, string method, Exception e)
|
||||
{
|
||||
if (!ValidateSettings(traceSource, TraceEventType.Error))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string infoLine = SR.GetString(SR.net_log_exception, GetObjectLogHash(obj), method, e.Message);
|
||||
if (!string.IsNullOrEmpty(e.StackTrace))
|
||||
{
|
||||
infoLine += "\r\n" + e.StackTrace;
|
||||
}
|
||||
PrintLine(traceSource, TraceEventType.Error, 0, infoLine);
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Logs an Info line</para>
|
||||
/// </devdoc>
|
||||
internal static void PrintInfo(TraceSource traceSource, string msg)
|
||||
{
|
||||
if (!ValidateSettings(traceSource, TraceEventType.Information))
|
||||
{
|
||||
return;
|
||||
}
|
||||
PrintLine(traceSource, TraceEventType.Information, 0, msg);
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Logs an Info line</para>
|
||||
/// </devdoc>
|
||||
internal static void PrintInfo(TraceSource traceSource, object obj, string msg)
|
||||
{
|
||||
if (!ValidateSettings(traceSource, TraceEventType.Information))
|
||||
{
|
||||
return;
|
||||
}
|
||||
PrintLine(traceSource, TraceEventType.Information, 0,
|
||||
GetObjectName(obj) + "#" + ValidationHelper.HashString(obj)
|
||||
+ " - " + msg);
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Logs an Info line</para>
|
||||
/// </devdoc>
|
||||
internal static void PrintInfo(TraceSource traceSource, object obj, string method, string param)
|
||||
{
|
||||
if (!ValidateSettings(traceSource, TraceEventType.Information))
|
||||
{
|
||||
return;
|
||||
}
|
||||
PrintLine(traceSource, TraceEventType.Information, 0,
|
||||
GetObjectName(obj) + "#" + ValidationHelper.HashString(obj)
|
||||
+ "::" + method + "(" + param + ")");
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Logs a Warning line</para>
|
||||
/// </devdoc>
|
||||
internal static void PrintWarning(TraceSource traceSource, string msg)
|
||||
{
|
||||
if (!ValidateSettings(traceSource, TraceEventType.Warning))
|
||||
{
|
||||
return;
|
||||
}
|
||||
PrintLine(traceSource, TraceEventType.Warning, 0, msg);
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Logs a Warning line</para>
|
||||
/// </devdoc>
|
||||
internal static void PrintWarning(TraceSource traceSource, object obj, string method, string msg)
|
||||
{
|
||||
if (!ValidateSettings(traceSource, TraceEventType.Warning))
|
||||
{
|
||||
return;
|
||||
}
|
||||
PrintLine(traceSource, TraceEventType.Warning, 0,
|
||||
GetObjectName(obj) + "#" + ValidationHelper.HashString(obj)
|
||||
+ "::" + method + "() - " + msg);
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Logs an Error line</para>
|
||||
/// </devdoc>
|
||||
internal static void PrintError(TraceSource traceSource, string msg)
|
||||
{
|
||||
if (!ValidateSettings(traceSource, TraceEventType.Error))
|
||||
{
|
||||
return;
|
||||
}
|
||||
PrintLine(traceSource, TraceEventType.Error, 0, msg);
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Logs an Error line</para>
|
||||
/// </devdoc>
|
||||
internal static void PrintError(TraceSource traceSource, object obj, string method, string msg)
|
||||
{
|
||||
if (!ValidateSettings(traceSource, TraceEventType.Error))
|
||||
{
|
||||
return;
|
||||
}
|
||||
PrintLine(traceSource, TraceEventType.Error, 0,
|
||||
GetObjectName(obj) + "#" + ValidationHelper.HashString(obj)
|
||||
+ "::" + method + "() - " + msg);
|
||||
}
|
||||
|
||||
internal static string GetObjectLogHash(object obj)
|
||||
{
|
||||
return GetObjectName(obj) + "#" + ValidationHelper.HashString(obj);
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Marhsalls a buffer ptr to an array and then dumps the byte array to the log</para>
|
||||
/// </devdoc>
|
||||
internal static void Dump(TraceSource traceSource, object obj, string method, IntPtr bufferPtr, int length)
|
||||
{
|
||||
if (!ValidateSettings(traceSource, TraceEventType.Verbose) || bufferPtr == IntPtr.Zero || length < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
byte[] buffer = new byte[length];
|
||||
Marshal.Copy(bufferPtr, buffer, 0, length);
|
||||
Dump(traceSource, obj, method, buffer, 0, length);
|
||||
}
|
||||
|
||||
/// <devdoc>
|
||||
/// <para>Dumps a byte array to the log</para>
|
||||
/// </devdoc>
|
||||
internal static void Dump(TraceSource traceSource, object obj, string method, byte[] buffer, int offset, int length)
|
||||
{
|
||||
if (!ValidateSettings(traceSource, TraceEventType.Verbose))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (buffer == null)
|
||||
{
|
||||
PrintLine(traceSource, TraceEventType.Verbose, 0, "(null)");
|
||||
return;
|
||||
}
|
||||
if (offset > buffer.Length)
|
||||
{
|
||||
PrintLine(traceSource, TraceEventType.Verbose, 0, "(offset out of range)");
|
||||
return;
|
||||
}
|
||||
PrintLine(traceSource, TraceEventType.Verbose, 0, "Data from " + GetObjectName(obj) + "#" + ValidationHelper.HashString(obj) + "::" + method);
|
||||
int maxDumpSize = GetMaxDumpSizeSetting(traceSource);
|
||||
if (length > maxDumpSize)
|
||||
{
|
||||
PrintLine(traceSource, TraceEventType.Verbose, 0, "(printing " + maxDumpSize.ToString(NumberFormatInfo.InvariantInfo) + " out of " + length.ToString(NumberFormatInfo.InvariantInfo) + ")");
|
||||
length = maxDumpSize;
|
||||
}
|
||||
if ((length < 0) || (length > buffer.Length - offset))
|
||||
{
|
||||
length = buffer.Length - offset;
|
||||
}
|
||||
if (GetUseProtocolTextSetting(traceSource))
|
||||
{
|
||||
string output = "<<" + HeaderEncoding.GetString(buffer, offset, length) + ">>";
|
||||
PrintLine(traceSource, TraceEventType.Verbose, 0, output);
|
||||
return;
|
||||
}
|
||||
do
|
||||
{
|
||||
int n = Math.Min(length, 16);
|
||||
string disp = String.Format(CultureInfo.CurrentCulture, "{0:X8} : ", offset);
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
disp += String.Format(CultureInfo.CurrentCulture, "{0:X2}", buffer[offset + i]) + ((i == 7) ? '-' : ' ');
|
||||
}
|
||||
for (int i = n; i < 16; ++i)
|
||||
{
|
||||
disp += " ";
|
||||
}
|
||||
disp += ": ";
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
disp += ((buffer[offset + i] < 0x20) || (buffer[offset + i] > 0x7e))
|
||||
? '.'
|
||||
: (char)(buffer[offset + i]);
|
||||
}
|
||||
PrintLine(traceSource, TraceEventType.Verbose, 0, disp);
|
||||
offset += n;
|
||||
length -= n;
|
||||
}
|
||||
while (length > 0);
|
||||
}
|
||||
|
||||
private class NclTraceSource : TraceSource
|
||||
{
|
||||
internal NclTraceSource(string name) : base(name)
|
||||
{
|
||||
}
|
||||
/*
|
||||
protected internal override string[] GetSupportedAttributes()
|
||||
{
|
||||
return Logging.SupportedAttributes;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,597 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="_LoggingObject.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// We have function based stack and thread based logging of basic behavior. We
|
||||
// also now have the ability to run a "watch thread" which does basic hang detection
|
||||
// and error-event based logging. The logging code buffers the callstack/picture
|
||||
// of all COMNET threads, and upon error from an assert or a hang, it will open a file
|
||||
// and dump the snapsnot. Future work will allow this to be configed by registry and
|
||||
// to use Runtime based logging. We'd also like to have different levels of logging.
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
using System;
|
||||
|
||||
// BaseLoggingObject - used to disable logging,
|
||||
// this is just a base class that does nothing.
|
||||
|
||||
[Flags]
|
||||
internal enum ThreadKinds
|
||||
{
|
||||
Unknown = 0x0000,
|
||||
|
||||
// Mutually exclusive.
|
||||
User = 0x0001, // Thread has entered via an API.
|
||||
System = 0x0002, // Thread has entered via a system callback (e.g. completion port) or is our own thread.
|
||||
|
||||
// Mutually exclusive.
|
||||
Sync = 0x0004, // Thread should block.
|
||||
Async = 0x0008, // Thread should not block.
|
||||
|
||||
// Mutually exclusive, not always known for a user thread. Never changes.
|
||||
Timer = 0x0010, // Thread is the timer thread. (Can't call user code.)
|
||||
CompletionPort = 0x0020, // Thread is a ThreadPool completion-port thread.
|
||||
Worker = 0x0040, // Thread is a ThreadPool worker thread.
|
||||
Finalization = 0x0080, // Thread is the finalization thread.
|
||||
Other = 0x0100, // Unknown source.
|
||||
|
||||
OwnerMask = User | System,
|
||||
SyncMask = Sync | Async,
|
||||
SourceMask = Timer | CompletionPort | Worker | Finalization | Other,
|
||||
|
||||
// Useful "macros"
|
||||
SafeSources = SourceMask & ~(Timer | Finalization), // Methods that "unsafe" sources can call must be explicitly marked.
|
||||
ThreadPool = CompletionPort | Worker, // Like Thread.CurrentThread.IsThreadPoolThread
|
||||
}
|
||||
|
||||
internal class BaseLoggingObject
|
||||
{
|
||||
internal BaseLoggingObject()
|
||||
{
|
||||
}
|
||||
|
||||
internal virtual void EnterFunc(string funcname)
|
||||
{
|
||||
}
|
||||
|
||||
internal virtual void LeaveFunc(string funcname)
|
||||
{
|
||||
}
|
||||
|
||||
internal virtual void DumpArrayToConsole()
|
||||
{
|
||||
}
|
||||
|
||||
internal virtual void PrintLine(string msg)
|
||||
{
|
||||
}
|
||||
|
||||
internal virtual void DumpArray(bool shouldClose)
|
||||
{
|
||||
}
|
||||
|
||||
internal virtual void DumpArrayToFile(bool shouldClose)
|
||||
{
|
||||
}
|
||||
|
||||
internal virtual void Flush()
|
||||
{
|
||||
}
|
||||
|
||||
internal virtual void Flush(bool close)
|
||||
{
|
||||
}
|
||||
|
||||
internal virtual void LoggingMonitorTick()
|
||||
{
|
||||
}
|
||||
|
||||
internal virtual void Dump(byte[] buffer)
|
||||
{
|
||||
}
|
||||
|
||||
internal virtual void Dump(byte[] buffer, int length)
|
||||
{
|
||||
}
|
||||
|
||||
internal virtual void Dump(byte[] buffer, int offset, int length)
|
||||
{
|
||||
}
|
||||
|
||||
internal virtual void Dump(IntPtr pBuffer, int offset, int length)
|
||||
{
|
||||
}
|
||||
} // class BaseLoggingObject
|
||||
|
||||
#if TRAVE
|
||||
/// <internalonly/>
|
||||
/// <devdoc>
|
||||
/// </devdoc>
|
||||
internal class LoggingObject : BaseLoggingObject {
|
||||
public ArrayList _Logarray;
|
||||
private Hashtable _ThreadNesting;
|
||||
private int _AddCount;
|
||||
private StreamWriter _Stream;
|
||||
private int _IamAlive;
|
||||
private int _LastIamAlive;
|
||||
private bool _Finalized = false;
|
||||
private double _NanosecondsPerTick;
|
||||
private int _StartMilliseconds;
|
||||
private long _StartTicks;
|
||||
|
||||
internal LoggingObject() : base() {
|
||||
_Logarray = new ArrayList();
|
||||
_ThreadNesting = new Hashtable();
|
||||
_AddCount = 0;
|
||||
_IamAlive = 0;
|
||||
_LastIamAlive = -1;
|
||||
|
||||
if (GlobalLog.s_UsePerfCounter) {
|
||||
long ticksPerSecond;
|
||||
SafeNativeMethods.QueryPerformanceFrequency(out ticksPerSecond);
|
||||
_NanosecondsPerTick = 10000000.0/(double)ticksPerSecond;
|
||||
SafeNativeMethods.QueryPerformanceCounter(out _StartTicks);
|
||||
} else {
|
||||
_StartMilliseconds = Environment.TickCount;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// LoggingMonitorTick - this function is run from the monitor thread,
|
||||
// and used to check to see if there any hangs, ie no logging
|
||||
// activitity
|
||||
//
|
||||
|
||||
internal override void LoggingMonitorTick() {
|
||||
if ( _LastIamAlive == _IamAlive ) {
|
||||
PrintLine("================= Error TIMEOUT - HANG DETECTED =================");
|
||||
DumpArray(true);
|
||||
}
|
||||
_LastIamAlive = _IamAlive;
|
||||
}
|
||||
|
||||
internal override void EnterFunc(string funcname) {
|
||||
if (_Finalized) {
|
||||
return;
|
||||
}
|
||||
IncNestingCount();
|
||||
ValidatePush(funcname);
|
||||
PrintLine(funcname);
|
||||
}
|
||||
|
||||
internal override void LeaveFunc(string funcname) {
|
||||
if (_Finalized) {
|
||||
return;
|
||||
}
|
||||
PrintLine(funcname);
|
||||
DecNestingCount();
|
||||
ValidatePop(funcname);
|
||||
}
|
||||
|
||||
internal override void DumpArrayToConsole() {
|
||||
for (int i=0; i < _Logarray.Count; i++) {
|
||||
Console.WriteLine((string) _Logarray[i]);
|
||||
}
|
||||
}
|
||||
|
||||
internal override void PrintLine(string msg) {
|
||||
if (_Finalized) {
|
||||
return;
|
||||
}
|
||||
string spc = "";
|
||||
|
||||
_IamAlive++;
|
||||
|
||||
spc = GetNestingString();
|
||||
|
||||
string tickString = "";
|
||||
|
||||
if (GlobalLog.s_UsePerfCounter) {
|
||||
long nowTicks;
|
||||
SafeNativeMethods.QueryPerformanceCounter(out nowTicks);
|
||||
if (_StartTicks>nowTicks) { // counter reset, restart from 0
|
||||
_StartTicks = nowTicks;
|
||||
}
|
||||
nowTicks -= _StartTicks;
|
||||
if (GlobalLog.s_UseTimeSpan) {
|
||||
tickString = new TimeSpan((long)(nowTicks*_NanosecondsPerTick)).ToString();
|
||||
// note: TimeSpan().ToString() doesn't return the uSec part
|
||||
// if its 0. .ToString() returns [H*]HH:MM:SS:uuuuuuu, hence 16
|
||||
if (tickString.Length < 16) {
|
||||
tickString += ".0000000";
|
||||
}
|
||||
}
|
||||
else {
|
||||
tickString = ((double)nowTicks*_NanosecondsPerTick/10000).ToString("f3");
|
||||
}
|
||||
}
|
||||
else {
|
||||
int nowMilliseconds = Environment.TickCount;
|
||||
if (_StartMilliseconds>nowMilliseconds) {
|
||||
_StartMilliseconds = nowMilliseconds;
|
||||
}
|
||||
nowMilliseconds -= _StartMilliseconds;
|
||||
if (GlobalLog.s_UseTimeSpan) {
|
||||
tickString = new TimeSpan(nowMilliseconds*10000).ToString();
|
||||
// note: TimeSpan().ToString() doesn't return the uSec part
|
||||
// if its 0. .ToString() returns [H*]HH:MM:SS:uuuuuuu, hence 16
|
||||
if (tickString.Length < 16) {
|
||||
tickString += ".0000000";
|
||||
}
|
||||
}
|
||||
else {
|
||||
tickString = nowMilliseconds.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
uint threadId = 0;
|
||||
|
||||
if (GlobalLog.s_UseThreadId) {
|
||||
try {
|
||||
object threadData = Thread.GetData(GlobalLog.s_ThreadIdSlot);
|
||||
if (threadData!= null) {
|
||||
threadId = (uint)threadData;
|
||||
}
|
||||
|
||||
}
|
||||
catch(Exception exception) {
|
||||
if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
if (threadId == 0) {
|
||||
threadId = UnsafeNclNativeMethods.GetCurrentThreadId();
|
||||
Thread.SetData(GlobalLog.s_ThreadIdSlot, threadId);
|
||||
}
|
||||
}
|
||||
if (threadId == 0) {
|
||||
threadId = (uint)Thread.CurrentThread.GetHashCode();
|
||||
}
|
||||
|
||||
string str = "[" + threadId.ToString("x8") + "]" + " (" +tickString+ ") " + spc + msg;
|
||||
|
||||
lock(this) {
|
||||
_AddCount++;
|
||||
_Logarray.Add(str);
|
||||
int MaxLines = GlobalLog.s_DumpToConsole ? 0 : GlobalLog.MaxLinesBeforeSave;
|
||||
if (_AddCount > MaxLines) {
|
||||
_AddCount = 0;
|
||||
DumpArray(false);
|
||||
_Logarray = new ArrayList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal override void DumpArray(bool shouldClose) {
|
||||
if ( GlobalLog.s_DumpToConsole ) {
|
||||
DumpArrayToConsole();
|
||||
} else {
|
||||
DumpArrayToFile(shouldClose);
|
||||
}
|
||||
}
|
||||
|
||||
internal unsafe override void Dump(byte[] buffer, int offset, int length) {
|
||||
//if (!GlobalLog.s_DumpWebData) {
|
||||
// return;
|
||||
//}
|
||||
if (buffer==null) {
|
||||
PrintLine("(null)");
|
||||
return;
|
||||
}
|
||||
if (offset > buffer.Length) {
|
||||
PrintLine("(offset out of range)");
|
||||
return;
|
||||
}
|
||||
if (length > GlobalLog.s_MaxDumpSize) {
|
||||
PrintLine("(printing " + GlobalLog.s_MaxDumpSize.ToString() + " out of " + length.ToString() + ")");
|
||||
length = GlobalLog.s_MaxDumpSize;
|
||||
}
|
||||
if ((length < 0) || (length > buffer.Length - offset)) {
|
||||
length = buffer.Length - offset;
|
||||
}
|
||||
fixed (byte* pBuffer = buffer) {
|
||||
Dump((IntPtr)pBuffer, offset, length);
|
||||
}
|
||||
}
|
||||
|
||||
internal unsafe override void Dump(IntPtr pBuffer, int offset, int length) {
|
||||
//if (!GlobalLog.s_DumpWebData) {
|
||||
// return;
|
||||
//}
|
||||
if (pBuffer==IntPtr.Zero || length<0) {
|
||||
PrintLine("(null)");
|
||||
return;
|
||||
}
|
||||
if (length > GlobalLog.s_MaxDumpSize) {
|
||||
PrintLine("(printing " + GlobalLog.s_MaxDumpSize.ToString() + " out of " + length.ToString() + ")");
|
||||
length = GlobalLog.s_MaxDumpSize;
|
||||
}
|
||||
byte* buffer = (byte*)pBuffer + offset;
|
||||
Dump(buffer, length);
|
||||
}
|
||||
|
||||
unsafe void Dump(byte* buffer, int length) {
|
||||
do {
|
||||
int offset = 0;
|
||||
int n = Math.Min(length, 16);
|
||||
string disp = ((IntPtr)buffer).ToString("X8") + " : " + offset.ToString("X8") + " : ";
|
||||
byte current;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
current = *(buffer + i);
|
||||
disp += current.ToString("X2") + ((i == 7) ? '-' : ' ');
|
||||
}
|
||||
for (int i = n; i < 16; ++i) {
|
||||
disp += " ";
|
||||
}
|
||||
disp += ": ";
|
||||
for (int i = 0; i < n; ++i) {
|
||||
current = *(buffer + i);
|
||||
disp += ((current < 0x20) || (current > 0x7e)) ? '.' : (char)current;
|
||||
}
|
||||
PrintLine(disp);
|
||||
offset += n;
|
||||
buffer += n;
|
||||
length -= n;
|
||||
} while (length > 0);
|
||||
}
|
||||
|
||||
// SECURITY: This is dev-debugging class and we need some permissions
|
||||
// to use it under trust-restricted environment as well.
|
||||
[PermissionSet(SecurityAction.Assert, Name="FullTrust")]
|
||||
internal override void DumpArrayToFile(bool shouldClose) {
|
||||
lock (this) {
|
||||
if (!shouldClose) {
|
||||
if (_Stream==null) {
|
||||
string mainLogFileRoot = GlobalLog.s_RootDirectory + "System.Net";
|
||||
string mainLogFile = mainLogFileRoot;
|
||||
for (int k=0; k<20; k++) {
|
||||
if (k>0) {
|
||||
mainLogFile = mainLogFileRoot + "." + k.ToString();
|
||||
}
|
||||
string fileName = mainLogFile + ".log";
|
||||
if (!File.Exists(fileName)) {
|
||||
try {
|
||||
_Stream = new StreamWriter(fileName);
|
||||
break;
|
||||
}
|
||||
catch (Exception exception) {
|
||||
if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
|
||||
throw;
|
||||
}
|
||||
if (exception is SecurityException || exception is UnauthorizedAccessException) {
|
||||
// can't be CAS (we assert) this is an ACL issue
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_Stream==null) {
|
||||
_Stream = StreamWriter.Null;
|
||||
}
|
||||
// write a header with information about the Process and the AppDomain
|
||||
_Stream.Write("# MachineName: " + Environment.MachineName + "\r\n");
|
||||
_Stream.Write("# ProcessName: " + Process.GetCurrentProcess().ProcessName + " (pid: " + Process.GetCurrentProcess().Id + ")\r\n");
|
||||
_Stream.Write("# AppDomainId: " + AppDomain.CurrentDomain.Id + "\r\n");
|
||||
_Stream.Write("# CurrentIdentity: " + WindowsIdentity.GetCurrent().Name + "\r\n");
|
||||
_Stream.Write("# CommandLine: " + Environment.CommandLine + "\r\n");
|
||||
_Stream.Write("# ClrVersion: " + Environment.Version + "\r\n");
|
||||
_Stream.Write("# CreationDate: " + DateTime.Now.ToString("g") + "\r\n");
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (_Logarray!=null) {
|
||||
for (int i=0; i<_Logarray.Count; i++) {
|
||||
_Stream.Write((string)_Logarray[i]);
|
||||
_Stream.Write("\r\n");
|
||||
}
|
||||
|
||||
if (_Logarray.Count > 0 && _Stream != null)
|
||||
_Stream.Flush();
|
||||
}
|
||||
}
|
||||
catch (Exception exception) {
|
||||
if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
if (shouldClose && _Stream!=null) {
|
||||
try {
|
||||
_Stream.Close();
|
||||
}
|
||||
catch (ObjectDisposedException) { }
|
||||
_Stream = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal override void Flush() {
|
||||
Flush(false);
|
||||
}
|
||||
|
||||
internal override void Flush(bool close) {
|
||||
lock (this) {
|
||||
if (!GlobalLog.s_DumpToConsole) {
|
||||
DumpArrayToFile(close);
|
||||
_AddCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ThreadInfoData {
|
||||
public ThreadInfoData(string indent) {
|
||||
Indent = indent;
|
||||
NestingStack = new Stack();
|
||||
}
|
||||
public string Indent;
|
||||
public Stack NestingStack;
|
||||
};
|
||||
|
||||
string IndentString {
|
||||
get {
|
||||
string indent = " ";
|
||||
Object obj = _ThreadNesting[Thread.CurrentThread.GetHashCode()];
|
||||
if (!GlobalLog.s_DebugCallNesting) {
|
||||
if (obj == null) {
|
||||
_ThreadNesting[Thread.CurrentThread.GetHashCode()] = indent;
|
||||
} else {
|
||||
indent = (String) obj;
|
||||
}
|
||||
} else {
|
||||
ThreadInfoData threadInfo = obj as ThreadInfoData;
|
||||
if (threadInfo == null) {
|
||||
threadInfo = new ThreadInfoData(indent);
|
||||
_ThreadNesting[Thread.CurrentThread.GetHashCode()] = threadInfo;
|
||||
}
|
||||
indent = threadInfo.Indent;
|
||||
}
|
||||
return indent;
|
||||
}
|
||||
set {
|
||||
Object obj = _ThreadNesting[Thread.CurrentThread.GetHashCode()];
|
||||
if (obj == null) {
|
||||
return;
|
||||
}
|
||||
if (!GlobalLog.s_DebugCallNesting) {
|
||||
_ThreadNesting[Thread.CurrentThread.GetHashCode()] = value;
|
||||
} else {
|
||||
ThreadInfoData threadInfo = obj as ThreadInfoData;
|
||||
if (threadInfo == null) {
|
||||
threadInfo = new ThreadInfoData(value);
|
||||
_ThreadNesting[Thread.CurrentThread.GetHashCode()] = threadInfo;
|
||||
}
|
||||
threadInfo.Indent = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[System.Diagnostics.Conditional("TRAVE")]
|
||||
private void IncNestingCount() {
|
||||
IndentString = IndentString + " ";
|
||||
}
|
||||
|
||||
[System.Diagnostics.Conditional("TRAVE")]
|
||||
private void DecNestingCount() {
|
||||
string indent = IndentString;
|
||||
if (indent.Length>1) {
|
||||
try {
|
||||
indent = indent.Substring(1);
|
||||
}
|
||||
catch {
|
||||
indent = string.Empty;
|
||||
}
|
||||
}
|
||||
if (indent.Length==0) {
|
||||
indent = "< ";
|
||||
}
|
||||
IndentString = indent;
|
||||
}
|
||||
|
||||
private string GetNestingString() {
|
||||
return IndentString;
|
||||
}
|
||||
|
||||
[System.Diagnostics.Conditional("TRAVE")]
|
||||
private void ValidatePush(string name) {
|
||||
if (GlobalLog.s_DebugCallNesting) {
|
||||
Object obj = _ThreadNesting[Thread.CurrentThread.GetHashCode()];
|
||||
ThreadInfoData threadInfo = obj as ThreadInfoData;
|
||||
if (threadInfo == null) {
|
||||
return;
|
||||
}
|
||||
threadInfo.NestingStack.Push(name);
|
||||
}
|
||||
}
|
||||
|
||||
[System.Diagnostics.Conditional("TRAVE")]
|
||||
private void ValidatePop(string name) {
|
||||
if (GlobalLog.s_DebugCallNesting) {
|
||||
try {
|
||||
Object obj = _ThreadNesting[Thread.CurrentThread.GetHashCode()];
|
||||
ThreadInfoData threadInfo = obj as ThreadInfoData;
|
||||
if (threadInfo == null) {
|
||||
return;
|
||||
}
|
||||
if (threadInfo.NestingStack.Count == 0) {
|
||||
PrintLine("++++====" + "Poped Empty Stack for :"+name);
|
||||
}
|
||||
string popedName = (string) threadInfo.NestingStack.Pop();
|
||||
string [] parsedList = popedName.Split(new char [] {'(',')',' ','.',':',',','#'});
|
||||
foreach (string element in parsedList) {
|
||||
if (element != null && element.Length > 1 && name.IndexOf(element) != -1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
PrintLine("++++====" + "Expected:" + popedName + ": got :" + name + ": StackSize:"+threadInfo.NestingStack.Count);
|
||||
// relevel the stack
|
||||
while(threadInfo.NestingStack.Count>0) {
|
||||
string popedName2 = (string) threadInfo.NestingStack.Pop();
|
||||
string [] parsedList2 = popedName2.Split(new char [] {'(',')',' ','.',':',',','#'});
|
||||
foreach (string element2 in parsedList2) {
|
||||
if (element2 != null && element2.Length > 1 && name.IndexOf(element2) != -1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
PrintLine("++++====" + "ValidatePop failed for: "+name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
~LoggingObject() {
|
||||
if(!_Finalized) {
|
||||
_Finalized = true;
|
||||
lock(this) {
|
||||
DumpArray(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // class LoggingObject
|
||||
|
||||
internal static class TraveHelper {
|
||||
private static readonly string Hexizer = "0x{0:x}";
|
||||
internal static string ToHex(object value) {
|
||||
return String.Format(Hexizer, value);
|
||||
}
|
||||
}
|
||||
#endif // TRAVE
|
||||
|
||||
#if TRAVE
|
||||
internal class IntegerSwitch : BooleanSwitch {
|
||||
public IntegerSwitch(string switchName, string switchDescription) : base(switchName, switchDescription) {
|
||||
}
|
||||
public new int Value {
|
||||
get {
|
||||
return base.SwitchSetting;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// class GlobalLog
|
||||
} // namespace System.Net
|
||||
|
|
@ -1,647 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="SR.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
namespace System
|
||||
{
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Globalization;
|
||||
using System.Resources;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Security.Permissions;
|
||||
using System.ComponentModel;
|
||||
|
||||
/// <summary>
|
||||
/// AutoGenerated resource class. Usage:
|
||||
/// string s = SR.GetString(SR.MyIdenfitier);
|
||||
/// </summary>
|
||||
internal sealed class SR
|
||||
{
|
||||
internal const string security_ExtendedProtection_NoOSSupport = "security_ExtendedProtection_NoOSSupport";
|
||||
internal const string net_nonClsCompliantException = "net_nonClsCompliantException";
|
||||
internal const string net_illegalConfigWith = "net_illegalConfigWith";
|
||||
internal const string net_illegalConfigWithout = "net_illegalConfigWithout";
|
||||
internal const string net_baddate = "net_baddate";
|
||||
internal const string net_writestarted = "net_writestarted";
|
||||
internal const string net_clsmall = "net_clsmall";
|
||||
internal const string net_reqsubmitted = "net_reqsubmitted";
|
||||
internal const string net_rspsubmitted = "net_rspsubmitted";
|
||||
internal const string net_ftp_no_http_cmd = "net_ftp_no_http_cmd";
|
||||
internal const string net_ftp_invalid_method_name = "net_ftp_invalid_method_name";
|
||||
internal const string net_ftp_invalid_renameto = "net_ftp_invalid_renameto";
|
||||
internal const string net_ftp_no_defaultcreds = "net_ftp_no_defaultcreds";
|
||||
internal const string net_ftpnoresponse = "net_ftpnoresponse";
|
||||
internal const string net_ftp_response_invalid_format = "net_ftp_response_invalid_format";
|
||||
internal const string net_ftp_no_offsetforhttp = "net_ftp_no_offsetforhttp";
|
||||
internal const string net_ftp_invalid_uri = "net_ftp_invalid_uri";
|
||||
internal const string net_ftp_invalid_status_response = "net_ftp_invalid_status_response";
|
||||
internal const string net_ftp_server_failed_passive = "net_ftp_server_failed_passive";
|
||||
internal const string net_ftp_active_address_different = "net_ftp_active_address_different";
|
||||
internal const string net_ftp_proxy_does_not_support_ssl = "net_ftp_proxy_does_not_support_ssl";
|
||||
internal const string net_ftp_invalid_response_filename = "net_ftp_invalid_response_filename";
|
||||
internal const string net_ftp_unsupported_method = "net_ftp_unsupported_method";
|
||||
internal const string net_resubmitcanceled = "net_resubmitcanceled";
|
||||
internal const string net_redirect_perm = "net_redirect_perm";
|
||||
internal const string net_resubmitprotofailed = "net_resubmitprotofailed";
|
||||
internal const string net_needchunked = "net_needchunked";
|
||||
internal const string net_nochunked = "net_nochunked";
|
||||
internal const string net_nochunkuploadonhttp10 = "net_nochunkuploadonhttp10";
|
||||
internal const string net_connarg = "net_connarg";
|
||||
internal const string net_no100 = "net_no100";
|
||||
internal const string net_fromto = "net_fromto";
|
||||
internal const string net_rangetoosmall = "net_rangetoosmall";
|
||||
internal const string net_entitytoobig = "net_entitytoobig";
|
||||
internal const string net_invalidversion = "net_invalidversion";
|
||||
internal const string net_invalidstatus = "net_invalidstatus";
|
||||
internal const string net_toosmall = "net_toosmall";
|
||||
internal const string net_toolong = "net_toolong";
|
||||
internal const string net_connclosed = "net_connclosed";
|
||||
internal const string net_noseek = "net_noseek";
|
||||
internal const string net_servererror = "net_servererror";
|
||||
internal const string net_nouploadonget = "net_nouploadonget";
|
||||
internal const string net_mutualauthfailed = "net_mutualauthfailed";
|
||||
internal const string net_invasync = "net_invasync";
|
||||
internal const string net_inasync = "net_inasync";
|
||||
internal const string net_mustbeuri = "net_mustbeuri";
|
||||
internal const string net_format_shexp = "net_format_shexp";
|
||||
internal const string net_cannot_load_proxy_helper = "net_cannot_load_proxy_helper";
|
||||
internal const string net_invalid_host = "net_invalid_host";
|
||||
internal const string net_repcall = "net_repcall";
|
||||
internal const string net_wrongversion = "net_wrongversion";
|
||||
internal const string net_badmethod = "net_badmethod";
|
||||
internal const string net_io_notenoughbyteswritten = "net_io_notenoughbyteswritten";
|
||||
internal const string net_io_timeout_use_ge_zero = "net_io_timeout_use_ge_zero";
|
||||
internal const string net_io_timeout_use_gt_zero = "net_io_timeout_use_gt_zero";
|
||||
internal const string net_io_no_0timeouts = "net_io_no_0timeouts";
|
||||
internal const string net_requestaborted = "net_requestaborted";
|
||||
internal const string net_tooManyRedirections = "net_tooManyRedirections";
|
||||
internal const string net_authmodulenotregistered = "net_authmodulenotregistered";
|
||||
internal const string net_authschemenotregistered = "net_authschemenotregistered";
|
||||
internal const string net_proxyschemenotsupported = "net_proxyschemenotsupported";
|
||||
internal const string net_maxsrvpoints = "net_maxsrvpoints";
|
||||
internal const string net_unknown_prefix = "net_unknown_prefix";
|
||||
internal const string net_notconnected = "net_notconnected";
|
||||
internal const string net_notstream = "net_notstream";
|
||||
internal const string net_timeout = "net_timeout";
|
||||
internal const string net_nocontentlengthonget = "net_nocontentlengthonget";
|
||||
internal const string net_contentlengthmissing = "net_contentlengthmissing";
|
||||
internal const string net_nonhttpproxynotallowed = "net_nonhttpproxynotallowed";
|
||||
internal const string net_nottoken = "net_nottoken";
|
||||
internal const string net_rangetype = "net_rangetype";
|
||||
internal const string net_need_writebuffering = "net_need_writebuffering";
|
||||
internal const string net_securitypackagesupport = "net_securitypackagesupport";
|
||||
internal const string net_securityprotocolnotsupported = "net_securityprotocolnotsupported";
|
||||
internal const string net_nodefaultcreds = "net_nodefaultcreds";
|
||||
internal const string net_stopped = "net_stopped";
|
||||
internal const string net_udpconnected = "net_udpconnected";
|
||||
internal const string net_readonlystream = "net_readonlystream";
|
||||
internal const string net_writeonlystream = "net_writeonlystream";
|
||||
internal const string net_no_concurrent_io_allowed = "net_no_concurrent_io_allowed";
|
||||
internal const string net_needmorethreads = "net_needmorethreads";
|
||||
internal const string net_MethodNotImplementedException = "net_MethodNotImplementedException";
|
||||
internal const string net_PropertyNotImplementedException = "net_PropertyNotImplementedException";
|
||||
internal const string net_MethodNotSupportedException = "net_MethodNotSupportedException";
|
||||
internal const string net_PropertyNotSupportedException = "net_PropertyNotSupportedException";
|
||||
internal const string net_ProtocolNotSupportedException = "net_ProtocolNotSupportedException";
|
||||
internal const string net_SelectModeNotSupportedException = "net_SelectModeNotSupportedException";
|
||||
internal const string net_InvalidSocketHandle = "net_InvalidSocketHandle";
|
||||
internal const string net_InvalidAddressFamily = "net_InvalidAddressFamily";
|
||||
internal const string net_InvalidEndPointAddressFamily = "net_InvalidEndPointAddressFamily";
|
||||
internal const string net_InvalidSocketAddressSize = "net_InvalidSocketAddressSize";
|
||||
internal const string net_invalidAddressList = "net_invalidAddressList";
|
||||
internal const string net_invalidPingBufferSize = "net_invalidPingBufferSize";
|
||||
internal const string net_cant_perform_during_shutdown = "net_cant_perform_during_shutdown";
|
||||
internal const string net_cant_create_environment = "net_cant_create_environment";
|
||||
internal const string net_completed_result = "net_completed_result";
|
||||
internal const string net_protocol_invalid_family = "net_protocol_invalid_family";
|
||||
internal const string net_protocol_invalid_multicast_family = "net_protocol_invalid_multicast_family";
|
||||
internal const string net_empty_osinstalltype = "net_empty_osinstalltype";
|
||||
internal const string net_unknown_osinstalltype = "net_unknown_osinstalltype";
|
||||
internal const string net_cant_determine_osinstalltype = "net_cant_determine_osinstalltype";
|
||||
internal const string net_osinstalltype = "net_osinstalltype";
|
||||
internal const string net_entire_body_not_written = "net_entire_body_not_written";
|
||||
internal const string net_must_provide_request_body = "net_must_provide_request_body";
|
||||
internal const string net_ssp_dont_support_cbt = "net_ssp_dont_support_cbt";
|
||||
internal const string net_sockets_zerolist = "net_sockets_zerolist";
|
||||
internal const string net_sockets_blocking = "net_sockets_blocking";
|
||||
internal const string net_sockets_useblocking = "net_sockets_useblocking";
|
||||
internal const string net_sockets_select = "net_sockets_select";
|
||||
internal const string net_sockets_toolarge_select = "net_sockets_toolarge_select";
|
||||
internal const string net_sockets_empty_select = "net_sockets_empty_select";
|
||||
internal const string net_sockets_mustbind = "net_sockets_mustbind";
|
||||
internal const string net_sockets_mustlisten = "net_sockets_mustlisten";
|
||||
internal const string net_sockets_mustnotlisten = "net_sockets_mustnotlisten";
|
||||
internal const string net_sockets_mustnotbebound = "net_sockets_mustnotbebound";
|
||||
internal const string net_sockets_namedmustnotbebound = "net_sockets_namedmustnotbebound";
|
||||
internal const string net_sockets_invalid_socketinformation = "net_sockets_invalid_socketinformation";
|
||||
internal const string net_sockets_invalid_ipaddress_length = "net_sockets_invalid_ipaddress_length";
|
||||
internal const string net_sockets_invalid_optionValue = "net_sockets_invalid_optionValue";
|
||||
internal const string net_sockets_invalid_optionValue_all = "net_sockets_invalid_optionValue_all";
|
||||
internal const string net_sockets_invalid_dnsendpoint = "net_sockets_invalid_dnsendpoint";
|
||||
internal const string net_sockets_disconnectedConnect = "net_sockets_disconnectedConnect";
|
||||
internal const string net_sockets_disconnectedAccept = "net_sockets_disconnectedAccept";
|
||||
internal const string net_tcplistener_mustbestopped = "net_tcplistener_mustbestopped";
|
||||
internal const string net_sockets_no_duplicate_async = "net_sockets_no_duplicate_async";
|
||||
internal const string net_socketopinprogress = "net_socketopinprogress";
|
||||
internal const string net_buffercounttoosmall = "net_buffercounttoosmall";
|
||||
internal const string net_multibuffernotsupported = "net_multibuffernotsupported";
|
||||
internal const string net_ambiguousbuffers = "net_ambiguousbuffers";
|
||||
internal const string net_sockets_ipv6only = "net_sockets_ipv6only";
|
||||
internal const string net_perfcounter_initialized_success = "net_perfcounter_initialized_success";
|
||||
internal const string net_perfcounter_initialized_error = "net_perfcounter_initialized_error";
|
||||
internal const string net_perfcounter_nocategory = "net_perfcounter_nocategory";
|
||||
internal const string net_perfcounter_initialization_started = "net_perfcounter_initialization_started";
|
||||
internal const string net_perfcounter_cant_queue_workitem = "net_perfcounter_cant_queue_workitem";
|
||||
internal const string net_config_proxy = "net_config_proxy";
|
||||
internal const string net_config_proxy_module_not_public = "net_config_proxy_module_not_public";
|
||||
internal const string net_config_authenticationmodules = "net_config_authenticationmodules";
|
||||
internal const string net_config_webrequestmodules = "net_config_webrequestmodules";
|
||||
internal const string net_config_requestcaching = "net_config_requestcaching";
|
||||
internal const string net_config_section_permission = "net_config_section_permission";
|
||||
internal const string net_config_element_permission = "net_config_element_permission";
|
||||
internal const string net_config_property_permission = "net_config_property_permission";
|
||||
internal const string net_WebResponseParseError_InvalidHeaderName = "net_WebResponseParseError_InvalidHeaderName";
|
||||
internal const string net_WebResponseParseError_InvalidContentLength = "net_WebResponseParseError_InvalidContentLength";
|
||||
internal const string net_WebResponseParseError_IncompleteHeaderLine = "net_WebResponseParseError_IncompleteHeaderLine";
|
||||
internal const string net_WebResponseParseError_CrLfError = "net_WebResponseParseError_CrLfError";
|
||||
internal const string net_WebResponseParseError_InvalidChunkFormat = "net_WebResponseParseError_InvalidChunkFormat";
|
||||
internal const string net_WebResponseParseError_UnexpectedServerResponse = "net_WebResponseParseError_UnexpectedServerResponse";
|
||||
internal const string net_webstatus_Success = "net_webstatus_Success";
|
||||
internal const string net_webstatus_NameResolutionFailure = "net_webstatus_NameResolutionFailure";
|
||||
internal const string net_webstatus_ConnectFailure = "net_webstatus_ConnectFailure";
|
||||
internal const string net_webstatus_ReceiveFailure = "net_webstatus_ReceiveFailure";
|
||||
internal const string net_webstatus_SendFailure = "net_webstatus_SendFailure";
|
||||
internal const string net_webstatus_PipelineFailure = "net_webstatus_PipelineFailure";
|
||||
internal const string net_webstatus_RequestCanceled = "net_webstatus_RequestCanceled";
|
||||
internal const string net_webstatus_ConnectionClosed = "net_webstatus_ConnectionClosed";
|
||||
internal const string net_webstatus_TrustFailure = "net_webstatus_TrustFailure";
|
||||
internal const string net_webstatus_SecureChannelFailure = "net_webstatus_SecureChannelFailure";
|
||||
internal const string net_webstatus_ServerProtocolViolation = "net_webstatus_ServerProtocolViolation";
|
||||
internal const string net_webstatus_KeepAliveFailure = "net_webstatus_KeepAliveFailure";
|
||||
internal const string net_webstatus_ProxyNameResolutionFailure = "net_webstatus_ProxyNameResolutionFailure";
|
||||
internal const string net_webstatus_MessageLengthLimitExceeded = "net_webstatus_MessageLengthLimitExceeded";
|
||||
internal const string net_webstatus_CacheEntryNotFound = "net_webstatus_CacheEntryNotFound";
|
||||
internal const string net_webstatus_RequestProhibitedByCachePolicy = "net_webstatus_RequestProhibitedByCachePolicy";
|
||||
internal const string net_webstatus_Timeout = "net_webstatus_Timeout";
|
||||
internal const string net_webstatus_RequestProhibitedByProxy = "net_webstatus_RequestProhibitedByProxy";
|
||||
internal const string net_InvalidStatusCode = "net_InvalidStatusCode";
|
||||
internal const string net_ftpstatuscode_ServiceNotAvailable = "net_ftpstatuscode_ServiceNotAvailable";
|
||||
internal const string net_ftpstatuscode_CantOpenData = "net_ftpstatuscode_CantOpenData";
|
||||
internal const string net_ftpstatuscode_ConnectionClosed = "net_ftpstatuscode_ConnectionClosed";
|
||||
internal const string net_ftpstatuscode_ActionNotTakenFileUnavailableOrBusy = "net_ftpstatuscode_ActionNotTakenFileUnavailableOrBusy";
|
||||
internal const string net_ftpstatuscode_ActionAbortedLocalProcessingError = "net_ftpstatuscode_ActionAbortedLocalProcessingError";
|
||||
internal const string net_ftpstatuscode_ActionNotTakenInsufficentSpace = "net_ftpstatuscode_ActionNotTakenInsufficentSpace";
|
||||
internal const string net_ftpstatuscode_CommandSyntaxError = "net_ftpstatuscode_CommandSyntaxError";
|
||||
internal const string net_ftpstatuscode_ArgumentSyntaxError = "net_ftpstatuscode_ArgumentSyntaxError";
|
||||
internal const string net_ftpstatuscode_CommandNotImplemented = "net_ftpstatuscode_CommandNotImplemented";
|
||||
internal const string net_ftpstatuscode_BadCommandSequence = "net_ftpstatuscode_BadCommandSequence";
|
||||
internal const string net_ftpstatuscode_NotLoggedIn = "net_ftpstatuscode_NotLoggedIn";
|
||||
internal const string net_ftpstatuscode_AccountNeeded = "net_ftpstatuscode_AccountNeeded";
|
||||
internal const string net_ftpstatuscode_ActionNotTakenFileUnavailable = "net_ftpstatuscode_ActionNotTakenFileUnavailable";
|
||||
internal const string net_ftpstatuscode_ActionAbortedUnknownPageType = "net_ftpstatuscode_ActionAbortedUnknownPageType";
|
||||
internal const string net_ftpstatuscode_FileActionAborted = "net_ftpstatuscode_FileActionAborted";
|
||||
internal const string net_ftpstatuscode_ActionNotTakenFilenameNotAllowed = "net_ftpstatuscode_ActionNotTakenFilenameNotAllowed";
|
||||
internal const string net_httpstatuscode_NoContent = "net_httpstatuscode_NoContent";
|
||||
internal const string net_httpstatuscode_NonAuthoritativeInformation = "net_httpstatuscode_NonAuthoritativeInformation";
|
||||
internal const string net_httpstatuscode_ResetContent = "net_httpstatuscode_ResetContent";
|
||||
internal const string net_httpstatuscode_PartialContent = "net_httpstatuscode_PartialContent";
|
||||
internal const string net_httpstatuscode_MultipleChoices = "net_httpstatuscode_MultipleChoices";
|
||||
internal const string net_httpstatuscode_Ambiguous = "net_httpstatuscode_Ambiguous";
|
||||
internal const string net_httpstatuscode_MovedPermanently = "net_httpstatuscode_MovedPermanently";
|
||||
internal const string net_httpstatuscode_Moved = "net_httpstatuscode_Moved";
|
||||
internal const string net_httpstatuscode_Found = "net_httpstatuscode_Found";
|
||||
internal const string net_httpstatuscode_Redirect = "net_httpstatuscode_Redirect";
|
||||
internal const string net_httpstatuscode_SeeOther = "net_httpstatuscode_SeeOther";
|
||||
internal const string net_httpstatuscode_RedirectMethod = "net_httpstatuscode_RedirectMethod";
|
||||
internal const string net_httpstatuscode_NotModified = "net_httpstatuscode_NotModified";
|
||||
internal const string net_httpstatuscode_UseProxy = "net_httpstatuscode_UseProxy";
|
||||
internal const string net_httpstatuscode_TemporaryRedirect = "net_httpstatuscode_TemporaryRedirect";
|
||||
internal const string net_httpstatuscode_RedirectKeepVerb = "net_httpstatuscode_RedirectKeepVerb";
|
||||
internal const string net_httpstatuscode_BadRequest = "net_httpstatuscode_BadRequest";
|
||||
internal const string net_httpstatuscode_Unauthorized = "net_httpstatuscode_Unauthorized";
|
||||
internal const string net_httpstatuscode_PaymentRequired = "net_httpstatuscode_PaymentRequired";
|
||||
internal const string net_httpstatuscode_Forbidden = "net_httpstatuscode_Forbidden";
|
||||
internal const string net_httpstatuscode_NotFound = "net_httpstatuscode_NotFound";
|
||||
internal const string net_httpstatuscode_MethodNotAllowed = "net_httpstatuscode_MethodNotAllowed";
|
||||
internal const string net_httpstatuscode_NotAcceptable = "net_httpstatuscode_NotAcceptable";
|
||||
internal const string net_httpstatuscode_ProxyAuthenticationRequired = "net_httpstatuscode_ProxyAuthenticationRequired";
|
||||
internal const string net_httpstatuscode_RequestTimeout = "net_httpstatuscode_RequestTimeout";
|
||||
internal const string net_httpstatuscode_Conflict = "net_httpstatuscode_Conflict";
|
||||
internal const string net_httpstatuscode_Gone = "net_httpstatuscode_Gone";
|
||||
internal const string net_httpstatuscode_LengthRequired = "net_httpstatuscode_LengthRequired";
|
||||
internal const string net_httpstatuscode_InternalServerError = "net_httpstatuscode_InternalServerError";
|
||||
internal const string net_httpstatuscode_NotImplemented = "net_httpstatuscode_NotImplemented";
|
||||
internal const string net_httpstatuscode_BadGateway = "net_httpstatuscode_BadGateway";
|
||||
internal const string net_httpstatuscode_ServiceUnavailable = "net_httpstatuscode_ServiceUnavailable";
|
||||
internal const string net_httpstatuscode_GatewayTimeout = "net_httpstatuscode_GatewayTimeout";
|
||||
internal const string net_httpstatuscode_HttpVersionNotSupported = "net_httpstatuscode_HttpVersionNotSupported";
|
||||
internal const string net_uri_BadScheme = "net_uri_BadScheme";
|
||||
internal const string net_uri_BadFormat = "net_uri_BadFormat";
|
||||
internal const string net_uri_BadUserPassword = "net_uri_BadUserPassword";
|
||||
internal const string net_uri_BadHostName = "net_uri_BadHostName";
|
||||
internal const string net_uri_BadAuthority = "net_uri_BadAuthority";
|
||||
internal const string net_uri_BadAuthorityTerminator = "net_uri_BadAuthorityTerminator";
|
||||
internal const string net_uri_EmptyUri = "net_uri_EmptyUri";
|
||||
internal const string net_uri_BadString = "net_uri_BadString";
|
||||
internal const string net_uri_MustRootedPath = "net_uri_MustRootedPath";
|
||||
internal const string net_uri_BadPort = "net_uri_BadPort";
|
||||
internal const string net_uri_SizeLimit = "net_uri_SizeLimit";
|
||||
internal const string net_uri_SchemeLimit = "net_uri_SchemeLimit";
|
||||
internal const string net_uri_NotAbsolute = "net_uri_NotAbsolute";
|
||||
internal const string net_uri_PortOutOfRange = "net_uri_PortOutOfRange";
|
||||
internal const string net_uri_UserDrivenParsing = "net_uri_UserDrivenParsing";
|
||||
internal const string net_uri_AlreadyRegistered = "net_uri_AlreadyRegistered";
|
||||
internal const string net_uri_NeedFreshParser = "net_uri_NeedFreshParser";
|
||||
internal const string net_uri_CannotCreateRelative = "net_uri_CannotCreateRelative";
|
||||
internal const string net_uri_InvalidUriKind = "net_uri_InvalidUriKind";
|
||||
internal const string net_uri_BadUnicodeHostForIdn = "net_uri_BadUnicodeHostForIdn";
|
||||
internal const string net_uri_GenericAuthorityNotDnsSafe = "net_uri_GenericAuthorityNotDnsSafe";
|
||||
internal const string net_uri_NotJustSerialization = "net_uri_NotJustSerialization";
|
||||
internal const string net_emptystringset = "net_emptystringset";
|
||||
internal const string net_emptystringcall = "net_emptystringcall";
|
||||
internal const string net_headers_req = "net_headers_req";
|
||||
internal const string net_headers_rsp = "net_headers_rsp";
|
||||
internal const string net_headers_toolong = "net_headers_toolong";
|
||||
internal const string net_WebHeaderInvalidControlChars = "net_WebHeaderInvalidControlChars";
|
||||
internal const string net_WebHeaderInvalidCRLFChars = "net_WebHeaderInvalidCRLFChars";
|
||||
internal const string net_WebHeaderInvalidHeaderChars = "net_WebHeaderInvalidHeaderChars";
|
||||
internal const string net_WebHeaderInvalidNonAsciiChars = "net_WebHeaderInvalidNonAsciiChars";
|
||||
internal const string net_WebHeaderMissingColon = "net_WebHeaderMissingColon";
|
||||
internal const string net_headerrestrict = "net_headerrestrict";
|
||||
internal const string net_io_completionportwasbound = "net_io_completionportwasbound";
|
||||
internal const string net_io_writefailure = "net_io_writefailure";
|
||||
internal const string net_io_readfailure = "net_io_readfailure";
|
||||
internal const string net_io_connectionclosed = "net_io_connectionclosed";
|
||||
internal const string net_io_transportfailure = "net_io_transportfailure";
|
||||
internal const string net_io_internal_bind = "net_io_internal_bind";
|
||||
internal const string net_io_invalidasyncresult = "net_io_invalidasyncresult";
|
||||
internal const string net_io_invalidnestedcall = "net_io_invalidnestedcall";
|
||||
internal const string net_io_invalidendcall = "net_io_invalidendcall";
|
||||
internal const string net_io_must_be_rw_stream = "net_io_must_be_rw_stream";
|
||||
internal const string net_io_header_id = "net_io_header_id";
|
||||
internal const string net_io_out_range = "net_io_out_range";
|
||||
internal const string net_io_encrypt = "net_io_encrypt";
|
||||
internal const string net_io_decrypt = "net_io_decrypt";
|
||||
internal const string net_io_read = "net_io_read";
|
||||
internal const string net_io_write = "net_io_write";
|
||||
internal const string net_io_eof = "net_io_eof";
|
||||
internal const string net_io_async_result = "net_io_async_result";
|
||||
internal const string net_listener_mustcall = "net_listener_mustcall";
|
||||
internal const string net_listener_mustcompletecall = "net_listener_mustcompletecall";
|
||||
internal const string net_listener_callinprogress = "net_listener_callinprogress";
|
||||
internal const string net_listener_scheme = "net_listener_scheme";
|
||||
internal const string net_listener_host = "net_listener_host";
|
||||
internal const string net_listener_slash = "net_listener_slash";
|
||||
internal const string net_listener_repcall = "net_listener_repcall";
|
||||
internal const string net_listener_invalid_cbt_type = "net_listener_invalid_cbt_type";
|
||||
internal const string net_listener_no_spns = "net_listener_no_spns";
|
||||
internal const string net_listener_cannot_set_custom_cbt = "net_listener_cannot_set_custom_cbt";
|
||||
internal const string net_listener_cbt_not_supported = "net_listener_cbt_not_supported";
|
||||
internal const string net_listener_detach_error = "net_listener_detach_error";
|
||||
internal const string net_listener_close_urlgroup_error = "net_listener_close_urlgroup_error";
|
||||
internal const string net_tls_version = "net_tls_version";
|
||||
internal const string net_perm_target = "net_perm_target";
|
||||
internal const string net_perm_both_regex = "net_perm_both_regex";
|
||||
internal const string net_perm_none = "net_perm_none";
|
||||
internal const string net_perm_attrib_count = "net_perm_attrib_count";
|
||||
internal const string net_perm_invalid_val = "net_perm_invalid_val";
|
||||
internal const string net_perm_attrib_multi = "net_perm_attrib_multi";
|
||||
internal const string net_perm_epname = "net_perm_epname";
|
||||
internal const string net_perm_invalid_val_in_element = "net_perm_invalid_val_in_element";
|
||||
internal const string net_invalid_ip_addr = "net_invalid_ip_addr";
|
||||
internal const string dns_bad_ip_address = "dns_bad_ip_address";
|
||||
internal const string net_bad_mac_address = "net_bad_mac_address";
|
||||
internal const string net_ping = "net_ping";
|
||||
internal const string net_bad_ip_address_prefix = "net_bad_ip_address_prefix";
|
||||
internal const string net_max_ip_address_list_length_exceeded = "net_max_ip_address_list_length_exceeded";
|
||||
internal const string net_ipv4_not_installed = "net_ipv4_not_installed";
|
||||
internal const string net_ipv6_not_installed = "net_ipv6_not_installed";
|
||||
internal const string net_webclient = "net_webclient";
|
||||
internal const string net_webclient_ContentType = "net_webclient_ContentType";
|
||||
internal const string net_webclient_Multipart = "net_webclient_Multipart";
|
||||
internal const string net_webclient_no_concurrent_io_allowed = "net_webclient_no_concurrent_io_allowed";
|
||||
internal const string net_webclient_invalid_baseaddress = "net_webclient_invalid_baseaddress";
|
||||
internal const string net_container_add_cookie = "net_container_add_cookie";
|
||||
internal const string net_cookie_invalid = "net_cookie_invalid";
|
||||
internal const string net_cookie_size = "net_cookie_size";
|
||||
internal const string net_cookie_parse_header = "net_cookie_parse_header";
|
||||
internal const string net_cookie_attribute = "net_cookie_attribute";
|
||||
internal const string net_cookie_format = "net_cookie_format";
|
||||
internal const string net_cookie_exists = "net_cookie_exists";
|
||||
internal const string net_cookie_capacity_range = "net_cookie_capacity_range";
|
||||
internal const string net_set_token = "net_set_token";
|
||||
internal const string net_revert_token = "net_revert_token";
|
||||
internal const string net_ssl_io_async_context = "net_ssl_io_async_context";
|
||||
internal const string net_ssl_io_encrypt = "net_ssl_io_encrypt";
|
||||
internal const string net_ssl_io_decrypt = "net_ssl_io_decrypt";
|
||||
internal const string net_ssl_io_context_expired = "net_ssl_io_context_expired";
|
||||
internal const string net_ssl_io_handshake_start = "net_ssl_io_handshake_start";
|
||||
internal const string net_ssl_io_handshake = "net_ssl_io_handshake";
|
||||
internal const string net_ssl_io_frame = "net_ssl_io_frame";
|
||||
internal const string net_ssl_io_corrupted = "net_ssl_io_corrupted";
|
||||
internal const string net_ssl_io_cert_validation = "net_ssl_io_cert_validation";
|
||||
internal const string net_ssl_io_invalid_end_call = "net_ssl_io_invalid_end_call";
|
||||
internal const string net_ssl_io_invalid_begin_call = "net_ssl_io_invalid_begin_call";
|
||||
internal const string net_ssl_io_no_server_cert = "net_ssl_io_no_server_cert";
|
||||
internal const string net_auth_bad_client_creds = "net_auth_bad_client_creds";
|
||||
internal const string net_auth_bad_client_creds_or_target_mismatch = "net_auth_bad_client_creds_or_target_mismatch";
|
||||
internal const string net_auth_context_expectation = "net_auth_context_expectation";
|
||||
internal const string net_auth_context_expectation_remote = "net_auth_context_expectation_remote";
|
||||
internal const string net_auth_supported_impl_levels = "net_auth_supported_impl_levels";
|
||||
internal const string net_auth_no_anonymous_support = "net_auth_no_anonymous_support";
|
||||
internal const string net_auth_reauth = "net_auth_reauth";
|
||||
internal const string net_auth_noauth = "net_auth_noauth";
|
||||
internal const string net_auth_client_server = "net_auth_client_server";
|
||||
internal const string net_auth_noencryption = "net_auth_noencryption";
|
||||
internal const string net_auth_SSPI = "net_auth_SSPI";
|
||||
internal const string net_auth_failure = "net_auth_failure";
|
||||
internal const string net_auth_eof = "net_auth_eof";
|
||||
internal const string net_auth_alert = "net_auth_alert";
|
||||
internal const string net_auth_ignored_reauth = "net_auth_ignored_reauth";
|
||||
internal const string net_auth_empty_read = "net_auth_empty_read";
|
||||
internal const string net_auth_message_not_encrypted = "net_auth_message_not_encrypted";
|
||||
internal const string net_auth_must_specify_extended_protection_scheme = "net_auth_must_specify_extended_protection_scheme";
|
||||
internal const string net_frame_size = "net_frame_size";
|
||||
internal const string net_frame_read_io = "net_frame_read_io";
|
||||
internal const string net_frame_read_size = "net_frame_read_size";
|
||||
internal const string net_frame_max_size = "net_frame_max_size";
|
||||
internal const string net_jscript_load = "net_jscript_load";
|
||||
internal const string net_proxy_not_gmt = "net_proxy_not_gmt";
|
||||
internal const string net_proxy_invalid_dayofweek = "net_proxy_invalid_dayofweek";
|
||||
internal const string net_proxy_invalid_url_format = "net_proxy_invalid_url_format";
|
||||
internal const string net_param_not_string = "net_param_not_string";
|
||||
internal const string net_value_cannot_be_negative = "net_value_cannot_be_negative";
|
||||
internal const string net_invalid_offset = "net_invalid_offset";
|
||||
internal const string net_offset_plus_count = "net_offset_plus_count";
|
||||
internal const string net_cannot_be_false = "net_cannot_be_false";
|
||||
internal const string net_invalid_enum = "net_invalid_enum";
|
||||
internal const string net_listener_already = "net_listener_already";
|
||||
internal const string net_cache_shadowstream_not_writable = "net_cache_shadowstream_not_writable";
|
||||
internal const string net_cache_validator_fail = "net_cache_validator_fail";
|
||||
internal const string net_cache_access_denied = "net_cache_access_denied";
|
||||
internal const string net_cache_validator_result = "net_cache_validator_result";
|
||||
internal const string net_cache_retrieve_failure = "net_cache_retrieve_failure";
|
||||
internal const string net_cache_not_supported_body = "net_cache_not_supported_body";
|
||||
internal const string net_cache_not_supported_command = "net_cache_not_supported_command";
|
||||
internal const string net_cache_not_accept_response = "net_cache_not_accept_response";
|
||||
internal const string net_cache_method_failed = "net_cache_method_failed";
|
||||
internal const string net_cache_key_failed = "net_cache_key_failed";
|
||||
internal const string net_cache_no_stream = "net_cache_no_stream";
|
||||
internal const string net_cache_unsupported_partial_stream = "net_cache_unsupported_partial_stream";
|
||||
internal const string net_cache_not_configured = "net_cache_not_configured";
|
||||
internal const string net_cache_non_seekable_stream_not_supported = "net_cache_non_seekable_stream_not_supported";
|
||||
internal const string net_invalid_cast = "net_invalid_cast";
|
||||
internal const string net_collection_readonly = "net_collection_readonly";
|
||||
internal const string net_not_ipermission = "net_not_ipermission";
|
||||
internal const string net_no_classname = "net_no_classname";
|
||||
internal const string net_no_typename = "net_no_typename";
|
||||
internal const string net_array_too_small = "net_array_too_small";
|
||||
internal const string net_servicePointAddressNotSupportedInHostMode = "net_servicePointAddressNotSupportedInHostMode";
|
||||
internal const string net_Websockets_AlreadyOneOutstandingOperation = "net_Websockets_AlreadyOneOutstandingOperation";
|
||||
internal const string net_Websockets_WebSocketBaseFaulted = "net_Websockets_WebSocketBaseFaulted";
|
||||
internal const string net_WebSockets_NativeSendResponseHeaders = "net_WebSockets_NativeSendResponseHeaders";
|
||||
internal const string net_WebSockets_Generic = "net_WebSockets_Generic";
|
||||
internal const string net_WebSockets_NotAWebSocket_Generic = "net_WebSockets_NotAWebSocket_Generic";
|
||||
internal const string net_WebSockets_UnsupportedWebSocketVersion_Generic = "net_WebSockets_UnsupportedWebSocketVersion_Generic";
|
||||
internal const string net_WebSockets_HeaderError_Generic = "net_WebSockets_HeaderError_Generic";
|
||||
internal const string net_WebSockets_UnsupportedProtocol_Generic = "net_WebSockets_UnsupportedProtocol_Generic";
|
||||
internal const string net_WebSockets_UnsupportedPlatform = "net_WebSockets_UnsupportedPlatform";
|
||||
internal const string net_WebSockets_AcceptNotAWebSocket = "net_WebSockets_AcceptNotAWebSocket";
|
||||
internal const string net_WebSockets_AcceptUnsupportedWebSocketVersion = "net_WebSockets_AcceptUnsupportedWebSocketVersion";
|
||||
internal const string net_WebSockets_AcceptHeaderNotFound = "net_WebSockets_AcceptHeaderNotFound";
|
||||
internal const string net_WebSockets_AcceptUnsupportedProtocol = "net_WebSockets_AcceptUnsupportedProtocol";
|
||||
internal const string net_WebSockets_ClientAcceptingNoProtocols = "net_WebSockets_ClientAcceptingNoProtocols";
|
||||
internal const string net_WebSockets_ClientSecWebSocketProtocolsBlank = "net_WebSockets_ClientSecWebSocketProtocolsBlank";
|
||||
internal const string net_WebSockets_ArgumentOutOfRange_TooSmall = "net_WebSockets_ArgumentOutOfRange_TooSmall";
|
||||
internal const string net_WebSockets_ArgumentOutOfRange_InternalBuffer = "net_WebSockets_ArgumentOutOfRange_InternalBuffer";
|
||||
internal const string net_WebSockets_ArgumentOutOfRange_TooBig = "net_WebSockets_ArgumentOutOfRange_TooBig";
|
||||
internal const string net_WebSockets_InvalidState_Generic = "net_WebSockets_InvalidState_Generic";
|
||||
internal const string net_WebSockets_InvalidState_ClosedOrAborted = "net_WebSockets_InvalidState_ClosedOrAborted";
|
||||
internal const string net_WebSockets_InvalidState = "net_WebSockets_InvalidState";
|
||||
internal const string net_WebSockets_ReceiveAsyncDisallowedAfterCloseAsync = "net_WebSockets_ReceiveAsyncDisallowedAfterCloseAsync";
|
||||
internal const string net_WebSockets_InvalidMessageType = "net_WebSockets_InvalidMessageType";
|
||||
internal const string net_WebSockets_InvalidBufferType = "net_WebSockets_InvalidBufferType";
|
||||
internal const string net_WebSockets_InvalidMessageType_Generic = "net_WebSockets_InvalidMessageType_Generic";
|
||||
internal const string net_WebSockets_Argument_InvalidMessageType = "net_WebSockets_Argument_InvalidMessageType";
|
||||
internal const string net_WebSockets_ConnectionClosedPrematurely_Generic = "net_WebSockets_ConnectionClosedPrematurely_Generic";
|
||||
internal const string net_WebSockets_InvalidCharInProtocolString = "net_WebSockets_InvalidCharInProtocolString";
|
||||
internal const string net_WebSockets_InvalidEmptySubProtocol = "net_WebSockets_InvalidEmptySubProtocol";
|
||||
internal const string net_WebSockets_ReasonNotNull = "net_WebSockets_ReasonNotNull";
|
||||
internal const string net_WebSockets_InvalidCloseStatusCode = "net_WebSockets_InvalidCloseStatusCode";
|
||||
internal const string net_WebSockets_InvalidCloseStatusDescription = "net_WebSockets_InvalidCloseStatusDescription";
|
||||
internal const string net_WebSockets_Scheme = "net_WebSockets_Scheme";
|
||||
internal const string net_WebSockets_AlreadyStarted = "net_WebSockets_AlreadyStarted";
|
||||
internal const string net_WebSockets_Connect101Expected = "net_WebSockets_Connect101Expected";
|
||||
internal const string net_WebSockets_InvalidResponseHeader = "net_WebSockets_InvalidResponseHeader";
|
||||
internal const string net_WebSockets_NotConnected = "net_WebSockets_NotConnected";
|
||||
internal const string net_WebSockets_InvalidRegistration = "net_WebSockets_InvalidRegistration";
|
||||
internal const string net_WebSockets_NoDuplicateProtocol = "net_WebSockets_NoDuplicateProtocol";
|
||||
internal const string net_log_exception = "net_log_exception";
|
||||
internal const string net_log_listener_delegate_exception = "net_log_listener_delegate_exception";
|
||||
internal const string net_log_listener_unsupported_authentication_scheme = "net_log_listener_unsupported_authentication_scheme";
|
||||
internal const string net_log_listener_unmatched_authentication_scheme = "net_log_listener_unmatched_authentication_scheme";
|
||||
internal const string net_log_listener_create_valid_identity_failed = "net_log_listener_create_valid_identity_failed";
|
||||
internal const string net_log_listener_httpsys_registry_null = "net_log_listener_httpsys_registry_null";
|
||||
internal const string net_log_listener_httpsys_registry_error = "net_log_listener_httpsys_registry_error";
|
||||
internal const string net_log_listener_cant_convert_raw_path = "net_log_listener_cant_convert_raw_path";
|
||||
internal const string net_log_listener_cant_convert_percent_value = "net_log_listener_cant_convert_percent_value";
|
||||
internal const string net_log_listener_cant_convert_bytes = "net_log_listener_cant_convert_bytes";
|
||||
internal const string net_log_listener_cant_convert_to_utf8 = "net_log_listener_cant_convert_to_utf8";
|
||||
internal const string net_log_listener_cant_create_uri = "net_log_listener_cant_create_uri";
|
||||
internal const string net_log_listener_no_cbt_disabled = "net_log_listener_no_cbt_disabled";
|
||||
internal const string net_log_listener_no_cbt_http = "net_log_listener_no_cbt_http";
|
||||
internal const string net_log_listener_no_cbt_platform = "net_log_listener_no_cbt_platform";
|
||||
internal const string net_log_listener_no_cbt_trustedproxy = "net_log_listener_no_cbt_trustedproxy";
|
||||
internal const string net_log_listener_cbt = "net_log_listener_cbt";
|
||||
internal const string net_log_listener_no_spn_kerberos = "net_log_listener_no_spn_kerberos";
|
||||
internal const string net_log_listener_no_spn_disabled = "net_log_listener_no_spn_disabled";
|
||||
internal const string net_log_listener_no_spn_cbt = "net_log_listener_no_spn_cbt";
|
||||
internal const string net_log_listener_no_spn_platform = "net_log_listener_no_spn_platform";
|
||||
internal const string net_log_listener_no_spn_whensupported = "net_log_listener_no_spn_whensupported";
|
||||
internal const string net_log_listener_no_spn_loopback = "net_log_listener_no_spn_loopback";
|
||||
internal const string net_log_listener_spn = "net_log_listener_spn";
|
||||
internal const string net_log_listener_spn_passed = "net_log_listener_spn_passed";
|
||||
internal const string net_log_listener_spn_failed = "net_log_listener_spn_failed";
|
||||
internal const string net_log_listener_spn_failed_always = "net_log_listener_spn_failed_always";
|
||||
internal const string net_log_listener_spn_failed_empty = "net_log_listener_spn_failed_empty";
|
||||
internal const string net_log_listener_spn_failed_dump = "net_log_listener_spn_failed_dump";
|
||||
internal const string net_log_listener_spn_add = "net_log_listener_spn_add";
|
||||
internal const string net_log_listener_spn_not_add = "net_log_listener_spn_not_add";
|
||||
internal const string net_log_listener_spn_remove = "net_log_listener_spn_remove";
|
||||
internal const string net_log_listener_spn_not_remove = "net_log_listener_spn_not_remove";
|
||||
internal const string net_log_sspi_enumerating_security_packages = "net_log_sspi_enumerating_security_packages";
|
||||
internal const string net_log_sspi_security_package_not_found = "net_log_sspi_security_package_not_found";
|
||||
internal const string net_log_sspi_security_context_input_buffer = "net_log_sspi_security_context_input_buffer";
|
||||
internal const string net_log_sspi_security_context_input_buffers = "net_log_sspi_security_context_input_buffers";
|
||||
internal const string net_log_sspi_selected_cipher_suite = "net_log_sspi_selected_cipher_suite";
|
||||
internal const string net_log_remote_certificate = "net_log_remote_certificate";
|
||||
internal const string net_log_locating_private_key_for_certificate = "net_log_locating_private_key_for_certificate";
|
||||
internal const string net_log_cert_is_of_type_2 = "net_log_cert_is_of_type_2";
|
||||
internal const string net_log_found_cert_in_store = "net_log_found_cert_in_store";
|
||||
internal const string net_log_did_not_find_cert_in_store = "net_log_did_not_find_cert_in_store";
|
||||
internal const string net_log_open_store_failed = "net_log_open_store_failed";
|
||||
internal const string net_log_got_certificate_from_delegate = "net_log_got_certificate_from_delegate";
|
||||
internal const string net_log_no_delegate_and_have_no_client_cert = "net_log_no_delegate_and_have_no_client_cert";
|
||||
internal const string net_log_no_delegate_but_have_client_cert = "net_log_no_delegate_but_have_client_cert";
|
||||
internal const string net_log_attempting_restart_using_cert = "net_log_attempting_restart_using_cert";
|
||||
internal const string net_log_no_issuers_try_all_certs = "net_log_no_issuers_try_all_certs";
|
||||
internal const string net_log_server_issuers_look_for_matching_certs = "net_log_server_issuers_look_for_matching_certs";
|
||||
internal const string net_log_selected_cert = "net_log_selected_cert";
|
||||
internal const string net_log_n_certs_after_filtering = "net_log_n_certs_after_filtering";
|
||||
internal const string net_log_finding_matching_certs = "net_log_finding_matching_certs";
|
||||
internal const string net_log_using_cached_credential = "net_log_using_cached_credential";
|
||||
internal const string net_log_remote_cert_user_declared_valid = "net_log_remote_cert_user_declared_valid";
|
||||
internal const string net_log_remote_cert_user_declared_invalid = "net_log_remote_cert_user_declared_invalid";
|
||||
internal const string net_log_remote_cert_has_no_errors = "net_log_remote_cert_has_no_errors";
|
||||
internal const string net_log_remote_cert_has_errors = "net_log_remote_cert_has_errors";
|
||||
internal const string net_log_remote_cert_not_available = "net_log_remote_cert_not_available";
|
||||
internal const string net_log_remote_cert_name_mismatch = "net_log_remote_cert_name_mismatch";
|
||||
internal const string net_log_proxy_autodetect_script_location_parse_error = "net_log_proxy_autodetect_script_location_parse_error";
|
||||
internal const string net_log_proxy_autodetect_failed = "net_log_proxy_autodetect_failed";
|
||||
internal const string net_log_proxy_script_execution_error = "net_log_proxy_script_execution_error";
|
||||
internal const string net_log_proxy_script_download_compile_error = "net_log_proxy_script_download_compile_error";
|
||||
internal const string net_log_proxy_system_setting_update = "net_log_proxy_system_setting_update";
|
||||
internal const string net_log_proxy_update_due_to_ip_config_change = "net_log_proxy_update_due_to_ip_config_change";
|
||||
internal const string net_log_proxy_called_with_null_parameter = "net_log_proxy_called_with_null_parameter";
|
||||
internal const string net_log_proxy_called_with_invalid_parameter = "net_log_proxy_called_with_invalid_parameter";
|
||||
internal const string net_log_proxy_ras_supported = "net_log_proxy_ras_supported";
|
||||
internal const string net_log_proxy_ras_notsupported_exception = "net_log_proxy_ras_notsupported_exception";
|
||||
internal const string net_log_proxy_winhttp_cant_open_session = "net_log_proxy_winhttp_cant_open_session";
|
||||
internal const string net_log_proxy_winhttp_getproxy_failed = "net_log_proxy_winhttp_getproxy_failed";
|
||||
internal const string net_log_proxy_winhttp_timeout_error = "net_log_proxy_winhttp_timeout_error";
|
||||
internal const string net_log_digest_hash_algorithm_not_supported = "net_log_digest_hash_algorithm_not_supported";
|
||||
internal const string net_log_digest_qop_not_supported = "net_log_digest_qop_not_supported";
|
||||
internal const string net_log_digest_requires_nonce = "net_log_digest_requires_nonce";
|
||||
internal const string net_log_auth_invalid_challenge = "net_log_auth_invalid_challenge";
|
||||
internal const string net_log_unknown = "net_log_unknown";
|
||||
internal const string net_log_operation_returned_something = "net_log_operation_returned_something";
|
||||
internal const string net_log_operation_failed_with_error = "net_log_operation_failed_with_error";
|
||||
internal const string net_log_buffered_n_bytes = "net_log_buffered_n_bytes";
|
||||
internal const string net_log_method_equal = "net_log_method_equal";
|
||||
internal const string net_log_releasing_connection = "net_log_releasing_connection";
|
||||
internal const string net_log_unexpected_exception = "net_log_unexpected_exception";
|
||||
internal const string net_log_server_response_error_code = "net_log_server_response_error_code";
|
||||
internal const string net_log_resubmitting_request = "net_log_resubmitting_request";
|
||||
internal const string net_log_retrieving_localhost_exception = "net_log_retrieving_localhost_exception";
|
||||
internal const string net_log_resolved_servicepoint_may_not_be_remote_server = "net_log_resolved_servicepoint_may_not_be_remote_server";
|
||||
internal const string net_log_closed_idle = "net_log_closed_idle";
|
||||
internal const string net_log_received_status_line = "net_log_received_status_line";
|
||||
internal const string net_log_sending_headers = "net_log_sending_headers";
|
||||
internal const string net_log_received_headers = "net_log_received_headers";
|
||||
internal const string net_log_shell_expression_pattern_format_warning = "net_log_shell_expression_pattern_format_warning";
|
||||
internal const string net_log_exception_in_callback = "net_log_exception_in_callback";
|
||||
internal const string net_log_sending_command = "net_log_sending_command";
|
||||
internal const string net_log_received_response = "net_log_received_response";
|
||||
internal const string net_log_socket_connected = "net_log_socket_connected";
|
||||
internal const string net_log_socket_accepted = "net_log_socket_accepted";
|
||||
internal const string net_log_socket_not_logged_file = "net_log_socket_not_logged_file";
|
||||
internal const string net_log_socket_connect_dnsendpoint = "net_log_socket_connect_dnsendpoint";
|
||||
internal const string SSPIInvalidHandleType = "SSPIInvalidHandleType";
|
||||
|
||||
private static SR loader = null;
|
||||
private ResourceManager resources;
|
||||
|
||||
internal SR()
|
||||
{
|
||||
resources = new System.Resources.ResourceManager("System", this.GetType().Assembly);
|
||||
}
|
||||
|
||||
private static SR GetLoader()
|
||||
{
|
||||
if (loader == null)
|
||||
{
|
||||
SR sr = new SR();
|
||||
Interlocked.CompareExchange(ref loader, sr, null);
|
||||
}
|
||||
return loader;
|
||||
}
|
||||
|
||||
private static CultureInfo Culture
|
||||
{
|
||||
get { return null/*use ResourceManager default, CultureInfo.CurrentUICulture*/; }
|
||||
}
|
||||
|
||||
public static ResourceManager Resources
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetLoader().resources;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetString(string name, params object[] args)
|
||||
{
|
||||
SR sys = GetLoader();
|
||||
if (sys == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
string res = sys.resources.GetString(name, SR.Culture);
|
||||
|
||||
if (args != null && args.Length > 0)
|
||||
{
|
||||
for (int i = 0; i < args.Length; i++)
|
||||
{
|
||||
String value = args[i] as String;
|
||||
if (value != null && value.Length > 1024)
|
||||
{
|
||||
args[i] = value.Substring(0, 1024 - 3) + "...";
|
||||
}
|
||||
}
|
||||
return String.Format(CultureInfo.CurrentCulture, res, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetString(string name)
|
||||
{
|
||||
SR sys = GetLoader();
|
||||
if (sys == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return sys.resources.GetString(name, SR.Culture);
|
||||
}
|
||||
|
||||
public static string GetString(string name, out bool usedFallback)
|
||||
{
|
||||
// always false for this version of gensr
|
||||
usedFallback = false;
|
||||
return GetString(name);
|
||||
}
|
||||
|
||||
public static object GetObject(string name)
|
||||
{
|
||||
SR sys = GetLoader();
|
||||
if (sys == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return sys.resources.GetObject(name, SR.Culture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="ValidationHelper.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Net.Security;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Security.Authentication.ExtendedProtection;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Security.Permissions;
|
||||
|
||||
internal static class ValidationHelper
|
||||
{
|
||||
public static string ExceptionMessage(Exception exception)
|
||||
{
|
||||
if (exception == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
if (exception.InnerException == null)
|
||||
{
|
||||
return exception.Message;
|
||||
}
|
||||
return exception.Message + " (" + ExceptionMessage(exception.InnerException) + ")";
|
||||
}
|
||||
|
||||
public static string ToString(object objectValue)
|
||||
{
|
||||
if (objectValue == null)
|
||||
{
|
||||
return "(null)";
|
||||
}
|
||||
else if (objectValue is string && ((string)objectValue).Length == 0)
|
||||
{
|
||||
return "(string.empty)";
|
||||
}
|
||||
else if (objectValue is Exception)
|
||||
{
|
||||
return ExceptionMessage(objectValue as Exception);
|
||||
}
|
||||
else if (objectValue is IntPtr)
|
||||
{
|
||||
return "0x" + ((IntPtr)objectValue).ToString("x");
|
||||
}
|
||||
else
|
||||
{
|
||||
return objectValue.ToString();
|
||||
}
|
||||
}
|
||||
public static string HashString(object objectValue)
|
||||
{
|
||||
if (objectValue == null)
|
||||
{
|
||||
return "(null)";
|
||||
}
|
||||
else if (objectValue is string && ((string)objectValue).Length == 0)
|
||||
{
|
||||
return "(string.empty)";
|
||||
}
|
||||
else
|
||||
{
|
||||
return objectValue.GetHashCode().ToString(NumberFormatInfo.InvariantInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="__ToolsVersion__" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">12.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>efc7538f-7aeb-4a3e-a1e6-6bdccbd272bf</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<ActiveTargetFramework>net45</ActiveTargetFramework>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'" Label="Configuration">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'" Label="Configuration">
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
||||
|
|
@ -1,738 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="_NTAuthentication.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Net;
|
||||
using System.Security.Authentication.ExtendedProtection;
|
||||
using System.Security.Permissions;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
internal class NTAuthentication
|
||||
{
|
||||
private static readonly ContextCallback Callback = new ContextCallback(InitializeCallback);
|
||||
private static ISSPIInterface SSPIAuth = new SSPIAuthType();
|
||||
|
||||
private bool _isServer;
|
||||
|
||||
private SafeFreeCredentials _credentialsHandle;
|
||||
private SafeDeleteContext _securityContext;
|
||||
private string _spn;
|
||||
private string _clientSpecifiedSpn;
|
||||
|
||||
private int _tokenSize;
|
||||
private ContextFlags _requestedContextFlags;
|
||||
private ContextFlags _contextFlags;
|
||||
private string _uniqueUserId;
|
||||
|
||||
private bool _isCompleted;
|
||||
private string _protocolName;
|
||||
private SecSizes _sizes;
|
||||
private string _lastProtocolName;
|
||||
private string _package;
|
||||
|
||||
private ChannelBinding _channelBinding;
|
||||
|
||||
// This overload does not attmept to impersonate because the caller either did it already or the original thread context is still preserved
|
||||
|
||||
internal NTAuthentication(bool isServer, string package, NetworkCredential credential, string spn, ContextFlags requestedContextFlags, ChannelBinding channelBinding)
|
||||
{
|
||||
Initialize(isServer, package, credential, spn, requestedContextFlags, channelBinding);
|
||||
}
|
||||
|
||||
// This overload always uses the default credentials for the process.
|
||||
|
||||
[SecurityPermission(SecurityAction.Assert, Flags = SecurityPermissionFlag.ControlPrincipal)]
|
||||
internal NTAuthentication(bool isServer, string package, string spn, ContextFlags requestedContextFlags, ChannelBinding channelBinding)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (WindowsIdentity.Impersonate(IntPtr.Zero))
|
||||
{
|
||||
Initialize(isServer, package, CredentialCache.DefaultNetworkCredentials, spn, requestedContextFlags, channelBinding);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Avoid exception filter attacks.
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
// The semantic of this propoerty is "Don't call me again".
|
||||
// It can be completed either with success or error
|
||||
// The latest case is signalled by IsValidContext==false
|
||||
internal bool IsCompleted
|
||||
{
|
||||
get
|
||||
{
|
||||
return _isCompleted;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsValidContext
|
||||
{
|
||||
get
|
||||
{
|
||||
return !(_securityContext == null || _securityContext.IsInvalid);
|
||||
}
|
||||
}
|
||||
|
||||
internal string AssociatedName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!(IsValidContext && IsCompleted))
|
||||
{
|
||||
throw new Win32Exception((int)SecurityStatus.InvalidHandle);
|
||||
}
|
||||
|
||||
string name = SSPIWrapper.QueryContextAttributes(SSPIAuth, _securityContext, ContextAttribute.Names) as string;
|
||||
GlobalLog.Print("NTAuthentication: The context is associated with [" + name + "]");
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsConfidentialityFlag
|
||||
{
|
||||
get
|
||||
{
|
||||
return (_contextFlags & ContextFlags.Confidentiality) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsIntegrityFlag
|
||||
{
|
||||
get
|
||||
{
|
||||
return (_contextFlags & (_isServer ? ContextFlags.AcceptIntegrity : ContextFlags.InitIntegrity)) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsMutualAuthFlag
|
||||
{
|
||||
get
|
||||
{
|
||||
return (_contextFlags & ContextFlags.MutualAuth) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsDelegationFlag
|
||||
{
|
||||
get
|
||||
{
|
||||
return (_contextFlags & ContextFlags.Delegate) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsIdentifyFlag
|
||||
{
|
||||
get
|
||||
{
|
||||
return (_contextFlags & (_isServer ? ContextFlags.AcceptIdentify : ContextFlags.InitIdentify)) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
internal string Spn
|
||||
{
|
||||
get
|
||||
{
|
||||
return _spn;
|
||||
}
|
||||
}
|
||||
|
||||
internal string ClientSpecifiedSpn
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_clientSpecifiedSpn == null)
|
||||
{
|
||||
_clientSpecifiedSpn = GetClientSpecifiedSpn();
|
||||
}
|
||||
return _clientSpecifiedSpn;
|
||||
}
|
||||
}
|
||||
|
||||
// True indicates this instance is for Server and will use AcceptSecurityContext SSPI API
|
||||
|
||||
internal bool IsServer
|
||||
{
|
||||
get
|
||||
{
|
||||
return _isServer;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsKerberos
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_lastProtocolName == null)
|
||||
{
|
||||
_lastProtocolName = ProtocolName;
|
||||
}
|
||||
|
||||
return (object)_lastProtocolName == (object)NegotiationInfoClass.Kerberos;
|
||||
}
|
||||
}
|
||||
internal bool IsNTLM
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_lastProtocolName == null)
|
||||
{
|
||||
_lastProtocolName = ProtocolName;
|
||||
}
|
||||
|
||||
return (object)_lastProtocolName == (object)NegotiationInfoClass.NTLM;
|
||||
}
|
||||
}
|
||||
|
||||
internal string Package
|
||||
{
|
||||
get
|
||||
{
|
||||
return _package;
|
||||
}
|
||||
}
|
||||
|
||||
internal string ProtocolName
|
||||
{
|
||||
get
|
||||
{
|
||||
// NB: May return string.Empty if the auth is not done yet or failed
|
||||
if (_protocolName == null)
|
||||
{
|
||||
NegotiationInfoClass negotiationInfo = null;
|
||||
|
||||
if (IsValidContext)
|
||||
{
|
||||
negotiationInfo = SSPIWrapper.QueryContextAttributes(SSPIAuth, _securityContext, ContextAttribute.NegotiationInfo) as NegotiationInfoClass;
|
||||
if (IsCompleted)
|
||||
{
|
||||
if (negotiationInfo != null)
|
||||
{
|
||||
// cache it only when it's completed
|
||||
_protocolName = negotiationInfo.AuthenticationPackage;
|
||||
}
|
||||
}
|
||||
}
|
||||
return negotiationInfo == null ? string.Empty : negotiationInfo.AuthenticationPackage;
|
||||
}
|
||||
return _protocolName;
|
||||
}
|
||||
}
|
||||
|
||||
internal SecSizes Sizes
|
||||
{
|
||||
get
|
||||
{
|
||||
GlobalLog.Assert(IsCompleted && IsValidContext, "NTAuthentication#{0}::MaxDataSize|The context is not completed or invalid.", ValidationHelper.HashString(this));
|
||||
if (_sizes == null)
|
||||
{
|
||||
_sizes = SSPIWrapper.QueryContextAttributes(
|
||||
SSPIAuth,
|
||||
_securityContext,
|
||||
ContextAttribute.Sizes) as SecSizes;
|
||||
}
|
||||
return _sizes;
|
||||
}
|
||||
}
|
||||
|
||||
internal ChannelBinding ChannelBinding
|
||||
{
|
||||
get { return _channelBinding; }
|
||||
}
|
||||
|
||||
private static void InitializeCallback(object state)
|
||||
{
|
||||
InitializeCallbackContext context = (InitializeCallbackContext)state;
|
||||
context.ThisPtr.Initialize(context.IsServer, context.Package, context.Credential, context.Spn, context.RequestedContextFlags, context.ChannelBinding);
|
||||
}
|
||||
|
||||
private void Initialize(bool isServer, string package, NetworkCredential credential, string spn, ContextFlags requestedContextFlags, ChannelBinding channelBinding)
|
||||
{
|
||||
GlobalLog.Print("NTAuthentication#" + ValidationHelper.HashString(this) + "::.ctor() package:" + ValidationHelper.ToString(package) + " spn:" + ValidationHelper.ToString(spn) + " flags :" + requestedContextFlags.ToString());
|
||||
_tokenSize = SSPIWrapper.GetVerifyPackageInfo(SSPIAuth, package, true).MaxToken;
|
||||
_isServer = isServer;
|
||||
_spn = spn;
|
||||
_securityContext = null;
|
||||
_requestedContextFlags = requestedContextFlags;
|
||||
_package = package;
|
||||
_channelBinding = channelBinding;
|
||||
|
||||
GlobalLog.Print("Peer SPN-> '" + _spn + "'");
|
||||
|
||||
// check if we're using DefaultCredentials
|
||||
|
||||
if (credential == CredentialCache.DefaultNetworkCredentials)
|
||||
{
|
||||
GlobalLog.Print("NTAuthentication#" + ValidationHelper.HashString(this) + "::.ctor(): using DefaultCredentials");
|
||||
_credentialsHandle = SSPIWrapper.AcquireDefaultCredential(
|
||||
SSPIAuth,
|
||||
package,
|
||||
(_isServer ? CredentialUse.Inbound : CredentialUse.Outbound));
|
||||
_uniqueUserId = "/S"; // save off for unique connection marking ONLY used by HTTP client
|
||||
}
|
||||
else if (ComNetOS.IsWin7orLater)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
SafeSspiAuthDataHandle authData = null;
|
||||
try
|
||||
{
|
||||
SecurityStatus result = UnsafeNclNativeMethods.SspiHelper.SspiEncodeStringsAsAuthIdentity(
|
||||
credential.UserName/*InternalGetUserName()*/, credential.Domain/*InternalGetDomain()*/,
|
||||
credential.Password/*InternalGetPassword()*/, out authData);
|
||||
|
||||
if (result != SecurityStatus.OK)
|
||||
{
|
||||
if (Logging.On)
|
||||
{
|
||||
Logging.PrintError(Logging.Web, SR.GetString(SR.net_log_operation_failed_with_error, "SspiEncodeStringsAsAuthIdentity()", String.Format(CultureInfo.CurrentCulture, "0x{0:X}", (int)result)));
|
||||
}
|
||||
throw new Win32Exception((int)result);
|
||||
}
|
||||
|
||||
_credentialsHandle = SSPIWrapper.AcquireCredentialsHandle(SSPIAuth,
|
||||
package, (_isServer ? CredentialUse.Inbound : CredentialUse.Outbound), ref authData);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (authData != null)
|
||||
{
|
||||
authData.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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 = credential.UserName; // InternalGetUserName();
|
||||
|
||||
string domain = credential.Domain; // InternalGetDomain();
|
||||
// ATTN:
|
||||
// NetworkCredential class does not differentiate between null and "" but SSPI packages treat these cases differently
|
||||
// For NTLM we want to keep "" for Wdigest.Dll we should use null.
|
||||
AuthIdentity authIdentity = new AuthIdentity(username, credential.Password/*InternalGetPassword()*/, (object)package == (object)NegotiationInfoClass.WDigest && (domain == null || domain.Length == 0) ? null : domain);
|
||||
|
||||
_uniqueUserId = domain + "/" + username + "/U"; // save off for unique connection marking ONLY used by HTTP client
|
||||
|
||||
GlobalLog.Print("NTAuthentication#" + ValidationHelper.HashString(this) + "::.ctor(): using authIdentity:" + authIdentity.ToString());
|
||||
|
||||
_credentialsHandle = SSPIWrapper.AcquireCredentialsHandle(
|
||||
SSPIAuth,
|
||||
package,
|
||||
(_isServer ? CredentialUse.Inbound : CredentialUse.Outbound),
|
||||
ref authIdentity);
|
||||
}
|
||||
}
|
||||
|
||||
// This will return an client token when conducted authentication on server side'
|
||||
// This token can be used ofr impersanation
|
||||
// We use it to create a WindowsIdentity and hand it out to the server app.
|
||||
internal SafeCloseHandle GetContextToken(out SecurityStatus status)
|
||||
{
|
||||
GlobalLog.Assert(IsCompleted && IsValidContext, "NTAuthentication#{0}::GetContextToken|Should be called only when completed with success, currently is not!", ValidationHelper.HashString(this));
|
||||
GlobalLog.Assert(IsServer, "NTAuthentication#{0}::GetContextToken|The method must not be called by the client side!", ValidationHelper.HashString(this));
|
||||
|
||||
if (!IsValidContext)
|
||||
{
|
||||
throw new Win32Exception((int)SecurityStatus.InvalidHandle);
|
||||
}
|
||||
|
||||
SafeCloseHandle token = null;
|
||||
status = (SecurityStatus)SSPIWrapper.QuerySecurityContextToken(
|
||||
SSPIAuth,
|
||||
_securityContext,
|
||||
out token);
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
internal SafeCloseHandle GetContextToken()
|
||||
{
|
||||
SecurityStatus status;
|
||||
SafeCloseHandle token = GetContextToken(out status);
|
||||
if (status != SecurityStatus.OK)
|
||||
{
|
||||
throw new Win32Exception((int)status);
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
internal void CloseContext()
|
||||
{
|
||||
if (_securityContext != null && !_securityContext.IsClosed)
|
||||
{
|
||||
_securityContext.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
// NTAuth::GetOutgoingBlob()
|
||||
// Created: 12-01-1999: L.M.
|
||||
// Description:
|
||||
// Accepts an incoming binary security blob and returns
|
||||
// an outgoing binary security blob
|
||||
internal byte[] GetOutgoingBlob(byte[] incomingBlob, bool throwOnError, out SecurityStatus statusCode)
|
||||
{
|
||||
GlobalLog.Enter("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingBlob", ((incomingBlob == null) ? "0" : incomingBlob.Length.ToString(NumberFormatInfo.InvariantInfo)) + " bytes");
|
||||
|
||||
List<SecurityBuffer> list = new List<SecurityBuffer>(2);
|
||||
|
||||
if (incomingBlob != null)
|
||||
{
|
||||
list.Add(new SecurityBuffer(incomingBlob, BufferType.Token));
|
||||
}
|
||||
if (_channelBinding != null)
|
||||
{
|
||||
list.Add(new SecurityBuffer(_channelBinding));
|
||||
}
|
||||
|
||||
SecurityBuffer[] inSecurityBufferArray = null;
|
||||
if (list.Count > 0)
|
||||
{
|
||||
inSecurityBufferArray = list.ToArray();
|
||||
}
|
||||
|
||||
SecurityBuffer outSecurityBuffer = new SecurityBuffer(_tokenSize, BufferType.Token);
|
||||
|
||||
bool firstTime = _securityContext == null;
|
||||
try
|
||||
{
|
||||
if (!_isServer)
|
||||
{
|
||||
// client session
|
||||
statusCode = (SecurityStatus)SSPIWrapper.InitializeSecurityContext(
|
||||
SSPIAuth,
|
||||
_credentialsHandle,
|
||||
ref _securityContext,
|
||||
_spn,
|
||||
_requestedContextFlags,
|
||||
Endianness.Network,
|
||||
inSecurityBufferArray,
|
||||
outSecurityBuffer,
|
||||
ref _contextFlags);
|
||||
|
||||
GlobalLog.Print("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingBlob() SSPIWrapper.InitializeSecurityContext() returns statusCode:0x" + ((int)statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")");
|
||||
|
||||
if (statusCode == SecurityStatus.CompleteNeeded)
|
||||
{
|
||||
SecurityBuffer[] inSecurityBuffers = new SecurityBuffer[1];
|
||||
inSecurityBuffers[0] = outSecurityBuffer;
|
||||
|
||||
statusCode = (SecurityStatus)SSPIWrapper.CompleteAuthToken(
|
||||
SSPIAuth,
|
||||
ref _securityContext,
|
||||
inSecurityBuffers);
|
||||
|
||||
GlobalLog.Print("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingDigestBlob() SSPIWrapper.CompleteAuthToken() returns statusCode:0x" + ((int)statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")");
|
||||
outSecurityBuffer.token = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// server session
|
||||
statusCode = (SecurityStatus)SSPIWrapper.AcceptSecurityContext(
|
||||
SSPIAuth,
|
||||
_credentialsHandle,
|
||||
ref _securityContext,
|
||||
_requestedContextFlags,
|
||||
Endianness.Network,
|
||||
inSecurityBufferArray,
|
||||
outSecurityBuffer,
|
||||
ref _contextFlags);
|
||||
|
||||
GlobalLog.Print("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingBlob() SSPIWrapper.AcceptSecurityContext() returns statusCode:0x" + ((int)statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")");
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Assuming the ISC or ASC has referenced the credential on the first successful call,
|
||||
// we want to decrement the effective ref count by "disposing" it.
|
||||
// The real dispose will happen when the security context is closed.
|
||||
// Note if the first call was not successfull the handle is physically destroyed here
|
||||
|
||||
if (firstTime && _credentialsHandle != null)
|
||||
{
|
||||
_credentialsHandle.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
if (((int)statusCode & unchecked((int)0x80000000)) != 0)
|
||||
{
|
||||
CloseContext();
|
||||
_isCompleted = true;
|
||||
if (throwOnError)
|
||||
{
|
||||
Win32Exception exception = new Win32Exception((int)statusCode);
|
||||
GlobalLog.Leave("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingBlob", "Win32Exception:" + exception);
|
||||
throw exception;
|
||||
}
|
||||
GlobalLog.Leave("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingBlob", "null statusCode:0x" + ((int)statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")");
|
||||
return null;
|
||||
}
|
||||
else if (firstTime && _credentialsHandle != null)
|
||||
{
|
||||
// cache until it is pushed out by newly incoming handles
|
||||
SSPIHandleCache.CacheCredential(_credentialsHandle);
|
||||
}
|
||||
|
||||
// the return value from SSPI will tell us correctly if the
|
||||
// handshake is over or not: http://msdn.microsoft.com/library/psdk/secspi/sspiref_67p0.htm
|
||||
// we also have to consider the case in which SSPI formed a new context, in this case we're done as well.
|
||||
if (statusCode == SecurityStatus.OK)
|
||||
{
|
||||
// we're sucessfully done
|
||||
GlobalLog.Assert(statusCode == SecurityStatus.OK, "NTAuthentication#{0}::GetOutgoingBlob()|statusCode:[0x{1:x8}] ({2}) m_SecurityContext#{3}::Handle:[{4}] [STATUS != OK]", ValidationHelper.HashString(this), (int)statusCode, statusCode, ValidationHelper.HashString(_securityContext), ValidationHelper.ToString(_securityContext));
|
||||
_isCompleted = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we need to continue
|
||||
GlobalLog.Print("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingBlob() need continue statusCode:[0x" + ((int)statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + "] (" + statusCode.ToString() + ") m_SecurityContext#" + ValidationHelper.HashString(_securityContext) + "::Handle:" + ValidationHelper.ToString(_securityContext) + "]");
|
||||
}
|
||||
// GlobalLog.Print("out token = " + outSecurityBuffer.ToString());
|
||||
// GlobalLog.Dump(outSecurityBuffer.token);
|
||||
GlobalLog.Leave("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingBlob", "IsCompleted:" + IsCompleted.ToString());
|
||||
return outSecurityBuffer.token;
|
||||
}
|
||||
|
||||
// for Server side (IIS 6.0) see: \\netindex\Sources\inetsrv\iis\iisrearc\iisplus\ulw3\digestprovider.cxx
|
||||
// for Client side (HTTP.SYS) see: \\netindex\Sources\net\http\sys\ucauth.c
|
||||
internal string GetOutgoingDigestBlob(string incomingBlob, string requestMethod, string requestedUri, string realm, bool isClientPreAuth, bool throwOnError, out SecurityStatus statusCode)
|
||||
{
|
||||
GlobalLog.Enter("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingDigestBlob", incomingBlob);
|
||||
|
||||
// second time call with 3 incoming buffers to select HTTP client.
|
||||
// we should get back a SecurityStatus.OK and a non null outgoingBlob.
|
||||
SecurityBuffer[] inSecurityBuffers = null;
|
||||
SecurityBuffer outSecurityBuffer = new SecurityBuffer(_tokenSize, isClientPreAuth ? BufferType.Parameters : BufferType.Token);
|
||||
|
||||
bool firstTime = _securityContext == null;
|
||||
try
|
||||
{
|
||||
if (!_isServer)
|
||||
{
|
||||
// client session
|
||||
|
||||
if (!isClientPreAuth)
|
||||
{
|
||||
if (incomingBlob != null)
|
||||
{
|
||||
List<SecurityBuffer> list = new List<SecurityBuffer>(5);
|
||||
|
||||
list.Add(new SecurityBuffer(HeaderEncoding.GetBytes(incomingBlob), BufferType.Token));
|
||||
list.Add(new SecurityBuffer(HeaderEncoding.GetBytes(requestMethod), BufferType.Parameters));
|
||||
list.Add(new SecurityBuffer(null, BufferType.Parameters));
|
||||
list.Add(new SecurityBuffer(Encoding.Unicode.GetBytes(_spn), BufferType.TargetHost));
|
||||
|
||||
if (_channelBinding != null)
|
||||
{
|
||||
list.Add(new SecurityBuffer(_channelBinding));
|
||||
}
|
||||
|
||||
inSecurityBuffers = list.ToArray();
|
||||
}
|
||||
|
||||
statusCode = (SecurityStatus)SSPIWrapper.InitializeSecurityContext(
|
||||
SSPIAuth,
|
||||
_credentialsHandle,
|
||||
ref _securityContext,
|
||||
requestedUri, // this must match the Uri in the HTTP status line for the current request
|
||||
_requestedContextFlags,
|
||||
Endianness.Network,
|
||||
inSecurityBuffers,
|
||||
outSecurityBuffer,
|
||||
ref _contextFlags);
|
||||
|
||||
GlobalLog.Print("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingDigestBlob() SSPIWrapper.InitializeSecurityContext() returns statusCode:0x" + ((int)statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
#if WDIGEST_PREAUTH
|
||||
inSecurityBuffers = new SecurityBuffer[] {
|
||||
new SecurityBuffer(null, BufferType.Token),
|
||||
new SecurityBuffer(WebHeaderCollection.HeaderEncoding.GetBytes(requestMethod), BufferType.Parameters),
|
||||
new SecurityBuffer(WebHeaderCollection.HeaderEncoding.GetBytes(requestedUri), BufferType.Parameters),
|
||||
new SecurityBuffer(null, BufferType.Parameters),
|
||||
outSecurityBuffer,
|
||||
};
|
||||
|
||||
statusCode = (SecurityStatus) SSPIWrapper.MakeSignature(GlobalSSPI.SSPIAuth, m_SecurityContext, inSecurityBuffers, 0);
|
||||
|
||||
GlobalLog.Print("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingDigestBlob() SSPIWrapper.MakeSignature() returns statusCode:0x" + ((int) statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")");
|
||||
#else
|
||||
statusCode = SecurityStatus.OK;
|
||||
GlobalLog.Assert("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingDigestBlob()", "Invalid code path.");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// server session
|
||||
List<SecurityBuffer> list = new List<SecurityBuffer>(6);
|
||||
|
||||
list.Add(incomingBlob == null ? new SecurityBuffer(0, BufferType.Token) : new SecurityBuffer(HeaderEncoding.GetBytes(incomingBlob), BufferType.Token));
|
||||
list.Add(requestMethod == null ? new SecurityBuffer(0, BufferType.Parameters) : new SecurityBuffer(HeaderEncoding.GetBytes(requestMethod), BufferType.Parameters));
|
||||
list.Add(requestedUri == null ? new SecurityBuffer(0, BufferType.Parameters) : new SecurityBuffer(HeaderEncoding.GetBytes(requestedUri), BufferType.Parameters));
|
||||
list.Add(new SecurityBuffer(0, BufferType.Parameters));
|
||||
list.Add(realm == null ? new SecurityBuffer(0, BufferType.Parameters) : new SecurityBuffer(Encoding.Unicode.GetBytes(realm), BufferType.Parameters));
|
||||
|
||||
if (_channelBinding != null)
|
||||
{
|
||||
list.Add(new SecurityBuffer(_channelBinding));
|
||||
}
|
||||
|
||||
inSecurityBuffers = list.ToArray();
|
||||
|
||||
statusCode = (SecurityStatus)SSPIWrapper.AcceptSecurityContext(
|
||||
SSPIAuth,
|
||||
_credentialsHandle,
|
||||
ref _securityContext,
|
||||
_requestedContextFlags,
|
||||
Endianness.Network,
|
||||
inSecurityBuffers,
|
||||
outSecurityBuffer,
|
||||
ref _contextFlags);
|
||||
|
||||
GlobalLog.Print("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingDigestBlob() SSPIWrapper.AcceptSecurityContext() returns statusCode:0x" + ((int)statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")");
|
||||
|
||||
if (statusCode == SecurityStatus.CompleteNeeded)
|
||||
{
|
||||
inSecurityBuffers[4] = outSecurityBuffer;
|
||||
|
||||
statusCode = (SecurityStatus)SSPIWrapper.CompleteAuthToken(
|
||||
SSPIAuth,
|
||||
ref _securityContext,
|
||||
inSecurityBuffers);
|
||||
|
||||
GlobalLog.Print("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingDigestBlob() SSPIWrapper.CompleteAuthToken() returns statusCode:0x" + ((int)statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")");
|
||||
|
||||
outSecurityBuffer.token = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Assuming the ISC or ASC has referenced the credential on the first successful call,
|
||||
// we want to decrement the effective ref count by "disposing" it.
|
||||
// The real dispose will happen when the security context is closed.
|
||||
// Note if the first call was not successfull the handle is physically destroyed here
|
||||
|
||||
if (firstTime && _credentialsHandle != null)
|
||||
{
|
||||
_credentialsHandle.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
if (((int)statusCode & unchecked((int)0x80000000)) != 0)
|
||||
{
|
||||
CloseContext();
|
||||
if (throwOnError)
|
||||
{
|
||||
Win32Exception exception = new Win32Exception((int)statusCode);
|
||||
GlobalLog.Leave("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingDigestBlob", "Win32Exception:" + exception);
|
||||
throw exception;
|
||||
}
|
||||
GlobalLog.Leave("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingDigestBlob", "null statusCode:0x" + ((int)statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + " (" + statusCode.ToString() + ")");
|
||||
return null;
|
||||
}
|
||||
else if (firstTime && _credentialsHandle != null)
|
||||
{
|
||||
// cache until it is pushed out by newly incoming handles
|
||||
SSPIHandleCache.CacheCredential(_credentialsHandle);
|
||||
}
|
||||
|
||||
// the return value from SSPI will tell us correctly if the
|
||||
// handshake is over or not: http://msdn.microsoft.com/library/psdk/secspi/sspiref_67p0.htm
|
||||
if (statusCode == SecurityStatus.OK)
|
||||
{
|
||||
// we're done, cleanup
|
||||
_isCompleted = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we need to continue
|
||||
GlobalLog.Print("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingDigestBlob() need continue statusCode:[0x" + ((int)statusCode).ToString("x8", NumberFormatInfo.InvariantInfo) + "] (" + statusCode.ToString() + ") m_SecurityContext#" + ValidationHelper.HashString(_securityContext) + "::Handle:" + ValidationHelper.ToString(_securityContext) + "]");
|
||||
}
|
||||
GlobalLog.Print("out token = " + outSecurityBuffer.ToString());
|
||||
GlobalLog.Dump(outSecurityBuffer.token);
|
||||
GlobalLog.Print("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingDigestBlob() IsCompleted:" + IsCompleted.ToString());
|
||||
|
||||
byte[] decodedOutgoingBlob = outSecurityBuffer.token;
|
||||
string outgoingBlob = null;
|
||||
if (decodedOutgoingBlob != null && decodedOutgoingBlob.Length > 0)
|
||||
{
|
||||
outgoingBlob = HeaderEncoding.GetString(decodedOutgoingBlob, 0, outSecurityBuffer.size);
|
||||
}
|
||||
GlobalLog.Leave("NTAuthentication#" + ValidationHelper.HashString(this) + "::GetOutgoingDigestBlob", outgoingBlob);
|
||||
return outgoingBlob;
|
||||
}
|
||||
|
||||
private string GetClientSpecifiedSpn()
|
||||
{
|
||||
GlobalLog.Assert(IsValidContext && IsCompleted, "NTAuthentication: Trying to get the client SPN before handshaking is done!");
|
||||
|
||||
string spn = SSPIWrapper.QueryContextAttributes(SSPIAuth, _securityContext,
|
||||
ContextAttribute.ClientSpecifiedSpn) as string;
|
||||
|
||||
GlobalLog.Print("NTAuthentication: The client specified SPN is [" + spn + "]");
|
||||
return spn;
|
||||
}
|
||||
|
||||
private class InitializeCallbackContext
|
||||
{
|
||||
internal readonly NTAuthentication ThisPtr;
|
||||
internal readonly bool IsServer;
|
||||
internal readonly string Package;
|
||||
internal readonly NetworkCredential Credential;
|
||||
internal readonly string Spn;
|
||||
internal readonly ContextFlags RequestedContextFlags;
|
||||
internal readonly ChannelBinding ChannelBinding;
|
||||
|
||||
internal InitializeCallbackContext(NTAuthentication thisPtr, bool isServer, string package, NetworkCredential credential, string spn, ContextFlags requestedContextFlags, ChannelBinding channelBinding)
|
||||
{
|
||||
this.ThisPtr = thisPtr;
|
||||
this.IsServer = isServer;
|
||||
this.Package = package;
|
||||
this.Credential = credential;
|
||||
this.Spn = spn;
|
||||
this.RequestedContextFlags = requestedContextFlags;
|
||||
this.ChannelBinding = channelBinding;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="AuthIdentity.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||
internal struct AuthIdentity
|
||||
{
|
||||
// see SEC_WINNT_AUTH_IDENTITY_W
|
||||
internal string UserName;
|
||||
internal int UserNameLength;
|
||||
internal string Domain;
|
||||
internal int DomainLength;
|
||||
internal string Password;
|
||||
internal int PasswordLength;
|
||||
internal int Flags;
|
||||
|
||||
internal AuthIdentity(string userName, string password, string domain)
|
||||
{
|
||||
UserName = userName;
|
||||
UserNameLength = userName == null ? 0 : userName.Length;
|
||||
Password = password;
|
||||
PasswordLength = password == null ? 0 : password.Length;
|
||||
Domain = domain;
|
||||
DomainLength = domain == null ? 0 : domain.Length;
|
||||
// Flags are 2 for Unicode and 1 for ANSI. We use 2 on NT and 1 on Win9x.
|
||||
Flags = 2;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return ValidationHelper.ToString(Domain) + "\\" + ValidationHelper.ToString(UserName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,141 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="ContextFlags.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
// #define ISC_REQ_DELEGATE 0x00000001
|
||||
// #define ISC_REQ_MUTUAL_AUTH 0x00000002
|
||||
// #define ISC_REQ_REPLAY_DETECT 0x00000004
|
||||
// #define ISC_REQ_SEQUENCE_DETECT 0x00000008
|
||||
// #define ISC_REQ_CONFIDENTIALITY 0x00000010
|
||||
// #define ISC_REQ_USE_SESSION_KEY 0x00000020
|
||||
// #define ISC_REQ_PROMPT_FOR_CREDS 0x00000040
|
||||
// #define ISC_REQ_USE_SUPPLIED_CREDS 0x00000080
|
||||
// #define ISC_REQ_ALLOCATE_MEMORY 0x00000100
|
||||
// #define ISC_REQ_USE_DCE_STYLE 0x00000200
|
||||
// #define ISC_REQ_DATAGRAM 0x00000400
|
||||
// #define ISC_REQ_CONNECTION 0x00000800
|
||||
// #define ISC_REQ_CALL_LEVEL 0x00001000
|
||||
// #define ISC_REQ_FRAGMENT_SUPPLIED 0x00002000
|
||||
// #define ISC_REQ_EXTENDED_ERROR 0x00004000
|
||||
// #define ISC_REQ_STREAM 0x00008000
|
||||
// #define ISC_REQ_INTEGRITY 0x00010000
|
||||
// #define ISC_REQ_IDENTIFY 0x00020000
|
||||
// #define ISC_REQ_NULL_SESSION 0x00040000
|
||||
// #define ISC_REQ_MANUAL_CRED_VALIDATION 0x00080000
|
||||
// #define ISC_REQ_RESERVED1 0x00100000
|
||||
// #define ISC_REQ_FRAGMENT_TO_FIT 0x00200000
|
||||
// #define ISC_REQ_HTTP 0x10000000
|
||||
// Win7 SP1 +
|
||||
// #define ISC_REQ_UNVERIFIED_TARGET_NAME 0x20000000
|
||||
|
||||
// #define ASC_REQ_DELEGATE 0x00000001
|
||||
// #define ASC_REQ_MUTUAL_AUTH 0x00000002
|
||||
// #define ASC_REQ_REPLAY_DETECT 0x00000004
|
||||
// #define ASC_REQ_SEQUENCE_DETECT 0x00000008
|
||||
// #define ASC_REQ_CONFIDENTIALITY 0x00000010
|
||||
// #define ASC_REQ_USE_SESSION_KEY 0x00000020
|
||||
// #define ASC_REQ_ALLOCATE_MEMORY 0x00000100
|
||||
// #define ASC_REQ_USE_DCE_STYLE 0x00000200
|
||||
// #define ASC_REQ_DATAGRAM 0x00000400
|
||||
// #define ASC_REQ_CONNECTION 0x00000800
|
||||
// #define ASC_REQ_CALL_LEVEL 0x00001000
|
||||
// #define ASC_REQ_EXTENDED_ERROR 0x00008000
|
||||
// #define ASC_REQ_STREAM 0x00010000
|
||||
// #define ASC_REQ_INTEGRITY 0x00020000
|
||||
// #define ASC_REQ_LICENSING 0x00040000
|
||||
// #define ASC_REQ_IDENTIFY 0x00080000
|
||||
// #define ASC_REQ_ALLOW_NULL_SESSION 0x00100000
|
||||
// #define ASC_REQ_ALLOW_NON_USER_LOGONS 0x00200000
|
||||
// #define ASC_REQ_ALLOW_CONTEXT_REPLAY 0x00400000
|
||||
// #define ASC_REQ_FRAGMENT_TO_FIT 0x00800000
|
||||
// #define ASC_REQ_FRAGMENT_SUPPLIED 0x00002000
|
||||
// #define ASC_REQ_NO_TOKEN 0x01000000
|
||||
// #define ASC_REQ_HTTP 0x10000000
|
||||
|
||||
[Flags]
|
||||
internal enum ContextFlags
|
||||
{
|
||||
Zero = 0,
|
||||
// The server in the transport application can
|
||||
// build new security contexts impersonating the
|
||||
// client that will be accepted by other servers
|
||||
// as the client's contexts.
|
||||
Delegate = 0x00000001,
|
||||
// The communicating parties must authenticate
|
||||
// their identities to each other. Without MutualAuth,
|
||||
// the client authenticates its identity to the server.
|
||||
// With MutualAuth, the server also must authenticate
|
||||
// its identity to the client.
|
||||
MutualAuth = 0x00000002,
|
||||
// The security package detects replayed packets and
|
||||
// notifies the caller if a packet has been replayed.
|
||||
// The use of this flag implies all of the conditions
|
||||
// specified by the Integrity flag.
|
||||
ReplayDetect = 0x00000004,
|
||||
// The context must be allowed to detect out-of-order
|
||||
// delivery of packets later through the message support
|
||||
// functions. Use of this flag implies all of the
|
||||
// conditions specified by the Integrity flag.
|
||||
SequenceDetect = 0x00000008,
|
||||
// The context must protect data while in transit.
|
||||
// Confidentiality is supported for NTLM with Microsoft
|
||||
// Windows NT version 4.0, SP4 and later and with the
|
||||
// Kerberos protocol in Microsoft Windows 2000 and later.
|
||||
Confidentiality = 0x00000010,
|
||||
UseSessionKey = 0x00000020,
|
||||
AllocateMemory = 0x00000100,
|
||||
|
||||
// Connection semantics must be used.
|
||||
Connection = 0x00000800,
|
||||
|
||||
// Client applications requiring extended error messages specify the
|
||||
// ISC_REQ_EXTENDED_ERROR flag when calling the InitializeSecurityContext
|
||||
// Server applications requiring extended error messages set
|
||||
// the ASC_REQ_EXTENDED_ERROR flag when calling AcceptSecurityContext.
|
||||
InitExtendedError = 0x00004000,
|
||||
AcceptExtendedError = 0x00008000,
|
||||
// A transport application requests stream semantics
|
||||
// by setting the ISC_REQ_STREAM and ASC_REQ_STREAM
|
||||
// flags in the calls to the InitializeSecurityContext
|
||||
// and AcceptSecurityContext functions
|
||||
InitStream = 0x00008000,
|
||||
AcceptStream = 0x00010000,
|
||||
// Buffer integrity can be verified; however, replayed
|
||||
// and out-of-sequence messages will not be detected
|
||||
InitIntegrity = 0x00010000, // ISC_REQ_INTEGRITY
|
||||
AcceptIntegrity = 0x00020000, // ASC_REQ_INTEGRITY
|
||||
|
||||
InitManualCredValidation = 0x00080000, // ISC_REQ_MANUAL_CRED_VALIDATION
|
||||
InitUseSuppliedCreds = 0x00000080, // ISC_REQ_USE_SUPPLIED_CREDS
|
||||
InitIdentify = 0x00020000, // ISC_REQ_IDENTIFY
|
||||
AcceptIdentify = 0x00080000, // ASC_REQ_IDENTIFY
|
||||
|
||||
ProxyBindings = 0x04000000, // ASC_REQ_PROXY_BINDINGS
|
||||
AllowMissingBindings = 0x10000000, // ASC_REQ_ALLOW_MISSING_BINDINGS
|
||||
|
||||
UnverifiedTargetName = 0x20000000, // ISC_REQ_UNVERIFIED_TARGET_NAME
|
||||
}
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="_NativeSSPI.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
// used to define the interface for security to use.
|
||||
internal interface ISSPIInterface
|
||||
{
|
||||
SecurityPackageInfoClass[] SecurityPackages { get; set; }
|
||||
int EnumerateSecurityPackages(out int pkgnum, out SafeFreeContextBuffer pkgArray);
|
||||
int AcquireCredentialsHandle(string moduleName, CredentialUse usage, ref AuthIdentity authdata, out SafeFreeCredentials outCredential);
|
||||
int AcquireCredentialsHandle(string moduleName, CredentialUse usage, ref SafeSspiAuthDataHandle authdata, out SafeFreeCredentials outCredential);
|
||||
int AcquireDefaultCredential(string moduleName, CredentialUse usage, out SafeFreeCredentials outCredential);
|
||||
int AcquireCredentialsHandle(string moduleName, CredentialUse usage, ref SecureCredential authdata, out SafeFreeCredentials outCredential);
|
||||
int AcceptSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer inputBuffer, ContextFlags inFlags,
|
||||
Endianness endianness, SecurityBuffer outputBuffer, ref ContextFlags outFlags);
|
||||
int AcceptSecurityContext(SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer[] inputBuffers, ContextFlags inFlags,
|
||||
Endianness endianness, SecurityBuffer outputBuffer, ref ContextFlags outFlags);
|
||||
int InitializeSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, ContextFlags inFlags,
|
||||
Endianness endianness, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, ref ContextFlags outFlags);
|
||||
int InitializeSecurityContext(SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, ContextFlags inFlags,
|
||||
Endianness endianness, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, ref ContextFlags outFlags);
|
||||
int EncryptMessage(SafeDeleteContext context, SecurityBufferDescriptor inputOutput, uint sequenceNumber);
|
||||
int DecryptMessage(SafeDeleteContext context, SecurityBufferDescriptor inputOutput, uint sequenceNumber);
|
||||
int MakeSignature(SafeDeleteContext context, SecurityBufferDescriptor inputOutput, uint sequenceNumber);
|
||||
int VerifySignature(SafeDeleteContext context, SecurityBufferDescriptor inputOutput, uint sequenceNumber);
|
||||
|
||||
int QueryContextChannelBinding(SafeDeleteContext phContext, ContextAttribute attribute, out SafeFreeContextBufferChannelBinding refHandle);
|
||||
int QueryContextAttributes(SafeDeleteContext phContext, ContextAttribute attribute, byte[] buffer, Type handleType, out SafeHandle refHandle);
|
||||
int SetContextAttributes(SafeDeleteContext phContext, ContextAttribute attribute, byte[] buffer);
|
||||
int QuerySecurityContextToken(SafeDeleteContext phContext, out SafeCloseHandle phToken);
|
||||
int CompleteAuthToken(ref SafeDeleteContext refContext, SecurityBuffer[] inputBuffers);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,319 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="SSPIAuthType.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
internal class SSPIAuthType : ISSPIInterface
|
||||
{
|
||||
private static volatile SecurityPackageInfoClass[] _securityPackages;
|
||||
|
||||
public SecurityPackageInfoClass[] SecurityPackages
|
||||
{
|
||||
get
|
||||
{
|
||||
return _securityPackages;
|
||||
}
|
||||
set
|
||||
{
|
||||
_securityPackages = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int EnumerateSecurityPackages(out int pkgnum, out SafeFreeContextBuffer pkgArray)
|
||||
{
|
||||
GlobalLog.Print("SSPIAuthType::EnumerateSecurityPackages()");
|
||||
return SafeFreeContextBuffer.EnumeratePackages(out pkgnum, out pkgArray);
|
||||
}
|
||||
|
||||
public int AcquireCredentialsHandle(string moduleName, CredentialUse usage, ref AuthIdentity authdata, out SafeFreeCredentials outCredential)
|
||||
{
|
||||
return SafeFreeCredentials.AcquireCredentialsHandle(moduleName, usage, ref authdata, out outCredential);
|
||||
}
|
||||
|
||||
public int AcquireCredentialsHandle(string moduleName, CredentialUse usage, ref SafeSspiAuthDataHandle authdata, out SafeFreeCredentials outCredential)
|
||||
{
|
||||
return SafeFreeCredentials.AcquireCredentialsHandle(moduleName, usage, ref authdata, out outCredential);
|
||||
}
|
||||
|
||||
public int AcquireDefaultCredential(string moduleName, CredentialUse usage, out SafeFreeCredentials outCredential)
|
||||
{
|
||||
return SafeFreeCredentials.AcquireDefaultCredential(moduleName, usage, out outCredential);
|
||||
}
|
||||
|
||||
public int AcquireCredentialsHandle(string moduleName, CredentialUse usage, ref SecureCredential authdata, out SafeFreeCredentials outCredential)
|
||||
{
|
||||
return SafeFreeCredentials.AcquireCredentialsHandle(moduleName, usage, ref authdata, out outCredential);
|
||||
}
|
||||
|
||||
public int AcceptSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer inputBuffer, ContextFlags inFlags, Endianness endianness, SecurityBuffer outputBuffer, ref ContextFlags outFlags)
|
||||
{
|
||||
return SafeDeleteContext.AcceptSecurityContext(ref credential, ref context, inFlags, endianness, inputBuffer, null, outputBuffer, ref outFlags);
|
||||
}
|
||||
|
||||
public int AcceptSecurityContext(SafeFreeCredentials credential, ref SafeDeleteContext context, SecurityBuffer[] inputBuffers, ContextFlags inFlags, Endianness endianness, SecurityBuffer outputBuffer, ref ContextFlags outFlags)
|
||||
{
|
||||
return SafeDeleteContext.AcceptSecurityContext(ref credential, ref context, inFlags, endianness, null, inputBuffers, outputBuffer, ref outFlags);
|
||||
}
|
||||
|
||||
public int InitializeSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, ContextFlags inFlags, Endianness endianness, SecurityBuffer inputBuffer, SecurityBuffer outputBuffer, ref ContextFlags outFlags)
|
||||
{
|
||||
return SafeDeleteContext.InitializeSecurityContext(ref credential, ref context, targetName, inFlags, endianness, inputBuffer, null, outputBuffer, ref outFlags);
|
||||
}
|
||||
|
||||
public int InitializeSecurityContext(SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, ContextFlags inFlags, Endianness endianness, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, ref ContextFlags outFlags)
|
||||
{
|
||||
return SafeDeleteContext.InitializeSecurityContext(ref credential, ref context, targetName, inFlags, endianness, null, inputBuffers, outputBuffer, ref outFlags);
|
||||
}
|
||||
|
||||
public int EncryptMessage(SafeDeleteContext context, SecurityBufferDescriptor inputOutput, uint sequenceNumber)
|
||||
{
|
||||
int status = (int)SecurityStatus.InvalidHandle;
|
||||
bool b = false;
|
||||
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try
|
||||
{
|
||||
context.DangerousAddRef(ref b);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
context.DangerousRelease();
|
||||
b = false;
|
||||
}
|
||||
if (!(e is ObjectDisposedException))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
status = UnsafeNclNativeMethods.NativeNTSSPI.EncryptMessage(ref context._handle, 0, inputOutput, sequenceNumber);
|
||||
context.DangerousRelease();
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
public unsafe int DecryptMessage(SafeDeleteContext context, SecurityBufferDescriptor inputOutput, uint sequenceNumber)
|
||||
{
|
||||
int status = (int)SecurityStatus.InvalidHandle;
|
||||
bool b = false;
|
||||
uint qop = 0;
|
||||
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try
|
||||
{
|
||||
context.DangerousAddRef(ref b);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
context.DangerousRelease();
|
||||
b = false;
|
||||
}
|
||||
if (!(e is ObjectDisposedException))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
status = UnsafeNclNativeMethods.NativeNTSSPI.DecryptMessage(ref context._handle, inputOutput, sequenceNumber, &qop);
|
||||
context.DangerousRelease();
|
||||
}
|
||||
}
|
||||
|
||||
const uint SECQOP_WRAP_NO_ENCRYPT = 0x80000001;
|
||||
if (status == 0 && qop == SECQOP_WRAP_NO_ENCRYPT)
|
||||
{
|
||||
GlobalLog.Assert("NativeNTSSPI.DecryptMessage", "Expected qop = 0, returned value = " + qop.ToString("x", CultureInfo.InvariantCulture));
|
||||
throw new InvalidOperationException(SR.GetString(SR.net_auth_message_not_encrypted));
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
public int MakeSignature(SafeDeleteContext context, SecurityBufferDescriptor inputOutput, uint sequenceNumber)
|
||||
{
|
||||
int status = (int)SecurityStatus.InvalidHandle;
|
||||
bool b = false;
|
||||
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try
|
||||
{
|
||||
context.DangerousAddRef(ref b);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
context.DangerousRelease();
|
||||
b = false;
|
||||
}
|
||||
if (!(e is ObjectDisposedException))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
const uint SECQOP_WRAP_NO_ENCRYPT = 0x80000001;
|
||||
status = UnsafeNclNativeMethods.NativeNTSSPI.EncryptMessage(ref context._handle, SECQOP_WRAP_NO_ENCRYPT, inputOutput, sequenceNumber);
|
||||
context.DangerousRelease();
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
public unsafe int VerifySignature(SafeDeleteContext context, SecurityBufferDescriptor inputOutput, uint sequenceNumber)
|
||||
{
|
||||
int status = (int)SecurityStatus.InvalidHandle;
|
||||
bool b = false;
|
||||
|
||||
uint qop = 0;
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try
|
||||
{
|
||||
context.DangerousAddRef(ref b);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
context.DangerousRelease();
|
||||
b = false;
|
||||
}
|
||||
if (!(e is ObjectDisposedException))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
status = UnsafeNclNativeMethods.NativeNTSSPI.DecryptMessage(ref context._handle, inputOutput, sequenceNumber, &qop);
|
||||
context.DangerousRelease();
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
public int QueryContextChannelBinding(SafeDeleteContext context, ContextAttribute attribute, out SafeFreeContextBufferChannelBinding binding)
|
||||
{
|
||||
// Querying an auth SSP for a CBT doesn't make sense
|
||||
binding = null;
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public unsafe int QueryContextAttributes(SafeDeleteContext context, ContextAttribute attribute, byte[] buffer, Type handleType, out SafeHandle refHandle)
|
||||
{
|
||||
refHandle = null;
|
||||
if (handleType != null)
|
||||
{
|
||||
if (handleType == typeof(SafeFreeContextBuffer))
|
||||
{
|
||||
refHandle = SafeFreeContextBuffer.CreateEmptyHandle();
|
||||
}
|
||||
else if (handleType == typeof(SafeFreeCertContext))
|
||||
{
|
||||
refHandle = new SafeFreeCertContext();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException(SR.GetString(SR.SSPIInvalidHandleType, handleType.FullName), "handleType");
|
||||
}
|
||||
}
|
||||
|
||||
fixed (byte* bufferPtr = buffer)
|
||||
{
|
||||
return SafeFreeContextBuffer.QueryContextAttributes(context, attribute, bufferPtr, refHandle);
|
||||
}
|
||||
}
|
||||
|
||||
public int SetContextAttributes(SafeDeleteContext context, ContextAttribute attribute, byte[] buffer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public int QuerySecurityContextToken(SafeDeleteContext phContext, out SafeCloseHandle phToken)
|
||||
{
|
||||
return GetSecurityContextToken(phContext, out phToken);
|
||||
}
|
||||
|
||||
public int CompleteAuthToken(ref SafeDeleteContext refContext, SecurityBuffer[] inputBuffers)
|
||||
{
|
||||
return SafeDeleteContext.CompleteAuthToken(ref refContext, inputBuffers);
|
||||
}
|
||||
|
||||
private static int GetSecurityContextToken(SafeDeleteContext phContext, out SafeCloseHandle safeHandle)
|
||||
{
|
||||
int status = (int)SecurityStatus.InvalidHandle;
|
||||
bool b = false;
|
||||
safeHandle = null;
|
||||
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try
|
||||
{
|
||||
phContext.DangerousAddRef(ref b);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
phContext.DangerousRelease();
|
||||
b = false;
|
||||
}
|
||||
if (!(e is ObjectDisposedException))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
status = UnsafeNclNativeMethods.SafeNetHandles.QuerySecurityContextToken(ref phContext._handle, out safeHandle);
|
||||
phContext.DangerousRelease();
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="SSPIHandle.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
internal struct SSPIHandle
|
||||
{
|
||||
private IntPtr HandleHi;
|
||||
private IntPtr HandleLo;
|
||||
|
||||
public bool IsZero
|
||||
{
|
||||
get { return HandleHi == IntPtr.Zero && HandleLo == IntPtr.Zero; }
|
||||
}
|
||||
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
internal void SetToInvalid()
|
||||
{
|
||||
HandleHi = IntPtr.Zero;
|
||||
HandleLo = IntPtr.Zero;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return HandleHi.ToString("x") + ":" + HandleLo.ToString("x");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="SSPIHandleCache.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Abstract:
|
||||
The file implements trivial SSPI credential caching mechanism based on lru list
|
||||
*/
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
// Implements delayed SSPI handle release, like a finalizable object though the handles are kept alive until being pushed out
|
||||
// by the newly incoming ones.
|
||||
internal static class SSPIHandleCache
|
||||
{
|
||||
private const int MaxCacheSize = 0x1F; // must a (power of 2) - 1
|
||||
private static SafeCredentialReference[] _cacheSlots = new SafeCredentialReference[MaxCacheSize + 1];
|
||||
private static int _current = -1;
|
||||
|
||||
internal static void CacheCredential(SafeFreeCredentials newHandle)
|
||||
{
|
||||
try
|
||||
{
|
||||
SafeCredentialReference newRef = SafeCredentialReference.CreateReference(newHandle);
|
||||
if (newRef == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
unchecked
|
||||
{
|
||||
int index = Interlocked.Increment(ref _current) & MaxCacheSize;
|
||||
newRef = Interlocked.Exchange<SafeCredentialReference>(ref _cacheSlots[index], newRef);
|
||||
}
|
||||
if (newRef != null)
|
||||
{
|
||||
newRef.Dispose();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
GlobalLog.Assert("SSPIHandlCache", "Attempted to throw: " + e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,479 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="_SSPIWrapper.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
// From Schannel.h
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct NegotiationInfo
|
||||
{
|
||||
// see SecPkgContext_NegotiationInfoW in <sspi.h>
|
||||
|
||||
// [MarshalAs(UnmanagedType.LPStruct)] internal SecurityPackageInfo PackageInfo;
|
||||
internal IntPtr PackageInfo;
|
||||
internal uint NegotiationState;
|
||||
internal static readonly int Size = Marshal.SizeOf(typeof(NegotiationInfo));
|
||||
internal static readonly int NegotiationStateOffest = (int)Marshal.OffsetOf(typeof(NegotiationInfo), "NegotiationState");
|
||||
}
|
||||
|
||||
// we keep it simple since we use this only to know if NTLM or
|
||||
// Kerberos are used in the context of a Negotiate handshake
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct SecurityPackageInfo
|
||||
{
|
||||
// see SecPkgInfoW in <sspi.h>
|
||||
internal int Capabilities;
|
||||
internal short Version;
|
||||
internal short RPCID;
|
||||
internal int MaxToken;
|
||||
internal IntPtr Name;
|
||||
internal IntPtr Comment;
|
||||
|
||||
internal static readonly int Size = Marshal.SizeOf(typeof(SecurityPackageInfo));
|
||||
internal static readonly int NameOffest = (int)Marshal.OffsetOf(typeof(SecurityPackageInfo), "Name");
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct Bindings
|
||||
{
|
||||
// see SecPkgContext_Bindings in <sspi.h>
|
||||
internal int BindingsLength;
|
||||
internal IntPtr pBindings;
|
||||
}
|
||||
|
||||
internal static class SSPIWrapper
|
||||
{
|
||||
internal static SecurityPackageInfoClass[] EnumerateSecurityPackages(ISSPIInterface secModule)
|
||||
{
|
||||
GlobalLog.Enter("EnumerateSecurityPackages");
|
||||
if (secModule.SecurityPackages == null)
|
||||
{
|
||||
lock (secModule)
|
||||
{
|
||||
if (secModule.SecurityPackages == null)
|
||||
{
|
||||
int moduleCount = 0;
|
||||
SafeFreeContextBuffer arrayBaseHandle = null;
|
||||
try
|
||||
{
|
||||
int errorCode = secModule.EnumerateSecurityPackages(out moduleCount, out arrayBaseHandle);
|
||||
GlobalLog.Print("SSPIWrapper::arrayBase: " + (arrayBaseHandle.DangerousGetHandle().ToString("x")));
|
||||
if (errorCode != 0)
|
||||
{
|
||||
throw new Win32Exception(errorCode);
|
||||
}
|
||||
SecurityPackageInfoClass[] securityPackages = new SecurityPackageInfoClass[moduleCount];
|
||||
if (Logging.On)
|
||||
{
|
||||
Logging.PrintInfo(Logging.Web, SR.GetString(SR.net_log_sspi_enumerating_security_packages));
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < moduleCount; i++)
|
||||
{
|
||||
securityPackages[i] = new SecurityPackageInfoClass(arrayBaseHandle, i);
|
||||
if (Logging.On)
|
||||
{
|
||||
Logging.PrintInfo(Logging.Web, " " + securityPackages[i].Name);
|
||||
}
|
||||
}
|
||||
secModule.SecurityPackages = securityPackages;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (arrayBaseHandle != null)
|
||||
{
|
||||
arrayBaseHandle.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
GlobalLog.Leave("EnumerateSecurityPackages");
|
||||
return secModule.SecurityPackages;
|
||||
}
|
||||
|
||||
internal static SecurityPackageInfoClass GetVerifyPackageInfo(ISSPIInterface secModule, string packageName, bool throwIfMissing)
|
||||
{
|
||||
SecurityPackageInfoClass[] supportedSecurityPackages = EnumerateSecurityPackages(secModule);
|
||||
if (supportedSecurityPackages != null)
|
||||
{
|
||||
for (int i = 0; i < supportedSecurityPackages.Length; i++)
|
||||
{
|
||||
if (string.Compare(supportedSecurityPackages[i].Name, packageName, StringComparison.OrdinalIgnoreCase) == 0)
|
||||
{
|
||||
return supportedSecurityPackages[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Logging.On)
|
||||
{
|
||||
Logging.PrintInfo(Logging.Web, SR.GetString(SR.net_log_sspi_security_package_not_found, packageName));
|
||||
}
|
||||
|
||||
// error
|
||||
if (throwIfMissing)
|
||||
{
|
||||
throw new NotSupportedException(SR.GetString(SR.net_securitypackagesupport));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static SafeFreeCredentials AcquireDefaultCredential(ISSPIInterface secModule, string package, CredentialUse intent)
|
||||
{
|
||||
GlobalLog.Print("SSPIWrapper::AcquireDefaultCredential(): using " + package);
|
||||
if (Logging.On)
|
||||
{
|
||||
Logging.PrintInfo(Logging.Web,
|
||||
"AcquireDefaultCredential(" +
|
||||
"package = " + package + ", " +
|
||||
"intent = " + intent + ")");
|
||||
}
|
||||
|
||||
SafeFreeCredentials outCredential = null;
|
||||
int errorCode = secModule.AcquireDefaultCredential(package, intent, out outCredential);
|
||||
|
||||
if (errorCode != 0)
|
||||
{
|
||||
#if TRAVE
|
||||
GlobalLog.Print("SSPIWrapper::AcquireDefaultCredential(): error " + SecureChannel.MapSecurityStatus((uint)errorCode));
|
||||
#endif
|
||||
if (Logging.On)
|
||||
{
|
||||
Logging.PrintError(Logging.Web, SR.GetString(SR.net_log_operation_failed_with_error, "AcquireDefaultCredential()", String.Format(CultureInfo.CurrentCulture, "0X{0:X}", errorCode)));
|
||||
}
|
||||
throw new Win32Exception(errorCode);
|
||||
}
|
||||
return outCredential;
|
||||
}
|
||||
|
||||
public static SafeFreeCredentials AcquireCredentialsHandle(ISSPIInterface secModule, string package, CredentialUse intent, ref AuthIdentity authdata)
|
||||
{
|
||||
GlobalLog.Print("SSPIWrapper::AcquireCredentialsHandle#2(): using " + package);
|
||||
|
||||
if (Logging.On)
|
||||
{
|
||||
Logging.PrintInfo(Logging.Web,
|
||||
"AcquireCredentialsHandle(" +
|
||||
"package = " + package + ", " +
|
||||
"intent = " + intent + ", " +
|
||||
"authdata = " + authdata + ")");
|
||||
}
|
||||
|
||||
SafeFreeCredentials credentialsHandle = null;
|
||||
int errorCode = secModule.AcquireCredentialsHandle(package,
|
||||
intent,
|
||||
ref authdata,
|
||||
out credentialsHandle);
|
||||
|
||||
if (errorCode != 0)
|
||||
{
|
||||
if (Logging.On)
|
||||
{
|
||||
Logging.PrintError(Logging.Web, SR.GetString(SR.net_log_operation_failed_with_error, "AcquireCredentialsHandle()", String.Format(CultureInfo.CurrentCulture, "0X{0:X}", errorCode)));
|
||||
}
|
||||
throw new Win32Exception(errorCode);
|
||||
}
|
||||
return credentialsHandle;
|
||||
}
|
||||
|
||||
public static SafeFreeCredentials AcquireCredentialsHandle(ISSPIInterface secModule, string package, CredentialUse intent, ref SafeSspiAuthDataHandle authdata)
|
||||
{
|
||||
if (Logging.On)
|
||||
{
|
||||
Logging.PrintInfo(Logging.Web,
|
||||
"AcquireCredentialsHandle(" +
|
||||
"package = " + package + ", " +
|
||||
"intent = " + intent + ", " +
|
||||
"authdata = " + authdata + ")");
|
||||
}
|
||||
|
||||
SafeFreeCredentials credentialsHandle = null;
|
||||
int errorCode = secModule.AcquireCredentialsHandle(package, intent, ref authdata, out credentialsHandle);
|
||||
|
||||
if (errorCode != 0)
|
||||
{
|
||||
if (Logging.On)
|
||||
{
|
||||
Logging.PrintError(Logging.Web, SR.GetString(SR.net_log_operation_failed_with_error, "AcquireCredentialsHandle()", String.Format(CultureInfo.CurrentCulture, "0X{0:X}", errorCode)));
|
||||
}
|
||||
throw new Win32Exception(errorCode);
|
||||
}
|
||||
return credentialsHandle;
|
||||
}
|
||||
|
||||
internal static int InitializeSecurityContext(ISSPIInterface secModule, SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, ContextFlags inFlags, Endianness datarep, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, ref ContextFlags outFlags)
|
||||
{
|
||||
if (Logging.On)
|
||||
{
|
||||
Logging.PrintInfo(Logging.Web,
|
||||
"InitializeSecurityContext(" +
|
||||
"credential = " + credential.ToString() + ", " +
|
||||
"context = " + ValidationHelper.ToString(context) + ", " +
|
||||
"targetName = " + targetName + ", " +
|
||||
"inFlags = " + inFlags + ")");
|
||||
}
|
||||
|
||||
int errorCode = secModule.InitializeSecurityContext(credential, ref context, targetName, inFlags, datarep, inputBuffers, outputBuffer, ref outFlags);
|
||||
|
||||
if (Logging.On)
|
||||
{
|
||||
Logging.PrintInfo(Logging.Web, SR.GetString(SR.net_log_sspi_security_context_input_buffers, "InitializeSecurityContext", (inputBuffers == null ? 0 : inputBuffers.Length), outputBuffer.size, (SecurityStatus)errorCode));
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
internal static int AcceptSecurityContext(ISSPIInterface secModule, SafeFreeCredentials credential, ref SafeDeleteContext context, ContextFlags inFlags, Endianness datarep, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, ref ContextFlags outFlags)
|
||||
{
|
||||
if (Logging.On)
|
||||
{
|
||||
Logging.PrintInfo(Logging.Web,
|
||||
"AcceptSecurityContext(" +
|
||||
"credential = " + credential.ToString() + ", " +
|
||||
"context = " + ValidationHelper.ToString(context) + ", " +
|
||||
"inFlags = " + inFlags + ")");
|
||||
}
|
||||
|
||||
int errorCode = secModule.AcceptSecurityContext(credential, ref context, inputBuffers, inFlags, datarep, outputBuffer, ref outFlags);
|
||||
|
||||
if (Logging.On)
|
||||
{
|
||||
Logging.PrintInfo(Logging.Web, SR.GetString(SR.net_log_sspi_security_context_input_buffers, "AcceptSecurityContext", (inputBuffers == null ? 0 : inputBuffers.Length), outputBuffer.size, (SecurityStatus)errorCode));
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
internal static int CompleteAuthToken(ISSPIInterface secModule, ref SafeDeleteContext context, SecurityBuffer[] inputBuffers)
|
||||
{
|
||||
int errorCode = secModule.CompleteAuthToken(ref context, inputBuffers);
|
||||
|
||||
if (Logging.On)
|
||||
{
|
||||
Logging.PrintInfo(Logging.Web, SR.GetString(SR.net_log_operation_returned_something, "CompleteAuthToken()", (SecurityStatus)errorCode));
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
public static int QuerySecurityContextToken(ISSPIInterface secModule, SafeDeleteContext context, out SafeCloseHandle token)
|
||||
{
|
||||
return secModule.QuerySecurityContextToken(context, out token);
|
||||
}
|
||||
|
||||
public static SafeFreeContextBufferChannelBinding QueryContextChannelBinding(ISSPIInterface secModule, SafeDeleteContext securityContext, ContextAttribute contextAttribute)
|
||||
{
|
||||
GlobalLog.Enter("QueryContextChannelBinding", contextAttribute.ToString());
|
||||
|
||||
SafeFreeContextBufferChannelBinding result;
|
||||
int errorCode = secModule.QueryContextChannelBinding(securityContext, contextAttribute, out result);
|
||||
if (errorCode != 0)
|
||||
{
|
||||
GlobalLog.Leave("QueryContextChannelBinding", "ERROR = " + ErrorDescription(errorCode));
|
||||
return null;
|
||||
}
|
||||
|
||||
GlobalLog.Leave("QueryContextChannelBinding", ValidationHelper.HashString(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
public static object QueryContextAttributes(ISSPIInterface secModule, SafeDeleteContext securityContext, ContextAttribute contextAttribute)
|
||||
{
|
||||
int errorCode;
|
||||
return QueryContextAttributes(secModule, securityContext, contextAttribute, out errorCode);
|
||||
}
|
||||
|
||||
public static object QueryContextAttributes(ISSPIInterface secModule, SafeDeleteContext securityContext, ContextAttribute contextAttribute, out int errorCode)
|
||||
{
|
||||
GlobalLog.Enter("QueryContextAttributes", contextAttribute.ToString());
|
||||
|
||||
int nativeBlockSize = IntPtr.Size;
|
||||
Type handleType = null;
|
||||
|
||||
switch (contextAttribute)
|
||||
{
|
||||
case ContextAttribute.Sizes:
|
||||
nativeBlockSize = SecSizes.SizeOf;
|
||||
break;
|
||||
case ContextAttribute.StreamSizes:
|
||||
nativeBlockSize = StreamSizes.SizeOf;
|
||||
break;
|
||||
|
||||
case ContextAttribute.Names:
|
||||
handleType = typeof(SafeFreeContextBuffer);
|
||||
break;
|
||||
|
||||
case ContextAttribute.PackageInfo:
|
||||
handleType = typeof(SafeFreeContextBuffer);
|
||||
break;
|
||||
|
||||
case ContextAttribute.NegotiationInfo:
|
||||
handleType = typeof(SafeFreeContextBuffer);
|
||||
nativeBlockSize = Marshal.SizeOf(typeof(NegotiationInfo));
|
||||
break;
|
||||
|
||||
case ContextAttribute.ClientSpecifiedSpn:
|
||||
handleType = typeof(SafeFreeContextBuffer);
|
||||
break;
|
||||
|
||||
case ContextAttribute.RemoteCertificate:
|
||||
handleType = typeof(SafeFreeCertContext);
|
||||
break;
|
||||
|
||||
case ContextAttribute.LocalCertificate:
|
||||
handleType = typeof(SafeFreeCertContext);
|
||||
break;
|
||||
|
||||
case ContextAttribute.IssuerListInfoEx:
|
||||
nativeBlockSize = Marshal.SizeOf(typeof(IssuerListInfoEx));
|
||||
handleType = typeof(SafeFreeContextBuffer);
|
||||
break;
|
||||
|
||||
case ContextAttribute.ConnectionInfo:
|
||||
nativeBlockSize = Marshal.SizeOf(typeof(SslConnectionInfo));
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentException(SR.GetString(SR.net_invalid_enum, "ContextAttribute"), "contextAttribute");
|
||||
}
|
||||
|
||||
SafeHandle SspiHandle = null;
|
||||
object attribute = null;
|
||||
|
||||
try
|
||||
{
|
||||
byte[] nativeBuffer = new byte[nativeBlockSize];
|
||||
errorCode = secModule.QueryContextAttributes(securityContext, contextAttribute, nativeBuffer, handleType, out SspiHandle);
|
||||
if (errorCode != 0)
|
||||
{
|
||||
GlobalLog.Leave("Win32:QueryContextAttributes", "ERROR = " + ErrorDescription(errorCode));
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (contextAttribute)
|
||||
{
|
||||
case ContextAttribute.Sizes:
|
||||
attribute = new SecSizes(nativeBuffer);
|
||||
break;
|
||||
|
||||
case ContextAttribute.StreamSizes:
|
||||
attribute = new StreamSizes(nativeBuffer);
|
||||
break;
|
||||
|
||||
case ContextAttribute.Names:
|
||||
attribute = Marshal.PtrToStringUni(SspiHandle.DangerousGetHandle());
|
||||
break;
|
||||
|
||||
case ContextAttribute.PackageInfo:
|
||||
attribute = new SecurityPackageInfoClass(SspiHandle, 0);
|
||||
break;
|
||||
|
||||
case ContextAttribute.NegotiationInfo:
|
||||
unsafe
|
||||
{
|
||||
fixed (void* ptr = nativeBuffer)
|
||||
{
|
||||
attribute = new NegotiationInfoClass(SspiHandle, Marshal.ReadInt32(new IntPtr(ptr), NegotiationInfo.NegotiationStateOffest));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ContextAttribute.ClientSpecifiedSpn:
|
||||
attribute = Marshal.PtrToStringUni(SspiHandle.DangerousGetHandle());
|
||||
break;
|
||||
|
||||
case ContextAttribute.LocalCertificate:
|
||||
goto case ContextAttribute.RemoteCertificate;
|
||||
case ContextAttribute.RemoteCertificate:
|
||||
attribute = SspiHandle;
|
||||
SspiHandle = null;
|
||||
break;
|
||||
|
||||
case ContextAttribute.IssuerListInfoEx:
|
||||
attribute = new IssuerListInfoEx(SspiHandle, nativeBuffer);
|
||||
SspiHandle = null;
|
||||
break;
|
||||
|
||||
case ContextAttribute.ConnectionInfo:
|
||||
attribute = new SslConnectionInfo(nativeBuffer);
|
||||
break;
|
||||
default:
|
||||
// will return null
|
||||
break;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (SspiHandle != null)
|
||||
{
|
||||
SspiHandle.Dispose();
|
||||
}
|
||||
}
|
||||
GlobalLog.Leave("QueryContextAttributes", ValidationHelper.ToString(attribute));
|
||||
return attribute;
|
||||
}
|
||||
|
||||
public static string ErrorDescription(int errorCode)
|
||||
{
|
||||
if (errorCode == -1)
|
||||
{
|
||||
return "An exception when invoking Win32 API";
|
||||
}
|
||||
switch ((SecurityStatus)errorCode)
|
||||
{
|
||||
case SecurityStatus.InvalidHandle:
|
||||
return "Invalid handle";
|
||||
case SecurityStatus.InvalidToken:
|
||||
return "Invalid token";
|
||||
case SecurityStatus.ContinueNeeded:
|
||||
return "Continue needed";
|
||||
case SecurityStatus.IncompleteMessage:
|
||||
return "Message incomplete";
|
||||
case SecurityStatus.WrongPrincipal:
|
||||
return "Wrong principal";
|
||||
case SecurityStatus.TargetUnknown:
|
||||
return "Target unknown";
|
||||
case SecurityStatus.PackageNotFound:
|
||||
return "Package not found";
|
||||
case SecurityStatus.BufferNotEnough:
|
||||
return "Buffer not enough";
|
||||
case SecurityStatus.MessageAltered:
|
||||
return "Message altered";
|
||||
case SecurityStatus.UntrustedRoot:
|
||||
return "Untrusted root";
|
||||
default:
|
||||
return "0x" + errorCode.ToString("x", NumberFormatInfo.InvariantInfo);
|
||||
}
|
||||
}
|
||||
} // class SSPIWrapper
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="SafeCloseHandle.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Security;
|
||||
using System.Threading;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
internal sealed class SafeCloseHandle : CriticalHandleZeroOrMinusOneIsInvalid
|
||||
{
|
||||
private int _disposed;
|
||||
|
||||
private SafeCloseHandle()
|
||||
: base()
|
||||
{
|
||||
}
|
||||
|
||||
internal IntPtr DangerousGetHandle()
|
||||
{
|
||||
return handle;
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
if (!IsInvalid)
|
||||
{
|
||||
if (Interlocked.Increment(ref _disposed) == 1)
|
||||
{
|
||||
return UnsafeNclNativeMethods.SafeNetHandles.CloseHandle(handle);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// This method will bypass refCount check done by VM
|
||||
// Means it will force handle release if has a valid value
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
internal void Abort()
|
||||
{
|
||||
ReleaseHandle();
|
||||
SetHandleAsInvalid();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="SafeCredentialReference.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
internal sealed class SafeCredentialReference : CriticalHandleMinusOneIsInvalid
|
||||
{
|
||||
// Static cache will return the target handle if found the reference in the table.
|
||||
internal SafeFreeCredentials _Target;
|
||||
|
||||
private SafeCredentialReference(SafeFreeCredentials target)
|
||||
: base()
|
||||
{
|
||||
// Bumps up the refcount on Target to signify that target handle is statically cached so
|
||||
// its dispose should be postponed
|
||||
bool b = false;
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try
|
||||
{
|
||||
target.DangerousAddRef(ref b);
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
target.DangerousRelease();
|
||||
b = false;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
_Target = target;
|
||||
SetHandle(new IntPtr(0)); // make this handle valid
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static SafeCredentialReference CreateReference(SafeFreeCredentials target)
|
||||
{
|
||||
SafeCredentialReference result = new SafeCredentialReference(target);
|
||||
if (result.IsInvalid)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
SafeFreeCredentials target = _Target;
|
||||
if (target != null)
|
||||
{
|
||||
target.DangerousRelease();
|
||||
}
|
||||
_Target = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,724 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="SafeDeleteContext.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
internal sealed class SafeDeleteContext : SafeHandle
|
||||
{
|
||||
private const string DummyStr = " ";
|
||||
private static readonly byte[] DummyBytes = new byte[] { 0 };
|
||||
|
||||
// ATN: _handle is internal since it is used on PInvokes by other wrapper methods.
|
||||
// However all such wrappers MUST manually and reliably adjust refCounter of SafeDeleteContext handle.
|
||||
|
||||
internal SSPIHandle _handle;
|
||||
|
||||
private SafeFreeCredentials _effectiveCredential;
|
||||
|
||||
private SafeDeleteContext()
|
||||
: base(IntPtr.Zero, true)
|
||||
{
|
||||
_handle = new SSPIHandle();
|
||||
}
|
||||
|
||||
public override bool IsInvalid
|
||||
{
|
||||
get
|
||||
{
|
||||
return IsClosed || _handle.IsZero;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return _handle.ToString();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
internal static unsafe int InitializeSecurityContext(ref SafeFreeCredentials inCredentials, ref SafeDeleteContext refContext,
|
||||
string targetName, ContextFlags inFlags, Endianness endianness, SecurityBuffer inSecBuffer, SecurityBuffer[] inSecBuffers,
|
||||
SecurityBuffer outSecBuffer, ref ContextFlags outFlags)
|
||||
{
|
||||
GlobalLog.Assert(outSecBuffer != null, "SafeDeleteContext::InitializeSecurityContext()|outSecBuffer != null");
|
||||
GlobalLog.Assert(inSecBuffer == null || inSecBuffers == null, "SafeDeleteContext::InitializeSecurityContext()|inSecBuffer == null || inSecBuffers == null");
|
||||
|
||||
if (inCredentials == null)
|
||||
{
|
||||
throw new ArgumentNullException("inCredentials");
|
||||
}
|
||||
|
||||
SecurityBufferDescriptor inSecurityBufferDescriptor = null;
|
||||
if (inSecBuffer != null)
|
||||
{
|
||||
inSecurityBufferDescriptor = new SecurityBufferDescriptor(1);
|
||||
}
|
||||
else if (inSecBuffers != null)
|
||||
{
|
||||
inSecurityBufferDescriptor = new SecurityBufferDescriptor(inSecBuffers.Length);
|
||||
}
|
||||
SecurityBufferDescriptor outSecurityBufferDescriptor = new SecurityBufferDescriptor(1);
|
||||
|
||||
// actually this is returned in outFlags
|
||||
bool isSspiAllocated = (inFlags & ContextFlags.AllocateMemory) != 0 ? true : false;
|
||||
|
||||
int errorCode = -1;
|
||||
|
||||
SSPIHandle contextHandle = new SSPIHandle();
|
||||
if (refContext != null)
|
||||
{
|
||||
contextHandle = refContext._handle;
|
||||
}
|
||||
|
||||
// these are pinned user byte arrays passed along with SecurityBuffers
|
||||
GCHandle[] pinnedInBytes = null;
|
||||
GCHandle pinnedOutBytes = new GCHandle();
|
||||
// optional output buffer that may need to be freed
|
||||
SafeFreeContextBuffer outFreeContextBuffer = null;
|
||||
try
|
||||
{
|
||||
pinnedOutBytes = GCHandle.Alloc(outSecBuffer.token, GCHandleType.Pinned);
|
||||
SecurityBufferStruct[] inUnmanagedBuffer = new SecurityBufferStruct[inSecurityBufferDescriptor == null ? 1 : inSecurityBufferDescriptor.Count];
|
||||
fixed (void* inUnmanagedBufferPtr = inUnmanagedBuffer)
|
||||
{
|
||||
if (inSecurityBufferDescriptor != null)
|
||||
{
|
||||
// Fix Descriptor pointer that points to unmanaged SecurityBuffers
|
||||
inSecurityBufferDescriptor.UnmanagedPointer = inUnmanagedBufferPtr;
|
||||
pinnedInBytes = new GCHandle[inSecurityBufferDescriptor.Count];
|
||||
SecurityBuffer securityBuffer;
|
||||
for (int index = 0; index < inSecurityBufferDescriptor.Count; ++index)
|
||||
{
|
||||
securityBuffer = inSecBuffer != null ? inSecBuffer : inSecBuffers[index];
|
||||
if (securityBuffer != null)
|
||||
{
|
||||
// Copy the SecurityBuffer content into unmanaged place holder
|
||||
inUnmanagedBuffer[index].count = securityBuffer.size;
|
||||
inUnmanagedBuffer[index].type = securityBuffer.type;
|
||||
|
||||
// use the unmanaged token if it's not null; otherwise use the managed buffer
|
||||
if (securityBuffer.unmanagedToken != null)
|
||||
{
|
||||
inUnmanagedBuffer[index].token = securityBuffer.unmanagedToken.DangerousGetHandle();
|
||||
}
|
||||
else if (securityBuffer.token == null || securityBuffer.token.Length == 0)
|
||||
{
|
||||
inUnmanagedBuffer[index].token = IntPtr.Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pinnedInBytes[index] = GCHandle.Alloc(securityBuffer.token, GCHandleType.Pinned);
|
||||
inUnmanagedBuffer[index].token = Marshal.UnsafeAddrOfPinnedArrayElement(securityBuffer.token, securityBuffer.offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SecurityBufferStruct[] outUnmanagedBuffer = new SecurityBufferStruct[1];
|
||||
fixed (void* outUnmanagedBufferPtr = outUnmanagedBuffer)
|
||||
{
|
||||
// Fix Descriptor pointer that points to unmanaged SecurityBuffers
|
||||
outSecurityBufferDescriptor.UnmanagedPointer = outUnmanagedBufferPtr;
|
||||
outUnmanagedBuffer[0].count = outSecBuffer.size;
|
||||
outUnmanagedBuffer[0].type = outSecBuffer.type;
|
||||
if (outSecBuffer.token == null || outSecBuffer.token.Length == 0)
|
||||
{
|
||||
outUnmanagedBuffer[0].token = IntPtr.Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
outUnmanagedBuffer[0].token = Marshal.UnsafeAddrOfPinnedArrayElement(outSecBuffer.token, outSecBuffer.offset);
|
||||
}
|
||||
if (isSspiAllocated)
|
||||
{
|
||||
outFreeContextBuffer = SafeFreeContextBuffer.CreateEmptyHandle();
|
||||
}
|
||||
|
||||
if (refContext == null || refContext.IsInvalid)
|
||||
{
|
||||
refContext = new SafeDeleteContext();
|
||||
}
|
||||
|
||||
if (targetName == null || targetName.Length == 0)
|
||||
{
|
||||
targetName = DummyStr;
|
||||
}
|
||||
|
||||
fixed (char* namePtr = targetName)
|
||||
{
|
||||
errorCode = MustRunInitializeSecurityContext(
|
||||
ref inCredentials,
|
||||
contextHandle.IsZero ? null : &contextHandle,
|
||||
(byte*)(((object)targetName == (object)DummyStr) ? null : namePtr),
|
||||
inFlags,
|
||||
endianness,
|
||||
inSecurityBufferDescriptor,
|
||||
refContext,
|
||||
outSecurityBufferDescriptor,
|
||||
ref outFlags,
|
||||
outFreeContextBuffer);
|
||||
}
|
||||
|
||||
GlobalLog.Print("SafeDeleteContext:InitializeSecurityContext Marshalling OUT buffer");
|
||||
// Get unmanaged buffer with index 0 as the only one passed into PInvoke
|
||||
outSecBuffer.size = outUnmanagedBuffer[0].count;
|
||||
outSecBuffer.type = outUnmanagedBuffer[0].type;
|
||||
if (outSecBuffer.size > 0)
|
||||
{
|
||||
outSecBuffer.token = new byte[outSecBuffer.size];
|
||||
Marshal.Copy(outUnmanagedBuffer[0].token, outSecBuffer.token, 0, outSecBuffer.size);
|
||||
}
|
||||
else
|
||||
{
|
||||
outSecBuffer.token = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (pinnedInBytes != null)
|
||||
{
|
||||
for (int index = 0; index < pinnedInBytes.Length; index++)
|
||||
{
|
||||
if (pinnedInBytes[index].IsAllocated)
|
||||
{
|
||||
pinnedInBytes[index].Free();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pinnedOutBytes.IsAllocated)
|
||||
{
|
||||
pinnedOutBytes.Free();
|
||||
}
|
||||
|
||||
if (outFreeContextBuffer != null)
|
||||
{
|
||||
outFreeContextBuffer.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
GlobalLog.Leave("SafeDeleteContext::InitializeSecurityContext() unmanaged InitializeSecurityContext()", "errorCode:0x" + errorCode.ToString("x8") + " refContext:" + ValidationHelper.ToString(refContext));
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
// After PINvoke call the method will fix the handleTemplate.handle with the returned value.
|
||||
// The caller is responsible for creating a correct SafeFreeContextBuffer_XXX flavour or null can be passed if no handle is returned.
|
||||
//
|
||||
// Since it has a CER, this method can't have any references to imports from DLLs that may not exist on the system.
|
||||
|
||||
private static unsafe int MustRunInitializeSecurityContext(
|
||||
ref SafeFreeCredentials inCredentials,
|
||||
void* inContextPtr,
|
||||
byte* targetName,
|
||||
ContextFlags inFlags,
|
||||
Endianness endianness,
|
||||
SecurityBufferDescriptor inputBuffer,
|
||||
SafeDeleteContext outContext,
|
||||
SecurityBufferDescriptor outputBuffer,
|
||||
ref ContextFlags attributes,
|
||||
SafeFreeContextBuffer handleTemplate)
|
||||
{
|
||||
int errorCode = (int)SecurityStatus.InvalidHandle;
|
||||
bool b1 = false;
|
||||
bool b2 = false;
|
||||
|
||||
// Run the body of this method as a non-interruptible block.
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try
|
||||
{
|
||||
inCredentials.DangerousAddRef(ref b1);
|
||||
outContext.DangerousAddRef(ref b2);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (b1)
|
||||
{
|
||||
inCredentials.DangerousRelease();
|
||||
b1 = false;
|
||||
}
|
||||
if (b2)
|
||||
{
|
||||
outContext.DangerousRelease();
|
||||
b2 = false;
|
||||
}
|
||||
|
||||
if (!(e is ObjectDisposedException))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
SSPIHandle credentialHandle = inCredentials._handle;
|
||||
long timeStamp;
|
||||
|
||||
if (!b1)
|
||||
{
|
||||
// caller should retry
|
||||
inCredentials = null;
|
||||
}
|
||||
else if (b1 && b2)
|
||||
{
|
||||
errorCode = UnsafeNclNativeMethods.SafeNetHandles.InitializeSecurityContextW(
|
||||
ref credentialHandle,
|
||||
inContextPtr,
|
||||
targetName,
|
||||
inFlags,
|
||||
0,
|
||||
endianness,
|
||||
inputBuffer,
|
||||
0,
|
||||
ref outContext._handle,
|
||||
outputBuffer,
|
||||
ref attributes,
|
||||
out timeStamp);
|
||||
|
||||
// When a credential handle is first associated with the context we keep credential
|
||||
// ref count bumped up to ensure ordered finalization.
|
||||
// If the credential handle has been changed we de-ref the old one and associate the
|
||||
// context with the new cred handle but only if the call was successful.
|
||||
if (outContext._effectiveCredential != inCredentials && (errorCode & 0x80000000) == 0)
|
||||
{
|
||||
// Disassociate the previous credential handle
|
||||
if (outContext._effectiveCredential != null)
|
||||
{
|
||||
outContext._effectiveCredential.DangerousRelease();
|
||||
}
|
||||
outContext._effectiveCredential = inCredentials;
|
||||
}
|
||||
else
|
||||
{
|
||||
inCredentials.DangerousRelease();
|
||||
}
|
||||
|
||||
outContext.DangerousRelease();
|
||||
|
||||
// The idea is that SSPI has allocated a block and filled up outUnmanagedBuffer+8 slot with the pointer.
|
||||
if (handleTemplate != null)
|
||||
{
|
||||
handleTemplate.Set(((SecurityBufferStruct*)outputBuffer.UnmanagedPointer)->token); // ATTN: on 64 BIT that is still +8 cause of 2* c++ unsigned long == 8 bytes
|
||||
if (handleTemplate.IsInvalid)
|
||||
{
|
||||
handleTemplate.SetHandleAsInvalid();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (inContextPtr == null && (errorCode & 0x80000000) != 0)
|
||||
{
|
||||
// an error on the first call, need to set the out handle to invalid value
|
||||
outContext._handle.SetToInvalid();
|
||||
}
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
internal static unsafe int AcceptSecurityContext(ref SafeFreeCredentials inCredentials, ref SafeDeleteContext refContext,
|
||||
ContextFlags inFlags, Endianness endianness, SecurityBuffer inSecBuffer, SecurityBuffer[] inSecBuffers, SecurityBuffer outSecBuffer,
|
||||
ref ContextFlags outFlags)
|
||||
{
|
||||
GlobalLog.Assert(outSecBuffer != null, "SafeDeleteContext::AcceptSecurityContext()|outSecBuffer != null");
|
||||
GlobalLog.Assert(inSecBuffer == null || inSecBuffers == null, "SafeDeleteContext::AcceptSecurityContext()|inSecBuffer == null || inSecBuffers == null");
|
||||
|
||||
if (inCredentials == null)
|
||||
{
|
||||
throw new ArgumentNullException("inCredentials");
|
||||
}
|
||||
|
||||
SecurityBufferDescriptor inSecurityBufferDescriptor = null;
|
||||
if (inSecBuffer != null)
|
||||
{
|
||||
inSecurityBufferDescriptor = new SecurityBufferDescriptor(1);
|
||||
}
|
||||
else if (inSecBuffers != null)
|
||||
{
|
||||
inSecurityBufferDescriptor = new SecurityBufferDescriptor(inSecBuffers.Length);
|
||||
}
|
||||
SecurityBufferDescriptor outSecurityBufferDescriptor = new SecurityBufferDescriptor(1);
|
||||
|
||||
// actually this is returned in outFlags
|
||||
bool isSspiAllocated = (inFlags & ContextFlags.AllocateMemory) != 0 ? true : false;
|
||||
|
||||
int errorCode = -1;
|
||||
|
||||
SSPIHandle contextHandle = new SSPIHandle();
|
||||
if (refContext != null)
|
||||
{
|
||||
contextHandle = refContext._handle;
|
||||
}
|
||||
|
||||
// these are pinned user byte arrays passed along with SecurityBuffers
|
||||
GCHandle[] pinnedInBytes = null;
|
||||
GCHandle pinnedOutBytes = new GCHandle();
|
||||
// optional output buffer that may need to be freed
|
||||
SafeFreeContextBuffer outFreeContextBuffer = null;
|
||||
try
|
||||
{
|
||||
pinnedOutBytes = GCHandle.Alloc(outSecBuffer.token, GCHandleType.Pinned);
|
||||
SecurityBufferStruct[] inUnmanagedBuffer = new SecurityBufferStruct[inSecurityBufferDescriptor == null ? 1 : inSecurityBufferDescriptor.Count];
|
||||
fixed (void* inUnmanagedBufferPtr = inUnmanagedBuffer)
|
||||
{
|
||||
if (inSecurityBufferDescriptor != null)
|
||||
{
|
||||
// Fix Descriptor pointer that points to unmanaged SecurityBuffers
|
||||
inSecurityBufferDescriptor.UnmanagedPointer = inUnmanagedBufferPtr;
|
||||
pinnedInBytes = new GCHandle[inSecurityBufferDescriptor.Count];
|
||||
SecurityBuffer securityBuffer;
|
||||
for (int index = 0; index < inSecurityBufferDescriptor.Count; ++index)
|
||||
{
|
||||
securityBuffer = inSecBuffer != null ? inSecBuffer : inSecBuffers[index];
|
||||
if (securityBuffer != null)
|
||||
{
|
||||
// Copy the SecurityBuffer content into unmanaged place holder
|
||||
inUnmanagedBuffer[index].count = securityBuffer.size;
|
||||
inUnmanagedBuffer[index].type = securityBuffer.type;
|
||||
|
||||
// use the unmanaged token if it's not null; otherwise use the managed buffer
|
||||
if (securityBuffer.unmanagedToken != null)
|
||||
{
|
||||
inUnmanagedBuffer[index].token = securityBuffer.unmanagedToken.DangerousGetHandle();
|
||||
}
|
||||
else if (securityBuffer.token == null || securityBuffer.token.Length == 0)
|
||||
{
|
||||
inUnmanagedBuffer[index].token = IntPtr.Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pinnedInBytes[index] = GCHandle.Alloc(securityBuffer.token, GCHandleType.Pinned);
|
||||
inUnmanagedBuffer[index].token = Marshal.UnsafeAddrOfPinnedArrayElement(securityBuffer.token, securityBuffer.offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SecurityBufferStruct[] outUnmanagedBuffer = new SecurityBufferStruct[1];
|
||||
fixed (void* outUnmanagedBufferPtr = outUnmanagedBuffer)
|
||||
{
|
||||
// Fix Descriptor pointer that points to unmanaged SecurityBuffers
|
||||
outSecurityBufferDescriptor.UnmanagedPointer = outUnmanagedBufferPtr;
|
||||
// Copy the SecurityBuffer content into unmanaged place holder
|
||||
outUnmanagedBuffer[0].count = outSecBuffer.size;
|
||||
outUnmanagedBuffer[0].type = outSecBuffer.type;
|
||||
|
||||
if (outSecBuffer.token == null || outSecBuffer.token.Length == 0)
|
||||
{
|
||||
outUnmanagedBuffer[0].token = IntPtr.Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
outUnmanagedBuffer[0].token = Marshal.UnsafeAddrOfPinnedArrayElement(outSecBuffer.token, outSecBuffer.offset);
|
||||
}
|
||||
if (isSspiAllocated)
|
||||
{
|
||||
outFreeContextBuffer = SafeFreeContextBuffer.CreateEmptyHandle();
|
||||
}
|
||||
|
||||
if (refContext == null || refContext.IsInvalid)
|
||||
{
|
||||
refContext = new SafeDeleteContext();
|
||||
}
|
||||
|
||||
errorCode = MustRunAcceptSecurityContext(
|
||||
ref inCredentials,
|
||||
contextHandle.IsZero ? null : &contextHandle,
|
||||
inSecurityBufferDescriptor,
|
||||
inFlags,
|
||||
endianness,
|
||||
refContext,
|
||||
outSecurityBufferDescriptor,
|
||||
ref outFlags,
|
||||
outFreeContextBuffer);
|
||||
|
||||
GlobalLog.Print("SafeDeleteContext:AcceptSecurityContext Marshalling OUT buffer");
|
||||
// Get unmanaged buffer with index 0 as the only one passed into PInvoke
|
||||
outSecBuffer.size = outUnmanagedBuffer[0].count;
|
||||
outSecBuffer.type = outUnmanagedBuffer[0].type;
|
||||
if (outSecBuffer.size > 0)
|
||||
{
|
||||
outSecBuffer.token = new byte[outSecBuffer.size];
|
||||
Marshal.Copy(outUnmanagedBuffer[0].token, outSecBuffer.token, 0, outSecBuffer.size);
|
||||
}
|
||||
else
|
||||
{
|
||||
outSecBuffer.token = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (pinnedInBytes != null)
|
||||
{
|
||||
for (int index = 0; index < pinnedInBytes.Length; index++)
|
||||
{
|
||||
if (pinnedInBytes[index].IsAllocated)
|
||||
{
|
||||
pinnedInBytes[index].Free();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pinnedOutBytes.IsAllocated)
|
||||
{
|
||||
pinnedOutBytes.Free();
|
||||
}
|
||||
|
||||
if (outFreeContextBuffer != null)
|
||||
{
|
||||
outFreeContextBuffer.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
GlobalLog.Leave("SafeDeleteContext::AcceptSecurityContex() unmanaged AcceptSecurityContex()", "errorCode:0x" + errorCode.ToString("x8") + " refContext:" + ValidationHelper.ToString(refContext));
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
// After PINvoke call the method will fix the handleTemplate.handle with the returned value.
|
||||
// The caller is responsible for creating a correct SafeFreeContextBuffer_XXX flavour or null can be passed if no handle is returned.
|
||||
//
|
||||
// Since it has a CER, this method can't have any references to imports from DLLs that may not exist on the system.
|
||||
|
||||
private static unsafe int MustRunAcceptSecurityContext(
|
||||
ref SafeFreeCredentials inCredentials,
|
||||
void* inContextPtr,
|
||||
SecurityBufferDescriptor inputBuffer,
|
||||
ContextFlags inFlags,
|
||||
Endianness endianness,
|
||||
SafeDeleteContext outContext,
|
||||
SecurityBufferDescriptor outputBuffer,
|
||||
ref ContextFlags outFlags,
|
||||
SafeFreeContextBuffer handleTemplate)
|
||||
{
|
||||
int errorCode = (int)SecurityStatus.InvalidHandle;
|
||||
bool b1 = false;
|
||||
bool b2 = false;
|
||||
|
||||
// Run the body of this method as a non-interruptible block.
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try
|
||||
{
|
||||
inCredentials.DangerousAddRef(ref b1);
|
||||
outContext.DangerousAddRef(ref b2);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (b1)
|
||||
{
|
||||
inCredentials.DangerousRelease();
|
||||
b1 = false;
|
||||
}
|
||||
if (b2)
|
||||
{
|
||||
outContext.DangerousRelease();
|
||||
b2 = false;
|
||||
}
|
||||
if (!(e is ObjectDisposedException))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
SSPIHandle credentialHandle = inCredentials._handle;
|
||||
long timeStamp;
|
||||
|
||||
if (!b1)
|
||||
{
|
||||
// caller should retry
|
||||
inCredentials = null;
|
||||
}
|
||||
else if (b1 && b2)
|
||||
{
|
||||
errorCode = UnsafeNclNativeMethods.SafeNetHandles.AcceptSecurityContext(
|
||||
ref credentialHandle,
|
||||
inContextPtr,
|
||||
inputBuffer,
|
||||
inFlags,
|
||||
endianness,
|
||||
ref outContext._handle,
|
||||
outputBuffer,
|
||||
ref outFlags,
|
||||
out timeStamp);
|
||||
|
||||
// When a credential handle is first associated with the context we keep credential
|
||||
// ref count bumped up to ensure ordered finalization.
|
||||
// If the credential handle has been changed we de-ref the old one and associate the
|
||||
// context with the new cred handle but only if the call was successful.
|
||||
if (outContext._effectiveCredential != inCredentials && (errorCode & 0x80000000) == 0)
|
||||
{
|
||||
// Disassociate the previous credential handle
|
||||
if (outContext._effectiveCredential != null)
|
||||
{
|
||||
outContext._effectiveCredential.DangerousRelease();
|
||||
}
|
||||
outContext._effectiveCredential = inCredentials;
|
||||
}
|
||||
else
|
||||
{
|
||||
inCredentials.DangerousRelease();
|
||||
}
|
||||
|
||||
outContext.DangerousRelease();
|
||||
|
||||
// The idea is that SSPI has allocated a block and filled up outUnmanagedBuffer+8 slot with the pointer.
|
||||
if (handleTemplate != null)
|
||||
{
|
||||
handleTemplate.Set(((SecurityBufferStruct*)outputBuffer.UnmanagedPointer)->token); // ATTN: on 64 BIT that is still +8 cause of 2* c++ unsigned long == 8 bytes
|
||||
if (handleTemplate.IsInvalid)
|
||||
{
|
||||
handleTemplate.SetHandleAsInvalid();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (inContextPtr == null && (errorCode & 0x80000000) != 0)
|
||||
{
|
||||
// an error on the first call, need to set the out handle to invalid value
|
||||
outContext._handle.SetToInvalid();
|
||||
}
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
internal static unsafe int CompleteAuthToken(ref SafeDeleteContext refContext, SecurityBuffer[] inSecBuffers)
|
||||
{
|
||||
GlobalLog.Enter("SafeDeleteContext::CompleteAuthToken");
|
||||
GlobalLog.Print(" refContext = " + ValidationHelper.ToString(refContext));
|
||||
GlobalLog.Assert(inSecBuffers != null, "SafeDeleteContext::CompleteAuthToken()|inSecBuffers == null");
|
||||
SecurityBufferDescriptor inSecurityBufferDescriptor = new SecurityBufferDescriptor(inSecBuffers.Length);
|
||||
|
||||
int errorCode = (int)SecurityStatus.InvalidHandle;
|
||||
|
||||
// these are pinned user byte arrays passed along with SecurityBuffers
|
||||
GCHandle[] pinnedInBytes = null;
|
||||
|
||||
SecurityBufferStruct[] inUnmanagedBuffer = new SecurityBufferStruct[inSecurityBufferDescriptor.Count];
|
||||
fixed (void* inUnmanagedBufferPtr = inUnmanagedBuffer)
|
||||
{
|
||||
// Fix Descriptor pointer that points to unmanaged SecurityBuffers
|
||||
inSecurityBufferDescriptor.UnmanagedPointer = inUnmanagedBufferPtr;
|
||||
pinnedInBytes = new GCHandle[inSecurityBufferDescriptor.Count];
|
||||
SecurityBuffer securityBuffer;
|
||||
for (int index = 0; index < inSecurityBufferDescriptor.Count; ++index)
|
||||
{
|
||||
securityBuffer = inSecBuffers[index];
|
||||
if (securityBuffer != null)
|
||||
{
|
||||
inUnmanagedBuffer[index].count = securityBuffer.size;
|
||||
inUnmanagedBuffer[index].type = securityBuffer.type;
|
||||
|
||||
// use the unmanaged token if it's not null; otherwise use the managed buffer
|
||||
if (securityBuffer.unmanagedToken != null)
|
||||
{
|
||||
inUnmanagedBuffer[index].token = securityBuffer.unmanagedToken.DangerousGetHandle();
|
||||
}
|
||||
else if (securityBuffer.token == null || securityBuffer.token.Length == 0)
|
||||
{
|
||||
inUnmanagedBuffer[index].token = IntPtr.Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
pinnedInBytes[index] = GCHandle.Alloc(securityBuffer.token, GCHandleType.Pinned);
|
||||
inUnmanagedBuffer[index].token = Marshal.UnsafeAddrOfPinnedArrayElement(securityBuffer.token, securityBuffer.offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SSPIHandle contextHandle = new SSPIHandle();
|
||||
if (refContext != null)
|
||||
{
|
||||
contextHandle = refContext._handle;
|
||||
}
|
||||
try
|
||||
{
|
||||
if (refContext == null || refContext.IsInvalid)
|
||||
{
|
||||
refContext = new SafeDeleteContext();
|
||||
}
|
||||
|
||||
bool b = false;
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try
|
||||
{
|
||||
refContext.DangerousAddRef(ref b);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
refContext.DangerousRelease();
|
||||
b = false;
|
||||
}
|
||||
if (!(e is ObjectDisposedException))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
errorCode = UnsafeNclNativeMethods.SafeNetHandles.CompleteAuthToken(contextHandle.IsZero ? null : &contextHandle, inSecurityBufferDescriptor);
|
||||
refContext.DangerousRelease();
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (pinnedInBytes != null)
|
||||
{
|
||||
for (int index = 0; index < pinnedInBytes.Length; index++)
|
||||
{
|
||||
if (pinnedInBytes[index].IsAllocated)
|
||||
{
|
||||
pinnedInBytes[index].Free();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GlobalLog.Leave("SafeDeleteContext::CompleteAuthToken() unmanaged CompleteAuthToken()", "errorCode:0x" + errorCode.ToString("x8") + " refContext:" + ValidationHelper.ToString(refContext));
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
if (this._effectiveCredential != null)
|
||||
{
|
||||
this._effectiveCredential.DangerousRelease();
|
||||
}
|
||||
|
||||
return UnsafeNclNativeMethods.SafeNetHandles.DeleteSecurityContext(ref _handle) == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="SafeFreeCertContext.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Security;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
internal sealed class SafeFreeCertContext : SafeHandleZeroOrMinusOneIsInvalid
|
||||
{
|
||||
internal SafeFreeCertContext()
|
||||
: base(true)
|
||||
{
|
||||
}
|
||||
|
||||
// This must be ONLY called from this file within a CER.
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
internal unsafe void Set(IntPtr value)
|
||||
{
|
||||
this.handle = value;
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
UnsafeNclNativeMethods.SafeNetHandles.CertFreeCertificateContext(handle);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,165 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="SafeFreeContextBuffer.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
internal sealed class SafeFreeContextBuffer : SafeHandleZeroOrMinusOneIsInvalid
|
||||
{
|
||||
private SafeFreeContextBuffer()
|
||||
: base(true)
|
||||
{
|
||||
}
|
||||
|
||||
// This must be ONLY called from this file and in the context of a CER
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
internal unsafe void Set(IntPtr value)
|
||||
{
|
||||
this.handle = value;
|
||||
}
|
||||
|
||||
internal static int EnumeratePackages(out int pkgnum, out SafeFreeContextBuffer pkgArray)
|
||||
{
|
||||
int res = -1;
|
||||
res = UnsafeNclNativeMethods.SafeNetHandles.EnumerateSecurityPackagesW(out pkgnum, out pkgArray);
|
||||
if (res != 0 && pkgArray != null)
|
||||
{
|
||||
pkgArray.SetHandleAsInvalid();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
internal static SafeFreeContextBuffer CreateEmptyHandle()
|
||||
{
|
||||
return new SafeFreeContextBuffer();
|
||||
}
|
||||
|
||||
// After PINvoke call the method will fix the refHandle.handle with the returned value.
|
||||
// The caller is responsible for creating a correct SafeHandle template or null can be passed if no handle is returned.
|
||||
//
|
||||
// This method switches between three non-interruptible helper methods. (This method can't be both non-interruptible and
|
||||
// reference imports from all three DLLs - doing so would cause all three DLLs to try to be bound to.)
|
||||
|
||||
public static unsafe int QueryContextAttributes(SafeDeleteContext phContext, ContextAttribute contextAttribute, byte* buffer, SafeHandle refHandle)
|
||||
{
|
||||
int status = (int)SecurityStatus.InvalidHandle;
|
||||
bool b = false;
|
||||
|
||||
// We don't want to be interrupted by thread abort exceptions or unexpected out-of-memory errors failing to jit
|
||||
// one of the following methods. So run within a CER non-interruptible block.
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try
|
||||
{
|
||||
phContext.DangerousAddRef(ref b);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
phContext.DangerousRelease();
|
||||
b = false;
|
||||
}
|
||||
if (!(e is ObjectDisposedException))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
status = UnsafeNclNativeMethods.SafeNetHandles.QueryContextAttributesW(ref phContext._handle, contextAttribute, buffer);
|
||||
phContext.DangerousRelease();
|
||||
}
|
||||
|
||||
if (status == 0 && refHandle != null)
|
||||
{
|
||||
if (refHandle is SafeFreeContextBuffer)
|
||||
{
|
||||
((SafeFreeContextBuffer)refHandle).Set(*(IntPtr*)buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
((SafeFreeCertContext)refHandle).Set(*(IntPtr*)buffer);
|
||||
}
|
||||
}
|
||||
|
||||
if (status != 0 && refHandle != null)
|
||||
{
|
||||
refHandle.SetHandleAsInvalid();
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
public static int SetContextAttributes(SafeDeleteContext phContext, ContextAttribute contextAttribute, byte[] buffer)
|
||||
{
|
||||
int status = (int)SecurityStatus.InvalidHandle;
|
||||
bool b = false;
|
||||
|
||||
// We don't want to be interrupted by thread abort exceptions or unexpected out-of-memory errors failing
|
||||
// to jit one of the following methods. So run within a CER non-interruptible block.
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try
|
||||
{
|
||||
phContext.DangerousAddRef(ref b);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
phContext.DangerousRelease();
|
||||
b = false;
|
||||
}
|
||||
if (!(e is ObjectDisposedException))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
status = UnsafeNclNativeMethods.SafeNetHandles.SetContextAttributesW(
|
||||
ref phContext._handle, contextAttribute, buffer, buffer.Length);
|
||||
phContext.DangerousRelease();
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
return UnsafeNclNativeMethods.SafeNetHandles.FreeContextBuffer(handle) == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,106 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="SafeFreeContextBufferChannelBinding.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Security;
|
||||
using System.Security.Authentication.ExtendedProtection;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
internal sealed class SafeFreeContextBufferChannelBinding : ChannelBinding
|
||||
{
|
||||
private int size;
|
||||
|
||||
public override int Size
|
||||
{
|
||||
get { return size; }
|
||||
}
|
||||
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
internal unsafe void Set(IntPtr value)
|
||||
{
|
||||
this.handle = value;
|
||||
}
|
||||
|
||||
internal static SafeFreeContextBufferChannelBinding CreateEmptyHandle()
|
||||
{
|
||||
return new SafeFreeContextBufferChannelBinding();
|
||||
}
|
||||
|
||||
public static unsafe int QueryContextChannelBinding(SafeDeleteContext phContext, ContextAttribute contextAttribute, Bindings* buffer,
|
||||
SafeFreeContextBufferChannelBinding refHandle)
|
||||
{
|
||||
int status = (int)SecurityStatus.InvalidHandle;
|
||||
bool b = false;
|
||||
|
||||
// We don't want to be interrupted by thread abort exceptions or unexpected out-of-memory errors failing to jit
|
||||
// one of the following methods. So run within a CER non-interruptible block.
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try
|
||||
{
|
||||
phContext.DangerousAddRef(ref b);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
phContext.DangerousRelease();
|
||||
b = false;
|
||||
}
|
||||
if (!(e is ObjectDisposedException))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
status = UnsafeNclNativeMethods.SafeNetHandles.QueryContextAttributesW(ref phContext._handle, contextAttribute, buffer);
|
||||
phContext.DangerousRelease();
|
||||
}
|
||||
|
||||
if (status == 0 && refHandle != null)
|
||||
{
|
||||
refHandle.Set((*buffer).pBindings);
|
||||
refHandle.size = (*buffer).BindingsLength;
|
||||
}
|
||||
|
||||
if (status != 0 && refHandle != null)
|
||||
{
|
||||
refHandle.SetHandleAsInvalid();
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
return UnsafeNclNativeMethods.SafeNetHandles.FreeContextBuffer(handle) == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,216 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="SafeFreeCredentials.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
internal sealed class SafeFreeCredentials : SafeHandle
|
||||
{
|
||||
internal SSPIHandle _handle; // should be always used as by ref in PINvokes parameters
|
||||
|
||||
private SafeFreeCredentials()
|
||||
: base(IntPtr.Zero, true)
|
||||
{
|
||||
_handle = new SSPIHandle();
|
||||
}
|
||||
|
||||
public override bool IsInvalid
|
||||
{
|
||||
get { return IsClosed || _handle.IsZero; }
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
return UnsafeNclNativeMethods.SafeNetHandles.FreeCredentialsHandle(ref _handle) == 0;
|
||||
}
|
||||
|
||||
public static unsafe int AcquireCredentialsHandle(string package, CredentialUse intent, ref AuthIdentity authdata,
|
||||
out SafeFreeCredentials outCredential)
|
||||
{
|
||||
GlobalLog.Print("SafeFreeCredentials::AcquireCredentialsHandle#1("
|
||||
+ package + ", "
|
||||
+ intent + ", "
|
||||
+ authdata + ")");
|
||||
|
||||
int errorCode = -1;
|
||||
long timeStamp;
|
||||
|
||||
outCredential = new SafeFreeCredentials();
|
||||
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
errorCode = UnsafeNclNativeMethods.SafeNetHandles.AcquireCredentialsHandleW(
|
||||
null,
|
||||
package,
|
||||
(int)intent,
|
||||
null,
|
||||
ref authdata,
|
||||
null,
|
||||
null,
|
||||
ref outCredential._handle,
|
||||
out timeStamp);
|
||||
}
|
||||
|
||||
if (errorCode != 0)
|
||||
{
|
||||
outCredential.SetHandleAsInvalid();
|
||||
}
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
public static unsafe int AcquireDefaultCredential(string package, CredentialUse intent, out SafeFreeCredentials outCredential)
|
||||
{
|
||||
GlobalLog.Print("SafeFreeCredentials::AcquireDefaultCredential("
|
||||
+ package + ", "
|
||||
+ intent + ")");
|
||||
|
||||
int errorCode = -1;
|
||||
long timeStamp;
|
||||
|
||||
outCredential = new SafeFreeCredentials();
|
||||
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
errorCode = UnsafeNclNativeMethods.SafeNetHandles.AcquireCredentialsHandleW(
|
||||
null,
|
||||
package,
|
||||
(int)intent,
|
||||
null,
|
||||
IntPtr.Zero,
|
||||
null,
|
||||
null,
|
||||
ref outCredential._handle,
|
||||
out timeStamp);
|
||||
}
|
||||
|
||||
if (errorCode != 0)
|
||||
{
|
||||
outCredential.SetHandleAsInvalid();
|
||||
}
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
// This overload is only called on Win7+ where SspiEncodeStringsAsAuthIdentity() was used to
|
||||
// create the authData blob.
|
||||
public static unsafe int AcquireCredentialsHandle(
|
||||
string package,
|
||||
CredentialUse intent,
|
||||
ref SafeSspiAuthDataHandle authdata,
|
||||
out SafeFreeCredentials outCredential)
|
||||
{
|
||||
int errorCode = -1;
|
||||
long timeStamp;
|
||||
|
||||
outCredential = new SafeFreeCredentials();
|
||||
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
errorCode = UnsafeNclNativeMethods.SafeNetHandles.AcquireCredentialsHandleW(
|
||||
null,
|
||||
package,
|
||||
(int)intent,
|
||||
null,
|
||||
authdata,
|
||||
null,
|
||||
null,
|
||||
ref outCredential._handle,
|
||||
out timeStamp);
|
||||
}
|
||||
|
||||
if (errorCode != 0)
|
||||
{
|
||||
outCredential.SetHandleAsInvalid();
|
||||
}
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
public static unsafe int AcquireCredentialsHandle(string package, CredentialUse intent, ref SecureCredential authdata,
|
||||
out SafeFreeCredentials outCredential)
|
||||
{
|
||||
GlobalLog.Print("SafeFreeCredentials::AcquireCredentialsHandle#2("
|
||||
+ package + ", "
|
||||
+ intent + ", "
|
||||
+ authdata + ")");
|
||||
|
||||
int errorCode = -1;
|
||||
long timeStamp;
|
||||
|
||||
// If there is a certificate, wrap it into an array.
|
||||
// Not threadsafe.
|
||||
IntPtr copiedPtr = authdata.certContextArray;
|
||||
try
|
||||
{
|
||||
IntPtr certArrayPtr = new IntPtr(&copiedPtr);
|
||||
if (copiedPtr != IntPtr.Zero)
|
||||
{
|
||||
authdata.certContextArray = certArrayPtr;
|
||||
}
|
||||
|
||||
outCredential = new SafeFreeCredentials();
|
||||
|
||||
RuntimeHelpers.PrepareConstrainedRegions();
|
||||
try
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
errorCode = UnsafeNclNativeMethods.SafeNetHandles.AcquireCredentialsHandleW(
|
||||
null,
|
||||
package,
|
||||
(int)intent,
|
||||
null,
|
||||
ref authdata,
|
||||
null,
|
||||
null,
|
||||
ref outCredential._handle,
|
||||
out timeStamp);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
authdata.certContextArray = copiedPtr;
|
||||
}
|
||||
|
||||
if (errorCode != 0)
|
||||
{
|
||||
outCredential.SetHandleAsInvalid();
|
||||
}
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="SafeLocalFree.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Security;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
internal sealed class SafeLocalFree : SafeHandleZeroOrMinusOneIsInvalid
|
||||
{
|
||||
private const int LmemFixed = 0;
|
||||
private const int NULL = 0;
|
||||
|
||||
// This returned handle cannot be modified by the application.
|
||||
public static SafeLocalFree Zero = new SafeLocalFree(false);
|
||||
|
||||
private SafeLocalFree()
|
||||
: base(true)
|
||||
{
|
||||
}
|
||||
|
||||
private SafeLocalFree(bool ownsHandle)
|
||||
: base(ownsHandle)
|
||||
{
|
||||
}
|
||||
|
||||
public static SafeLocalFree LocalAlloc(int cb)
|
||||
{
|
||||
SafeLocalFree result = UnsafeNclNativeMethods.SafeNetHandles.LocalAlloc(LmemFixed, (UIntPtr)cb);
|
||||
if (result.IsInvalid)
|
||||
{
|
||||
result.SetHandleAsInvalid();
|
||||
throw new OutOfMemoryException();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
return UnsafeNclNativeMethods.SafeNetHandles.LocalFree(handle) == IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="SafeSspiAuthDataHandle.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Security.Authentication.ExtendedProtection;
|
||||
using System.Threading;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
internal sealed class SafeSspiAuthDataHandle : SafeHandleZeroOrMinusOneIsInvalid
|
||||
{
|
||||
public SafeSspiAuthDataHandle()
|
||||
: base(true)
|
||||
{
|
||||
}
|
||||
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
return UnsafeNclNativeMethods.SspiHelper.SspiFreeAuthIdentity(handle) == SecurityStatus.OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="SchProtocols.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
// From Schannel.h
|
||||
[Flags]
|
||||
internal enum SchProtocols
|
||||
{
|
||||
Zero = 0,
|
||||
PctClient = 0x00000002,
|
||||
PctServer = 0x00000001,
|
||||
Pct = (PctClient | PctServer),
|
||||
Ssl2Client = 0x00000008,
|
||||
Ssl2Server = 0x00000004,
|
||||
Ssl2 = (Ssl2Client | Ssl2Server),
|
||||
Ssl3Client = 0x00000020,
|
||||
Ssl3Server = 0x00000010,
|
||||
Ssl3 = (Ssl3Client | Ssl3Server),
|
||||
Tls10Client = 0x00000080,
|
||||
Tls10Server = 0x00000040,
|
||||
Tls10 = (Tls10Client | Tls10Server),
|
||||
Tls11Client = 0x00000200,
|
||||
Tls11Server = 0x00000100,
|
||||
Tls11 = (Tls11Client | Tls11Server),
|
||||
Tls12Client = 0x00000800,
|
||||
Tls12Server = 0x00000400,
|
||||
Tls12 = (Tls12Client | Tls12Server),
|
||||
Ssl3Tls = (Ssl3 | Tls10),
|
||||
UniClient = unchecked((int)0x80000000),
|
||||
UniServer = 0x40000000,
|
||||
Unified = (UniClient | UniServer),
|
||||
ClientMask = (PctClient | Ssl2Client | Ssl3Client | Tls10Client | Tls11Client | Tls12Client | UniClient),
|
||||
ServerMask = (PctServer | Ssl2Server | Ssl3Server | Tls10Server | Tls11Server | Tls12Server | UniServer)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="SecSizes.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal class SecSizes
|
||||
{
|
||||
public readonly int MaxToken;
|
||||
public readonly int MaxSignature;
|
||||
public readonly int BlockSize;
|
||||
public readonly int SecurityTrailer;
|
||||
|
||||
internal unsafe SecSizes(byte[] memory)
|
||||
{
|
||||
fixed (void* voidPtr = memory)
|
||||
{
|
||||
IntPtr unmanagedAddress = new IntPtr(voidPtr);
|
||||
try
|
||||
{
|
||||
MaxToken = (int)checked((uint)Marshal.ReadInt32(unmanagedAddress));
|
||||
MaxSignature = (int)checked((uint)Marshal.ReadInt32(unmanagedAddress, 4));
|
||||
BlockSize = (int)checked((uint)Marshal.ReadInt32(unmanagedAddress, 8));
|
||||
SecurityTrailer = (int)checked((uint)Marshal.ReadInt32(unmanagedAddress, 12));
|
||||
}
|
||||
catch (OverflowException)
|
||||
{
|
||||
GlobalLog.Assert(false, "SecSizes::.ctor", "Negative size.");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
public static readonly int SizeOf = Marshal.SizeOf(typeof(SecSizes));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="SecurityBuffer.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Authentication.ExtendedProtection;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
internal class SecurityBuffer
|
||||
{
|
||||
public int size;
|
||||
public BufferType type;
|
||||
public byte[] token;
|
||||
public SafeHandle unmanagedToken;
|
||||
public int offset;
|
||||
|
||||
public SecurityBuffer(byte[] data, int offset, int size, BufferType tokentype)
|
||||
{
|
||||
GlobalLog.Assert(offset >= 0 && offset <= (data == null ? 0 : data.Length), "SecurityBuffer::.ctor", "'offset' out of range. [" + offset + "]");
|
||||
GlobalLog.Assert(size >= 0 && size <= (data == null ? 0 : data.Length - offset), "SecurityBuffer::.ctor", "'size' out of range. [" + size + "]");
|
||||
|
||||
this.offset = data == null || offset < 0 ? 0 : Math.Min(offset, data.Length);
|
||||
this.size = data == null || size < 0 ? 0 : Math.Min(size, data.Length - this.offset);
|
||||
this.type = tokentype;
|
||||
this.token = size == 0 ? null : data;
|
||||
}
|
||||
|
||||
public SecurityBuffer(byte[] data, BufferType tokentype)
|
||||
{
|
||||
this.size = data == null ? 0 : data.Length;
|
||||
this.type = tokentype;
|
||||
this.token = size == 0 ? null : data;
|
||||
}
|
||||
|
||||
public SecurityBuffer(int size, BufferType tokentype)
|
||||
{
|
||||
GlobalLog.Assert(size >= 0, "SecurityBuffer::.ctor", "'size' out of range. [" + size.ToString(NumberFormatInfo.InvariantInfo) + "]");
|
||||
|
||||
this.size = size;
|
||||
this.type = tokentype;
|
||||
this.token = size == 0 ? null : new byte[size];
|
||||
}
|
||||
|
||||
public SecurityBuffer(ChannelBinding binding)
|
||||
{
|
||||
this.size = (binding == null ? 0 : binding.Size);
|
||||
this.type = BufferType.ChannelBindings;
|
||||
this.unmanagedToken = binding;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="SecurityBufferDescriptor.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal unsafe class SecurityBufferDescriptor
|
||||
{
|
||||
/*
|
||||
typedef struct _SecBufferDesc {
|
||||
ULONG ulVersion;
|
||||
ULONG cBuffers;
|
||||
PSecBuffer pBuffers;
|
||||
} SecBufferDesc, * PSecBufferDesc;
|
||||
*/
|
||||
public readonly int Version;
|
||||
public readonly int Count;
|
||||
public void* UnmanagedPointer;
|
||||
|
||||
public SecurityBufferDescriptor(int count)
|
||||
{
|
||||
Version = 0;
|
||||
Count = count;
|
||||
UnmanagedPointer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="SecurityPackageInfoClass.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
internal class SecurityPackageInfoClass
|
||||
{
|
||||
private int _capabilities = 0;
|
||||
private short _version = 0;
|
||||
private short _rpcid = 0;
|
||||
private int _maxToken = 0;
|
||||
private string _name = null;
|
||||
private string _comment = null;
|
||||
|
||||
/*
|
||||
* This is to support SSL under semi trusted environment.
|
||||
* Note that it is only for SSL with no client cert
|
||||
*/
|
||||
internal SecurityPackageInfoClass(SafeHandle safeHandle, int index)
|
||||
{
|
||||
if (safeHandle.IsInvalid)
|
||||
{
|
||||
GlobalLog.Print("SecurityPackageInfoClass::.ctor() the pointer is invalid: " + (safeHandle.DangerousGetHandle()).ToString("x"));
|
||||
return;
|
||||
}
|
||||
IntPtr unmanagedAddress = IntPtrHelper.Add(safeHandle.DangerousGetHandle(), SecurityPackageInfo.Size * index);
|
||||
GlobalLog.Print("SecurityPackageInfoClass::.ctor() unmanagedPointer: " + ((long)unmanagedAddress).ToString("x"));
|
||||
|
||||
_capabilities = Marshal.ReadInt32(unmanagedAddress, (int)Marshal.OffsetOf(typeof(SecurityPackageInfo), "Capabilities"));
|
||||
_version = Marshal.ReadInt16(unmanagedAddress, (int)Marshal.OffsetOf(typeof(SecurityPackageInfo), "Version"));
|
||||
_rpcid = Marshal.ReadInt16(unmanagedAddress, (int)Marshal.OffsetOf(typeof(SecurityPackageInfo), "RPCID"));
|
||||
_maxToken = Marshal.ReadInt32(unmanagedAddress, (int)Marshal.OffsetOf(typeof(SecurityPackageInfo), "MaxToken"));
|
||||
|
||||
IntPtr unmanagedString;
|
||||
|
||||
unmanagedString = Marshal.ReadIntPtr(unmanagedAddress, (int)Marshal.OffsetOf(typeof(SecurityPackageInfo), "Name"));
|
||||
if (unmanagedString != IntPtr.Zero)
|
||||
{
|
||||
_name = Marshal.PtrToStringUni(unmanagedString);
|
||||
GlobalLog.Print("Name: " + Name);
|
||||
}
|
||||
|
||||
unmanagedString = Marshal.ReadIntPtr(unmanagedAddress, (int)Marshal.OffsetOf(typeof(SecurityPackageInfo), "Comment"));
|
||||
if (unmanagedString != IntPtr.Zero)
|
||||
{
|
||||
_comment = Marshal.PtrToStringUni(unmanagedString);
|
||||
GlobalLog.Print("Comment: " + _comment);
|
||||
}
|
||||
|
||||
GlobalLog.Print("SecurityPackageInfoClass::.ctor(): " + ToString());
|
||||
}
|
||||
|
||||
internal int MaxToken
|
||||
{
|
||||
get { return _maxToken; }
|
||||
}
|
||||
|
||||
internal string Name
|
||||
{
|
||||
get { return _name; }
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "Capabilities:" + String.Format(CultureInfo.InvariantCulture, "0x{0:x}", _capabilities)
|
||||
+ " Version:" + _version.ToString(NumberFormatInfo.InvariantInfo)
|
||||
+ " RPCID:" + _rpcid.ToString(NumberFormatInfo.InvariantInfo)
|
||||
+ " MaxToken:" + MaxToken.ToString(NumberFormatInfo.InvariantInfo)
|
||||
+ " Name:" + ((Name == null) ? "(null)" : Name)
|
||||
+ " Comment:" + ((_comment == null) ? "(null)" : _comment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="SslConnectionInfo.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal class SslConnectionInfo
|
||||
{
|
||||
public readonly int Protocol;
|
||||
public readonly int DataCipherAlg;
|
||||
public readonly int DataKeySize;
|
||||
public readonly int DataHashAlg;
|
||||
public readonly int DataHashKeySize;
|
||||
public readonly int KeyExchangeAlg;
|
||||
public readonly int KeyExchKeySize;
|
||||
|
||||
internal unsafe SslConnectionInfo(byte[] nativeBuffer)
|
||||
{
|
||||
fixed (void* voidPtr = nativeBuffer)
|
||||
{
|
||||
IntPtr unmanagedAddress = new IntPtr(voidPtr);
|
||||
Protocol = Marshal.ReadInt32(unmanagedAddress);
|
||||
DataCipherAlg = Marshal.ReadInt32(unmanagedAddress, 4);
|
||||
DataKeySize = Marshal.ReadInt32(unmanagedAddress, 8);
|
||||
DataHashAlg = Marshal.ReadInt32(unmanagedAddress, 12);
|
||||
DataHashKeySize = Marshal.ReadInt32(unmanagedAddress, 16);
|
||||
KeyExchangeAlg = Marshal.ReadInt32(unmanagedAddress, 20);
|
||||
KeyExchKeySize = Marshal.ReadInt32(unmanagedAddress, 24);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="StreamSizes.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal class StreamSizes
|
||||
{
|
||||
public int header;
|
||||
public int trailer;
|
||||
public int maximumMessage;
|
||||
public int buffersCount;
|
||||
public int blockSize;
|
||||
|
||||
internal unsafe StreamSizes(byte[] memory)
|
||||
{
|
||||
fixed (void* voidPtr = memory)
|
||||
{
|
||||
IntPtr unmanagedAddress = new IntPtr(voidPtr);
|
||||
try
|
||||
{
|
||||
header = (int)checked((uint)Marshal.ReadInt32(unmanagedAddress));
|
||||
trailer = (int)checked((uint)Marshal.ReadInt32(unmanagedAddress, 4));
|
||||
maximumMessage = (int)checked((uint)Marshal.ReadInt32(unmanagedAddress, 8));
|
||||
buffersCount = (int)checked((uint)Marshal.ReadInt32(unmanagedAddress, 12));
|
||||
blockSize = (int)checked((uint)Marshal.ReadInt32(unmanagedAddress, 16));
|
||||
}
|
||||
catch (OverflowException)
|
||||
{
|
||||
GlobalLog.Assert(false, "StreamSizes::.ctor", "Negative size.");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
public static readonly int SizeOf = Marshal.SizeOf(typeof(StreamSizes));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,272 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="UnsafeNativeMethods.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
[System.Security.SuppressUnmanagedCodeSecurityAttribute]
|
||||
internal static class UnsafeNclNativeMethods
|
||||
{
|
||||
#if ASPNETCORE50
|
||||
private const string sspicli_LIB = "sspicli.dll";
|
||||
private const string api_ms_win_core_processthreads_LIB = "api-ms-win-core-processthreads-l1-1-1.dll";
|
||||
private const string api_ms_win_core_handle_LIB = "api-ms-win-core-handle-l1-1-0.dll";
|
||||
private const string api_ms_win_core_libraryloader_LIB = "api-ms-win-core-libraryloader-l1-1-1.dll";
|
||||
private const string api_ms_win_core_heap_obsolete_LIB = "api-ms-win-core-heap-obsolete-l1-1-0.dll";
|
||||
#else
|
||||
private const string KERNEL32 = "kernel32.dll";
|
||||
#endif
|
||||
private const string SECUR32 = "secur32.dll";
|
||||
private const string CRYPT32 = "crypt32.dll";
|
||||
|
||||
#if ASPNETCORE50
|
||||
[DllImport(api_ms_win_core_processthreads_LIB, ExactSpelling = true, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
|
||||
#else
|
||||
[DllImport(KERNEL32, ExactSpelling = true, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
|
||||
#endif
|
||||
internal static extern uint GetCurrentThreadId();
|
||||
|
||||
|
||||
[System.Security.SuppressUnmanagedCodeSecurityAttribute]
|
||||
internal static class SafeNetHandles
|
||||
{
|
||||
[DllImport(SECUR32, ExactSpelling = true, SetLastError = true)]
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
internal static extern int FreeContextBuffer(
|
||||
[In] IntPtr contextBuffer);
|
||||
|
||||
[DllImport(SECUR32, ExactSpelling = true, SetLastError = true)]
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
internal static extern int FreeCredentialsHandle(
|
||||
ref SSPIHandle handlePtr);
|
||||
|
||||
[DllImport(SECUR32, ExactSpelling = true, SetLastError = true)]
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
internal static extern int DeleteSecurityContext(
|
||||
ref SSPIHandle handlePtr);
|
||||
|
||||
[DllImport(SECUR32, ExactSpelling = true, SetLastError = true)]
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
||||
internal static unsafe extern int AcceptSecurityContext(
|
||||
ref SSPIHandle credentialHandle,
|
||||
[In] void* inContextPtr,
|
||||
[In] SecurityBufferDescriptor inputBuffer,
|
||||
[In] ContextFlags inFlags,
|
||||
[In] Endianness endianness,
|
||||
ref SSPIHandle outContextPtr,
|
||||
[In, Out] SecurityBufferDescriptor outputBuffer,
|
||||
[In, Out] ref ContextFlags attributes,
|
||||
out long timeStamp);
|
||||
|
||||
[DllImport(SECUR32, ExactSpelling = true, SetLastError = true)]
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
||||
internal static unsafe extern int QueryContextAttributesW(
|
||||
ref SSPIHandle contextHandle,
|
||||
[In] ContextAttribute attribute,
|
||||
[In] void* buffer);
|
||||
|
||||
[DllImport(SECUR32, ExactSpelling = true, SetLastError = true)]
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
||||
internal static unsafe extern int SetContextAttributesW(
|
||||
ref SSPIHandle contextHandle,
|
||||
[In] ContextAttribute attribute,
|
||||
[In] byte[] buffer,
|
||||
[In] int bufferSize);
|
||||
|
||||
[DllImport(SECUR32, ExactSpelling = true, SetLastError = true)]
|
||||
internal static extern int EnumerateSecurityPackagesW(
|
||||
[Out] out int pkgnum,
|
||||
[Out] out SafeFreeContextBuffer handle);
|
||||
|
||||
[DllImport(SECUR32, ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
internal static unsafe extern int AcquireCredentialsHandleW(
|
||||
[In] string principal,
|
||||
[In] string moduleName,
|
||||
[In] int usage,
|
||||
[In] void* logonID,
|
||||
[In] ref AuthIdentity authdata,
|
||||
[In] void* keyCallback,
|
||||
[In] void* keyArgument,
|
||||
ref SSPIHandle handlePtr,
|
||||
[Out] out long timeStamp);
|
||||
|
||||
[DllImport(SECUR32, ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
internal static unsafe extern int AcquireCredentialsHandleW(
|
||||
[In] string principal,
|
||||
[In] string moduleName,
|
||||
[In] int usage,
|
||||
[In] void* logonID,
|
||||
[In] IntPtr zero,
|
||||
[In] void* keyCallback,
|
||||
[In] void* keyArgument,
|
||||
ref SSPIHandle handlePtr,
|
||||
[Out] out long timeStamp);
|
||||
|
||||
// Win7+
|
||||
[DllImport(SECUR32, ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
internal static unsafe extern int AcquireCredentialsHandleW(
|
||||
[In] string principal,
|
||||
[In] string moduleName,
|
||||
[In] int usage,
|
||||
[In] void* logonID,
|
||||
[In] SafeSspiAuthDataHandle authdata,
|
||||
[In] void* keyCallback,
|
||||
[In] void* keyArgument,
|
||||
ref SSPIHandle handlePtr,
|
||||
[Out] out long timeStamp);
|
||||
|
||||
[DllImport(SECUR32, ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
internal static unsafe extern int AcquireCredentialsHandleW(
|
||||
[In] string principal,
|
||||
[In] string moduleName,
|
||||
[In] int usage,
|
||||
[In] void* logonID,
|
||||
[In] ref SecureCredential authData,
|
||||
[In] void* keyCallback,
|
||||
[In] void* keyArgument,
|
||||
ref SSPIHandle handlePtr,
|
||||
[Out] out long timeStamp);
|
||||
|
||||
[DllImport(SECUR32, ExactSpelling = true, SetLastError = true)]
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
||||
internal static unsafe extern int InitializeSecurityContextW(
|
||||
ref SSPIHandle credentialHandle,
|
||||
[In] void* inContextPtr,
|
||||
[In] byte* targetName,
|
||||
[In] ContextFlags inFlags,
|
||||
[In] int reservedI,
|
||||
[In] Endianness endianness,
|
||||
[In] SecurityBufferDescriptor inputBuffer,
|
||||
[In] int reservedII,
|
||||
ref SSPIHandle outContextPtr,
|
||||
[In, Out] SecurityBufferDescriptor outputBuffer,
|
||||
[In, Out] ref ContextFlags attributes,
|
||||
out long timeStamp);
|
||||
|
||||
[DllImport(SECUR32, ExactSpelling = true, SetLastError = true)]
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
||||
internal static unsafe extern int CompleteAuthToken(
|
||||
[In] void* inContextPtr,
|
||||
[In, Out] SecurityBufferDescriptor inputBuffers);
|
||||
|
||||
[DllImport(SECUR32, ExactSpelling = true, SetLastError = true)]
|
||||
internal static extern int QuerySecurityContextToken(ref SSPIHandle phContext, [Out] out SafeCloseHandle handle);
|
||||
|
||||
#if ASPNETCORE50
|
||||
[DllImport(api_ms_win_core_handle_LIB, ExactSpelling = true, SetLastError = true)]
|
||||
#else
|
||||
[DllImport(KERNEL32, ExactSpelling = true, SetLastError = true)]
|
||||
#endif
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
internal static extern bool CloseHandle(IntPtr handle);
|
||||
|
||||
#if ASPNETCORE50
|
||||
[DllImport(api_ms_win_core_heap_obsolete_LIB, ExactSpelling = true, SetLastError = true)]
|
||||
#else
|
||||
[DllImport(KERNEL32, ExactSpelling = true, SetLastError = true)]
|
||||
#endif
|
||||
internal static extern SafeLocalFree LocalAlloc(int uFlags, UIntPtr sizetdwBytes);
|
||||
|
||||
#if ASPNETCORE50
|
||||
[DllImport(api_ms_win_core_heap_obsolete_LIB, ExactSpelling = true, SetLastError = true)]
|
||||
#else
|
||||
[DllImport(KERNEL32, ExactSpelling = true, SetLastError = true)]
|
||||
#endif
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
internal static extern IntPtr LocalFree(IntPtr handle);
|
||||
|
||||
#if ASPNETCORE50
|
||||
[DllImport(api_ms_win_core_libraryloader_LIB, ExactSpelling = true, SetLastError = true)]
|
||||
#else
|
||||
[DllImport(KERNEL32, ExactSpelling = true, SetLastError = true)]
|
||||
#endif
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
internal static extern unsafe bool FreeLibrary([In] IntPtr hModule);
|
||||
|
||||
[DllImport(CRYPT32, ExactSpelling = true, SetLastError = true)]
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
internal static extern void CertFreeCertificateChain(
|
||||
[In] IntPtr pChainContext);
|
||||
|
||||
[DllImport(CRYPT32, ExactSpelling = true, SetLastError = true)]
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
internal static extern void CertFreeCertificateChainList(
|
||||
[In] IntPtr ppChainContext);
|
||||
|
||||
[DllImport(CRYPT32, ExactSpelling = true, SetLastError = true)]
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
internal static extern bool CertFreeCertificateContext( // Suppressing returned status check, it's always==TRUE,
|
||||
[In] IntPtr certContext);
|
||||
|
||||
#if ASPNETCORE50
|
||||
[DllImport(api_ms_win_core_heap_obsolete_LIB, ExactSpelling = true, SetLastError = true)]
|
||||
#else
|
||||
[DllImport(KERNEL32, ExactSpelling = true, SetLastError = true)]
|
||||
#endif
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
internal static extern IntPtr GlobalFree(IntPtr handle);
|
||||
}
|
||||
|
||||
[System.Security.SuppressUnmanagedCodeSecurityAttribute]
|
||||
internal static class NativeNTSSPI
|
||||
{
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
||||
[DllImport(SECUR32, ExactSpelling = true, SetLastError = true)]
|
||||
internal static extern int EncryptMessage(
|
||||
ref SSPIHandle contextHandle,
|
||||
[In] uint qualityOfProtection,
|
||||
[In, Out] SecurityBufferDescriptor inputOutput,
|
||||
[In] uint sequenceNumber);
|
||||
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
||||
[DllImport(SECUR32, ExactSpelling = true, SetLastError = true)]
|
||||
internal static unsafe extern int DecryptMessage(
|
||||
[In] ref SSPIHandle contextHandle,
|
||||
[In, Out] SecurityBufferDescriptor inputOutput,
|
||||
[In] uint sequenceNumber,
|
||||
uint* qualityOfProtection);
|
||||
} // class UnsafeNclNativeMethods.NativeNTSSPI
|
||||
|
||||
[SuppressUnmanagedCodeSecurityAttribute]
|
||||
internal static class SspiHelper
|
||||
{
|
||||
[DllImport(SECUR32, ExactSpelling = true, SetLastError = true)]
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
||||
internal static unsafe extern SecurityStatus SspiFreeAuthIdentity(
|
||||
[In] IntPtr authData);
|
||||
|
||||
[SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "Implementation requires unmanaged code usage")]
|
||||
[DllImport(SECUR32, ExactSpelling = true, SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
internal static unsafe extern SecurityStatus SspiEncodeStringsAsAuthIdentity(
|
||||
[In] string userName,
|
||||
[In] string domainName,
|
||||
[In] string password,
|
||||
[Out] out SafeSspiAuthDataHandle authData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="NegotiationInfoClass.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
internal class NegotiationInfoClass
|
||||
{
|
||||
internal const string NTLM = "NTLM";
|
||||
internal const string Kerberos = "Kerberos";
|
||||
internal const string WDigest = "WDigest";
|
||||
internal const string Digest = "Digest";
|
||||
internal const string Negotiate = "Negotiate";
|
||||
internal string AuthenticationPackage;
|
||||
|
||||
internal NegotiationInfoClass(SafeHandle safeHandle, int negotiationState)
|
||||
{
|
||||
if (safeHandle.IsInvalid)
|
||||
{
|
||||
GlobalLog.Print("NegotiationInfoClass::.ctor() the handle is invalid:" + (safeHandle.DangerousGetHandle()).ToString("x"));
|
||||
return;
|
||||
}
|
||||
IntPtr packageInfo = safeHandle.DangerousGetHandle();
|
||||
GlobalLog.Print("NegotiationInfoClass::.ctor() packageInfo:" + packageInfo.ToString("x8") + " negotiationState:" + negotiationState.ToString("x8"));
|
||||
|
||||
const int SECPKG_NEGOTIATION_COMPLETE = 0;
|
||||
const int SECPKG_NEGOTIATION_OPTIMISTIC = 1;
|
||||
// const int SECPKG_NEGOTIATION_IN_PROGRESS = 2;
|
||||
// const int SECPKG_NEGOTIATION_DIRECT = 3;
|
||||
// const int SECPKG_NEGOTIATION_TRY_MULTICRED = 4;
|
||||
|
||||
if (negotiationState == SECPKG_NEGOTIATION_COMPLETE || negotiationState == SECPKG_NEGOTIATION_OPTIMISTIC)
|
||||
{
|
||||
IntPtr unmanagedString = Marshal.ReadIntPtr(packageInfo, SecurityPackageInfo.NameOffest);
|
||||
string name = null;
|
||||
if (unmanagedString != IntPtr.Zero)
|
||||
{
|
||||
name = Marshal.PtrToStringUni(unmanagedString);
|
||||
}
|
||||
GlobalLog.Print("NegotiationInfoClass::.ctor() packageInfo:" + packageInfo.ToString("x8") + " negotiationState:" + negotiationState.ToString("x8") + " name:" + ValidationHelper.ToString(name));
|
||||
|
||||
// an optimization for future string comparisons
|
||||
if (string.Compare(name, Kerberos, StringComparison.OrdinalIgnoreCase) == 0)
|
||||
{
|
||||
AuthenticationPackage = Kerberos;
|
||||
}
|
||||
else if (string.Compare(name, NTLM, StringComparison.OrdinalIgnoreCase) == 0)
|
||||
{
|
||||
AuthenticationPackage = NTLM;
|
||||
}
|
||||
else if (string.Compare(name, WDigest, StringComparison.OrdinalIgnoreCase) == 0)
|
||||
{
|
||||
AuthenticationPackage = WDigest;
|
||||
}
|
||||
else
|
||||
{
|
||||
AuthenticationPackage = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,126 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="HttpListenerPrefixCollection.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
internal class PrefixCollection : ICollection<string>
|
||||
{
|
||||
private WindowsAuthMiddleware _winAuth;
|
||||
|
||||
internal PrefixCollection(WindowsAuthMiddleware winAuth)
|
||||
{
|
||||
_winAuth = winAuth;
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
return _winAuth._uriPrefixes.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSynchronized
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void CopyTo(Array array, int offset)
|
||||
{
|
||||
if (Count > array.Length)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("array", SR.GetString(SR.net_array_too_small));
|
||||
}
|
||||
if (offset + Count > array.Length)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("offset");
|
||||
}
|
||||
int index = 0;
|
||||
foreach (string uriPrefix in _winAuth._uriPrefixes.Keys)
|
||||
{
|
||||
array.SetValue(uriPrefix, offset + index++);
|
||||
}
|
||||
}
|
||||
|
||||
public void CopyTo(string[] array, int offset)
|
||||
{
|
||||
if (Count > array.Length)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("array", SR.GetString(SR.net_array_too_small));
|
||||
}
|
||||
if (offset + Count > array.Length)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("offset");
|
||||
}
|
||||
int index = 0;
|
||||
foreach (string uriPrefix in _winAuth._uriPrefixes.Keys)
|
||||
{
|
||||
array[offset + index++] = uriPrefix;
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(string uriPrefix)
|
||||
{
|
||||
_winAuth.AddPrefix(uriPrefix);
|
||||
}
|
||||
|
||||
public bool Contains(string uriPrefix)
|
||||
{
|
||||
return _winAuth._uriPrefixes.Contains(uriPrefix);
|
||||
}
|
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
|
||||
{
|
||||
return this.GetEnumerator();
|
||||
}
|
||||
|
||||
public IEnumerator<string> GetEnumerator()
|
||||
{
|
||||
return new PrefixEnumerator(_winAuth._uriPrefixes.Keys.GetEnumerator());
|
||||
}
|
||||
|
||||
public bool Remove(string uriPrefix)
|
||||
{
|
||||
return _winAuth.RemovePrefix(uriPrefix);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_winAuth.RemoveAll(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="PrefixEnumerator.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
internal class PrefixEnumerator : IEnumerator<string>
|
||||
{
|
||||
private IEnumerator enumerator;
|
||||
|
||||
internal PrefixEnumerator(IEnumerator enumerator)
|
||||
{
|
||||
this.enumerator = enumerator;
|
||||
}
|
||||
|
||||
public string Current
|
||||
{
|
||||
get
|
||||
{
|
||||
return (string)enumerator.Current;
|
||||
}
|
||||
}
|
||||
|
||||
object System.Collections.IEnumerator.Current
|
||||
{
|
||||
get
|
||||
{
|
||||
return enumerator.Current;
|
||||
}
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
return enumerator.MoveNext();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
void System.Collections.IEnumerator.Reset()
|
||||
{
|
||||
enumerator.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,385 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
|
||||
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
||||
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="ServiceNameStore.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Net;
|
||||
using System.Security.Authentication.ExtendedProtection;
|
||||
|
||||
namespace Microsoft.AspNet.Security.Windows
|
||||
{
|
||||
internal class ServiceNameStore
|
||||
{
|
||||
private List<string> serviceNames;
|
||||
private ServiceNameCollection serviceNameCollection;
|
||||
|
||||
public ServiceNameStore()
|
||||
{
|
||||
serviceNames = new List<string>();
|
||||
serviceNameCollection = null; // set only when needed (due to expensive item-by-item copy)
|
||||
}
|
||||
|
||||
public ServiceNameCollection ServiceNames
|
||||
{
|
||||
get
|
||||
{
|
||||
if (serviceNameCollection == null)
|
||||
{
|
||||
serviceNameCollection = new ServiceNameCollection(serviceNames);
|
||||
}
|
||||
return serviceNameCollection;
|
||||
}
|
||||
}
|
||||
|
||||
private bool AddSingleServiceName(string spn)
|
||||
{
|
||||
spn = NormalizeServiceName(spn);
|
||||
if (Contains(spn))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
serviceNames.Add(spn);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Add(string uriPrefix)
|
||||
{
|
||||
Debug.Assert(!String.IsNullOrEmpty(uriPrefix));
|
||||
|
||||
string[] newServiceNames = BuildServiceNames(uriPrefix);
|
||||
|
||||
bool addedAny = false;
|
||||
foreach (string spn in newServiceNames)
|
||||
{
|
||||
if (AddSingleServiceName(spn))
|
||||
{
|
||||
addedAny = true;
|
||||
|
||||
if (Logging.On)
|
||||
{
|
||||
Logging.PrintInfo(Logging.HttpListener, "ServiceNameStore#" +
|
||||
ValidationHelper.HashString(this) + "::Add() "
|
||||
+ SR.GetString(SR.net_log_listener_spn_add, spn, uriPrefix));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (addedAny)
|
||||
{
|
||||
serviceNameCollection = null;
|
||||
}
|
||||
else if (Logging.On)
|
||||
{
|
||||
Logging.PrintInfo(Logging.HttpListener, "ServiceNameStore#" +
|
||||
ValidationHelper.HashString(this) + "::Add() "
|
||||
+ SR.GetString(SR.net_log_listener_spn_not_add, uriPrefix));
|
||||
}
|
||||
|
||||
return addedAny;
|
||||
}
|
||||
|
||||
public bool Remove(string uriPrefix)
|
||||
{
|
||||
Debug.Assert(!String.IsNullOrEmpty(uriPrefix));
|
||||
|
||||
string newServiceName = BuildSimpleServiceName(uriPrefix);
|
||||
newServiceName = NormalizeServiceName(newServiceName);
|
||||
bool needToRemove = Contains(newServiceName);
|
||||
|
||||
if (needToRemove)
|
||||
{
|
||||
serviceNames.Remove(newServiceName);
|
||||
serviceNameCollection = null; // invalidate (readonly) ServiceNameCollection
|
||||
}
|
||||
|
||||
if (Logging.On)
|
||||
{
|
||||
if (needToRemove)
|
||||
{
|
||||
Logging.PrintInfo(Logging.HttpListener, "ServiceNameStore#" +
|
||||
ValidationHelper.HashString(this) + "::Remove() "
|
||||
+ SR.GetString(SR.net_log_listener_spn_remove, newServiceName, uriPrefix));
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.PrintInfo(Logging.HttpListener, "ServiceNameStore#" +
|
||||
ValidationHelper.HashString(this) + "::Remove() "
|
||||
+ SR.GetString(SR.net_log_listener_spn_not_remove, uriPrefix));
|
||||
}
|
||||
}
|
||||
|
||||
return needToRemove;
|
||||
}
|
||||
|
||||
// Assumes already normalized
|
||||
private bool Contains(string newServiceName)
|
||||
{
|
||||
if (newServiceName == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Contains(newServiceName, serviceNames);
|
||||
}
|
||||
|
||||
// Assumes searchServiceName and serviceNames have already been normalized
|
||||
internal static bool Contains(string searchServiceName, ICollection serviceNames)
|
||||
{
|
||||
Debug.Assert(serviceNames != null);
|
||||
Debug.Assert(!String.IsNullOrEmpty(searchServiceName));
|
||||
|
||||
foreach (string serviceName in serviceNames)
|
||||
{
|
||||
if (Match(serviceName, searchServiceName))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Assumes already normalized
|
||||
internal static bool Match(string serviceName1, string serviceName2)
|
||||
{
|
||||
return (String.Compare(serviceName1, serviceName2, StringComparison.OrdinalIgnoreCase) == 0);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
serviceNames.Clear();
|
||||
serviceNameCollection = null; // invalidate (readonly) ServiceNameCollection
|
||||
}
|
||||
|
||||
private string ExtractHostname(string uriPrefix, bool allowInvalidUriStrings)
|
||||
{
|
||||
if (Uri.IsWellFormedUriString(uriPrefix, UriKind.Absolute))
|
||||
{
|
||||
Uri hostUri = new Uri(uriPrefix);
|
||||
return hostUri.Host;
|
||||
}
|
||||
else if (allowInvalidUriStrings)
|
||||
{
|
||||
int i = uriPrefix.IndexOf("://") + 3;
|
||||
int j = i;
|
||||
|
||||
bool inSquareBrackets = false;
|
||||
while (j < uriPrefix.Length && uriPrefix[j] != '/' && (uriPrefix[j] != ':' || inSquareBrackets))
|
||||
{
|
||||
if (uriPrefix[j] == '[')
|
||||
{
|
||||
if (inSquareBrackets)
|
||||
{
|
||||
j = i;
|
||||
break;
|
||||
}
|
||||
inSquareBrackets = true;
|
||||
}
|
||||
if (inSquareBrackets && uriPrefix[j] == ']')
|
||||
{
|
||||
inSquareBrackets = false;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
|
||||
return uriPrefix.Substring(i, j - i);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public string BuildSimpleServiceName(string uriPrefix)
|
||||
{
|
||||
string hostname = ExtractHostname(uriPrefix, false);
|
||||
|
||||
if (hostname != null)
|
||||
{
|
||||
return "HTTP/" + hostname;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public string[] BuildServiceNames(string uriPrefix)
|
||||
{
|
||||
string hostname = ExtractHostname(uriPrefix, true);
|
||||
|
||||
IPAddress ipAddress = null;
|
||||
if (String.Compare(hostname, "*", StringComparison.InvariantCultureIgnoreCase) == 0 ||
|
||||
String.Compare(hostname, "+", StringComparison.InvariantCultureIgnoreCase) == 0 ||
|
||||
IPAddress.TryParse(hostname, out ipAddress))
|
||||
{
|
||||
// for a wildcard, register the machine name. If the caller doesn't have DNS permission
|
||||
// or the query fails for some reason, don't add an SPN.
|
||||
try
|
||||
{
|
||||
string machineName = Dns.GetHostEntry(String.Empty).HostName;
|
||||
return new string[] { "HTTP/" + machineName };
|
||||
}
|
||||
catch (System.Net.Sockets.SocketException)
|
||||
{
|
||||
return new string[0];
|
||||
}
|
||||
catch (System.Security.SecurityException)
|
||||
{
|
||||
return new string[0];
|
||||
}
|
||||
}
|
||||
else if (!hostname.Contains("."))
|
||||
{
|
||||
// for a dotless name, try to resolve the FQDN. If the caller doesn't have DNS permission
|
||||
// or the query fails for some reason, add only the dotless name.
|
||||
try
|
||||
{
|
||||
string fqdn = Dns.GetHostEntry(hostname).HostName;
|
||||
return new string[] { "HTTP/" + hostname, "HTTP/" + fqdn };
|
||||
}
|
||||
catch (System.Net.Sockets.SocketException)
|
||||
{
|
||||
return new string[] { "HTTP/" + hostname };
|
||||
}
|
||||
catch (System.Security.SecurityException)
|
||||
{
|
||||
return new string[] { "HTTP/" + hostname };
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return new string[] { "HTTP/" + hostname };
|
||||
}
|
||||
}
|
||||
|
||||
// Normalizes any punycode to unicode in an Service Name (SPN) host.
|
||||
// If the algorithm fails at any point then the original input is returned.
|
||||
// ServiceName is in one of the following forms:
|
||||
// prefix/host
|
||||
// prefix/host:port
|
||||
// prefix/host/DistinguishedName
|
||||
// prefix/host:port/DistinguishedName
|
||||
internal static string NormalizeServiceName(string inputServiceName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(inputServiceName))
|
||||
{
|
||||
return inputServiceName;
|
||||
}
|
||||
|
||||
// Separate out the prefix
|
||||
int shashIndex = inputServiceName.IndexOf('/');
|
||||
if (shashIndex < 0)
|
||||
{
|
||||
return inputServiceName;
|
||||
}
|
||||
string prefix = inputServiceName.Substring(0, shashIndex + 1); // Includes slash
|
||||
string hostPortAndDistinguisher = inputServiceName.Substring(shashIndex + 1); // Excludes slash
|
||||
|
||||
if (string.IsNullOrWhiteSpace(hostPortAndDistinguisher))
|
||||
{
|
||||
return inputServiceName;
|
||||
}
|
||||
|
||||
string host = hostPortAndDistinguisher;
|
||||
string port = string.Empty;
|
||||
string distinguisher = string.Empty;
|
||||
|
||||
// Check for the absence of a port or distinguisher.
|
||||
UriHostNameType hostType = Uri.CheckHostName(hostPortAndDistinguisher);
|
||||
if (hostType == UriHostNameType.Unknown)
|
||||
{
|
||||
string hostAndPort = hostPortAndDistinguisher;
|
||||
|
||||
// Check for distinguisher
|
||||
int nextSlashIndex = hostPortAndDistinguisher.IndexOf('/');
|
||||
if (nextSlashIndex >= 0)
|
||||
{
|
||||
// host:port/distinguisher or host/distinguisher
|
||||
hostAndPort = hostPortAndDistinguisher.Substring(0, nextSlashIndex); // Excludes Slash
|
||||
distinguisher = hostPortAndDistinguisher.Substring(nextSlashIndex); // Includes Slash
|
||||
host = hostAndPort; // We don't know if there is a port yet.
|
||||
|
||||
// No need to validate the distinguisher
|
||||
}
|
||||
|
||||
// Check for port
|
||||
int colonIndex = hostAndPort.LastIndexOf(':'); // Allow IPv6 addresses
|
||||
if (colonIndex >= 0)
|
||||
{
|
||||
// host:port
|
||||
host = hostAndPort.Substring(0, colonIndex); // Excludes colon
|
||||
port = hostAndPort.Substring(colonIndex + 1); // Excludes colon
|
||||
|
||||
// Loosely validate the port just to make sure it was a port and not something else
|
||||
UInt16 portValue;
|
||||
if (!UInt16.TryParse(port, NumberStyles.Integer, CultureInfo.InvariantCulture, out portValue))
|
||||
{
|
||||
return inputServiceName;
|
||||
}
|
||||
|
||||
// Re-include the colon for the final output. Do not change the port format.
|
||||
port = hostAndPort.Substring(colonIndex);
|
||||
}
|
||||
|
||||
hostType = Uri.CheckHostName(host); // Revaidate the host
|
||||
}
|
||||
|
||||
if (hostType != UriHostNameType.Dns)
|
||||
{
|
||||
// UriHostNameType.IPv4, UriHostNameType.IPv6: Do not normalize IPv4/6 hosts.
|
||||
// UriHostNameType.Basic: This is never returned by CheckHostName today
|
||||
// UriHostNameType.Unknown: Nothing recognizable to normalize
|
||||
// default Some new UriHostNameType?
|
||||
return inputServiceName;
|
||||
}
|
||||
|
||||
// Now we have a valid DNS host, normalize it.
|
||||
|
||||
Uri constructedUri;
|
||||
// This shouldn't fail, but we need to avoid any unexpected exceptions on this code path.
|
||||
if (!Uri.TryCreate(Uri.UriSchemeHttp + Uri.SchemeDelimiter + host, UriKind.Absolute, out constructedUri))
|
||||
{
|
||||
return inputServiceName;
|
||||
}
|
||||
|
||||
string normalizedHost = constructedUri.GetComponents(
|
||||
UriComponents.NormalizedHost, UriFormat.SafeUnescaped);
|
||||
|
||||
string normalizedServiceName = string.Format(CultureInfo.InvariantCulture,
|
||||
"{0}{1}{2}{3}", prefix, normalizedHost, port, distinguisher);
|
||||
|
||||
// Don't return the new one unless we absolutely have to. It may have only changed casing.
|
||||
if (String.Compare(inputServiceName, normalizedServiceName, StringComparison.OrdinalIgnoreCase) == 0)
|
||||
{
|
||||
return inputServiceName;
|
||||
}
|
||||
|
||||
return normalizedServiceName;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"version": "1.0.0-*",
|
||||
"dependencies": {
|
||||
},
|
||||
"compilationOptions" : { "allowUnsafe": true },
|
||||
"frameworks":
|
||||
{
|
||||
"aspnet50" : {
|
||||
"dependencies": {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue