diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/.gitignore | 2 | ||||
-rw-r--r-- | src/DotNetOpenAuth.AspNet/Clients/OAuth/AuthenticationOnlyCookieOAuthTokenManager.cs | 5 | ||||
-rw-r--r-- | src/DotNetOpenAuth.AspNet/Clients/OAuth/LinkedInClient.cs | 9 | ||||
-rw-r--r-- | src/DotNetOpenAuth.AspNet/Clients/OAuth/OAuthClient.cs | 17 | ||||
-rw-r--r-- | src/DotNetOpenAuth.AspNet/Clients/OAuth/TwitterClient.cs | 9 | ||||
-rw-r--r-- | src/DotNetOpenAuth.AspNet/MachineKeyUtil.cs | 20 | ||||
-rw-r--r-- | src/DotNetOpenAuth.AspNet/OpenAuthSecurityManager.cs | 53 | ||||
-rw-r--r-- | src/DotNetOpenAuth.AspNet/UriHelper.cs | 3 | ||||
-rw-r--r-- | src/DotNetOpenAuth/DotNetOpenAuth.proj | 15 | ||||
-rw-r--r-- | src/DotNetOpenAuth/Properties/AssemblyInfo.cs | 55 | ||||
-rw-r--r-- | src/DotNetOpenAuth/Stub.csproj | 35 |
11 files changed, 196 insertions, 27 deletions
diff --git a/src/.gitignore b/src/.gitignore index ad0e465..420748a 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,6 +1,6 @@ Backup* _UpgradeReport_Files -UpgradeLog.XML +UpgradeLog*.XML PrecompiledWeb _ReSharper.* *.suo diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth/AuthenticationOnlyCookieOAuthTokenManager.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth/AuthenticationOnlyCookieOAuthTokenManager.cs index a58549a..2ec988b 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OAuth/AuthenticationOnlyCookieOAuthTokenManager.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth/AuthenticationOnlyCookieOAuthTokenManager.cs @@ -86,7 +86,10 @@ namespace DotNetOpenAuth.AspNet.Clients { /// <param name="requestToken">The request token.</param> /// <param name="requestTokenSecret">The request token secret.</param> public void StoreRequestToken(string requestToken, string requestTokenSecret) { - var cookie = new HttpCookie(TokenCookieKey); + var cookie = new HttpCookie(TokenCookieKey) { + HttpOnly = true + }; + if (FormsAuthentication.RequireSSL) { cookie.Secure = true; } diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth/LinkedInClient.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth/LinkedInClient.cs index ac8186d..26bc88d 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OAuth/LinkedInClient.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth/LinkedInClient.cs @@ -89,7 +89,7 @@ namespace DotNetOpenAuth.AspNet.Clients { Justification = "We don't care if the request fails.")] protected override AuthenticationResult VerifyAuthenticationCore(AuthorizedTokenResponse response) { // See here for Field Selectors API http://developer.linkedin.com/docs/DOC-1014 - const string ProfileRequestUrl = "http://api.linkedin.com/v1/people/~:(id,first-name,last-name,headline,industry,summary)"; + const string ProfileRequestUrl = "https://api.linkedin.com/v1/people/~:(id,first-name,last-name,headline,industry,summary)"; string accessToken = response.AccessToken; @@ -99,7 +99,7 @@ namespace DotNetOpenAuth.AspNet.Clients { try { using (WebResponse profileResponse = request.GetResponse()) { using (Stream responseStream = profileResponse.GetResponseStream()) { - XDocument document = XDocument.Load(responseStream); + XDocument document = LoadXDocumentFromStream(responseStream); string userId = document.Root.Element("id").Value; string firstName = document.Root.Element("first-name").Value; @@ -117,11 +117,12 @@ namespace DotNetOpenAuth.AspNet.Clients { isSuccessful: true, provider: this.ProviderName, providerUserId: userId, userName: userName, extraData: extraData); } } - } catch (Exception exception) { + } + catch (Exception exception) { return new AuthenticationResult(exception); } } #endregion } -} +}
\ No newline at end of file diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth/OAuthClient.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth/OAuthClient.cs index 3f9e85a..9a9f40d 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OAuth/OAuthClient.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth/OAuthClient.cs @@ -8,7 +8,10 @@ namespace DotNetOpenAuth.AspNet.Clients { using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; + using System.IO; using System.Web; + using System.Xml; + using System.Xml.Linq; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.OAuth; using DotNetOpenAuth.OAuth.ChannelElements; @@ -154,6 +157,20 @@ namespace DotNetOpenAuth.AspNet.Clients { #region Methods /// <summary> + /// Helper method to load an XDocument from an input stream. + /// </summary> + /// <param name="stream">The input stream from which to load the document.</param> + /// <returns>The XML document.</returns> + internal static XDocument LoadXDocumentFromStream(Stream stream) { + const int MaxChars = 0x10000; // 64k + + XmlReaderSettings settings = new XmlReaderSettings() { + MaxCharactersInDocument = MaxChars + }; + return XDocument.Load(XmlReader.Create(stream, settings)); + } + + /// <summary> /// Check if authentication succeeded after user is redirected back from the service provider. /// </summary> /// <param name="response"> diff --git a/src/DotNetOpenAuth.AspNet/Clients/OAuth/TwitterClient.cs b/src/DotNetOpenAuth.AspNet/Clients/OAuth/TwitterClient.cs index 96c1701..886917a 100644 --- a/src/DotNetOpenAuth.AspNet/Clients/OAuth/TwitterClient.cs +++ b/src/DotNetOpenAuth.AspNet/Clients/OAuth/TwitterClient.cs @@ -92,7 +92,7 @@ namespace DotNetOpenAuth.AspNet.Clients { string userId = response.ExtraData["user_id"]; string userName = response.ExtraData["screen_name"]; - var profileRequestUrl = new Uri("http://api.twitter.com/1/users/show.xml?user_id=" + var profileRequestUrl = new Uri("https://api.twitter.com/1/users/show.xml?user_id=" + MessagingUtilities.EscapeUriDataStringRfc3986(userId)); var profileEndpoint = new MessageReceivingEndpoint(profileRequestUrl, HttpDeliveryMethods.GetRequest); HttpWebRequest request = this.WebWorker.PrepareAuthorizedRequest(profileEndpoint, accessToken); @@ -102,14 +102,15 @@ namespace DotNetOpenAuth.AspNet.Clients { try { using (WebResponse profileResponse = request.GetResponse()) { using (Stream responseStream = profileResponse.GetResponseStream()) { - XDocument document = XDocument.Load(responseStream); + XDocument document = LoadXDocumentFromStream(responseStream); extraData.AddDataIfNotEmpty(document, "name"); extraData.AddDataIfNotEmpty(document, "location"); extraData.AddDataIfNotEmpty(document, "description"); extraData.AddDataIfNotEmpty(document, "url"); } } - } catch (Exception) { + } + catch (Exception) { // At this point, the authentication is already successful. // Here we are just trying to get additional data if we can. // If it fails, no problem. @@ -121,4 +122,4 @@ namespace DotNetOpenAuth.AspNet.Clients { #endregion } -} +}
\ No newline at end of file diff --git a/src/DotNetOpenAuth.AspNet/MachineKeyUtil.cs b/src/DotNetOpenAuth.AspNet/MachineKeyUtil.cs index f5c8547..eb2020b 100644 --- a/src/DotNetOpenAuth.AspNet/MachineKeyUtil.cs +++ b/src/DotNetOpenAuth.AspNet/MachineKeyUtil.cs @@ -10,8 +10,10 @@ namespace DotNetOpenAuth.AspNet { using System.Diagnostics.CodeAnalysis; using System.IO; using System.Net; + using System.Reflection; using System.Security.Cryptography; using System.Text; + using System.Web; using System.Web.Security; /// <summary> @@ -84,12 +86,20 @@ namespace DotNetOpenAuth.AspNet { /// </summary> /// <returns>The machine key implementation</returns> private static IMachineKey GetMachineKeyImpl() { - ProtectUnprotect protectThunk = (ProtectUnprotect)Delegate.CreateDelegate(typeof(ProtectUnprotect), typeof(MachineKey), "Protect", ignoreCase: false, throwOnBindFailure: false); - ProtectUnprotect unprotectThunk = (ProtectUnprotect)Delegate.CreateDelegate(typeof(ProtectUnprotect), typeof(MachineKey), "Unprotect", ignoreCase: false, throwOnBindFailure: false); + // Late bind to the MachineKey.Protect / Unprotect methods only if <httpRuntime targetFramework="4.5" />. + // This helps ensure that round-tripping the payloads continues to work even if the application is + // deployed to a mixed 4.0 / 4.5 farm environment. + PropertyInfo targetFrameworkProperty = typeof(HttpRuntime).GetProperty("TargetFramework", typeof(Version)); + Version targetFramework = (targetFrameworkProperty != null) ? targetFrameworkProperty.GetValue(null, null) as Version : null; + if (targetFramework != null && targetFramework >= new Version(4, 5)) { + ProtectUnprotect protectThunk = (ProtectUnprotect)Delegate.CreateDelegate(typeof(ProtectUnprotect), typeof(MachineKey), "Protect", ignoreCase: false, throwOnBindFailure: false); + ProtectUnprotect unprotectThunk = (ProtectUnprotect)Delegate.CreateDelegate(typeof(ProtectUnprotect), typeof(MachineKey), "Unprotect", ignoreCase: false, throwOnBindFailure: false); + if (protectThunk != null && unprotectThunk != null) { + return new MachineKey45(protectThunk, unprotectThunk); // ASP.NET 4.5 + } + } - return (protectThunk != null && unprotectThunk != null) - ? (IMachineKey)new MachineKey45(protectThunk, unprotectThunk) // ASP.NET 4.5 - : (IMachineKey)new MachineKey40(); // ASP.NET 4.0 + return new MachineKey40(); // ASP.NET 4.0 } /// <summary> diff --git a/src/DotNetOpenAuth.AspNet/OpenAuthSecurityManager.cs b/src/DotNetOpenAuth.AspNet/OpenAuthSecurityManager.cs index d33913a..6a898a1 100644 --- a/src/DotNetOpenAuth.AspNet/OpenAuthSecurityManager.cs +++ b/src/DotNetOpenAuth.AspNet/OpenAuthSecurityManager.cs @@ -7,6 +7,7 @@ namespace DotNetOpenAuth.AspNet { using System; using System.Diagnostics.CodeAnalysis; + using System.Text; using System.Web; using System.Web.Security; using DotNetOpenAuth.AspNet.Clients; @@ -19,6 +20,11 @@ namespace DotNetOpenAuth.AspNet { #region Constants and Fields /// <summary> + /// Purposes string used for protecting the anti-XSRF token. + /// </summary> + private const string AntiXsrfPurposeString = "DotNetOpenAuth.AspNet.AntiXsrfToken.v1"; + + /// <summary> /// The provider query string name. /// </summary> private const string ProviderQueryStringName = "__provider__"; @@ -166,7 +172,10 @@ namespace DotNetOpenAuth.AspNet { string sessionId = Guid.NewGuid().ToString("N"); uri = uri.AttachQueryStringParameter(SessionIdQueryStringName, sessionId); - var xsrfCookie = new HttpCookie(SessionIdCookieName, sessionId) { + // The cookie value will be the current username secured against the session id we just created. + byte[] encryptedCookieBytes = MachineKeyUtil.Protect(Encoding.UTF8.GetBytes(GetUsername(this.requestContext)), AntiXsrfPurposeString, "Token: " + sessionId); + + var xsrfCookie = new HttpCookie(SessionIdCookieName, HttpServerUtility.UrlTokenEncode(encryptedCookieBytes)) { HttpOnly = true }; if (FormsAuthentication.RequireSSL) { @@ -245,6 +254,19 @@ namespace DotNetOpenAuth.AspNet { } /// <summary> + /// Returns the username of the current logged-in user. + /// </summary> + /// <param name="context">The HTTP request context.</param> + /// <returns>The username, or String.Empty if anonymous.</returns> + private static string GetUsername(HttpContextBase context) { + string username = null; + if (context.User.Identity.IsAuthenticated) { + username = context.User.Identity.Name; + } + return username ?? string.Empty; + } + + /// <summary> /// Validates the request against XSRF attack. /// </summary> /// <param name="sessionId">The session id embedded in the query string.</param> @@ -252,24 +274,45 @@ namespace DotNetOpenAuth.AspNet { /// <c>true</c> if the request is safe. Otherwise, <c>false</c>. /// </returns> private bool ValidateRequestAgainstXsrfAttack(out string sessionId) { + sessionId = null; + // get the session id query string parameter string queryStringSessionId = this.requestContext.Request.QueryString[SessionIdQueryStringName]; // verify that the query string value is a valid guid Guid guid; if (!Guid.TryParse(queryStringSessionId, out guid)) { - sessionId = null; return false; } - // get the cookie id query string parameter + // the cookie value should be the current username secured against this guid var cookie = this.requestContext.Request.Cookies[SessionIdCookieName]; + if (cookie == null || string.IsNullOrEmpty(cookie.Value)) { + return false; + } + + // extract the username embedded within the cookie + // if there is any error at all (crypto, malformed, etc.), fail gracefully + string usernameInCookie = null; + try { + byte[] encryptedCookieBytes = HttpServerUtility.UrlTokenDecode(cookie.Value); + byte[] decryptedCookieBytes = MachineKeyUtil.Unprotect(encryptedCookieBytes, AntiXsrfPurposeString, "Token: " + queryStringSessionId); + usernameInCookie = Encoding.UTF8.GetString(decryptedCookieBytes); + } + catch { + return false; + } - bool successful = cookie != null && queryStringSessionId == cookie.Value; + string currentUsername = GetUsername(this.requestContext); + bool successful = string.Equals(currentUsername, usernameInCookie, StringComparison.OrdinalIgnoreCase); if (successful) { // be a good citizen, clean up cookie when the authentication succeeds - this.requestContext.Response.Cookies.Remove(SessionIdCookieName); + var xsrfCookie = new HttpCookie(SessionIdCookieName, string.Empty) { + HttpOnly = true, + Expires = DateTime.Now.AddYears(-1) + }; + this.requestContext.Response.Cookies.Set(xsrfCookie); } sessionId = queryStringSessionId; diff --git a/src/DotNetOpenAuth.AspNet/UriHelper.cs b/src/DotNetOpenAuth.AspNet/UriHelper.cs index 602f00c..bdf2ed0 100644 --- a/src/DotNetOpenAuth.AspNet/UriHelper.cs +++ b/src/DotNetOpenAuth.AspNet/UriHelper.cs @@ -21,7 +21,8 @@ namespace DotNetOpenAuth.AspNet { /// The url. /// </param> /// <param name="parameterName"> - /// The parameter name. + /// The parameter name. This value should not be provided by an end user; the caller should + /// ensure that this value comes only from a literal string. /// </param> /// <param name="parameterValue"> /// The parameter value. diff --git a/src/DotNetOpenAuth/DotNetOpenAuth.proj b/src/DotNetOpenAuth/DotNetOpenAuth.proj index 1116119..8c9610d 100644 --- a/src/DotNetOpenAuth/DotNetOpenAuth.proj +++ b/src/DotNetOpenAuth/DotNetOpenAuth.proj @@ -17,7 +17,7 @@ </PropertyGroup> <ItemGroup> - <ProjectReference Include="@(ProductProjects)"> + <ProjectReference Include="stub.csproj;@(ProductProjects)"> <PrimaryProductOutput Condition=" '%(MergeIntoUnifiedAssembly)' != 'false' ">true</PrimaryProductOutput> </ProjectReference> <SignDependsOn Include="BuildUnifiedProduct" /> @@ -58,16 +58,19 @@ <MakeDir Directories="$(ILMergeOutputAssemblyDirectory)" /> <Message Text="Merging $(ILMergeOutputAssembly)" Importance="high" /> - <!-- Arrange for DNOA.Core to appear *last* in the input assemblies list so that its assembly attributes overrides the rest. --> + <!-- Arrange for DNOA.Core to appear *last* in the input assemblies list so that its assembly attributes overrides the rest. + Also, this project's output must appear *first* in the list so that ILMerge will use its PE Header as the final one, + allowing file Properties in Windows Explorer to show DotNetOpenAuth.dll as the "Original Filename" along with other properties. --> <ItemGroup> - <ILMergeProductInputCoreAssembly Include="@(ILMergeProductInputAssemblies)" Condition=" '%(Filename)' == 'DotNetOpenAuth.Core' " /> - <ILMergeProductInputAssemblies Remove="@(ILMergeProductInputCoreAssembly)" /> - <ILMergeProductInputAssemblies Include="@(ILMergeProductInputCoreAssembly)" /> + <OrderedMergeInputAssemblies Include="@(ILMergeProductInputAssemblies)" Condition=" '%(ILMergeProductInputAssemblies.FileName)' == 'DotNetOpenAuth' " /> + <OrderedMergeInputAssemblies Include="@(ILMergeProductInputAssemblies)" Condition=" '%(ILMergeProductInputAssemblies.FileName)' != 'DotNetOpenAuth.Core' and '%(ILMergeProductInputAssemblies.FileName)' != 'DotNetOpenAuth' " /> + <OrderedMergeInputAssemblies Include="@(ILMergeInputAssemblies)" /> + <OrderedMergeInputAssemblies Include="@(ILMergeProductInputAssemblies)" Condition=" '%(ILMergeProductInputAssemblies.FileName)' == 'DotNetOpenAuth.Core' " /> </ItemGroup> <ILMerge ExcludeFile="$(ProjectRoot)ILMergeInternalizeExceptions.txt" - InputAssemblies="@(ILMergeInputAssemblies);@(ILMergeProductInputAssemblies)" + InputAssemblies="@(OrderedMergeInputAssemblies)" OutputFile="$(ILMergeOutputAssembly)" SearchDirectories="@(ILMergeSearchDirectories)" KeyFile="$(PublicKeyFile)" diff --git a/src/DotNetOpenAuth/Properties/AssemblyInfo.cs b/src/DotNetOpenAuth/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..eb429c2 --- /dev/null +++ b/src/DotNetOpenAuth/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------- +// <copyright file="AssemblyInfo.cs" company="Outercurve Foundation"> +// Copyright (c) Outercurve Foundation. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +// We DON'T put an AssemblyVersionAttribute in here because it is generated in the build. + +using System; +using System.Net; +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Security; +using System.Security.Permissions; +using System.Web.UI; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("DotNetOpenAuth")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("DotNetOpenAuth")] +[assembly: AssemblyCopyright("Copyright © 2011 Outercurve Foundation")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: NeutralResourcesLanguage("en-US")] +[assembly: CLSCompliant(true)] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("AB72ED33-1B74-4433-B524-982101D353A1")] + +#if StrongNameSigned +// See comment at top of this file. We need this so that strong-naming doesn't +// keep this assembly from being useful to shared host (medium trust) web sites. +[assembly: AllowPartiallyTrustedCallers] + +[assembly: InternalsVisibleTo("DotNetOpenAuth.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100AD093C3765257C89A7010E853F2C7C741FF92FA8ACE06D7B8254702CAD5CF99104447F63AB05F8BB6F51CE0D81C8C93D2FCE8C20AAFF7042E721CBA16EAAE98778611DED11C0ABC8900DC5667F99B50A9DADEC24DBD8F2C91E3E8AD300EF64F1B4B9536CEB16FB440AF939F57624A9B486F867807C649AE4830EAB88C6C03998")] +[assembly: InternalsVisibleTo("DotNetOpenAuth.AspNet.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100AD093C3765257C89A7010E853F2C7C741FF92FA8ACE06D7B8254702CAD5CF99104447F63AB05F8BB6F51CE0D81C8C93D2FCE8C20AAFF7042E721CBA16EAAE98778611DED11C0ABC8900DC5667F99B50A9DADEC24DBD8F2C91E3E8AD300EF64F1B4B9536CEB16FB440AF939F57624A9B486F867807C649AE4830EAB88C6C03998")] +[assembly: InternalsVisibleTo("DotNetOpenAuth.AspNet, PublicKey=0024000004800000940000000602000000240000525341310004000001000100AD093C3765257C89A7010E853F2C7C741FF92FA8ACE06D7B8254702CAD5CF99104447F63AB05F8BB6F51CE0D81C8C93D2FCE8C20AAFF7042E721CBA16EAAE98778611DED11C0ABC8900DC5667F99B50A9DADEC24DBD8F2C91E3E8AD300EF64F1B4B9536CEB16FB440AF939F57624A9B486F867807C649AE4830EAB88C6C03998")] +[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] +#else +[assembly: InternalsVisibleTo("DotNetOpenAuth.Test")] +[assembly: InternalsVisibleTo("DotNetOpenAuth.AspNet.Test")] +[assembly: InternalsVisibleTo("DotNetOpenAuth.AspNet")] +[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] +#endif diff --git a/src/DotNetOpenAuth/Stub.csproj b/src/DotNetOpenAuth/Stub.csproj new file mode 100644 index 0000000..713639e --- /dev/null +++ b/src/DotNetOpenAuth/Stub.csproj @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))\EnlistmentInfo.props" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))' != '' " /> + + <PropertyGroup> + <SuppressBuildTarget>true</SuppressBuildTarget> + <AddContractsAssemblyForDelaySigning>false</AddContractsAssemblyForDelaySigning> + </PropertyGroup> + + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + </PropertyGroup> + <Import Project="$(ProjectRoot)tools\DotNetOpenAuth.props" /> + <PropertyGroup> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{7BAB551D-768A-4C34-9D9D-8299DEDFF778}</ProjectGuid> + <AppDesignerFolder>Properties</AppDesignerFolder> + <AssemblyName>DotNetOpenAuth</AssemblyName> + <OutputPath>$(IntermediatePath)\stub\</OutputPath> + <NoCodeContracts>true</NoCodeContracts> + </PropertyGroup> + <Import Project="$(ProjectRoot)tools\DotNetOpenAuth.Product.props" /> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + </PropertyGroup> + <ItemGroup> + <Compile Include="Properties\AssemblyInfo.cs" /> + </ItemGroup> + + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <Import Project="$(ProjectRoot)tools\DotNetOpenAuth.targets" /> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))\EnlistmentInfo.targets" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))' != '' " /> +</Project>
\ No newline at end of file |