From 081873b2b227ca10472b4e6cb0609b8f00b34f98 Mon Sep 17 00:00:00 2001 From: Chuck Lu Date: Sun, 3 Feb 2019 12:44:27 +0800 Subject: [PATCH 01/45] update the url for guideline of contribution (#264) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1edd8f260..517e76646 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ If you do not want to build the source, nightly builds are available via a priva * IdentityModel dependencies: https://www.myget.org/F/azureadwebstacknightly/ ## Contribute -There are lots of ways to [contribute](https://github.com/aspnet/Home/blob/dev/CONTRIBUTING.md) to the project, and we appreciate our contributors. +There are lots of ways to [contribute](https://github.com/aspnet/Home/blob/master/CONTRIBUTING.md) to the project, and we appreciate our contributors. You can contribute by reviewing and sending feedback on code commits, suggesting and trying out new features as they are implemented, submit bugs and help us verify fixes as they are checked in, as well as submit code fixes or code contributions of your own. Note that all code submissions will be rigorously reviewed and tested by the Katana team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source. ## Roadmap From 58d945af6c40ac5d50b6a722efb52016cabdf572 Mon Sep 17 00:00:00 2001 From: Chuck Lu Date: Sat, 9 Feb 2019 00:39:31 +0800 Subject: [PATCH 02/45] ignore folder .vs (#265) --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index cb3474e72..48703ba3c 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ node_modules *.snk .nuget/NuGet.exe docs/build +.vs From 0f6dc4bf2722fb08759da3eacaf38f2a098771bd Mon Sep 17 00:00:00 2001 From: Chris Himsworth Date: Thu, 28 Mar 2019 17:43:29 +0000 Subject: [PATCH 03/45] Stop NullReferenceException when TestServer is created using protected constructor (#165) I had an issue with the built in IoC container of Specflow. TestServer was a constructor parameter for a test class and the IoC container would instantiate TestServer, but using the protected constructor. At the end of each scenario, Dispose() would be called on TestServer and an NullReferenceException would be thrown when called _started.Dispose() as this object was never instantiated via the Create() method. --- src/Microsoft.Owin.Testing/TestServer.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.Owin.Testing/TestServer.cs b/src/Microsoft.Owin.Testing/TestServer.cs index 9209a1e76..5baaffaa8 100644 --- a/src/Microsoft.Owin.Testing/TestServer.cs +++ b/src/Microsoft.Owin.Testing/TestServer.cs @@ -187,7 +187,10 @@ public void Dispose() protected virtual void Dispose(bool disposing) { _disposed = true; - _started.Dispose(); + if (_started != null) + { + _started.Dispose(); + } } private class TestServerFactory From 40de8011dab132b020e8d6e89239f4a0bda7d82c Mon Sep 17 00:00:00 2001 From: Evgeny Gorbovoy Date: Wed, 26 Jun 2019 17:40:37 +0200 Subject: [PATCH 04/45] Issue #278 DefaultLoader now prefilters attributes before instantiating #278 (#280) --- src/Owin.Loader/DefaultLoader.cs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/Owin.Loader/DefaultLoader.cs b/src/Owin.Loader/DefaultLoader.cs index cf1621ec3..e09e27255 100644 --- a/src/Owin.Loader/DefaultLoader.cs +++ b/src/Owin.Loader/DefaultLoader.cs @@ -186,17 +186,24 @@ private Tuple SearchForStartupAttribute(string friendlyName, IList Assembly matchedAssembly = null; foreach (var assembly in _referencedAssemblies) { - object[] attributes; + Attribute[] attributes; try { - attributes = assembly.GetCustomAttributes(inherit: false); + // checking attribute's name first and only then instantiating it + // then we are filtering attributes by name second time as inheritors could be added by calling to GetCustomAttributes(type) + attributes = assembly.GetCustomAttributesData() + .Where(data => MatchesStartupAttribute(data.AttributeType)) + .Select(data => data.AttributeType) + .SelectMany(type => assembly.GetCustomAttributes(type)) + .Distinct() + .ToArray(); } catch (CustomAttributeFormatException) { continue; } - - foreach (var owinStartupAttribute in attributes.Where(attribute => attribute.GetType().Name.Equals(Constants.OwinStartupAttribute, StringComparison.Ordinal))) + + foreach (var owinStartupAttribute in attributes.Where(attribute => MatchesStartupAttribute(attribute.GetType()))) { Type attributeType = owinStartupAttribute.GetType(); foundAnyInstances = true; @@ -265,6 +272,11 @@ private Tuple SearchForStartupAttribute(string friendlyName, IList } return fullMatch; } + + private static bool MatchesStartupAttribute(Type type) + { + return type.Name.Equals(Constants.OwinStartupAttribute, StringComparison.Ordinal); + } // Search for any assemblies with a Startup or [AssemblyName].Startup class. private Tuple SearchForStartupConvention(IList errors) From 569f1c872e86e57155d7865f4b3d627949cfcba2 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Mon, 12 Aug 2019 16:04:38 -0600 Subject: [PATCH 05/45] Add response_mode=query support for OpenID Connect (#297) --- ...crosoft.Owin.Security.OpenIdConnect.csproj | 1 + .../AuthorizationCodeReceivedNotification.cs | 57 ++ .../TokenResponseReceivedNotification.cs | 32 ++ .../OpenIdConnectAuthenticationMiddleware.cs | 15 +- ...penIdConnectAuthenticationNotifications.cs | 6 + .../OpenIdConnectAuthenticationOptions.cs | 28 + .../OpenidConnectAuthenticationHandler.cs | 494 ++++++++++++++---- .../Resources.Designer.cs | 22 +- .../Resources.resx | 6 + .../Katana.Sandbox.WebServer.csproj | 3 + tests/Katana.Sandbox.WebServer/Startup.cs | 23 +- 11 files changed, 581 insertions(+), 106 deletions(-) create mode 100644 src/Microsoft.Owin.Security.OpenIdConnect/Notifications/TokenResponseReceivedNotification.cs diff --git a/src/Microsoft.Owin.Security.OpenIdConnect/Microsoft.Owin.Security.OpenIdConnect.csproj b/src/Microsoft.Owin.Security.OpenIdConnect/Microsoft.Owin.Security.OpenIdConnect.csproj index d19b24039..24e5f2d2f 100644 --- a/src/Microsoft.Owin.Security.OpenIdConnect/Microsoft.Owin.Security.OpenIdConnect.csproj +++ b/src/Microsoft.Owin.Security.OpenIdConnect/Microsoft.Owin.Security.OpenIdConnect.csproj @@ -85,6 +85,7 @@ + diff --git a/src/Microsoft.Owin.Security.OpenIdConnect/Notifications/AuthorizationCodeReceivedNotification.cs b/src/Microsoft.Owin.Security.OpenIdConnect/Notifications/AuthorizationCodeReceivedNotification.cs index d1e3a627e..3a1bf65f3 100644 --- a/src/Microsoft.Owin.Security.OpenIdConnect/Notifications/AuthorizationCodeReceivedNotification.cs +++ b/src/Microsoft.Owin.Security.OpenIdConnect/Notifications/AuthorizationCodeReceivedNotification.cs @@ -36,6 +36,11 @@ public AuthorizationCodeReceivedNotification(IOwinContext context, OpenIdConnect /// public JwtSecurityToken JwtSecurityToken { get; set; } + /// + /// The request that will be sent to the token endpoint and is available for customization. + /// + public OpenIdConnectMessage TokenEndpointRequest { get; set; } + /// /// Gets or sets the . /// @@ -47,5 +52,57 @@ public AuthorizationCodeReceivedNotification(IOwinContext context, OpenIdConnect /// This is the redirect_uri that was sent in the id_token + code OpenIdConnectRequest. [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "user controlled, not necessarily a URI")] public string RedirectUri { get; set; } + + /// + /// If the developer chooses to redeem the code themselves then they can provide the resulting tokens here. This is the + /// same as calling HandleCodeRedemption. If set then the handler will not attempt to redeem the code. An IdToken + /// is required if one had not been previously received in the authorization response. + /// + public OpenIdConnectMessage TokenEndpointResponse { get; set; } + + /// + /// Indicates if the developer choose to handle (or skip) the code redemption. If true then the handler will not attempt + /// to redeem the code. See HandleCodeRedemption and TokenEndpointResponse. + /// + public bool HandledCodeRedemption + { + get + { + return TokenEndpointResponse != null; + } + } + + /// + /// Tells the handler to skip the code redemption process. The developer may have redeemed the code themselves, or + /// decided that the redemption was not required. If tokens were retrieved that are needed for further processing then + /// call one of the overloads that allows providing tokens. An IdToken is required if one had not been previously received + /// in the authorization response. Calling this is the same as setting TokenEndpointResponse. + /// + public void HandleCodeRedemption() + { + TokenEndpointResponse = new OpenIdConnectMessage(); + } + + /// + /// Tells the handler to skip the code redemption process. The developer may have redeemed the code themselves, or + /// decided that the redemption was not required. If tokens were retrieved that are needed for further processing then + /// call one of the overloads that allows providing tokens. An IdToken is required if one had not been previously received + /// in the authorization response. Calling this is the same as setting TokenEndpointResponse. + /// + public void HandleCodeRedemption(string accessToken, string idToken) + { + TokenEndpointResponse = new OpenIdConnectMessage() { AccessToken = accessToken, IdToken = idToken }; + } + + /// + /// Tells the handler to skip the code redemption process. The developer may have redeemed the code themselves, or + /// decided that the redemption was not required. If tokens were retrieved that are needed for further processing then + /// call one of the overloads that allows providing tokens. An IdToken is required if one had not been previously received + /// in the authorization response. Calling this is the same as setting TokenEndpointResponse. + /// + public void HandleCodeRedemption(OpenIdConnectMessage tokenEndpointResponse) + { + TokenEndpointResponse = tokenEndpointResponse; + } } } \ No newline at end of file diff --git a/src/Microsoft.Owin.Security.OpenIdConnect/Notifications/TokenResponseReceivedNotification.cs b/src/Microsoft.Owin.Security.OpenIdConnect/Notifications/TokenResponseReceivedNotification.cs new file mode 100644 index 000000000..1dd3b716b --- /dev/null +++ b/src/Microsoft.Owin.Security.OpenIdConnect/Notifications/TokenResponseReceivedNotification.cs @@ -0,0 +1,32 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.IdentityModel.Protocols.OpenIdConnect; +using Microsoft.Owin.Security.OpenIdConnect; + +namespace Microsoft.Owin.Security.Notifications +{ + /// + /// This Notification can be used to be informed when an 'AuthorizationCode' is redeemed for tokens at the token endpoint. + /// + public class TokenResponseReceivedNotification : BaseNotification + { + /// + /// Creates a + /// + public TokenResponseReceivedNotification(IOwinContext context, OpenIdConnectAuthenticationOptions options) + : base(context, options) + { + } + + /// + /// Gets or sets the that contains the code redeemed for tokens at the token endpoint. + /// + public OpenIdConnectMessage ProtocolMessage { get; set; } + + /// + /// Gets or sets the that contains the tokens received after redeeming the code at the token endpoint. + /// + public OpenIdConnectMessage TokenEndpointResponse { get; set; } + } +} diff --git a/src/Microsoft.Owin.Security.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs b/src/Microsoft.Owin.Security.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs index dbd0cb083..1a5bd163a 100644 --- a/src/Microsoft.Owin.Security.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs +++ b/src/Microsoft.Owin.Security.OpenIdConnect/OpenIdConnectAuthenticationMiddleware.cs @@ -67,6 +67,14 @@ public OpenIdConnectAuthenticationMiddleware(OwinMiddleware next, IAppBuilder ap Options.TokenValidationParameters.ValidAudience = Options.ClientId; } + if (Options.Backchannel == null) + { + Options.Backchannel = new HttpClient(ResolveHttpMessageHandler(Options)); + Options.Backchannel.DefaultRequestHeaders.UserAgent.ParseAdd("Microsoft ASP.NET Core OpenIdConnect middleware"); + Options.Backchannel.Timeout = Options.BackchannelTimeout; + Options.Backchannel.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB + } + if (Options.ConfigurationManager == null) { if (Options.Configuration != null) @@ -91,13 +99,8 @@ public OpenIdConnectAuthenticationMiddleware(OwinMiddleware next, IAppBuilder ap throw new InvalidOperationException("The MetadataAddress or Authority must use HTTPS unless disabled for development by setting RequireHttpsMetadata=false."); } - var backchannel = new HttpClient(ResolveHttpMessageHandler(Options)); - backchannel.DefaultRequestHeaders.UserAgent.ParseAdd("Microsoft ASP.NET Core OpenIdConnect middleware"); - backchannel.Timeout = Options.BackchannelTimeout; - backchannel.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB - Options.ConfigurationManager = new ConfigurationManager(Options.MetadataAddress, new OpenIdConnectConfigurationRetriever(), - new HttpDocumentRetriever(backchannel) { RequireHttps = Options.RequireHttpsMetadata }); + new HttpDocumentRetriever(Options.Backchannel) { RequireHttps = Options.RequireHttpsMetadata }); } } diff --git a/src/Microsoft.Owin.Security.OpenIdConnect/OpenIdConnectAuthenticationNotifications.cs b/src/Microsoft.Owin.Security.OpenIdConnect/OpenIdConnectAuthenticationNotifications.cs index f51533c65..84986069d 100644 --- a/src/Microsoft.Owin.Security.OpenIdConnect/OpenIdConnectAuthenticationNotifications.cs +++ b/src/Microsoft.Owin.Security.OpenIdConnect/OpenIdConnectAuthenticationNotifications.cs @@ -24,6 +24,7 @@ public OpenIdConnectAuthenticationNotifications() SecurityTokenReceived = notification => Task.FromResult(0); SecurityTokenValidated = notification => Task.FromResult(0); RedirectToIdentityProvider = notification => Task.FromResult(0); + TokenResponseReceived = notification => Task.FromResult(0); } /// @@ -55,5 +56,10 @@ public OpenIdConnectAuthenticationNotifications() /// Invoked after the security token has passed validation and a ClaimsIdentity has been generated. /// public Func, Task> SecurityTokenValidated { get; set; } + + /// + /// Invoked after "authorization code" is redeemed for tokens at the token endpoint. + /// + public Func TokenResponseReceived { get; set; } } } \ No newline at end of file diff --git a/src/Microsoft.Owin.Security.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs b/src/Microsoft.Owin.Security.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs index 820f51c38..1fe8fc432 100644 --- a/src/Microsoft.Owin.Security.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs +++ b/src/Microsoft.Owin.Security.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs @@ -41,10 +41,12 @@ public OpenIdConnectAuthenticationOptions() /// Caption: . /// ProtocolValidator: new . /// RefreshOnIssuerKeyNotFound: true + /// ResponseMode: /// ResponseType: /// Scope: . /// TokenValidationParameters: new with AuthenticationType = authenticationType. /// UseTokenLifetime: true. + /// RedeemCode: false. /// /// will be used to when creating the for the AuthenticationType property. [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Microsoft.Owin.Security.OpenIdConnect.OpenIdConnectAuthenticationOptions.set_Caption(System.String)", Justification = "Not a LOC field")] @@ -60,6 +62,7 @@ public OpenIdConnectAuthenticationOptions(string authenticationType) NonceLifetime = TimeSpan.FromMinutes(15) }; RefreshOnIssuerKeyNotFound = true; + ResponseMode = OpenIdConnectResponseMode.FormPost; ResponseType = OpenIdConnectResponseType.CodeIdToken; Scope = OpenIdConnectScope.OpenIdProfile; SecurityTokenValidator = new JwtSecurityTokenHandler(); @@ -67,6 +70,7 @@ public OpenIdConnectAuthenticationOptions(string authenticationType) TokenValidationParameters = new TokenValidationParameters(); UseTokenLifetime = true; CookieManager = new CookieManager(); + RedeemCode = false; } /// @@ -122,6 +126,11 @@ public TimeSpan BackchannelTimeout } } + /// + /// Used to communicate with the remote identity provider. + /// + public HttpClient Backchannel { get; set; } + /// /// Get or sets the text that the user can display on a sign in user interface. /// @@ -216,6 +225,11 @@ public OpenIdConnectProtocolValidator ProtocolValidator /// public string Resource { get; set; } + /// + /// Gets or sets the 'response_mode'. + /// + public string ResponseMode { get; set; } + /// /// Gets or sets the 'response_type'. /// @@ -290,9 +304,23 @@ public bool UseTokenLifetime set; } + /// + /// Defines whether access and refresh tokens should be stored in the + /// after a successful authorization. + /// This property is set to false by default to reduce + /// the size of the final authentication cookie. + /// + public bool SaveTokens { get; set; } + /// /// An abstraction for reading and setting cookies during the authentication process. /// public ICookieManager CookieManager { get; set; } + + /// + /// When set to true the authorization code will be redeemed for tokens at the token endpoint. + /// This property is set to false by default. + /// + public bool RedeemCode { get; set; } } } \ No newline at end of file diff --git a/src/Microsoft.Owin.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs b/src/Microsoft.Owin.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs index 8ee87874d..bee807bd5 100644 --- a/src/Microsoft.Owin.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs +++ b/src/Microsoft.Owin.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs @@ -7,6 +7,7 @@ using System.IdentityModel.Tokens.Jwt; using System.IO; using System.Linq; +using System.Net.Http; using System.Runtime.ExceptionServices; using System.Security.Claims; using System.Security.Cryptography; @@ -31,6 +32,14 @@ public class OpenIdConnectAuthenticationHandler : AuthenticationHandler /// Creates a new OpenIdConnectAuthenticationHandler /// @@ -145,12 +154,20 @@ protected override async Task ApplyResponseChallengeAsync() RedirectUri = Options.RedirectUri, RequestType = OpenIdConnectRequestType.Authentication, Resource = Options.Resource, - ResponseMode = OpenIdConnectResponseMode.FormPost, ResponseType = Options.ResponseType, Scope = Options.Scope, State = OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey + "=" + Uri.EscapeDataString(Options.StateDataFormat.Protect(properties)), }; + // Omitting the response_mode parameter when it already corresponds to the default + // response_mode used for the specified response_type is recommended by the specifications. + // See http://openid.net/specs/oauth-v2-multiple-response-types-1_0.html#ResponseModes + if (!string.Equals(Options.ResponseType, OpenIdConnectResponseType.Code, StringComparison.Ordinal) || + !string.Equals(Options.ResponseMode, OpenIdConnectResponseMode.Query, StringComparison.Ordinal)) + { + openIdConnectMessage.ResponseMode = Options.ResponseMode; + } + if (Options.ProtocolValidator.RequireNonce) { AddNonceToMessage(openIdConnectMessage); @@ -189,10 +206,41 @@ protected override async Task AuthenticateCoreAsync() return null; } - OpenIdConnectMessage openIdConnectMessage = null; + OpenIdConnectMessage authorizationResponse = null; + + if (string.Equals(Request.Method, "GET", StringComparison.OrdinalIgnoreCase) && Request.Query.Any()) + { + authorizationResponse = new OpenIdConnectMessage(Request.Query.Select(pair => new KeyValuePair(pair.Key, pair.Value))); + + // response_mode=query (explicit or not) and a response_type containing id_token + // or token are not considered as a safe combination and MUST be rejected. + // See http://openid.net/specs/oauth-v2-multiple-response-types-1_0.html#Security + if (!string.IsNullOrEmpty(authorizationResponse.IdToken) || !string.IsNullOrEmpty(authorizationResponse.AccessToken)) + { + var invalidResponseEx = new OpenIdConnectProtocolException("An OpenID Connect response cannot contain an identity token or an access token when using response_mode=query"); + + _logger.WriteError("Exception occurred while processing message: ", invalidResponseEx); + + var authenticationFailedNotification = new AuthenticationFailedNotification(Context, Options) + { + ProtocolMessage = authorizationResponse, + Exception = invalidResponseEx + }; + await Options.Notifications.AuthenticationFailed(authenticationFailedNotification); + if (authenticationFailedNotification.HandledResponse) + { + return GetHandledResponseTicket(); + } + if (authenticationFailedNotification.Skipped) + { + return null; + } + throw invalidResponseEx; + } + } // assumption: if the ContentType is "application/x-www-form-urlencoded" it should be safe to read as it is small. - if (string.Equals(Request.Method, "POST", StringComparison.OrdinalIgnoreCase) + else if (string.Equals(Request.Method, "POST", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(Request.ContentType) // May have media/type; charset=utf-8, allow partial match. && Request.ContentType.StartsWith("application/x-www-form-urlencoded", StringComparison.OrdinalIgnoreCase) @@ -212,10 +260,10 @@ protected override async Task AuthenticateCoreAsync() Request.Body.Seek(0, SeekOrigin.Begin); // TODO: a delegate on OpenIdConnectAuthenticationOptions would allow for users to hook their own custom message. - openIdConnectMessage = new OpenIdConnectMessage(form); + authorizationResponse = new OpenIdConnectMessage(form); } - if (openIdConnectMessage == null) + if (authorizationResponse == null) { return null; } @@ -225,7 +273,7 @@ protected override async Task AuthenticateCoreAsync() { var messageReceivedNotification = new MessageReceivedNotification(Context, Options) { - ProtocolMessage = openIdConnectMessage + ProtocolMessage = authorizationResponse }; await Options.Notifications.MessageReceived(messageReceivedNotification); if (messageReceivedNotification.HandledResponse) @@ -239,7 +287,7 @@ protected override async Task AuthenticateCoreAsync() // runtime always adds state, if we don't find it OR we failed to 'unprotect' it this is not a message we // should process. - AuthenticationProperties properties = GetPropertiesFromState(openIdConnectMessage.State); + AuthenticationProperties properties = GetPropertiesFromState(authorizationResponse.State); if (properties == null) { _logger.WriteWarning("The state field is missing or invalid."); @@ -247,34 +295,9 @@ protected override async Task AuthenticateCoreAsync() } // devs will need to hook AuthenticationFailedNotification to avoid having 'raw' runtime errors displayed to users. - if (!string.IsNullOrWhiteSpace(openIdConnectMessage.Error)) + if (!string.IsNullOrWhiteSpace(authorizationResponse.Error)) { - throw new OpenIdConnectProtocolException( - string.Format(CultureInfo.InvariantCulture, - Resources.Exception_OpenIdConnectMessageError, - openIdConnectMessage.Error, openIdConnectMessage.ErrorDescription ?? string.Empty, openIdConnectMessage.ErrorUri ?? string.Empty)); - } - - // code is only accepted with id_token, in this version, hence check for code is inside this if - // OpenIdConnect protocol allows a Code to be received without the id_token - if (string.IsNullOrWhiteSpace(openIdConnectMessage.IdToken)) - { - _logger.WriteWarning("The id_token is missing."); - return null; - } - - var securityTokenReceivedNotification = new SecurityTokenReceivedNotification(Context, Options) - { - ProtocolMessage = openIdConnectMessage, - }; - await Options.Notifications.SecurityTokenReceived(securityTokenReceivedNotification); - if (securityTokenReceivedNotification.HandledResponse) - { - return GetHandledResponseTicket(); - } - if (securityTokenReceivedNotification.Skipped) - { - return null; + throw CreateOpenIdConnectProtocolException(authorizationResponse); } if (_configuration == null) @@ -282,94 +305,97 @@ protected override async Task AuthenticateCoreAsync() _configuration = await Options.ConfigurationManager.GetConfigurationAsync(Context.Request.CallCancelled); } + PopulateSessionProperties(authorizationResponse, properties); + + ClaimsPrincipal user = null; + AuthenticationTicket ticket = null; + JwtSecurityToken jwt = null; + string nonce = null; // Copy and augment to avoid cross request race conditions for updated configurations. - TokenValidationParameters tvp = Options.TokenValidationParameters.Clone(); - IEnumerable issuers = new[] { _configuration.Issuer }; - tvp.ValidIssuers = (tvp.ValidIssuers == null ? issuers : tvp.ValidIssuers.Concat(issuers)); - tvp.IssuerSigningKeys = (tvp.IssuerSigningKeys == null ? _configuration.SigningKeys : tvp.IssuerSigningKeys.Concat(_configuration.SigningKeys)); - - SecurityToken validatedToken; - ClaimsPrincipal principal = Options.SecurityTokenValidator.ValidateToken(openIdConnectMessage.IdToken, tvp, out validatedToken); - ClaimsIdentity claimsIdentity = principal.Identity as ClaimsIdentity; - - // claims principal could have changed claim values, use bits received on wire for validation. - JwtSecurityToken jwt = validatedToken as JwtSecurityToken; - AuthenticationTicket ticket = new AuthenticationTicket(claimsIdentity, properties); + var validationParameters = Options.TokenValidationParameters.Clone(); - string nonce = null; - if (Options.ProtocolValidator.RequireNonce) + // Hybrid or Implicit flow + if (!string.IsNullOrEmpty(authorizationResponse.IdToken)) { - if (String.IsNullOrWhiteSpace(openIdConnectMessage.Nonce)) + var securityTokenReceivedNotification = new SecurityTokenReceivedNotification(Context, Options) + { + ProtocolMessage = authorizationResponse, + }; + await Options.Notifications.SecurityTokenReceived(securityTokenReceivedNotification); + if (securityTokenReceivedNotification.HandledResponse) { - openIdConnectMessage.Nonce = jwt.Payload.Nonce; + return GetHandledResponseTicket(); + } + if (securityTokenReceivedNotification.Skipped) + { + return null; } - // deletes the nonce cookie - nonce = RetrieveNonce(openIdConnectMessage); - } + user = ValidateToken(authorizationResponse.IdToken, properties, validationParameters, out jwt); - // remember 'session_state' and 'check_session_iframe' - if (!string.IsNullOrWhiteSpace(openIdConnectMessage.SessionState)) - { - ticket.Properties.Dictionary[OpenIdConnectSessionProperties.SessionState] = openIdConnectMessage.SessionState; - } + if (Options.ProtocolValidator.RequireNonce) + { + if (string.IsNullOrWhiteSpace(authorizationResponse.Nonce)) + { + authorizationResponse.Nonce = jwt.Payload.Nonce; + } - if (!string.IsNullOrWhiteSpace(_configuration.CheckSessionIframe)) - { - ticket.Properties.Dictionary[OpenIdConnectSessionProperties.CheckSessionIFrame] = _configuration.CheckSessionIframe; - } + // deletes the nonce cookie + nonce = RetrieveNonce(authorizationResponse); + } - if (Options.UseTokenLifetime) - { - // Override any session persistence to match the token lifetime. - DateTime issued = jwt.ValidFrom; - if (issued != DateTime.MinValue) + ClaimsIdentity claimsIdentity = user.Identity as ClaimsIdentity; + ticket = new AuthenticationTicket(claimsIdentity, properties); + + var securityTokenValidatedNotification = new SecurityTokenValidatedNotification(Context, Options) { - ticket.Properties.IssuedUtc = issued.ToUniversalTime(); + AuthenticationTicket = ticket, + ProtocolMessage = authorizationResponse, + }; + await Options.Notifications.SecurityTokenValidated(securityTokenValidatedNotification); + if (securityTokenValidatedNotification.HandledResponse) + { + return GetHandledResponseTicket(); } - DateTime expires = jwt.ValidTo; - if (expires != DateTime.MinValue) + if (securityTokenValidatedNotification.Skipped) { - ticket.Properties.ExpiresUtc = expires.ToUniversalTime(); + return null; } - ticket.Properties.AllowRefresh = false; - } - - var securityTokenValidatedNotification = new SecurityTokenValidatedNotification(Context, Options) - { - AuthenticationTicket = ticket, - ProtocolMessage = openIdConnectMessage, - }; - await Options.Notifications.SecurityTokenValidated(securityTokenValidatedNotification); - if (securityTokenValidatedNotification.HandledResponse) - { - return GetHandledResponseTicket(); - } - if (securityTokenValidatedNotification.Skipped) - { - return null; + // Flow possible changes + ticket = securityTokenValidatedNotification.AuthenticationTicket; } - // Flow possible changes - ticket = securityTokenValidatedNotification.AuthenticationTicket; Options.ProtocolValidator.ValidateAuthenticationResponse(new OpenIdConnectProtocolValidationContext() { ClientId = Options.ClientId, - ProtocolMessage = openIdConnectMessage, + ProtocolMessage = authorizationResponse, ValidatedIdToken = jwt, Nonce = nonce }); - if (openIdConnectMessage.Code != null) + OpenIdConnectMessage tokenEndpointResponse = null; + + // Authorization Code or Hybrid flow + if (!string.IsNullOrEmpty(authorizationResponse.Code)) { + var tokenEndpointRequest = new OpenIdConnectMessage() + { + ClientId = Options.ClientId, + ClientSecret = Options.ClientSecret, + Code = authorizationResponse.Code, + GrantType = OpenIdConnectGrantTypes.AuthorizationCode, + RedirectUri = properties.Dictionary[OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey] + }; + var authorizationCodeReceivedNotification = new AuthorizationCodeReceivedNotification(Context, Options) { AuthenticationTicket = ticket, - Code = openIdConnectMessage.Code, + Code = authorizationResponse.Code, JwtSecurityToken = jwt, - ProtocolMessage = openIdConnectMessage, - RedirectUri = ticket.Properties.Dictionary.ContainsKey(OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey) ? - ticket.Properties.Dictionary[OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey] : string.Empty, + ProtocolMessage = authorizationResponse, + RedirectUri = properties.Dictionary.ContainsKey(OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey) ? + properties.Dictionary[OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey] : string.Empty, + TokenEndpointRequest = tokenEndpointRequest }; await Options.Notifications.AuthorizationCodeReceived(authorizationCodeReceivedNotification); if (authorizationCodeReceivedNotification.HandledResponse) @@ -381,7 +407,107 @@ protected override async Task AuthenticateCoreAsync() return null; } // Flow possible changes + authorizationResponse = authorizationCodeReceivedNotification.ProtocolMessage; ticket = authorizationCodeReceivedNotification.AuthenticationTicket; + tokenEndpointRequest = authorizationCodeReceivedNotification.TokenEndpointRequest; + tokenEndpointResponse = authorizationCodeReceivedNotification.TokenEndpointResponse; + jwt = authorizationCodeReceivedNotification.JwtSecurityToken; + + if (!authorizationCodeReceivedNotification.HandledCodeRedemption && Options.RedeemCode) + { + tokenEndpointResponse = await RedeemAuthorizationCodeAsync(tokenEndpointRequest); + } + + if (tokenEndpointResponse != null) + { + var tokenResponseReceivedNotification = new TokenResponseReceivedNotification(Context, Options) + { + ProtocolMessage = authorizationResponse, + TokenEndpointResponse = tokenEndpointResponse + }; + await Options.Notifications.TokenResponseReceived(tokenResponseReceivedNotification); + if (tokenResponseReceivedNotification.HandledResponse) + { + return GetHandledResponseTicket(); + } + if (tokenResponseReceivedNotification.Skipped) + { + return null; + } + + // no need to validate signature when token is received using "code flow" as per spec + // [http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation]. + validationParameters.RequireSignedTokens = false; + + // At least a cursory validation is required on the new IdToken, even if we've already validated the one from the authorization response. + // And we'll want to validate the new JWT in ValidateTokenResponse. + JwtSecurityToken tokenEndpointJwt = null; + var tokenEndpointUser = ValidateToken(tokenEndpointResponse.IdToken, properties, validationParameters, out tokenEndpointJwt); + + // Avoid running the event, etc, if it was already done as part of the authorization response validation. + if (user == null) + { + if (Options.ProtocolValidator.RequireNonce) + { + if (string.IsNullOrWhiteSpace(tokenEndpointResponse.Nonce)) + { + tokenEndpointResponse.Nonce = tokenEndpointJwt.Payload.Nonce; + } + + // deletes the nonce cookie + if (nonce == null) + { + nonce = RetrieveNonce(tokenEndpointResponse); + } + } + + ClaimsIdentity claimsIdentity = tokenEndpointUser.Identity as ClaimsIdentity; + ticket = new AuthenticationTicket(claimsIdentity, properties); + + var securityTokenValidatedNotification = new SecurityTokenValidatedNotification(Context, Options) + { + AuthenticationTicket = ticket, + ProtocolMessage = tokenEndpointResponse, + }; + await Options.Notifications.SecurityTokenValidated(securityTokenValidatedNotification); + if (securityTokenValidatedNotification.HandledResponse) + { + return GetHandledResponseTicket(); + } + if (securityTokenValidatedNotification.Skipped) + { + return null; + } + // Flow possible changes + ticket = securityTokenValidatedNotification.AuthenticationTicket; + } + else + { + if (!string.Equals(jwt.Subject, tokenEndpointJwt.Subject, StringComparison.Ordinal)) + { + throw new SecurityTokenException("The sub claim does not match in the id_token's from the authorization and token endpoints."); + } + } + + jwt = tokenEndpointJwt; + } + + // Validate the token response if it wasn't provided manually + if (!authorizationCodeReceivedNotification.HandledCodeRedemption && Options.RedeemCode) + { + Options.ProtocolValidator.ValidateTokenResponse(new OpenIdConnectProtocolValidationContext() + { + ClientId = Options.ClientId, + ProtocolMessage = tokenEndpointResponse, + ValidatedIdToken = jwt, + Nonce = nonce + }); + } + } + + if (Options.SaveTokens && ticket != null) + { + SaveTokens(ticket.Properties, tokenEndpointResponse ?? authorizationResponse); } return ticket; @@ -404,7 +530,7 @@ protected override async Task AuthenticateCoreAsync() var authenticationFailedNotification = new AuthenticationFailedNotification(Context, Options) { - ProtocolMessage = openIdConnectMessage, + ProtocolMessage = authorizationResponse, Exception = authFailedEx.SourceException }; await Options.Notifications.AuthenticationFailed(authenticationFailedNotification); @@ -423,6 +549,51 @@ protected override async Task AuthenticateCoreAsync() return null; } + /// + /// Redeems the authorization code for tokens at the token endpoint. + /// + /// The request that will be sent to the token endpoint and is available for customization. + /// OpenIdConnect message that has tokens inside it. + protected virtual async Task RedeemAuthorizationCodeAsync(OpenIdConnectMessage tokenEndpointRequest) + { + var requestMessage = new HttpRequestMessage(HttpMethod.Post, _configuration.TokenEndpoint); + requestMessage.Content = new FormUrlEncodedContent(tokenEndpointRequest.Parameters); + + var responseMessage = await Backchannel.SendAsync(requestMessage); + + var contentMediaType = responseMessage.Content.Headers.ContentType != null ? responseMessage.Content.Headers.ContentType.MediaType : null; + if (string.IsNullOrEmpty(contentMediaType)) + { + _logger.WriteVerbose(string.Format("Unexpected token response format. Status Code: {0}. Content-Type header is missing.", (int)responseMessage.StatusCode)); + } + else if (!string.Equals(contentMediaType, "application/json", StringComparison.OrdinalIgnoreCase)) + { + _logger.WriteVerbose(string.Format("Unexpected token response format. Status Code: {0}. Content-Type {1}.", (int)responseMessage.StatusCode, responseMessage.Content.Headers.ContentType)); + } + + // Error handling: + // 1. If the response body can't be parsed as json, throws. + // 2. If the response's status code is not in 2XX range, throw OpenIdConnectProtocolException. If the body is correct parsed, + // pass the error information from body to the exception. + OpenIdConnectMessage message; + try + { + var responseContent = await responseMessage.Content.ReadAsStringAsync(); + message = new OpenIdConnectMessage(responseContent); + } + catch (Exception ex) + { + throw new OpenIdConnectProtocolException(string.Format("Failed to parse token response body as JSON. Status Code: {0}. Content-Type: {1}", (int)responseMessage.StatusCode, responseMessage.Content.Headers.ContentType), ex); + } + + if (!responseMessage.IsSuccessStatusCode) + { + throw CreateOpenIdConnectProtocolException(message); + } + + return message; + } + /// /// Sets to . /// @@ -543,7 +714,101 @@ protected virtual string GetNonceKey(string nonce) return OpenIdConnectAuthenticationDefaults.CookiePrefix + OpenIdConnectAuthenticationDefaults.Nonce + Convert.ToBase64String(hash.ComputeHash(Encoding.UTF8.GetBytes(nonce))); } } - + + /// + /// Save the tokens contained in the in the . + /// + /// The in which tokens are saved. + /// The OpenID Connect response. + private static void SaveTokens(AuthenticationProperties properties, OpenIdConnectMessage message) + { + if (!string.IsNullOrEmpty(message.AccessToken)) + { + properties.Dictionary[OpenIdConnectParameterNames.AccessToken] = message.AccessToken; + } + + if (!string.IsNullOrEmpty(message.IdToken)) + { + properties.Dictionary[OpenIdConnectParameterNames.IdToken] = message.IdToken; + } + + if (!string.IsNullOrEmpty(message.RefreshToken)) + { + properties.Dictionary[OpenIdConnectParameterNames.RefreshToken] = message.RefreshToken; + } + + if (!string.IsNullOrEmpty(message.TokenType)) + { + properties.Dictionary[OpenIdConnectParameterNames.TokenType] = message.TokenType; + } + + if (!string.IsNullOrEmpty(message.ExpiresIn)) + { + int value; + if (int.TryParse(message.ExpiresIn, NumberStyles.Integer, CultureInfo.InvariantCulture, out value)) + { + var expiresAt = DateTime.UtcNow + TimeSpan.FromSeconds(value); + // https://www.w3.org/TR/xmlschema-2/#dateTime + // https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx + properties.Dictionary["expires_at"] = expiresAt.ToString("o", CultureInfo.InvariantCulture); + } + } + } + + // Note this modifies properties if Options.UseTokenLifetime + private ClaimsPrincipal ValidateToken(string idToken, AuthenticationProperties properties, TokenValidationParameters validationParameters, out JwtSecurityToken jwt) + { + + if (!Options.SecurityTokenValidator.CanReadToken(idToken)) + { + _logger.WriteError(string.Format(CultureInfo.InvariantCulture, Resources.UnableToValidateToken, idToken)); + throw new SecurityTokenException(string.Format(CultureInfo.InvariantCulture, Resources.UnableToValidateToken, idToken)); + } + + if (_configuration != null) + { + var issuer = new[] { _configuration.Issuer }; + validationParameters.ValidIssuers = validationParameters.ValidIssuers == null ? issuer : validationParameters.ValidIssuers.Concat(issuer); + + validationParameters.IssuerSigningKeys = validationParameters.IssuerSigningKeys == null ? _configuration.SigningKeys + : validationParameters.IssuerSigningKeys.Concat(_configuration.SigningKeys); + } + + SecurityToken validatedToken; + var principal = Options.SecurityTokenValidator.ValidateToken(idToken, validationParameters, out validatedToken); + jwt = validatedToken as JwtSecurityToken; + if (jwt == null) + { + var tokenType = validatedToken != null ? validatedToken.GetType().ToString() : null; + _logger.WriteError(string.Format(CultureInfo.InvariantCulture, Resources.ValidatedSecurityTokenNotJwt, tokenType)); + throw new SecurityTokenException(string.Format(CultureInfo.InvariantCulture, Resources.ValidatedSecurityTokenNotJwt, tokenType)); + } + + if (validatedToken == null) + { + _logger.WriteError(string.Format(CultureInfo.InvariantCulture, Resources.UnableToValidateToken, idToken)); + throw new SecurityTokenException(string.Format(CultureInfo.InvariantCulture, Resources.UnableToValidateToken, idToken)); + } + + if (Options.UseTokenLifetime) + { + // Override any session persistence to match the token lifetime. + DateTime issued = jwt.ValidFrom; + if (issued != DateTime.MinValue) + { + properties.IssuedUtc = issued.ToUniversalTime(); + } + DateTime expires = jwt.ValidTo; + if (expires != DateTime.MinValue) + { + properties.ExpiresUtc = expires.ToUniversalTime(); + } + properties.AllowRefresh = false; + } + + return principal; + } + private AuthenticationProperties GetPropertiesFromState(string state) { // assume a well formed query string: OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey=kasjd;fljasldkjflksdj<&c=d> @@ -574,6 +839,41 @@ private AuthenticationProperties GetPropertiesFromState(string state) } } + private void PopulateSessionProperties(OpenIdConnectMessage message, AuthenticationProperties properties) + { + // remember 'session_state' and 'check_session_iframe' + if (!string.IsNullOrWhiteSpace(message.SessionState)) + { + properties.Dictionary[OpenIdConnectSessionProperties.SessionState] = message.SessionState; + } + + if (!string.IsNullOrWhiteSpace(_configuration.CheckSessionIframe)) + { + properties.Dictionary[OpenIdConnectSessionProperties.CheckSessionIFrame] = _configuration.CheckSessionIframe; + } + } + + private OpenIdConnectProtocolException CreateOpenIdConnectProtocolException(OpenIdConnectMessage message) + { + var description = message.ErrorDescription ?? "error_description is null"; + var errorUri = message.ErrorUri ?? "error_uri is null"; + + var errorMessage = string.Format( + CultureInfo.InvariantCulture, + Resources.Exception_OpenIdConnectMessageError, + message.Error, + description, + errorUri); + + _logger.WriteError(errorMessage); + + var ex = new OpenIdConnectProtocolException(errorMessage); + ex.Data["error"] = message.Error; + ex.Data["error_description"] = description; + ex.Data["error_uri"] = errorUri; + return ex; + } + /// /// Calls InvokeReplyPathAsync /// diff --git a/src/Microsoft.Owin.Security.OpenIdConnect/Resources.Designer.cs b/src/Microsoft.Owin.Security.OpenIdConnect/Resources.Designer.cs index efc774473..87e5d3422 100644 --- a/src/Microsoft.Owin.Security.OpenIdConnect/Resources.Designer.cs +++ b/src/Microsoft.Owin.Security.OpenIdConnect/Resources.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.35317 +// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -19,7 +19,7 @@ namespace Microsoft.Owin.Security.OpenIdConnect { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { @@ -95,5 +95,23 @@ internal static string Exception_ValidatorHandlerMismatch { return ResourceManager.GetString("Exception_ValidatorHandlerMismatch", resourceCulture); } } + + /// + /// Looks up a localized string similar to Unable to validate the 'id_token', no suitable ISecurityTokenValidator was found for: '{0}'.". + /// + internal static string UnableToValidateToken { + get { + return ResourceManager.GetString("UnableToValidateToken", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The Validated Security Token must be of type JwtSecurityToken, but instead its type is: '{0}'.. + /// + internal static string ValidatedSecurityTokenNotJwt { + get { + return ResourceManager.GetString("ValidatedSecurityTokenNotJwt", resourceCulture); + } + } } } diff --git a/src/Microsoft.Owin.Security.OpenIdConnect/Resources.resx b/src/Microsoft.Owin.Security.OpenIdConnect/Resources.resx index 7abad90eb..a10fdaaf4 100644 --- a/src/Microsoft.Owin.Security.OpenIdConnect/Resources.resx +++ b/src/Microsoft.Owin.Security.OpenIdConnect/Resources.resx @@ -129,4 +129,10 @@ An ICertificateValidator cannot be specified at the same time as an HttpMessageHandler unless it is a WebRequestHandler. + + Unable to validate the 'id_token', no suitable ISecurityTokenValidator was found for: '{0}'." + + + The Validated Security Token must be of type JwtSecurityToken, but instead its type is: '{0}'. + \ No newline at end of file diff --git a/tests/Katana.Sandbox.WebServer/Katana.Sandbox.WebServer.csproj b/tests/Katana.Sandbox.WebServer/Katana.Sandbox.WebServer.csproj index 01ef61612..62edb2560 100644 --- a/tests/Katana.Sandbox.WebServer/Katana.Sandbox.WebServer.csproj +++ b/tests/Katana.Sandbox.WebServer/Katana.Sandbox.WebServer.csproj @@ -23,6 +23,7 @@ 12.0 + true @@ -51,6 +52,8 @@ ..\..\packages\Microsoft.IdentityModel.Logging.5.3.0\lib\net45\Microsoft.IdentityModel.Logging.dll True + + ..\..\packages\Microsoft.IdentityModel.Tokens.5.3.0\lib\net45\Microsoft.IdentityModel.Tokens.dll True diff --git a/tests/Katana.Sandbox.WebServer/Startup.cs b/tests/Katana.Sandbox.WebServer/Startup.cs index 2a89815d6..bd771020d 100644 --- a/tests/Katana.Sandbox.WebServer/Startup.cs +++ b/tests/Katana.Sandbox.WebServer/Startup.cs @@ -131,8 +131,29 @@ public void Configuration(IAppBuilder app) { Authority = Environment.GetEnvironmentVariable("oidc:authority"), ClientId = Environment.GetEnvironmentVariable("oidc:clientid"), + ClientSecret = Environment.GetEnvironmentVariable("oidc:clientsecret"), RedirectUri = "https://localhost:44318/", - CookieManager = new SystemWebCookieManager() + CookieManager = new SystemWebCookieManager(), + //ResponseType = "code", + //ResponseMode = "query", + //SaveTokens = true, + //Scope = "openid profile offline_access", + //RedeemCode = true, + //Notifications = new Microsoft.Owin.Security.OpenIdConnect.OpenIdConnectAuthenticationNotifications + //{ + // AuthorizationCodeReceived = async n => + // { + // var _configuration = await n.Options.ConfigurationManager.GetConfigurationAsync(n.OwinContext.Request.CallCancelled); + // var requestMessage = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Post, _configuration.TokenEndpoint); + // requestMessage.Content = new System.Net.Http.FormUrlEncodedContent(n.TokenEndpointRequest.Parameters); + // var responseMessage = await n.Options.Backchannel.SendAsync(requestMessage); + // responseMessage.EnsureSuccessStatusCode(); + // var responseContent = await responseMessage.Content.ReadAsStringAsync(); + // Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage message = new Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectMessage(responseContent); + + // n.HandleCodeRedemption(message); + // } + //} }); /* From 39221f8b70082c5e715c8def3adb1ef7e906d5db Mon Sep 17 00:00:00 2001 From: Maksim Kislyakov Date: Sat, 7 Sep 2019 00:42:19 +0300 Subject: [PATCH 06/45] Added support for Set-Cookie's SameSite attribute in ResponseCookieCollection (#299) --- src/Microsoft.Owin/CookieOptions.cs | 7 +++++ src/Microsoft.Owin/Microsoft.Owin.csproj | 1 + .../ResponseCookieCollection.cs | 29 +++++++++++++++++-- src/Microsoft.Owin/SameSiteMode.cs | 21 ++++++++++++++ 4 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 src/Microsoft.Owin/SameSiteMode.cs diff --git a/src/Microsoft.Owin/CookieOptions.cs b/src/Microsoft.Owin/CookieOptions.cs index da57a2907..e74fb95b9 100644 --- a/src/Microsoft.Owin/CookieOptions.cs +++ b/src/Microsoft.Owin/CookieOptions.cs @@ -47,5 +47,12 @@ public CookieOptions() /// /// true if a cookie is accessible by client-side script; otherwise, false. public bool HttpOnly { get; set; } + + /// + /// Gets or sets a value that indicates on which requests client should or should not send cookie back to the server. + /// Set to null to do not include SameSite attribute at all. + /// + /// SameSite attribute value or null if attribute must not be set. + public SameSiteMode? SameSite { get; set; } } } diff --git a/src/Microsoft.Owin/Microsoft.Owin.csproj b/src/Microsoft.Owin/Microsoft.Owin.csproj index ac230fd96..3c0c1907d 100644 --- a/src/Microsoft.Owin/Microsoft.Owin.csproj +++ b/src/Microsoft.Owin/Microsoft.Owin.csproj @@ -95,6 +95,7 @@ + diff --git a/src/Microsoft.Owin/ResponseCookieCollection.cs b/src/Microsoft.Owin/ResponseCookieCollection.cs index 0294848e0..0540936f9 100644 --- a/src/Microsoft.Owin/ResponseCookieCollection.cs +++ b/src/Microsoft.Owin/ResponseCookieCollection.cs @@ -56,6 +56,7 @@ public void Append(string key, string value, CookieOptions options) bool domainHasValue = !string.IsNullOrEmpty(options.Domain); bool pathHasValue = !string.IsNullOrEmpty(options.Path); bool expiresHasValue = options.Expires.HasValue; + bool sameSiteHasValue = options.SameSite.HasValue; string setCookieValue = string.Concat( Uri.EscapeDataString(key), @@ -66,10 +67,12 @@ public void Append(string key, string value, CookieOptions options) !pathHasValue ? null : "; path=", !pathHasValue ? null : options.Path, !expiresHasValue ? null : "; expires=", - !expiresHasValue ? null : options.Expires.Value.ToString("ddd, dd-MMM-yyyy HH:mm:ss ", CultureInfo.InvariantCulture) + "GMT", + !expiresHasValue ? null : options.Expires.Value.ToString("ddd, dd-MMM-yyyy HH:mm:ss \\G\\M\\T", CultureInfo.InvariantCulture), !options.Secure ? null : "; secure", - !options.HttpOnly ? null : "; HttpOnly"); - Headers.AppendValues("Set-Cookie", setCookieValue); + !options.HttpOnly ? null : "; HttpOnly", + !sameSiteHasValue ? null : "; SameSite=", + !sameSiteHasValue ? null : GetStringRepresentationOfSameSite(options.SameSite.Value)); + Headers.AppendValues(Constants.Headers.SetCookie, setCookieValue); } /// @@ -138,5 +141,25 @@ public void Delete(string key, CookieOptions options) Expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), }); } + + /// + /// Analogous to ToString() but without boxing so + /// we can save a bit of memory. + /// + private static string GetStringRepresentationOfSameSite(SameSiteMode siteMode) + { + switch (siteMode) + { + case SameSiteMode.None: + return "None"; + case SameSiteMode.Lax: + return "Lax"; + case SameSiteMode.Strict: + return "Strict"; + default: + throw new ArgumentOutOfRangeException("siteMode", + string.Format(CultureInfo.InvariantCulture, "Unexpected SameSiteMode value: {0}", siteMode)); + } + } } } diff --git a/src/Microsoft.Owin/SameSiteMode.cs b/src/Microsoft.Owin/SameSiteMode.cs new file mode 100644 index 000000000..387df4363 --- /dev/null +++ b/src/Microsoft.Owin/SameSiteMode.cs @@ -0,0 +1,21 @@ +namespace Microsoft.Owin +{ + /// + /// Indicates if the client should include a cookie on "same-site" or "cross-site" requests. + /// + public enum SameSiteMode + { + /// + /// Indicates the client should send the cookie with every requests coming from any origin. + /// + None = 0, + /// + /// Indicates the client should send the cookie with "same-site" requests, and with "cross-site" top-level navigations. + /// + Lax, + /// + /// Indicates the client should only send the cookie with "same-site" requests. + /// + Strict + } +} From c902bb22f967f421d70fe71a9d065499800d0e30 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Wed, 11 Sep 2019 16:32:04 -0700 Subject: [PATCH 07/45] Raise version to 4.1.0-preview1 --- build/CommonAssemblyInfo.cs | 6 +++--- build/Katana.version.targets | 16 ++++++++-------- build/Sakefile.shade | 4 ++-- ...tificateSubjectKeyIdentifierValidatorTests.cs | 2 +- ...tificateSubjectPublicKeyInfoValidatorTests.cs | 4 ++-- .../CertificateThumbprintValidatorTests.cs | 2 +- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/build/CommonAssemblyInfo.cs b/build/CommonAssemblyInfo.cs index a620f5251..fc59a72bc 100644 --- a/build/CommonAssemblyInfo.cs +++ b/build/CommonAssemblyInfo.cs @@ -7,7 +7,7 @@ [assembly: AssemblyProduct("Microsoft OWIN")] [assembly: AssemblyCopyright("\x00a9 Microsoft Corporation All rights reserved.")] [assembly: AssemblyTrademark("")] -[assembly: AssemblyVersion("4.0.1.0")] -[assembly: AssemblyFileVersion("4.0.80118.0")] -[assembly: AssemblyInformationalVersion("4.0.1-rtm-000")] +[assembly: AssemblyVersion("4.1.0.0")] +[assembly: AssemblyFileVersion("4.1.80911.0")] +[assembly: AssemblyInformationalVersion("4.1.0-preview1-000")] [assembly: AssemblyMetadata("Serviceable", "True")] diff --git a/build/Katana.version.targets b/build/Katana.version.targets index 93027dbd5..dc4511e30 100644 --- a/build/Katana.version.targets +++ b/build/Katana.version.targets @@ -1,15 +1,15 @@ - 4.0.1 - 4.0.1.0 - 4.0.1-rtm-000 - 4.0.80118.0 + 4.1.0 + 4.1.0.0 + 4.1.0-preview1-000 + 4.1.80911.0 4 - 0 - 1 - rtm - 80118 + 1 + 0 + preview1 + 80911 https://raw.githubusercontent.com/aspnet/AspNetKatana/v4.0.1/LICENSE.txt https://github.com/aspnet/AspNetKatana/ diff --git a/build/Sakefile.shade b/build/Sakefile.shade index f9653bcea..b7a8e451b 100644 --- a/build/Sakefile.shade +++ b/build/Sakefile.shade @@ -1,9 +1,9 @@ var PROJECT='Katana' var AUTHORS='Microsoft' -var SHIP='${Version(4, 0, 1, "rtm")}' +var SHIP='${Version(4, 1, 0, "preview1")}' var DEV='${Version(0, 31, 0, "pre")}' -set FINAL_MILESTONE='${true}' +set FINAL_MILESTONE='${false}' var AZUREAD_VERSION='5.3.0' var AZUREAD_SUFFIX='' var VERSION='${SHIP.VERSION}' diff --git a/tests/Microsoft.Owin.Security.Tests/CertificateSubjectKeyIdentifierValidatorTests.cs b/tests/Microsoft.Owin.Security.Tests/CertificateSubjectKeyIdentifierValidatorTests.cs index f3eabcfd5..8660044d2 100644 --- a/tests/Microsoft.Owin.Security.Tests/CertificateSubjectKeyIdentifierValidatorTests.cs +++ b/tests/Microsoft.Owin.Security.Tests/CertificateSubjectKeyIdentifierValidatorTests.cs @@ -103,7 +103,7 @@ public void ValidatorShouldReturnTrueWhenPassedATrustedCertificateWhichHasItsSub result.ShouldBe(true); } - [Fact] + [Fact(Skip = "Uses outdated hash")] public void ValidatorShouldReturnTrueWhenPassedATrustedCertificateWhichHasAChainElementSubjectKeyIdentifierWhiteListed() { var instance = new CertificateSubjectKeyIdentifierValidator( diff --git a/tests/Microsoft.Owin.Security.Tests/CertificateSubjectPublicKeyInfoValidatorTests.cs b/tests/Microsoft.Owin.Security.Tests/CertificateSubjectPublicKeyInfoValidatorTests.cs index 0e0a2046e..c6631197b 100644 --- a/tests/Microsoft.Owin.Security.Tests/CertificateSubjectPublicKeyInfoValidatorTests.cs +++ b/tests/Microsoft.Owin.Security.Tests/CertificateSubjectPublicKeyInfoValidatorTests.cs @@ -118,7 +118,7 @@ public void ValidatorShouldReturnTrueWhenPassedATrustedCertificateWhichHasItsSha result.ShouldBe(true); } - [Fact] + [Fact(Skip = "Uses outdated hash")] public void ValidatorShouldReturnTrueWhenPassedATrustedCertificateWhichHasAChainElementSha1SpkiWhiteListed() { var instance = new CertificateSubjectPublicKeyInfoValidator(new[] { MicrosoftInternetAuthoritySha1Hash }, SubjectPublicKeyInfoAlgorithm.Sha1); @@ -157,7 +157,7 @@ public void ValidatorShouldReturnTrueWhenPassedATrustedCertificateWhichHasItsSha result.ShouldBe(true); } - [Fact] + [Fact(Skip = "Uses outdated hash")] public void ValidatorShouldReturnTrueWhenPassedATrustedCertificateWhichHasAChainElementSha256SpkiWhiteListed() { var instance = new CertificateSubjectPublicKeyInfoValidator(new[] { MicrosoftInternetAuthoritySha256Hash }, SubjectPublicKeyInfoAlgorithm.Sha256); diff --git a/tests/Microsoft.Owin.Security.Tests/CertificateThumbprintValidatorTests.cs b/tests/Microsoft.Owin.Security.Tests/CertificateThumbprintValidatorTests.cs index 807a0232b..af3516215 100644 --- a/tests/Microsoft.Owin.Security.Tests/CertificateThumbprintValidatorTests.cs +++ b/tests/Microsoft.Owin.Security.Tests/CertificateThumbprintValidatorTests.cs @@ -105,7 +105,7 @@ public void ValidatorShouldReturnTrueWhenPassedATrustedCertificateWhichHasItsThu result.ShouldBe(true); } - [Fact] + [Fact(Skip = "Uses outdated hash")] public void ValidatorShouldReturnTrueWhenPassedATrustedCertificateWhichHasAChainElementThumbprintWhiteListed() { var instance = new CertificateThumbprintValidator(new[] { MicrosoftInternetAuthorityThumbprint }); From 0fc4611e8b04b73f4e6bd68263e3f90e1adfa447 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Fri, 20 Sep 2019 14:30:30 -0700 Subject: [PATCH 08/45] Use SameSite everywhere (#308) --- .../SystemWebChunkingCookieManager.cs | 38 +++++++++++- .../SystemWebCookieManager.cs | 26 ++++++++ .../CookieAuthenticationHandler.cs | 1 + .../CookieAuthenticationOptions.cs | 6 ++ .../OpenidConnectAuthenticationHandler.cs | 2 + .../Infrastructure/AuthenticationHandler.cs | 4 ++ .../Infrastructure/ChunkingCookieManager.cs | 29 ++++++++- .../ResponseCookieCollection.cs | 7 +-- .../Katana.Sandbox.WebServer.csproj | 1 + .../SameSiteCookieManager.cs | 62 +++++++++++++++++++ tests/Katana.Sandbox.WebServer/Startup.cs | 20 ++++-- 11 files changed, 184 insertions(+), 12 deletions(-) create mode 100644 tests/Katana.Sandbox.WebServer/SameSiteCookieManager.cs diff --git a/src/Microsoft.Owin.Host.SystemWeb/SystemWebChunkingCookieManager.cs b/src/Microsoft.Owin.Host.SystemWeb/SystemWebChunkingCookieManager.cs index b88dba14a..55c04f5a3 100644 --- a/src/Microsoft.Owin.Host.SystemWeb/SystemWebChunkingCookieManager.cs +++ b/src/Microsoft.Owin.Host.SystemWeb/SystemWebChunkingCookieManager.cs @@ -163,6 +163,7 @@ public void AppendResponseCookie(IOwinContext context, string key, string value, bool domainHasValue = !string.IsNullOrEmpty(options.Domain); bool pathHasValue = !string.IsNullOrEmpty(options.Path); bool expiresHasValue = options.Expires.HasValue; + bool sameSiteHasValue = options.SameSite.HasValue && SystemWebCookieManager.IsSameSiteAvailable; string escapedKey = Uri.EscapeDataString(key); string prefix = escapedKey + "="; @@ -173,9 +174,12 @@ public void AppendResponseCookie(IOwinContext context, string key, string value, !pathHasValue ? null : "; path=", !pathHasValue ? null : options.Path, !expiresHasValue ? null : "; expires=", - !expiresHasValue ? null : options.Expires.Value.ToString("ddd, dd-MMM-yyyy HH:mm:ss ", CultureInfo.InvariantCulture) + "GMT", + !expiresHasValue ? null : options.Expires.Value.ToString("ddd, dd-MMM-yyyy HH:mm:ss \\G\\M\\T", CultureInfo.InvariantCulture), !options.Secure ? null : "; secure", - !options.HttpOnly ? null : "; HttpOnly"); + !options.HttpOnly ? null : "; HttpOnly", + !sameSiteHasValue ? null : "; SameSite=", + !sameSiteHasValue ? null : GetStringRepresentationOfSameSite(options.SameSite.Value) + ); value = value ?? string.Empty; bool quoted = false; @@ -273,6 +277,9 @@ public void DeleteCookie(IOwinContext context, string key, CookieOptions options { Path = options.Path, Domain = options.Domain, + HttpOnly = options.HttpOnly, + SameSite = options.SameSite, + Secure = options.Secure, Expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), }); @@ -286,6 +293,9 @@ public void DeleteCookie(IOwinContext context, string key, CookieOptions options { Path = options.Path, Domain = options.Domain, + HttpOnly = options.HttpOnly, + SameSite = options.SameSite, + Secure = options.Secure, Expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), }); } @@ -313,6 +323,14 @@ private static void SetOptions(HttpCookie cookie, CookieOptions options, bool do { cookie.HttpOnly = true; } + + if (SystemWebCookieManager.IsSameSiteAvailable) + { + SystemWebCookieManager.SameSiteSetter.Invoke(cookie, new object[] + { + options.SameSite ?? (SameSiteMode)(-1) // Unspecified + }); + } } private static bool IsQuoted(string value) @@ -329,5 +347,21 @@ private static string Quote(string value) { return '"' + value + '"'; } + + private static string GetStringRepresentationOfSameSite(SameSiteMode siteMode) + { + switch (siteMode) + { + case SameSiteMode.None: + return "None"; + case SameSiteMode.Lax: + return "Lax"; + case SameSiteMode.Strict: + return "Strict"; + default: + throw new ArgumentOutOfRangeException("siteMode", + string.Format(CultureInfo.InvariantCulture, "Unexpected SameSiteMode value: {0}", siteMode)); + } + } } } diff --git a/src/Microsoft.Owin.Host.SystemWeb/SystemWebCookieManager.cs b/src/Microsoft.Owin.Host.SystemWeb/SystemWebCookieManager.cs index 5eb3c8aaf..8a1fcc82d 100644 --- a/src/Microsoft.Owin.Host.SystemWeb/SystemWebCookieManager.cs +++ b/src/Microsoft.Owin.Host.SystemWeb/SystemWebCookieManager.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Reflection; using System.Web; using Microsoft.Owin.Infrastructure; @@ -12,6 +13,21 @@ namespace Microsoft.Owin.Host.SystemWeb /// public class SystemWebCookieManager : ICookieManager { + // .NET 4.7.2, but requries a patch to emit SameSite=None + internal static readonly bool IsSameSiteAvailable; + internal static readonly MethodInfo SameSiteSetter; + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline")] + static SystemWebCookieManager() + { + var systemWeb = typeof(HttpContextBase).Assembly; + IsSameSiteAvailable = systemWeb.GetType("System.Web.SameSiteMode") != null; + if (IsSameSiteAvailable) + { + SameSiteSetter = typeof(HttpCookie).GetProperty("SameSite").SetMethod; + } + } + /// /// Creates a new instance of SystemWebCookieManager. /// @@ -104,6 +120,13 @@ public void AppendResponseCookie(IOwinContext context, string key, string value, { cookie.HttpOnly = true; } + if (IsSameSiteAvailable) + { + SameSiteSetter.Invoke(cookie, new object[] + { + options.SameSite ?? (SameSiteMode)(-1) // Unspecified + }); + } webContext.Response.AppendCookie(cookie); } @@ -133,6 +156,9 @@ public void DeleteCookie(IOwinContext context, string key, CookieOptions options { Path = options.Path, Domain = options.Domain, + HttpOnly = options.HttpOnly, + Secure = options.Secure, + SameSite = options.SameSite, Expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), }); } diff --git a/src/Microsoft.Owin.Security.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.Owin.Security.Cookies/CookieAuthenticationHandler.cs index 743368e37..25dc25676 100644 --- a/src/Microsoft.Owin.Security.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.Owin.Security.Cookies/CookieAuthenticationHandler.cs @@ -146,6 +146,7 @@ protected override async Task ApplyResponseGrantAsync() { Domain = Options.CookieDomain, HttpOnly = Options.CookieHttpOnly, + SameSite = Options.CookieSameSite, Path = Options.CookiePath ?? "/", }; if (Options.CookieSecure == CookieSecureOption.SameAsRequest) diff --git a/src/Microsoft.Owin.Security.Cookies/CookieAuthenticationOptions.cs b/src/Microsoft.Owin.Security.Cookies/CookieAuthenticationOptions.cs index 9d8d58d07..019209f72 100644 --- a/src/Microsoft.Owin.Security.Cookies/CookieAuthenticationOptions.cs +++ b/src/Microsoft.Owin.Security.Cookies/CookieAuthenticationOptions.cs @@ -65,6 +65,12 @@ public string CookieName /// public bool CookieHttpOnly { get; set; } + /// + /// Determines if the browser should allow the cookie to be sent with requests initiated from other sites. + /// The default is 'null' to exclude the setting and let the browser choose the default behavior. + /// + public SameSiteMode? CookieSameSite { get; set; } + /// /// Determines if the cookie should only be transmitted on HTTPS request. The default is to limit the cookie /// to HTTPS requests if the page which is doing the SignIn is also HTTPS. If you have an HTTPS sign in page diff --git a/src/Microsoft.Owin.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs b/src/Microsoft.Owin.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs index bee807bd5..7a207e296 100644 --- a/src/Microsoft.Owin.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs +++ b/src/Microsoft.Owin.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs @@ -637,6 +637,7 @@ protected virtual void RememberNonce(OpenIdConnectMessage message, string nonce) Convert.ToBase64String(Encoding.UTF8.GetBytes(Options.StateDataFormat.Protect(properties))), new CookieOptions { + SameSite = SameSiteMode.None, HttpOnly = true, Secure = Request.IsSecure, Expires = DateTime.UtcNow + Options.ProtocolValidator.NonceLifetime @@ -667,6 +668,7 @@ protected virtual string RetrieveNonce(OpenIdConnectMessage message) { var cookieOptions = new CookieOptions { + SameSite = SameSiteMode.None, HttpOnly = true, Secure = Request.IsSecure }; diff --git a/src/Microsoft.Owin.Security/Infrastructure/AuthenticationHandler.cs b/src/Microsoft.Owin.Security/Infrastructure/AuthenticationHandler.cs index db5373c17..8a9bbbf84 100644 --- a/src/Microsoft.Owin.Security/Infrastructure/AuthenticationHandler.cs +++ b/src/Microsoft.Owin.Security/Infrastructure/AuthenticationHandler.cs @@ -215,6 +215,7 @@ protected void GenerateCorrelationId(AuthenticationProperties properties) var cookieOptions = new CookieOptions { + SameSite = SameSiteMode.None, HttpOnly = true, Secure = Request.IsSecure }; @@ -243,6 +244,7 @@ protected void GenerateCorrelationId(ICookieManager cookieManager, Authenticatio var cookieOptions = new CookieOptions { + SameSite = SameSiteMode.None, HttpOnly = true, Secure = Request.IsSecure }; @@ -277,6 +279,7 @@ protected bool ValidateCorrelationId(AuthenticationProperties properties, ILogge var cookieOptions = new CookieOptions { + SameSite = SameSiteMode.None, HttpOnly = true, Secure = Request.IsSecure }; @@ -332,6 +335,7 @@ protected bool ValidateCorrelationId(ICookieManager cookieManager, Authenticatio var cookieOptions = new CookieOptions { + SameSite = SameSiteMode.None, HttpOnly = true, Secure = Request.IsSecure }; diff --git a/src/Microsoft.Owin/Infrastructure/ChunkingCookieManager.cs b/src/Microsoft.Owin/Infrastructure/ChunkingCookieManager.cs index 8daf49276..4c3f87cb7 100644 --- a/src/Microsoft.Owin/Infrastructure/ChunkingCookieManager.cs +++ b/src/Microsoft.Owin/Infrastructure/ChunkingCookieManager.cs @@ -136,6 +136,7 @@ public void AppendResponseCookie(IOwinContext context, string key, string value, bool domainHasValue = !string.IsNullOrEmpty(options.Domain); bool pathHasValue = !string.IsNullOrEmpty(options.Path); bool expiresHasValue = options.Expires.HasValue; + bool sameSiteHasValue = options.SameSite.HasValue; string escapedKey = Uri.EscapeDataString(key); string prefix = escapedKey + "="; @@ -146,9 +147,11 @@ public void AppendResponseCookie(IOwinContext context, string key, string value, !pathHasValue ? null : "; path=", !pathHasValue ? null : options.Path, !expiresHasValue ? null : "; expires=", - !expiresHasValue ? null : options.Expires.Value.ToString("ddd, dd-MMM-yyyy HH:mm:ss ", CultureInfo.InvariantCulture) + "GMT", + !expiresHasValue ? null : options.Expires.Value.ToString("ddd, dd-MMM-yyyy HH:mm:ss \\G\\M\\T", CultureInfo.InvariantCulture), !options.Secure ? null : "; secure", - !options.HttpOnly ? null : "; HttpOnly"); + !options.HttpOnly ? null : "; HttpOnly", + !sameSiteHasValue ? null : "; SameSite=", + !sameSiteHasValue ? null : GetStringRepresentationOfSameSite(options.SameSite.Value)); value = value ?? string.Empty; bool quoted = false; @@ -277,6 +280,9 @@ public void DeleteCookie(IOwinContext context, string key, CookieOptions options { Path = options.Path, Domain = options.Domain, + HttpOnly = options.HttpOnly, + SameSite = options.SameSite, + Secure = options.Secure, Expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), }); @@ -290,6 +296,9 @@ public void DeleteCookie(IOwinContext context, string key, CookieOptions options { Path = options.Path, Domain = options.Domain, + HttpOnly = options.HttpOnly, + SameSite = options.SameSite, + Secure = options.Secure, Expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), }); } @@ -309,5 +318,21 @@ private static string Quote(string value) { return '"' + value + '"'; } + + private static string GetStringRepresentationOfSameSite(SameSiteMode siteMode) + { + switch (siteMode) + { + case SameSiteMode.None: + return "None"; + case SameSiteMode.Lax: + return "Lax"; + case SameSiteMode.Strict: + return "Strict"; + default: + throw new ArgumentOutOfRangeException("siteMode", + string.Format(CultureInfo.InvariantCulture, "Unexpected SameSiteMode value: {0}", siteMode)); + } + } } } diff --git a/src/Microsoft.Owin/ResponseCookieCollection.cs b/src/Microsoft.Owin/ResponseCookieCollection.cs index 0540936f9..8c6a0be36 100644 --- a/src/Microsoft.Owin/ResponseCookieCollection.cs +++ b/src/Microsoft.Owin/ResponseCookieCollection.cs @@ -138,14 +138,13 @@ public void Delete(string key, CookieOptions options) { Path = options.Path, Domain = options.Domain, + HttpOnly = options.HttpOnly, + SameSite = options.SameSite, + Secure = options.Secure, Expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), }); } - /// - /// Analogous to ToString() but without boxing so - /// we can save a bit of memory. - /// private static string GetStringRepresentationOfSameSite(SameSiteMode siteMode) { switch (siteMode) diff --git a/tests/Katana.Sandbox.WebServer/Katana.Sandbox.WebServer.csproj b/tests/Katana.Sandbox.WebServer/Katana.Sandbox.WebServer.csproj index 62edb2560..76b02d1fc 100644 --- a/tests/Katana.Sandbox.WebServer/Katana.Sandbox.WebServer.csproj +++ b/tests/Katana.Sandbox.WebServer/Katana.Sandbox.WebServer.csproj @@ -101,6 +101,7 @@ + diff --git a/tests/Katana.Sandbox.WebServer/SameSiteCookieManager.cs b/tests/Katana.Sandbox.WebServer/SameSiteCookieManager.cs new file mode 100644 index 000000000..d5f8869a3 --- /dev/null +++ b/tests/Katana.Sandbox.WebServer/SameSiteCookieManager.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using Microsoft.Owin; +using Microsoft.Owin.Infrastructure; + +namespace Katana.Sandbox.WebServer +{ + public class SameSiteCookieManager : ICookieManager + { + private readonly ICookieManager _innerManager; + + public SameSiteCookieManager() + : this(new CookieManager()) + { + } + + public SameSiteCookieManager(ICookieManager innerManager) + { + _innerManager = innerManager; + } + + public void AppendResponseCookie(IOwinContext context, string key, string value, CookieOptions options) + { + CheckSameSite(context, options); + _innerManager.AppendResponseCookie(context, key, value, options); + } + + public void DeleteCookie(IOwinContext context, string key, CookieOptions options) + { + CheckSameSite(context, options); + _innerManager.DeleteCookie(context, key, options); + } + + public string GetRequestCookie(IOwinContext context, string key) + { + return _innerManager.GetRequestCookie(context, key); + } + + private void CheckSameSite(IOwinContext context, CookieOptions options) + { + if (DisallowsSameSiteNone(context) && options.SameSite == SameSiteMode.None) + { + // IOS12 and Mac OS X 10.14 treat SameSite=None as SameSite=Strict. Exclude the option instead. + // https://bugs.webkit.org/show_bug.cgi?id=198181 + options.SameSite = null; + } + } + + // https://myip.ms/view/comp_browsers/8568/Safari_12.html + public static bool DisallowsSameSiteNone(IOwinContext context) + { + // TODO: Use your User Agent library of choice here. + var userAgent = context.Request.Headers["User-Agent"]; + return userAgent.Contains("CPU iPhone OS 12") // Also covers iPod touch + || userAgent.Contains("iPad; CPU OS 12") + // Safari 12 and 13 are both broken on Mojave + || userAgent.Contains("Macintosh; Intel Mac OS X 10_14"); + } + } +} \ No newline at end of file diff --git a/tests/Katana.Sandbox.WebServer/Startup.cs b/tests/Katana.Sandbox.WebServer/Startup.cs index bd771020d..235ea7ee5 100644 --- a/tests/Katana.Sandbox.WebServer/Startup.cs +++ b/tests/Katana.Sandbox.WebServer/Startup.cs @@ -5,6 +5,7 @@ using System.Collections.Concurrent; using System.IO; using System.Linq; +using System.Net; using System.Security.Claims; using System.Security.Principal; using System.Threading.Tasks; @@ -32,6 +33,9 @@ public class Startup public void Configuration(IAppBuilder app) { + // For twitter: + ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; + var logger = app.CreateLogger("Katana.Sandbox.WebServer"); logger.WriteInformation("Application Started"); @@ -59,7 +63,8 @@ public void Configuration(IAppBuilder app) AuthenticationMode = AuthenticationMode.Active, CookieName = CookieAuthenticationDefaults.CookiePrefix + "External", ExpireTimeSpan = TimeSpan.FromMinutes(5), - CookieManager = new SystemWebChunkingCookieManager() + // CookieManager = new SystemWebChunkingCookieManager() + CookieManager = new SameSiteCookieManager() }); // https://developers.facebook.com/apps/ @@ -69,7 +74,7 @@ public void Configuration(IAppBuilder app) AppSecret = Environment.GetEnvironmentVariable("facebook:appsecret"), Scope = { "email" }, Fields = { "name", "email" }, - CookieManager = new SystemWebCookieManager() + // CookieManager = new SystemWebCookieManager() }); // https://console.developers.google.com/apis/credentials @@ -125,15 +130,22 @@ public void Configuration(IAppBuilder app) { Wtrealm = "https://tratcheroutlook.onmicrosoft.com/AspNetCoreSample", MetadataAddress = "https://login.windows.net/cdc690f9-b6b8-4023-813a-bae7143d1f87/FederationMetadata/2007-06/FederationMetadata.xml", + Wreply = "https://localhost:44318/", }); app.UseOpenIdConnectAuthentication(new Microsoft.Owin.Security.OpenIdConnect.OpenIdConnectAuthenticationOptions() { + // https://github.com/IdentityServer/IdentityServer4.Demo/blob/master/src/IdentityServer4Demo/Config.cs + ClientId = "server.hybrid", + ClientSecret = "secret", // for code flow + Authority = "https://demo.identityserver.io/", + /* Authority = Environment.GetEnvironmentVariable("oidc:authority"), ClientId = Environment.GetEnvironmentVariable("oidc:clientid"), - ClientSecret = Environment.GetEnvironmentVariable("oidc:clientsecret"), RedirectUri = "https://localhost:44318/", - CookieManager = new SystemWebCookieManager(), + ClientSecret = Environment.GetEnvironmentVariable("oidc:clientsecret"),*/ + // CookieManager = new SystemWebCookieManager(), + CookieManager = new SameSiteCookieManager(), //ResponseType = "code", //ResponseMode = "query", //SaveTokens = true, From ae59e4b900a7bcf2e1fb7ed6118cd04b9ac2c005 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Mon, 7 Oct 2019 13:37:33 -0700 Subject: [PATCH 09/45] Use larger buffer for static file copy #304 (#311) --- src/Microsoft.Owin.StaticFiles/StreamCopyOperation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.Owin.StaticFiles/StreamCopyOperation.cs b/src/Microsoft.Owin.StaticFiles/StreamCopyOperation.cs index 1402682ba..636b2b311 100644 --- a/src/Microsoft.Owin.StaticFiles/StreamCopyOperation.cs +++ b/src/Microsoft.Owin.StaticFiles/StreamCopyOperation.cs @@ -13,7 +13,7 @@ namespace Microsoft.Owin.StaticFiles // FYI: In most cases the source will be a FileStream and the destination will be to the network. internal class StreamCopyOperation { - private const int DefaultBufferSize = 1024 * 16; + private const int DefaultBufferSize = 1024 * 64; private readonly TaskCompletionSource _tcs; private readonly Stream _source; From 2c68ecff843266b852328e07626a97450b19d27a Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Thu, 24 Oct 2019 11:48:52 -0700 Subject: [PATCH 10/45] Fix KeyNotFoundException in OIDCHandler.AuthenticateCoreAsync #315 (#316) --- .../OpenidConnectAuthenticationHandler.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.Owin.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs b/src/Microsoft.Owin.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs index 7a207e296..0d54beb37 100644 --- a/src/Microsoft.Owin.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs +++ b/src/Microsoft.Owin.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs @@ -384,7 +384,8 @@ protected override async Task AuthenticateCoreAsync() ClientSecret = Options.ClientSecret, Code = authorizationResponse.Code, GrantType = OpenIdConnectGrantTypes.AuthorizationCode, - RedirectUri = properties.Dictionary[OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey] + RedirectUri = properties.Dictionary.ContainsKey(OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey) ? + properties.Dictionary[OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey] : string.Empty, }; var authorizationCodeReceivedNotification = new AuthorizationCodeReceivedNotification(Context, Options) @@ -393,8 +394,7 @@ protected override async Task AuthenticateCoreAsync() Code = authorizationResponse.Code, JwtSecurityToken = jwt, ProtocolMessage = authorizationResponse, - RedirectUri = properties.Dictionary.ContainsKey(OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey) ? - properties.Dictionary[OpenIdConnectAuthenticationDefaults.RedirectUriUsedForCodeKey] : string.Empty, + RedirectUri = tokenEndpointRequest.RedirectUri, TokenEndpointRequest = tokenEndpointRequest }; await Options.Notifications.AuthorizationCodeReceived(authorizationCodeReceivedNotification); From 294be6a757918b4262ff7c385b3f03591204fffb Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Thu, 24 Oct 2019 14:50:43 -0700 Subject: [PATCH 11/45] HttpListener exception handling #314 (#317) --- Katana.sln | 7 ++ .../OwinHttpListener.cs | 26 +----- tests/Katana.Sandbox.Selfhost/App.config | 6 ++ .../Katana.Sandbox.Selfhost.csproj | 90 +++++++++++++++++++ tests/Katana.Sandbox.Selfhost/Program.cs | 30 +++++++ .../Properties/AssemblyInfo.cs | 36 ++++++++ tests/Katana.Sandbox.Selfhost/packages.config | 4 + 7 files changed, 177 insertions(+), 22 deletions(-) create mode 100644 tests/Katana.Sandbox.Selfhost/App.config create mode 100644 tests/Katana.Sandbox.Selfhost/Katana.Sandbox.Selfhost.csproj create mode 100644 tests/Katana.Sandbox.Selfhost/Program.cs create mode 100644 tests/Katana.Sandbox.Selfhost/Properties/AssemblyInfo.cs create mode 100644 tests/Katana.Sandbox.Selfhost/packages.config diff --git a/Katana.sln b/Katana.sln index 4ac6af959..635baf9e4 100644 --- a/Katana.sln +++ b/Katana.sln @@ -138,6 +138,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FunctionalTests", "Function EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FunctionalTests", "tests\FunctionalTests\FunctionalTests.csproj", "{4EF3F748-16D0-4112-AE43-AACADB3EF8E9}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Katana.Sandbox.Selfhost", "tests\Katana.Sandbox.Selfhost\Katana.Sandbox.Selfhost.csproj", "{9F2F31EF-6017-48CC-88D6-EC4FF4FEAAA5}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -308,6 +310,10 @@ Global {4EF3F748-16D0-4112-AE43-AACADB3EF8E9}.Debug|Any CPU.Build.0 = Debug|Any CPU {4EF3F748-16D0-4112-AE43-AACADB3EF8E9}.Release|Any CPU.ActiveCfg = Release|Any CPU {4EF3F748-16D0-4112-AE43-AACADB3EF8E9}.Release|Any CPU.Build.0 = Release|Any CPU + {9F2F31EF-6017-48CC-88D6-EC4FF4FEAAA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9F2F31EF-6017-48CC-88D6-EC4FF4FEAAA5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9F2F31EF-6017-48CC-88D6-EC4FF4FEAAA5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9F2F31EF-6017-48CC-88D6-EC4FF4FEAAA5}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -357,5 +363,6 @@ Global {23D90C94-647A-416C-9227-9A0779401EBC} = {10A4935F-4C17-44ED-BB00-D044FC7C77B8} {AA80B4A3-C885-4A7E-AF1A-FC3E89611988} = {10A4935F-4C17-44ED-BB00-D044FC7C77B8} {4EF3F748-16D0-4112-AE43-AACADB3EF8E9} = {DD2E82F1-F3EA-4D1F-B623-9C34440D79D6} + {9F2F31EF-6017-48CC-88D6-EC4FF4FEAAA5} = {D067FB54-B69D-4502-8E2F-676271AC4B86} EndGlobalSection EndGlobal diff --git a/src/Microsoft.Owin.Host.HttpListener/OwinHttpListener.cs b/src/Microsoft.Owin.Host.HttpListener/OwinHttpListener.cs index 732f4bdf1..fd7d59c89 100644 --- a/src/Microsoft.Owin.Host.HttpListener/OwinHttpListener.cs +++ b/src/Microsoft.Owin.Host.HttpListener/OwinHttpListener.cs @@ -214,30 +214,12 @@ private async void ProcessRequestsAsync() { context = await _listener.GetContextAsync(); } - catch (ApplicationException ae) - { - // These come from the thread pool if HttpListener tries to call BindHandle after the listener has been disposed. - Interlocked.Decrement(ref _currentOutstandingAccepts); - LogHelper.LogException(_logger, "Accept", ae); - return; - } - catch (HttpListenerException hle) - { - // These happen if HttpListener has been disposed - Interlocked.Decrement(ref _currentOutstandingAccepts); - LogHelper.LogException(_logger, "Accept", hle); - return; - } - catch (ObjectDisposedException ode) - { - // These happen if HttpListener has been disposed - Interlocked.Decrement(ref _currentOutstandingAccepts); - LogHelper.LogException(_logger, "Accept", ode); - return; - } catch (Exception ex) { - // Some other unknown error. Log it and try to keep going. + // HttpListenerException happen if HttpListener has been disposed, or if the client disconnects mid request. + // ObjectDisposedException happen if HttpListener has been disposed. + // ApplicationException come from the thread pool if HttpListener tries to call BindHandle after the listener has been disposed. + // Log it and try to keep going. Let IsListening break the loop. Interlocked.Decrement(ref _currentOutstandingAccepts); LogHelper.LogException(_logger, "Accept", ex); continue; diff --git a/tests/Katana.Sandbox.Selfhost/App.config b/tests/Katana.Sandbox.Selfhost/App.config new file mode 100644 index 000000000..8e1564635 --- /dev/null +++ b/tests/Katana.Sandbox.Selfhost/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/tests/Katana.Sandbox.Selfhost/Katana.Sandbox.Selfhost.csproj b/tests/Katana.Sandbox.Selfhost/Katana.Sandbox.Selfhost.csproj new file mode 100644 index 000000000..8af2ff16a --- /dev/null +++ b/tests/Katana.Sandbox.Selfhost/Katana.Sandbox.Selfhost.csproj @@ -0,0 +1,90 @@ + + + + + Debug + AnyCPU + {9F2F31EF-6017-48CC-88D6-EC4FF4FEAAA5} + Exe + Properties + Katana.Sandbox.Selfhost + Katana.Sandbox.Selfhost + v4.5 + 512 + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\packages\Owin.1.0\lib\net40\Owin.dll + True + + + + + + + + + + + + + + + + + + + + + {670915f7-f111-42ff-b004-39379a9d5951} + Microsoft.Owin.Diagnostics + + + {63988a9b-fa70-4bba-8c7e-784145384f7c} + Microsoft.Owin.FileSystems + + + {9f0c72d8-e43f-4f01-9deb-919191911919} + Microsoft.Owin.Host.HttpListener + + + {c225eb2f-e7a7-463f-b058-1705f204978e} + Microsoft.Owin.Hosting + + + {f31a42db-2f57-4dac-b2bc-106f2d6f3c82} + Microsoft.Owin.StaticFiles + + + {0db69cae-b0bc-4688-9467-66b4c1023d3f} + Microsoft.Owin + + + + + \ No newline at end of file diff --git a/tests/Katana.Sandbox.Selfhost/Program.cs b/tests/Katana.Sandbox.Selfhost/Program.cs new file mode 100644 index 000000000..176bc7813 --- /dev/null +++ b/tests/Katana.Sandbox.Selfhost/Program.cs @@ -0,0 +1,30 @@ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Owin; +using Microsoft.Owin.Hosting; +using Microsoft.Owin.Host.HttpListener; +using Owin; + +namespace Katana.Sandbox.Selfhost +{ + class Program + { + static void Main() + { + var address = "http://localhost:8000/"; + using (var server = WebApp.Start(address, appBuilder => + { + var owinHttpListener = appBuilder.Properties[typeof(OwinHttpListener).FullName] as OwinHttpListener; + appBuilder.Use(async (context, next) => await context.Response.WriteAsync("Hello world!")); + })) + { + Console.WriteLine("Listening on " + address); + Console.ReadKey(); + } + } + } +} diff --git a/tests/Katana.Sandbox.Selfhost/Properties/AssemblyInfo.cs b/tests/Katana.Sandbox.Selfhost/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..4555a1569 --- /dev/null +++ b/tests/Katana.Sandbox.Selfhost/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 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("Katana.Sandbox.Selfhost")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Katana.Sandbox.Selfhost")] +[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 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("9f2f31ef-6017-48cc-88d6-ec4ff4feaaa5")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/tests/Katana.Sandbox.Selfhost/packages.config b/tests/Katana.Sandbox.Selfhost/packages.config new file mode 100644 index 000000000..743219642 --- /dev/null +++ b/tests/Katana.Sandbox.Selfhost/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file From 9e9c44d0b0027cb58a3252a10ea93f25ccab32af Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Tue, 12 Nov 2019 09:33:17 -0800 Subject: [PATCH 12/45] Toggle versions for final 4.1.0 build --- build/CommonAssemblyInfo.cs | 4 ++-- build/DevAssemblyInfo.cs | 2 +- build/Katana.version.targets | 8 ++++---- build/Sakefile.shade | 4 ++-- tests/FunctionalTests/Properties/AssemblyInfo.cs | 2 +- .../Katana.Sandbox.Selfhost/Properties/AssemblyInfo.cs | 10 +++++----- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/build/CommonAssemblyInfo.cs b/build/CommonAssemblyInfo.cs index fc59a72bc..c713044c6 100644 --- a/build/CommonAssemblyInfo.cs +++ b/build/CommonAssemblyInfo.cs @@ -8,6 +8,6 @@ [assembly: AssemblyCopyright("\x00a9 Microsoft Corporation All rights reserved.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyVersion("4.1.0.0")] -[assembly: AssemblyFileVersion("4.1.80911.0")] -[assembly: AssemblyInformationalVersion("4.1.0-preview1-000")] +[assembly: AssemblyFileVersion("4.1.81112.0")] +[assembly: AssemblyInformationalVersion("4.1.0-rtw-000")] [assembly: AssemblyMetadata("Serviceable", "True")] diff --git a/build/DevAssemblyInfo.cs b/build/DevAssemblyInfo.cs index 6f6f92be3..6e7bebc2c 100644 --- a/build/DevAssemblyInfo.cs +++ b/build/DevAssemblyInfo.cs @@ -8,6 +8,6 @@ [assembly: AssemblyCopyright("\x00a9 Microsoft Corporation All rights reserved.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyVersion("0.31.0.0")] -[assembly: AssemblyFileVersion("0.31.80118.0")] +[assembly: AssemblyFileVersion("0.31.81112.0")] [assembly: AssemblyInformationalVersion("0.31.0-pre-000")] [assembly: AssemblyMetadata("Serviceable", "True")] diff --git a/build/Katana.version.targets b/build/Katana.version.targets index dc4511e30..6ad5f004b 100644 --- a/build/Katana.version.targets +++ b/build/Katana.version.targets @@ -3,13 +3,13 @@ 4.1.0 4.1.0.0 - 4.1.0-preview1-000 - 4.1.80911.0 + 4.1.0-rtw-000 + 4.1.81112.0 4 1 0 - preview1 - 80911 + rtw + 81112 https://raw.githubusercontent.com/aspnet/AspNetKatana/v4.0.1/LICENSE.txt https://github.com/aspnet/AspNetKatana/ diff --git a/build/Sakefile.shade b/build/Sakefile.shade index b7a8e451b..1c08c2de3 100644 --- a/build/Sakefile.shade +++ b/build/Sakefile.shade @@ -1,9 +1,9 @@ var PROJECT='Katana' var AUTHORS='Microsoft' -var SHIP='${Version(4, 1, 0, "preview1")}' +var SHIP='${Version(4, 1, 0, "rtw")}' var DEV='${Version(0, 31, 0, "pre")}' -set FINAL_MILESTONE='${false}' +set FINAL_MILESTONE='${true}' var AZUREAD_VERSION='5.3.0' var AZUREAD_SUFFIX='' var VERSION='${SHIP.VERSION}' diff --git a/tests/FunctionalTests/Properties/AssemblyInfo.cs b/tests/FunctionalTests/Properties/AssemblyInfo.cs index 174c0796a..6a002eca0 100644 --- a/tests/FunctionalTests/Properties/AssemblyInfo.cs +++ b/tests/FunctionalTests/Properties/AssemblyInfo.cs @@ -33,4 +33,4 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("0.31.0.0")] [assembly: AssemblyVersion("0.31.0.0")] -[assembly: AssemblyFileVersion("0.31.80118.0")] +[assembly: AssemblyFileVersion("0.31.81112.0")] diff --git a/tests/Katana.Sandbox.Selfhost/Properties/AssemblyInfo.cs b/tests/Katana.Sandbox.Selfhost/Properties/AssemblyInfo.cs index 4555a1569..ecc5df754 100644 --- a/tests/Katana.Sandbox.Selfhost/Properties/AssemblyInfo.cs +++ b/tests/Katana.Sandbox.Selfhost/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -using System.Reflection; +using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -10,7 +10,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Katana.Sandbox.Selfhost")] -[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyCopyright("\x00a9 Microsoft Corporation All rights reserved.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -31,6 +31,6 @@ // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +// [assembly: AssemblyVersion("0.31.0.0")] +[assembly: AssemblyVersion("0.31.0.0")] +[assembly: AssemblyFileVersion("0.31.81112.0")] From e001fcf245ba4b6b2eb09ef410d398527882dc1a Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Mon, 10 Feb 2020 10:44:34 -0800 Subject: [PATCH 13/45] Update SameSiteCookieManager to match blog, check null --- .../SameSiteCookieManager.cs | 58 +++++++++++++++---- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/tests/Katana.Sandbox.WebServer/SameSiteCookieManager.cs b/tests/Katana.Sandbox.WebServer/SameSiteCookieManager.cs index d5f8869a3..699152009 100644 --- a/tests/Katana.Sandbox.WebServer/SameSiteCookieManager.cs +++ b/tests/Katana.Sandbox.WebServer/SameSiteCookieManager.cs @@ -11,9 +11,8 @@ public class SameSiteCookieManager : ICookieManager { private readonly ICookieManager _innerManager; - public SameSiteCookieManager() - : this(new CookieManager()) - { + public SameSiteCookieManager() : this(new CookieManager()) + { } public SameSiteCookieManager(ICookieManager innerManager) @@ -21,7 +20,8 @@ public SameSiteCookieManager(ICookieManager innerManager) _innerManager = innerManager; } - public void AppendResponseCookie(IOwinContext context, string key, string value, CookieOptions options) + public void AppendResponseCookie(IOwinContext context, string key, string value, + CookieOptions options) { CheckSameSite(context, options); _innerManager.AppendResponseCookie(context, key, value, options); @@ -40,23 +40,57 @@ public string GetRequestCookie(IOwinContext context, string key) private void CheckSameSite(IOwinContext context, CookieOptions options) { - if (DisallowsSameSiteNone(context) && options.SameSite == SameSiteMode.None) + if (options.SameSite == SameSiteMode.None && DisallowsSameSiteNone(context)) { - // IOS12 and Mac OS X 10.14 treat SameSite=None as SameSite=Strict. Exclude the option instead. - // https://bugs.webkit.org/show_bug.cgi?id=198181 options.SameSite = null; } } - // https://myip.ms/view/comp_browsers/8568/Safari_12.html public static bool DisallowsSameSiteNone(IOwinContext context) { // TODO: Use your User Agent library of choice here. var userAgent = context.Request.Headers["User-Agent"]; - return userAgent.Contains("CPU iPhone OS 12") // Also covers iPod touch - || userAgent.Contains("iPad; CPU OS 12") - // Safari 12 and 13 are both broken on Mojave - || userAgent.Contains("Macintosh; Intel Mac OS X 10_14"); + return DisallowsSameSiteNone(userAgent); + } + + public static bool DisallowsSameSiteNone(string userAgent) + { + if (string.IsNullOrEmpty(userAgent)) + { + return false; + } + + // Cover all iOS based browsers here. This includes: + // - Safari on iOS 12 for iPhone, iPod Touch, iPad + // - WkWebview on iOS 12 for iPhone, iPod Touch, iPad + // - Chrome on iOS 12 for iPhone, iPod Touch, iPad + // All of which are broken by SameSite=None, because they use the iOS networking stack + if (userAgent.Contains("CPU iPhone OS 12") || userAgent.Contains("iPad; CPU OS 12")) + { + return true; + } + + // Cover Mac OS X based browsers that use the Mac OS networking stack. This includes: + // - Safari on Mac OS X. + // This does not include: + // - Chrome on Mac OS X + // Because they do not use the Mac OS networking stack. + if (userAgent.Contains("Macintosh; Intel Mac OS X 10_14") && + userAgent.Contains("Version/") && userAgent.Contains("Safari")) + { + return true; + } + + // Cover Chrome 50-69, because some versions are broken by SameSite=None, + // and none in this range require it. + // Note: this covers some pre-Chromium Edge versions, + // but pre-Chromium Edge does not require SameSite=None. + if (userAgent.Contains("Chrome/5") || userAgent.Contains("Chrome/6")) + { + return true; + } + + return false; } } } \ No newline at end of file From 635c92f641ad1e014eead31cc7a365004949fda5 Mon Sep 17 00:00:00 2001 From: Immo Landwerth Date: Thu, 9 Apr 2020 12:13:55 -0700 Subject: [PATCH 14/45] Link Code of Conduct (#346) --- CODE-OF-CONDUCT.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 CODE-OF-CONDUCT.md diff --git a/CODE-OF-CONDUCT.md b/CODE-OF-CONDUCT.md new file mode 100644 index 000000000..775f221c9 --- /dev/null +++ b/CODE-OF-CONDUCT.md @@ -0,0 +1,6 @@ +# Code of Conduct + +This project has adopted the code of conduct defined by the Contributor Covenant +to clarify expected behavior in our community. + +For more information, see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct). From 535ab4ccc4ddf6650517e76712c888c3d920bd8b Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Wed, 12 Aug 2020 16:51:22 -0700 Subject: [PATCH 15/45] Remove cookie name decoding (#368) --- .../Infrastructure/OwinHelpers.cs | 23 +++++++++----- src/Microsoft.Owin/RequestCookieCollection.cs | 7 +++-- tests/Microsoft.Owin.Tests/FormsTests.cs | 10 +++--- .../Microsoft.Owin.Tests.csproj | 1 + .../RequestCookieTests.cs | 31 +++++++++++++++++++ 5 files changed, 57 insertions(+), 15 deletions(-) create mode 100644 tests/Microsoft.Owin.Tests/RequestCookieTests.cs diff --git a/src/Microsoft.Owin/Infrastructure/OwinHelpers.cs b/src/Microsoft.Owin/Infrastructure/OwinHelpers.cs index a0d6feec3..11a32b615 100644 --- a/src/Microsoft.Owin/Infrastructure/OwinHelpers.cs +++ b/src/Microsoft.Owin/Infrastructure/OwinHelpers.cs @@ -530,13 +530,13 @@ internal static IDictionary GetCookies(IOwinRequest request) if (request.Get("Microsoft.Owin.Cookies#text") != text) { cookies.Clear(); - ParseDelimited(text, SemicolonAndComma, AddCookieCallback, cookies); + ParseDelimited(text, SemicolonAndComma, AddCookieCallback, decodePlus: false, decodeKey: false, state: cookies); request.Set("Microsoft.Owin.Cookies#text", text); } return cookies; } - internal static void ParseDelimited(string text, char[] delimiters, Action callback, object state) + internal static void ParseDelimited(string text, char[] delimiters, Action callback, bool decodePlus, bool decodeKey, object state) { int textLength = text.Length; int equalIndex = text.IndexOf('='); @@ -560,10 +560,17 @@ internal static void ParseDelimited(string text, char[] delimiters, Action GetQuery(IOwinRequest request) { query.Clear(); var accumulator = new Dictionary>(StringComparer.OrdinalIgnoreCase); - ParseDelimited(text, AmpersandAndSemicolon, AppendItemCallback, accumulator); + ParseDelimited(text, AmpersandAndSemicolon, AppendItemCallback, decodePlus: true, decodeKey: true, state: accumulator); foreach (var kv in accumulator) { query.Add(kv.Key, kv.Value.ToArray()); @@ -813,7 +820,7 @@ internal static IFormCollection GetForm(string text) { IDictionary form = new Dictionary(StringComparer.OrdinalIgnoreCase); var accumulator = new Dictionary>(StringComparer.OrdinalIgnoreCase); - ParseDelimited(text, new[] { '&' }, AppendItemCallback, accumulator); + ParseDelimited(text, new[] { '&' }, AppendItemCallback, decodePlus: false, decodeKey: true, state: accumulator); foreach (var kv in accumulator) { form.Add(kv.Key, kv.Value.ToArray()); diff --git a/src/Microsoft.Owin/RequestCookieCollection.cs b/src/Microsoft.Owin/RequestCookieCollection.cs index aa797cfca..495e8ef9f 100644 --- a/src/Microsoft.Owin/RequestCookieCollection.cs +++ b/src/Microsoft.Owin/RequestCookieCollection.cs @@ -37,8 +37,11 @@ public string this[string key] get { string value; - Store.TryGetValue(key, out value); - return value; + if (Store.TryGetValue(key, out value) || Store.TryGetValue(Uri.EscapeDataString(key), out value)) + { + return value; + } + return null; } } diff --git a/tests/Microsoft.Owin.Tests/FormsTests.cs b/tests/Microsoft.Owin.Tests/FormsTests.cs index 08beab733..873beceeb 100644 --- a/tests/Microsoft.Owin.Tests/FormsTests.cs +++ b/tests/Microsoft.Owin.Tests/FormsTests.cs @@ -14,7 +14,7 @@ public class FormsTests private static readonly string[] RawValues = new[] { "v1", "v2, v3", "\"v4, b\"", "v5, v6", "v7", }; private const string JoinedValues = "v1,v2, v3,\"v4, b\",v5, v6,v7"; - private const string OriginalFormsString = "q1=v1&q2=v2,b&q3=v3&q3=v4&q4&q5=v5&q5=v5"; + private const string OriginalFormsString = "q1=v1&q2=v2,b&q3=v3&q3=v4&q4&q5=v5&q5=v+5"; [Fact] public void ParseForm() @@ -30,7 +30,7 @@ public void ParseForm() Assert.Equal("v2,b", form.Get("Q2")); Assert.Equal("v3,v4", form.Get("q3")); Assert.Null(form.Get("q4")); - Assert.Equal("v5,v5", form.Get("Q5")); + Assert.Equal("v5,v+5", form.Get("Q5")); Assert.True(stream.CanRead); } @@ -89,7 +89,7 @@ public void ReadFromStream() Assert.Equal("v2,b", form.Get("Q2")); Assert.Equal("v3,v4", form.Get("q3")); Assert.Null(form.Get("q4")); - Assert.Equal("v5,v5", form.Get("Q5")); + Assert.Equal("v5,v+5", form.Get("Q5")); } [Fact] @@ -107,14 +107,14 @@ public void ReadFromStreamTwice() Assert.Equal("v2,b", form.Get("Q2")); Assert.Equal("v3,v4", form.Get("q3")); Assert.Null(form.Get("q4")); - Assert.Equal("v5,v5", form.Get("Q5")); + Assert.Equal("v5,v+5", form.Get("Q5")); form = request.ReadFormAsync().Result; Assert.Equal("v1", form.Get("q1")); Assert.Equal("v2,b", form.Get("Q2")); Assert.Equal("v3,v4", form.Get("q3")); Assert.Null(form.Get("q4")); - Assert.Equal("v5,v5", form.Get("Q5")); + Assert.Equal("v5,v+5", form.Get("Q5")); } } } diff --git a/tests/Microsoft.Owin.Tests/Microsoft.Owin.Tests.csproj b/tests/Microsoft.Owin.Tests/Microsoft.Owin.Tests.csproj index 50120c1a1..8772ece14 100644 --- a/tests/Microsoft.Owin.Tests/Microsoft.Owin.Tests.csproj +++ b/tests/Microsoft.Owin.Tests/Microsoft.Owin.Tests.csproj @@ -63,6 +63,7 @@ + diff --git a/tests/Microsoft.Owin.Tests/RequestCookieTests.cs b/tests/Microsoft.Owin.Tests/RequestCookieTests.cs new file mode 100644 index 000000000..94ab3ea61 --- /dev/null +++ b/tests/Microsoft.Owin.Tests/RequestCookieTests.cs @@ -0,0 +1,31 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Linq; +using Xunit; +using Xunit.Extensions; + +namespace Microsoft.Owin.Tests +{ + public class RequestCookieTests + { + [Theory] + [InlineData("key=value", "key", "value")] + [InlineData("__secure-key=value", "__secure-key", "value")] + [InlineData("key%2C=%21value", "key,", "!value")] + [InlineData("ke%23y%2C=val%5Eue", "ke#y,", "val^ue")] + [InlineData("base64=QUI%2BREU%2FRw%3D%3D", "base64", "QUI+REU/Rw==")] + [InlineData("base64=QUI+REU/Rw==", "base64", "QUI+REU/Rw==")] + public void UnEscapesValues(string input, string expectedKey, string expectedValue) + { + var context = new OwinRequest(); + context.Headers["Cookie"] = input; + var cookies = context.Cookies; + + Assert.Equal(1, cookies.Count()); + Assert.Equal(Uri.EscapeDataString(expectedKey), cookies.Single().Key); + Assert.Equal(expectedValue, cookies[expectedKey]); + } + } +} From a754159746740afff6fb3051b557af85db58d81d Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Mon, 31 Aug 2020 09:19:25 -0700 Subject: [PATCH 16/45] Set TLS 1.2 when downloading nuget.exe --- build.cmd | 2 +- build/downloadnuget.ps1 | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 build/downloadnuget.ps1 diff --git a/build.cmd b/build.cmd index b48ba765b..42feedbcd 100644 --- a/build.cmd +++ b/build.cmd @@ -3,7 +3,7 @@ cd %~dp0 IF EXIST .nuget\NuGet.exe goto part2 echo Downloading latest version of NuGet.exe... -@powershell -NoProfile -ExecutionPolicy unrestricted -Command "((new-object net.webclient).DownloadFile('https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', '.nuget\NuGet.exe'))" +@powershell -NoProfile -ExecutionPolicy unrestricted -Command ".\build\downloadnuget.ps1" :part2 set EnableNuGetPackageRestore=true diff --git a/build/downloadnuget.ps1 b/build/downloadnuget.ps1 new file mode 100644 index 000000000..78ca8842e --- /dev/null +++ b/build/downloadnuget.ps1 @@ -0,0 +1,13 @@ +Set-PSDebug -Trace 1 +[System.Net.ServicePointManager]::SecurityProtocol +[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::TLS12 +[System.Net.ServicePointManager]::SecurityProtocol +try +{ + $client = New-Object System.Net.WebClient + $client.DownloadFile('https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', '.nuget\NuGet.exe') +} +catch [System.Exception] +{ + $Error[0].Exception.ToString() +} \ No newline at end of file From 409add74f22058a23d333882867ae52df033eae5 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Mon, 31 Aug 2020 15:12:36 -0700 Subject: [PATCH 17/45] Bump version to 4.1.1 --- build/CommonAssemblyInfo.cs | 6 +++--- build/Katana.version.targets | 12 ++++++------ build/Sakefile.shade | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/build/CommonAssemblyInfo.cs b/build/CommonAssemblyInfo.cs index c713044c6..af6993195 100644 --- a/build/CommonAssemblyInfo.cs +++ b/build/CommonAssemblyInfo.cs @@ -7,7 +7,7 @@ [assembly: AssemblyProduct("Microsoft OWIN")] [assembly: AssemblyCopyright("\x00a9 Microsoft Corporation All rights reserved.")] [assembly: AssemblyTrademark("")] -[assembly: AssemblyVersion("4.1.0.0")] -[assembly: AssemblyFileVersion("4.1.81112.0")] -[assembly: AssemblyInformationalVersion("4.1.0-rtw-000")] +[assembly: AssemblyVersion("4.1.1.0")] +[assembly: AssemblyFileVersion("4.1.90831.0")] +[assembly: AssemblyInformationalVersion("4.1.1-rtw-000")] [assembly: AssemblyMetadata("Serviceable", "True")] diff --git a/build/Katana.version.targets b/build/Katana.version.targets index 6ad5f004b..6e9ec9e81 100644 --- a/build/Katana.version.targets +++ b/build/Katana.version.targets @@ -1,15 +1,15 @@ - 4.1.0 - 4.1.0.0 - 4.1.0-rtw-000 - 4.1.81112.0 + 4.1.1 + 4.1.1.0 + 4.1.1-rtw-000 + 4.1.90831.0 4 1 - 0 + 1 rtw - 81112 + 90831 https://raw.githubusercontent.com/aspnet/AspNetKatana/v4.0.1/LICENSE.txt https://github.com/aspnet/AspNetKatana/ diff --git a/build/Sakefile.shade b/build/Sakefile.shade index 1c08c2de3..f5f0edbfb 100644 --- a/build/Sakefile.shade +++ b/build/Sakefile.shade @@ -1,7 +1,7 @@ var PROJECT='Katana' var AUTHORS='Microsoft' -var SHIP='${Version(4, 1, 0, "rtw")}' +var SHIP='${Version(4, 1, 1, "rtw")}' var DEV='${Version(0, 31, 0, "pre")}' set FINAL_MILESTONE='${true}' var AZUREAD_VERSION='5.3.0' From 17b8765e2f318dc78bc74497e5528bb6339bcd7b Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Thu, 3 Sep 2020 10:14:44 -0700 Subject: [PATCH 18/45] Fix plus decoding (#379) --- src/Microsoft.Owin/Infrastructure/OwinHelpers.cs | 4 ++-- tests/Microsoft.Owin.Tests/QueryTests.cs | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.Owin/Infrastructure/OwinHelpers.cs b/src/Microsoft.Owin/Infrastructure/OwinHelpers.cs index 11a32b615..b82bd5e12 100644 --- a/src/Microsoft.Owin/Infrastructure/OwinHelpers.cs +++ b/src/Microsoft.Owin/Infrastructure/OwinHelpers.cs @@ -562,8 +562,8 @@ internal static void ParseDelimited(string text, char[] delimiters, Action Date: Thu, 3 Sep 2020 10:57:17 -0700 Subject: [PATCH 19/45] Use License Expression #319 (#378) --- build/Katana.version.targets | 1 - build/Sakefile.shade | 5 +---- src/Microsoft.Owin.Cors/Microsoft.Owin.Cors.nuspec | 2 +- .../Microsoft.Owin.Diagnostics.nuspec | 2 +- .../Microsoft.Owin.FileSystems.nuspec | 2 +- .../Microsoft.Owin.Host.HttpListener.nuspec | 2 +- .../Microsoft.Owin.Host.SystemWeb.nuspec | 2 +- src/Microsoft.Owin.Hosting/Microsoft.Owin.Hosting.nuspec | 2 +- .../Microsoft.Owin.Security.ActiveDirectory.nuspec | 2 +- .../Microsoft.Owin.Security.Cookies.nuspec | 2 +- .../Microsoft.Owin.Security.Facebook.nuspec | 2 +- .../Microsoft.Owin.Security.Google.nuspec | 2 +- .../Microsoft.Owin.Security.Jwt.nuspec | 2 +- .../Microsoft.Owin.Security.MicrosoftAccount.nuspec | 2 +- .../Microsoft.Owin.Security.OAuth.nuspec | 2 +- .../Microsoft.Owin.Security.OpenIdConnect.nuspec | 2 +- .../Microsoft.Owin.Security.Twitter.nuspec | 2 +- .../Microsoft.Owin.Security.WsFederation.nuspec | 2 +- src/Microsoft.Owin.Security/Microsoft.Owin.Security.nuspec | 2 +- src/Microsoft.Owin.SelfHost/Microsoft.Owin.SelfHost.nuspec | 2 +- .../Microsoft.Owin.StaticFiles.nuspec | 2 +- src/Microsoft.Owin.Testing/Microsoft.Owin.Testing.nuspec | 2 +- src/Microsoft.Owin/Microsoft.Owin.nuspec | 2 +- src/OwinHost/OwinHost.nuspec | 2 +- 24 files changed, 23 insertions(+), 27 deletions(-) diff --git a/build/Katana.version.targets b/build/Katana.version.targets index 6e9ec9e81..0b55d41da 100644 --- a/build/Katana.version.targets +++ b/build/Katana.version.targets @@ -11,7 +11,6 @@ rtw 90831 - https://raw.githubusercontent.com/aspnet/AspNetKatana/v4.0.1/LICENSE.txt https://github.com/aspnet/AspNetKatana/ Microsoft OWIN Katana diff --git a/build/Sakefile.shade b/build/Sakefile.shade index f5f0edbfb..8d1fa962d 100644 --- a/build/Sakefile.shade +++ b/build/Sakefile.shade @@ -8,7 +8,6 @@ var AZUREAD_VERSION='5.3.0' var AZUREAD_SUFFIX='' var VERSION='${SHIP.VERSION}' var FULL_VERSION='${SHIP.FULL_VERSION}' -var EULA='https://raw.githubusercontent.com/aspnet/AspNetKatana/v4.0.1/LICENSE.txt' var PROJECT_URL='https://github.com/aspnet/AspNetKatana/' var TAGS='Microsoft OWIN Katana' @@ -107,7 +106,6 @@ use-standard-goals features='nuget,xunit' + " " + SHIP.MILESTONE + "" + Environment.NewLine + " " + BuildDate() + "" + Environment.NewLine + " " + BranchSuffix() + "" + Environment.NewLine - + " " + EULA + "" + Environment.NewLine + " " + PROJECT_URL + "" + Environment.NewLine + " " + TAGS + "" + Environment.NewLine + " " + Environment.NewLine @@ -275,11 +273,10 @@ var signing='${new List()}' var azureAdSuffix='${AZUREAD_SUFFIX}' set azureAdSuffix='' if='OFFICIAL_BUILD && RELEASE_BUILD && FINAL_MILESTONE' - var licenseUrl='${EULA}' var projectUrl='${PROJECT_URL}' var tags='${TAGS}' - nuget-pack nuspecFile='${file}' outputDir='${TARGET_DIR}' extra='-NoPackageAnalysis -Symbols -Properties "id=${baseName};authors=${AUTHORS};author=${AUTHORS};title=${title};description=${description};licenseUrl=${licenseUrl};projectUrl=${projectUrl};tags=${tags};azureAdVersion=${azureAdVersion};azureAdSuffix=${azureAdSuffix}"' + nuget-pack nuspecFile='${file}' outputDir='${TARGET_DIR}' extra='-NoPackageAnalysis -Symbols -Properties "id=${baseName};authors=${AUTHORS};author=${AUTHORS};title=${title};description=${description};projectUrl=${projectUrl};tags=${tags};azureAdVersion=${azureAdVersion};azureAdSuffix=${azureAdSuffix}"' #nuget-deploy target='deploy' description='Upload NuGet packages to gallery' var extra='' diff --git a/src/Microsoft.Owin.Cors/Microsoft.Owin.Cors.nuspec b/src/Microsoft.Owin.Cors/Microsoft.Owin.Cors.nuspec index 7acd39d39..5456f6ffa 100644 --- a/src/Microsoft.Owin.Cors/Microsoft.Owin.Cors.nuspec +++ b/src/Microsoft.Owin.Cors/Microsoft.Owin.Cors.nuspec @@ -6,7 +6,7 @@ $authors$ $authors$ © Microsoft Corporation. All rights reserved. - $licenseUrl$ + Apache-2.0 $projectUrl$ true $title$ diff --git a/src/Microsoft.Owin.Diagnostics/Microsoft.Owin.Diagnostics.nuspec b/src/Microsoft.Owin.Diagnostics/Microsoft.Owin.Diagnostics.nuspec index 66f784769..94254a357 100644 --- a/src/Microsoft.Owin.Diagnostics/Microsoft.Owin.Diagnostics.nuspec +++ b/src/Microsoft.Owin.Diagnostics/Microsoft.Owin.Diagnostics.nuspec @@ -6,7 +6,7 @@ $authors$ $authors$ © Microsoft Corporation. All rights reserved. - $licenseUrl$ + Apache-2.0 $projectUrl$ true $title$ diff --git a/src/Microsoft.Owin.FileSystems/Microsoft.Owin.FileSystems.nuspec b/src/Microsoft.Owin.FileSystems/Microsoft.Owin.FileSystems.nuspec index 0d887b476..ddeb94a00 100644 --- a/src/Microsoft.Owin.FileSystems/Microsoft.Owin.FileSystems.nuspec +++ b/src/Microsoft.Owin.FileSystems/Microsoft.Owin.FileSystems.nuspec @@ -6,7 +6,7 @@ $authors$ $authors$ © Microsoft Corporation. All rights reserved. - $licenseUrl$ + Apache-2.0 $projectUrl$ true $title$ diff --git a/src/Microsoft.Owin.Host.HttpListener/Microsoft.Owin.Host.HttpListener.nuspec b/src/Microsoft.Owin.Host.HttpListener/Microsoft.Owin.Host.HttpListener.nuspec index 537b803c7..9e19e4bd4 100644 --- a/src/Microsoft.Owin.Host.HttpListener/Microsoft.Owin.Host.HttpListener.nuspec +++ b/src/Microsoft.Owin.Host.HttpListener/Microsoft.Owin.Host.HttpListener.nuspec @@ -6,7 +6,7 @@ $authors$ $authors$ © Microsoft Corporation. All rights reserved. - $licenseUrl$ + Apache-2.0 $projectUrl$ true $title$ diff --git a/src/Microsoft.Owin.Host.SystemWeb/Microsoft.Owin.Host.SystemWeb.nuspec b/src/Microsoft.Owin.Host.SystemWeb/Microsoft.Owin.Host.SystemWeb.nuspec index 50810b3c2..6ff94ba82 100644 --- a/src/Microsoft.Owin.Host.SystemWeb/Microsoft.Owin.Host.SystemWeb.nuspec +++ b/src/Microsoft.Owin.Host.SystemWeb/Microsoft.Owin.Host.SystemWeb.nuspec @@ -5,7 +5,7 @@ $authors$ $authors$ © Microsoft Corporation. All rights reserved. - $licenseUrl$ + Apache-2.0 $projectUrl$ true $title$ diff --git a/src/Microsoft.Owin.Hosting/Microsoft.Owin.Hosting.nuspec b/src/Microsoft.Owin.Hosting/Microsoft.Owin.Hosting.nuspec index dd42bb436..e33f47ecf 100644 --- a/src/Microsoft.Owin.Hosting/Microsoft.Owin.Hosting.nuspec +++ b/src/Microsoft.Owin.Hosting/Microsoft.Owin.Hosting.nuspec @@ -6,7 +6,7 @@ $authors$ $authors$ © Microsoft Corporation. All rights reserved. - $licenseUrl$ + Apache-2.0 $projectUrl$ true $title$ diff --git a/src/Microsoft.Owin.Security.ActiveDirectory/Microsoft.Owin.Security.ActiveDirectory.nuspec b/src/Microsoft.Owin.Security.ActiveDirectory/Microsoft.Owin.Security.ActiveDirectory.nuspec index fa9946f25..ef269f5a0 100644 --- a/src/Microsoft.Owin.Security.ActiveDirectory/Microsoft.Owin.Security.ActiveDirectory.nuspec +++ b/src/Microsoft.Owin.Security.ActiveDirectory/Microsoft.Owin.Security.ActiveDirectory.nuspec @@ -6,7 +6,7 @@ $authors$ $authors$ © Microsoft Corporation. All rights reserved. - $licenseUrl$ + Apache-2.0 $projectUrl$ true $title$ diff --git a/src/Microsoft.Owin.Security.Cookies/Microsoft.Owin.Security.Cookies.nuspec b/src/Microsoft.Owin.Security.Cookies/Microsoft.Owin.Security.Cookies.nuspec index b644a5b48..26e7757e1 100644 --- a/src/Microsoft.Owin.Security.Cookies/Microsoft.Owin.Security.Cookies.nuspec +++ b/src/Microsoft.Owin.Security.Cookies/Microsoft.Owin.Security.Cookies.nuspec @@ -6,7 +6,7 @@ $authors$ $authors$ © Microsoft Corporation. All rights reserved. - $licenseUrl$ + Apache-2.0 $projectUrl$ true $title$ diff --git a/src/Microsoft.Owin.Security.Facebook/Microsoft.Owin.Security.Facebook.nuspec b/src/Microsoft.Owin.Security.Facebook/Microsoft.Owin.Security.Facebook.nuspec index a32767392..e7c2605e4 100644 --- a/src/Microsoft.Owin.Security.Facebook/Microsoft.Owin.Security.Facebook.nuspec +++ b/src/Microsoft.Owin.Security.Facebook/Microsoft.Owin.Security.Facebook.nuspec @@ -6,7 +6,7 @@ $authors$ $authors$ © Microsoft Corporation. All rights reserved. - $licenseUrl$ + Apache-2.0 $projectUrl$ true $title$ diff --git a/src/Microsoft.Owin.Security.Google/Microsoft.Owin.Security.Google.nuspec b/src/Microsoft.Owin.Security.Google/Microsoft.Owin.Security.Google.nuspec index 148ac42ff..6b041864d 100644 --- a/src/Microsoft.Owin.Security.Google/Microsoft.Owin.Security.Google.nuspec +++ b/src/Microsoft.Owin.Security.Google/Microsoft.Owin.Security.Google.nuspec @@ -6,7 +6,7 @@ $authors$ $authors$ © Microsoft Corporation. All rights reserved. - $licenseUrl$ + Apache-2.0 $projectUrl$ true $title$ diff --git a/src/Microsoft.Owin.Security.Jwt/Microsoft.Owin.Security.Jwt.nuspec b/src/Microsoft.Owin.Security.Jwt/Microsoft.Owin.Security.Jwt.nuspec index 4da7593b9..c9bdf019c 100644 --- a/src/Microsoft.Owin.Security.Jwt/Microsoft.Owin.Security.Jwt.nuspec +++ b/src/Microsoft.Owin.Security.Jwt/Microsoft.Owin.Security.Jwt.nuspec @@ -6,7 +6,7 @@ $authors$ $authors$ © Microsoft Corporation. All rights reserved. - $licenseUrl$ + Apache-2.0 $projectUrl$ true $title$ diff --git a/src/Microsoft.Owin.Security.MicrosoftAccount/Microsoft.Owin.Security.MicrosoftAccount.nuspec b/src/Microsoft.Owin.Security.MicrosoftAccount/Microsoft.Owin.Security.MicrosoftAccount.nuspec index fb573e112..9cdf3281a 100644 --- a/src/Microsoft.Owin.Security.MicrosoftAccount/Microsoft.Owin.Security.MicrosoftAccount.nuspec +++ b/src/Microsoft.Owin.Security.MicrosoftAccount/Microsoft.Owin.Security.MicrosoftAccount.nuspec @@ -6,7 +6,7 @@ $authors$ $authors$ © Microsoft Corporation. All rights reserved. - $licenseUrl$ + Apache-2.0 $projectUrl$ true $title$ diff --git a/src/Microsoft.Owin.Security.OAuth/Microsoft.Owin.Security.OAuth.nuspec b/src/Microsoft.Owin.Security.OAuth/Microsoft.Owin.Security.OAuth.nuspec index ab8c1a76f..02743c47e 100644 --- a/src/Microsoft.Owin.Security.OAuth/Microsoft.Owin.Security.OAuth.nuspec +++ b/src/Microsoft.Owin.Security.OAuth/Microsoft.Owin.Security.OAuth.nuspec @@ -6,7 +6,7 @@ $authors$ $authors$ © Microsoft Corporation. All rights reserved. - $licenseUrl$ + Apache-2.0 $projectUrl$ true $title$ diff --git a/src/Microsoft.Owin.Security.OpenIdConnect/Microsoft.Owin.Security.OpenIdConnect.nuspec b/src/Microsoft.Owin.Security.OpenIdConnect/Microsoft.Owin.Security.OpenIdConnect.nuspec index a99ffacfd..5568820c5 100644 --- a/src/Microsoft.Owin.Security.OpenIdConnect/Microsoft.Owin.Security.OpenIdConnect.nuspec +++ b/src/Microsoft.Owin.Security.OpenIdConnect/Microsoft.Owin.Security.OpenIdConnect.nuspec @@ -6,7 +6,7 @@ $authors$ $authors$ © Microsoft Corporation. All rights reserved. - $licenseUrl$ + Apache-2.0 $projectUrl$ true $title$ diff --git a/src/Microsoft.Owin.Security.Twitter/Microsoft.Owin.Security.Twitter.nuspec b/src/Microsoft.Owin.Security.Twitter/Microsoft.Owin.Security.Twitter.nuspec index 802c3e23b..4c10e7223 100644 --- a/src/Microsoft.Owin.Security.Twitter/Microsoft.Owin.Security.Twitter.nuspec +++ b/src/Microsoft.Owin.Security.Twitter/Microsoft.Owin.Security.Twitter.nuspec @@ -6,7 +6,7 @@ $authors$ $authors$ © Microsoft Corporation. All rights reserved. - $licenseUrl$ + Apache-2.0 $projectUrl$ true $title$ diff --git a/src/Microsoft.Owin.Security.WsFederation/Microsoft.Owin.Security.WsFederation.nuspec b/src/Microsoft.Owin.Security.WsFederation/Microsoft.Owin.Security.WsFederation.nuspec index db31b68a2..3d63188c8 100644 --- a/src/Microsoft.Owin.Security.WsFederation/Microsoft.Owin.Security.WsFederation.nuspec +++ b/src/Microsoft.Owin.Security.WsFederation/Microsoft.Owin.Security.WsFederation.nuspec @@ -6,7 +6,7 @@ $authors$ $authors$ © Microsoft Corporation. All rights reserved. - $licenseUrl$ + Apache-2.0 $projectUrl$ true $title$ diff --git a/src/Microsoft.Owin.Security/Microsoft.Owin.Security.nuspec b/src/Microsoft.Owin.Security/Microsoft.Owin.Security.nuspec index 641a68011..66127b87b 100644 --- a/src/Microsoft.Owin.Security/Microsoft.Owin.Security.nuspec +++ b/src/Microsoft.Owin.Security/Microsoft.Owin.Security.nuspec @@ -6,7 +6,7 @@ $authors$ $authors$ © Microsoft Corporation. All rights reserved. - $licenseUrl$ + Apache-2.0 $projectUrl$ true $title$ diff --git a/src/Microsoft.Owin.SelfHost/Microsoft.Owin.SelfHost.nuspec b/src/Microsoft.Owin.SelfHost/Microsoft.Owin.SelfHost.nuspec index c9ae012c5..024a0bb05 100644 --- a/src/Microsoft.Owin.SelfHost/Microsoft.Owin.SelfHost.nuspec +++ b/src/Microsoft.Owin.SelfHost/Microsoft.Owin.SelfHost.nuspec @@ -6,7 +6,7 @@ $authors$ $authors$ © Microsoft Corporation. All rights reserved. - $licenseUrl$ + Apache-2.0 $projectUrl$ true $title$ diff --git a/src/Microsoft.Owin.StaticFiles/Microsoft.Owin.StaticFiles.nuspec b/src/Microsoft.Owin.StaticFiles/Microsoft.Owin.StaticFiles.nuspec index b3db55604..677000bd3 100644 --- a/src/Microsoft.Owin.StaticFiles/Microsoft.Owin.StaticFiles.nuspec +++ b/src/Microsoft.Owin.StaticFiles/Microsoft.Owin.StaticFiles.nuspec @@ -6,7 +6,7 @@ $authors$ $authors$ © Microsoft Corporation. All rights reserved. - $licenseUrl$ + Apache-2.0 $projectUrl$ true $title$ diff --git a/src/Microsoft.Owin.Testing/Microsoft.Owin.Testing.nuspec b/src/Microsoft.Owin.Testing/Microsoft.Owin.Testing.nuspec index 267f90efa..e232ffc27 100644 --- a/src/Microsoft.Owin.Testing/Microsoft.Owin.Testing.nuspec +++ b/src/Microsoft.Owin.Testing/Microsoft.Owin.Testing.nuspec @@ -6,7 +6,7 @@ $authors$ $authors$ © Microsoft Corporation. All rights reserved. - $licenseUrl$ + Apache-2.0 $projectUrl$ true $title$ diff --git a/src/Microsoft.Owin/Microsoft.Owin.nuspec b/src/Microsoft.Owin/Microsoft.Owin.nuspec index a0b9257ef..29b2ee42d 100644 --- a/src/Microsoft.Owin/Microsoft.Owin.nuspec +++ b/src/Microsoft.Owin/Microsoft.Owin.nuspec @@ -6,7 +6,7 @@ $authors$ $authors$ © Microsoft Corporation. All rights reserved. - $licenseUrl$ + Apache-2.0 $projectUrl$ true $title$ diff --git a/src/OwinHost/OwinHost.nuspec b/src/OwinHost/OwinHost.nuspec index 66c7f04f4..28220e3e8 100644 --- a/src/OwinHost/OwinHost.nuspec +++ b/src/OwinHost/OwinHost.nuspec @@ -6,7 +6,7 @@ $authors$ $authors$ © Microsoft Corporation. All rights reserved. - $licenseUrl$ + Apache-2.0 $projectUrl$ true $title$ From 7aa465d56878b43409a603cf5384e7614cc35e19 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Tue, 8 Sep 2020 09:28:06 -0700 Subject: [PATCH 20/45] Update OAuth endpoints #327 (#380) --- src/Microsoft.Owin.Security.Facebook/Constants.cs | 7 ++++--- src/Microsoft.Owin.Security.Google/Constants.cs | 3 ++- .../Constants.cs | 1 + .../TwitterAuthenticationHandler.cs | 3 +++ src/Microsoft.Owin/Infrastructure/OwinHelpers.cs | 2 +- tests/Katana.Sandbox.WebServer/Startup.cs | 4 ++-- tests/Microsoft.Owin.Tests/FormsTests.cs | 14 +++++++++----- 7 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/Microsoft.Owin.Security.Facebook/Constants.cs b/src/Microsoft.Owin.Security.Facebook/Constants.cs index 9d80f70ee..4ef9e04ab 100644 --- a/src/Microsoft.Owin.Security.Facebook/Constants.cs +++ b/src/Microsoft.Owin.Security.Facebook/Constants.cs @@ -7,8 +7,9 @@ internal static class Constants { public const string DefaultAuthenticationType = "Facebook"; - internal const string AuthorizationEndpoint = "https://www.facebook.com/v2.8/dialog/oauth"; - internal const string TokenEndpoint = "https://graph.facebook.com/v2.8/oauth/access_token"; - internal const string UserInformationEndpoint = "https://graph.facebook.com/v2.8/me"; + // https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow#login + internal const string AuthorizationEndpoint = "https://www.facebook.com/v8.0/dialog/oauth"; + internal const string TokenEndpoint = "https://graph.facebook.com/v8.0/oauth/access_token"; + internal const string UserInformationEndpoint = "https://graph.facebook.com/v8.0/me"; } } diff --git a/src/Microsoft.Owin.Security.Google/Constants.cs b/src/Microsoft.Owin.Security.Google/Constants.cs index c153fd3a8..24f34a72c 100644 --- a/src/Microsoft.Owin.Security.Google/Constants.cs +++ b/src/Microsoft.Owin.Security.Google/Constants.cs @@ -7,8 +7,9 @@ internal static class Constants { internal const string DefaultAuthenticationType = "Google"; + // https://developers.google.com/identity/protocols/oauth2/web-server#httprest internal const string AuthorizationEndpoint = "https://accounts.google.com/o/oauth2/v2/auth"; - internal const string TokenEndpoint = "https://www.googleapis.com/oauth2/v4/token"; + internal const string TokenEndpoint = "https://oauth2.googleapis.com/token"; internal const string UserInformationEndpoint = "https://www.googleapis.com/oauth2/v2/userinfo"; } } diff --git a/src/Microsoft.Owin.Security.MicrosoftAccount/Constants.cs b/src/Microsoft.Owin.Security.MicrosoftAccount/Constants.cs index e80df4151..e5b242eff 100644 --- a/src/Microsoft.Owin.Security.MicrosoftAccount/Constants.cs +++ b/src/Microsoft.Owin.Security.MicrosoftAccount/Constants.cs @@ -7,6 +7,7 @@ internal static class Constants { internal const string DefaultAuthenticationType = "Microsoft"; + // https://developer.microsoft.com/en-us/graph/docs/concepts/auth_v2_user internal const string AuthorizationEndpoint = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize"; internal const string TokenEndpoint = "https://login.microsoftonline.com/common/oauth2/v2.0/token"; internal const string UserInformationEndpoint = "https://graph.microsoft.com/v1.0/me"; diff --git a/src/Microsoft.Owin.Security.Twitter/TwitterAuthenticationHandler.cs b/src/Microsoft.Owin.Security.Twitter/TwitterAuthenticationHandler.cs index 1935a7af3..3198d964c 100644 --- a/src/Microsoft.Owin.Security.Twitter/TwitterAuthenticationHandler.cs +++ b/src/Microsoft.Owin.Security.Twitter/TwitterAuthenticationHandler.cs @@ -21,8 +21,11 @@ internal class TwitterAuthenticationHandler : AuthenticationHandler form = new Dictionary(StringComparer.OrdinalIgnoreCase); var accumulator = new Dictionary>(StringComparer.OrdinalIgnoreCase); - ParseDelimited(text, new[] { '&' }, AppendItemCallback, decodePlus: false, decodeKey: true, state: accumulator); + ParseDelimited(text, new[] { '&' }, AppendItemCallback, decodePlus: true, decodeKey: true, state: accumulator); foreach (var kv in accumulator) { form.Add(kv.Key, kv.Value.ToArray()); diff --git a/tests/Katana.Sandbox.WebServer/Startup.cs b/tests/Katana.Sandbox.WebServer/Startup.cs index 235ea7ee5..34389d875 100644 --- a/tests/Katana.Sandbox.WebServer/Startup.cs +++ b/tests/Katana.Sandbox.WebServer/Startup.cs @@ -136,13 +136,13 @@ public void Configuration(IAppBuilder app) app.UseOpenIdConnectAuthentication(new Microsoft.Owin.Security.OpenIdConnect.OpenIdConnectAuthenticationOptions() { // https://github.com/IdentityServer/IdentityServer4.Demo/blob/master/src/IdentityServer4Demo/Config.cs - ClientId = "server.hybrid", + ClientId = "hybrid", ClientSecret = "secret", // for code flow Authority = "https://demo.identityserver.io/", + RedirectUri = "https://localhost:44318/signin-oidc", /* Authority = Environment.GetEnvironmentVariable("oidc:authority"), ClientId = Environment.GetEnvironmentVariable("oidc:clientid"), - RedirectUri = "https://localhost:44318/", ClientSecret = Environment.GetEnvironmentVariable("oidc:clientsecret"),*/ // CookieManager = new SystemWebCookieManager(), CookieManager = new SameSiteCookieManager(), diff --git a/tests/Microsoft.Owin.Tests/FormsTests.cs b/tests/Microsoft.Owin.Tests/FormsTests.cs index 873beceeb..ba442ac2a 100644 --- a/tests/Microsoft.Owin.Tests/FormsTests.cs +++ b/tests/Microsoft.Owin.Tests/FormsTests.cs @@ -14,7 +14,7 @@ public class FormsTests private static readonly string[] RawValues = new[] { "v1", "v2, v3", "\"v4, b\"", "v5, v6", "v7", }; private const string JoinedValues = "v1,v2, v3,\"v4, b\",v5, v6,v7"; - private const string OriginalFormsString = "q1=v1&q2=v2,b&q3=v3&q3=v4&q4&q5=v5&q5=v+5"; + private const string OriginalFormsString = "q1=v1&q2=v2,b&q3=v3&q3=v4&q4&q5=v5&q5=v5&q+6=v+6"; [Fact] public void ParseForm() @@ -30,7 +30,8 @@ public void ParseForm() Assert.Equal("v2,b", form.Get("Q2")); Assert.Equal("v3,v4", form.Get("q3")); Assert.Null(form.Get("q4")); - Assert.Equal("v5,v+5", form.Get("Q5")); + Assert.Equal("v5,v5", form.Get("Q5")); + Assert.Equal("v 6", form.Get("Q 6")); Assert.True(stream.CanRead); } @@ -89,7 +90,8 @@ public void ReadFromStream() Assert.Equal("v2,b", form.Get("Q2")); Assert.Equal("v3,v4", form.Get("q3")); Assert.Null(form.Get("q4")); - Assert.Equal("v5,v+5", form.Get("Q5")); + Assert.Equal("v5,v5", form.Get("Q5")); + Assert.Equal("v 6", form.Get("Q 6")); } [Fact] @@ -107,14 +109,16 @@ public void ReadFromStreamTwice() Assert.Equal("v2,b", form.Get("Q2")); Assert.Equal("v3,v4", form.Get("q3")); Assert.Null(form.Get("q4")); - Assert.Equal("v5,v+5", form.Get("Q5")); + Assert.Equal("v5,v5", form.Get("Q5")); + Assert.Equal("v 6", form.Get("Q 6")); form = request.ReadFormAsync().Result; Assert.Equal("v1", form.Get("q1")); Assert.Equal("v2,b", form.Get("Q2")); Assert.Equal("v3,v4", form.Get("q3")); Assert.Null(form.Get("q4")); - Assert.Equal("v5,v+5", form.Get("Q5")); + Assert.Equal("v5,v5", form.Get("Q5")); + Assert.Equal("v 6", form.Get("Q 6")); } } } From 1fba52940ccfa74470c75c627699baca13aadfa4 Mon Sep 17 00:00:00 2001 From: Rok Zontar Date: Thu, 10 Dec 2020 18:30:43 +0100 Subject: [PATCH 21/45] Backport ASP.NET Core PKCE Support to OpenIdConnectAuthenticationHandler (#389) --- ...crosoft.Owin.Security.OpenIdConnect.csproj | 1 + .../OAuthConstants.cs | 30 +++ .../OpenIdConnectAuthenticationOptions.cs | 14 +- .../OpenidConnectAuthenticationHandler.cs | 35 +++- tests/Katana.Sandbox.WebServer/Startup.cs | 18 +- .../Microsoft.Owin.Security.Tests.csproj | 7 + .../OpenIdConnectMiddlewareTests.cs | 182 ++++++++++++++++++ .../packages.config | 2 + 8 files changed, 278 insertions(+), 11 deletions(-) create mode 100644 src/Microsoft.Owin.Security.OpenIdConnect/OAuthConstants.cs create mode 100644 tests/Microsoft.Owin.Security.Tests/OpenIdConnect/OpenIdConnectMiddlewareTests.cs diff --git a/src/Microsoft.Owin.Security.OpenIdConnect/Microsoft.Owin.Security.OpenIdConnect.csproj b/src/Microsoft.Owin.Security.OpenIdConnect/Microsoft.Owin.Security.OpenIdConnect.csproj index 24e5f2d2f..3715c8304 100644 --- a/src/Microsoft.Owin.Security.OpenIdConnect/Microsoft.Owin.Security.OpenIdConnect.csproj +++ b/src/Microsoft.Owin.Security.OpenIdConnect/Microsoft.Owin.Security.OpenIdConnect.csproj @@ -86,6 +86,7 @@ + diff --git a/src/Microsoft.Owin.Security.OpenIdConnect/OAuthConstants.cs b/src/Microsoft.Owin.Security.OpenIdConnect/OAuthConstants.cs new file mode 100644 index 000000000..3d744b6b4 --- /dev/null +++ b/src/Microsoft.Owin.Security.OpenIdConnect/OAuthConstants.cs @@ -0,0 +1,30 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.Owin.Security.OpenIdConnect +{ + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Auth", + Justification = "OAuth2 is a valid word.")] + internal static class OAuthConstants + { + /// + /// code_verifier defined in https://tools.ietf.org/html/rfc7636 + /// + public const string CodeVerifierKey = "code_verifier"; + + /// + /// code_challenge defined in https://tools.ietf.org/html/rfc7636 + /// + public const string CodeChallengeKey = "code_challenge"; + + /// + /// code_challenge_method defined in https://tools.ietf.org/html/rfc7636 + /// + public const string CodeChallengeMethodKey = "code_challenge_method"; + + /// + /// S256 defined in https://tools.ietf.org/html/rfc7636 + /// + public const string CodeChallengeMethodS256 = "S256"; + } +} \ No newline at end of file diff --git a/src/Microsoft.Owin.Security.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs b/src/Microsoft.Owin.Security.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs index 1fe8fc432..00c5f398b 100644 --- a/src/Microsoft.Owin.Security.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs +++ b/src/Microsoft.Owin.Security.OpenIdConnect/OpenIdConnectAuthenticationOptions.cs @@ -47,6 +47,7 @@ public OpenIdConnectAuthenticationOptions() /// TokenValidationParameters: new with AuthenticationType = authenticationType. /// UseTokenLifetime: true. /// RedeemCode: false. + /// UsePkce: true. /// /// will be used to when creating the for the AuthenticationType property. [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "Microsoft.Owin.Security.OpenIdConnect.OpenIdConnectAuthenticationOptions.set_Caption(System.String)", Justification = "Not a LOC field")] @@ -71,6 +72,7 @@ public OpenIdConnectAuthenticationOptions(string authenticationType) UseTokenLifetime = true; CookieManager = new CookieManager(); RedeemCode = false; + UsePkce = true; } /// @@ -322,5 +324,15 @@ public bool UseTokenLifetime /// This property is set to false by default. /// public bool RedeemCode { get; set; } + + /// + /// Enables or disables the use of the Proof Key for Code Exchange (PKCE) standard. + /// This only applies when the is set to . + /// See https://tools.ietf.org/html/rfc7636. + /// The default value is `true`. + /// + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Pkce", + Justification = "Pkce is a valid acronym.")] + public bool UsePkce { get; set; } } -} \ No newline at end of file +} diff --git a/src/Microsoft.Owin.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs b/src/Microsoft.Owin.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs index 0d54beb37..2ec402162 100644 --- a/src/Microsoft.Owin.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs +++ b/src/Microsoft.Owin.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs @@ -16,6 +16,7 @@ using Microsoft.IdentityModel.Protocols.OpenIdConnect; using Microsoft.IdentityModel.Tokens; using Microsoft.Owin.Logging; +using Microsoft.Owin.Security.DataHandler.Encoder; using Microsoft.Owin.Security.Infrastructure; using Microsoft.Owin.Security.Notifications; @@ -155,10 +156,31 @@ protected override async Task ApplyResponseChallengeAsync() RequestType = OpenIdConnectRequestType.Authentication, Resource = Options.Resource, ResponseType = Options.ResponseType, - Scope = Options.Scope, - State = OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey + "=" + Uri.EscapeDataString(Options.StateDataFormat.Protect(properties)), + Scope = Options.Scope }; + // https://tools.ietf.org/html/rfc7636 + if (Options.UsePkce && Options.ResponseType == OpenIdConnectResponseType.Code) + { + using (RandomNumberGenerator randomNumberGenerator = RandomNumberGenerator.Create()) + using (HashAlgorithm hash = SHA256.Create()) + { + byte[] bytes = new byte[32]; + randomNumberGenerator.GetBytes(bytes); + string codeVerifier = TextEncodings.Base64Url.Encode(bytes); + + // Store this for use during the code redemption. + properties.Dictionary.Add(OAuthConstants.CodeVerifierKey, codeVerifier); + byte[] challengeBytes = hash.ComputeHash(Encoding.UTF8.GetBytes(codeVerifier)); + string codeChallenge = TextEncodings.Base64Url.Encode(challengeBytes); + + openIdConnectMessage.Parameters.Add(OAuthConstants.CodeChallengeKey, codeChallenge); + openIdConnectMessage.Parameters.Add(OAuthConstants.CodeChallengeMethodKey, OAuthConstants.CodeChallengeMethodS256); + } + } + + openIdConnectMessage.State = OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey + "=" + Uri.EscapeDataString(Options.StateDataFormat.Protect(properties)); + // Omitting the response_mode parameter when it already corresponds to the default // response_mode used for the specified response_type is recommended by the specifications. // See http://openid.net/specs/oauth-v2-multiple-response-types-1_0.html#ResponseModes @@ -397,6 +419,15 @@ protected override async Task AuthenticateCoreAsync() RedirectUri = tokenEndpointRequest.RedirectUri, TokenEndpointRequest = tokenEndpointRequest }; + + // PKCE https://tools.ietf.org/html/rfc7636#section-4.5 + string codeVerifier; + if (properties.Dictionary.TryGetValue(OAuthConstants.CodeVerifierKey, out codeVerifier)) + { + tokenEndpointRequest.Parameters.Add(OAuthConstants.CodeVerifierKey, codeVerifier); + properties.Dictionary.Remove(OAuthConstants.CodeVerifierKey); + } + await Options.Notifications.AuthorizationCodeReceived(authorizationCodeReceivedNotification); if (authorizationCodeReceivedNotification.HandledResponse) { diff --git a/tests/Katana.Sandbox.WebServer/Startup.cs b/tests/Katana.Sandbox.WebServer/Startup.cs index 34389d875..0d5e882bc 100644 --- a/tests/Katana.Sandbox.WebServer/Startup.cs +++ b/tests/Katana.Sandbox.WebServer/Startup.cs @@ -10,6 +10,7 @@ using System.Security.Principal; using System.Threading.Tasks; using Katana.Sandbox.WebServer; +using Microsoft.IdentityModel.Protocols.OpenIdConnect; using Microsoft.Owin; using Microsoft.Owin.Extensions; using Microsoft.Owin.Host.SystemWeb; @@ -135,9 +136,9 @@ public void Configuration(IAppBuilder app) app.UseOpenIdConnectAuthentication(new Microsoft.Owin.Security.OpenIdConnect.OpenIdConnectAuthenticationOptions() { - // https://github.com/IdentityServer/IdentityServer4.Demo/blob/master/src/IdentityServer4Demo/Config.cs - ClientId = "hybrid", - ClientSecret = "secret", // for code flow + // https://github.com/IdentityServer/IdentityServer4.Demo/blob/main/src/IdentityServer4Demo/Config.cs + ClientId = "interactive.confidential.short", // client requires pkce + ClientSecret = "secret", Authority = "https://demo.identityserver.io/", RedirectUri = "https://localhost:44318/signin-oidc", /* @@ -146,11 +147,11 @@ public void Configuration(IAppBuilder app) ClientSecret = Environment.GetEnvironmentVariable("oidc:clientsecret"),*/ // CookieManager = new SystemWebCookieManager(), CookieManager = new SameSiteCookieManager(), - //ResponseType = "code", - //ResponseMode = "query", - //SaveTokens = true, - //Scope = "openid profile offline_access", - //RedeemCode = true, + ResponseType = OpenIdConnectResponseType.Code, + ResponseMode = OpenIdConnectResponseMode.Query, + SaveTokens = true, + Scope = "openid profile offline_access", + RedeemCode = true, //Notifications = new Microsoft.Owin.Security.OpenIdConnect.OpenIdConnectAuthenticationNotifications //{ // AuthorizationCodeReceived = async n => @@ -166,6 +167,7 @@ public void Configuration(IAppBuilder app) // n.HandleCodeRedemption(message); // } //} + UsePkce = true, }); /* diff --git a/tests/Microsoft.Owin.Security.Tests/Microsoft.Owin.Security.Tests.csproj b/tests/Microsoft.Owin.Security.Tests/Microsoft.Owin.Security.Tests.csproj index 94d867374..49943bb1c 100644 --- a/tests/Microsoft.Owin.Security.Tests/Microsoft.Owin.Security.Tests.csproj +++ b/tests/Microsoft.Owin.Security.Tests/Microsoft.Owin.Security.Tests.csproj @@ -43,6 +43,12 @@ ..\..\packages\Microsoft.IdentityModel.Logging.5.3.0\lib\net45\Microsoft.IdentityModel.Logging.dll True + + ..\..\packages\Microsoft.IdentityModel.Protocols.5.3.0\lib\net45\Microsoft.IdentityModel.Protocols.dll + + + ..\..\packages\Microsoft.IdentityModel.Protocols.OpenIdConnect.5.3.0\lib\net45\Microsoft.IdentityModel.Protocols.OpenIdConnect.dll + ..\..\packages\Microsoft.IdentityModel.Tokens.5.3.0\lib\net45\Microsoft.IdentityModel.Tokens.dll True @@ -89,6 +95,7 @@ + diff --git a/tests/Microsoft.Owin.Security.Tests/OpenIdConnect/OpenIdConnectMiddlewareTests.cs b/tests/Microsoft.Owin.Security.Tests/OpenIdConnect/OpenIdConnectMiddlewareTests.cs new file mode 100644 index 000000000..e93cd71e0 --- /dev/null +++ b/tests/Microsoft.Owin.Security.Tests/OpenIdConnect/OpenIdConnectMiddlewareTests.cs @@ -0,0 +1,182 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; +using System.Xml.Linq; +using Microsoft.IdentityModel.Protocols.OpenIdConnect; +using Microsoft.Owin.Security.Cookies; +using Microsoft.Owin.Security.OpenIdConnect; +using Microsoft.Owin.Testing; +using Owin; +using Xunit; +using Xunit.Extensions; + +namespace Microsoft.Owin.Security.Tests.OpenIdConnect +{ + public class OpenIdConnectMiddlewareTests + { + [Theory] + [InlineData(true)] + [InlineData(false)] + public async Task ChallengeIncludesPkceIfRequested(bool include) + { + var options = new OpenIdConnectAuthenticationOptions() + { + Authority = "https://demo.identityserver.io", + ClientId = "Test Client Id", + ClientSecret = "Test Client Secret", + UsePkce = include, + ResponseType = OpenIdConnectResponseType.Code + }; + var server = CreateServer( + app => app.UseOpenIdConnectAuthentication(options), + context => + { + context.Authentication.Challenge("OpenIdConnect"); + return true; + }); + + var transaction = await SendAsync(server, "http://example.com/challenge"); + + var res = transaction.Response; + Assert.Equal(HttpStatusCode.Redirect, res.StatusCode); + Assert.NotNull(res.Headers.Location); + + if (include) + { + Assert.Contains("code_challenge=", res.Headers.Location.Query); + Assert.Contains("code_challenge_method=S256", res.Headers.Location.Query); + } + else + { + Assert.DoesNotContain("code_challenge=", res.Headers.Location.Query); + Assert.DoesNotContain("code_challenge_method=", res.Headers.Location.Query); + } + } + + [Theory] + [InlineData(OpenIdConnectResponseType.Token)] + [InlineData(OpenIdConnectResponseType.IdToken)] + [InlineData(OpenIdConnectResponseType.CodeIdToken)] + public async Task ChallengeDoesNotIncludePkceForOtherResponseTypes(string responseType) + { + var options = new OpenIdConnectAuthenticationOptions() + { + Authority = "https://demo.identityserver.io", + ClientId = "Test Client Id", + ClientSecret = "Test Client Secret", + UsePkce = true, + ResponseType = responseType + }; + var server = CreateServer( + app => app.UseOpenIdConnectAuthentication(options), + context => + { + context.Authentication.Challenge("OpenIdConnect"); + return true; + }); + + var transaction = await SendAsync(server, "http://example.com/challenge"); + + var res = transaction.Response; + Assert.Equal(HttpStatusCode.Redirect, res.StatusCode); + Assert.NotNull(res.Headers.Location); + + Assert.DoesNotContain("code_challenge=", res.Headers.Location.Query); + Assert.DoesNotContain("code_challenge_method=", res.Headers.Location.Query); + } + + + private static TestServer CreateServer(Action configure, Func handler) + { + return TestServer.Create(app => + { + app.Properties["host.AppName"] = "OpenIdConnect.Owin.Security.Tests"; + app.UseCookieAuthentication(new CookieAuthenticationOptions + { + AuthenticationType = "External" + }); + app.SetDefaultSignInAsAuthenticationType("External"); + if (configure != null) + { + configure(app); + } + app.Use(async (context, next) => + { + if (handler == null || !handler(context)) + { + await next(); + } + }); + }); + } + + private static async Task SendAsync(TestServer server, string uri, string cookieHeader = null) + { + var request = new HttpRequestMessage(HttpMethod.Get, uri); + if (!string.IsNullOrEmpty(cookieHeader)) + { + request.Headers.Add("Cookie", cookieHeader); + } + var transaction = new Transaction + { + Request = request, + Response = await server.HttpClient.SendAsync(request), + }; + if (transaction.Response.Headers.Contains("Set-Cookie")) + { + transaction.SetCookie = transaction.Response.Headers.GetValues("Set-Cookie").ToList(); + } + transaction.ResponseText = await transaction.Response.Content.ReadAsStringAsync(); + + if (transaction.Response.Content != null && + transaction.Response.Content.Headers.ContentType != null && + transaction.Response.Content.Headers.ContentType.MediaType == "text/xml") + { + transaction.ResponseElement = XElement.Parse(transaction.ResponseText); + } + return transaction; + } + + private class Transaction + { + public HttpRequestMessage Request { get; set; } + public HttpResponseMessage Response { get; set; } + public IList SetCookie { get; set; } + public string ResponseText { get; set; } + public XElement ResponseElement { get; set; } + + public string AuthenticationCookieValue + { + get + { + if (SetCookie != null && SetCookie.Count > 0) + { + var authCookie = SetCookie.SingleOrDefault(c => c.Contains(".AspNet.External=")); + if (authCookie != null) + { + return authCookie.Substring(0, authCookie.IndexOf(';')); + } + } + + return null; + } + } + + public string FindClaimValue(string claimType) + { + XElement claim = ResponseElement.Elements("claim").SingleOrDefault(elt => elt.Attribute("type").Value == claimType); + if (claim == null) + { + return null; + } + return claim.Attribute("value").Value; + } + } + } +} diff --git a/tests/Microsoft.Owin.Security.Tests/packages.config b/tests/Microsoft.Owin.Security.Tests/packages.config index ba008f48d..e810e7063 100644 --- a/tests/Microsoft.Owin.Security.Tests/packages.config +++ b/tests/Microsoft.Owin.Security.Tests/packages.config @@ -2,6 +2,8 @@ + + From 7942cff211d5b43f21f4ee2f7407f8aa6a85dabb Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Tue, 9 Feb 2021 10:24:57 -0800 Subject: [PATCH 22/45] Fixup feeds (#399) Co-authored-by: Matt Mitchell --- .nuget/NuGet.Config | 10 ++++------ build/Sakefile.shade | 4 ++-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/.nuget/NuGet.Config b/.nuget/NuGet.Config index 60b352afc..3b04a7b74 100644 --- a/.nuget/NuGet.Config +++ b/.nuget/NuGet.Config @@ -4,14 +4,12 @@ - - - - + + - - + + \ No newline at end of file diff --git a/build/Sakefile.shade b/build/Sakefile.shade index 8d1fa962d..e11f811a4 100644 --- a/build/Sakefile.shade +++ b/build/Sakefile.shade @@ -21,8 +21,8 @@ var TEST_DIR='${Path.Combine(TARGET_DIR, "test")}' var SIGN_DIR='${Path.Combine(TARGET_DIR, "sign")}' var PACKAGE_DIR='${Path.Combine(TARGET_DIR, "package")}' -var NUGET_GALLERY_SOURCE='https://api.nuget.org/v3/index.json' -var NUGET_ASPNET_SOURCE='https://dotnet.myget.org/F/katana-dev/api/v3/index.json' +var NUGET_GALLERY_SOURCE='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json' +var NUGET_ASPNET_SOURCE='https://pkgs.dev.azure.com/dnceng/public/_packaging/myget-legacy/nuget/v3/index.json' -// var NUGET_AZUREAD_SOURCE='https://www.myget.org/F/azureadwebstacknightly/' var NUGET_AZUREAD_SOURCE='' From 74476cee7ee560711333a867cc1d4eaa92a7ca9b Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Tue, 9 Feb 2021 10:25:31 -0800 Subject: [PATCH 23/45] Fixup feeds (#398) Co-authored-by: Matt Mitchell --- .nuget/NuGet.Config | 10 ++++------ build/Sakefile.shade | 4 ++-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/.nuget/NuGet.Config b/.nuget/NuGet.Config index 60b352afc..3b04a7b74 100644 --- a/.nuget/NuGet.Config +++ b/.nuget/NuGet.Config @@ -4,14 +4,12 @@ - - - - + + - - + + \ No newline at end of file diff --git a/build/Sakefile.shade b/build/Sakefile.shade index 8d1fa962d..e11f811a4 100644 --- a/build/Sakefile.shade +++ b/build/Sakefile.shade @@ -21,8 +21,8 @@ var TEST_DIR='${Path.Combine(TARGET_DIR, "test")}' var SIGN_DIR='${Path.Combine(TARGET_DIR, "sign")}' var PACKAGE_DIR='${Path.Combine(TARGET_DIR, "package")}' -var NUGET_GALLERY_SOURCE='https://api.nuget.org/v3/index.json' -var NUGET_ASPNET_SOURCE='https://dotnet.myget.org/F/katana-dev/api/v3/index.json' +var NUGET_GALLERY_SOURCE='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json' +var NUGET_ASPNET_SOURCE='https://pkgs.dev.azure.com/dnceng/public/_packaging/myget-legacy/nuget/v3/index.json' -// var NUGET_AZUREAD_SOURCE='https://www.myget.org/F/azureadwebstacknightly/' var NUGET_AZUREAD_SOURCE='' From e6de33e82a593a8000ac3e661fc175f9d698ef28 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Tue, 9 Feb 2021 10:26:01 -0800 Subject: [PATCH 24/45] Fixup feeds (#397) Co-authored-by: Matt Mitchell --- .nuget/NuGet.Config | 10 ++++------ build/Sakefile.shade | 4 ++-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/.nuget/NuGet.Config b/.nuget/NuGet.Config index 60b352afc..3b04a7b74 100644 --- a/.nuget/NuGet.Config +++ b/.nuget/NuGet.Config @@ -4,14 +4,12 @@ - - - - + + - - + + \ No newline at end of file diff --git a/build/Sakefile.shade b/build/Sakefile.shade index 8d1fa962d..e11f811a4 100644 --- a/build/Sakefile.shade +++ b/build/Sakefile.shade @@ -21,8 +21,8 @@ var TEST_DIR='${Path.Combine(TARGET_DIR, "test")}' var SIGN_DIR='${Path.Combine(TARGET_DIR, "sign")}' var PACKAGE_DIR='${Path.Combine(TARGET_DIR, "package")}' -var NUGET_GALLERY_SOURCE='https://api.nuget.org/v3/index.json' -var NUGET_ASPNET_SOURCE='https://dotnet.myget.org/F/katana-dev/api/v3/index.json' +var NUGET_GALLERY_SOURCE='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json' +var NUGET_ASPNET_SOURCE='https://pkgs.dev.azure.com/dnceng/public/_packaging/myget-legacy/nuget/v3/index.json' -// var NUGET_AZUREAD_SOURCE='https://www.myget.org/F/azureadwebstacknightly/' var NUGET_AZUREAD_SOURCE='' From 1c9943570de6cbf4154202bcd4ef220067c3e62a Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Fri, 19 Feb 2021 16:09:41 -0800 Subject: [PATCH 25/45] Reduce dependencies (#401) --- .../Containers/CastleWindsorContainerTests.cs | 51 ------------------- .../Containers/NinjectContainerTests.cs | 38 -------------- .../Microsoft.Owin.Hosting.Tests.csproj | 10 ---- .../packages.config | 2 - 4 files changed, 101 deletions(-) delete mode 100644 tests/Microsoft.Owin.Hosting.Tests/Containers/CastleWindsorContainerTests.cs delete mode 100644 tests/Microsoft.Owin.Hosting.Tests/Containers/NinjectContainerTests.cs diff --git a/tests/Microsoft.Owin.Hosting.Tests/Containers/CastleWindsorContainerTests.cs b/tests/Microsoft.Owin.Hosting.Tests/Containers/CastleWindsorContainerTests.cs deleted file mode 100644 index 8ed5945a1..000000000 --- a/tests/Microsoft.Owin.Hosting.Tests/Containers/CastleWindsorContainerTests.cs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using Castle.MicroKernel; -using Castle.MicroKernel.Registration; -using Castle.MicroKernel.Resolvers.SpecializedResolvers; -using Castle.Windsor; -using Microsoft.Owin.Hosting.Loader; -using Microsoft.Owin.Hosting.Services; - -namespace Microsoft.Owin.Hosting.Tests.Containers -{ - public class CastleWindsorContainerTests : ContainerTestsBase - { - public override Func CreateContainer() - { - var container = new WindsorContainer(); - - container.Kernel.Resolver.AddSubResolver( - new CollectionResolver(container.Kernel, true)); - - container.Register( - Component.For().ImplementedBy()); - - ServicesFactory.ForEach((service, implementation) => - container.Register(Component.For(service).ImplementedBy(implementation))); - - container.Register( - Component.For().ImplementedBy(), - Component.For().ImplementedBy()); - - return container.Resolve; - } - - public class WindsorServiceProvider : IServiceProvider - { - private readonly IKernel _kernel; - - public WindsorServiceProvider(IKernel kernel) - { - _kernel = kernel; - } - - public object GetService(Type serviceType) - { - return _kernel.Resolve(serviceType); - } - } - } -} diff --git a/tests/Microsoft.Owin.Hosting.Tests/Containers/NinjectContainerTests.cs b/tests/Microsoft.Owin.Hosting.Tests/Containers/NinjectContainerTests.cs deleted file mode 100644 index 093af1116..000000000 --- a/tests/Microsoft.Owin.Hosting.Tests/Containers/NinjectContainerTests.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using Microsoft.Owin.Hosting.Loader; -using Microsoft.Owin.Hosting.Services; -using Ninject; - -namespace Microsoft.Owin.Hosting.Tests.Containers -{ - public class NinjectContainerTests : ContainerTestsBase - { - public override Func CreateContainer() - { - var kernel = new StandardKernel(); - kernel.Bind().To(); - ServicesFactory.ForEach((service, implementation) => kernel.Bind(service).To(implementation)); - kernel.Bind().To(); - kernel.Bind().To(); - return serviceType => kernel.Get(serviceType); - } - - public class NinjectServiceProvider : IServiceProvider - { - private readonly IKernel _kernel; - - public NinjectServiceProvider(IKernel kernel) - { - _kernel = kernel; - } - - public object GetService(Type serviceType) - { - return _kernel.Get(serviceType); - } - } - } -} diff --git a/tests/Microsoft.Owin.Hosting.Tests/Microsoft.Owin.Hosting.Tests.csproj b/tests/Microsoft.Owin.Hosting.Tests/Microsoft.Owin.Hosting.Tests.csproj index b0e1ac880..5da25a2ea 100644 --- a/tests/Microsoft.Owin.Hosting.Tests/Microsoft.Owin.Hosting.Tests.csproj +++ b/tests/Microsoft.Owin.Hosting.Tests/Microsoft.Owin.Hosting.Tests.csproj @@ -50,14 +50,6 @@ False ..\..\packages\Castle.Core.3.2.2\lib\net45\Castle.Core.dll - - False - ..\..\packages\Castle.Windsor.3.2.1\lib\net45\Castle.Windsor.dll - - - False - ..\..\packages\Ninject.3.0.1.10\lib\net45-full\Ninject.dll - False ..\..\packages\Owin.1.0\lib\net40\Owin.dll @@ -93,14 +85,12 @@ - - diff --git a/tests/Microsoft.Owin.Hosting.Tests/packages.config b/tests/Microsoft.Owin.Hosting.Tests/packages.config index edd79d6e6..379668733 100644 --- a/tests/Microsoft.Owin.Hosting.Tests/packages.config +++ b/tests/Microsoft.Owin.Hosting.Tests/packages.config @@ -2,8 +2,6 @@ - - From d196e785e277452f1382dded08ca12974d29170e Mon Sep 17 00:00:00 2001 From: Matthew Freeman <39219791+m6freeman@users.noreply.github.com> Date: Mon, 8 Mar 2021 11:53:53 -0500 Subject: [PATCH 26/45] Update AuthorizeEndpointRequest.cs documentation (#404) Line 63: changed documentation from "scope" to "state" to accurately reflect property --- .../Messages/AuthorizeEndpointRequest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.Owin.Security.OAuth/Messages/AuthorizeEndpointRequest.cs b/src/Microsoft.Owin.Security.OAuth/Messages/AuthorizeEndpointRequest.cs index 422be3681..b815584d9 100644 --- a/src/Microsoft.Owin.Security.OAuth/Messages/AuthorizeEndpointRequest.cs +++ b/src/Microsoft.Owin.Security.OAuth/Messages/AuthorizeEndpointRequest.cs @@ -60,7 +60,7 @@ public AuthorizeEndpointRequest(IReadableStringCollection parameters) public IList Scope { get; private set; } /// - /// The "scope" query string parameter of the Authorize request. May be absent if the client does not require state to be + /// The "state" query string parameter of the Authorize request. May be absent if the client does not require state to be /// included when returning to the RedirectUri. /// public string State { get; set; } From d702a05e83ae9be4212a270c4198985bb953619a Mon Sep 17 00:00:00 2001 From: Kahbazi Date: Tue, 27 Apr 2021 04:17:49 +0430 Subject: [PATCH 27/45] Unicode path in static files middleware (#411) --- .../DefaultFilesMiddleware.cs | 2 +- .../DefaultFilesMiddlewareTests.cs | 2 ++ .../Microsoft.Owin.StaticFiles.Tests.csproj | 6 ++++++ .../SubFolder/\344\275\240\345\245\275/Default.html" | 11 +++++++++++ .../\344\270\226\347\225\214/Default.html" | 11 +++++++++++ 5 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 "tests/Microsoft.Owin.StaticFiles.Tests/SubFolder/\344\275\240\345\245\275/Default.html" create mode 100644 "tests/Microsoft.Owin.StaticFiles.Tests/SubFolder/\344\275\240\345\245\275/\344\270\226\347\225\214/Default.html" diff --git a/src/Microsoft.Owin.StaticFiles/DefaultFilesMiddleware.cs b/src/Microsoft.Owin.StaticFiles/DefaultFilesMiddleware.cs index e4d9783ab..52f575b21 100644 --- a/src/Microsoft.Owin.StaticFiles/DefaultFilesMiddleware.cs +++ b/src/Microsoft.Owin.StaticFiles/DefaultFilesMiddleware.cs @@ -70,7 +70,7 @@ public Task Invoke(IDictionary environment) string defaultFile = _options.DefaultFileNames[matchIndex]; IFileInfo file; // TryMatchPath will make sure subpath always ends with a "/" by adding it if needed. - if (_options.FileSystem.TryGetFileInfo(subpath + defaultFile, out file)) + if (_options.FileSystem.TryGetFileInfo(subpath.Value + defaultFile, out file)) { // If the path matches a directory but does not end in a slash, redirect to add the slash. // This prevents relative links from breaking. diff --git a/tests/Microsoft.Owin.StaticFiles.Tests/DefaultFilesMiddlewareTests.cs b/tests/Microsoft.Owin.StaticFiles.Tests/DefaultFilesMiddlewareTests.cs index 644d924dc..3c67cf60f 100644 --- a/tests/Microsoft.Owin.StaticFiles.Tests/DefaultFilesMiddlewareTests.cs +++ b/tests/Microsoft.Owin.StaticFiles.Tests/DefaultFilesMiddlewareTests.cs @@ -61,6 +61,8 @@ public void NoMatch_PassesThrough(string baseUrl, string baseDir, string request [InlineData("", @".\", "/SubFolder/")] [InlineData("", @"SubFolder", "/")] [InlineData("", @".\SubFolder", "/")] + [InlineData("", @"./SubFolder", "/你好/")] + [InlineData("", @"./SubFolder", "/你好/世界/")] public void FoundDirectoryWithDefaultFile_PathModified(string baseUrl, string baseDir, string requestUrl) { IAppBuilder builder = new AppBuilder(); diff --git a/tests/Microsoft.Owin.StaticFiles.Tests/Microsoft.Owin.StaticFiles.Tests.csproj b/tests/Microsoft.Owin.StaticFiles.Tests/Microsoft.Owin.StaticFiles.Tests.csproj index f4df85fc4..81d892dfb 100644 --- a/tests/Microsoft.Owin.StaticFiles.Tests/Microsoft.Owin.StaticFiles.Tests.csproj +++ b/tests/Microsoft.Owin.StaticFiles.Tests/Microsoft.Owin.StaticFiles.Tests.csproj @@ -108,6 +108,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest diff --git "a/tests/Microsoft.Owin.StaticFiles.Tests/SubFolder/\344\275\240\345\245\275/Default.html" "b/tests/Microsoft.Owin.StaticFiles.Tests/SubFolder/\344\275\240\345\245\275/Default.html" new file mode 100644 index 000000000..4740d8368 --- /dev/null +++ "b/tests/Microsoft.Owin.StaticFiles.Tests/SubFolder/\344\275\240\345\245\275/Default.html" @@ -0,0 +1,11 @@ + + + + + + + + + Hello World + + \ No newline at end of file diff --git "a/tests/Microsoft.Owin.StaticFiles.Tests/SubFolder/\344\275\240\345\245\275/\344\270\226\347\225\214/Default.html" "b/tests/Microsoft.Owin.StaticFiles.Tests/SubFolder/\344\275\240\345\245\275/\344\270\226\347\225\214/Default.html" new file mode 100644 index 000000000..4740d8368 --- /dev/null +++ "b/tests/Microsoft.Owin.StaticFiles.Tests/SubFolder/\344\275\240\345\245\275/\344\270\226\347\225\214/Default.html" @@ -0,0 +1,11 @@ + + + + + + + + + Hello World + + \ No newline at end of file From f29598ab6d7c45da6d9790eb2a7ee02759e99cc6 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Thu, 29 Apr 2021 16:20:57 -0700 Subject: [PATCH 28/45] Update Facebook OAuth endpoints, tests (#413) --- src/Microsoft.Owin.Security.Facebook/Constants.cs | 6 +++--- .../Facebook/FacebookMiddlewareTests.cs | 2 +- .../Google/GoogleOAuth2MiddlewareTests.cs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.Owin.Security.Facebook/Constants.cs b/src/Microsoft.Owin.Security.Facebook/Constants.cs index 4ef9e04ab..4498b1214 100644 --- a/src/Microsoft.Owin.Security.Facebook/Constants.cs +++ b/src/Microsoft.Owin.Security.Facebook/Constants.cs @@ -8,8 +8,8 @@ internal static class Constants public const string DefaultAuthenticationType = "Facebook"; // https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow#login - internal const string AuthorizationEndpoint = "https://www.facebook.com/v8.0/dialog/oauth"; - internal const string TokenEndpoint = "https://graph.facebook.com/v8.0/oauth/access_token"; - internal const string UserInformationEndpoint = "https://graph.facebook.com/v8.0/me"; + internal const string AuthorizationEndpoint = "https://www.facebook.com/v10.0/dialog/oauth"; + internal const string TokenEndpoint = "https://graph.facebook.com/v10.0/oauth/access_token"; + internal const string UserInformationEndpoint = "https://graph.facebook.com/v10.0/me"; } } diff --git a/tests/Microsoft.Owin.Security.Tests/Facebook/FacebookMiddlewareTests.cs b/tests/Microsoft.Owin.Security.Tests/Facebook/FacebookMiddlewareTests.cs index 44a7c9265..5c6133e4d 100644 --- a/tests/Microsoft.Owin.Security.Tests/Facebook/FacebookMiddlewareTests.cs +++ b/tests/Microsoft.Owin.Security.Tests/Facebook/FacebookMiddlewareTests.cs @@ -59,7 +59,7 @@ public async Task ChallengeWillTriggerRedirection() var transaction = await SendAsync(server, "http://example.com/challenge"); transaction.Response.StatusCode.ShouldBe(HttpStatusCode.Redirect); var location = transaction.Response.Headers.Location.AbsoluteUri; - location.ShouldContain("https://www.facebook.com/v2.8/dialog/oauth"); + location.ShouldContain("https://www.facebook.com/v10.0/dialog/oauth"); location.ShouldContain("?response_type=code"); location.ShouldContain("&client_id="); location.ShouldContain("&redirect_uri="); diff --git a/tests/Microsoft.Owin.Security.Tests/Google/GoogleOAuth2MiddlewareTests.cs b/tests/Microsoft.Owin.Security.Tests/Google/GoogleOAuth2MiddlewareTests.cs index eb8690675..be4cf671c 100644 --- a/tests/Microsoft.Owin.Security.Tests/Google/GoogleOAuth2MiddlewareTests.cs +++ b/tests/Microsoft.Owin.Security.Tests/Google/GoogleOAuth2MiddlewareTests.cs @@ -230,7 +230,7 @@ public async Task ReplyPathWillAuthenticateValidAuthorizeCodeAndState() { Sender = async req => { - if (req.RequestUri.AbsoluteUri == "https://www.googleapis.com/oauth2/v4/token") + if (req.RequestUri.AbsoluteUri == "https://oauth2.googleapis.com/token") { return await ReturnJsonResponse(new { @@ -351,7 +351,7 @@ public async Task AuthenticatedEventCanGetRefreshToken() { Sender = async req => { - if (req.RequestUri.AbsoluteUri == "https://www.googleapis.com/oauth2/v4/token") + if (req.RequestUri.AbsoluteUri == "https://oauth2.googleapis.com/token") { return await ReturnJsonResponse(new { From d00d910b2f804ae19f28ee8839aa641cd8ff8214 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Fri, 30 Apr 2021 10:23:43 -0700 Subject: [PATCH 29/45] Warn that SecurityTokenValidated is not that last step #405 (#412) --- .../OpenIdConnectAuthenticationNotifications.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.Owin.Security.OpenIdConnect/OpenIdConnectAuthenticationNotifications.cs b/src/Microsoft.Owin.Security.OpenIdConnect/OpenIdConnectAuthenticationNotifications.cs index 84986069d..d909f8ef8 100644 --- a/src/Microsoft.Owin.Security.OpenIdConnect/OpenIdConnectAuthenticationNotifications.cs +++ b/src/Microsoft.Owin.Security.OpenIdConnect/OpenIdConnectAuthenticationNotifications.cs @@ -53,7 +53,8 @@ public OpenIdConnectAuthenticationNotifications() public Func, Task> SecurityTokenReceived { get; set; } /// - /// Invoked after the security token has passed validation and a ClaimsIdentity has been generated. + /// Invoked after the security token has passed validation and a ClaimsIdentity has been generated. Note there are additional checks after this + /// event that validate other aspects of the authentication flow like the nonce. /// public Func, Task> SecurityTokenValidated { get; set; } From 81aa05345cb680c6095242a60e673a24868e192b Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Fri, 7 May 2021 14:46:39 -0700 Subject: [PATCH 30/45] Update build number to 4.2.0-rtw --- build/CommonAssemblyInfo.cs | 6 +++--- build/Katana.version.targets | 14 +++++++------- build/Sakefile.shade | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/build/CommonAssemblyInfo.cs b/build/CommonAssemblyInfo.cs index af6993195..03f92a80b 100644 --- a/build/CommonAssemblyInfo.cs +++ b/build/CommonAssemblyInfo.cs @@ -7,7 +7,7 @@ [assembly: AssemblyProduct("Microsoft OWIN")] [assembly: AssemblyCopyright("\x00a9 Microsoft Corporation All rights reserved.")] [assembly: AssemblyTrademark("")] -[assembly: AssemblyVersion("4.1.1.0")] -[assembly: AssemblyFileVersion("4.1.90831.0")] -[assembly: AssemblyInformationalVersion("4.1.1-rtw-000")] +[assembly: AssemblyVersion("4.2.0.0")] +[assembly: AssemblyFileVersion("4.2.100507.0")] +[assembly: AssemblyInformationalVersion("4.2.0-rtw-000")] [assembly: AssemblyMetadata("Serviceable", "True")] diff --git a/build/Katana.version.targets b/build/Katana.version.targets index 0b55d41da..f0d2e69a7 100644 --- a/build/Katana.version.targets +++ b/build/Katana.version.targets @@ -1,15 +1,15 @@ - 4.1.1 - 4.1.1.0 - 4.1.1-rtw-000 - 4.1.90831.0 + 4.2.0 + 4.2.0.0 + 4.2.0-rtw-000 + 4.2.100507.0 4 - 1 - 1 + 2 + 0 rtw - 90831 + 100507 https://github.com/aspnet/AspNetKatana/ Microsoft OWIN Katana diff --git a/build/Sakefile.shade b/build/Sakefile.shade index e11f811a4..b8f262441 100644 --- a/build/Sakefile.shade +++ b/build/Sakefile.shade @@ -1,7 +1,7 @@ var PROJECT='Katana' var AUTHORS='Microsoft' -var SHIP='${Version(4, 1, 1, "rtw")}' +var SHIP='${Version(4, 2, 0, "rtw")}' var DEV='${Version(0, 31, 0, "pre")}' set FINAL_MILESTONE='${true}' var AZUREAD_VERSION='5.3.0' From fae38fae683bb0977bcaf7c3ffce244aced82135 Mon Sep 17 00:00:00 2001 From: Bouke Haarsma Date: Wed, 19 May 2021 17:14:40 +0200 Subject: [PATCH 31/45] Fix typo (#416) --- .../Infrastructure/AuthenticationHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.Owin.Security/Infrastructure/AuthenticationHandler.cs b/src/Microsoft.Owin.Security/Infrastructure/AuthenticationHandler.cs index 8a9bbbf84..99a6fcf87 100644 --- a/src/Microsoft.Owin.Security/Infrastructure/AuthenticationHandler.cs +++ b/src/Microsoft.Owin.Security/Infrastructure/AuthenticationHandler.cs @@ -180,7 +180,7 @@ protected virtual async Task ApplyResponseCoreAsync() } /// - /// Override this method to dela with sign-in/sign-out concerns, if an authentication scheme in question + /// Override this method to deal with sign-in/sign-out concerns, if an authentication scheme in question /// deals with grant/revoke as part of it's request flow. (like setting/deleting cookies) /// /// From 9e38620fee7afa3de1786c4f3f8f16685bb591a0 Mon Sep 17 00:00:00 2001 From: gregwoodio Date: Tue, 28 Sep 2021 16:24:45 -0400 Subject: [PATCH 32/45] Correct HttpOnly description (#419) (#429) --- src/Microsoft.Owin/CookieOptions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.Owin/CookieOptions.cs b/src/Microsoft.Owin/CookieOptions.cs index e74fb95b9..5ba63be5d 100644 --- a/src/Microsoft.Owin/CookieOptions.cs +++ b/src/Microsoft.Owin/CookieOptions.cs @@ -45,7 +45,7 @@ public CookieOptions() /// /// Gets or sets a value that indicates whether a cookie is accessible by client-side script. /// - /// true if a cookie is accessible by client-side script; otherwise, false. + /// false if a cookie is accessible by client-side script; otherwise, true. public bool HttpOnly { get; set; } /// From 412e6492df7c19e01ce8236a3283f5593274d83b Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Mon, 25 Oct 2021 08:57:53 -0700 Subject: [PATCH 33/45] Update version to 4.2.1 (#431) --- build/CommonAssemblyInfo.cs | 6 +++--- build/Katana.version.targets | 12 ++++++------ build/Sakefile.shade | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/build/CommonAssemblyInfo.cs b/build/CommonAssemblyInfo.cs index 03f92a80b..c3d1f3841 100644 --- a/build/CommonAssemblyInfo.cs +++ b/build/CommonAssemblyInfo.cs @@ -7,7 +7,7 @@ [assembly: AssemblyProduct("Microsoft OWIN")] [assembly: AssemblyCopyright("\x00a9 Microsoft Corporation All rights reserved.")] [assembly: AssemblyTrademark("")] -[assembly: AssemblyVersion("4.2.0.0")] -[assembly: AssemblyFileVersion("4.2.100507.0")] -[assembly: AssemblyInformationalVersion("4.2.0-rtw-000")] +[assembly: AssemblyVersion("4.2.1.0")] +[assembly: AssemblyFileVersion("4.2.101025.0")] +[assembly: AssemblyInformationalVersion("4.2.1-rtw-000")] [assembly: AssemblyMetadata("Serviceable", "True")] diff --git a/build/Katana.version.targets b/build/Katana.version.targets index f0d2e69a7..485997f69 100644 --- a/build/Katana.version.targets +++ b/build/Katana.version.targets @@ -1,15 +1,15 @@ - 4.2.0 - 4.2.0.0 - 4.2.0-rtw-000 - 4.2.100507.0 + 4.2.1 + 4.2.1.0 + 4.2.1-rtw-000 + 4.2.101025.0 4 2 - 0 + 1 rtw - 100507 + 101025 https://github.com/aspnet/AspNetKatana/ Microsoft OWIN Katana diff --git a/build/Sakefile.shade b/build/Sakefile.shade index b8f262441..8af99b6df 100644 --- a/build/Sakefile.shade +++ b/build/Sakefile.shade @@ -1,7 +1,7 @@ var PROJECT='Katana' var AUTHORS='Microsoft' -var SHIP='${Version(4, 2, 0, "rtw")}' +var SHIP='${Version(4, 2, 1, "rtw")}' var DEV='${Version(0, 31, 0, "pre")}' set FINAL_MILESTONE='${true}' var AZUREAD_VERSION='5.3.0' From cc2ae7ec7777c54bc4a483e174fc4e3004f5c734 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Mon, 25 Oct 2021 11:38:24 -0700 Subject: [PATCH 34/45] Do not call End/Abort on disconnect #430 (#432) --- .../OwinHttpListenerContext.cs | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/Microsoft.Owin.Host.HttpListener/RequestProcessing/OwinHttpListenerContext.cs b/src/Microsoft.Owin.Host.HttpListener/RequestProcessing/OwinHttpListenerContext.cs index 1037631ec..6d246c103 100644 --- a/src/Microsoft.Owin.Host.HttpListener/RequestProcessing/OwinHttpListenerContext.cs +++ b/src/Microsoft.Owin.Host.HttpListener/RequestProcessing/OwinHttpListenerContext.cs @@ -62,22 +62,7 @@ internal void End(Exception ex) { if (ex != null) { - // TODO: LOG - // Lazy initialized - if (_cts != null) - { - try - { - _cts.Cancel(); - } - catch (ObjectDisposedException) - { - } - catch (AggregateException) - { - // TODO: LOG - } - } + CancelDisconnectToken(); } End(); @@ -99,7 +84,26 @@ internal void End() private static void SetDisconnected(object state) { var context = (OwinHttpListenerContext)state; - context.End(new HttpListenerException(Constants.ErrorConnectionNoLongerValid)); + context.CancelDisconnectToken(); + } + + private void CancelDisconnectToken() + { + // Lazy initialized + if (_cts != null) + { + try + { + _cts.Cancel(); + } + catch (ObjectDisposedException) + { + } + catch (AggregateException) + { + // TODO: LOG + } + } } public void Dispose() From b32c437b05217f367c201e420f147acf115e0712 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Tue, 23 Nov 2021 14:41:45 -0800 Subject: [PATCH 35/45] Remove nightly feed from readme --- README.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/README.md b/README.md index 517e76646..2be911c64 100644 --- a/README.md +++ b/README.md @@ -14,14 +14,6 @@ To build and run the tests from a command prompt, run `build.cmd` (found in the See Katana.sln in the root directory to open the solution in Visual Studio. -## Signed Nightly Builds -If you do not want to build the source, nightly builds are available via a private NuGet feed. Nightly builds are meant for developers to try out new features or bug fixes ahead of an official prerelease or final build. Nightly builds are not supported for production use. - -## Nightly build feeds: -* Dev (latest) branch: https://dotnet.myget.org/f/katana-dev/ -* Release (stabilization) branch: https://dotnet.myget.org/f/katana-release/ -* IdentityModel dependencies: https://www.myget.org/F/azureadwebstacknightly/ - ## Contribute There are lots of ways to [contribute](https://github.com/aspnet/Home/blob/master/CONTRIBUTING.md) to the project, and we appreciate our contributors. You can contribute by reviewing and sending feedback on code commits, suggesting and trying out new features as they are implemented, submit bugs and help us verify fixes as they are checked in, as well as submit code fixes or code contributions of your own. Note that all code submissions will be rigorously reviewed and tested by the Katana team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source. From dbe159e43e2eee44f315f26268943e8ab5a4f60d Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Fri, 25 Mar 2022 15:42:31 -0700 Subject: [PATCH 36/45] Re-do the build infrastructure (#445) --- .gitignore | 2 + .nuget/NuGet.Config | 15 - BuildServer.targets | 5 - CredScanSuppressions.json | 12 + Directory.Build.props | 25 + Directory.Build.targets | 3 + Katana.sln | 193 +- LICENSE.txt | 5 +- NuGet.Config | 14 + Settings.StyleCop | 375 -- azure-pipelines.yml | 125 + build.cmd | 11 +- build/CodeAnalysis.ruleset | 14 - build/Common.targets | 19 - build/CommonAssemblyInfo.cs | 13 - build/CustomDictionary.xml | 13 - build/Delay.dat | Bin 160 -> 0 bytes build/DevAssemblyInfo.cs | 13 - build/Katana.version.targets | 17 - build/Sakefile.shade | 424 -- build/_apply-net45-changes.shade | 20 - build/_clone-and-tweak-file.shade | 17 - build/_documentation-load.shade | 13 - build/_documentation-render.shade | 1 - build/_package-vsixmanifest.shade | 40 - build/_package-vstemplate.shade | 38 - build/downloadnuget.ps1 | 13 - build/shared/_build.shade | 49 - build/shared/_xunit.shade | 38 - eng/Build.props | 6 + eng/Publishing.props | 5 + eng/Signing.props | 9 + eng/Version.Details.xml | 9 + eng/Versions.props | 15 + eng/common/CIBuild.cmd | 2 + eng/common/PSScriptAnalyzerSettings.psd1 | 11 + eng/common/README.md | 28 + eng/common/SetupNugetSources.ps1 | 167 + eng/common/SetupNugetSources.sh | 191 + eng/common/build.ps1 | 161 + eng/common/build.sh | 232 + eng/common/cibuild.sh | 16 + eng/common/cross/arm/sources.list.bionic | 11 + eng/common/cross/arm/sources.list.jessie | 3 + eng/common/cross/arm/sources.list.xenial | 11 + eng/common/cross/arm/sources.list.zesty | 11 + eng/common/cross/arm/tizen-build-rootfs.sh | 35 + eng/common/cross/arm/tizen-fetch.sh | 170 + eng/common/cross/arm/tizen/tizen.patch | 9 + eng/common/cross/arm64/sources.list.bionic | 11 + eng/common/cross/arm64/sources.list.buster | 11 + eng/common/cross/arm64/sources.list.stretch | 12 + eng/common/cross/arm64/sources.list.xenial | 11 + eng/common/cross/arm64/sources.list.zesty | 11 + eng/common/cross/arm64/tizen-build-rootfs.sh | 35 + eng/common/cross/arm64/tizen-fetch.sh | 170 + eng/common/cross/arm64/tizen/tizen.patch | 9 + eng/common/cross/armel/armel.jessie.patch | 43 + eng/common/cross/armel/sources.list.jessie | 3 + eng/common/cross/armel/tizen-build-rootfs.sh | 35 + eng/common/cross/armel/tizen-fetch.sh | 170 + eng/common/cross/armel/tizen/tizen-dotnet.ks | 50 + eng/common/cross/armel/tizen/tizen.patch | 9 + eng/common/cross/armv6/sources.list.buster | 2 + eng/common/cross/build-android-rootfs.sh | 131 + eng/common/cross/build-rootfs.sh | 383 ++ eng/common/cross/ppc64le/sources.list.bionic | 11 + eng/common/cross/s390x/sources.list.bionic | 11 + eng/common/cross/toolchain.cmake | 272 + eng/common/cross/x86/sources.list.bionic | 11 + eng/common/cross/x86/sources.list.xenial | 11 + eng/common/darc-init.ps1 | 47 + eng/common/darc-init.sh | 82 + eng/common/dotnet-install.cmd | 2 + eng/common/dotnet-install.ps1 | 28 + eng/common/dotnet-install.sh | 87 + eng/common/enable-cross-org-publishing.ps1 | 13 + eng/common/generate-locproject.ps1 | 117 + eng/common/generate-sbom-prep.ps1 | 19 + eng/common/generate-sbom-prep.sh | 22 + eng/common/helixpublish.proj | 26 + eng/common/init-tools-native.cmd | 3 + eng/common/init-tools-native.ps1 | 152 + eng/common/init-tools-native.sh | 238 + eng/common/internal-feed-operations.ps1 | 132 + eng/common/internal-feed-operations.sh | 141 + eng/common/internal/Directory.Build.props | 4 + eng/common/internal/NuGet.config | 7 + eng/common/internal/Tools.csproj | 27 + eng/common/msbuild.ps1 | 28 + eng/common/msbuild.sh | 58 + eng/common/native/CommonLibrary.psm1 | 400 ++ eng/common/native/common-library.sh | 172 + eng/common/native/init-compiler.sh | 144 + eng/common/native/install-cmake-test.sh | 117 + eng/common/native/install-cmake.sh | 117 + eng/common/native/install-tool.ps1 | 132 + eng/common/pipeline-logging-functions.ps1 | 260 + eng/common/pipeline-logging-functions.sh | 206 + .../post-build/add-build-to-channel.ps1 | 48 + .../post-build/check-channel-consistency.ps1 | 40 + eng/common/post-build/nuget-validation.ps1 | 24 + eng/common/post-build/post-build-utils.ps1 | 91 + eng/common/post-build/publish-using-darc.ps1 | 54 + .../post-build/sourcelink-validation.ps1 | 319 + eng/common/post-build/symbols-validation.ps1 | 339 ++ .../post-build/trigger-subscriptions.ps1 | 64 + eng/common/retain-build.ps1 | 47 + eng/common/sdk-task.ps1 | 97 + eng/common/sdl/NuGet.config | 13 + eng/common/sdl/configure-sdl-tool.ps1 | 116 + eng/common/sdl/execute-all-sdl-tools.ps1 | 165 + eng/common/sdl/extract-artifact-archives.ps1 | 63 + eng/common/sdl/extract-artifact-packages.ps1 | 80 + eng/common/sdl/init-sdl.ps1 | 55 + eng/common/sdl/packages.config | 4 + eng/common/sdl/run-sdl.ps1 | 49 + eng/common/templates/job/execute-sdl.yml | 131 + eng/common/templates/job/job.yml | 261 + eng/common/templates/job/onelocbuild.yml | 106 + .../templates/job/publish-build-assets.yml | 121 + eng/common/templates/job/source-build.yml | 63 + .../templates/job/source-index-stage1.yml | 61 + eng/common/templates/jobs/codeql-build.yml | 31 + eng/common/templates/jobs/jobs.yml | 97 + eng/common/templates/jobs/source-build.yml | 46 + .../templates/post-build/common-variables.yml | 26 + .../templates/post-build/post-build.yml | 277 + .../post-build/setup-maestro-vars.yml | 70 + .../post-build/trigger-subscription.yml | 13 + .../templates/steps/add-build-to-channel.yml | 13 + eng/common/templates/steps/build-reason.yml | 12 + eng/common/templates/steps/execute-codeql.yml | 32 + eng/common/templates/steps/execute-sdl.yml | 68 + eng/common/templates/steps/generate-sbom.yml | 44 + eng/common/templates/steps/publish-logs.yml | 23 + eng/common/templates/steps/retain-build.yml | 28 + eng/common/templates/steps/run-on-unix.yml | 7 + eng/common/templates/steps/run-on-windows.yml | 7 + .../steps/run-script-ifequalelse.yml | 33 + eng/common/templates/steps/send-to-helix.yml | 91 + eng/common/templates/steps/source-build.yml | 102 + eng/common/templates/steps/telemetry-end.yml | 102 + .../templates/steps/telemetry-start.yml | 241 + .../templates/variables/sdl-variables.yml | 7 + eng/common/tools.ps1 | 908 +++ eng/common/tools.sh | 550 ++ global.json | 11 + pack.cmd | 2 + restore.cmd | 2 + .../Katana.Sandbox.Selfhost/App.config | 0 .../Katana.Sandbox.Selfhost.csproj | 0 .../Katana.Sandbox.Selfhost/Program.cs | 0 .../Properties/AssemblyInfo.cs | 12 - .../Katana.Sandbox.Selfhost}/packages.config | 0 .../Katana.Sandbox.WebClient/ClientApp.aspx | 0 .../ClientApp.aspx.cs | 0 .../ClientApp.aspx.designer.cs | 0 .../Katana.Sandbox.WebClient/ClientPage.html | 0 .../Katana.Sandbox.WebClient/ClientPage.js | 0 .../ClientPageSignIn.html | 0 .../ClientPageSignIn.js | 0 .../Katana.Sandbox.WebClient.csproj | 0 .../Properties/AssemblyInfo.cs | 0 .../Web.Debug.config | 0 .../Web.Release.config | 0 .../Katana.Sandbox.WebClient/Web.config | 8 +- .../Katana.Sandbox.WebClient/packages.config | 0 .../AspNetAuthSessionStore.cs | 0 .../Katana.Sandbox.WebServer/Authorize.cshtml | 0 .../AuthorizeError.cshtml | 0 .../Katana.Sandbox.WebServer/External.cshtml | 0 .../InMemoryAuthSessionStore.cs | 0 .../Katana.Sandbox.WebServer.csproj | 0 .../Katana.Sandbox.WebServer/Login.cshtml | 0 .../Katana.Sandbox.WebServer/Logout.cshtml | 0 .../Properties/AssemblyInfo.cs | 0 .../SameSiteCookieManager.cs | 0 .../Katana.Sandbox.WebServer/Startup.cs | 4 +- .../Web.Debug.config | 0 .../Web.Release.config | 0 .../Katana.Sandbox.WebServer/Web.config | 0 .../Katana.Sandbox.WebServer}/packages.config | 0 src/Directory.Build.props | 9 + .../Microsoft.Owin.Cors.csproj | 95 +- .../Microsoft.Owin.Cors.nuspec | 27 - .../Properties/AssemblyInfo.cs | 22 - src/Microsoft.Owin.Cors/packages.config | 5 - .../ErrorPageMiddleware.cs | 3 - .../Microsoft.Owin.Diagnostics.csproj | 156 +- .../Microsoft.Owin.Diagnostics.nuspec | 26 - .../Properties/AssemblyInfo.cs | 22 - .../packages.config | 5 - .../Microsoft.Owin.FileSystems.csproj | 70 +- .../Microsoft.Owin.FileSystems.nuspec | 23 - .../Properties/AssemblyInfo.cs | 20 - .../Microsoft.Owin.Host.HttpListener.csproj | 128 +- .../Microsoft.Owin.Host.HttpListener.nuspec | 22 - .../Properties/AssemblyInfo.cs | 30 +- .../Microsoft.Owin.Host.SystemWeb.csproj | 205 +- .../Microsoft.Owin.Host.SystemWeb.nuspec | 25 - .../Properties/AssemblyInfo.cs | 30 +- .../Microsoft.Owin.Hosting.csproj | 168 +- .../Microsoft.Owin.Hosting.nuspec | 26 - .../Properties/AssemblyInfo.cs | 30 +- src/Microsoft.Owin.Hosting/packages.config | 4 - ...osoft.Owin.Security.ActiveDirectory.csproj | 175 +- ...osoft.Owin.Security.ActiveDirectory.nuspec | 35 - .../Properties/AssemblyInfo.cs | 10 - .../packages.config | 13 - .../Microsoft.Owin.Security.Cookies.csproj | 107 +- .../Microsoft.Owin.Security.Cookies.nuspec | 27 - .../Properties/AssemblyInfo.cs | 20 - .../packages.config | 4 - .../Microsoft.Owin.Security.Facebook.csproj | 127 +- .../Microsoft.Owin.Security.Facebook.nuspec | 32 - .../Properties/AssemblyInfo.cs | 18 - .../packages.config | 5 - .../Microsoft.Owin.Security.Google.csproj | 127 +- .../Microsoft.Owin.Security.Google.nuspec | 32 - .../Properties/AssemblyInfo.cs | 18 - .../packages.config | 5 - .../Microsoft.Owin.Security.Jwt.csproj | 144 +- .../Microsoft.Owin.Security.Jwt.nuspec | 29 - .../Properties/AssemblyInfo.cs | 22 - ...soft.Owin.Security.MicrosoftAccount.csproj | 125 +- ...soft.Owin.Security.MicrosoftAccount.nuspec | 32 - .../Properties/AssemblyInfo.cs | 18 - .../packages.config | 5 - .../Microsoft.Owin.Security.OAuth.csproj | 144 +- .../Microsoft.Owin.Security.OAuth.nuspec | 28 - .../Properties/AssemblyInfo.cs | 20 - .../OAuthAuthorizationServerProvider.cs | 2 - .../OAuthAuthorizeEndpointResponseContext.cs | 4 - .../OAuthTokenEndpointResponseContext.cs | 4 - .../packages.config | 5 - ...crosoft.Owin.Security.OpenIdConnect.csproj | 165 +- ...crosoft.Owin.Security.OpenIdConnect.nuspec | 38 - .../OpenIdConnectAuthenticationOptions.cs | 4 +- .../OpenidConnectAuthenticationHandler.cs | 8 +- .../Properties/AssemblyInfo.cs | 13 - .../packages.config | 11 - .../Microsoft.Owin.Security.Twitter.csproj | 131 +- .../Microsoft.Owin.Security.Twitter.nuspec | 32 - .../Properties/AssemblyInfo.cs | 22 - .../packages.config | 5 - ...icrosoft.Owin.Security.WsFederation.csproj | 166 +- ...icrosoft.Owin.Security.WsFederation.nuspec | 35 - .../Properties/AssemblyInfo.cs | 12 - .../WsFederationAuthenticationOptions.cs | 2 +- .../packages.config | 12 - .../CertificateThumbprintValidator.cs | 2 +- .../Microsoft.Owin.Security.csproj | 157 +- ...Microsoft.Owin.Security.csproj.DotSettings | 2 - .../Microsoft.Owin.Security.nuspec | 26 - .../Properties/AssemblyInfo.cs | 22 - src/Microsoft.Owin.Security/packages.config | 4 - .../Microsoft.Owin.SelfHost.csproj | 23 + .../Microsoft.Owin.SelfHost.nuspec | 23 - .../{ReadMe.txt => README.md} | 8 +- .../Microsoft.Owin.StaticFiles.csproj | 128 +- .../Microsoft.Owin.StaticFiles.nuspec | 27 - .../Properties/AssemblyInfo.cs | 22 - .../packages.config | 4 - .../Microsoft.Owin.Testing.csproj | 119 +- .../Microsoft.Owin.Testing.nuspec | 30 - .../Properties/AssemblyInfo.cs | 24 +- src/Microsoft.Owin.Testing/packages.config | 4 - src/Microsoft.Owin/Microsoft.Owin.csproj | 159 +- src/Microsoft.Owin/Microsoft.Owin.nuspec | 25 - src/Microsoft.Owin/Properties/AssemblyInfo.cs | 22 - src/Microsoft.Owin/packages.config | 4 - src/Owin.Loader/Owin.Loader.csproj | 92 +- src/Owin.Loader/Properties/AssemblyInfo.cs | 30 - src/Owin.Loader/packages.config | 4 - src/OwinHost/OwinHost.csproj | 146 +- src/OwinHost/OwinHost.csproj.DotSettings | 3 - src/OwinHost/OwinHost.nuspec | 28 - .../Package/{ReadMe.txt => ReadMe.md} | 0 src/OwinHost/Properties/AssemblyInfo.cs | 22 - .../CertInstaller/CertInstaller.csproj | 69 +- .../CertInstaller/Properties/AssemblyInfo.cs | 24 - startvs.cmd | 28 + test.cmd | 2 + tests/Directory.Build.props | 9 + .../Facts/Diagnostics/ErrorPageFacts.cs | 2 +- .../Facts/Diagnostics/WelcomePageFacts.cs | 4 +- ...InvalidConfigurationMethodSignatureTest.cs | 2 +- .../Facts/Discovery/NegativeScenarios.cs | 2 +- .../Facts/General/ApplicationPoolStopTest.cs | 2 +- .../EnvironmentDictionaryVerificationTest.cs | 2 +- .../Facts/General/OnSendingHeadersTest.cs | 3 +- .../Facts/General/OwinCallCancelledTest.cs | 2 +- .../Facts/General/ResponseStatusCodeTest.cs | 6 +- .../Facts/General/WebSocketTest.cs | 2 +- .../IntegratedPipeline/DefaultStageMarkers.cs | 2 +- .../IntegratedPipelineWithMap.cs | 2 +- .../MiddlewaresAtDifferentStagesTest.cs | 2 +- .../OrderOfExecutionTest.cs | 2 +- .../Facts/MSOwin/MsOwinFacts.cs | 2 +- .../MappingMiddlewareFacts.cs | 12 +- .../InstanceBasedMiddleware.cs | 2 +- .../MiddlewarePatterns/OwinMiddlewareFacts.cs | 2 +- .../Facts/OwinHost/OwinHostAppSettings.cs | 2 +- .../Facts/OwinHost/StartOptionsAndOwinHost.cs | 3 +- .../ActiveDirectory/WaadAuthentication.cs | 2 +- .../Security/AuthServer/AuthServerTests.cs | 71 +- .../BearerToken/BearerTokenAuthentication.cs | 4 +- .../SymmetricJwtTokenAuthentication.cs | 4 +- .../Facts/Security/Cookies/AjaxRequest.cs | 8 +- .../Security/Cookies/CookiesApplyRedirect.cs | 4 +- .../Cookies/CookiesAuthCookiePathFact.cs | 12 +- .../Security/Cookies/CookiesAuthDefault.cs | 18 +- .../CookiesAuthReturnUrlOverrideFact.cs | 4 +- .../Facts/Security/Cookies/CookiesCommon.cs | 2 +- .../Cookies/CustomSecureDataHandler.cs | 14 +- .../Security/Cookies/PersistentCookie.cs | 6 +- .../Facebook/FacebookAuthentication.cs | 47 +- .../Security/Federation/WsFederationTest.cs | 13 +- .../Google/GoogleOAuth2Authentication.cs | 39 +- .../Google/GoogleOAuth2AuthorizeParameters.cs | 10 +- .../Jwt/SymmetricKeyTokenVerification.cs | 16 +- .../Jwt/X509CertificateTokenVerification.cs | 16 +- .../MicrosoftAuthentication.cs | 41 +- .../Security/Twitter/TwitterAuthentication.cs | 30 +- .../Facts/SideBySide/MapOwinPathTest.cs | 8 +- .../Facts/SideBySide/MapOwinRouteTest.cs | 18 +- .../DefaultFiles/DefaultFileExtensibility.cs | 6 +- .../StaticFiles/DefaultFiles/DefaultFiles.cs | 28 +- .../DirectoryBrowser/DirectoryBrowser.cs | 34 +- .../DirectoryBrowserExtensibility.cs | 6 +- .../EmbeddedDefaultFiles.cs | 5 +- .../EmbeddedDirectoryBrowser.cs | 4 +- .../EmbeddedFileSystemTests.cs | 4 +- .../FileServer/FileServerExtensibility.cs | 6 +- .../StaticFiles/StaticFile/CacheTests.cs | 2 +- .../StaticFile/CustomSendFileFunc.cs | 4 +- .../StaticFiles/StaticFile/IfMatchTests.cs | 2 +- .../StaticFile/IfModifiedSinceTests.cs | 2 +- .../StaticFile/IfNoneMatchTests.cs | 2 +- .../StaticFiles/StaticFile/IfRangeTests.cs | 4 +- .../StaticFile/IfUnModifiedSinceTests.cs | 2 +- .../StaticFiles/StaticFile/RangeTests.cs | 2 +- .../StaticFiles/StaticFile/StaticFile.cs | 28 +- .../StaticFile/StaticFileSecurity.cs | 6 +- .../Facts/Testing/TestServerFacts.cs | 8 +- .../Facts/Tracing/TracingFacts.cs | 3 +- tests/FunctionalTests/FunctionalTests.csproj | 616 +- .../Properties/AssemblyInfo.cs | 38 +- .../App.config | 6 - ...ana.Performance.ReferenceApp.Client.csproj | 63 - .../Program.cs | 44 - .../Properties/AssemblyInfo.cs | 22 - .../App.config | 9 - ...a.Performance.ReferenceApp.Selfhost.csproj | 123 - .../Program.cs | 20 - .../Properties/AssemblyInfo.cs | 24 - .../Public/large.txt | 5342 ----------------- .../Public/small.txt | 11 - .../packages.config | 4 - .../CanonicalRequestPatternsTests.cs | 54 - ...tana.Performance.ReferenceApp.Tests.csproj | 105 - .../Properties/AssemblyInfo.cs | 24 - .../packages.config | 5 - .../AutoTuneMiddleware.cs | 55 - .../CanonicalRequestAttribute.cs | 13 - .../CanonicalRequestPatterns.cs | 240 - .../HelloWorld.aspx | 12 - .../HelloWorld.aspx.cs | 19 - .../HelloWorld.aspx.designer.cs | 15 - .../Katana.Performance.ReferenceApp.csproj | 163 - .../Properties/AssemblyInfo.cs | 24 - .../Public/large.txt | 5342 ----------------- .../Public/small.txt | 11 - .../Startup.cs | 52 - tests/Katana.Performance.ReferenceApp/Util.cs | 70 - .../Web.config | 51 - .../packages.config | 4 - .../canonicalRequestPatterns.js | 133 - .../Katana.Performance.ReferenceAppJs/go.cmd | 1 - .../package.json | 16 - .../public/large.txt | 5342 ----------------- .../public/small.txt | 11 - .../server.js | 27 - tests/Katana.Sandbox.Selfhost/packages.config | 4 - .../Katana.Sandbox.WebServer/Web.Debug.config | 30 - .../Web.Release.config | 31 - .../Katana.Sandbox.WebServer/packages.config | 9 - .../CorsMiddlewareTests.cs | 10 +- .../Microsoft.Owin.Cors.Tests.csproj | 108 +- .../Properties/AssemblyInfo.cs | 24 - .../Microsoft.Owin.Cors.Tests/packages.config | 8 - .../Microsoft.Owin.FileSystems.Tests.csproj | 117 +- .../Properties/AssemblyInfo.cs | 24 - .../packages.config | 6 - ...rosoft.Owin.Host.HttpListener.Tests.csproj | 133 +- .../OwinHttpListenerRequestTests.cs | 28 +- .../OwinHttpListenerResponseTests.cs | 26 +- .../OwinHttpListenerTests.cs | 11 +- .../OwinWebSocketTests.cs | 28 +- .../Properties/AssemblyInfo.cs | 24 +- .../ServerFactoryTests.cs | 4 +- .../SetVariables.bat | 1 + .../ClientCertificateTests.cs | 5 +- .../ExceptionsTests.cs | 5 +- .../HostPropertyTests.cs | 3 +- .../IntegratedPipelineTests.cs | 3 +- ...icrosoft.Owin.Host.IntegrationTests.csproj | 197 +- .../PathEscapingTests.cs | 3 +- .../Properties/AssemblyInfo.cs | 24 - .../QueryEscapingTests.cs | 3 +- .../RequestBodyTests.cs | 6 +- .../RequestHeadersTests.cs | 3 +- .../ResponseBodyTests.cs | 3 +- .../ResponseHeadersTests.cs | 3 +- .../RouteTableTests.cs | 6 +- .../SecurityTests.cs | 3 +- .../SimpleGetTests.cs | 4 +- .../StaticFilesTests.cs | 3 +- .../SystemWebChunkingCookieManagerTests.cs | 3 +- .../SystemWebCookieManagerTests.cs | 10 +- .../SystemWebIntegrationTests.cs | 11 +- .../TestBaseWorks.cs | 10 +- .../packages.config | 8 - .../CallHeaders/AspNetRequestHeadersTests.cs | 12 +- .../FakeN/FakeHttpContext.cs | 31 + .../FakeN/FakeHttpContextEx.cs | 1 - .../FakeN/FakeHttpRequest.cs | 37 + .../FakeN/FakeHttpRequestEx.cs | 1 - .../FakeN/FakeHttpResponse.cs | 20 + .../FakeN/FakeHttpResponseEx.cs | 1 - ...Microsoft.Owin.Host.SystemWeb.Tests.csproj | 130 +- .../OwinHttpHandlerTests.cs | 2 +- .../OwinRouteHandlerTests.cs | 2 +- .../OwinRouteTests.cs | 2 +- .../Properties/AssemblyInfo.cs | 24 - .../TestsBase.cs | 1 - .../packages.config | 8 - .../Microsoft.Owin.Hosting.Tests.csproj | 173 +- .../Properties/AssemblyInfo.cs | 24 - .../ServerFactoryLoaderTests.cs | 6 +- .../SettingsTests.cs | 16 +- .../packages.config | 11 - .../Microsoft.Owin.Security.Tests.csproj | 222 +- .../Properties/AssemblyInfo.cs | 24 - .../DefaultFilesMiddlewareTests.cs | 4 +- .../DirectoryBrowserMiddlewareTests.cs | 4 +- .../Microsoft.Owin.StaticFiles.Tests.csproj | 173 +- .../Properties/AssemblyInfo.cs | 24 - .../SendFileResponseExtensionsTests.cs | 4 +- .../StaticFileMiddlewareTests.cs | 26 +- .../TestRootFile.xml | 1 + .../packages.config | 8 - .../Microsoft.Owin.Testing.Tests.csproj | 109 +- .../OwinClientHandlerTests.cs | 4 +- .../Properties/AssemblyInfo.cs | 24 - .../Microsoft.Owin.Tests.csproj | 116 +- tests/Microsoft.Owin.Tests/PathStringTests.cs | 1 - .../Properties/AssemblyInfo.cs | 26 - .../RequestCookieTests.cs | 6 +- tests/Microsoft.Owin.Tests/packages.config | 8 - .../DefaultConfigurationLoaderTests.cs | 3 + .../Owin.Loader.Tests.csproj | 103 +- .../Properties/AssemblyInfo.cs | 26 - tests/OwinHost.Tests/OwinHost.Tests.csproj | 113 +- .../OwinHost.Tests/Properties/AssemblyInfo.cs | 37 - tests/OwinHost.Tests/packages.config | 7 - 467 files changed, 12284 insertions(+), 25483 deletions(-) delete mode 100644 .nuget/NuGet.Config delete mode 100644 BuildServer.targets create mode 100644 CredScanSuppressions.json create mode 100644 Directory.Build.props create mode 100644 Directory.Build.targets create mode 100644 NuGet.Config delete mode 100644 Settings.StyleCop create mode 100644 azure-pipelines.yml delete mode 100644 build/CodeAnalysis.ruleset delete mode 100644 build/Common.targets delete mode 100644 build/CommonAssemblyInfo.cs delete mode 100644 build/CustomDictionary.xml delete mode 100644 build/Delay.dat delete mode 100644 build/DevAssemblyInfo.cs delete mode 100644 build/Katana.version.targets delete mode 100644 build/Sakefile.shade delete mode 100644 build/_apply-net45-changes.shade delete mode 100644 build/_clone-and-tweak-file.shade delete mode 100644 build/_documentation-load.shade delete mode 100644 build/_documentation-render.shade delete mode 100644 build/_package-vsixmanifest.shade delete mode 100644 build/_package-vstemplate.shade delete mode 100644 build/downloadnuget.ps1 delete mode 100644 build/shared/_build.shade delete mode 100644 build/shared/_xunit.shade create mode 100644 eng/Build.props create mode 100644 eng/Publishing.props create mode 100644 eng/Signing.props create mode 100644 eng/Version.Details.xml create mode 100644 eng/Versions.props create mode 100644 eng/common/CIBuild.cmd create mode 100644 eng/common/PSScriptAnalyzerSettings.psd1 create mode 100644 eng/common/README.md create mode 100644 eng/common/SetupNugetSources.ps1 create mode 100644 eng/common/SetupNugetSources.sh create mode 100644 eng/common/build.ps1 create mode 100644 eng/common/build.sh create mode 100644 eng/common/cibuild.sh create mode 100644 eng/common/cross/arm/sources.list.bionic create mode 100644 eng/common/cross/arm/sources.list.jessie create mode 100644 eng/common/cross/arm/sources.list.xenial create mode 100644 eng/common/cross/arm/sources.list.zesty create mode 100644 eng/common/cross/arm/tizen-build-rootfs.sh create mode 100644 eng/common/cross/arm/tizen-fetch.sh create mode 100644 eng/common/cross/arm/tizen/tizen.patch create mode 100644 eng/common/cross/arm64/sources.list.bionic create mode 100644 eng/common/cross/arm64/sources.list.buster create mode 100644 eng/common/cross/arm64/sources.list.stretch create mode 100644 eng/common/cross/arm64/sources.list.xenial create mode 100644 eng/common/cross/arm64/sources.list.zesty create mode 100644 eng/common/cross/arm64/tizen-build-rootfs.sh create mode 100644 eng/common/cross/arm64/tizen-fetch.sh create mode 100644 eng/common/cross/arm64/tizen/tizen.patch create mode 100644 eng/common/cross/armel/armel.jessie.patch create mode 100644 eng/common/cross/armel/sources.list.jessie create mode 100644 eng/common/cross/armel/tizen-build-rootfs.sh create mode 100644 eng/common/cross/armel/tizen-fetch.sh create mode 100644 eng/common/cross/armel/tizen/tizen-dotnet.ks create mode 100644 eng/common/cross/armel/tizen/tizen.patch create mode 100644 eng/common/cross/armv6/sources.list.buster create mode 100644 eng/common/cross/build-android-rootfs.sh create mode 100644 eng/common/cross/build-rootfs.sh create mode 100644 eng/common/cross/ppc64le/sources.list.bionic create mode 100644 eng/common/cross/s390x/sources.list.bionic create mode 100644 eng/common/cross/toolchain.cmake create mode 100644 eng/common/cross/x86/sources.list.bionic create mode 100644 eng/common/cross/x86/sources.list.xenial create mode 100644 eng/common/darc-init.ps1 create mode 100644 eng/common/darc-init.sh create mode 100644 eng/common/dotnet-install.cmd create mode 100644 eng/common/dotnet-install.ps1 create mode 100644 eng/common/dotnet-install.sh create mode 100644 eng/common/enable-cross-org-publishing.ps1 create mode 100644 eng/common/generate-locproject.ps1 create mode 100644 eng/common/generate-sbom-prep.ps1 create mode 100644 eng/common/generate-sbom-prep.sh create mode 100644 eng/common/helixpublish.proj create mode 100644 eng/common/init-tools-native.cmd create mode 100644 eng/common/init-tools-native.ps1 create mode 100644 eng/common/init-tools-native.sh create mode 100644 eng/common/internal-feed-operations.ps1 create mode 100644 eng/common/internal-feed-operations.sh create mode 100644 eng/common/internal/Directory.Build.props create mode 100644 eng/common/internal/NuGet.config create mode 100644 eng/common/internal/Tools.csproj create mode 100644 eng/common/msbuild.ps1 create mode 100644 eng/common/msbuild.sh create mode 100644 eng/common/native/CommonLibrary.psm1 create mode 100644 eng/common/native/common-library.sh create mode 100644 eng/common/native/init-compiler.sh create mode 100644 eng/common/native/install-cmake-test.sh create mode 100644 eng/common/native/install-cmake.sh create mode 100644 eng/common/native/install-tool.ps1 create mode 100644 eng/common/pipeline-logging-functions.ps1 create mode 100644 eng/common/pipeline-logging-functions.sh create mode 100644 eng/common/post-build/add-build-to-channel.ps1 create mode 100644 eng/common/post-build/check-channel-consistency.ps1 create mode 100644 eng/common/post-build/nuget-validation.ps1 create mode 100644 eng/common/post-build/post-build-utils.ps1 create mode 100644 eng/common/post-build/publish-using-darc.ps1 create mode 100644 eng/common/post-build/sourcelink-validation.ps1 create mode 100644 eng/common/post-build/symbols-validation.ps1 create mode 100644 eng/common/post-build/trigger-subscriptions.ps1 create mode 100644 eng/common/retain-build.ps1 create mode 100644 eng/common/sdk-task.ps1 create mode 100644 eng/common/sdl/NuGet.config create mode 100644 eng/common/sdl/configure-sdl-tool.ps1 create mode 100644 eng/common/sdl/execute-all-sdl-tools.ps1 create mode 100644 eng/common/sdl/extract-artifact-archives.ps1 create mode 100644 eng/common/sdl/extract-artifact-packages.ps1 create mode 100644 eng/common/sdl/init-sdl.ps1 create mode 100644 eng/common/sdl/packages.config create mode 100644 eng/common/sdl/run-sdl.ps1 create mode 100644 eng/common/templates/job/execute-sdl.yml create mode 100644 eng/common/templates/job/job.yml create mode 100644 eng/common/templates/job/onelocbuild.yml create mode 100644 eng/common/templates/job/publish-build-assets.yml create mode 100644 eng/common/templates/job/source-build.yml create mode 100644 eng/common/templates/job/source-index-stage1.yml create mode 100644 eng/common/templates/jobs/codeql-build.yml create mode 100644 eng/common/templates/jobs/jobs.yml create mode 100644 eng/common/templates/jobs/source-build.yml create mode 100644 eng/common/templates/post-build/common-variables.yml create mode 100644 eng/common/templates/post-build/post-build.yml create mode 100644 eng/common/templates/post-build/setup-maestro-vars.yml create mode 100644 eng/common/templates/post-build/trigger-subscription.yml create mode 100644 eng/common/templates/steps/add-build-to-channel.yml create mode 100644 eng/common/templates/steps/build-reason.yml create mode 100644 eng/common/templates/steps/execute-codeql.yml create mode 100644 eng/common/templates/steps/execute-sdl.yml create mode 100644 eng/common/templates/steps/generate-sbom.yml create mode 100644 eng/common/templates/steps/publish-logs.yml create mode 100644 eng/common/templates/steps/retain-build.yml create mode 100644 eng/common/templates/steps/run-on-unix.yml create mode 100644 eng/common/templates/steps/run-on-windows.yml create mode 100644 eng/common/templates/steps/run-script-ifequalelse.yml create mode 100644 eng/common/templates/steps/send-to-helix.yml create mode 100644 eng/common/templates/steps/source-build.yml create mode 100644 eng/common/templates/steps/telemetry-end.yml create mode 100644 eng/common/templates/steps/telemetry-start.yml create mode 100644 eng/common/templates/variables/sdl-variables.yml create mode 100644 eng/common/tools.ps1 create mode 100644 eng/common/tools.sh create mode 100644 global.json create mode 100644 pack.cmd create mode 100644 restore.cmd rename {tests => samples}/Katana.Sandbox.Selfhost/App.config (100%) rename {tests => samples}/Katana.Sandbox.Selfhost/Katana.Sandbox.Selfhost.csproj (100%) rename {tests => samples}/Katana.Sandbox.Selfhost/Program.cs (100%) rename {tests => samples}/Katana.Sandbox.Selfhost/Properties/AssemblyInfo.cs (71%) rename {src/Microsoft.Owin.Host.SystemWeb => samples/Katana.Sandbox.Selfhost}/packages.config (100%) rename {tests => samples}/Katana.Sandbox.WebClient/ClientApp.aspx (100%) rename {tests => samples}/Katana.Sandbox.WebClient/ClientApp.aspx.cs (100%) rename {tests => samples}/Katana.Sandbox.WebClient/ClientApp.aspx.designer.cs (100%) rename {tests => samples}/Katana.Sandbox.WebClient/ClientPage.html (100%) rename {tests => samples}/Katana.Sandbox.WebClient/ClientPage.js (100%) rename {tests => samples}/Katana.Sandbox.WebClient/ClientPageSignIn.html (100%) rename {tests => samples}/Katana.Sandbox.WebClient/ClientPageSignIn.js (100%) rename {tests => samples}/Katana.Sandbox.WebClient/Katana.Sandbox.WebClient.csproj (100%) rename {tests => samples}/Katana.Sandbox.WebClient/Properties/AssemblyInfo.cs (100%) rename {tests/Katana.Performance.ReferenceApp => samples/Katana.Sandbox.WebClient}/Web.Debug.config (100%) rename {tests/Katana.Performance.ReferenceApp => samples/Katana.Sandbox.WebClient}/Web.Release.config (100%) rename {tests => samples}/Katana.Sandbox.WebClient/Web.config (86%) rename {tests => samples}/Katana.Sandbox.WebClient/packages.config (100%) rename {tests => samples}/Katana.Sandbox.WebServer/AspNetAuthSessionStore.cs (100%) rename {tests => samples}/Katana.Sandbox.WebServer/Authorize.cshtml (100%) rename {tests => samples}/Katana.Sandbox.WebServer/AuthorizeError.cshtml (100%) rename {tests => samples}/Katana.Sandbox.WebServer/External.cshtml (100%) rename {tests => samples}/Katana.Sandbox.WebServer/InMemoryAuthSessionStore.cs (100%) rename {tests => samples}/Katana.Sandbox.WebServer/Katana.Sandbox.WebServer.csproj (100%) rename {tests => samples}/Katana.Sandbox.WebServer/Login.cshtml (100%) rename {tests => samples}/Katana.Sandbox.WebServer/Logout.cshtml (100%) rename {tests => samples}/Katana.Sandbox.WebServer/Properties/AssemblyInfo.cs (100%) rename {tests => samples}/Katana.Sandbox.WebServer/SameSiteCookieManager.cs (100%) rename {tests => samples}/Katana.Sandbox.WebServer/Startup.cs (98%) rename {tests/Katana.Sandbox.WebClient => samples/Katana.Sandbox.WebServer}/Web.Debug.config (100%) rename {tests/Katana.Sandbox.WebClient => samples/Katana.Sandbox.WebServer}/Web.Release.config (100%) rename {tests => samples}/Katana.Sandbox.WebServer/Web.config (100%) rename {src/Microsoft.Owin.Security.Jwt => samples/Katana.Sandbox.WebServer}/packages.config (100%) create mode 100644 src/Directory.Build.props delete mode 100644 src/Microsoft.Owin.Cors/Microsoft.Owin.Cors.nuspec delete mode 100644 src/Microsoft.Owin.Cors/packages.config delete mode 100644 src/Microsoft.Owin.Diagnostics/Microsoft.Owin.Diagnostics.nuspec delete mode 100644 src/Microsoft.Owin.Diagnostics/packages.config delete mode 100644 src/Microsoft.Owin.FileSystems/Microsoft.Owin.FileSystems.nuspec delete mode 100644 src/Microsoft.Owin.Host.HttpListener/Microsoft.Owin.Host.HttpListener.nuspec delete mode 100644 src/Microsoft.Owin.Host.SystemWeb/Microsoft.Owin.Host.SystemWeb.nuspec delete mode 100644 src/Microsoft.Owin.Hosting/Microsoft.Owin.Hosting.nuspec delete mode 100644 src/Microsoft.Owin.Hosting/packages.config delete mode 100644 src/Microsoft.Owin.Security.ActiveDirectory/Microsoft.Owin.Security.ActiveDirectory.nuspec delete mode 100644 src/Microsoft.Owin.Security.ActiveDirectory/packages.config delete mode 100644 src/Microsoft.Owin.Security.Cookies/Microsoft.Owin.Security.Cookies.nuspec delete mode 100644 src/Microsoft.Owin.Security.Cookies/packages.config delete mode 100644 src/Microsoft.Owin.Security.Facebook/Microsoft.Owin.Security.Facebook.nuspec delete mode 100644 src/Microsoft.Owin.Security.Facebook/packages.config delete mode 100644 src/Microsoft.Owin.Security.Google/Microsoft.Owin.Security.Google.nuspec delete mode 100644 src/Microsoft.Owin.Security.Google/packages.config delete mode 100644 src/Microsoft.Owin.Security.Jwt/Microsoft.Owin.Security.Jwt.nuspec delete mode 100644 src/Microsoft.Owin.Security.MicrosoftAccount/Microsoft.Owin.Security.MicrosoftAccount.nuspec delete mode 100644 src/Microsoft.Owin.Security.MicrosoftAccount/packages.config delete mode 100644 src/Microsoft.Owin.Security.OAuth/Microsoft.Owin.Security.OAuth.nuspec delete mode 100644 src/Microsoft.Owin.Security.OAuth/packages.config delete mode 100644 src/Microsoft.Owin.Security.OpenIdConnect/Microsoft.Owin.Security.OpenIdConnect.nuspec delete mode 100644 src/Microsoft.Owin.Security.OpenIdConnect/packages.config delete mode 100644 src/Microsoft.Owin.Security.Twitter/Microsoft.Owin.Security.Twitter.nuspec delete mode 100644 src/Microsoft.Owin.Security.Twitter/packages.config delete mode 100644 src/Microsoft.Owin.Security.WsFederation/Microsoft.Owin.Security.WsFederation.nuspec delete mode 100644 src/Microsoft.Owin.Security.WsFederation/packages.config delete mode 100644 src/Microsoft.Owin.Security/Microsoft.Owin.Security.csproj.DotSettings delete mode 100644 src/Microsoft.Owin.Security/Microsoft.Owin.Security.nuspec delete mode 100644 src/Microsoft.Owin.Security/packages.config create mode 100644 src/Microsoft.Owin.SelfHost/Microsoft.Owin.SelfHost.csproj delete mode 100644 src/Microsoft.Owin.SelfHost/Microsoft.Owin.SelfHost.nuspec rename src/Microsoft.Owin.SelfHost/{ReadMe.txt => README.md} (72%) delete mode 100644 src/Microsoft.Owin.StaticFiles/Microsoft.Owin.StaticFiles.nuspec delete mode 100644 src/Microsoft.Owin.StaticFiles/packages.config delete mode 100644 src/Microsoft.Owin.Testing/Microsoft.Owin.Testing.nuspec delete mode 100644 src/Microsoft.Owin.Testing/packages.config delete mode 100644 src/Microsoft.Owin/Microsoft.Owin.nuspec delete mode 100644 src/Microsoft.Owin/packages.config delete mode 100644 src/Owin.Loader/Properties/AssemblyInfo.cs delete mode 100644 src/Owin.Loader/packages.config delete mode 100644 src/OwinHost/OwinHost.csproj.DotSettings delete mode 100644 src/OwinHost/OwinHost.nuspec rename src/OwinHost/Package/{ReadMe.txt => ReadMe.md} (100%) delete mode 100644 src/Tools/CertificateInstaller/CertInstaller/Properties/AssemblyInfo.cs create mode 100644 startvs.cmd create mode 100644 test.cmd create mode 100644 tests/Directory.Build.props delete mode 100644 tests/Katana.Performance.ReferenceApp.Client/App.config delete mode 100644 tests/Katana.Performance.ReferenceApp.Client/Katana.Performance.ReferenceApp.Client.csproj delete mode 100644 tests/Katana.Performance.ReferenceApp.Client/Program.cs delete mode 100644 tests/Katana.Performance.ReferenceApp.Client/Properties/AssemblyInfo.cs delete mode 100644 tests/Katana.Performance.ReferenceApp.Selfhost/App.config delete mode 100644 tests/Katana.Performance.ReferenceApp.Selfhost/Katana.Performance.ReferenceApp.Selfhost.csproj delete mode 100644 tests/Katana.Performance.ReferenceApp.Selfhost/Program.cs delete mode 100644 tests/Katana.Performance.ReferenceApp.Selfhost/Properties/AssemblyInfo.cs delete mode 100644 tests/Katana.Performance.ReferenceApp.Selfhost/Public/large.txt delete mode 100644 tests/Katana.Performance.ReferenceApp.Selfhost/Public/small.txt delete mode 100644 tests/Katana.Performance.ReferenceApp.Selfhost/packages.config delete mode 100644 tests/Katana.Performance.ReferenceApp.Tests/CanonicalRequestPatternsTests.cs delete mode 100644 tests/Katana.Performance.ReferenceApp.Tests/Katana.Performance.ReferenceApp.Tests.csproj delete mode 100644 tests/Katana.Performance.ReferenceApp.Tests/Properties/AssemblyInfo.cs delete mode 100644 tests/Katana.Performance.ReferenceApp.Tests/packages.config delete mode 100644 tests/Katana.Performance.ReferenceApp/AutoTuneMiddleware.cs delete mode 100644 tests/Katana.Performance.ReferenceApp/CanonicalRequestAttribute.cs delete mode 100644 tests/Katana.Performance.ReferenceApp/CanonicalRequestPatterns.cs delete mode 100644 tests/Katana.Performance.ReferenceApp/HelloWorld.aspx delete mode 100644 tests/Katana.Performance.ReferenceApp/HelloWorld.aspx.cs delete mode 100644 tests/Katana.Performance.ReferenceApp/HelloWorld.aspx.designer.cs delete mode 100644 tests/Katana.Performance.ReferenceApp/Katana.Performance.ReferenceApp.csproj delete mode 100644 tests/Katana.Performance.ReferenceApp/Properties/AssemblyInfo.cs delete mode 100644 tests/Katana.Performance.ReferenceApp/Public/large.txt delete mode 100644 tests/Katana.Performance.ReferenceApp/Public/small.txt delete mode 100644 tests/Katana.Performance.ReferenceApp/Startup.cs delete mode 100644 tests/Katana.Performance.ReferenceApp/Util.cs delete mode 100644 tests/Katana.Performance.ReferenceApp/Web.config delete mode 100644 tests/Katana.Performance.ReferenceApp/packages.config delete mode 100644 tests/Katana.Performance.ReferenceAppJs/canonicalRequestPatterns.js delete mode 100644 tests/Katana.Performance.ReferenceAppJs/go.cmd delete mode 100644 tests/Katana.Performance.ReferenceAppJs/package.json delete mode 100644 tests/Katana.Performance.ReferenceAppJs/public/large.txt delete mode 100644 tests/Katana.Performance.ReferenceAppJs/public/small.txt delete mode 100644 tests/Katana.Performance.ReferenceAppJs/server.js delete mode 100644 tests/Katana.Sandbox.Selfhost/packages.config delete mode 100644 tests/Katana.Sandbox.WebServer/Web.Debug.config delete mode 100644 tests/Katana.Sandbox.WebServer/Web.Release.config delete mode 100644 tests/Katana.Sandbox.WebServer/packages.config delete mode 100644 tests/Microsoft.Owin.Cors.Tests/Properties/AssemblyInfo.cs delete mode 100644 tests/Microsoft.Owin.Cors.Tests/packages.config delete mode 100644 tests/Microsoft.Owin.FileSystems.Tests/Properties/AssemblyInfo.cs delete mode 100644 tests/Microsoft.Owin.FileSystems.Tests/packages.config delete mode 100644 tests/Microsoft.Owin.Host.IntegrationTests/Properties/AssemblyInfo.cs delete mode 100644 tests/Microsoft.Owin.Host.IntegrationTests/packages.config create mode 100644 tests/Microsoft.Owin.Host.SystemWeb.Tests/FakeN/FakeHttpContext.cs create mode 100644 tests/Microsoft.Owin.Host.SystemWeb.Tests/FakeN/FakeHttpRequest.cs create mode 100644 tests/Microsoft.Owin.Host.SystemWeb.Tests/FakeN/FakeHttpResponse.cs delete mode 100644 tests/Microsoft.Owin.Host.SystemWeb.Tests/Properties/AssemblyInfo.cs delete mode 100644 tests/Microsoft.Owin.Host.SystemWeb.Tests/packages.config delete mode 100644 tests/Microsoft.Owin.Hosting.Tests/Properties/AssemblyInfo.cs delete mode 100644 tests/Microsoft.Owin.Hosting.Tests/packages.config delete mode 100644 tests/Microsoft.Owin.Security.Tests/Properties/AssemblyInfo.cs delete mode 100644 tests/Microsoft.Owin.StaticFiles.Tests/Properties/AssemblyInfo.cs create mode 100644 tests/Microsoft.Owin.StaticFiles.Tests/TestRootFile.xml delete mode 100644 tests/Microsoft.Owin.StaticFiles.Tests/packages.config delete mode 100644 tests/Microsoft.Owin.Testing.Tests/Properties/AssemblyInfo.cs delete mode 100644 tests/Microsoft.Owin.Tests/Properties/AssemblyInfo.cs delete mode 100644 tests/Microsoft.Owin.Tests/packages.config delete mode 100644 tests/Owin.Loader.Tests/Properties/AssemblyInfo.cs delete mode 100644 tests/OwinHost.Tests/Properties/AssemblyInfo.cs delete mode 100644 tests/OwinHost.Tests/packages.config diff --git a/.gitignore b/.gitignore index 48703ba3c..2e1cf6a8b 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,5 @@ node_modules .nuget/NuGet.exe docs/build .vs +.dotnet +.packages \ No newline at end of file diff --git a/.nuget/NuGet.Config b/.nuget/NuGet.Config deleted file mode 100644 index 3b04a7b74..000000000 --- a/.nuget/NuGet.Config +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/BuildServer.targets b/BuildServer.targets deleted file mode 100644 index aa6a38f5a..000000000 --- a/BuildServer.targets +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/CredScanSuppressions.json b/CredScanSuppressions.json new file mode 100644 index 000000000..ff45b5433 --- /dev/null +++ b/CredScanSuppressions.json @@ -0,0 +1,12 @@ +{ + "tool": "Credential Scanner", + "suppressions": [ + { + "_justification": "Legitimate key/cert used for testing", + "file": [ + "tests/Microsoft.Owin.Host.HttpListener.Tests/HttpsServerTestCertificate.pfx", + "tests/Microsoft.Owin.Host.IntegrationTests/SelfSignedClientCert.pfx" + ] + } + ] +} \ No newline at end of file diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 000000000..117c49dff --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,25 @@ + + + + + $(CopyrightMicrosoft) + Apache-2.0 + True + embedded + true + Latest + true + Microsoft OWIN Katana + net4.5 + net4.5.2 + + + + + $(MicrosoftCodeAnalysisCSharpVersion) + + \ No newline at end of file diff --git a/Directory.Build.targets b/Directory.Build.targets new file mode 100644 index 000000000..bc6bef528 --- /dev/null +++ b/Directory.Build.targets @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/Katana.sln b/Katana.sln index 635baf9e4..ae48e7aed 100644 --- a/Katana.sln +++ b/Katana.sln @@ -1,67 +1,48 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +# Visual Studio Version 17 +VisualStudioVersion = 17.1.32210.238 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".Build", ".Build", "{D425FDFA-90FC-4276-8CBD-2850E8D78656}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".Solution Items", ".Solution Items", "{D425FDFA-90FC-4276-8CBD-2850E8D78656}" ProjectSection(SolutionItems) = preProject + .gitignore = .gitignore + azure-pipelines.yml = azure-pipelines.yml + Directory.Build.props = Directory.Build.props + Directory.Build.targets = Directory.Build.targets + global.json = global.json LICENSE.txt = LICENSE.txt + NuGet.Config = NuGet.Config README.md = README.md - Settings.StyleCop = Settings.StyleCop EndProjectSection EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{69D0ABFE-1C8A-4CFD-AF3A-D71445AEE6BF}" - ProjectSection(SolutionItems) = preProject - build\_apply-net45-changes.shade = build\_apply-net45-changes.shade - build.cmd = build.cmd - build.sh = build.sh - build\CodeAnalysis.ruleset = build\CodeAnalysis.ruleset - build\Common.targets = build\Common.targets - build\CommonAssemblyInfo.cs = build\CommonAssemblyInfo.cs - build\CustomDictionary.xml = build\CustomDictionary.xml - build\DevAssemblyInfo.cs = build\DevAssemblyInfo.cs - build\Katana.version.targets = build\Katana.version.targets - build\Sakefile.shade = build\Sakefile.shade - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.Hosting.Tests", "tests\Microsoft.Owin.Hosting.Tests\Microsoft.Owin.Hosting.Tests.csproj", "{D74769C3-CC85-440E-BDB8-9B20BFBFDDAE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.Hosting.Tests", "tests\Microsoft.Owin.Hosting.Tests\Microsoft.Owin.Hosting.Tests.csproj", "{D74769C3-CC85-440E-BDB8-9B20BFBFDDAE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.Host.HttpListener.Tests", "tests\Microsoft.Owin.Host.HttpListener.Tests\Microsoft.Owin.Host.HttpListener.Tests.csproj", "{A8FB7DCB-3370-4D2F-B41A-63C89D281A51}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.Host.HttpListener.Tests", "tests\Microsoft.Owin.Host.HttpListener.Tests\Microsoft.Owin.Host.HttpListener.Tests.csproj", "{A8FB7DCB-3370-4D2F-B41A-63C89D281A51}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Server", "Server", "{E80B5DAB-7D94-4E26-8A9E-98E5A887A72A}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Performance", "Performance", "{923FBCC6-ACE8-462C-ACE1-927C3EC8E77B}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Katana.Performance.ReferenceApp", "tests\Katana.Performance.ReferenceApp\Katana.Performance.ReferenceApp.csproj", "{C232AB29-2F3C-4E18-9234-67B1C70CDAD5}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Katana.Performance.ReferenceApp.Tests", "tests\Katana.Performance.ReferenceApp.Tests\Katana.Performance.ReferenceApp.Tests.csproj", "{E38930BA-9F12-4609-B97C-55F08200A392}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.Host.SystemWeb", "src\Microsoft.Owin.Host.SystemWeb\Microsoft.Owin.Host.SystemWeb.csproj", "{9F0C72D8-E43F-4F01-9DEB-9E8FE0AE179E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.Host.SystemWeb", "src\Microsoft.Owin.Host.SystemWeb\Microsoft.Owin.Host.SystemWeb.csproj", "{9F0C72D8-E43F-4F01-9DEB-9E8FE0AE179E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.Host.HttpListener", "src\Microsoft.Owin.Host.HttpListener\Microsoft.Owin.Host.HttpListener.csproj", "{9F0C72D8-E43F-4F01-9DEB-919191911919}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.Host.HttpListener", "src\Microsoft.Owin.Host.HttpListener\Microsoft.Owin.Host.HttpListener.csproj", "{9F0C72D8-E43F-4F01-9DEB-919191911919}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.Host.SystemWeb.Tests", "tests\Microsoft.Owin.Host.SystemWeb.Tests\Microsoft.Owin.Host.SystemWeb.Tests.csproj", "{9F0C72D8-E43F-4F01-9DEB-919191919191}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.Host.SystemWeb.Tests", "tests\Microsoft.Owin.Host.SystemWeb.Tests\Microsoft.Owin.Host.SystemWeb.Tests.csproj", "{9F0C72D8-E43F-4F01-9DEB-919191919191}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.Host.IntegrationTests", "tests\Microsoft.Owin.Host.IntegrationTests\Microsoft.Owin.Host.IntegrationTests.csproj", "{9F0C72D8-E43F-4F01-9DEB-123412341234}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.Host.IntegrationTests", "tests\Microsoft.Owin.Host.IntegrationTests\Microsoft.Owin.Host.IntegrationTests.csproj", "{9F0C72D8-E43F-4F01-9DEB-123412341234}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CertInstaller", "src\Tools\CertificateInstaller\CertInstaller\CertInstaller.csproj", "{558F65BE-E09D-4A9B-9DA8-C0983445726F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CertInstaller", "src\Tools\CertificateInstaller\CertInstaller\CertInstaller.csproj", "{558F65BE-E09D-4A9B-9DA8-C0983445726F}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{47488541-F6D1-4385-AE49-7E3C72042521}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Katana.Performance.ReferenceApp.Selfhost", "tests\Katana.Performance.ReferenceApp.Selfhost\Katana.Performance.ReferenceApp.Selfhost.csproj", "{8AE2E716-258A-4EF3-ADF1-D3B75D677F29}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.StaticFiles", "src\Microsoft.Owin.StaticFiles\Microsoft.Owin.StaticFiles.csproj", "{F31A42DB-2F57-4DAC-B2BC-106F2D6F3C82}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.StaticFiles", "src\Microsoft.Owin.StaticFiles\Microsoft.Owin.StaticFiles.csproj", "{F31A42DB-2F57-4DAC-B2BC-106F2D6F3C82}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.StaticFiles.Tests", "tests\Microsoft.Owin.StaticFiles.Tests\Microsoft.Owin.StaticFiles.Tests.csproj", "{473F6EEE-455F-4553-953D-5D0736D62D11}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.StaticFiles.Tests", "tests\Microsoft.Owin.StaticFiles.Tests\Microsoft.Owin.StaticFiles.Tests.csproj", "{473F6EEE-455F-4553-953D-5D0736D62D11}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.Testing", "src\Microsoft.Owin.Testing\Microsoft.Owin.Testing.csproj", "{73F1A72C-BCDE-4912-8AF7-6BE33D92FCC0}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.Testing", "src\Microsoft.Owin.Testing\Microsoft.Owin.Testing.csproj", "{73F1A72C-BCDE-4912-8AF7-6BE33D92FCC0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.Diagnostics", "src\Microsoft.Owin.Diagnostics\Microsoft.Owin.Diagnostics.csproj", "{670915F7-F111-42FF-B004-39379A9D5951}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.Diagnostics", "src\Microsoft.Owin.Diagnostics\Microsoft.Owin.Diagnostics.csproj", "{670915F7-F111-42FF-B004-39379A9D5951}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.FileSystems", "src\Microsoft.Owin.FileSystems\Microsoft.Owin.FileSystems.csproj", "{63988A9B-FA70-4BBA-8C7E-784145384F7C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.FileSystems", "src\Microsoft.Owin.FileSystems\Microsoft.Owin.FileSystems.csproj", "{63988A9B-FA70-4BBA-8C7E-784145384F7C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.FileSystems.Tests", "tests\Microsoft.Owin.FileSystems.Tests\Microsoft.Owin.FileSystems.Tests.csproj", "{5737FA14-B873-496B-8141-49D5B273AC3A}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".Prerelease", ".Prerelease", "{A7292674-B84F-4D30-9E2D-C4885AF20608}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.FileSystems.Tests", "tests\Microsoft.Owin.FileSystems.Tests\Microsoft.Owin.FileSystems.Tests.csproj", "{5737FA14-B873-496B-8141-49D5B273AC3A}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Hosting", "Hosting", "{B9AC3489-752E-4C4E-84E4-1C82227435BA}" EndProject @@ -69,76 +50,74 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Development", "Development" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Security", "Security", "{10A4935F-4C17-44ED-BB00-D044FC7C77B8}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.Security.Cookies", "src\Microsoft.Owin.Security.Cookies\Microsoft.Owin.Security.Cookies.csproj", "{2FB9342F-CA85-4903-8667-45ED64AD25A6}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.Security", "src\Microsoft.Owin.Security\Microsoft.Owin.Security.csproj", "{AAAF8157-1E33-4D6C-8319-3B304D018005}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.Security.Cookies", "src\Microsoft.Owin.Security.Cookies\Microsoft.Owin.Security.Cookies.csproj", "{2FB9342F-CA85-4903-8667-45ED64AD25A6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.Security.Tests", "tests\Microsoft.Owin.Security.Tests\Microsoft.Owin.Security.Tests.csproj", "{E3B9A023-2146-4D9D-A806-1479683078AE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.Security", "src\Microsoft.Owin.Security\Microsoft.Owin.Security.csproj", "{AAAF8157-1E33-4D6C-8319-3B304D018005}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.Security.Facebook", "src\Microsoft.Owin.Security.Facebook\Microsoft.Owin.Security.Facebook.csproj", "{F6F1D34F-3AF6-41DD-B493-60899F959BBA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.Security.Tests", "tests\Microsoft.Owin.Security.Tests\Microsoft.Owin.Security.Tests.csproj", "{E3B9A023-2146-4D9D-A806-1479683078AE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.Security.Google", "src\Microsoft.Owin.Security.Google\Microsoft.Owin.Security.Google.csproj", "{1F46BC62-A011-4B63-A5C6-51AEE2EF538D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.Security.Facebook", "src\Microsoft.Owin.Security.Facebook\Microsoft.Owin.Security.Facebook.csproj", "{F6F1D34F-3AF6-41DD-B493-60899F959BBA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.Security.OAuth", "src\Microsoft.Owin.Security.OAuth\Microsoft.Owin.Security.OAuth.csproj", "{F71E48D0-115A-4105-B332-FCCB2139DC23}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.Security.Google", "src\Microsoft.Owin.Security.Google\Microsoft.Owin.Security.Google.csproj", "{1F46BC62-A011-4B63-A5C6-51AEE2EF538D}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sandbox", "Sandbox", "{D067FB54-B69D-4502-8E2F-676271AC4B86}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.Security.OAuth", "src\Microsoft.Owin.Security.OAuth\Microsoft.Owin.Security.OAuth.csproj", "{F71E48D0-115A-4105-B332-FCCB2139DC23}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Katana.Sandbox.WebServer", "tests\Katana.Sandbox.WebServer\Katana.Sandbox.WebServer.csproj", "{1069B86E-F2C1-498B-9DD8-76C7257C6A2A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OwinHost", "src\OwinHost\OwinHost.csproj", "{D56B8357-F044-45DE-85E9-41AA7C84751E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Katana.Sandbox.WebClient", "tests\Katana.Sandbox.WebClient\Katana.Sandbox.WebClient.csproj", "{3AE67011-EBB1-4ADE-8F42-8E90EB884219}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OwinHost.Tests", "tests\OwinHost.Tests\OwinHost.Tests.csproj", "{62ACEFEA-39F8-405E-BC25-0633F1770A4B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OwinHost", "src\OwinHost\OwinHost.csproj", "{D56B8357-F044-45DE-85E9-41AA7C84751E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin", "src\Microsoft.Owin\Microsoft.Owin.csproj", "{0DB69CAE-B0BC-4688-9467-66B4C1023D3F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OwinHost.Tests", "tests\OwinHost.Tests\OwinHost.Tests.csproj", "{62ACEFEA-39F8-405E-BC25-0633F1770A4B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Owin.Loader", "src\Owin.Loader\Owin.Loader.csproj", "{DF967ED4-C320-421C-859C-81034EFF615E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin", "src\Microsoft.Owin\Microsoft.Owin.csproj", "{0DB69CAE-B0BC-4688-9467-66B4C1023D3F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.Tests", "tests\Microsoft.Owin.Tests\Microsoft.Owin.Tests.csproj", "{0AF835A6-8181-46DB-A17E-C765FA07A5A0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Owin.Loader", "src\Owin.Loader\Owin.Loader.csproj", "{DF967ED4-C320-421C-859C-81034EFF615E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Owin.Loader.Tests", "tests\Owin.Loader.Tests\Owin.Loader.Tests.csproj", "{13785347-FC73-4D0E-9DCA-300DD87C308E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.Tests", "tests\Microsoft.Owin.Tests\Microsoft.Owin.Tests.csproj", "{0AF835A6-8181-46DB-A17E-C765FA07A5A0}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.Security.Twitter", "src\Microsoft.Owin.Security.Twitter\Microsoft.Owin.Security.Twitter.csproj", "{BBB663CB-E6A2-4E23-83C9-9C8F52325F44}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Owin.Loader.Tests", "tests\Owin.Loader.Tests\Owin.Loader.Tests.csproj", "{13785347-FC73-4D0E-9DCA-300DD87C308E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.Security.MicrosoftAccount", "src\Microsoft.Owin.Security.MicrosoftAccount\Microsoft.Owin.Security.MicrosoftAccount.csproj", "{52F6930F-FBC0-404B-B135-6B6756F5713A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.Security.Twitter", "src\Microsoft.Owin.Security.Twitter\Microsoft.Owin.Security.Twitter.csproj", "{BBB663CB-E6A2-4E23-83C9-9C8F52325F44}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.Hosting", "src\Microsoft.Owin.Hosting\Microsoft.Owin.Hosting.csproj", "{C225EB2F-E7A7-463F-B058-1705F204978E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.Security.MicrosoftAccount", "src\Microsoft.Owin.Security.MicrosoftAccount\Microsoft.Owin.Security.MicrosoftAccount.csproj", "{52F6930F-FBC0-404B-B135-6B6756F5713A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.Testing.Tests", "tests\Microsoft.Owin.Testing.Tests\Microsoft.Owin.Testing.Tests.csproj", "{628A8C89-5E59-4747-8D6A-AA22267552ED}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.Owin.SelfHost", "Microsoft.Owin.SelfHost", "{9298DB20-54F3-4078-8F7F-D95B3CFA1312}" - ProjectSection(SolutionItems) = preProject - src\Microsoft.Owin.SelfHost\Microsoft.Owin.SelfHost.nuspec = src\Microsoft.Owin.SelfHost\Microsoft.Owin.SelfHost.nuspec - src\Microsoft.Owin.SelfHost\ReadMe.txt = src\Microsoft.Owin.SelfHost\ReadMe.txt - EndProjectSection +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Middleware", "Middleware", "{C5F4B293-90EC-48B8-97FA-CD23C44C9C30}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.Hosting", "src\Microsoft.Owin.Hosting\Microsoft.Owin.Hosting.csproj", "{C225EB2F-E7A7-463F-B058-1705F204978E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.Cors", "src\Microsoft.Owin.Cors\Microsoft.Owin.Cors.csproj", "{CD4593FD-F70C-4485-ACAD-AC69DAD1BBB1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.Testing.Tests", "tests\Microsoft.Owin.Testing.Tests\Microsoft.Owin.Testing.Tests.csproj", "{628A8C89-5E59-4747-8D6A-AA22267552ED}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.Cors.Tests", "tests\Microsoft.Owin.Cors.Tests\Microsoft.Owin.Cors.Tests.csproj", "{3DDAC01B-2567-4C0C-88E1-0A716729203E}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Middleware", "Middleware", "{C5F4B293-90EC-48B8-97FA-CD23C44C9C30}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.Security.Jwt", "src\Microsoft.Owin.Security.Jwt\Microsoft.Owin.Security.Jwt.csproj", "{CC7E3A76-37B0-4C3D-B666-62DC34F04ABC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.Cors", "src\Microsoft.Owin.Cors\Microsoft.Owin.Cors.csproj", "{CD4593FD-F70C-4485-ACAD-AC69DAD1BBB1}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.Security.ActiveDirectory", "src\Microsoft.Owin.Security.ActiveDirectory\Microsoft.Owin.Security.ActiveDirectory.csproj", "{03F2BF9F-BE6C-4DAE-9615-46A7F05EF842}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.Cors.Tests", "tests\Microsoft.Owin.Cors.Tests\Microsoft.Owin.Cors.Tests.csproj", "{3DDAC01B-2567-4C0C-88E1-0A716729203E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.Security.WsFederation", "src\Microsoft.Owin.Security.WsFederation\Microsoft.Owin.Security.WsFederation.csproj", "{23D90C94-647A-416C-9227-9A0779401EBC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Katana.Performance.ReferenceApp.Client", "tests\Katana.Performance.ReferenceApp.Client\Katana.Performance.ReferenceApp.Client.csproj", "{0D370C5B-7518-4D60-9D47-1AD59794F38F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.Security.OpenIdConnect", "src\Microsoft.Owin.Security.OpenIdConnect\Microsoft.Owin.Security.OpenIdConnect.csproj", "{AA80B4A3-C885-4A7E-AF1A-FC3E89611988}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.Security.Jwt", "src\Microsoft.Owin.Security.Jwt\Microsoft.Owin.Security.Jwt.csproj", "{CC7E3A76-37B0-4C3D-B666-62DC34F04ABC}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FunctionalTests", "FunctionalTests", "{DD2E82F1-F3EA-4D1F-B623-9C34440D79D6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.Security.ActiveDirectory", "src\Microsoft.Owin.Security.ActiveDirectory\Microsoft.Owin.Security.ActiveDirectory.csproj", "{03F2BF9F-BE6C-4DAE-9615-46A7F05EF842}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FunctionalTests", "tests\FunctionalTests\FunctionalTests.csproj", "{4EF3F748-16D0-4112-AE43-AACADB3EF8E9}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".Nuget", ".Nuget", "{5230439B-C2AD-4A08-8927-526BA3BF9BF6}" - ProjectSection(SolutionItems) = preProject - .nuget\NuGet.Config = .nuget\NuGet.Config - EndProjectSection +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{EFB86EB3-F362-4E30-92DD-5CB9C5084A6D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.Security.WsFederation", "src\Microsoft.Owin.Security.WsFederation\Microsoft.Owin.Security.WsFederation.csproj", "{23D90C94-647A-416C-9227-9A0779401EBC}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Katana.Sandbox.Selfhost", "samples\Katana.Sandbox.Selfhost\Katana.Sandbox.Selfhost.csproj", "{9F2F31EF-6017-48CC-88D6-EC4FF4FEAAA5}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Owin.Security.OpenIdConnect", "src\Microsoft.Owin.Security.OpenIdConnect\Microsoft.Owin.Security.OpenIdConnect.csproj", "{AA80B4A3-C885-4A7E-AF1A-FC3E89611988}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Katana.Sandbox.WebClient", "samples\Katana.Sandbox.WebClient\Katana.Sandbox.WebClient.csproj", "{3AE67011-EBB1-4ADE-8F42-8E90EB884219}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FunctionalTests", "FunctionalTests", "{DD2E82F1-F3EA-4D1F-B623-9C34440D79D6}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Katana.Sandbox.WebServer", "samples\Katana.Sandbox.WebServer\Katana.Sandbox.WebServer.csproj", "{1069B86E-F2C1-498B-9DD8-76C7257C6A2A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FunctionalTests", "tests\FunctionalTests\FunctionalTests.csproj", "{4EF3F748-16D0-4112-AE43-AACADB3EF8E9}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Owin.SelfHost", "src\Microsoft.Owin.SelfHost\Microsoft.Owin.SelfHost.csproj", "{631EE03C-7887-4F03-A01B-AB669560A061}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Katana.Sandbox.Selfhost", "tests\Katana.Sandbox.Selfhost\Katana.Sandbox.Selfhost.csproj", "{9F2F31EF-6017-48CC-88D6-EC4FF4FEAAA5}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "eng", "eng", "{B5567E1E-04AC-42D6-BAAC-E795601C157E}" + ProjectSection(SolutionItems) = preProject + eng\Build.props = eng\Build.props + eng\Publishing.props = eng\Publishing.props + eng\Signing.props = eng\Signing.props + eng\Version.Details.xml = eng\Version.Details.xml + eng\Versions.props = eng\Versions.props + EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -152,14 +131,6 @@ Global {A8FB7DCB-3370-4D2F-B41A-63C89D281A51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A8FB7DCB-3370-4D2F-B41A-63C89D281A51}.Debug|Any CPU.Build.0 = Debug|Any CPU {A8FB7DCB-3370-4D2F-B41A-63C89D281A51}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C232AB29-2F3C-4E18-9234-67B1C70CDAD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C232AB29-2F3C-4E18-9234-67B1C70CDAD5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C232AB29-2F3C-4E18-9234-67B1C70CDAD5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C232AB29-2F3C-4E18-9234-67B1C70CDAD5}.Release|Any CPU.Build.0 = Release|Any CPU - {E38930BA-9F12-4609-B97C-55F08200A392}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E38930BA-9F12-4609-B97C-55F08200A392}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E38930BA-9F12-4609-B97C-55F08200A392}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E38930BA-9F12-4609-B97C-55F08200A392}.Release|Any CPU.Build.0 = Release|Any CPU {9F0C72D8-E43F-4F01-9DEB-9E8FE0AE179E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9F0C72D8-E43F-4F01-9DEB-9E8FE0AE179E}.Debug|Any CPU.Build.0 = Debug|Any CPU {9F0C72D8-E43F-4F01-9DEB-9E8FE0AE179E}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -179,10 +150,6 @@ Global {558F65BE-E09D-4A9B-9DA8-C0983445726F}.Debug|Any CPU.Build.0 = Debug|Any CPU {558F65BE-E09D-4A9B-9DA8-C0983445726F}.Release|Any CPU.ActiveCfg = Release|Any CPU {558F65BE-E09D-4A9B-9DA8-C0983445726F}.Release|Any CPU.Build.0 = Release|Any CPU - {8AE2E716-258A-4EF3-ADF1-D3B75D677F29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8AE2E716-258A-4EF3-ADF1-D3B75D677F29}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8AE2E716-258A-4EF3-ADF1-D3B75D677F29}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8AE2E716-258A-4EF3-ADF1-D3B75D677F29}.Release|Any CPU.Build.0 = Release|Any CPU {F31A42DB-2F57-4DAC-B2BC-106F2D6F3C82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F31A42DB-2F57-4DAC-B2BC-106F2D6F3C82}.Debug|Any CPU.Build.0 = Debug|Any CPU {F31A42DB-2F57-4DAC-B2BC-106F2D6F3C82}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -231,13 +198,6 @@ Global {F71E48D0-115A-4105-B332-FCCB2139DC23}.Debug|Any CPU.Build.0 = Debug|Any CPU {F71E48D0-115A-4105-B332-FCCB2139DC23}.Release|Any CPU.ActiveCfg = Release|Any CPU {F71E48D0-115A-4105-B332-FCCB2139DC23}.Release|Any CPU.Build.0 = Release|Any CPU - {1069B86E-F2C1-498B-9DD8-76C7257C6A2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1069B86E-F2C1-498B-9DD8-76C7257C6A2A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1069B86E-F2C1-498B-9DD8-76C7257C6A2A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3AE67011-EBB1-4ADE-8F42-8E90EB884219}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3AE67011-EBB1-4ADE-8F42-8E90EB884219}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3AE67011-EBB1-4ADE-8F42-8E90EB884219}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3AE67011-EBB1-4ADE-8F42-8E90EB884219}.Release|Any CPU.Build.0 = Release|Any CPU {D56B8357-F044-45DE-85E9-41AA7C84751E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D56B8357-F044-45DE-85E9-41AA7C84751E}.Debug|Any CPU.Build.0 = Debug|Any CPU {D56B8357-F044-45DE-85E9-41AA7C84751E}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -286,10 +246,6 @@ Global {3DDAC01B-2567-4C0C-88E1-0A716729203E}.Debug|Any CPU.Build.0 = Debug|Any CPU {3DDAC01B-2567-4C0C-88E1-0A716729203E}.Release|Any CPU.ActiveCfg = Release|Any CPU {3DDAC01B-2567-4C0C-88E1-0A716729203E}.Release|Any CPU.Build.0 = Release|Any CPU - {0D370C5B-7518-4D60-9D47-1AD59794F38F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0D370C5B-7518-4D60-9D47-1AD59794F38F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0D370C5B-7518-4D60-9D47-1AD59794F38F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0D370C5B-7518-4D60-9D47-1AD59794F38F}.Release|Any CPU.Build.0 = Release|Any CPU {CC7E3A76-37B0-4C3D-B666-62DC34F04ABC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CC7E3A76-37B0-4C3D-B666-62DC34F04ABC}.Debug|Any CPU.Build.0 = Debug|Any CPU {CC7E3A76-37B0-4C3D-B666-62DC34F04ABC}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -314,22 +270,30 @@ Global {9F2F31EF-6017-48CC-88D6-EC4FF4FEAAA5}.Debug|Any CPU.Build.0 = Debug|Any CPU {9F2F31EF-6017-48CC-88D6-EC4FF4FEAAA5}.Release|Any CPU.ActiveCfg = Release|Any CPU {9F2F31EF-6017-48CC-88D6-EC4FF4FEAAA5}.Release|Any CPU.Build.0 = Release|Any CPU + {3AE67011-EBB1-4ADE-8F42-8E90EB884219}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3AE67011-EBB1-4ADE-8F42-8E90EB884219}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3AE67011-EBB1-4ADE-8F42-8E90EB884219}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3AE67011-EBB1-4ADE-8F42-8E90EB884219}.Release|Any CPU.Build.0 = Release|Any CPU + {1069B86E-F2C1-498B-9DD8-76C7257C6A2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1069B86E-F2C1-498B-9DD8-76C7257C6A2A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1069B86E-F2C1-498B-9DD8-76C7257C6A2A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1069B86E-F2C1-498B-9DD8-76C7257C6A2A}.Release|Any CPU.Build.0 = Release|Any CPU + {631EE03C-7887-4F03-A01B-AB669560A061}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {631EE03C-7887-4F03-A01B-AB669560A061}.Debug|Any CPU.Build.0 = Debug|Any CPU + {631EE03C-7887-4F03-A01B-AB669560A061}.Release|Any CPU.ActiveCfg = Release|Any CPU + {631EE03C-7887-4F03-A01B-AB669560A061}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {69D0ABFE-1C8A-4CFD-AF3A-D71445AEE6BF} = {D425FDFA-90FC-4276-8CBD-2850E8D78656} {D74769C3-CC85-440E-BDB8-9B20BFBFDDAE} = {B9AC3489-752E-4C4E-84E4-1C82227435BA} {A8FB7DCB-3370-4D2F-B41A-63C89D281A51} = {E80B5DAB-7D94-4E26-8A9E-98E5A887A72A} - {C232AB29-2F3C-4E18-9234-67B1C70CDAD5} = {923FBCC6-ACE8-462C-ACE1-927C3EC8E77B} - {E38930BA-9F12-4609-B97C-55F08200A392} = {923FBCC6-ACE8-462C-ACE1-927C3EC8E77B} {9F0C72D8-E43F-4F01-9DEB-9E8FE0AE179E} = {E80B5DAB-7D94-4E26-8A9E-98E5A887A72A} {9F0C72D8-E43F-4F01-9DEB-919191911919} = {E80B5DAB-7D94-4E26-8A9E-98E5A887A72A} {9F0C72D8-E43F-4F01-9DEB-919191919191} = {E80B5DAB-7D94-4E26-8A9E-98E5A887A72A} {9F0C72D8-E43F-4F01-9DEB-123412341234} = {E80B5DAB-7D94-4E26-8A9E-98E5A887A72A} {558F65BE-E09D-4A9B-9DA8-C0983445726F} = {47488541-F6D1-4385-AE49-7E3C72042521} - {8AE2E716-258A-4EF3-ADF1-D3B75D677F29} = {923FBCC6-ACE8-462C-ACE1-927C3EC8E77B} {F31A42DB-2F57-4DAC-B2BC-106F2D6F3C82} = {C5F4B293-90EC-48B8-97FA-CD23C44C9C30} {473F6EEE-455F-4553-953D-5D0736D62D11} = {C5F4B293-90EC-48B8-97FA-CD23C44C9C30} {73F1A72C-BCDE-4912-8AF7-6BE33D92FCC0} = {E7D2B8A2-4586-4660-BB84-E46A58CD5F7F} @@ -342,8 +306,6 @@ Global {F6F1D34F-3AF6-41DD-B493-60899F959BBA} = {10A4935F-4C17-44ED-BB00-D044FC7C77B8} {1F46BC62-A011-4B63-A5C6-51AEE2EF538D} = {10A4935F-4C17-44ED-BB00-D044FC7C77B8} {F71E48D0-115A-4105-B332-FCCB2139DC23} = {10A4935F-4C17-44ED-BB00-D044FC7C77B8} - {1069B86E-F2C1-498B-9DD8-76C7257C6A2A} = {D067FB54-B69D-4502-8E2F-676271AC4B86} - {3AE67011-EBB1-4ADE-8F42-8E90EB884219} = {D067FB54-B69D-4502-8E2F-676271AC4B86} {D56B8357-F044-45DE-85E9-41AA7C84751E} = {B9AC3489-752E-4C4E-84E4-1C82227435BA} {62ACEFEA-39F8-405E-BC25-0633F1770A4B} = {B9AC3489-752E-4C4E-84E4-1C82227435BA} {0DB69CAE-B0BC-4688-9467-66B4C1023D3F} = {E7D2B8A2-4586-4660-BB84-E46A58CD5F7F} @@ -352,17 +314,22 @@ Global {13785347-FC73-4D0E-9DCA-300DD87C308E} = {B9AC3489-752E-4C4E-84E4-1C82227435BA} {BBB663CB-E6A2-4E23-83C9-9C8F52325F44} = {10A4935F-4C17-44ED-BB00-D044FC7C77B8} {52F6930F-FBC0-404B-B135-6B6756F5713A} = {10A4935F-4C17-44ED-BB00-D044FC7C77B8} - {9298DB20-54F3-4078-8F7F-D95B3CFA1312} = {B9AC3489-752E-4C4E-84E4-1C82227435BA} {C225EB2F-E7A7-463F-B058-1705F204978E} = {B9AC3489-752E-4C4E-84E4-1C82227435BA} {628A8C89-5E59-4747-8D6A-AA22267552ED} = {E7D2B8A2-4586-4660-BB84-E46A58CD5F7F} {CD4593FD-F70C-4485-ACAD-AC69DAD1BBB1} = {C5F4B293-90EC-48B8-97FA-CD23C44C9C30} {3DDAC01B-2567-4C0C-88E1-0A716729203E} = {C5F4B293-90EC-48B8-97FA-CD23C44C9C30} - {0D370C5B-7518-4D60-9D47-1AD59794F38F} = {923FBCC6-ACE8-462C-ACE1-927C3EC8E77B} {CC7E3A76-37B0-4C3D-B666-62DC34F04ABC} = {10A4935F-4C17-44ED-BB00-D044FC7C77B8} {03F2BF9F-BE6C-4DAE-9615-46A7F05EF842} = {10A4935F-4C17-44ED-BB00-D044FC7C77B8} {23D90C94-647A-416C-9227-9A0779401EBC} = {10A4935F-4C17-44ED-BB00-D044FC7C77B8} {AA80B4A3-C885-4A7E-AF1A-FC3E89611988} = {10A4935F-4C17-44ED-BB00-D044FC7C77B8} {4EF3F748-16D0-4112-AE43-AACADB3EF8E9} = {DD2E82F1-F3EA-4D1F-B623-9C34440D79D6} - {9F2F31EF-6017-48CC-88D6-EC4FF4FEAAA5} = {D067FB54-B69D-4502-8E2F-676271AC4B86} + {9F2F31EF-6017-48CC-88D6-EC4FF4FEAAA5} = {EFB86EB3-F362-4E30-92DD-5CB9C5084A6D} + {3AE67011-EBB1-4ADE-8F42-8E90EB884219} = {EFB86EB3-F362-4E30-92DD-5CB9C5084A6D} + {1069B86E-F2C1-498B-9DD8-76C7257C6A2A} = {EFB86EB3-F362-4E30-92DD-5CB9C5084A6D} + {631EE03C-7887-4F03-A01B-AB669560A061} = {B9AC3489-752E-4C4E-84E4-1C82227435BA} + {B5567E1E-04AC-42D6-BAAC-E795601C157E} = {D425FDFA-90FC-4276-8CBD-2850E8D78656} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {02123D4B-8D21-4C7F-88B5-E1B1834302BB} EndGlobalSection EndGlobal diff --git a/LICENSE.txt b/LICENSE.txt index abac509a6..d64569567 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,3 +1,4 @@ + Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -186,7 +187,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright (c) .NET Foundation and Contributors + Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -198,4 +199,4 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file + limitations under the License. diff --git a/NuGet.Config b/NuGet.Config new file mode 100644 index 000000000..8a01990e4 --- /dev/null +++ b/NuGet.Config @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/Settings.StyleCop b/Settings.StyleCop deleted file mode 100644 index abf2d5033..000000000 --- a/Settings.StyleCop +++ /dev/null @@ -1,375 +0,0 @@ - - - NoMerge - - finalizer - Func - Owin - Ws - - - - - - False - - \.g\.cs$ - \.generated\.cs$ - \.g\.i\.cs$ - TemporaryGeneratedFile_.*\.cs$ - .*\\App_Packages\\.* - - - - - - - - - - False - - - - - False - - - - - - as - db - dc - do - ef - id - if - in - is - my - no - on - sl - to - ui - vs - ws - - - - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - True - True - - - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - - - - - - False - - - - - False - - - - - False - - - - - False - - - - - False - - - - - - - - - - False - - - - - False - - - - - False - - - - - - - - - - False - - - - - False - - - - - False - - - - - False - - - - - - - \ No newline at end of file diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 000000000..df398d674 --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,125 @@ +# +# See https://docs.microsoft.com/azure/devops/pipelines/yaml-schema for details +# + +variables: + - name: _TeamName + value: AspNetCore + - name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE + value: true + - name: _PublishUsingPipelines + value: true + - name: _BuildConfig + value: Release + + # used for post-build phases, internal builds only + - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - group: AspNetKatana-SDLValidation-Params + +# CI and PR triggers +trigger: + batch: true + branches: + include: + - main + - release/* + - internal/release/* + +pr: + autoCancel: false + branches: + include: + - '*' + +stages: +- stage: build + displayName: Build + jobs: + - template: /eng/common/templates/jobs/jobs.yml + parameters: + enableMicrobuild: true + enablePublishBuildArtifacts: true + enablePublishTestResults: true + enablePublishBuildAssets: true + enablePublishUsingPipelines: ${{ variables._PublishUsingPipelines }} + enableTelemetry: true + mergeTestResults: true + jobs: + - job: Windows + pool: + ${{ if eq(variables['System.TeamProject'], 'public') }}: + name: NetCore1ESPool-Public + demands: ImageOverride -equals Build.Windows.10.Amd64.VS2019.Pre.Open + ${{ if ne(variables['System.TeamProject'], 'public') }}: + name: NetCore1ESPool-Internal + demands: ImageOverride -equals Build.Windows.10.Amd64.VS2019.Pre + variables: + + + # Only enable publishing in official builds. + - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + # Publish-Build-Assets provides: MaestroAccessToken, BotAccount-dotnet-maestro-bot-PAT + - group: Publish-Build-Assets + - name: _OfficialBuildArgs + value: /p:DotNetSignType=$(_SignType) + /p:TeamName=$(_TeamName) + /p:DotNetPublishUsingPipelines=$(_PublishUsingPipelines) + /p:OfficialBuildId=$(BUILD.BUILDNUMBER) + - name: _SignType + value: real + # else + - ${{ if or(eq(variables['System.TeamProject'], 'public'), in(variables['Build.Reason'], 'PullRequest')) }}: + - name: _OfficialBuildArgs + value: '' + - name: _SignType + value: test + + steps: + - checkout: self + clean: true + - script: eng\common\cibuild.cmd -configuration $(_BuildConfig) -prepareMachine $(_OfficialBuildArgs) + displayName: Build and Publish + - task: PublishBuildArtifacts@1 + displayName: Upload TestResults + condition: always() + continueOnError: true + inputs: + pathtoPublish: artifacts/TestResults/$(_BuildConfig)/ + artifactName: $(Agent.Os)_$(Agent.JobName) TestResults + artifactType: Container + parallel: true + - task: PublishBuildArtifacts@1 + displayName: Upload package artifacts + condition: and(succeeded(), eq(variables['system.pullrequest.isfork'], false), eq(variables['_BuildConfig'], 'Release')) + inputs: + pathtoPublish: artifacts/packages/ + artifactName: artifacts + artifactType: Container + parallel: true + +- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - template: eng\common\templates\post-build\post-build.yml + parameters: + publishingInfraVersion: 3 + # Symbol validation isn't being very reliable lately. This should be enabled back + # once this issue is resolved: https://github.com/dotnet/arcade/issues/2871 + enableSymbolValidation: false + # It's a private repo in github so this won't pass until we create an internal mirror + enableSourceLinkValidation: false + enableSigningValidation: false + enableNugetValidation: false + # This is to enable SDL runs part of Post-Build Validation Stage + SDLValidationParameters: + enable: true + continueOnError: false + params: ' -SourceToolsList @("policheck","credscan") + -TsaInstanceURL $(_TsaInstanceURL) + -TsaProjectName $(_TsaProjectName) + -TsaNotificationEmail $(_TsaNotificationEmail) + -TsaCodebaseAdmin $(_TsaCodebaseAdmin) + -TsaBugAreaPath $(_TsaBugAreaPath) + -TsaIterationPath $(_TsaIterationPath) + -TsaRepositoryName "AspNetKatana" + -TsaCodebaseName "AspNetKatana" + -TsaPublish $True + ' diff --git a/build.cmd b/build.cmd index 42feedbcd..675fdf83f 100644 --- a/build.cmd +++ b/build.cmd @@ -1,11 +1,2 @@ @echo off -cd %~dp0 - -IF EXIST .nuget\NuGet.exe goto part2 -echo Downloading latest version of NuGet.exe... -@powershell -NoProfile -ExecutionPolicy unrestricted -Command ".\build\downloadnuget.ps1" - -:part2 -set EnableNuGetPackageRestore=true -.nuget\NuGet.exe install Sake -version 0.2 -o packages -source https://api.nuget.org/v3/index.json -packages\Sake.0.2\tools\Sake.exe -I build -f Sakefile.shade %* +powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0eng\common\Build.ps1""" -restore -build %*" diff --git a/build/CodeAnalysis.ruleset b/build/CodeAnalysis.ruleset deleted file mode 100644 index 5f814a66b..000000000 --- a/build/CodeAnalysis.ruleset +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/build/Common.targets b/build/Common.targets deleted file mode 100644 index f872d882c..000000000 --- a/build/Common.targets +++ /dev/null @@ -1,19 +0,0 @@ - - - - - CustomDictionary.xml - - - - 5 - false - true - - - $(DefineConstants);SIGNED - true - true - $(KeyFile) - - diff --git a/build/CommonAssemblyInfo.cs b/build/CommonAssemblyInfo.cs deleted file mode 100644 index c3d1f3841..000000000 --- a/build/CommonAssemblyInfo.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Reflection; - -[assembly: AssemblyCompany("Microsoft Corporation")] -[assembly: AssemblyProduct("Microsoft OWIN")] -[assembly: AssemblyCopyright("\x00a9 Microsoft Corporation All rights reserved.")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyVersion("4.2.1.0")] -[assembly: AssemblyFileVersion("4.2.101025.0")] -[assembly: AssemblyInformationalVersion("4.2.1-rtw-000")] -[assembly: AssemblyMetadata("Serviceable", "True")] diff --git a/build/CustomDictionary.xml b/build/CustomDictionary.xml deleted file mode 100644 index c89244061..000000000 --- a/build/CustomDictionary.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - Owin - Ip - Jwt - Cors - - - - - diff --git a/build/Delay.dat b/build/Delay.dat deleted file mode 100644 index 695f1b38774e839e5b90059bfb7f32df1dff4223..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 160 zcmV;R0AK$ABme*efB*oL000060ssI2Bme+XQ$aBR1ONa50098C{E+7Ye`kjtcRG*W zi8#m|)B?I?xgZ^2Sw5D;l4TxtPwG;3)3^j?qDHjEteSTF{rM+4WI`v zCD?tsZ^;k+S&r1&HRMb=j738S=;J$tCKNrc$@P|lZ - - - 4.2.1 - 4.2.1.0 - 4.2.1-rtw-000 - 4.2.101025.0 - 4 - 2 - 1 - rtw - 101025 - - https://github.com/aspnet/AspNetKatana/ - Microsoft OWIN Katana - - diff --git a/build/Sakefile.shade b/build/Sakefile.shade deleted file mode 100644 index 8af99b6df..000000000 --- a/build/Sakefile.shade +++ /dev/null @@ -1,424 +0,0 @@ - -var PROJECT='Katana' -var AUTHORS='Microsoft' -var SHIP='${Version(4, 2, 1, "rtw")}' -var DEV='${Version(0, 31, 0, "pre")}' -set FINAL_MILESTONE='${true}' -var AZUREAD_VERSION='5.3.0' -var AZUREAD_SUFFIX='' -var VERSION='${SHIP.VERSION}' -var FULL_VERSION='${SHIP.FULL_VERSION}' -var PROJECT_URL='https://github.com/aspnet/AspNetKatana/' -var TAGS='Microsoft OWIN Katana' - -var BASE_DIR='${Directory.GetCurrentDirectory()}' -var KEY_FILE='${Files.Include("*.snk").Select(x=>Path.Combine(BASE_DIR,x)).SingleOrDefault()}' -set OFFICIAL_BUILD='${!string.IsNullOrEmpty(KEY_FILE)}' - -var TARGET_DIR='${Path.Combine(BASE_DIR, "artifacts")}' -var BUILD_DIR='${Path.Combine(TARGET_DIR, "compile")}' -var TEST_DIR='${Path.Combine(TARGET_DIR, "test")}' -var SIGN_DIR='${Path.Combine(TARGET_DIR, "sign")}' -var PACKAGE_DIR='${Path.Combine(TARGET_DIR, "package")}' - -var NUGET_GALLERY_SOURCE='https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json' -var NUGET_ASPNET_SOURCE='https://pkgs.dev.azure.com/dnceng/public/_packaging/myget-legacy/nuget/v3/index.json' --// var NUGET_AZUREAD_SOURCE='https://www.myget.org/F/azureadwebstacknightly/' -var NUGET_AZUREAD_SOURCE='' - -var NUGET_DEPLOY='https://dotnet.myget.org/F/katana-dev/' - -log info='PROJECT: ${PROJECT}' if='PROJECT != ""' -log info='SHIP.FULL_VERSION: ${SHIP.FULL_VERSION}' -log info='DEV.FULL_VERSION: ${DEV.FULL_VERSION}' -log info='SHIP.FILE_VERSION: ${SHIP.FILE_VERSION}' -log info='DEV.FILE_VERSION: ${DEV.FILE_VERSION}' -log info='KEY_FILE: ${KEY_FILE}' if='KEY_FILE != ""' -log info='OFFICIAL_BUILD: ${OFFICIAL_BUILD}' - -var shipping='${new[] { - "OwinHost", - "Microsoft.Owin", - "Microsoft.Owin.Security", - "Microsoft.Owin.Security.Facebook", - "Microsoft.Owin.Security.Cookies", - "Microsoft.Owin.Security.Google", - "Microsoft.Owin.Security.OAuth", - "Microsoft.Owin.Security.Twitter", - "Microsoft.Owin.Security.MicrosoftAccount", - "Microsoft.Owin.Security.ActiveDirectory", - "Microsoft.Owin.Security.WsFederation", - "Microsoft.Owin.Security.OpenIdConnect", - "Microsoft.Owin.Security.Jwt", - "Microsoft.Owin.FileSystems", - "Microsoft.Owin.StaticFiles", - "Microsoft.Owin.Host.SystemWeb", - "Microsoft.Owin.Host.HttpListener", - "Microsoft.Owin.Hosting", - "Microsoft.Owin.Diagnostics", - "Microsoft.Owin.SelfHost", - "Microsoft.Owin.Cors", - "Microsoft.Owin.Testing", -}}' - -var metapackages='${new[] { - "Microsoft.Owin.SelfHost", -}}' - -var skip="${new string[] { - }}" - -set if='IsMono' skip='${new[]{ - "./**/*.Tests.csproj", - }}' - -var BUILD_PROJECTS='${Files.Include("src/**/*.csproj").Exclude(skip)}' -var TEST_PROJECTS='${Files.Include("tests/**/*.Tests.csproj").Include("tests/**/*.IntegrationTests.csproj").Exclude("tests/**/*.Sandbox.*.csproj").Exclude("tests/Katana.Performance.ReferenceApp.Tests/Katana.Performance.ReferenceApp.Tests.csproj")}' -var TEST_ASSEMBLIES='${Files.Include(TEST_DIR + "/**/*.Tests.dll")}' - -test if='IsMono' - set TEST_PROJECTS='${Files.Include("./**/Microsoft.Owin.Hosting.Tests.csproj")}' - --// include range of standard general targets. run "sake targets" to display -use-standard-lifecycle - --// include sets of standard work targets. features include 'nuget,xunit,nunit' -use-standard-goals features='nuget,xunit' - --// additional work targets are defined below - -#version-target target='post-clean' - log info='Emitting ./build/Katana.version.targets' - @{ - // Emit a version targets file for the official builds - string fileName = "./build/Katana.version.targets"; - File.WriteAllText(fileName, - "" + Environment.NewLine - + "" + Environment.NewLine - + " " + Environment.NewLine - + " " + SHIP.VERSION + "" + Environment.NewLine - + " " + SHIP.SN_VERSION + "" + Environment.NewLine - + " " + SHIP.FULL_VERSION + "" + Environment.NewLine - + " " + SHIP.FILE_VERSION + "" + Environment.NewLine - + " " + SHIP.MAJOR + "" + Environment.NewLine - + " " + SHIP.MINOR + "" + Environment.NewLine - + " " + SHIP.PATCH + "" + Environment.NewLine - + " " + SHIP.MILESTONE + "" + Environment.NewLine - + " " + BuildDate() + "" + Environment.NewLine - + " " + BranchSuffix() + "" + Environment.NewLine - + " " + PROJECT_URL + "" + Environment.NewLine - + " " + TAGS + "" + Environment.NewLine - + " " + Environment.NewLine - + "" + Environment.NewLine - ); - } - -#assemblyinfo-initialize target='initialize' - var assemblyVersion='${SHIP.SN_VERSION}' - var assemblyFileVersion='${SHIP.FILE_VERSION}' - var assemblyInformationalVersion='${SHIP.FULL_VERSION}' - var assemblyCopyright='\x00a9 Microsoft Corporation All rights reserved.' - assemblyinfo each='var updateFile in Files.Include("./build/CommonAssemblyInfo.cs")' - -#assemblyinfo-dev-initialize target='initialize' - var assemblyVersion='${DEV.SN_VERSION}' - var assemblyFileVersion='${DEV.FILE_VERSION}' - var assemblyInformationalVersion='${DEV.FULL_VERSION}' - var assemblyCopyright='\x00a9 Microsoft Corporation All rights reserved.' - assemblyinfo each='var updateFile in Files.Include("src/**/*AssemblyInfo.cs", "tests/**/*AssemblyInfo.cs", "./build/DevAssemblyInfo.cs")' - -#assemblyinfo-rev-initialize target='initialize' - for each='var updateFile in Files.Include("src/**/AssemblyInfo.cs", "tests/**/AssemblyInfo.cs")' - var up1='${Path.GetDirectoryName(updateFile)}' - var up2='${Path.GetDirectoryName(up1)}' - test if='Path.GetFileName(up1) == "Properties"' - test if='!string.IsNullOrEmpty(SourceRevision())' - assemblyinfo assemblyTitle='${Path.GetFileName(up2)} (${SourceRevision()})' - else - assemblyinfo assemblyTitle='${Path.GetFileName(up2)}' - -var signing='${new List()}' - -#build-compile target='compile' description='Compile primary project' - for each='var projectFile in BUILD_PROJECTS.Except(TEST_PROJECTS)' - var outputDirName='${Path.GetFileNameWithoutExtension(projectFile)}' - var outputFileName='${Path.GetFileName(Path.GetDirectoryName(projectFile))}.dll' - - var outputDir='${Path.Combine(BUILD_DIR, outputDirName)}' - - test if='KEY_FILE != ""' - build configuration='Release' extra='/t:Rebuild "/p:KeyFile=${KEY_FILE}"' - else - build configuration='Release' extra='/t:Rebuild' - - copy sourceDir='${Path.GetDirectoryName(projectFile)}' include='*.nuspec' overwrite='${true}' - - use namespace='System.Xml.Linq' - var doc='${XDocument.Load(projectFile)}' - var ns='http://schemas.microsoft.com/developer/msbuild/2003' - var itemGroups='${doc.Elements(XName.Get("Project", ns)).Elements(XName.Get("ItemGroup", ns))}' - var compileItems='${itemGroups.Elements(XName.Get("Compile", ns))}' - var contentItems='${itemGroups.Elements(XName.Get("Content", ns))}' - var noneItems='${itemGroups.Elements(XName.Get("None", ns))}' - var razorItems='${contentItems.Union(noneItems).Where(x=>x.Attribute("Include").Value.EndsWith(".cshtml"))}' - - for each='var compileElt in compileItems.Union(razorItems)' - var linkElt='${compileElt.Elements(XName.Get("Link", ns)).SingleOrDefault()}' - - var sourceFile='${compileElt.Attribute("Include").Value}' - var targetFile='${linkElt == null ? sourceFile : linkElt.Value}' - - var sourceFull='${Path.Combine(Path.GetDirectoryName(projectFile), sourceFile)}' - var targetFull='${Path.Combine(outputDir, "src", targetFile)}' - directory create='${Path.GetDirectoryName(targetFull)}' - -File.Copy(sourceFull, targetFull, true); - - -#sign-compile target='compile' description='Sign primary compiled outputs' - @{ - Func and = (a,b)=>()=>{a();b();}; - Action copySigned = ()=>{}; - } - - test if='OFFICIAL_BUILD' - directory create='${Path.Combine(SIGN_DIR, "input", "Net40")}' - directory create='${Path.Combine(SIGN_DIR, "input", "Net45")}' - directory create='${Path.Combine(SIGN_DIR, "output", "Net40")}' - directory create='${Path.Combine(SIGN_DIR, "output", "Net45")}' - for each='var assemblyFile in Files.BasePath(BUILD_DIR).Include("**/Microsoft.*.dll", "**/OwinHost.exe", "**/Katana.Boot.AspNet.dll")' - var assemblyName='${Path.GetFileNameWithoutExtension(assemblyFile)}' - var extension='${Path.GetExtension(assemblyFile)}' - var folderName='${Path.GetFileName(Path.GetDirectoryName(assemblyFile))}' - - var frameworkName='' - set frameworkName='Net45' if='folderName == assemblyName || folderName == assemblyName + ".Net45"' - set frameworkName='Net40' if='folderName == assemblyName + ".Net40"' - - test if='frameworkName != ""' - log info='Signing ${frameworkName} ${assemblyFile}' - @{ - var initialFile = Path.Combine(BUILD_DIR, assemblyFile); - var inputFile = Path.Combine(SIGN_DIR, "input", frameworkName, assemblyName + extension); - var outputFile = Path.Combine(SIGN_DIR, "output", frameworkName, assemblyName + extension); - var finalFile = Path.Combine(PACKAGE_DIR, assemblyFile); - - File.Copy(initialFile, inputFile, true); - copySigned = and(copySigned, ()=>File.Copy(outputFile, finalFile, true)); - } - build projectFile='BuildServer.targets' configuration='Release' extra='/t:SignArtifacts "/p:Sign=Sign;BranchName=Dev"' - - directory delete='${PACKAGE_DIR}' - copy sourceDir='${BUILD_DIR}' outputDir='${PACKAGE_DIR}' - -copySigned(); - - -#nuget-initialize target='initialize' - var extra='-Source ${NUGET_GALLERY_SOURCE};${NUGET_ASPNET_SOURCE};${NUGET_AZUREAD_SOURCE} -NoCache' - nuget-install each='var package in Files.Include("src/**/packages.config","tests/**/packages.config").Exclude("tests/*.Sandbox.*/*")' outputDir='packages' - -#prep-metapackages target='compile' description='Prep meta-packages' - for each='var metapackage in metapackages' - log info='Copying files for ${metapackage}' - copy sourceDir='${Path.Combine("src", metapackage)}' outputDir='${Path.Combine(PACKAGE_DIR, metapackage)}' - -#nuget-package target='package' description='Create NuGet packages' - for each='var file in Files.Include(PACKAGE_DIR + "/**/*.nuspec")' - var doc='${XDocument.Load(file)}' - var fileElts='${doc - .Elements(XName.Get("package", "http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd")) - .Elements(XName.Get("files", "http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd")) - .Elements(XName.Get("file", "http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"))}' - for each='var fileElt in fileElts' - var srcAttr='${fileElt.Attribute(XName.Get("src"))}' - -if (srcAttr == null) continue; - var segments='${srcAttr.Value.Split((char)'\\')}' - -if (segments[0] != "..") continue; - - var up1='${Path.GetDirectoryName(file)}' - var up2='${Path.GetDirectoryName(up1)}' - log info='Copy ${segments[1]}' - copy sourceDir='${Path.Combine(up2, segments[1])}' outputDir='${Path.Combine(up1, segments[1])}' include='${segments[2]}' overwrite='${true}' - -srcAttr.Value = srcAttr.Value.Substring(3); - -doc.Save(file); - - var baseName='${Path.GetFileNameWithoutExtension(file)}' - - var packageVersion='${DEV.FULL_VERSION}' - set packageVersion='${SHIP.FULL_VERSION}' if='shipping.Contains(baseName)' - - use namespace='System.Reflection' - var assemblyName='${Path.Combine(Path.GetDirectoryName(file), baseName + ".dll")}' - var title='${baseName}' - var description='${baseName}' - test if='File.Exists(assemblyName)' - @{ - var assembly = Assembly.LoadFrom(assemblyName); - description = assembly.GetCustomAttribute().Description; - if (string.IsNullOrEmpty(description)) - { - description = baseName; - } - title = assembly.GetCustomAttribute().Title; - if (string.IsNullOrEmpty(title)) - { - title = baseName; - } - } - test if='OFFICIAL_BUILD && RELEASE_BUILD' - -title = title.Split(new[]{"("}, StringSplitOptions.None)[0]; - test if='OFFICIAL_BUILD && !RELEASE_BUILD' - -title = title.Split(new[]{"("}, StringSplitOptions.None)[0] + string.Format(" (nightly {0:yyyy MMM dd})", DateTime.Now); - - var azureAdVersion='${AZUREAD_VERSION}' - var azureAdSuffix='${AZUREAD_SUFFIX}' - set azureAdSuffix='' if='OFFICIAL_BUILD && RELEASE_BUILD && FINAL_MILESTONE' - - var projectUrl='${PROJECT_URL}' - var tags='${TAGS}' - - nuget-pack nuspecFile='${file}' outputDir='${TARGET_DIR}' extra='-NoPackageAnalysis -Symbols -Properties "id=${baseName};authors=${AUTHORS};author=${AUTHORS};title=${title};description=${description};projectUrl=${projectUrl};tags=${tags};azureAdVersion=${azureAdVersion};azureAdSuffix=${azureAdSuffix}"' - -#nuget-deploy target='deploy' description='Upload NuGet packages to gallery' - var extra='' - set extra='${extra} -Source ${NUGET_DEPLOY}' if='!string.IsNullOrEmpty(NUGET_DEPLOY)' - nuget-push each='var nupkgFile in Files.Include(Path.Combine(TARGET_DIR, "*.nupkg"))' - -#download-package target='package' - var DOWNLOAD_DIR='${Path.Combine(TARGET_DIR, "download")}' - var DOWNLOAD_FILE='${Path.Combine(TARGET_DIR, "Katana." + DEV.FULL_VERSION + ".zip")}' - var includeFiles='${new[]{ - "OwinHost/Owin.dll", - "OwinHost/OwinHost.exe", - "OwinHost/OwinHost.exe.config", - "Microsoft.Owin/Microsoft.Owin.dll", - "Microsoft.Owin.Hosting/Microsoft.Owin.Hosting.dll", - "Microsoft.Owin.Host.HttpListener/Microsoft.Owin.Host.HttpListener.dll" - }}' - var includeRoot='${new[]{"LICENSE.txt", "NOTICE.txt", "DISCLAIMER.txt"}}' - var overwrite='${true}' - - copy outputDir='${DOWNLOAD_DIR}' sourceDir='.' each='var include in includeRoot' - for each='var file in includeFiles' - @{ var fileDir = Path.GetDirectoryName(file); } - @{ var fileName = Path.GetFileName(file); } - copy outputDir='${DOWNLOAD_DIR}/bin' sourceDir='${PACKAGE_DIR}/${fileDir}' include='${fileName}' - - log info='Compressing ${DOWNLOAD_DIR}' - test if='File.Exists(DOWNLOAD_FILE)' -File.Delete(DOWNLOAD_FILE); - use assembly='System.IO.Compression.FileSystem, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL' - use namespace='System.IO.Compression' - -ZipFile.CreateFromDirectory(DOWNLOAD_DIR, DOWNLOAD_FILE); - - -#xunit-integration-test target="integration-test" description='Run xunit tests' - var INTEGRATIONTEST_ASSEMBLIES='${Files.Include(Path.Combine(TEST_DIR, "**/*.IntegrationTests.dll"))}' - xunit each='var testFile in INTEGRATIONTEST_ASSEMBLIES' - -#release - @{ - // To publish, call `build release deploy` - RELEASE_BUILD = true; - NUGET_DEPLOY = ''; - VERSION = SHIP.VERSION; - FULL_VERSION = SHIP.FULL_VERSION; - } - log info='Versions updated for release' - log info='SHIP.FULL_VERSION: ${SHIP.FULL_VERSION}' - log info='DEV.FULL_VERSION: ${DEV.FULL_VERSION}' - log info='SHIP.FILE_VERSION: ${SHIP.FILE_VERSION}' - log info='DEV.FILE_VERSION: ${DEV.FILE_VERSION}' - -functions - @{ - static bool RELEASE_BUILD; - static bool OFFICIAL_BUILD; - static bool FINAL_MILESTONE; - BuildVersion Version(int major, int minor, int patch, string milestone = "") - { - return new BuildVersion - { - MAJOR = major, - MINOR = minor, - PATCH = patch, - MILESTONE = milestone, - }; - } - static string BuildDate() - { - var now = DateTime.Now; - return (now.Year - 2011) + DateTime.Now.ToString("MMdd"); - } - static string BuildNumber() - { - var buildNumber = Environment.GetEnvironmentVariable("BUILD_NUMBER"); - if (String.IsNullOrEmpty(buildNumber)) - { - return "0"; - } - return buildNumber; - } - static string BranchSuffix() - { - string branchName = Environment.GetEnvironmentVariable("BRANCH_SUFFIX"); - if (!string.IsNullOrEmpty(branchName)) - { - return branchName; - } - return ""; - } - static string SourceRevision() - { - return Environment.GetEnvironmentVariable("SourceRevision"); - } - class BuildVersion - { - public int MAJOR {get;set;} - public int MINOR {get;set;} - public int PATCH {get;set;} - public string MILESTONE {get;set;} - public string PRERELEASE - { - get - { - if (OFFICIAL_BUILD && RELEASE_BUILD && FINAL_MILESTONE) - { - return ""; - } - // -MILESTONE-BUILD_NUMBER-BUILD_SUFFIX - var pre = ""; - if (!String.IsNullOrEmpty(MILESTONE)) - { - pre = "-" + MILESTONE; - } - if (!RELEASE_BUILD) - { - var buildNumber = "000" + Environment.GetEnvironmentVariable("BUILD_NUMBER"); - buildNumber = buildNumber.Substring(buildNumber.Length - 3); - pre += "-" + buildNumber; - - if (!String.IsNullOrEmpty(BranchSuffix())) - { - pre += "-" + BranchSuffix(); - } - } - return pre; - } - } - public string VERSION - { - get {return MAJOR + "." + MINOR + "." + PATCH;} - } - public string SN_VERSION - { - get { return MAJOR + "." + MINOR + "." + PATCH + ".0"; } - } - public string FULL_VERSION - { - get {return MAJOR + "." + MINOR + "." + PATCH + PRERELEASE;} - } - public string FILE_VERSION - { - get {return MAJOR + "." + MINOR + "." + BuildDate() + "." + BuildNumber();} - } - } - } diff --git a/build/_apply-net45-changes.shade b/build/_apply-net45-changes.shade deleted file mode 100644 index 9656488fa..000000000 --- a/build/_apply-net45-changes.shade +++ /dev/null @@ -1,20 +0,0 @@ - -clone-and-tweak-file - @{ - updateText = updateText - .Replace(';NET40', ';NET45') - .Replace(@'bin\net40\', @'bin\net45\') - .Replace(@'obj\net40\', @'obj\net45\') - ; - - var guids = new[]{ - Tuple.Create("0DB69CAD-B0BC-4688-9467-66B4C1023D3F", "0DB69CAE-B0BC-4688-9467-66B4C1023D3F"), - Tuple.Create("840D1648-5884-491B-8F11-981DA286F771", "840D1649-5884-491B-8F11-981DA286F771"), - }; - foreach(var swap in guids) - { - updateText = updateText - .Replace('>{'+swap.Item1+'}{'+swap.Item2+'}{'+swap.Item1.ToLower()+'}{'+swap.Item2.ToLower()+'} AddPart = (path, mimeType) => - { - var partUri = PackUriHelper.CreatePartUri(new Uri(path, UriKind.Relative)); - var part = package.CreatePart(partUri, mimeType); - - using (var stream = new FileStream( - Path.Combine(subjectFolder, path), - FileMode.Open, - FileAccess.Read)) - { - stream.CopyTo(part.GetStream()); - } - }; - - AddPart("extension.vsixmanifest", "text/xml"); - AddPart("LICENSE.txt", "text/txt"); - foreach(var filePath in Files.BasePath(TEMPLATES_DIR + "/Katana").Include("**/*.zip")) - { - Log.Info("Adding " + filePath); - AddPart(filePath, "application/zip"); - } - - package.Close(); - } diff --git a/build/_package-vstemplate.shade b/build/_package-vstemplate.shade deleted file mode 100644 index fabf4ffda..000000000 --- a/build/_package-vstemplate.shade +++ /dev/null @@ -1,38 +0,0 @@ -use namespace='System.Linq' -use namespace='System.Xml.Linq' -use namespace='System.IO.Compression' -use assembly='System.IO.Compression.FileSystem, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL' - -log info='Processing ${subjectFile}' - -var subjectName='${Path.GetFileNameWithoutExtension(subjectFile)}' -var subjectFolder='${Path.GetDirectoryName(subjectFile)}' -var subjectZip='${Path.Combine(outputDir, subjectName + ".zip")}' - -test if='!Directory.Exists(outputDir)' -Directory.CreateDirectory(outputDir); - -var xmlns='http://schemas.microsoft.com/developer/vstemplate/2005' -var packages='${XDocument.Load(subjectFile) - .Elements(XName.Get("VSTemplate", xmlns)) - .Elements(XName.Get("WizardData", xmlns)) - .Elements(XName.Get("packages", xmlns)) - .Elements(XName.Get("package", xmlns)) -}' - -for each='var package in packages' - var nupkgName='${package.Attribute("id").Value}.${package.Attribute("version").Value}' - var fromPath1='${TARGET_DIR}/${nupkgName}.nupkg' - var fromPath2='packages/${nupkgName}/${nupkgName}.nupkg' - var toPath='${Path.Combine(subjectFolder, nupkgName + ".nupkg")}' - test if='File.Exists(fromPath1)' - log info='Moving ${fromPath1} to ${subjectFolder}' - - File.Copy(fromPath1, toPath, true); - else if='File.Exists(fromPath2)' - log info='Moving ${fromPath2} to ${subjectFolder}' - - File.Copy(fromPath2, toPath, true); - else - - throw new ApplicationException(nupkgName + " not found"); - -log info='Compressing ${subjectFolder} to ${subjectZip}' -test if='File.Exists(subjectZip)' -File.Delete(subjectZip); --ZipFile.CreateFromDirectory(subjectFolder, subjectZip); diff --git a/build/downloadnuget.ps1 b/build/downloadnuget.ps1 deleted file mode 100644 index 78ca8842e..000000000 --- a/build/downloadnuget.ps1 +++ /dev/null @@ -1,13 +0,0 @@ -Set-PSDebug -Trace 1 -[System.Net.ServicePointManager]::SecurityProtocol -[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::TLS12 -[System.Net.ServicePointManager]::SecurityProtocol -try -{ - $client = New-Object System.Net.WebClient - $client.DownloadFile('https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', '.nuget\NuGet.exe') -} -catch [System.Exception] -{ - $Error[0].Exception.ToString() -} \ No newline at end of file diff --git a/build/shared/_build.shade b/build/shared/_build.shade deleted file mode 100644 index 4f3875f93..000000000 --- a/build/shared/_build.shade +++ /dev/null @@ -1,49 +0,0 @@ -@{/* - -build - Executes msbuild or xbuild to compile your project or solution - -projectFile='' - Required. Path to the project or solution file to build. - -configuration='Release' - Determines which configuration to use when building. - -outputDir='' - Directs all compiler outputs into the target path. - -extra='' - Additional commandline parameters for msbuild or xbuild - -*/} - -default configuration='Release' -default outputDir='' -default extra='' - -use import="Environment" -use assembly="Microsoft.Build.Utilities.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" -use namespace="Microsoft.Build.Utilities" - -var buildProgram='' -@{ - var vsPath = Environment.GetEnvironmentVariable("MSBuildTools15.0_x86_Path"); - if (!string.IsNullOrEmpty(vsPath)) - { - buildProgram = Path.Combine(vsPath, "msbuild.exe"); - } - else - { - buildProgram = ToolLocationHelper.GetPathToDotNetFrameworkFile("msbuild.exe",TargetDotNetFrameworkVersion.Version40); - } -} -log info="Build" -log info=" configuration: ${configuration}" -log info=" outputDir: ${outputDir}" -log info=" extra: ${extra}" -log info=" vsPath: ${vsPath}" - -var OutDirProperty='' -set OutDirProperty='OutDir=${outputDir}${Path.DirectorySeparatorChar};' if='!string.IsNullOrWhiteSpace(outputDir)' - -exec program="${buildProgram}" commandline='${projectFile} "/p:${OutDirProperty}Configuration=${configuration}" ${extra}' \ No newline at end of file diff --git a/build/shared/_xunit.shade b/build/shared/_xunit.shade deleted file mode 100644 index 1e8622248..000000000 --- a/build/shared/_xunit.shade +++ /dev/null @@ -1,38 +0,0 @@ -@{/* - -xunit - Run unit tests in your project. Downloads and executes xunit console runner. - -testFile='' - Required. Path to the test assembly to execute - -extra='' - Additional commandline parameters for xunit - -xunitVersion='1.9.0.1566' - May be passed to override the nuget package version holding xunit console runner. - -xunitProgram='packages/xunit.runners.${xunitVersion}/tools/xunit.console.clr4.exe' - May be passed to override the path to the xunit program that will be executed - -*/} - -default xunitVersion='1.9.0.1566' -default xunitProgram='packages/xunit.runners.${xunitVersion}/tools/xunit.console.clr4.exe' -default xunitfilter='/-trait scheme=https' - -use namespace='System.IO' -var xunitDllPath1='${Path.Combine(Path.GetDirectoryName(testFile), "xunit.dll")}' -var xunitDllPath2='${Path.Combine(Path.GetDirectoryName(xunitProgram), "xunit.dll")}' - --// Download xunit from nuget sources if not already present -test if='!File.Exists(xunitProgram)' - nuget-install package='xunit.runners' packageVersion='${xunitVersion}' outputDir='packages' - --// Copy xunit.dll from test assembly location to xunit exe location (if missing) -test if='File.Exists(xunitDllPath1) && !File.Exists(xunitDllPath2)' - -File.Copy(xunitDllPath1, xunitDllPath2); - - -exec-clr program='${xunitProgram}' commandline='${testFile} ${xunitfilter}' - diff --git a/eng/Build.props b/eng/Build.props new file mode 100644 index 000000000..35ebcaa69 --- /dev/null +++ b/eng/Build.props @@ -0,0 +1,6 @@ + + + + + + diff --git a/eng/Publishing.props b/eng/Publishing.props new file mode 100644 index 000000000..9454e9071 --- /dev/null +++ b/eng/Publishing.props @@ -0,0 +1,5 @@ + + + 3 + + diff --git a/eng/Signing.props b/eng/Signing.props new file mode 100644 index 000000000..d28c58761 --- /dev/null +++ b/eng/Signing.props @@ -0,0 +1,9 @@ + + + + + + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml new file mode 100644 index 000000000..ad669b676 --- /dev/null +++ b/eng/Version.Details.xml @@ -0,0 +1,9 @@ + + + + + https://github.com/dotnet/arcade + eac1a3f1eb7404c0438664381b58d7238600aafc + + + diff --git a/eng/Versions.props b/eng/Versions.props new file mode 100644 index 000000000..774bb4fe4 --- /dev/null +++ b/eng/Versions.props @@ -0,0 +1,15 @@ + + + + 4.2.1 + preview + 1 + + false + + 1.0.0 + 1.1.1.1 + 10.0.3 + 5.3.0 + + diff --git a/eng/common/CIBuild.cmd b/eng/common/CIBuild.cmd new file mode 100644 index 000000000..56c2f25ac --- /dev/null +++ b/eng/common/CIBuild.cmd @@ -0,0 +1,2 @@ +@echo off +powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0Build.ps1""" -restore -build -test -sign -pack -publish -ci %*" \ No newline at end of file diff --git a/eng/common/PSScriptAnalyzerSettings.psd1 b/eng/common/PSScriptAnalyzerSettings.psd1 new file mode 100644 index 000000000..4c1ea7c98 --- /dev/null +++ b/eng/common/PSScriptAnalyzerSettings.psd1 @@ -0,0 +1,11 @@ +@{ + IncludeRules=@('PSAvoidUsingCmdletAliases', + 'PSAvoidUsingWMICmdlet', + 'PSAvoidUsingPositionalParameters', + 'PSAvoidUsingInvokeExpression', + 'PSUseDeclaredVarsMoreThanAssignments', + 'PSUseCmdletCorrectly', + 'PSStandardDSCFunctionsInResource', + 'PSUseIdenticalMandatoryParametersForDSC', + 'PSUseIdenticalParametersForDSC') +} \ No newline at end of file diff --git a/eng/common/README.md b/eng/common/README.md new file mode 100644 index 000000000..ff49c3715 --- /dev/null +++ b/eng/common/README.md @@ -0,0 +1,28 @@ +# Don't touch this folder + + uuuuuuuuuuuuuuuuuuuu + u" uuuuuuuuuuuuuuuuuu "u + u" u$$$$$$$$$$$$$$$$$$$$u "u + u" u$$$$$$$$$$$$$$$$$$$$$$$$u "u + u" u$$$$$$$$$$$$$$$$$$$$$$$$$$$$u "u + u" u$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$u "u + u" u$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$u "u + $ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $ + $ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $ + $ $$$" ... "$... ...$" ... "$$$ ... "$$$ $ + $ $$$u `"$$$$$$$ $$$ $$$$$ $$ $$$ $$$ $ + $ $$$$$$uu "$$$$ $$$ $$$$$ $$ """ u$$$ $ + $ $$$""$$$ $$$$ $$$u "$$$" u$$ $$$$$$$$ $ + $ $$$$....,$$$$$..$$$$$....,$$$$..$$$$$$$$ $ + $ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $ + "u "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" u" + "u "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" u" + "u "$$$$$$$$$$$$$$$$$$$$$$$$$$$$" u" + "u "$$$$$$$$$$$$$$$$$$$$$$$$" u" + "u "$$$$$$$$$$$$$$$$$$$$" u" + "u """""""""""""""""" u" + """""""""""""""""""" + +!!! Changes made in this directory are subject to being overwritten by automation !!! + +The files in this directory are shared by all Arcade repos and managed by automation. If you need to make changes to these files, open an issue or submit a pull request to https://github.com/dotnet/arcade first. diff --git a/eng/common/SetupNugetSources.ps1 b/eng/common/SetupNugetSources.ps1 new file mode 100644 index 000000000..18823840b --- /dev/null +++ b/eng/common/SetupNugetSources.ps1 @@ -0,0 +1,167 @@ +# This file is a temporary workaround for internal builds to be able to restore from private AzDO feeds. +# This file should be removed as part of this issue: https://github.com/dotnet/arcade/issues/4080 +# +# What the script does is iterate over all package sources in the pointed NuGet.config and add a credential entry +# under for each Maestro managed private feed. Two additional credential +# entries are also added for the two private static internal feeds: dotnet3-internal and dotnet3-internal-transport. +# +# This script needs to be called in every job that will restore packages and which the base repo has +# private AzDO feeds in the NuGet.config. +# +# See example YAML call for this script below. Note the use of the variable `$(dn-bot-dnceng-artifact-feeds-rw)` +# from the AzureDevOps-Artifact-Feeds-Pats variable group. +# +# Any disabledPackageSources entries which start with "darc-int" will be re-enabled as part of this script executing +# +# - task: PowerShell@2 +# displayName: Setup Private Feeds Credentials +# condition: eq(variables['Agent.OS'], 'Windows_NT') +# inputs: +# filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1 +# arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $Env:Token +# env: +# Token: $(dn-bot-dnceng-artifact-feeds-rw) + +[CmdletBinding()] +param ( + [Parameter(Mandatory = $true)][string]$ConfigFile, + [Parameter(Mandatory = $true)][string]$Password +) + +$ErrorActionPreference = "Stop" +Set-StrictMode -Version 2.0 +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + +. $PSScriptRoot\tools.ps1 + +# Add source entry to PackageSources +function AddPackageSource($sources, $SourceName, $SourceEndPoint, $creds, $Username, $Password) { + $packageSource = $sources.SelectSingleNode("add[@key='$SourceName']") + + if ($packageSource -eq $null) + { + $packageSource = $doc.CreateElement("add") + $packageSource.SetAttribute("key", $SourceName) + $packageSource.SetAttribute("value", $SourceEndPoint) + $sources.AppendChild($packageSource) | Out-Null + } + else { + Write-Host "Package source $SourceName already present." + } + + AddCredential -Creds $creds -Source $SourceName -Username $Username -Password $Password +} + +# Add a credential node for the specified source +function AddCredential($creds, $source, $username, $password) { + # Looks for credential configuration for the given SourceName. Create it if none is found. + $sourceElement = $creds.SelectSingleNode($Source) + if ($sourceElement -eq $null) + { + $sourceElement = $doc.CreateElement($Source) + $creds.AppendChild($sourceElement) | Out-Null + } + + # Add the node to the credential if none is found. + $usernameElement = $sourceElement.SelectSingleNode("add[@key='Username']") + if ($usernameElement -eq $null) + { + $usernameElement = $doc.CreateElement("add") + $usernameElement.SetAttribute("key", "Username") + $sourceElement.AppendChild($usernameElement) | Out-Null + } + $usernameElement.SetAttribute("value", $Username) + + # Add the to the credential if none is found. + # Add it as a clear text because there is no support for encrypted ones in non-windows .Net SDKs. + # -> https://github.com/NuGet/Home/issues/5526 + $passwordElement = $sourceElement.SelectSingleNode("add[@key='ClearTextPassword']") + if ($passwordElement -eq $null) + { + $passwordElement = $doc.CreateElement("add") + $passwordElement.SetAttribute("key", "ClearTextPassword") + $sourceElement.AppendChild($passwordElement) | Out-Null + } + $passwordElement.SetAttribute("value", $Password) +} + +function InsertMaestroPrivateFeedCredentials($Sources, $Creds, $Username, $Password) { + $maestroPrivateSources = $Sources.SelectNodes("add[contains(@key,'darc-int')]") + + Write-Host "Inserting credentials for $($maestroPrivateSources.Count) Maestro's private feeds." + + ForEach ($PackageSource in $maestroPrivateSources) { + Write-Host "`tInserting credential for Maestro's feed:" $PackageSource.Key + AddCredential -Creds $creds -Source $PackageSource.Key -Username $Username -Password $Password + } +} + +function EnablePrivatePackageSources($DisabledPackageSources) { + $maestroPrivateSources = $DisabledPackageSources.SelectNodes("add[contains(@key,'darc-int')]") + ForEach ($DisabledPackageSource in $maestroPrivateSources) { + Write-Host "`tEnsuring private source '$($DisabledPackageSource.key)' is enabled by deleting it from disabledPackageSource" + # Due to https://github.com/NuGet/Home/issues/10291, we must actually remove the disabled entries + $DisabledPackageSources.RemoveChild($DisabledPackageSource) + } +} + +if (!(Test-Path $ConfigFile -PathType Leaf)) { + Write-PipelineTelemetryError -Category 'Build' -Message "Eng/common/SetupNugetSources.ps1 returned a non-zero exit code. Couldn't find the NuGet config file: $ConfigFile" + ExitWithExitCode 1 +} + +if (!$Password) { + Write-PipelineTelemetryError -Category 'Build' -Message 'Eng/common/SetupNugetSources.ps1 returned a non-zero exit code. Please supply a valid PAT' + ExitWithExitCode 1 +} + +# Load NuGet.config +$doc = New-Object System.Xml.XmlDocument +$filename = (Get-Item $ConfigFile).FullName +$doc.Load($filename) + +# Get reference to or create one if none exist already +$sources = $doc.DocumentElement.SelectSingleNode("packageSources") +if ($sources -eq $null) { + $sources = $doc.CreateElement("packageSources") + $doc.DocumentElement.AppendChild($sources) | Out-Null +} + +# Looks for a node. Create it if none is found. +$creds = $doc.DocumentElement.SelectSingleNode("packageSourceCredentials") +if ($creds -eq $null) { + $creds = $doc.CreateElement("packageSourceCredentials") + $doc.DocumentElement.AppendChild($creds) | Out-Null +} + +# Check for disabledPackageSources; we'll enable any darc-int ones we find there +$disabledSources = $doc.DocumentElement.SelectSingleNode("disabledPackageSources") +if ($disabledSources -ne $null) { + Write-Host "Checking for any darc-int disabled package sources in the disabledPackageSources node" + EnablePrivatePackageSources -DisabledPackageSources $disabledSources +} + +$userName = "dn-bot" + +# Insert credential nodes for Maestro's private feeds +InsertMaestroPrivateFeedCredentials -Sources $sources -Creds $creds -Username $userName -Password $Password + +$dotnet31Source = $sources.SelectSingleNode("add[@key='dotnet3.1']") +if ($dotnet31Source -ne $null) { + AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal/nuget/v2" -Creds $creds -Username $userName -Password $Password + AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v2" -Creds $creds -Username $userName -Password $Password +} + +$dotnet5Source = $sources.SelectSingleNode("add[@key='dotnet5']") +if ($dotnet5Source -ne $null) { + AddPackageSource -Sources $sources -SourceName "dotnet5-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet5-internal/nuget/v2" -Creds $creds -Username $userName -Password $Password + AddPackageSource -Sources $sources -SourceName "dotnet5-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet5-internal-transport/nuget/v2" -Creds $creds -Username $userName -Password $Password +} + +$dotnet6Source = $sources.SelectSingleNode("add[@key='dotnet6']") +if ($dotnet6Source -ne $null) { + AddPackageSource -Sources $sources -SourceName "dotnet6-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet6-internal/nuget/v2" -Creds $creds -Username $userName -Password $Password + AddPackageSource -Sources $sources -SourceName "dotnet6-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet6-internal-transport/nuget/v2" -Creds $creds -Username $userName -Password $Password +} + +$doc.Save($filename) diff --git a/eng/common/SetupNugetSources.sh b/eng/common/SetupNugetSources.sh new file mode 100644 index 000000000..ad3fb74fd --- /dev/null +++ b/eng/common/SetupNugetSources.sh @@ -0,0 +1,191 @@ +#!/usr/bin/env bash + +# This file is a temporary workaround for internal builds to be able to restore from private AzDO feeds. +# This file should be removed as part of this issue: https://github.com/dotnet/arcade/issues/4080 +# +# What the script does is iterate over all package sources in the pointed NuGet.config and add a credential entry +# under for each Maestro's managed private feed. Two additional credential +# entries are also added for the two private static internal feeds: dotnet3-internal and dotnet3-internal-transport. +# +# This script needs to be called in every job that will restore packages and which the base repo has +# private AzDO feeds in the NuGet.config. +# +# See example YAML call for this script below. Note the use of the variable `$(dn-bot-dnceng-artifact-feeds-rw)` +# from the AzureDevOps-Artifact-Feeds-Pats variable group. +# +# Any disabledPackageSources entries which start with "darc-int" will be re-enabled as part of this script executing. +# +# - task: Bash@3 +# displayName: Setup Private Feeds Credentials +# inputs: +# filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh +# arguments: $(Build.SourcesDirectory)/NuGet.config $Token +# condition: ne(variables['Agent.OS'], 'Windows_NT') +# env: +# Token: $(dn-bot-dnceng-artifact-feeds-rw) + +ConfigFile=$1 +CredToken=$2 +NL='\n' +TB=' ' + +source="${BASH_SOURCE[0]}" + +# resolve $source until the file is no longer a symlink +while [[ -h "$source" ]]; do + scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + source="$(readlink "$source")" + # if $source was a relative symlink, we need to resolve it relative to the path where the + # symlink file was located + [[ $source != /* ]] && source="$scriptroot/$source" +done +scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + +. "$scriptroot/tools.sh" + +if [ ! -f "$ConfigFile" ]; then + Write-PipelineTelemetryError -Category 'Build' "Error: Eng/common/SetupNugetSources.sh returned a non-zero exit code. Couldn't find the NuGet config file: $ConfigFile" + ExitWithExitCode 1 +fi + +if [ -z "$CredToken" ]; then + Write-PipelineTelemetryError -category 'Build' "Error: Eng/common/SetupNugetSources.sh returned a non-zero exit code. Please supply a valid PAT" + ExitWithExitCode 1 +fi + +if [[ `uname -s` == "Darwin" ]]; then + NL=$'\\\n' + TB='' +fi + +# Ensure there is a ... section. +grep -i "" $ConfigFile +if [ "$?" != "0" ]; then + echo "Adding ... section." + ConfigNodeHeader="" + PackageSourcesTemplate="${TB}${NL}${TB}" + + sed -i.bak "s|$ConfigNodeHeader|$ConfigNodeHeader${NL}$PackageSourcesTemplate|" $ConfigFile +fi + +# Ensure there is a ... section. +grep -i "" $ConfigFile +if [ "$?" != "0" ]; then + echo "Adding ... section." + + PackageSourcesNodeFooter="" + PackageSourceCredentialsTemplate="${TB}${NL}${TB}" + + sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourcesNodeFooter${NL}$PackageSourceCredentialsTemplate|" $ConfigFile +fi + +PackageSources=() + +# Ensure dotnet3.1-internal and dotnet3.1-internal-transport are in the packageSources if the public dotnet3.1 feeds are present +grep -i "" + + sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourceTemplate${NL}$PackageSourcesNodeFooter|" $ConfigFile + fi + PackageSources+=('dotnet3.1-internal') + + grep -i "" $ConfigFile + if [ "$?" != "0" ]; then + echo "Adding dotnet3.1-internal-transport to the packageSources." + PackageSourcesNodeFooter="" + PackageSourceTemplate="${TB}" + + sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourceTemplate${NL}$PackageSourcesNodeFooter|" $ConfigFile + fi + PackageSources+=('dotnet3.1-internal-transport') +fi + +# Ensure dotnet5-internal and dotnet5-internal-transport are in the packageSources if the public dotnet5 feeds are present +grep -i "" + + sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourceTemplate${NL}$PackageSourcesNodeFooter|" $ConfigFile + fi + PackageSources+=('dotnet5-internal') + + grep -i "" $ConfigFile + if [ "$?" != "0" ]; then + echo "Adding dotnet5-internal-transport to the packageSources." + PackageSourcesNodeFooter="" + PackageSourceTemplate="${TB}" + + sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourceTemplate${NL}$PackageSourcesNodeFooter|" $ConfigFile + fi + PackageSources+=('dotnet5-internal-transport') +fi + +# Ensure dotnet6-internal and dotnet6-internal-transport are in the packageSources if the public dotnet6 feeds are present +grep -i "" + + sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourceTemplate${NL}$PackageSourcesNodeFooter|" $ConfigFile + fi + PackageSources+=('dotnet6-internal') + + grep -i "" $ConfigFile + if [ "$?" != "0" ]; then + echo "Adding dotnet6-internal-transport to the packageSources." + PackageSourcesNodeFooter="" + PackageSourceTemplate="${TB}" + + sed -i.bak "s|$PackageSourcesNodeFooter|$PackageSourceTemplate${NL}$PackageSourcesNodeFooter|" $ConfigFile + fi + PackageSources+=('dotnet6-internal-transport') +fi + +# I want things split line by line +PrevIFS=$IFS +IFS=$'\n' +PackageSources+="$IFS" +PackageSources+=$(grep -oh '"darc-int-[^"]*"' $ConfigFile | tr -d '"') +IFS=$PrevIFS + +for FeedName in ${PackageSources[@]} ; do + # Check if there is no existing credential for this FeedName + grep -i "<$FeedName>" $ConfigFile + if [ "$?" != "0" ]; then + echo "Adding credentials for $FeedName." + + PackageSourceCredentialsNodeFooter="" + NewCredential="${TB}${TB}<$FeedName>${NL}${NL}${NL}" + + sed -i.bak "s|$PackageSourceCredentialsNodeFooter|$NewCredential${NL}$PackageSourceCredentialsNodeFooter|" $ConfigFile + fi +done + +# Re-enable any entries in disabledPackageSources where the feed name contains darc-int +grep -i "" $ConfigFile +if [ "$?" == "0" ]; then + DisabledDarcIntSources=() + echo "Re-enabling any disabled \"darc-int\" package sources in $ConfigFile" + DisabledDarcIntSources+=$(grep -oh '"darc-int-[^"]*" value="true"' $ConfigFile | tr -d '"') + for DisabledSourceName in ${DisabledDarcIntSources[@]} ; do + if [[ $DisabledSourceName == darc-int* ]] + then + OldDisableValue="" + NewDisableValue="" + sed -i.bak "s|$OldDisableValue|$NewDisableValue|" $ConfigFile + echo "Neutralized disablePackageSources entry for '$DisabledSourceName'" + fi + done +fi diff --git a/eng/common/build.ps1 b/eng/common/build.ps1 new file mode 100644 index 000000000..8943da242 --- /dev/null +++ b/eng/common/build.ps1 @@ -0,0 +1,161 @@ +[CmdletBinding(PositionalBinding=$false)] +Param( + [string][Alias('c')]$configuration = "Debug", + [string]$platform = $null, + [string] $projects, + [string][Alias('v')]$verbosity = "minimal", + [string] $msbuildEngine = $null, + [bool] $warnAsError = $true, + [bool] $nodeReuse = $true, + [switch][Alias('r')]$restore, + [switch] $deployDeps, + [switch][Alias('b')]$build, + [switch] $rebuild, + [switch] $deploy, + [switch][Alias('t')]$test, + [switch] $integrationTest, + [switch] $performanceTest, + [switch] $sign, + [switch] $pack, + [switch] $publish, + [switch] $clean, + [switch][Alias('bl')]$binaryLog, + [switch][Alias('nobl')]$excludeCIBinarylog, + [switch] $ci, + [switch] $prepareMachine, + [string] $runtimeSourceFeed = '', + [string] $runtimeSourceFeedKey = '', + [switch] $excludePrereleaseVS, + [switch] $help, + [Parameter(ValueFromRemainingArguments=$true)][String[]]$properties +) + +# Unset 'Platform' environment variable to avoid unwanted collision in InstallDotNetCore.targets file +# some computer has this env var defined (e.g. Some HP) +if($env:Platform) { + $env:Platform="" +} +function Print-Usage() { + Write-Host "Common settings:" + Write-Host " -configuration Build configuration: 'Debug' or 'Release' (short: -c)" + Write-Host " -platform Platform configuration: 'x86', 'x64' or any valid Platform value to pass to msbuild" + Write-Host " -verbosity Msbuild verbosity: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic] (short: -v)" + Write-Host " -binaryLog Output binary log (short: -bl)" + Write-Host " -help Print help and exit" + Write-Host "" + + Write-Host "Actions:" + Write-Host " -restore Restore dependencies (short: -r)" + Write-Host " -build Build solution (short: -b)" + Write-Host " -rebuild Rebuild solution" + Write-Host " -deploy Deploy built VSIXes" + Write-Host " -deployDeps Deploy dependencies (e.g. VSIXes for integration tests)" + Write-Host " -test Run all unit tests in the solution (short: -t)" + Write-Host " -integrationTest Run all integration tests in the solution" + Write-Host " -performanceTest Run all performance tests in the solution" + Write-Host " -pack Package build outputs into NuGet packages and Willow components" + Write-Host " -sign Sign build outputs" + Write-Host " -publish Publish artifacts (e.g. symbols)" + Write-Host " -clean Clean the solution" + Write-Host "" + + Write-Host "Advanced settings:" + Write-Host " -projects Semi-colon delimited list of sln/proj's to build. Globbing is supported (*.sln)" + Write-Host " -ci Set when running on CI server" + Write-Host " -excludeCIBinarylog Don't output binary log (short: -nobl)" + Write-Host " -prepareMachine Prepare machine for CI run, clean up processes after build" + Write-Host " -warnAsError Sets warnaserror msbuild parameter ('true' or 'false')" + Write-Host " -msbuildEngine Msbuild engine to use to run build ('dotnet', 'vs', or unspecified)." + Write-Host " -excludePrereleaseVS Set to exclude build engines in prerelease versions of Visual Studio" + Write-Host "" + + Write-Host "Command line arguments not listed above are passed thru to msbuild." + Write-Host "The above arguments can be shortened as much as to be unambiguous (e.g. -co for configuration, -t for test, etc.)." +} + +. $PSScriptRoot\tools.ps1 + +function InitializeCustomToolset { + if (-not $restore) { + return + } + + $script = Join-Path $EngRoot 'restore-toolset.ps1' + + if (Test-Path $script) { + . $script + } +} + +function Build { + $toolsetBuildProj = InitializeToolset + InitializeCustomToolset + + $bl = if ($binaryLog) { '/bl:' + (Join-Path $LogDir 'Build.binlog') } else { '' } + $platformArg = if ($platform) { "/p:Platform=$platform" } else { '' } + + if ($projects) { + # Re-assign properties to a new variable because PowerShell doesn't let us append properties directly for unclear reasons. + # Explicitly set the type as string[] because otherwise PowerShell would make this char[] if $properties is empty. + [string[]] $msbuildArgs = $properties + + # Resolve relative project paths into full paths + $projects = ($projects.Split(';').ForEach({Resolve-Path $_}) -join ';') + + $msbuildArgs += "/p:Projects=$projects" + $properties = $msbuildArgs + } + + MSBuild $toolsetBuildProj ` + $bl ` + $platformArg ` + /p:Configuration=$configuration ` + /p:RepoRoot=$RepoRoot ` + /p:Restore=$restore ` + /p:DeployDeps=$deployDeps ` + /p:Build=$build ` + /p:Rebuild=$rebuild ` + /p:Deploy=$deploy ` + /p:Test=$test ` + /p:Pack=$pack ` + /p:IntegrationTest=$integrationTest ` + /p:PerformanceTest=$performanceTest ` + /p:Sign=$sign ` + /p:Publish=$publish ` + @properties +} + +try { + if ($clean) { + if (Test-Path $ArtifactsDir) { + Remove-Item -Recurse -Force $ArtifactsDir + Write-Host 'Artifacts directory deleted.' + } + exit 0 + } + + if ($help -or (($null -ne $properties) -and ($properties.Contains('/help') -or $properties.Contains('/?')))) { + Print-Usage + exit 0 + } + + if ($ci) { + if (-not $excludeCIBinarylog) { + $binaryLog = $true + } + $nodeReuse = $false + } + + if ($restore) { + InitializeNativeTools + } + + Build +} +catch { + Write-Host $_.ScriptStackTrace + Write-PipelineTelemetryError -Category 'InitializeToolset' -Message $_ + ExitWithExitCode 1 +} + +ExitWithExitCode 0 diff --git a/eng/common/build.sh b/eng/common/build.sh new file mode 100644 index 000000000..55b298f16 --- /dev/null +++ b/eng/common/build.sh @@ -0,0 +1,232 @@ +#!/usr/bin/env bash + +# Stop script if unbound variable found (use ${var:-} if intentional) +set -u + +# Stop script if command returns non-zero exit code. +# Prevents hidden errors caused by missing error code propagation. +set -e + +usage() +{ + echo "Common settings:" + echo " --configuration Build configuration: 'Debug' or 'Release' (short: -c)" + echo " --verbosity Msbuild verbosity: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic] (short: -v)" + echo " --binaryLog Create MSBuild binary log (short: -bl)" + echo " --help Print help and exit (short: -h)" + echo "" + + echo "Actions:" + echo " --restore Restore dependencies (short: -r)" + echo " --build Build solution (short: -b)" + echo " --rebuild Rebuild solution" + echo " --test Run all unit tests in the solution (short: -t)" + echo " --integrationTest Run all integration tests in the solution" + echo " --performanceTest Run all performance tests in the solution" + echo " --pack Package build outputs into NuGet packages and Willow components" + echo " --sign Sign build outputs" + echo " --publish Publish artifacts (e.g. symbols)" + echo " --clean Clean the solution" + echo "" + + echo "Advanced settings:" + echo " --projects Project or solution file(s) to build" + echo " --ci Set when running on CI server" + echo " --excludeCIBinarylog Don't output binary log (short: -nobl)" + echo " --prepareMachine Prepare machine for CI run, clean up processes after build" + echo " --nodeReuse Sets nodereuse msbuild parameter ('true' or 'false')" + echo " --warnAsError Sets warnaserror msbuild parameter ('true' or 'false')" + echo "" + echo "Command line arguments not listed above are passed thru to msbuild." + echo "Arguments can also be passed in with a single hyphen." +} + +source="${BASH_SOURCE[0]}" + +# resolve $source until the file is no longer a symlink +while [[ -h "$source" ]]; do + scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + source="$(readlink "$source")" + # if $source was a relative symlink, we need to resolve it relative to the path where the + # symlink file was located + [[ $source != /* ]] && source="$scriptroot/$source" +done +scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + +restore=false +build=false +rebuild=false +test=false +integration_test=false +performance_test=false +pack=false +publish=false +sign=false +public=false +ci=false +clean=false + +warn_as_error=true +node_reuse=true +binary_log=false +exclude_ci_binary_log=false +pipelines_log=false + +projects='' +configuration='Debug' +prepare_machine=false +verbosity='minimal' +runtime_source_feed='' +runtime_source_feed_key='' + +properties='' +while [[ $# > 0 ]]; do + opt="$(echo "${1/#--/-}" | tr "[:upper:]" "[:lower:]")" + case "$opt" in + -help|-h) + usage + exit 0 + ;; + -clean) + clean=true + ;; + -configuration|-c) + configuration=$2 + shift + ;; + -verbosity|-v) + verbosity=$2 + shift + ;; + -binarylog|-bl) + binary_log=true + ;; + -excludeCIBinarylog|-nobl) + exclude_ci_binary_log=true + ;; + -pipelineslog|-pl) + pipelines_log=true + ;; + -restore|-r) + restore=true + ;; + -build|-b) + build=true + ;; + -rebuild) + rebuild=true + ;; + -pack) + pack=true + ;; + -test|-t) + test=true + ;; + -integrationtest) + integration_test=true + ;; + -performancetest) + performance_test=true + ;; + -sign) + sign=true + ;; + -publish) + publish=true + ;; + -preparemachine) + prepare_machine=true + ;; + -projects) + projects=$2 + shift + ;; + -ci) + ci=true + ;; + -warnaserror) + warn_as_error=$2 + shift + ;; + -nodereuse) + node_reuse=$2 + shift + ;; + -runtimesourcefeed) + runtime_source_feed=$2 + shift + ;; + -runtimesourcefeedkey) + runtime_source_feed_key=$2 + shift + ;; + *) + properties="$properties $1" + ;; + esac + + shift +done + +if [[ "$ci" == true ]]; then + pipelines_log=true + node_reuse=false + if [[ "$exclude_ci_binary_log" == false ]]; then + binary_log=true + fi +fi + +. "$scriptroot/tools.sh" + +function InitializeCustomToolset { + local script="$eng_root/restore-toolset.sh" + + if [[ -a "$script" ]]; then + . "$script" + fi +} + +function Build { + InitializeToolset + InitializeCustomToolset + + if [[ ! -z "$projects" ]]; then + properties="$properties /p:Projects=$projects" + fi + + local bl="" + if [[ "$binary_log" == true ]]; then + bl="/bl:\"$log_dir/Build.binlog\"" + fi + + MSBuild $_InitializeToolset \ + $bl \ + /p:Configuration=$configuration \ + /p:RepoRoot="$repo_root" \ + /p:Restore=$restore \ + /p:Build=$build \ + /p:Rebuild=$rebuild \ + /p:Test=$test \ + /p:Pack=$pack \ + /p:IntegrationTest=$integration_test \ + /p:PerformanceTest=$performance_test \ + /p:Sign=$sign \ + /p:Publish=$publish \ + $properties + + ExitWithExitCode 0 +} + +if [[ "$clean" == true ]]; then + if [ -d "$artifacts_dir" ]; then + rm -rf $artifacts_dir + echo "Artifacts directory deleted." + fi + exit 0 +fi + +if [[ "$restore" == true ]]; then + InitializeNativeTools +fi + +Build diff --git a/eng/common/cibuild.sh b/eng/common/cibuild.sh new file mode 100644 index 000000000..1a02c0dec --- /dev/null +++ b/eng/common/cibuild.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +source="${BASH_SOURCE[0]}" + +# resolve $SOURCE until the file is no longer a symlink +while [[ -h $source ]]; do + scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + source="$(readlink "$source")" + + # if $source was a relative symlink, we need to resolve it relative to the path where + # the symlink file was located + [[ $source != /* ]] && source="$scriptroot/$source" +done +scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + +. "$scriptroot/build.sh" --restore --build --test --pack --publish --ci $@ \ No newline at end of file diff --git a/eng/common/cross/arm/sources.list.bionic b/eng/common/cross/arm/sources.list.bionic new file mode 100644 index 000000000..210955740 --- /dev/null +++ b/eng/common/cross/arm/sources.list.bionic @@ -0,0 +1,11 @@ +deb http://ports.ubuntu.com/ubuntu-ports/ bionic main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ bionic-updates main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-updates main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ bionic-backports main restricted +deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-backports main restricted + +deb http://ports.ubuntu.com/ubuntu-ports/ bionic-security main restricted universe multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-security main restricted universe multiverse diff --git a/eng/common/cross/arm/sources.list.jessie b/eng/common/cross/arm/sources.list.jessie new file mode 100644 index 000000000..4d142ac9b --- /dev/null +++ b/eng/common/cross/arm/sources.list.jessie @@ -0,0 +1,3 @@ +# Debian (sid) # UNSTABLE +deb http://ftp.debian.org/debian/ sid main contrib non-free +deb-src http://ftp.debian.org/debian/ sid main contrib non-free diff --git a/eng/common/cross/arm/sources.list.xenial b/eng/common/cross/arm/sources.list.xenial new file mode 100644 index 000000000..eacd86b7d --- /dev/null +++ b/eng/common/cross/arm/sources.list.xenial @@ -0,0 +1,11 @@ +deb http://ports.ubuntu.com/ubuntu-ports/ xenial main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ xenial-backports main restricted +deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-backports main restricted + +deb http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted universe multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted universe multiverse \ No newline at end of file diff --git a/eng/common/cross/arm/sources.list.zesty b/eng/common/cross/arm/sources.list.zesty new file mode 100644 index 000000000..ea2c14a78 --- /dev/null +++ b/eng/common/cross/arm/sources.list.zesty @@ -0,0 +1,11 @@ +deb http://ports.ubuntu.com/ubuntu-ports/ zesty main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ zesty-updates main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty-updates main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ zesty-backports main restricted +deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty-backports main restricted + +deb http://ports.ubuntu.com/ubuntu-ports/ zesty-security main restricted universe multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty-security main restricted universe multiverse diff --git a/eng/common/cross/arm/tizen-build-rootfs.sh b/eng/common/cross/arm/tizen-build-rootfs.sh new file mode 100644 index 000000000..9fdb32e92 --- /dev/null +++ b/eng/common/cross/arm/tizen-build-rootfs.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +set -e + +__ARM_HARDFP_CrossDir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +__TIZEN_CROSSDIR="$__ARM_HARDFP_CrossDir/tizen" + +if [[ -z "$ROOTFS_DIR" ]]; then + echo "ROOTFS_DIR is not defined." + exit 1; +fi + +TIZEN_TMP_DIR=$ROOTFS_DIR/tizen_tmp +mkdir -p $TIZEN_TMP_DIR + +# Download files +echo ">>Start downloading files" +VERBOSE=1 $__ARM_HARDFP_CrossDir/tizen-fetch.sh $TIZEN_TMP_DIR +echo "<>Start constructing Tizen rootfs" +TIZEN_RPM_FILES=`ls $TIZEN_TMP_DIR/*.rpm` +cd $ROOTFS_DIR +for f in $TIZEN_RPM_FILES; do + rpm2cpio $f | cpio -idm --quiet +done +echo "<>Start configuring Tizen rootfs" +ln -sfn asm-arm ./usr/include/asm +patch -p1 < $__TIZEN_CROSSDIR/tizen.patch +echo "</dev/null; then + VERBOSE=0 +fi + +Log() +{ + if [ $VERBOSE -ge $1 ]; then + echo ${@:2} + fi +} + +Inform() +{ + Log 1 -e "\x1B[0;34m$@\x1B[m" +} + +Debug() +{ + Log 2 -e "\x1B[0;32m$@\x1B[m" +} + +Error() +{ + >&2 Log 0 -e "\x1B[0;31m$@\x1B[m" +} + +Fetch() +{ + URL=$1 + FILE=$2 + PROGRESS=$3 + if [ $VERBOSE -ge 1 ] && [ $PROGRESS ]; then + CURL_OPT="--progress-bar" + else + CURL_OPT="--silent" + fi + curl $CURL_OPT $URL > $FILE +} + +hash curl 2> /dev/null || { Error "Require 'curl' Aborting."; exit 1; } +hash xmllint 2> /dev/null || { Error "Require 'xmllint' Aborting."; exit 1; } +hash sha256sum 2> /dev/null || { Error "Require 'sha256sum' Aborting."; exit 1; } + +TMPDIR=$1 +if [ ! -d $TMPDIR ]; then + TMPDIR=./tizen_tmp + Debug "Create temporary directory : $TMPDIR" + mkdir -p $TMPDIR +fi + +TIZEN_URL=http://download.tizen.org/snapshots/tizen +BUILD_XML=build.xml +REPOMD_XML=repomd.xml +PRIMARY_XML=primary.xml +TARGET_URL="http://__not_initialized" + +Xpath_get() +{ + XPATH_RESULT='' + XPATH=$1 + XML_FILE=$2 + RESULT=$(xmllint --xpath $XPATH $XML_FILE) + if [[ -z ${RESULT// } ]]; then + Error "Can not find target from $XML_FILE" + Debug "Xpath = $XPATH" + exit 1 + fi + XPATH_RESULT=$RESULT +} + +fetch_tizen_pkgs_init() +{ + TARGET=$1 + PROFILE=$2 + Debug "Initialize TARGET=$TARGET, PROFILE=$PROFILE" + + TMP_PKG_DIR=$TMPDIR/tizen_${PROFILE}_pkgs + if [ -d $TMP_PKG_DIR ]; then rm -rf $TMP_PKG_DIR; fi + mkdir -p $TMP_PKG_DIR + + PKG_URL=$TIZEN_URL/$PROFILE/latest + + BUILD_XML_URL=$PKG_URL/$BUILD_XML + TMP_BUILD=$TMP_PKG_DIR/$BUILD_XML + TMP_REPOMD=$TMP_PKG_DIR/$REPOMD_XML + TMP_PRIMARY=$TMP_PKG_DIR/$PRIMARY_XML + TMP_PRIMARYGZ=${TMP_PRIMARY}.gz + + Fetch $BUILD_XML_URL $TMP_BUILD + + Debug "fetch $BUILD_XML_URL to $TMP_BUILD" + + TARGET_XPATH="//build/buildtargets/buildtarget[@name=\"$TARGET\"]/repo[@type=\"binary\"]/text()" + Xpath_get $TARGET_XPATH $TMP_BUILD + TARGET_PATH=$XPATH_RESULT + TARGET_URL=$PKG_URL/$TARGET_PATH + + REPOMD_URL=$TARGET_URL/repodata/repomd.xml + PRIMARY_XPATH='string(//*[local-name()="data"][@type="primary"]/*[local-name()="location"]/@href)' + + Fetch $REPOMD_URL $TMP_REPOMD + + Debug "fetch $REPOMD_URL to $TMP_REPOMD" + + Xpath_get $PRIMARY_XPATH $TMP_REPOMD + PRIMARY_XML_PATH=$XPATH_RESULT + PRIMARY_URL=$TARGET_URL/$PRIMARY_XML_PATH + + Fetch $PRIMARY_URL $TMP_PRIMARYGZ + + Debug "fetch $PRIMARY_URL to $TMP_PRIMARYGZ" + + gunzip $TMP_PRIMARYGZ + + Debug "unzip $TMP_PRIMARYGZ to $TMP_PRIMARY" +} + +fetch_tizen_pkgs() +{ + ARCH=$1 + PACKAGE_XPATH_TPL='string(//*[local-name()="metadata"]/*[local-name()="package"][*[local-name()="name"][text()="_PKG_"]][*[local-name()="arch"][text()="_ARCH_"]]/*[local-name()="location"]/@href)' + + PACKAGE_CHECKSUM_XPATH_TPL='string(//*[local-name()="metadata"]/*[local-name()="package"][*[local-name()="name"][text()="_PKG_"]][*[local-name()="arch"][text()="_ARCH_"]]/*[local-name()="checksum"]/text())' + + for pkg in ${@:2} + do + Inform "Fetching... $pkg" + XPATH=${PACKAGE_XPATH_TPL/_PKG_/$pkg} + XPATH=${XPATH/_ARCH_/$ARCH} + Xpath_get $XPATH $TMP_PRIMARY + PKG_PATH=$XPATH_RESULT + + XPATH=${PACKAGE_CHECKSUM_XPATH_TPL/_PKG_/$pkg} + XPATH=${XPATH/_ARCH_/$ARCH} + Xpath_get $XPATH $TMP_PRIMARY + CHECKSUM=$XPATH_RESULT + + PKG_URL=$TARGET_URL/$PKG_PATH + PKG_FILE=$(basename $PKG_PATH) + PKG_PATH=$TMPDIR/$PKG_FILE + + Debug "Download $PKG_URL to $PKG_PATH" + Fetch $PKG_URL $PKG_PATH true + + echo "$CHECKSUM $PKG_PATH" | sha256sum -c - > /dev/null + if [ $? -ne 0 ]; then + Error "Fail to fetch $PKG_URL to $PKG_PATH" + Debug "Checksum = $CHECKSUM" + exit 1 + fi + done +} + +Inform "Initialize arm base" +fetch_tizen_pkgs_init standard base +Inform "fetch common packages" +fetch_tizen_pkgs armv7hl gcc gcc-devel-static glibc glibc-devel libicu libicu-devel libatomic linux-glibc-devel keyutils keyutils-devel libkeyutils +Inform "fetch coreclr packages" +fetch_tizen_pkgs armv7hl lldb lldb-devel libgcc libstdc++ libstdc++-devel libunwind libunwind-devel lttng-ust-devel lttng-ust userspace-rcu-devel userspace-rcu +Inform "fetch corefx packages" +fetch_tizen_pkgs armv7hl libcom_err libcom_err-devel zlib zlib-devel libopenssl11 libopenssl1.1-devel krb5 krb5-devel + +Inform "Initialize standard unified" +fetch_tizen_pkgs_init standard unified +Inform "fetch corefx packages" +fetch_tizen_pkgs armv7hl gssdp gssdp-devel tizen-release + diff --git a/eng/common/cross/arm/tizen/tizen.patch b/eng/common/cross/arm/tizen/tizen.patch new file mode 100644 index 000000000..fb12ade72 --- /dev/null +++ b/eng/common/cross/arm/tizen/tizen.patch @@ -0,0 +1,9 @@ +diff -u -r a/usr/lib/libc.so b/usr/lib/libc.so +--- a/usr/lib/libc.so 2016-12-30 23:00:08.284951863 +0900 ++++ b/usr/lib/libc.so 2016-12-30 23:00:32.140951815 +0900 +@@ -2,4 +2,4 @@ + Use the shared library, but some functions are only in + the static library, so try that secondarily. */ + OUTPUT_FORMAT(elf32-littlearm) +-GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a AS_NEEDED ( /lib/ld-linux-armhf.so.3 ) ) ++GROUP ( libc.so.6 libc_nonshared.a AS_NEEDED ( ld-linux-armhf.so.3 ) ) diff --git a/eng/common/cross/arm64/sources.list.bionic b/eng/common/cross/arm64/sources.list.bionic new file mode 100644 index 000000000..210955740 --- /dev/null +++ b/eng/common/cross/arm64/sources.list.bionic @@ -0,0 +1,11 @@ +deb http://ports.ubuntu.com/ubuntu-ports/ bionic main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ bionic-updates main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-updates main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ bionic-backports main restricted +deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-backports main restricted + +deb http://ports.ubuntu.com/ubuntu-ports/ bionic-security main restricted universe multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-security main restricted universe multiverse diff --git a/eng/common/cross/arm64/sources.list.buster b/eng/common/cross/arm64/sources.list.buster new file mode 100644 index 000000000..7194ac64a --- /dev/null +++ b/eng/common/cross/arm64/sources.list.buster @@ -0,0 +1,11 @@ +deb http://deb.debian.org/debian buster main +deb-src http://deb.debian.org/debian buster main + +deb http://deb.debian.org/debian-security/ buster/updates main +deb-src http://deb.debian.org/debian-security/ buster/updates main + +deb http://deb.debian.org/debian buster-updates main +deb-src http://deb.debian.org/debian buster-updates main + +deb http://deb.debian.org/debian buster-backports main contrib non-free +deb-src http://deb.debian.org/debian buster-backports main contrib non-free diff --git a/eng/common/cross/arm64/sources.list.stretch b/eng/common/cross/arm64/sources.list.stretch new file mode 100644 index 000000000..0e1215774 --- /dev/null +++ b/eng/common/cross/arm64/sources.list.stretch @@ -0,0 +1,12 @@ +deb http://deb.debian.org/debian stretch main +deb-src http://deb.debian.org/debian stretch main + +deb http://deb.debian.org/debian-security/ stretch/updates main +deb-src http://deb.debian.org/debian-security/ stretch/updates main + +deb http://deb.debian.org/debian stretch-updates main +deb-src http://deb.debian.org/debian stretch-updates main + +deb http://deb.debian.org/debian stretch-backports main contrib non-free +deb-src http://deb.debian.org/debian stretch-backports main contrib non-free + diff --git a/eng/common/cross/arm64/sources.list.xenial b/eng/common/cross/arm64/sources.list.xenial new file mode 100644 index 000000000..eacd86b7d --- /dev/null +++ b/eng/common/cross/arm64/sources.list.xenial @@ -0,0 +1,11 @@ +deb http://ports.ubuntu.com/ubuntu-ports/ xenial main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ xenial-backports main restricted +deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-backports main restricted + +deb http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted universe multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted universe multiverse \ No newline at end of file diff --git a/eng/common/cross/arm64/sources.list.zesty b/eng/common/cross/arm64/sources.list.zesty new file mode 100644 index 000000000..ea2c14a78 --- /dev/null +++ b/eng/common/cross/arm64/sources.list.zesty @@ -0,0 +1,11 @@ +deb http://ports.ubuntu.com/ubuntu-ports/ zesty main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ zesty-updates main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty-updates main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ zesty-backports main restricted +deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty-backports main restricted + +deb http://ports.ubuntu.com/ubuntu-ports/ zesty-security main restricted universe multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ zesty-security main restricted universe multiverse diff --git a/eng/common/cross/arm64/tizen-build-rootfs.sh b/eng/common/cross/arm64/tizen-build-rootfs.sh new file mode 100644 index 000000000..13bfddb5e --- /dev/null +++ b/eng/common/cross/arm64/tizen-build-rootfs.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +set -e + +__CrossDir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +__TIZEN_CROSSDIR="$__CrossDir/tizen" + +if [[ -z "$ROOTFS_DIR" ]]; then + echo "ROOTFS_DIR is not defined." + exit 1; +fi + +TIZEN_TMP_DIR=$ROOTFS_DIR/tizen_tmp +mkdir -p $TIZEN_TMP_DIR + +# Download files +echo ">>Start downloading files" +VERBOSE=1 $__CrossDir/tizen-fetch.sh $TIZEN_TMP_DIR +echo "<>Start constructing Tizen rootfs" +TIZEN_RPM_FILES=`ls $TIZEN_TMP_DIR/*.rpm` +cd $ROOTFS_DIR +for f in $TIZEN_RPM_FILES; do + rpm2cpio $f | cpio -idm --quiet +done +echo "<>Start configuring Tizen rootfs" +ln -sfn asm-arm64 ./usr/include/asm +patch -p1 < $__TIZEN_CROSSDIR/tizen.patch +echo "</dev/null; then + VERBOSE=0 +fi + +Log() +{ + if [ $VERBOSE -ge $1 ]; then + echo ${@:2} + fi +} + +Inform() +{ + Log 1 -e "\x1B[0;34m$@\x1B[m" +} + +Debug() +{ + Log 2 -e "\x1B[0;32m$@\x1B[m" +} + +Error() +{ + >&2 Log 0 -e "\x1B[0;31m$@\x1B[m" +} + +Fetch() +{ + URL=$1 + FILE=$2 + PROGRESS=$3 + if [ $VERBOSE -ge 1 ] && [ $PROGRESS ]; then + CURL_OPT="--progress-bar" + else + CURL_OPT="--silent" + fi + curl $CURL_OPT $URL > $FILE +} + +hash curl 2> /dev/null || { Error "Require 'curl' Aborting."; exit 1; } +hash xmllint 2> /dev/null || { Error "Require 'xmllint' Aborting."; exit 1; } +hash sha256sum 2> /dev/null || { Error "Require 'sha256sum' Aborting."; exit 1; } + +TMPDIR=$1 +if [ ! -d $TMPDIR ]; then + TMPDIR=./tizen_tmp + Debug "Create temporary directory : $TMPDIR" + mkdir -p $TMPDIR +fi + +TIZEN_URL=http://download.tizen.org/snapshots/tizen/ +BUILD_XML=build.xml +REPOMD_XML=repomd.xml +PRIMARY_XML=primary.xml +TARGET_URL="http://__not_initialized" + +Xpath_get() +{ + XPATH_RESULT='' + XPATH=$1 + XML_FILE=$2 + RESULT=$(xmllint --xpath $XPATH $XML_FILE) + if [[ -z ${RESULT// } ]]; then + Error "Can not find target from $XML_FILE" + Debug "Xpath = $XPATH" + exit 1 + fi + XPATH_RESULT=$RESULT +} + +fetch_tizen_pkgs_init() +{ + TARGET=$1 + PROFILE=$2 + Debug "Initialize TARGET=$TARGET, PROFILE=$PROFILE" + + TMP_PKG_DIR=$TMPDIR/tizen_${PROFILE}_pkgs + if [ -d $TMP_PKG_DIR ]; then rm -rf $TMP_PKG_DIR; fi + mkdir -p $TMP_PKG_DIR + + PKG_URL=$TIZEN_URL/$PROFILE/latest + + BUILD_XML_URL=$PKG_URL/$BUILD_XML + TMP_BUILD=$TMP_PKG_DIR/$BUILD_XML + TMP_REPOMD=$TMP_PKG_DIR/$REPOMD_XML + TMP_PRIMARY=$TMP_PKG_DIR/$PRIMARY_XML + TMP_PRIMARYGZ=${TMP_PRIMARY}.gz + + Fetch $BUILD_XML_URL $TMP_BUILD + + Debug "fetch $BUILD_XML_URL to $TMP_BUILD" + + TARGET_XPATH="//build/buildtargets/buildtarget[@name=\"$TARGET\"]/repo[@type=\"binary\"]/text()" + Xpath_get $TARGET_XPATH $TMP_BUILD + TARGET_PATH=$XPATH_RESULT + TARGET_URL=$PKG_URL/$TARGET_PATH + + REPOMD_URL=$TARGET_URL/repodata/repomd.xml + PRIMARY_XPATH='string(//*[local-name()="data"][@type="primary"]/*[local-name()="location"]/@href)' + + Fetch $REPOMD_URL $TMP_REPOMD + + Debug "fetch $REPOMD_URL to $TMP_REPOMD" + + Xpath_get $PRIMARY_XPATH $TMP_REPOMD + PRIMARY_XML_PATH=$XPATH_RESULT + PRIMARY_URL=$TARGET_URL/$PRIMARY_XML_PATH + + Fetch $PRIMARY_URL $TMP_PRIMARYGZ + + Debug "fetch $PRIMARY_URL to $TMP_PRIMARYGZ" + + gunzip $TMP_PRIMARYGZ + + Debug "unzip $TMP_PRIMARYGZ to $TMP_PRIMARY" +} + +fetch_tizen_pkgs() +{ + ARCH=$1 + PACKAGE_XPATH_TPL='string(//*[local-name()="metadata"]/*[local-name()="package"][*[local-name()="name"][text()="_PKG_"]][*[local-name()="arch"][text()="_ARCH_"]]/*[local-name()="location"]/@href)' + + PACKAGE_CHECKSUM_XPATH_TPL='string(//*[local-name()="metadata"]/*[local-name()="package"][*[local-name()="name"][text()="_PKG_"]][*[local-name()="arch"][text()="_ARCH_"]]/*[local-name()="checksum"]/text())' + + for pkg in ${@:2} + do + Inform "Fetching... $pkg" + XPATH=${PACKAGE_XPATH_TPL/_PKG_/$pkg} + XPATH=${XPATH/_ARCH_/$ARCH} + Xpath_get $XPATH $TMP_PRIMARY + PKG_PATH=$XPATH_RESULT + + XPATH=${PACKAGE_CHECKSUM_XPATH_TPL/_PKG_/$pkg} + XPATH=${XPATH/_ARCH_/$ARCH} + Xpath_get $XPATH $TMP_PRIMARY + CHECKSUM=$XPATH_RESULT + + PKG_URL=$TARGET_URL/$PKG_PATH + PKG_FILE=$(basename $PKG_PATH) + PKG_PATH=$TMPDIR/$PKG_FILE + + Debug "Download $PKG_URL to $PKG_PATH" + Fetch $PKG_URL $PKG_PATH true + + echo "$CHECKSUM $PKG_PATH" | sha256sum -c - > /dev/null + if [ $? -ne 0 ]; then + Error "Fail to fetch $PKG_URL to $PKG_PATH" + Debug "Checksum = $CHECKSUM" + exit 1 + fi + done +} + +Inform "Initialize arm base" +fetch_tizen_pkgs_init standard base +Inform "fetch common packages" +fetch_tizen_pkgs aarch64 gcc glibc glibc-devel libicu libicu-devel libatomic linux-glibc-devel keyutils keyutils-devel libkeyutils +Inform "fetch coreclr packages" +fetch_tizen_pkgs aarch64 lldb lldb-devel libgcc libstdc++ libstdc++-devel libunwind libunwind-devel lttng-ust-devel lttng-ust userspace-rcu-devel userspace-rcu +Inform "fetch corefx packages" +fetch_tizen_pkgs aarch64 libcom_err libcom_err-devel zlib zlib-devel libopenssl11 libopenssl1.1-devel krb5 krb5-devel + +Inform "Initialize standard unified" +fetch_tizen_pkgs_init standard unified +Inform "fetch corefx packages" +fetch_tizen_pkgs aarch64 gssdp gssdp-devel tizen-release + diff --git a/eng/common/cross/arm64/tizen/tizen.patch b/eng/common/cross/arm64/tizen/tizen.patch new file mode 100644 index 000000000..af7c8be05 --- /dev/null +++ b/eng/common/cross/arm64/tizen/tizen.patch @@ -0,0 +1,9 @@ +diff -u -r a/usr/lib/libc.so b/usr/lib/libc.so +--- a/usr/lib64/libc.so 2016-12-30 23:00:08.284951863 +0900 ++++ b/usr/lib64/libc.so 2016-12-30 23:00:32.140951815 +0900 +@@ -2,4 +2,4 @@ + Use the shared library, but some functions are only in + the static library, so try that secondarily. */ + OUTPUT_FORMAT(elf64-littleaarch64) +-GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a AS_NEEDED ( /lib/ld-linux-aarch64.so.1 ) ) ++GROUP ( libc.so.6 libc_nonshared.a AS_NEEDED ( ld-linux-aarch64.so.1 ) ) diff --git a/eng/common/cross/armel/armel.jessie.patch b/eng/common/cross/armel/armel.jessie.patch new file mode 100644 index 000000000..2d2615619 --- /dev/null +++ b/eng/common/cross/armel/armel.jessie.patch @@ -0,0 +1,43 @@ +diff -u -r a/usr/include/urcu/uatomic/generic.h b/usr/include/urcu/uatomic/generic.h +--- a/usr/include/urcu/uatomic/generic.h 2014-10-22 15:00:58.000000000 -0700 ++++ b/usr/include/urcu/uatomic/generic.h 2020-10-30 21:38:28.550000000 -0700 +@@ -69,10 +69,10 @@ + #endif + #ifdef UATOMIC_HAS_ATOMIC_SHORT + case 2: +- return __sync_val_compare_and_swap_2(addr, old, _new); ++ return __sync_val_compare_and_swap_2((uint16_t*) addr, old, _new); + #endif + case 4: +- return __sync_val_compare_and_swap_4(addr, old, _new); ++ return __sync_val_compare_and_swap_4((uint32_t*) addr, old, _new); + #if (CAA_BITS_PER_LONG == 64) + case 8: + return __sync_val_compare_and_swap_8(addr, old, _new); +@@ -109,7 +109,7 @@ + return; + #endif + case 4: +- __sync_and_and_fetch_4(addr, val); ++ __sync_and_and_fetch_4((uint32_t*) addr, val); + return; + #if (CAA_BITS_PER_LONG == 64) + case 8: +@@ -148,7 +148,7 @@ + return; + #endif + case 4: +- __sync_or_and_fetch_4(addr, val); ++ __sync_or_and_fetch_4((uint32_t*) addr, val); + return; + #if (CAA_BITS_PER_LONG == 64) + case 8: +@@ -187,7 +187,7 @@ + return __sync_add_and_fetch_2(addr, val); + #endif + case 4: +- return __sync_add_and_fetch_4(addr, val); ++ return __sync_add_and_fetch_4((uint32_t*) addr, val); + #if (CAA_BITS_PER_LONG == 64) + case 8: + return __sync_add_and_fetch_8(addr, val); diff --git a/eng/common/cross/armel/sources.list.jessie b/eng/common/cross/armel/sources.list.jessie new file mode 100644 index 000000000..3d9c3059d --- /dev/null +++ b/eng/common/cross/armel/sources.list.jessie @@ -0,0 +1,3 @@ +# Debian (jessie) # Stable +deb http://ftp.debian.org/debian/ jessie main contrib non-free +deb-src http://ftp.debian.org/debian/ jessie main contrib non-free diff --git a/eng/common/cross/armel/tizen-build-rootfs.sh b/eng/common/cross/armel/tizen-build-rootfs.sh new file mode 100644 index 000000000..9a4438af6 --- /dev/null +++ b/eng/common/cross/armel/tizen-build-rootfs.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +set -e + +__ARM_SOFTFP_CrossDir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +__TIZEN_CROSSDIR="$__ARM_SOFTFP_CrossDir/tizen" + +if [[ -z "$ROOTFS_DIR" ]]; then + echo "ROOTFS_DIR is not defined." + exit 1; +fi + +TIZEN_TMP_DIR=$ROOTFS_DIR/tizen_tmp +mkdir -p $TIZEN_TMP_DIR + +# Download files +echo ">>Start downloading files" +VERBOSE=1 $__ARM_SOFTFP_CrossDir/tizen-fetch.sh $TIZEN_TMP_DIR +echo "<>Start constructing Tizen rootfs" +TIZEN_RPM_FILES=`ls $TIZEN_TMP_DIR/*.rpm` +cd $ROOTFS_DIR +for f in $TIZEN_RPM_FILES; do + rpm2cpio $f | cpio -idm --quiet +done +echo "<>Start configuring Tizen rootfs" +ln -sfn asm-arm ./usr/include/asm +patch -p1 < $__TIZEN_CROSSDIR/tizen.patch +echo "</dev/null; then + VERBOSE=0 +fi + +Log() +{ + if [ $VERBOSE -ge $1 ]; then + echo ${@:2} + fi +} + +Inform() +{ + Log 1 -e "\x1B[0;34m$@\x1B[m" +} + +Debug() +{ + Log 2 -e "\x1B[0;32m$@\x1B[m" +} + +Error() +{ + >&2 Log 0 -e "\x1B[0;31m$@\x1B[m" +} + +Fetch() +{ + URL=$1 + FILE=$2 + PROGRESS=$3 + if [ $VERBOSE -ge 1 ] && [ $PROGRESS ]; then + CURL_OPT="--progress-bar" + else + CURL_OPT="--silent" + fi + curl $CURL_OPT $URL > $FILE +} + +hash curl 2> /dev/null || { Error "Require 'curl' Aborting."; exit 1; } +hash xmllint 2> /dev/null || { Error "Require 'xmllint' Aborting."; exit 1; } +hash sha256sum 2> /dev/null || { Error "Require 'sha256sum' Aborting."; exit 1; } + +TMPDIR=$1 +if [ ! -d $TMPDIR ]; then + TMPDIR=./tizen_tmp + Debug "Create temporary directory : $TMPDIR" + mkdir -p $TMPDIR +fi + +TIZEN_URL=http://download.tizen.org/snapshots/tizen +BUILD_XML=build.xml +REPOMD_XML=repomd.xml +PRIMARY_XML=primary.xml +TARGET_URL="http://__not_initialized" + +Xpath_get() +{ + XPATH_RESULT='' + XPATH=$1 + XML_FILE=$2 + RESULT=$(xmllint --xpath $XPATH $XML_FILE) + if [[ -z ${RESULT// } ]]; then + Error "Can not find target from $XML_FILE" + Debug "Xpath = $XPATH" + exit 1 + fi + XPATH_RESULT=$RESULT +} + +fetch_tizen_pkgs_init() +{ + TARGET=$1 + PROFILE=$2 + Debug "Initialize TARGET=$TARGET, PROFILE=$PROFILE" + + TMP_PKG_DIR=$TMPDIR/tizen_${PROFILE}_pkgs + if [ -d $TMP_PKG_DIR ]; then rm -rf $TMP_PKG_DIR; fi + mkdir -p $TMP_PKG_DIR + + PKG_URL=$TIZEN_URL/$PROFILE/latest + + BUILD_XML_URL=$PKG_URL/$BUILD_XML + TMP_BUILD=$TMP_PKG_DIR/$BUILD_XML + TMP_REPOMD=$TMP_PKG_DIR/$REPOMD_XML + TMP_PRIMARY=$TMP_PKG_DIR/$PRIMARY_XML + TMP_PRIMARYGZ=${TMP_PRIMARY}.gz + + Fetch $BUILD_XML_URL $TMP_BUILD + + Debug "fetch $BUILD_XML_URL to $TMP_BUILD" + + TARGET_XPATH="//build/buildtargets/buildtarget[@name=\"$TARGET\"]/repo[@type=\"binary\"]/text()" + Xpath_get $TARGET_XPATH $TMP_BUILD + TARGET_PATH=$XPATH_RESULT + TARGET_URL=$PKG_URL/$TARGET_PATH + + REPOMD_URL=$TARGET_URL/repodata/repomd.xml + PRIMARY_XPATH='string(//*[local-name()="data"][@type="primary"]/*[local-name()="location"]/@href)' + + Fetch $REPOMD_URL $TMP_REPOMD + + Debug "fetch $REPOMD_URL to $TMP_REPOMD" + + Xpath_get $PRIMARY_XPATH $TMP_REPOMD + PRIMARY_XML_PATH=$XPATH_RESULT + PRIMARY_URL=$TARGET_URL/$PRIMARY_XML_PATH + + Fetch $PRIMARY_URL $TMP_PRIMARYGZ + + Debug "fetch $PRIMARY_URL to $TMP_PRIMARYGZ" + + gunzip $TMP_PRIMARYGZ + + Debug "unzip $TMP_PRIMARYGZ to $TMP_PRIMARY" +} + +fetch_tizen_pkgs() +{ + ARCH=$1 + PACKAGE_XPATH_TPL='string(//*[local-name()="metadata"]/*[local-name()="package"][*[local-name()="name"][text()="_PKG_"]][*[local-name()="arch"][text()="_ARCH_"]]/*[local-name()="location"]/@href)' + + PACKAGE_CHECKSUM_XPATH_TPL='string(//*[local-name()="metadata"]/*[local-name()="package"][*[local-name()="name"][text()="_PKG_"]][*[local-name()="arch"][text()="_ARCH_"]]/*[local-name()="checksum"]/text())' + + for pkg in ${@:2} + do + Inform "Fetching... $pkg" + XPATH=${PACKAGE_XPATH_TPL/_PKG_/$pkg} + XPATH=${XPATH/_ARCH_/$ARCH} + Xpath_get $XPATH $TMP_PRIMARY + PKG_PATH=$XPATH_RESULT + + XPATH=${PACKAGE_CHECKSUM_XPATH_TPL/_PKG_/$pkg} + XPATH=${XPATH/_ARCH_/$ARCH} + Xpath_get $XPATH $TMP_PRIMARY + CHECKSUM=$XPATH_RESULT + + PKG_URL=$TARGET_URL/$PKG_PATH + PKG_FILE=$(basename $PKG_PATH) + PKG_PATH=$TMPDIR/$PKG_FILE + + Debug "Download $PKG_URL to $PKG_PATH" + Fetch $PKG_URL $PKG_PATH true + + echo "$CHECKSUM $PKG_PATH" | sha256sum -c - > /dev/null + if [ $? -ne 0 ]; then + Error "Fail to fetch $PKG_URL to $PKG_PATH" + Debug "Checksum = $CHECKSUM" + exit 1 + fi + done +} + +Inform "Initialize arm base" +fetch_tizen_pkgs_init standard base +Inform "fetch common packages" +fetch_tizen_pkgs armv7l gcc gcc-devel-static glibc glibc-devel libicu libicu-devel libatomic linux-glibc-devel keyutils keyutils-devel libkeyutils +Inform "fetch coreclr packages" +fetch_tizen_pkgs armv7l lldb lldb-devel libgcc libstdc++ libstdc++-devel libunwind libunwind-devel lttng-ust-devel lttng-ust userspace-rcu-devel userspace-rcu +Inform "fetch corefx packages" +fetch_tizen_pkgs armv7l libcom_err libcom_err-devel zlib zlib-devel libopenssl11 libopenssl1.1-devel krb5 krb5-devel + +Inform "Initialize standard unified" +fetch_tizen_pkgs_init standard unified +Inform "fetch corefx packages" +fetch_tizen_pkgs armv7l gssdp gssdp-devel tizen-release + diff --git a/eng/common/cross/armel/tizen/tizen-dotnet.ks b/eng/common/cross/armel/tizen/tizen-dotnet.ks new file mode 100644 index 000000000..506d455bd --- /dev/null +++ b/eng/common/cross/armel/tizen/tizen-dotnet.ks @@ -0,0 +1,50 @@ +lang en_US.UTF-8 +keyboard us +timezone --utc Asia/Seoul + +part / --fstype="ext4" --size=3500 --ondisk=mmcblk0 --label rootfs --fsoptions=defaults,noatime + +rootpw tizen +desktop --autologinuser=root +user --name root --groups audio,video --password 'tizen' + +repo --name=standard --baseurl=http://download.tizen.org/releases/milestone/tizen/unified/latest/repos/standard/packages/ --ssl_verify=no +repo --name=base --baseurl=http://download.tizen.org/releases/milestone/tizen/base/latest/repos/standard/packages/ --ssl_verify=no + +%packages +tar +gzip + +sed +grep +gawk +perl + +binutils +findutils +util-linux +lttng-ust +userspace-rcu +procps-ng +tzdata +ca-certificates + + +### Core FX +libicu +libunwind +iputils +zlib +krb5 +libcurl +libopenssl + +%end + +%post + +### Update /tmp privilege +chmod 777 /tmp +#################################### + +%end diff --git a/eng/common/cross/armel/tizen/tizen.patch b/eng/common/cross/armel/tizen/tizen.patch new file mode 100644 index 000000000..ca7c7c1ff --- /dev/null +++ b/eng/common/cross/armel/tizen/tizen.patch @@ -0,0 +1,9 @@ +diff -u -r a/usr/lib/libc.so b/usr/lib/libc.so +--- a/usr/lib/libc.so 2016-12-30 23:00:08.284951863 +0900 ++++ b/usr/lib/libc.so 2016-12-30 23:00:32.140951815 +0900 +@@ -2,4 +2,4 @@ + Use the shared library, but some functions are only in + the static library, so try that secondarily. */ + OUTPUT_FORMAT(elf32-littlearm) +-GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a AS_NEEDED ( /lib/ld-linux.so.3 ) ) ++GROUP ( libc.so.6 libc_nonshared.a AS_NEEDED ( ld-linux.so.3 ) ) diff --git a/eng/common/cross/armv6/sources.list.buster b/eng/common/cross/armv6/sources.list.buster new file mode 100644 index 000000000..f27fc4fb3 --- /dev/null +++ b/eng/common/cross/armv6/sources.list.buster @@ -0,0 +1,2 @@ +deb http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi +deb-src http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi diff --git a/eng/common/cross/build-android-rootfs.sh b/eng/common/cross/build-android-rootfs.sh new file mode 100644 index 000000000..42516bbee --- /dev/null +++ b/eng/common/cross/build-android-rootfs.sh @@ -0,0 +1,131 @@ +#!/usr/bin/env bash +set -e +__NDK_Version=r21 + +usage() +{ + echo "Creates a toolchain and sysroot used for cross-compiling for Android." + echo. + echo "Usage: $0 [BuildArch] [ApiLevel]" + echo. + echo "BuildArch is the target architecture of Android. Currently only arm64 is supported." + echo "ApiLevel is the target Android API level. API levels usually match to Android releases. See https://source.android.com/source/build-numbers.html" + echo. + echo "By default, the toolchain and sysroot will be generated in cross/android-rootfs/toolchain/[BuildArch]. You can change this behavior" + echo "by setting the TOOLCHAIN_DIR environment variable" + echo. + echo "By default, the NDK will be downloaded into the cross/android-rootfs/android-ndk-$__NDK_Version directory. If you already have an NDK installation," + echo "you can set the NDK_DIR environment variable to have this script use that installation of the NDK." + echo "By default, this script will generate a file, android_platform, in the root of the ROOTFS_DIR directory that contains the RID for the supported and tested Android build: android.28-arm64. This file is to replace '/etc/os-release', which is not available for Android." + exit 1 +} + +__ApiLevel=28 # The minimum platform for arm64 is API level 21 but the minimum version that support glob(3) is 28. See $ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/glob.h +__BuildArch=arm64 +__AndroidArch=aarch64 +__AndroidToolchain=aarch64-linux-android + +for i in "$@" + do + lowerI="$(echo $i | tr "[:upper:]" "[:lower:]")" + case $lowerI in + -?|-h|--help) + usage + exit 1 + ;; + arm64) + __BuildArch=arm64 + __AndroidArch=aarch64 + __AndroidToolchain=aarch64-linux-android + ;; + arm) + __BuildArch=arm + __AndroidArch=arm + __AndroidToolchain=arm-linux-androideabi + ;; + *[0-9]) + __ApiLevel=$i + ;; + *) + __UnprocessedBuildArgs="$__UnprocessedBuildArgs $i" + ;; + esac +done + +# Obtain the location of the bash script to figure out where the root of the repo is. +__ScriptBaseDir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +__CrossDir="$__ScriptBaseDir/../../../.tools/android-rootfs" + +if [[ ! -f "$__CrossDir" ]]; then + mkdir -p "$__CrossDir" +fi + +# Resolve absolute path to avoid `../` in build logs +__CrossDir="$( cd "$__CrossDir" && pwd )" + +__NDK_Dir="$__CrossDir/android-ndk-$__NDK_Version" +__lldb_Dir="$__CrossDir/lldb" +__ToolchainDir="$__CrossDir/android-ndk-$__NDK_Version" + +if [[ -n "$TOOLCHAIN_DIR" ]]; then + __ToolchainDir=$TOOLCHAIN_DIR +fi + +if [[ -n "$NDK_DIR" ]]; then + __NDK_Dir=$NDK_DIR +fi + +echo "Target API level: $__ApiLevel" +echo "Target architecture: $__BuildArch" +echo "NDK location: $__NDK_Dir" +echo "Target Toolchain location: $__ToolchainDir" + +# Download the NDK if required +if [ ! -d $__NDK_Dir ]; then + echo Downloading the NDK into $__NDK_Dir + mkdir -p $__NDK_Dir + wget -q --progress=bar:force:noscroll --show-progress https://dl.google.com/android/repository/android-ndk-$__NDK_Version-linux-x86_64.zip -O $__CrossDir/android-ndk-$__NDK_Version-linux-x86_64.zip + unzip -q $__CrossDir/android-ndk-$__NDK_Version-linux-x86_64.zip -d $__CrossDir +fi + +if [ ! -d $__lldb_Dir ]; then + mkdir -p $__lldb_Dir + echo Downloading LLDB into $__lldb_Dir + wget -q --progress=bar:force:noscroll --show-progress https://dl.google.com/android/repository/lldb-2.3.3614996-linux-x86_64.zip -O $__CrossDir/lldb-2.3.3614996-linux-x86_64.zip + unzip -q $__CrossDir/lldb-2.3.3614996-linux-x86_64.zip -d $__lldb_Dir +fi + +echo "Download dependencies..." +__TmpDir=$__CrossDir/tmp/$__BuildArch/ +mkdir -p "$__TmpDir" + +# combined dependencies for coreclr, installer and libraries +__AndroidPackages="libicu" +__AndroidPackages+=" libandroid-glob" +__AndroidPackages+=" liblzma" +__AndroidPackages+=" krb5" +__AndroidPackages+=" openssl" + +for path in $(wget -qO- http://termux.net/dists/stable/main/binary-$__AndroidArch/Packages |\ + grep -A15 "Package: \(${__AndroidPackages// /\\|}\)" | grep -v "static\|tool" | grep Filename); do + + if [[ "$path" != "Filename:" ]]; then + echo "Working on: $path" + wget -qO- http://termux.net/$path | dpkg -x - "$__TmpDir" + fi +done + +cp -R "$__TmpDir/data/data/com.termux/files/usr/"* "$__ToolchainDir/sysroot/usr/" + +# Generate platform file for build.sh script to assign to __DistroRid +echo "Generating platform file..." +echo "RID=android.${__ApiLevel}-${__BuildArch}" > $__ToolchainDir/sysroot/android_platform + +echo "Now to build coreclr, libraries and installers; run:" +echo ROOTFS_DIR=\$\(realpath $__ToolchainDir/sysroot\) ./build.sh --cross --arch $__BuildArch \ + --subsetCategory coreclr +echo ROOTFS_DIR=\$\(realpath $__ToolchainDir/sysroot\) ./build.sh --cross --arch $__BuildArch \ + --subsetCategory libraries +echo ROOTFS_DIR=\$\(realpath $__ToolchainDir/sysroot\) ./build.sh --cross --arch $__BuildArch \ + --subsetCategory installer diff --git a/eng/common/cross/build-rootfs.sh b/eng/common/cross/build-rootfs.sh new file mode 100644 index 000000000..7e4be9a0c --- /dev/null +++ b/eng/common/cross/build-rootfs.sh @@ -0,0 +1,383 @@ +#!/usr/bin/env bash + +set -e + +usage() +{ + echo "Usage: $0 [BuildArch] [CodeName] [lldbx.y] [--skipunmount] --rootfsdir ]" + echo "BuildArch can be: arm(default), armel, arm64, x86" + echo "CodeName - optional, Code name for Linux, can be: xenial(default), zesty, bionic, alpine, alpine3.13 or alpine3.14. If BuildArch is armel, LinuxCodeName is jessie(default) or tizen." + echo " for FreeBSD can be: freebsd12, freebsd13" + echo " for illumos can be: illumos." + echo "lldbx.y - optional, LLDB version, can be: lldb3.9(default), lldb4.0, lldb5.0, lldb6.0 no-lldb. Ignored for alpine and FreeBSD" + echo "--skipunmount - optional, will skip the unmount of rootfs folder." + echo "--use-mirror - optional, use mirror URL to fetch resources, when available." + exit 1 +} + +__CodeName=xenial +__CrossDir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +__InitialDir=$PWD +__BuildArch=arm +__AlpineArch=armv7 +__QEMUArch=arm +__UbuntuArch=armhf +__UbuntuRepo="http://ports.ubuntu.com/" +__LLDB_Package="liblldb-3.9-dev" +__SkipUnmount=0 + +# base development support +__UbuntuPackages="build-essential" + +__AlpinePackages="alpine-base" +__AlpinePackages+=" build-base" +__AlpinePackages+=" linux-headers" +__AlpinePackages+=" lldb-dev" +__AlpinePackages+=" python3" +__AlpinePackages+=" libedit" + +# symlinks fixer +__UbuntuPackages+=" symlinks" + +# CoreCLR and CoreFX dependencies +__UbuntuPackages+=" libicu-dev" +__UbuntuPackages+=" liblttng-ust-dev" +__UbuntuPackages+=" libunwind8-dev" + +__AlpinePackages+=" gettext-dev" +__AlpinePackages+=" icu-dev" +__AlpinePackages+=" libunwind-dev" +__AlpinePackages+=" lttng-ust-dev" + +# CoreFX dependencies +__UbuntuPackages+=" libcurl4-openssl-dev" +__UbuntuPackages+=" libkrb5-dev" +__UbuntuPackages+=" libssl-dev" +__UbuntuPackages+=" zlib1g-dev" + +__AlpinePackages+=" curl-dev" +__AlpinePackages+=" krb5-dev" +__AlpinePackages+=" openssl-dev" +__AlpinePackages+=" zlib-dev" + +__FreeBSDBase="12.3-RELEASE" +__FreeBSDPkg="1.17.0" +__FreeBSDABI="12" +__FreeBSDPackages="libunwind" +__FreeBSDPackages+=" icu" +__FreeBSDPackages+=" libinotify" +__FreeBSDPackages+=" openssl" +__FreeBSDPackages+=" krb5" +__FreeBSDPackages+=" terminfo-db" + +__IllumosPackages="icu-64.2nb2" +__IllumosPackages+=" mit-krb5-1.16.2nb4" +__IllumosPackages+=" openssl-1.1.1e" +__IllumosPackages+=" zlib-1.2.11" + +# ML.NET dependencies +__UbuntuPackages+=" libomp5" +__UbuntuPackages+=" libomp-dev" + +__UseMirror=0 + +__UnprocessedBuildArgs= +while :; do + if [ $# -le 0 ]; then + break + fi + + lowerI="$(echo $1 | tr "[:upper:]" "[:lower:]")" + case $lowerI in + -?|-h|--help) + usage + exit 1 + ;; + arm) + __BuildArch=arm + __UbuntuArch=armhf + __AlpineArch=armv7 + __QEMUArch=arm + ;; + armv6) + __BuildArch=armv6 + __UbuntuArch=armhf + __QEMUArch=arm + __UbuntuRepo="http://raspbian.raspberrypi.org/raspbian/" + __CodeName=buster + __LLDB_Package="liblldb-6.0-dev" + __Keyring="/usr/share/keyrings/raspbian-archive-keyring.gpg" + ;; + arm64) + __BuildArch=arm64 + __UbuntuArch=arm64 + __AlpineArch=aarch64 + __QEMUArch=aarch64 + ;; + armel) + __BuildArch=armel + __UbuntuArch=armel + __UbuntuRepo="http://ftp.debian.org/debian/" + __CodeName=jessie + ;; + ppc64le) + __BuildArch=ppc64le + __UbuntuArch=ppc64el + __UbuntuRepo="http://ports.ubuntu.com/ubuntu-ports/" + __UbuntuPackages=$(echo ${__UbuntuPackages} | sed 's/ libunwind8-dev//') + __UbuntuPackages=$(echo ${__UbuntuPackages} | sed 's/ libomp-dev//') + __UbuntuPackages=$(echo ${__UbuntuPackages} | sed 's/ libomp5//') + unset __LLDB_Package + ;; + s390x) + __BuildArch=s390x + __UbuntuArch=s390x + __UbuntuRepo="http://ports.ubuntu.com/ubuntu-ports/" + __UbuntuPackages=$(echo ${__UbuntuPackages} | sed 's/ libunwind8-dev//') + __UbuntuPackages=$(echo ${__UbuntuPackages} | sed 's/ libomp-dev//') + __UbuntuPackages=$(echo ${__UbuntuPackages} | sed 's/ libomp5//') + unset __LLDB_Package + ;; + x86) + __BuildArch=x86 + __UbuntuArch=i386 + __UbuntuRepo="http://archive.ubuntu.com/ubuntu/" + ;; + lldb3.6) + __LLDB_Package="lldb-3.6-dev" + ;; + lldb3.8) + __LLDB_Package="lldb-3.8-dev" + ;; + lldb3.9) + __LLDB_Package="liblldb-3.9-dev" + ;; + lldb4.0) + __LLDB_Package="liblldb-4.0-dev" + ;; + lldb5.0) + __LLDB_Package="liblldb-5.0-dev" + ;; + lldb6.0) + __LLDB_Package="liblldb-6.0-dev" + ;; + no-lldb) + unset __LLDB_Package + ;; + xenial) # Ubuntu 16.04 + if [ "$__CodeName" != "jessie" ]; then + __CodeName=xenial + fi + ;; + zesty) # Ubuntu 17.04 + if [ "$__CodeName" != "jessie" ]; then + __CodeName=zesty + fi + ;; + bionic) # Ubuntu 18.04 + if [ "$__CodeName" != "jessie" ]; then + __CodeName=bionic + fi + ;; + jessie) # Debian 8 + __CodeName=jessie + __UbuntuRepo="http://ftp.debian.org/debian/" + ;; + stretch) # Debian 9 + __CodeName=stretch + __UbuntuRepo="http://ftp.debian.org/debian/" + __LLDB_Package="liblldb-6.0-dev" + ;; + buster) # Debian 10 + __CodeName=buster + __UbuntuRepo="http://ftp.debian.org/debian/" + __LLDB_Package="liblldb-6.0-dev" + ;; + tizen) + if [ "$__BuildArch" != "arm" ] && [ "$__BuildArch" != "armel" ] && [ "$__BuildArch" != "arm64" ]; then + echo "Tizen is available only for arm, armel and arm64." + usage; + exit 1; + fi + __CodeName= + __UbuntuRepo= + __Tizen=tizen + ;; + alpine|alpine3.13) + __CodeName=alpine + __UbuntuRepo= + __AlpineVersion=3.13 + __AlpinePackages+=" llvm10-libs" + ;; + alpine3.14) + __CodeName=alpine + __UbuntuRepo= + __AlpineVersion=3.14 + __AlpinePackages+=" llvm11-libs" + ;; + freebsd12) + __CodeName=freebsd + __BuildArch=x64 + __SkipUnmount=1 + ;; + freebsd13) + __CodeName=freebsd + __FreeBSDBase="13.0-RELEASE" + __FreeBSDABI="13" + __BuildArch=x64 + __SkipUnmount=1 + ;; + illumos) + __CodeName=illumos + __BuildArch=x64 + __SkipUnmount=1 + ;; + --skipunmount) + __SkipUnmount=1 + ;; + --rootfsdir|-rootfsdir) + shift + __RootfsDir=$1 + ;; + --use-mirror) + __UseMirror=1 + ;; + *) + __UnprocessedBuildArgs="$__UnprocessedBuildArgs $1" + ;; + esac + + shift +done + +if [ -e "$__Keyring" ]; then + __Keyring="--keyring=$__Keyring" +else + __Keyring="" +fi + +if [ "$__BuildArch" == "armel" ]; then + __LLDB_Package="lldb-3.5-dev" +fi +__UbuntuPackages+=" ${__LLDB_Package:-}" + +if [ -z "$__RootfsDir" ] && [ ! -z "$ROOTFS_DIR" ]; then + __RootfsDir=$ROOTFS_DIR +fi + +if [ -z "$__RootfsDir" ]; then + __RootfsDir="$__CrossDir/../../../.tools/rootfs/$__BuildArch" +fi + +if [ -d "$__RootfsDir" ]; then + if [ $__SkipUnmount == 0 ]; then + umount $__RootfsDir/* || true + fi + rm -rf $__RootfsDir +fi + +mkdir -p $__RootfsDir +__RootfsDir="$( cd "$__RootfsDir" && pwd )" + +if [[ "$__CodeName" == "alpine" ]]; then + __ApkToolsVersion=2.9.1 + __ApkToolsDir=$(mktemp -d) + wget https://github.com/alpinelinux/apk-tools/releases/download/v$__ApkToolsVersion/apk-tools-$__ApkToolsVersion-x86_64-linux.tar.gz -P $__ApkToolsDir + tar -xf $__ApkToolsDir/apk-tools-$__ApkToolsVersion-x86_64-linux.tar.gz -C $__ApkToolsDir + mkdir -p $__RootfsDir/usr/bin + cp -v /usr/bin/qemu-$__QEMUArch-static $__RootfsDir/usr/bin + + $__ApkToolsDir/apk-tools-$__ApkToolsVersion/apk \ + -X http://dl-cdn.alpinelinux.org/alpine/v$__AlpineVersion/main \ + -X http://dl-cdn.alpinelinux.org/alpine/v$__AlpineVersion/community \ + -U --allow-untrusted --root $__RootfsDir --arch $__AlpineArch --initdb \ + add $__AlpinePackages + + rm -r $__ApkToolsDir +elif [[ "$__CodeName" == "freebsd" ]]; then + mkdir -p $__RootfsDir/usr/local/etc + JOBS="$(getconf _NPROCESSORS_ONLN)" + wget -O - https://download.freebsd.org/ftp/releases/amd64/${__FreeBSDBase}/base.txz | tar -C $__RootfsDir -Jxf - ./lib ./usr/lib ./usr/libdata ./usr/include ./usr/share/keys ./etc ./bin/freebsd-version + echo "ABI = \"FreeBSD:${__FreeBSDABI}:amd64\"; FINGERPRINTS = \"${__RootfsDir}/usr/share/keys\"; REPOS_DIR = [\"${__RootfsDir}/etc/pkg\"]; REPO_AUTOUPDATE = NO; RUN_SCRIPTS = NO;" > ${__RootfsDir}/usr/local/etc/pkg.conf + echo "FreeBSD: { url: "pkg+http://pkg.FreeBSD.org/\${ABI}/quarterly", mirror_type: \"srv\", signature_type: \"fingerprints\", fingerprints: \"${__RootfsDir}/usr/share/keys/pkg\", enabled: yes }" > ${__RootfsDir}/etc/pkg/FreeBSD.conf + mkdir -p $__RootfsDir/tmp + # get and build package manager + wget -O - https://github.com/freebsd/pkg/archive/${__FreeBSDPkg}.tar.gz | tar -C $__RootfsDir/tmp -zxf - + cd $__RootfsDir/tmp/pkg-${__FreeBSDPkg} + # needed for install to succeed + mkdir -p $__RootfsDir/host/etc + ./autogen.sh && ./configure --prefix=$__RootfsDir/host && make -j "$JOBS" && make install + rm -rf $__RootfsDir/tmp/pkg-${__FreeBSDPkg} + # install packages we need. + INSTALL_AS_USER=$(whoami) $__RootfsDir/host/sbin/pkg -r $__RootfsDir -C $__RootfsDir/usr/local/etc/pkg.conf update + INSTALL_AS_USER=$(whoami) $__RootfsDir/host/sbin/pkg -r $__RootfsDir -C $__RootfsDir/usr/local/etc/pkg.conf install --yes $__FreeBSDPackages +elif [[ "$__CodeName" == "illumos" ]]; then + mkdir "$__RootfsDir/tmp" + pushd "$__RootfsDir/tmp" + JOBS="$(getconf _NPROCESSORS_ONLN)" + echo "Downloading sysroot." + wget -O - https://github.com/illumos/sysroot/releases/download/20181213-de6af22ae73b-v1/illumos-sysroot-i386-20181213-de6af22ae73b-v1.tar.gz | tar -C "$__RootfsDir" -xzf - + echo "Building binutils. Please wait.." + wget -O - https://ftp.gnu.org/gnu/binutils/binutils-2.33.1.tar.bz2 | tar -xjf - + mkdir build-binutils && cd build-binutils + ../binutils-2.33.1/configure --prefix="$__RootfsDir" --target="x86_64-sun-solaris2.10" --program-prefix="x86_64-illumos-" --with-sysroot="$__RootfsDir" + make -j "$JOBS" && make install && cd .. + echo "Building gcc. Please wait.." + wget -O - https://ftp.gnu.org/gnu/gcc/gcc-8.4.0/gcc-8.4.0.tar.xz | tar -xJf - + CFLAGS="-fPIC" + CXXFLAGS="-fPIC" + CXXFLAGS_FOR_TARGET="-fPIC" + CFLAGS_FOR_TARGET="-fPIC" + export CFLAGS CXXFLAGS CXXFLAGS_FOR_TARGET CFLAGS_FOR_TARGET + mkdir build-gcc && cd build-gcc + ../gcc-8.4.0/configure --prefix="$__RootfsDir" --target="x86_64-sun-solaris2.10" --program-prefix="x86_64-illumos-" --with-sysroot="$__RootfsDir" --with-gnu-as \ + --with-gnu-ld --disable-nls --disable-libgomp --disable-libquadmath --disable-libssp --disable-libvtv --disable-libcilkrts --disable-libada --disable-libsanitizer \ + --disable-libquadmath-support --disable-shared --enable-tls + make -j "$JOBS" && make install && cd .. + BaseUrl=https://pkgsrc.joyent.com + if [[ "$__UseMirror" == 1 ]]; then + BaseUrl=http://pkgsrc.smartos.skylime.net + fi + BaseUrl="$BaseUrl"/packages/SmartOS/2020Q1/x86_64/All + echo "Downloading dependencies." + read -ra array <<<"$__IllumosPackages" + for package in "${array[@]}"; do + echo "Installing $package..." + wget "$BaseUrl"/"$package".tgz + ar -x "$package".tgz + tar --skip-old-files -xzf "$package".tmp.tgz -C "$__RootfsDir" 2>/dev/null + done + echo "Cleaning up temporary files." + popd + rm -rf "$__RootfsDir"/{tmp,+*} + mkdir -p "$__RootfsDir"/usr/include/net + mkdir -p "$__RootfsDir"/usr/include/netpacket + wget -P "$__RootfsDir"/usr/include/net https://raw.githubusercontent.com/illumos/illumos-gate/master/usr/src/uts/common/io/bpf/net/bpf.h + wget -P "$__RootfsDir"/usr/include/net https://raw.githubusercontent.com/illumos/illumos-gate/master/usr/src/uts/common/io/bpf/net/dlt.h + wget -P "$__RootfsDir"/usr/include/netpacket https://raw.githubusercontent.com/illumos/illumos-gate/master/usr/src/uts/common/inet/sockmods/netpacket/packet.h + wget -P "$__RootfsDir"/usr/include/sys https://raw.githubusercontent.com/illumos/illumos-gate/master/usr/src/uts/common/sys/sdt.h +elif [[ -n $__CodeName ]]; then + qemu-debootstrap $__Keyring --arch $__UbuntuArch $__CodeName $__RootfsDir $__UbuntuRepo + cp $__CrossDir/$__BuildArch/sources.list.$__CodeName $__RootfsDir/etc/apt/sources.list + chroot $__RootfsDir apt-get update + chroot $__RootfsDir apt-get -f -y install + chroot $__RootfsDir apt-get -y install $__UbuntuPackages + chroot $__RootfsDir symlinks -cr /usr + chroot $__RootfsDir apt-get clean + + if [ $__SkipUnmount == 0 ]; then + umount $__RootfsDir/* || true + fi + + if [[ "$__BuildArch" == "armel" && "$__CodeName" == "jessie" ]]; then + pushd $__RootfsDir + patch -p1 < $__CrossDir/$__BuildArch/armel.jessie.patch + popd + fi +elif [[ "$__Tizen" == "tizen" ]]; then + ROOTFS_DIR=$__RootfsDir $__CrossDir/$__BuildArch/tizen-build-rootfs.sh +else + echo "Unsupported target platform." + usage; + exit 1 +fi diff --git a/eng/common/cross/ppc64le/sources.list.bionic b/eng/common/cross/ppc64le/sources.list.bionic new file mode 100644 index 000000000..210955740 --- /dev/null +++ b/eng/common/cross/ppc64le/sources.list.bionic @@ -0,0 +1,11 @@ +deb http://ports.ubuntu.com/ubuntu-ports/ bionic main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ bionic-updates main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-updates main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ bionic-backports main restricted +deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-backports main restricted + +deb http://ports.ubuntu.com/ubuntu-ports/ bionic-security main restricted universe multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-security main restricted universe multiverse diff --git a/eng/common/cross/s390x/sources.list.bionic b/eng/common/cross/s390x/sources.list.bionic new file mode 100644 index 000000000..210955740 --- /dev/null +++ b/eng/common/cross/s390x/sources.list.bionic @@ -0,0 +1,11 @@ +deb http://ports.ubuntu.com/ubuntu-ports/ bionic main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ bionic-updates main restricted universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-updates main restricted universe + +deb http://ports.ubuntu.com/ubuntu-ports/ bionic-backports main restricted +deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-backports main restricted + +deb http://ports.ubuntu.com/ubuntu-ports/ bionic-security main restricted universe multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ bionic-security main restricted universe multiverse diff --git a/eng/common/cross/toolchain.cmake b/eng/common/cross/toolchain.cmake new file mode 100644 index 000000000..9fd345bde --- /dev/null +++ b/eng/common/cross/toolchain.cmake @@ -0,0 +1,272 @@ +set(CROSS_ROOTFS $ENV{ROOTFS_DIR}) + +set(TARGET_ARCH_NAME $ENV{TARGET_BUILD_ARCH}) +if(EXISTS ${CROSS_ROOTFS}/bin/freebsd-version) + set(CMAKE_SYSTEM_NAME FreeBSD) + set(FREEBSD 1) +elseif(EXISTS ${CROSS_ROOTFS}/usr/platform/i86pc) + set(CMAKE_SYSTEM_NAME SunOS) + set(ILLUMOS 1) +else() + set(CMAKE_SYSTEM_NAME Linux) + set(LINUX 1) +endif() +set(CMAKE_SYSTEM_VERSION 1) + +if(EXISTS ${CROSS_ROOTFS}/etc/tizen-release) + set(TIZEN 1) +elseif(EXISTS ${CROSS_ROOTFS}/android_platform) + set(ANDROID 1) +endif() + +if(TARGET_ARCH_NAME STREQUAL "armel") + set(CMAKE_SYSTEM_PROCESSOR armv7l) + set(TOOLCHAIN "arm-linux-gnueabi") + if(TIZEN) + set(TIZEN_TOOLCHAIN "armv7l-tizen-linux-gnueabi/9.2.0") + endif() +elseif(TARGET_ARCH_NAME STREQUAL "arm") + set(CMAKE_SYSTEM_PROCESSOR armv7l) + if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/armv7-alpine-linux-musleabihf) + set(TOOLCHAIN "armv7-alpine-linux-musleabihf") + elseif(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/armv6-alpine-linux-musleabihf) + set(TOOLCHAIN "armv6-alpine-linux-musleabihf") + else() + set(TOOLCHAIN "arm-linux-gnueabihf") + endif() + if(TIZEN) + set(TIZEN_TOOLCHAIN "armv7hl-tizen-linux-gnueabihf/9.2.0") + endif() +elseif(TARGET_ARCH_NAME STREQUAL "armv6") + set(CMAKE_SYSTEM_PROCESSOR armv6l) + if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/armv6-alpine-linux-musleabihf) + set(TOOLCHAIN "armv6-alpine-linux-musleabihf") + else() + set(TOOLCHAIN "arm-linux-gnueabihf") + endif() +elseif(TARGET_ARCH_NAME STREQUAL "arm64") + set(CMAKE_SYSTEM_PROCESSOR aarch64) + if(EXISTS ${CROSS_ROOTFS}/usr/lib/gcc/aarch64-alpine-linux-musl) + set(TOOLCHAIN "aarch64-alpine-linux-musl") + else() + set(TOOLCHAIN "aarch64-linux-gnu") + endif() + if(TIZEN) + set(TIZEN_TOOLCHAIN "aarch64-tizen-linux-gnu/9.2.0") + endif() +elseif(TARGET_ARCH_NAME STREQUAL "ppc64le") + set(CMAKE_SYSTEM_PROCESSOR ppc64le) + set(TOOLCHAIN "powerpc64le-linux-gnu") +elseif(TARGET_ARCH_NAME STREQUAL "s390x") + set(CMAKE_SYSTEM_PROCESSOR s390x) + set(TOOLCHAIN "s390x-linux-gnu") +elseif(TARGET_ARCH_NAME STREQUAL "x86") + set(CMAKE_SYSTEM_PROCESSOR i686) + set(TOOLCHAIN "i686-linux-gnu") +elseif (FREEBSD) + set(CMAKE_SYSTEM_PROCESSOR "x86_64") + set(triple "x86_64-unknown-freebsd12") +elseif (ILLUMOS) + set(CMAKE_SYSTEM_PROCESSOR "x86_64") + set(TOOLCHAIN "x86_64-illumos") +else() + message(FATAL_ERROR "Arch is ${TARGET_ARCH_NAME}. Only armel, arm, armv6, arm64, ppc64le, s390x and x86 are supported!") +endif() + +if(DEFINED ENV{TOOLCHAIN}) + set(TOOLCHAIN $ENV{TOOLCHAIN}) +endif() + +# Specify include paths +if(TIZEN) + if(TARGET_ARCH_NAME STREQUAL "arm") + include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}/include/c++/) + include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}/include/c++/armv7hl-tizen-linux-gnueabihf) + endif() + if(TARGET_ARCH_NAME STREQUAL "armel") + include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}/include/c++/) + include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}/include/c++/armv7l-tizen-linux-gnueabi) + endif() + if(TARGET_ARCH_NAME STREQUAL "arm64") + include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}/include/c++/) + include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}/include/c++/aarch64-tizen-linux-gnu) + endif() +endif() + +if(ANDROID) + if(TARGET_ARCH_NAME STREQUAL "arm") + set(ANDROID_ABI armeabi-v7a) + elseif(TARGET_ARCH_NAME STREQUAL "arm64") + set(ANDROID_ABI arm64-v8a) + endif() + + # extract platform number required by the NDK's toolchain + file(READ "${CROSS_ROOTFS}/android_platform" RID_FILE_CONTENTS) + string(REPLACE "RID=" "" ANDROID_RID "${RID_FILE_CONTENTS}") + string(REGEX REPLACE ".*\\.([0-9]+)-.*" "\\1" ANDROID_PLATFORM "${ANDROID_RID}") + + set(ANDROID_TOOLCHAIN clang) + set(FEATURE_EVENT_TRACE 0) # disable event trace as there is no lttng-ust package in termux repository + set(CMAKE_SYSTEM_LIBRARY_PATH "${CROSS_ROOTFS}/usr/lib") + set(CMAKE_SYSTEM_INCLUDE_PATH "${CROSS_ROOTFS}/usr/include") + + # include official NDK toolchain script + include(${CROSS_ROOTFS}/../build/cmake/android.toolchain.cmake) +elseif(FREEBSD) + # we cross-compile by instructing clang + set(CMAKE_C_COMPILER_TARGET ${triple}) + set(CMAKE_CXX_COMPILER_TARGET ${triple}) + set(CMAKE_ASM_COMPILER_TARGET ${triple}) + set(CMAKE_SYSROOT "${CROSS_ROOTFS}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=lld") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fuse-ld=lld") + set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -fuse-ld=lld") +elseif(ILLUMOS) + set(CMAKE_SYSROOT "${CROSS_ROOTFS}") + + include_directories(SYSTEM ${CROSS_ROOTFS}/include) + + set(TOOLSET_PREFIX ${TOOLCHAIN}-) + function(locate_toolchain_exec exec var) + string(TOUPPER ${exec} EXEC_UPPERCASE) + if(NOT "$ENV{CLR_${EXEC_UPPERCASE}}" STREQUAL "") + set(${var} "$ENV{CLR_${EXEC_UPPERCASE}}" PARENT_SCOPE) + return() + endif() + + find_program(EXEC_LOCATION_${exec} + NAMES + "${TOOLSET_PREFIX}${exec}${CLR_CMAKE_COMPILER_FILE_NAME_VERSION}" + "${TOOLSET_PREFIX}${exec}") + + if (EXEC_LOCATION_${exec} STREQUAL "EXEC_LOCATION_${exec}-NOTFOUND") + message(FATAL_ERROR "Unable to find toolchain executable. Name: ${exec}, Prefix: ${TOOLSET_PREFIX}.") + endif() + set(${var} ${EXEC_LOCATION_${exec}} PARENT_SCOPE) + endfunction() + + set(CMAKE_SYSTEM_PREFIX_PATH "${CROSS_ROOTFS}") + + locate_toolchain_exec(gcc CMAKE_C_COMPILER) + locate_toolchain_exec(g++ CMAKE_CXX_COMPILER) + + set(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES} -lssp") + set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} -lssp") +else() + set(CMAKE_SYSROOT "${CROSS_ROOTFS}") + + set(CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN "${CROSS_ROOTFS}/usr") + set(CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN "${CROSS_ROOTFS}/usr") + set(CMAKE_ASM_COMPILER_EXTERNAL_TOOLCHAIN "${CROSS_ROOTFS}/usr") +endif() + +# Specify link flags + +function(add_toolchain_linker_flag Flag) + set(Config "${ARGV1}") + set(CONFIG_SUFFIX "") + if (NOT Config STREQUAL "") + set(CONFIG_SUFFIX "_${Config}") + endif() + set("CMAKE_EXE_LINKER_FLAGS${CONFIG_SUFFIX}_INIT" "${CMAKE_EXE_LINKER_FLAGS${CONFIG_SUFFIX}_INIT} ${Flag}" PARENT_SCOPE) + set("CMAKE_SHARED_LINKER_FLAGS${CONFIG_SUFFIX}_INIT" "${CMAKE_SHARED_LINKER_FLAGS${CONFIG_SUFFIX}_INIT} ${Flag}" PARENT_SCOPE) +endfunction() + +if(LINUX) + add_toolchain_linker_flag("-Wl,--rpath-link=${CROSS_ROOTFS}/lib/${TOOLCHAIN}") + add_toolchain_linker_flag("-Wl,--rpath-link=${CROSS_ROOTFS}/usr/lib/${TOOLCHAIN}") +endif() + +if(TARGET_ARCH_NAME MATCHES "^(arm|armel)$") + if(TIZEN) + add_toolchain_linker_flag("-B${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}") + add_toolchain_linker_flag("-L${CROSS_ROOTFS}/lib") + add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib") + add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}") + endif() +elseif(TARGET_ARCH_NAME STREQUAL "arm64") + if(TIZEN) + add_toolchain_linker_flag("-B${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}") + add_toolchain_linker_flag("-L${CROSS_ROOTFS}/lib64") + add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib64") + add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}") + + add_toolchain_linker_flag("-Wl,--rpath-link=${CROSS_ROOTFS}/lib64") + add_toolchain_linker_flag("-Wl,--rpath-link=${CROSS_ROOTFS}/usr/lib64") + add_toolchain_linker_flag("-Wl,--rpath-link=${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}") + endif() +elseif(TARGET_ARCH_NAME STREQUAL "x86") + add_toolchain_linker_flag(-m32) +elseif(ILLUMOS) + add_toolchain_linker_flag("-L${CROSS_ROOTFS}/lib/amd64") + add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/amd64/lib") +endif() + +# Specify compile options + +if((TARGET_ARCH_NAME MATCHES "^(arm|armv6|armel|arm64|ppc64le|s390x)$" AND NOT ANDROID) OR ILLUMOS) + set(CMAKE_C_COMPILER_TARGET ${TOOLCHAIN}) + set(CMAKE_CXX_COMPILER_TARGET ${TOOLCHAIN}) + set(CMAKE_ASM_COMPILER_TARGET ${TOOLCHAIN}) +endif() + +if(TARGET_ARCH_NAME MATCHES "^(arm|armel)$") + add_compile_options(-mthumb) + if (NOT DEFINED CLR_ARM_FPU_TYPE) + set (CLR_ARM_FPU_TYPE vfpv3) + endif (NOT DEFINED CLR_ARM_FPU_TYPE) + + add_compile_options (-mfpu=${CLR_ARM_FPU_TYPE}) + if (NOT DEFINED CLR_ARM_FPU_CAPABILITY) + set (CLR_ARM_FPU_CAPABILITY 0x7) + endif (NOT DEFINED CLR_ARM_FPU_CAPABILITY) + + add_definitions (-DCLR_ARM_FPU_CAPABILITY=${CLR_ARM_FPU_CAPABILITY}) + + if(TARGET_ARCH_NAME STREQUAL "armel") + add_compile_options(-mfloat-abi=softfp) + endif() +elseif(TARGET_ARCH_NAME STREQUAL "x86") + add_compile_options(-m32) + add_compile_options(-Wno-error=unused-command-line-argument) +endif() + +if(TIZEN) + if(TARGET_ARCH_NAME MATCHES "^(arm|armel|arm64)$") + add_compile_options(-Wno-deprecated-declarations) # compile-time option + add_compile_options(-D__extern_always_inline=inline) # compile-time option + endif() +endif() + +# Set LLDB include and library paths for builds that need lldb. +if(TARGET_ARCH_NAME MATCHES "^(arm|armel|x86)$") + if(TARGET_ARCH_NAME STREQUAL "x86") + set(LLVM_CROSS_DIR "$ENV{LLVM_CROSS_HOME}") + else() # arm/armel case + set(LLVM_CROSS_DIR "$ENV{LLVM_ARM_HOME}") + endif() + if(LLVM_CROSS_DIR) + set(WITH_LLDB_LIBS "${LLVM_CROSS_DIR}/lib/" CACHE STRING "") + set(WITH_LLDB_INCLUDES "${LLVM_CROSS_DIR}/include" CACHE STRING "") + set(LLDB_H "${WITH_LLDB_INCLUDES}" CACHE STRING "") + set(LLDB "${LLVM_CROSS_DIR}/lib/liblldb.so" CACHE STRING "") + else() + if(TARGET_ARCH_NAME STREQUAL "x86") + set(WITH_LLDB_LIBS "${CROSS_ROOTFS}/usr/lib/i386-linux-gnu" CACHE STRING "") + set(CHECK_LLVM_DIR "${CROSS_ROOTFS}/usr/lib/llvm-3.8/include") + if(EXISTS "${CHECK_LLVM_DIR}" AND IS_DIRECTORY "${CHECK_LLVM_DIR}") + set(WITH_LLDB_INCLUDES "${CHECK_LLVM_DIR}") + else() + set(WITH_LLDB_INCLUDES "${CROSS_ROOTFS}/usr/lib/llvm-3.6/include") + endif() + else() # arm/armel case + set(WITH_LLDB_LIBS "${CROSS_ROOTFS}/usr/lib/${TOOLCHAIN}" CACHE STRING "") + set(WITH_LLDB_INCLUDES "${CROSS_ROOTFS}/usr/lib/llvm-3.6/include" CACHE STRING "") + endif() + endif() +endif() + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) diff --git a/eng/common/cross/x86/sources.list.bionic b/eng/common/cross/x86/sources.list.bionic new file mode 100644 index 000000000..a71ccadcf --- /dev/null +++ b/eng/common/cross/x86/sources.list.bionic @@ -0,0 +1,11 @@ +deb http://archive.ubuntu.com/ubuntu/ bionic main restricted universe +deb-src http://archive.ubuntu.com/ubuntu/ bionic main restricted universe + +deb http://archive.ubuntu.com/ubuntu/ bionic-updates main restricted universe +deb-src http://archive.ubuntu.com/ubuntu/ bionic-updates main restricted universe + +deb http://archive.ubuntu.com/ubuntu/ bionic-backports main restricted +deb-src http://archive.ubuntu.com/ubuntu/ bionic-backports main restricted + +deb http://archive.ubuntu.com/ubuntu/ bionic-security main restricted universe multiverse +deb-src http://archive.ubuntu.com/ubuntu/ bionic-security main restricted universe multiverse diff --git a/eng/common/cross/x86/sources.list.xenial b/eng/common/cross/x86/sources.list.xenial new file mode 100644 index 000000000..ad9c5a014 --- /dev/null +++ b/eng/common/cross/x86/sources.list.xenial @@ -0,0 +1,11 @@ +deb http://archive.ubuntu.com/ubuntu/ xenial main restricted universe +deb-src http://archive.ubuntu.com/ubuntu/ xenial main restricted universe + +deb http://archive.ubuntu.com/ubuntu/ xenial-updates main restricted universe +deb-src http://archive.ubuntu.com/ubuntu/ xenial-updates main restricted universe + +deb http://archive.ubuntu.com/ubuntu/ xenial-backports main restricted +deb-src http://archive.ubuntu.com/ubuntu/ xenial-backports main restricted + +deb http://archive.ubuntu.com/ubuntu/ xenial-security main restricted universe multiverse +deb-src http://archive.ubuntu.com/ubuntu/ xenial-security main restricted universe multiverse diff --git a/eng/common/darc-init.ps1 b/eng/common/darc-init.ps1 new file mode 100644 index 000000000..435e76413 --- /dev/null +++ b/eng/common/darc-init.ps1 @@ -0,0 +1,47 @@ +param ( + $darcVersion = $null, + $versionEndpoint = 'https://maestro-prod.westus2.cloudapp.azure.com/api/assets/darc-version?api-version=2019-01-16', + $verbosity = 'minimal', + $toolpath = $null +) + +. $PSScriptRoot\tools.ps1 + +function InstallDarcCli ($darcVersion, $toolpath) { + $darcCliPackageName = 'microsoft.dotnet.darc' + + $dotnetRoot = InitializeDotNetCli -install:$true + $dotnet = "$dotnetRoot\dotnet.exe" + $toolList = & "$dotnet" tool list -g + + if ($toolList -like "*$darcCliPackageName*") { + & "$dotnet" tool uninstall $darcCliPackageName -g + } + + # If the user didn't explicitly specify the darc version, + # query the Maestro API for the correct version of darc to install. + if (-not $darcVersion) { + $darcVersion = $(Invoke-WebRequest -Uri $versionEndpoint -UseBasicParsing).Content + } + + $arcadeServicesSource = 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json' + + Write-Host "Installing Darc CLI version $darcVersion..." + Write-Host 'You may need to restart your command window if this is the first dotnet tool you have installed.' + if (-not $toolpath) { + Write-Host "'$dotnet' tool install $darcCliPackageName --version $darcVersion --add-source '$arcadeServicesSource' -v $verbosity -g" + & "$dotnet" tool install $darcCliPackageName --version $darcVersion --add-source "$arcadeServicesSource" -v $verbosity -g + }else { + Write-Host "'$dotnet' tool install $darcCliPackageName --version $darcVersion --add-source '$arcadeServicesSource' -v $verbosity --tool-path '$toolpath'" + & "$dotnet" tool install $darcCliPackageName --version $darcVersion --add-source "$arcadeServicesSource" -v $verbosity --tool-path "$toolpath" + } +} + +try { + InstallDarcCli $darcVersion $toolpath +} +catch { + Write-Host $_.ScriptStackTrace + Write-PipelineTelemetryError -Category 'Darc' -Message $_ + ExitWithExitCode 1 +} \ No newline at end of file diff --git a/eng/common/darc-init.sh b/eng/common/darc-init.sh new file mode 100644 index 000000000..84c1d0cc2 --- /dev/null +++ b/eng/common/darc-init.sh @@ -0,0 +1,82 @@ +#!/usr/bin/env bash + +source="${BASH_SOURCE[0]}" +darcVersion='' +versionEndpoint='https://maestro-prod.westus2.cloudapp.azure.com/api/assets/darc-version?api-version=2019-01-16' +verbosity='minimal' + +while [[ $# > 0 ]]; do + opt="$(echo "$1" | tr "[:upper:]" "[:lower:]")" + case "$opt" in + --darcversion) + darcVersion=$2 + shift + ;; + --versionendpoint) + versionEndpoint=$2 + shift + ;; + --verbosity) + verbosity=$2 + shift + ;; + --toolpath) + toolpath=$2 + shift + ;; + *) + echo "Invalid argument: $1" + usage + exit 1 + ;; + esac + + shift +done + +# resolve $source until the file is no longer a symlink +while [[ -h "$source" ]]; do + scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + source="$(readlink "$source")" + # if $source was a relative symlink, we need to resolve it relative to the path where the + # symlink file was located + [[ $source != /* ]] && source="$scriptroot/$source" +done +scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + +. "$scriptroot/tools.sh" + +if [ -z "$darcVersion" ]; then + darcVersion=$(curl -X GET "$versionEndpoint" -H "accept: text/plain") +fi + +function InstallDarcCli { + local darc_cli_package_name="microsoft.dotnet.darc" + + InitializeDotNetCli true + local dotnet_root=$_InitializeDotNetCli + + if [ -z "$toolpath" ]; then + local tool_list=$($dotnet_root/dotnet tool list -g) + if [[ $tool_list = *$darc_cli_package_name* ]]; then + echo $($dotnet_root/dotnet tool uninstall $darc_cli_package_name -g) + fi + else + local tool_list=$($dotnet_root/dotnet tool list --tool-path "$toolpath") + if [[ $tool_list = *$darc_cli_package_name* ]]; then + echo $($dotnet_root/dotnet tool uninstall $darc_cli_package_name --tool-path "$toolpath") + fi + fi + + local arcadeServicesSource="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json" + + echo "Installing Darc CLI version $darcVersion..." + echo "You may need to restart your command shell if this is the first dotnet tool you have installed." + if [ -z "$toolpath" ]; then + echo $($dotnet_root/dotnet tool install $darc_cli_package_name --version $darcVersion --add-source "$arcadeServicesSource" -v $verbosity -g) + else + echo $($dotnet_root/dotnet tool install $darc_cli_package_name --version $darcVersion --add-source "$arcadeServicesSource" -v $verbosity --tool-path "$toolpath") + fi +} + +InstallDarcCli diff --git a/eng/common/dotnet-install.cmd b/eng/common/dotnet-install.cmd new file mode 100644 index 000000000..b1c2642e7 --- /dev/null +++ b/eng/common/dotnet-install.cmd @@ -0,0 +1,2 @@ +@echo off +powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0dotnet-install.ps1""" %*" \ No newline at end of file diff --git a/eng/common/dotnet-install.ps1 b/eng/common/dotnet-install.ps1 new file mode 100644 index 000000000..811f0f717 --- /dev/null +++ b/eng/common/dotnet-install.ps1 @@ -0,0 +1,28 @@ +[CmdletBinding(PositionalBinding=$false)] +Param( + [string] $verbosity = 'minimal', + [string] $architecture = '', + [string] $version = 'Latest', + [string] $runtime = 'dotnet', + [string] $RuntimeSourceFeed = '', + [string] $RuntimeSourceFeedKey = '' +) + +. $PSScriptRoot\tools.ps1 + +$dotnetRoot = Join-Path $RepoRoot '.dotnet' + +$installdir = $dotnetRoot +try { + if ($architecture -and $architecture.Trim() -eq 'x86') { + $installdir = Join-Path $installdir 'x86' + } + InstallDotNet $installdir $version $architecture $runtime $true -RuntimeSourceFeed $RuntimeSourceFeed -RuntimeSourceFeedKey $RuntimeSourceFeedKey +} +catch { + Write-Host $_.ScriptStackTrace + Write-PipelineTelemetryError -Category 'InitializeToolset' -Message $_ + ExitWithExitCode 1 +} + +ExitWithExitCode 0 diff --git a/eng/common/dotnet-install.sh b/eng/common/dotnet-install.sh new file mode 100644 index 000000000..5c94e9863 --- /dev/null +++ b/eng/common/dotnet-install.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash + +source="${BASH_SOURCE[0]}" +# resolve $source until the file is no longer a symlink +while [[ -h "$source" ]]; do + scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + source="$(readlink "$source")" + # if $source was a relative symlink, we need to resolve it relative to the path where the + # symlink file was located + [[ $source != /* ]] && source="$scriptroot/$source" +done +scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + +. "$scriptroot/tools.sh" + +version='Latest' +architecture='' +runtime='dotnet' +runtimeSourceFeed='' +runtimeSourceFeedKey='' +while [[ $# > 0 ]]; do + opt="$(echo "$1" | tr "[:upper:]" "[:lower:]")" + case "$opt" in + -version|-v) + shift + version="$1" + ;; + -architecture|-a) + shift + architecture="$1" + ;; + -runtime|-r) + shift + runtime="$1" + ;; + -runtimesourcefeed) + shift + runtimeSourceFeed="$1" + ;; + -runtimesourcefeedkey) + shift + runtimeSourceFeedKey="$1" + ;; + *) + Write-PipelineTelemetryError -Category 'Build' -Message "Invalid argument: $1" + exit 1 + ;; + esac + shift +done + +# Use uname to determine what the CPU is, see https://en.wikipedia.org/wiki/Uname#Examples +cpuname=$(uname -m) +case $cpuname in + aarch64) + buildarch=arm64 + ;; + loongarch64) + buildarch=loongarch64 + ;; + amd64|x86_64) + buildarch=x64 + ;; + armv*l) + buildarch=arm + ;; + i686) + buildarch=x86 + ;; + *) + echo "Unknown CPU $cpuname detected, treating it as x64" + buildarch=x64 + ;; +esac + +dotnetRoot="${repo_root}.dotnet" +if [[ $architecture != "" ]] && [[ $architecture != $buildarch ]]; then + dotnetRoot="$dotnetRoot/$architecture" +fi + +InstallDotNet $dotnetRoot $version "$architecture" $runtime true $runtimeSourceFeed $runtimeSourceFeedKey || { + local exit_code=$? + Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "dotnet-install.sh failed (exit code '$exit_code')." >&2 + ExitWithExitCode $exit_code +} + +ExitWithExitCode 0 diff --git a/eng/common/enable-cross-org-publishing.ps1 b/eng/common/enable-cross-org-publishing.ps1 new file mode 100644 index 000000000..da09da4f1 --- /dev/null +++ b/eng/common/enable-cross-org-publishing.ps1 @@ -0,0 +1,13 @@ +param( + [string] $token +) + + +. $PSScriptRoot\pipeline-logging-functions.ps1 + +# Write-PipelineSetVariable will no-op if a variable named $ci is not defined +# Since this script is only ever called in AzDO builds, just universally set it +$ci = $true + +Write-PipelineSetVariable -Name 'VSS_NUGET_ACCESSTOKEN' -Value $token -IsMultiJobVariable $false +Write-PipelineSetVariable -Name 'VSS_NUGET_URI_PREFIXES' -Value 'https://dnceng.pkgs.visualstudio.com/;https://pkgs.dev.azure.com/dnceng/;https://devdiv.pkgs.visualstudio.com/;https://pkgs.dev.azure.com/devdiv/' -IsMultiJobVariable $false diff --git a/eng/common/generate-locproject.ps1 b/eng/common/generate-locproject.ps1 new file mode 100644 index 000000000..25e97ac00 --- /dev/null +++ b/eng/common/generate-locproject.ps1 @@ -0,0 +1,117 @@ +Param( + [Parameter(Mandatory=$true)][string] $SourcesDirectory, # Directory where source files live; if using a Localize directory it should live in here + [string] $LanguageSet = 'VS_Main_Languages', # Language set to be used in the LocProject.json + [switch] $UseCheckedInLocProjectJson, # When set, generates a LocProject.json and compares it to one that already exists in the repo; otherwise just generates one + [switch] $CreateNeutralXlfs # Creates neutral xlf files. Only set to false when running locally +) + +# Generates LocProject.json files for the OneLocBuild task. OneLocBuildTask is described here: +# https://ceapex.visualstudio.com/CEINTL/_wiki/wikis/CEINTL.wiki/107/Localization-with-OneLocBuild-Task + +Set-StrictMode -Version 2.0 +$ErrorActionPreference = "Stop" +. $PSScriptRoot\tools.ps1 + +Import-Module -Name (Join-Path $PSScriptRoot 'native\CommonLibrary.psm1') + +$exclusionsFilePath = "$SourcesDirectory\eng\Localize\LocExclusions.json" +$exclusions = @{ Exclusions = @() } +if (Test-Path -Path $exclusionsFilePath) +{ + $exclusions = Get-Content "$exclusionsFilePath" | ConvertFrom-Json +} + +Push-Location "$SourcesDirectory" # push location for Resolve-Path -Relative to work + +# Template files +$jsonFiles = @() +$jsonTemplateFiles = Get-ChildItem -Recurse -Path "$SourcesDirectory" | Where-Object { $_.FullName -Match "\.template\.config\\localize\\.+\.en\.json" } # .NET templating pattern +$jsonTemplateFiles | ForEach-Object { + $null = $_.Name -Match "(.+)\.[\w-]+\.json" # matches '[filename].[langcode].json + + $destinationFile = "$($_.Directory.FullName)\$($Matches.1).json" + $jsonFiles += Copy-Item "$($_.FullName)" -Destination $destinationFile -PassThru +} + +$jsonWinformsTemplateFiles = Get-ChildItem -Recurse -Path "$SourcesDirectory" | Where-Object { $_.FullName -Match "en\\strings\.json" } # current winforms pattern + +$xlfFiles = @() + +$allXlfFiles = Get-ChildItem -Recurse -Path "$SourcesDirectory\*\*.xlf" +$langXlfFiles = @() +if ($allXlfFiles) { + $null = $allXlfFiles[0].FullName -Match "\.([\w-]+)\.xlf" # matches '[langcode].xlf' + $firstLangCode = $Matches.1 + $langXlfFiles = Get-ChildItem -Recurse -Path "$SourcesDirectory\*\*.$firstLangCode.xlf" +} +$langXlfFiles | ForEach-Object { + $null = $_.Name -Match "(.+)\.[\w-]+\.xlf" # matches '[filename].[langcode].xlf + + $destinationFile = "$($_.Directory.FullName)\$($Matches.1).xlf" + $xlfFiles += Copy-Item "$($_.FullName)" -Destination $destinationFile -PassThru +} + +$locFiles = $jsonFiles + $jsonWinformsTemplateFiles + $xlfFiles + +$locJson = @{ + Projects = @( + @{ + LanguageSet = $LanguageSet + LocItems = @( + $locFiles | ForEach-Object { + $outputPath = "$(($_.DirectoryName | Resolve-Path -Relative) + "\")" + $continue = $true + foreach ($exclusion in $exclusions.Exclusions) { + if ($outputPath.Contains($exclusion)) + { + $continue = $false + } + } + $sourceFile = ($_.FullName | Resolve-Path -Relative) + if (!$CreateNeutralXlfs -and $_.Extension -eq '.xlf') { + Remove-Item -Path $sourceFile + } + if ($continue) + { + if ($_.Directory.Name -eq 'en' -and $_.Extension -eq '.json') { + return @{ + SourceFile = $sourceFile + CopyOption = "LangIDOnPath" + OutputPath = "$($_.Directory.Parent.FullName | Resolve-Path -Relative)\" + } + } + else { + return @{ + SourceFile = $sourceFile + CopyOption = "LangIDOnName" + OutputPath = $outputPath + } + } + } + } + ) + } + ) +} + +$json = ConvertTo-Json $locJson -Depth 5 +Write-Host "LocProject.json generated:`n`n$json`n`n" +Pop-Location + +if (!$UseCheckedInLocProjectJson) { + New-Item "$SourcesDirectory\eng\Localize\LocProject.json" -Force # Need this to make sure the Localize directory is created + Set-Content "$SourcesDirectory\eng\Localize\LocProject.json" $json +} +else { + New-Item "$SourcesDirectory\eng\Localize\LocProject-generated.json" -Force # Need this to make sure the Localize directory is created + Set-Content "$SourcesDirectory\eng\Localize\LocProject-generated.json" $json + + if ((Get-FileHash "$SourcesDirectory\eng\Localize\LocProject-generated.json").Hash -ne (Get-FileHash "$SourcesDirectory\eng\Localize\LocProject.json").Hash) { + Write-PipelineTelemetryError -Category "OneLocBuild" -Message "Existing LocProject.json differs from generated LocProject.json. Download LocProject-generated.json and compare them." + + exit 1 + } + else { + Write-Host "Generated LocProject.json and current LocProject.json are identical." + } +} \ No newline at end of file diff --git a/eng/common/generate-sbom-prep.ps1 b/eng/common/generate-sbom-prep.ps1 new file mode 100644 index 000000000..a733a8885 --- /dev/null +++ b/eng/common/generate-sbom-prep.ps1 @@ -0,0 +1,19 @@ +Param( + [Parameter(Mandatory=$true)][string] $ManifestDirPath # Manifest directory where sbom will be placed +) + +Write-Host "Creating dir $ManifestDirPath" +# create directory for sbom manifest to be placed +if (!(Test-Path -path $ManifestDirPath)) +{ + New-Item -ItemType Directory -path $ManifestDirPath + Write-Host "Successfully created directory $ManifestDirPath" +} +else{ + Write-PipelineTelemetryError -category 'Build' "Unable to create sbom folder." +} + +Write-Host "Updating artifact name" +$artifact_name = "${env:SYSTEM_STAGENAME}_${env:AGENT_JOBNAME}_SBOM" -replace '["/:<>\\|?@*"() ]', '_' +Write-Host "Artifact name $artifact_name" +Write-Host "##vso[task.setvariable variable=ARTIFACT_NAME]$artifact_name" diff --git a/eng/common/generate-sbom-prep.sh b/eng/common/generate-sbom-prep.sh new file mode 100644 index 000000000..f6c774531 --- /dev/null +++ b/eng/common/generate-sbom-prep.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +source="${BASH_SOURCE[0]}" + +manifest_dir=$1 + +if [ ! -d "$manifest_dir" ] ; then + mkdir -p "$manifest_dir" + echo "Sbom directory created." $manifest_dir +else + Write-PipelineTelemetryError -category 'Build' "Unable to create sbom folder." +fi + +artifact_name=$SYSTEM_STAGENAME"_"$AGENT_JOBNAME"_SBOM" +echo "Artifact name before : "$artifact_name +# replace all special characters with _, some builds use special characters like : in Agent.Jobname, that is not a permissible name while uploading artifacts. +safe_artifact_name="${artifact_name//["/:<>\\|?@*$" ]/_}" +echo "Artifact name after : "$safe_artifact_name +export ARTIFACT_NAME=$safe_artifact_name +echo "##vso[task.setvariable variable=ARTIFACT_NAME]$safe_artifact_name" + +exit 0 diff --git a/eng/common/helixpublish.proj b/eng/common/helixpublish.proj new file mode 100644 index 000000000..d7f185856 --- /dev/null +++ b/eng/common/helixpublish.proj @@ -0,0 +1,26 @@ + + + + msbuild + + + + + %(Identity) + + + + + + $(WorkItemDirectory) + $(WorkItemCommand) + $(WorkItemTimeout) + + + + + + + + + diff --git a/eng/common/init-tools-native.cmd b/eng/common/init-tools-native.cmd new file mode 100644 index 000000000..438cd548c --- /dev/null +++ b/eng/common/init-tools-native.cmd @@ -0,0 +1,3 @@ +@echo off +powershell -NoProfile -NoLogo -ExecutionPolicy ByPass -command "& """%~dp0init-tools-native.ps1""" %*" +exit /b %ErrorLevel% \ No newline at end of file diff --git a/eng/common/init-tools-native.ps1 b/eng/common/init-tools-native.ps1 new file mode 100644 index 000000000..db830c00a --- /dev/null +++ b/eng/common/init-tools-native.ps1 @@ -0,0 +1,152 @@ +<# +.SYNOPSIS +Entry point script for installing native tools + +.DESCRIPTION +Reads $RepoRoot\global.json file to determine native assets to install +and executes installers for those tools + +.PARAMETER BaseUri +Base file directory or Url from which to acquire tool archives + +.PARAMETER InstallDirectory +Directory to install native toolset. This is a command-line override for the default +Install directory precedence order: +- InstallDirectory command-line override +- NETCOREENG_INSTALL_DIRECTORY environment variable +- (default) %USERPROFILE%/.netcoreeng/native + +.PARAMETER Clean +Switch specifying to not install anything, but cleanup native asset folders + +.PARAMETER Force +Clean and then install tools + +.PARAMETER DownloadRetries +Total number of retry attempts + +.PARAMETER RetryWaitTimeInSeconds +Wait time between retry attempts in seconds + +.PARAMETER GlobalJsonFile +File path to global.json file + +.NOTES +#> +[CmdletBinding(PositionalBinding=$false)] +Param ( + [string] $BaseUri = 'https://netcorenativeassets.blob.core.windows.net/resource-packages/external', + [string] $InstallDirectory, + [switch] $Clean = $False, + [switch] $Force = $False, + [int] $DownloadRetries = 5, + [int] $RetryWaitTimeInSeconds = 30, + [string] $GlobalJsonFile +) + +if (!$GlobalJsonFile) { + $GlobalJsonFile = Join-Path (Get-Item $PSScriptRoot).Parent.Parent.FullName 'global.json' +} + +Set-StrictMode -version 2.0 +$ErrorActionPreference='Stop' + +. $PSScriptRoot\pipeline-logging-functions.ps1 +Import-Module -Name (Join-Path $PSScriptRoot 'native\CommonLibrary.psm1') + +try { + # Define verbose switch if undefined + $Verbose = $VerbosePreference -Eq 'Continue' + + $EngCommonBaseDir = Join-Path $PSScriptRoot 'native\' + $NativeBaseDir = $InstallDirectory + if (!$NativeBaseDir) { + $NativeBaseDir = CommonLibrary\Get-NativeInstallDirectory + } + $Env:CommonLibrary_NativeInstallDir = $NativeBaseDir + $InstallBin = Join-Path $NativeBaseDir 'bin' + $InstallerPath = Join-Path $EngCommonBaseDir 'install-tool.ps1' + + # Process tools list + Write-Host "Processing $GlobalJsonFile" + If (-Not (Test-Path $GlobalJsonFile)) { + Write-Host "Unable to find '$GlobalJsonFile'" + exit 0 + } + $NativeTools = Get-Content($GlobalJsonFile) -Raw | + ConvertFrom-Json | + Select-Object -Expand 'native-tools' -ErrorAction SilentlyContinue + if ($NativeTools) { + $NativeTools.PSObject.Properties | ForEach-Object { + $ToolName = $_.Name + $ToolVersion = $_.Value + $LocalInstallerArguments = @{ ToolName = "$ToolName" } + $LocalInstallerArguments += @{ InstallPath = "$InstallBin" } + $LocalInstallerArguments += @{ BaseUri = "$BaseUri" } + $LocalInstallerArguments += @{ CommonLibraryDirectory = "$EngCommonBaseDir" } + $LocalInstallerArguments += @{ Version = "$ToolVersion" } + + if ($Verbose) { + $LocalInstallerArguments += @{ Verbose = $True } + } + if (Get-Variable 'Force' -ErrorAction 'SilentlyContinue') { + if($Force) { + $LocalInstallerArguments += @{ Force = $True } + } + } + if ($Clean) { + $LocalInstallerArguments += @{ Clean = $True } + } + + Write-Verbose "Installing $ToolName version $ToolVersion" + Write-Verbose "Executing '$InstallerPath $($LocalInstallerArguments.Keys.ForEach({"-$_ '$($LocalInstallerArguments.$_)'"}) -join ' ')'" + & $InstallerPath @LocalInstallerArguments + if ($LASTEXITCODE -Ne "0") { + $errMsg = "$ToolName installation failed" + if ((Get-Variable 'DoNotAbortNativeToolsInstallationOnFailure' -ErrorAction 'SilentlyContinue') -and $DoNotAbortNativeToolsInstallationOnFailure) { + $showNativeToolsWarning = $true + if ((Get-Variable 'DoNotDisplayNativeToolsInstallationWarnings' -ErrorAction 'SilentlyContinue') -and $DoNotDisplayNativeToolsInstallationWarnings) { + $showNativeToolsWarning = $false + } + if ($showNativeToolsWarning) { + Write-Warning $errMsg + } + $toolInstallationFailure = $true + } else { + # We cannot change this to Write-PipelineTelemetryError because of https://github.com/dotnet/arcade/issues/4482 + Write-Host $errMsg + exit 1 + } + } + } + + if ((Get-Variable 'toolInstallationFailure' -ErrorAction 'SilentlyContinue') -and $toolInstallationFailure) { + # We cannot change this to Write-PipelineTelemetryError because of https://github.com/dotnet/arcade/issues/4482 + Write-Host 'Native tools bootstrap failed' + exit 1 + } + } + else { + Write-Host 'No native tools defined in global.json' + exit 0 + } + + if ($Clean) { + exit 0 + } + if (Test-Path $InstallBin) { + Write-Host 'Native tools are available from ' (Convert-Path -Path $InstallBin) + Write-Host "##vso[task.prependpath]$(Convert-Path -Path $InstallBin)" + return $InstallBin + } + else { + Write-PipelineTelemetryError -Category 'NativeToolsBootstrap' -Message 'Native tools install directory does not exist, installation failed' + exit 1 + } + exit 0 +} +catch { + Write-Host $_.ScriptStackTrace + Write-PipelineTelemetryError -Category 'NativeToolsBootstrap' -Message $_ + ExitWithExitCode 1 +} diff --git a/eng/common/init-tools-native.sh b/eng/common/init-tools-native.sh new file mode 100644 index 000000000..3e6a8d6ac --- /dev/null +++ b/eng/common/init-tools-native.sh @@ -0,0 +1,238 @@ +#!/usr/bin/env bash + +source="${BASH_SOURCE[0]}" +scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + +base_uri='https://netcorenativeassets.blob.core.windows.net/resource-packages/external' +install_directory='' +clean=false +force=false +download_retries=5 +retry_wait_time_seconds=30 +global_json_file="$(dirname "$(dirname "${scriptroot}")")/global.json" +declare -a native_assets + +. $scriptroot/pipeline-logging-functions.sh +. $scriptroot/native/common-library.sh + +while (($# > 0)); do + lowerI="$(echo $1 | tr "[:upper:]" "[:lower:]")" + case $lowerI in + --baseuri) + base_uri=$2 + shift 2 + ;; + --installdirectory) + install_directory=$2 + shift 2 + ;; + --clean) + clean=true + shift 1 + ;; + --force) + force=true + shift 1 + ;; + --donotabortonfailure) + donotabortonfailure=true + shift 1 + ;; + --donotdisplaywarnings) + donotdisplaywarnings=true + shift 1 + ;; + --downloadretries) + download_retries=$2 + shift 2 + ;; + --retrywaittimeseconds) + retry_wait_time_seconds=$2 + shift 2 + ;; + --help) + echo "Common settings:" + echo " --installdirectory Directory to install native toolset." + echo " This is a command-line override for the default" + echo " Install directory precedence order:" + echo " - InstallDirectory command-line override" + echo " - NETCOREENG_INSTALL_DIRECTORY environment variable" + echo " - (default) %USERPROFILE%/.netcoreeng/native" + echo "" + echo " --clean Switch specifying not to install anything, but cleanup native asset folders" + echo " --donotabortonfailure Switch specifiying whether to abort native tools installation on failure" + echo " --donotdisplaywarnings Switch specifiying whether to display warnings during native tools installation on failure" + echo " --force Clean and then install tools" + echo " --help Print help and exit" + echo "" + echo "Advanced settings:" + echo " --baseuri Base URI for where to download native tools from" + echo " --downloadretries Number of times a download should be attempted" + echo " --retrywaittimeseconds Wait time between download attempts" + echo "" + exit 0 + ;; + esac +done + +function ReadGlobalJsonNativeTools { + # happy path: we have a proper JSON parsing tool `jq(1)` in PATH! + if command -v jq &> /dev/null; then + + # jq: read each key/value pair under "native-tools" entry and emit: + # KEY="" VALUE="" + # followed by a null byte. + # + # bash: read line with null byte delimeter and push to array (for later `eval`uation). + + while IFS= read -rd '' line; do + native_assets+=("$line") + done < <(jq -r '. | + select(has("native-tools")) | + ."native-tools" | + keys[] as $k | + @sh "KEY=\($k) VALUE=\(.[$k])\u0000"' "$global_json_file") + + return + fi + + # Warning: falling back to manually parsing JSON, which is not recommended. + + # Following routine matches the output and escaping logic of jq(1)'s @sh formatter used above. + # It has been tested with several weird strings with escaped characters in entries (key and value) + # and results were compared with the output of jq(1) in binary representation using xxd(1); + # just before the assignment to 'native_assets' array (above and below). + + # try to capture the section under "native-tools". + if [[ ! "$(cat "$global_json_file")" =~ \"native-tools\"[[:space:]\:\{]*([^\}]+) ]]; then + return + fi + + section="${BASH_REMATCH[1]}" + + parseStarted=0 + possibleEnd=0 + escaping=0 + escaped=0 + isKey=1 + + for (( i=0; i<${#section}; i++ )); do + char="${section:$i:1}" + if ! ((parseStarted)) && [[ "$char" =~ [[:space:],:] ]]; then continue; fi + + if ! ((escaping)) && [[ "$char" == "\\" ]]; then + escaping=1 + elif ((escaping)) && ! ((escaped)); then + escaped=1 + fi + + if ! ((parseStarted)) && [[ "$char" == "\"" ]]; then + parseStarted=1 + possibleEnd=0 + elif [[ "$char" == "'" ]]; then + token="$token'\\\''" + possibleEnd=0 + elif ((escaping)) || [[ "$char" != "\"" ]]; then + token="$token$char" + possibleEnd=1 + fi + + if ((possibleEnd)) && ! ((escaping)) && [[ "$char" == "\"" ]]; then + # Use printf to unescape token to match jq(1)'s @sh formatting rules. + # do not use 'token="$(printf "$token")"' syntax, as $() eats the trailing linefeed. + printf -v token "'$token'" + + if ((isKey)); then + KEY="$token" + isKey=0 + else + line="KEY=$KEY VALUE=$token" + native_assets+=("$line") + isKey=1 + fi + + # reset for next token + parseStarted=0 + token= + elif ((escaping)) && ((escaped)); then + escaping=0 + escaped=0 + fi + done +} + +native_base_dir=$install_directory +if [[ -z $install_directory ]]; then + native_base_dir=$(GetNativeInstallDirectory) +fi + +install_bin="${native_base_dir}/bin" +installed_any=false + +ReadGlobalJsonNativeTools + +if [[ ${#native_assets[@]} -eq 0 ]]; then + echo "No native tools defined in global.json" + exit 0; +else + native_installer_dir="$scriptroot/native" + for index in "${!native_assets[@]}"; do + eval "${native_assets["$index"]}" + + installer_path="$native_installer_dir/install-$KEY.sh" + installer_command="$installer_path" + installer_command+=" --baseuri $base_uri" + installer_command+=" --installpath $install_bin" + installer_command+=" --version $VALUE" + echo $installer_command + + if [[ $force = true ]]; then + installer_command+=" --force" + fi + + if [[ $clean = true ]]; then + installer_command+=" --clean" + fi + + if [[ -a $installer_path ]]; then + $installer_command + if [[ $? != 0 ]]; then + if [[ $donotabortonfailure = true ]]; then + if [[ $donotdisplaywarnings != true ]]; then + Write-PipelineTelemetryError -category 'NativeToolsBootstrap' "Execution Failed" + fi + else + Write-PipelineTelemetryError -category 'NativeToolsBootstrap' "Execution Failed" + exit 1 + fi + else + $installed_any = true + fi + else + if [[ $donotabortonfailure == true ]]; then + if [[ $donotdisplaywarnings != true ]]; then + Write-PipelineTelemetryError -category 'NativeToolsBootstrap' "Execution Failed: no install script" + fi + else + Write-PipelineTelemetryError -category 'NativeToolsBootstrap' "Execution Failed: no install script" + exit 1 + fi + fi + done +fi + +if [[ $clean = true ]]; then + exit 0 +fi + +if [[ -d $install_bin ]]; then + echo "Native tools are available from $install_bin" + echo "##vso[task.prependpath]$install_bin" +else + if [[ $installed_any = true ]]; then + Write-PipelineTelemetryError -category 'NativeToolsBootstrap' "Native tools install directory does not exist, installation failed" + exit 1 + fi +fi + +exit 0 diff --git a/eng/common/internal-feed-operations.ps1 b/eng/common/internal-feed-operations.ps1 new file mode 100644 index 000000000..92b77347d --- /dev/null +++ b/eng/common/internal-feed-operations.ps1 @@ -0,0 +1,132 @@ +param( + [Parameter(Mandatory=$true)][string] $Operation, + [string] $AuthToken, + [string] $CommitSha, + [string] $RepoName, + [switch] $IsFeedPrivate +) + +$ErrorActionPreference = 'Stop' +Set-StrictMode -Version 2.0 +. $PSScriptRoot\tools.ps1 + +# Sets VSS_NUGET_EXTERNAL_FEED_ENDPOINTS based on the "darc-int-*" feeds defined in NuGet.config. This is needed +# in build agents by CredProvider to authenticate the restore requests to internal feeds as specified in +# https://github.com/microsoft/artifacts-credprovider/blob/0f53327cd12fd893d8627d7b08a2171bf5852a41/README.md#environment-variables. This should ONLY be called from identified +# internal builds +function SetupCredProvider { + param( + [string] $AuthToken + ) + + # Install the Cred Provider NuGet plugin + Write-Host 'Setting up Cred Provider NuGet plugin in the agent...' + Write-Host "Getting 'installcredprovider.ps1' from 'https://github.com/microsoft/artifacts-credprovider'..." + + $url = 'https://raw.githubusercontent.com/microsoft/artifacts-credprovider/master/helpers/installcredprovider.ps1' + + Write-Host "Writing the contents of 'installcredprovider.ps1' locally..." + Invoke-WebRequest $url -OutFile installcredprovider.ps1 + + Write-Host 'Installing plugin...' + .\installcredprovider.ps1 -Force + + Write-Host "Deleting local copy of 'installcredprovider.ps1'..." + Remove-Item .\installcredprovider.ps1 + + if (-Not("$env:USERPROFILE\.nuget\plugins\netcore")) { + Write-PipelineTelemetryError -Category 'Arcade' -Message 'CredProvider plugin was not installed correctly!' + ExitWithExitCode 1 + } + else { + Write-Host 'CredProvider plugin was installed correctly!' + } + + # Then, we set the 'VSS_NUGET_EXTERNAL_FEED_ENDPOINTS' environment variable to restore from the stable + # feeds successfully + + $nugetConfigPath = Join-Path $RepoRoot "NuGet.config" + + if (-Not (Test-Path -Path $nugetConfigPath)) { + Write-PipelineTelemetryError -Category 'Build' -Message 'NuGet.config file not found in repo root!' + ExitWithExitCode 1 + } + + $endpoints = New-Object System.Collections.ArrayList + $nugetConfigPackageSources = Select-Xml -Path $nugetConfigPath -XPath "//packageSources/add[contains(@key, 'darc-int-')]/@value" | foreach{$_.Node.Value} + + if (($nugetConfigPackageSources | Measure-Object).Count -gt 0 ) { + foreach ($stableRestoreResource in $nugetConfigPackageSources) { + $trimmedResource = ([string]$stableRestoreResource).Trim() + [void]$endpoints.Add(@{endpoint="$trimmedResource"; password="$AuthToken"}) + } + } + + if (($endpoints | Measure-Object).Count -gt 0) { + $endpointCredentials = @{endpointCredentials=$endpoints} | ConvertTo-Json -Compress + + # Create the environment variables the AzDo way + Write-LoggingCommand -Area 'task' -Event 'setvariable' -Data $endpointCredentials -Properties @{ + 'variable' = 'VSS_NUGET_EXTERNAL_FEED_ENDPOINTS' + 'issecret' = 'false' + } + + # We don't want sessions cached since we will be updating the endpoints quite frequently + Write-LoggingCommand -Area 'task' -Event 'setvariable' -Data 'False' -Properties @{ + 'variable' = 'NUGET_CREDENTIALPROVIDER_SESSIONTOKENCACHE_ENABLED' + 'issecret' = 'false' + } + } + else + { + Write-Host 'No internal endpoints found in NuGet.config' + } +} + +#Workaround for https://github.com/microsoft/msbuild/issues/4430 +function InstallDotNetSdkAndRestoreArcade { + $dotnetTempDir = Join-Path $RepoRoot "dotnet" + $dotnetSdkVersion="2.1.507" # After experimentation we know this version works when restoring the SDK (compared to 3.0.*) + $dotnet = "$dotnetTempDir\dotnet.exe" + $restoreProjPath = "$PSScriptRoot\restore.proj" + + Write-Host "Installing dotnet SDK version $dotnetSdkVersion to restore Arcade SDK..." + InstallDotNetSdk "$dotnetTempDir" "$dotnetSdkVersion" + + '' | Out-File "$restoreProjPath" + + & $dotnet restore $restoreProjPath + + Write-Host 'Arcade SDK restored!' + + if (Test-Path -Path $restoreProjPath) { + Remove-Item $restoreProjPath + } + + if (Test-Path -Path $dotnetTempDir) { + Remove-Item $dotnetTempDir -Recurse + } +} + +try { + Push-Location $PSScriptRoot + + if ($Operation -like 'setup') { + SetupCredProvider $AuthToken + } + elseif ($Operation -like 'install-restore') { + InstallDotNetSdkAndRestoreArcade + } + else { + Write-PipelineTelemetryError -Category 'Arcade' -Message "Unknown operation '$Operation'!" + ExitWithExitCode 1 + } +} +catch { + Write-Host $_.ScriptStackTrace + Write-PipelineTelemetryError -Category 'Arcade' -Message $_ + ExitWithExitCode 1 +} +finally { + Pop-Location +} diff --git a/eng/common/internal-feed-operations.sh b/eng/common/internal-feed-operations.sh new file mode 100644 index 000000000..9378223ba --- /dev/null +++ b/eng/common/internal-feed-operations.sh @@ -0,0 +1,141 @@ +#!/usr/bin/env bash + +set -e + +# Sets VSS_NUGET_EXTERNAL_FEED_ENDPOINTS based on the "darc-int-*" feeds defined in NuGet.config. This is needed +# in build agents by CredProvider to authenticate the restore requests to internal feeds as specified in +# https://github.com/microsoft/artifacts-credprovider/blob/0f53327cd12fd893d8627d7b08a2171bf5852a41/README.md#environment-variables. +# This should ONLY be called from identified internal builds +function SetupCredProvider { + local authToken=$1 + + # Install the Cred Provider NuGet plugin + echo "Setting up Cred Provider NuGet plugin in the agent..."... + echo "Getting 'installcredprovider.ps1' from 'https://github.com/microsoft/artifacts-credprovider'..." + + local url="https://raw.githubusercontent.com/microsoft/artifacts-credprovider/master/helpers/installcredprovider.sh" + + echo "Writing the contents of 'installcredprovider.ps1' locally..." + local installcredproviderPath="installcredprovider.sh" + if command -v curl > /dev/null; then + curl $url > "$installcredproviderPath" + else + wget -q -O "$installcredproviderPath" "$url" + fi + + echo "Installing plugin..." + . "$installcredproviderPath" + + echo "Deleting local copy of 'installcredprovider.sh'..." + rm installcredprovider.sh + + if [ ! -d "$HOME/.nuget/plugins" ]; then + Write-PipelineTelemetryError -category 'Build' 'CredProvider plugin was not installed correctly!' + ExitWithExitCode 1 + else + echo "CredProvider plugin was installed correctly!" + fi + + # Then, we set the 'VSS_NUGET_EXTERNAL_FEED_ENDPOINTS' environment variable to restore from the stable + # feeds successfully + + local nugetConfigPath="{$repo_root}NuGet.config" + + if [ ! "$nugetConfigPath" ]; then + Write-PipelineTelemetryError -category 'Build' "NuGet.config file not found in repo's root!" + ExitWithExitCode 1 + fi + + local endpoints='[' + local nugetConfigPackageValues=`cat "$nugetConfigPath" | grep "key=\"darc-int-"` + local pattern="value=\"(.*)\"" + + for value in $nugetConfigPackageValues + do + if [[ $value =~ $pattern ]]; then + local endpoint="${BASH_REMATCH[1]}" + endpoints+="{\"endpoint\": \"$endpoint\", \"password\": \"$authToken\"}," + fi + done + + endpoints=${endpoints%?} + endpoints+=']' + + if [ ${#endpoints} -gt 2 ]; then + local endpointCredentials="{\"endpointCredentials\": "$endpoints"}" + + echo "##vso[task.setvariable variable=VSS_NUGET_EXTERNAL_FEED_ENDPOINTS]$endpointCredentials" + echo "##vso[task.setvariable variable=NUGET_CREDENTIALPROVIDER_SESSIONTOKENCACHE_ENABLED]False" + else + echo "No internal endpoints found in NuGet.config" + fi +} + +# Workaround for https://github.com/microsoft/msbuild/issues/4430 +function InstallDotNetSdkAndRestoreArcade { + local dotnetTempDir="$repo_root/dotnet" + local dotnetSdkVersion="2.1.507" # After experimentation we know this version works when restoring the SDK (compared to 3.0.*) + local restoreProjPath="$repo_root/eng/common/restore.proj" + + echo "Installing dotnet SDK version $dotnetSdkVersion to restore Arcade SDK..." + echo "" > "$restoreProjPath" + + InstallDotNetSdk "$dotnetTempDir" "$dotnetSdkVersion" + + local res=`$dotnetTempDir/dotnet restore $restoreProjPath` + echo "Arcade SDK restored!" + + # Cleanup + if [ "$restoreProjPath" ]; then + rm "$restoreProjPath" + fi + + if [ "$dotnetTempDir" ]; then + rm -r $dotnetTempDir + fi +} + +source="${BASH_SOURCE[0]}" +operation='' +authToken='' +repoName='' + +while [[ $# > 0 ]]; do + opt="$(echo "$1" | tr "[:upper:]" "[:lower:]")" + case "$opt" in + --operation) + operation=$2 + shift + ;; + --authtoken) + authToken=$2 + shift + ;; + *) + echo "Invalid argument: $1" + usage + exit 1 + ;; + esac + + shift +done + +while [[ -h "$source" ]]; do + scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + source="$(readlink "$source")" + # if $source was a relative symlink, we need to resolve it relative to the path where the + # symlink file was located + [[ $source != /* ]] && source="$scriptroot/$source" +done +scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + +. "$scriptroot/tools.sh" + +if [ "$operation" = "setup" ]; then + SetupCredProvider $authToken +elif [ "$operation" = "install-restore" ]; then + InstallDotNetSdkAndRestoreArcade +else + echo "Unknown operation '$operation'!" +fi diff --git a/eng/common/internal/Directory.Build.props b/eng/common/internal/Directory.Build.props new file mode 100644 index 000000000..dbf99d82a --- /dev/null +++ b/eng/common/internal/Directory.Build.props @@ -0,0 +1,4 @@ + + + + diff --git a/eng/common/internal/NuGet.config b/eng/common/internal/NuGet.config new file mode 100644 index 000000000..19d3d311b --- /dev/null +++ b/eng/common/internal/NuGet.config @@ -0,0 +1,7 @@ + + + + + + + diff --git a/eng/common/internal/Tools.csproj b/eng/common/internal/Tools.csproj new file mode 100644 index 000000000..beb9c4648 --- /dev/null +++ b/eng/common/internal/Tools.csproj @@ -0,0 +1,27 @@ + + + + net472 + false + false + + + + + + + + + + + https://devdiv.pkgs.visualstudio.com/_packaging/dotnet-core-internal-tooling/nuget/v3/index.json; + + + $(RestoreSources); + https://devdiv.pkgs.visualstudio.com/_packaging/VS/nuget/v3/index.json; + + + + + + diff --git a/eng/common/msbuild.ps1 b/eng/common/msbuild.ps1 new file mode 100644 index 000000000..f041e5ddd --- /dev/null +++ b/eng/common/msbuild.ps1 @@ -0,0 +1,28 @@ +[CmdletBinding(PositionalBinding=$false)] +Param( + [string] $verbosity = 'minimal', + [bool] $warnAsError = $true, + [bool] $nodeReuse = $true, + [switch] $ci, + [switch] $prepareMachine, + [switch] $excludePrereleaseVS, + [string] $msbuildEngine = $null, + [Parameter(ValueFromRemainingArguments=$true)][String[]]$extraArgs +) + +. $PSScriptRoot\tools.ps1 + +try { + if ($ci) { + $nodeReuse = $false + } + + MSBuild @extraArgs +} +catch { + Write-Host $_.ScriptStackTrace + Write-PipelineTelemetryError -Category 'Build' -Message $_ + ExitWithExitCode 1 +} + +ExitWithExitCode 0 \ No newline at end of file diff --git a/eng/common/msbuild.sh b/eng/common/msbuild.sh new file mode 100644 index 000000000..20d3dad54 --- /dev/null +++ b/eng/common/msbuild.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +source="${BASH_SOURCE[0]}" + +# resolve $source until the file is no longer a symlink +while [[ -h "$source" ]]; do + scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + source="$(readlink "$source")" + # if $source was a relative symlink, we need to resolve it relative to the path where the + # symlink file was located + [[ $source != /* ]] && source="$scriptroot/$source" +done +scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" + +verbosity='minimal' +warn_as_error=true +node_reuse=true +prepare_machine=false +extra_args='' + +while (($# > 0)); do + lowerI="$(echo $1 | tr "[:upper:]" "[:lower:]")" + case $lowerI in + --verbosity) + verbosity=$2 + shift 2 + ;; + --warnaserror) + warn_as_error=$2 + shift 2 + ;; + --nodereuse) + node_reuse=$2 + shift 2 + ;; + --ci) + ci=true + shift 1 + ;; + --preparemachine) + prepare_machine=true + shift 1 + ;; + *) + extra_args="$extra_args $1" + shift 1 + ;; + esac +done + +. "$scriptroot/tools.sh" + +if [[ "$ci" == true ]]; then + node_reuse=false +fi + +MSBuild $extra_args +ExitWithExitCode 0 diff --git a/eng/common/native/CommonLibrary.psm1 b/eng/common/native/CommonLibrary.psm1 new file mode 100644 index 000000000..ca38268c4 --- /dev/null +++ b/eng/common/native/CommonLibrary.psm1 @@ -0,0 +1,400 @@ +<# +.SYNOPSIS +Helper module to install an archive to a directory + +.DESCRIPTION +Helper module to download and extract an archive to a specified directory + +.PARAMETER Uri +Uri of artifact to download + +.PARAMETER InstallDirectory +Directory to extract artifact contents to + +.PARAMETER Force +Force download / extraction if file or contents already exist. Default = False + +.PARAMETER DownloadRetries +Total number of retry attempts. Default = 5 + +.PARAMETER RetryWaitTimeInSeconds +Wait time between retry attempts in seconds. Default = 30 + +.NOTES +Returns False if download or extraction fail, True otherwise +#> +function DownloadAndExtract { + [CmdletBinding(PositionalBinding=$false)] + Param ( + [Parameter(Mandatory=$True)] + [string] $Uri, + [Parameter(Mandatory=$True)] + [string] $InstallDirectory, + [switch] $Force = $False, + [int] $DownloadRetries = 5, + [int] $RetryWaitTimeInSeconds = 30 + ) + # Define verbose switch if undefined + $Verbose = $VerbosePreference -Eq "Continue" + + $TempToolPath = CommonLibrary\Get-TempPathFilename -Path $Uri + + # Download native tool + $DownloadStatus = CommonLibrary\Get-File -Uri $Uri ` + -Path $TempToolPath ` + -DownloadRetries $DownloadRetries ` + -RetryWaitTimeInSeconds $RetryWaitTimeInSeconds ` + -Force:$Force ` + -Verbose:$Verbose + + if ($DownloadStatus -Eq $False) { + Write-Error "Download failed from $Uri" + return $False + } + + # Extract native tool + $UnzipStatus = CommonLibrary\Expand-Zip -ZipPath $TempToolPath ` + -OutputDirectory $InstallDirectory ` + -Force:$Force ` + -Verbose:$Verbose + + if ($UnzipStatus -Eq $False) { + # Retry Download one more time with Force=true + $DownloadRetryStatus = CommonLibrary\Get-File -Uri $Uri ` + -Path $TempToolPath ` + -DownloadRetries 1 ` + -RetryWaitTimeInSeconds $RetryWaitTimeInSeconds ` + -Force:$True ` + -Verbose:$Verbose + + if ($DownloadRetryStatus -Eq $False) { + Write-Error "Last attempt of download failed as well" + return $False + } + + # Retry unzip again one more time with Force=true + $UnzipRetryStatus = CommonLibrary\Expand-Zip -ZipPath $TempToolPath ` + -OutputDirectory $InstallDirectory ` + -Force:$True ` + -Verbose:$Verbose + if ($UnzipRetryStatus -Eq $False) + { + Write-Error "Last attempt of unzip failed as well" + # Clean up partial zips and extracts + if (Test-Path $TempToolPath) { + Remove-Item $TempToolPath -Force + } + if (Test-Path $InstallDirectory) { + Remove-Item $InstallDirectory -Force -Recurse + } + return $False + } + } + + return $True +} + +<# +.SYNOPSIS +Download a file, retry on failure + +.DESCRIPTION +Download specified file and retry if attempt fails + +.PARAMETER Uri +Uri of file to download. If Uri is a local path, the file will be copied instead of downloaded + +.PARAMETER Path +Path to download or copy uri file to + +.PARAMETER Force +Overwrite existing file if present. Default = False + +.PARAMETER DownloadRetries +Total number of retry attempts. Default = 5 + +.PARAMETER RetryWaitTimeInSeconds +Wait time between retry attempts in seconds Default = 30 + +#> +function Get-File { + [CmdletBinding(PositionalBinding=$false)] + Param ( + [Parameter(Mandatory=$True)] + [string] $Uri, + [Parameter(Mandatory=$True)] + [string] $Path, + [int] $DownloadRetries = 5, + [int] $RetryWaitTimeInSeconds = 30, + [switch] $Force = $False + ) + $Attempt = 0 + + if ($Force) { + if (Test-Path $Path) { + Remove-Item $Path -Force + } + } + if (Test-Path $Path) { + Write-Host "File '$Path' already exists, skipping download" + return $True + } + + $DownloadDirectory = Split-Path -ErrorAction Ignore -Path "$Path" -Parent + if (-Not (Test-Path $DownloadDirectory)) { + New-Item -path $DownloadDirectory -force -itemType "Directory" | Out-Null + } + + $TempPath = "$Path.tmp" + if (Test-Path -IsValid -Path $Uri) { + Write-Verbose "'$Uri' is a file path, copying temporarily to '$TempPath'" + Copy-Item -Path $Uri -Destination $TempPath + Write-Verbose "Moving temporary file to '$Path'" + Move-Item -Path $TempPath -Destination $Path + return $? + } + else { + Write-Verbose "Downloading $Uri" + # Don't display the console progress UI - it's a huge perf hit + $ProgressPreference = 'SilentlyContinue' + while($Attempt -Lt $DownloadRetries) + { + try { + Invoke-WebRequest -UseBasicParsing -Uri $Uri -OutFile $TempPath + Write-Verbose "Downloaded to temporary location '$TempPath'" + Move-Item -Path $TempPath -Destination $Path + Write-Verbose "Moved temporary file to '$Path'" + return $True + } + catch { + $Attempt++ + if ($Attempt -Lt $DownloadRetries) { + $AttemptsLeft = $DownloadRetries - $Attempt + Write-Warning "Download failed, $AttemptsLeft attempts remaining, will retry in $RetryWaitTimeInSeconds seconds" + Start-Sleep -Seconds $RetryWaitTimeInSeconds + } + else { + Write-Error $_ + Write-Error $_.Exception + } + } + } + } + + return $False +} + +<# +.SYNOPSIS +Generate a shim for a native tool + +.DESCRIPTION +Creates a wrapper script (shim) that passes arguments forward to native tool assembly + +.PARAMETER ShimName +The name of the shim + +.PARAMETER ShimDirectory +The directory where shims are stored + +.PARAMETER ToolFilePath +Path to file that shim forwards to + +.PARAMETER Force +Replace shim if already present. Default = False + +.NOTES +Returns $True if generating shim succeeds, $False otherwise +#> +function New-ScriptShim { + [CmdletBinding(PositionalBinding=$false)] + Param ( + [Parameter(Mandatory=$True)] + [string] $ShimName, + [Parameter(Mandatory=$True)] + [string] $ShimDirectory, + [Parameter(Mandatory=$True)] + [string] $ToolFilePath, + [Parameter(Mandatory=$True)] + [string] $BaseUri, + [switch] $Force + ) + try { + Write-Verbose "Generating '$ShimName' shim" + + if (-Not (Test-Path $ToolFilePath)){ + Write-Error "Specified tool file path '$ToolFilePath' does not exist" + return $False + } + + # WinShimmer is a small .NET Framework program that creates .exe shims to bootstrapped programs + # Many of the checks for installed programs expect a .exe extension for Windows tools, rather + # than a .bat or .cmd file. + # Source: https://github.com/dotnet/arcade/tree/master/src/WinShimmer + if (-Not (Test-Path "$ShimDirectory\WinShimmer\winshimmer.exe")) { + $InstallStatus = DownloadAndExtract -Uri "$BaseUri/windows/winshimmer/WinShimmer.zip" ` + -InstallDirectory $ShimDirectory\WinShimmer ` + -Force:$Force ` + -DownloadRetries 2 ` + -RetryWaitTimeInSeconds 5 ` + -Verbose:$Verbose + } + + if ((Test-Path (Join-Path $ShimDirectory "$ShimName.exe"))) { + Write-Host "$ShimName.exe already exists; replacing..." + Remove-Item (Join-Path $ShimDirectory "$ShimName.exe") + } + + & "$ShimDirectory\WinShimmer\winshimmer.exe" $ShimName $ToolFilePath $ShimDirectory + return $True + } + catch { + Write-Host $_ + Write-Host $_.Exception + return $False + } +} + +<# +.SYNOPSIS +Returns the machine architecture of the host machine + +.NOTES +Returns 'x64' on 64 bit machines + Returns 'x86' on 32 bit machines +#> +function Get-MachineArchitecture { + $ProcessorArchitecture = $Env:PROCESSOR_ARCHITECTURE + $ProcessorArchitectureW6432 = $Env:PROCESSOR_ARCHITEW6432 + if($ProcessorArchitecture -Eq "X86") + { + if(($ProcessorArchitectureW6432 -Eq "") -Or + ($ProcessorArchitectureW6432 -Eq "X86")) { + return "x86" + } + $ProcessorArchitecture = $ProcessorArchitectureW6432 + } + if (($ProcessorArchitecture -Eq "AMD64") -Or + ($ProcessorArchitecture -Eq "IA64") -Or + ($ProcessorArchitecture -Eq "ARM64") -Or + ($ProcessorArchitecture -Eq "LOONGARCH64")) { + return "x64" + } + return "x86" +} + +<# +.SYNOPSIS +Get the name of a temporary folder under the native install directory +#> +function Get-TempDirectory { + return Join-Path (Get-NativeInstallDirectory) "temp/" +} + +function Get-TempPathFilename { + [CmdletBinding(PositionalBinding=$false)] + Param ( + [Parameter(Mandatory=$True)] + [string] $Path + ) + $TempDir = CommonLibrary\Get-TempDirectory + $TempFilename = Split-Path $Path -leaf + $TempPath = Join-Path $TempDir $TempFilename + return $TempPath +} + +<# +.SYNOPSIS +Returns the base directory to use for native tool installation + +.NOTES +Returns the value of the NETCOREENG_INSTALL_DIRECTORY if that environment variable +is set, or otherwise returns an install directory under the %USERPROFILE% +#> +function Get-NativeInstallDirectory { + $InstallDir = $Env:NETCOREENG_INSTALL_DIRECTORY + if (!$InstallDir) { + $InstallDir = Join-Path $Env:USERPROFILE ".netcoreeng/native/" + } + return $InstallDir +} + +<# +.SYNOPSIS +Unzip an archive + +.DESCRIPTION +Powershell module to unzip an archive to a specified directory + +.PARAMETER ZipPath (Required) +Path to archive to unzip + +.PARAMETER OutputDirectory (Required) +Output directory for archive contents + +.PARAMETER Force +Overwrite output directory contents if they already exist + +.NOTES +- Returns True and does not perform an extraction if output directory already exists but Overwrite is not True. +- Returns True if unzip operation is successful +- Returns False if Overwrite is True and it is unable to remove contents of OutputDirectory +- Returns False if unable to extract zip archive +#> +function Expand-Zip { + [CmdletBinding(PositionalBinding=$false)] + Param ( + [Parameter(Mandatory=$True)] + [string] $ZipPath, + [Parameter(Mandatory=$True)] + [string] $OutputDirectory, + [switch] $Force + ) + + Write-Verbose "Extracting '$ZipPath' to '$OutputDirectory'" + try { + if ((Test-Path $OutputDirectory) -And (-Not $Force)) { + Write-Host "Directory '$OutputDirectory' already exists, skipping extract" + return $True + } + if (Test-Path $OutputDirectory) { + Write-Verbose "'Force' is 'True', but '$OutputDirectory' exists, removing directory" + Remove-Item $OutputDirectory -Force -Recurse + if ($? -Eq $False) { + Write-Error "Unable to remove '$OutputDirectory'" + return $False + } + } + + $TempOutputDirectory = Join-Path "$(Split-Path -Parent $OutputDirectory)" "$(Split-Path -Leaf $OutputDirectory).tmp" + if (Test-Path $TempOutputDirectory) { + Remove-Item $TempOutputDirectory -Force -Recurse + } + New-Item -Path $TempOutputDirectory -Force -ItemType "Directory" | Out-Null + + Add-Type -assembly "system.io.compression.filesystem" + [io.compression.zipfile]::ExtractToDirectory("$ZipPath", "$TempOutputDirectory") + if ($? -Eq $False) { + Write-Error "Unable to extract '$ZipPath'" + return $False + } + + Move-Item -Path $TempOutputDirectory -Destination $OutputDirectory + } + catch { + Write-Host $_ + Write-Host $_.Exception + + return $False + } + return $True +} + +export-modulemember -function DownloadAndExtract +export-modulemember -function Expand-Zip +export-modulemember -function Get-File +export-modulemember -function Get-MachineArchitecture +export-modulemember -function Get-NativeInstallDirectory +export-modulemember -function Get-TempDirectory +export-modulemember -function Get-TempPathFilename +export-modulemember -function New-ScriptShim diff --git a/eng/common/native/common-library.sh b/eng/common/native/common-library.sh new file mode 100644 index 000000000..080c2c283 --- /dev/null +++ b/eng/common/native/common-library.sh @@ -0,0 +1,172 @@ +#!/usr/bin/env bash + +function GetNativeInstallDirectory { + local install_dir + + if [[ -z $NETCOREENG_INSTALL_DIRECTORY ]]; then + install_dir=$HOME/.netcoreeng/native/ + else + install_dir=$NETCOREENG_INSTALL_DIRECTORY + fi + + echo $install_dir + return 0 +} + +function GetTempDirectory { + + echo $(GetNativeInstallDirectory)temp/ + return 0 +} + +function ExpandZip { + local zip_path=$1 + local output_directory=$2 + local force=${3:-false} + + echo "Extracting $zip_path to $output_directory" + if [[ -d $output_directory ]] && [[ $force = false ]]; then + echo "Directory '$output_directory' already exists, skipping extract" + return 0 + fi + + if [[ -d $output_directory ]]; then + echo "'Force flag enabled, but '$output_directory' exists. Removing directory" + rm -rf $output_directory + if [[ $? != 0 ]]; then + Write-PipelineTelemetryError -category 'NativeToolsBootstrap' "Unable to remove '$output_directory'" + return 1 + fi + fi + + echo "Creating directory: '$output_directory'" + mkdir -p $output_directory + + echo "Extracting archive" + tar -xf $zip_path -C $output_directory + if [[ $? != 0 ]]; then + Write-PipelineTelemetryError -category 'NativeToolsBootstrap' "Unable to extract '$zip_path'" + return 1 + fi + + return 0 +} + +function GetCurrentOS { + local unameOut="$(uname -s)" + case $unameOut in + Linux*) echo "Linux";; + Darwin*) echo "MacOS";; + esac + return 0 +} + +function GetFile { + local uri=$1 + local path=$2 + local force=${3:-false} + local download_retries=${4:-5} + local retry_wait_time_seconds=${5:-30} + + if [[ -f $path ]]; then + if [[ $force = false ]]; then + echo "File '$path' already exists. Skipping download" + return 0 + else + rm -rf $path + fi + fi + + if [[ -f $uri ]]; then + echo "'$uri' is a file path, copying file to '$path'" + cp $uri $path + return $? + fi + + echo "Downloading $uri" + # Use curl if available, otherwise use wget + if command -v curl > /dev/null; then + curl "$uri" -sSL --retry $download_retries --retry-delay $retry_wait_time_seconds --create-dirs -o "$path" --fail + else + wget -q -O "$path" "$uri" --tries="$download_retries" + fi + + return $? +} + +function GetTempPathFileName { + local path=$1 + + local temp_dir=$(GetTempDirectory) + local temp_file_name=$(basename $path) + echo $temp_dir$temp_file_name + return 0 +} + +function DownloadAndExtract { + local uri=$1 + local installDir=$2 + local force=${3:-false} + local download_retries=${4:-5} + local retry_wait_time_seconds=${5:-30} + + local temp_tool_path=$(GetTempPathFileName $uri) + + echo "downloading to: $temp_tool_path" + + # Download file + GetFile "$uri" "$temp_tool_path" $force $download_retries $retry_wait_time_seconds + if [[ $? != 0 ]]; then + Write-PipelineTelemetryError -category 'NativeToolsBootstrap' "Failed to download '$uri' to '$temp_tool_path'." + return 1 + fi + + # Extract File + echo "extracting from $temp_tool_path to $installDir" + ExpandZip "$temp_tool_path" "$installDir" $force $download_retries $retry_wait_time_seconds + if [[ $? != 0 ]]; then + Write-PipelineTelemetryError -category 'NativeToolsBootstrap' "Failed to extract '$temp_tool_path' to '$installDir'." + return 1 + fi + + return 0 +} + +function NewScriptShim { + local shimpath=$1 + local tool_file_path=$2 + local force=${3:-false} + + echo "Generating '$shimpath' shim" + if [[ -f $shimpath ]]; then + if [[ $force = false ]]; then + echo "File '$shimpath' already exists." >&2 + return 1 + else + rm -rf $shimpath + fi + fi + + if [[ ! -f $tool_file_path ]]; then + # try to see if the path is lower cased + tool_file_path="$(echo $tool_file_path | tr "[:upper:]" "[:lower:]")" + if [[ ! -f $tool_file_path ]]; then + Write-PipelineTelemetryError -category 'NativeToolsBootstrap' "Specified tool file path:'$tool_file_path' does not exist" + return 1 + fi + fi + + local shim_contents=$'#!/usr/bin/env bash\n' + shim_contents+="SHIMARGS="$'$1\n' + shim_contents+="$tool_file_path"$' $SHIMARGS\n' + + # Write shim file + echo "$shim_contents" > $shimpath + + chmod +x $shimpath + + echo "Finished generating shim '$shimpath'" + + return $? +} + diff --git a/eng/common/native/init-compiler.sh b/eng/common/native/init-compiler.sh new file mode 100644 index 000000000..6d7ba15e5 --- /dev/null +++ b/eng/common/native/init-compiler.sh @@ -0,0 +1,144 @@ +#!/usr/bin/env bash +# +# This file detects the C/C++ compiler and exports it to the CC/CXX environment variables +# +# NOTE: some scripts source this file and rely on stdout being empty, make sure to not output anything here! + +if [[ "$#" -lt 3 ]]; then + echo "Usage..." + echo "init-compiler.sh