diff --git a/go.mod b/go.mod index c1704482e..35c7fcfb4 100644 --- a/go.mod +++ b/go.mod @@ -1,12 +1,13 @@ module github.com/terraform-providers/terraform-provider-azuread require ( - github.com/Azure/azure-sdk-for-go v45.0.0+incompatible - github.com/Azure/go-autorest/autorest v0.11.3 + github.com/Azure/azure-sdk-for-go v47.1.0+incompatible + github.com/Azure/go-autorest/autorest v0.11.10 github.com/Azure/go-autorest/autorest/date v0.3.0 github.com/google/uuid v1.1.1 - github.com/hashicorp/go-azure-helpers v0.12.0 + github.com/hashicorp/go-azure-helpers v0.13.0 github.com/hashicorp/go-uuid v1.0.1 + github.com/hashicorp/go-version v1.2.1 // indirect github.com/hashicorp/terraform-plugin-sdk v1.6.0 ) diff --git a/go.sum b/go.sum index ebb35afa8..9e53e8dd5 100644 --- a/go.sum +++ b/go.sum @@ -9,18 +9,27 @@ cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbf cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= github.com/Azure/azure-sdk-for-go v45.0.0+incompatible h1:/bZYPaJLCqXeCqQqEeEIQg/p7RNafOhaVFhC6IWxZ/8= github.com/Azure/azure-sdk-for-go v45.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v47.1.0+incompatible h1:D6MsWmsxF+pEjN/yZDyKXoUrsamdBdTlPedIgBlvVx4= +github.com/Azure/azure-sdk-for-go v47.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.11.3 h1:fyYnmYujkIXUgv88D9/Wo2ybE4Zwd/TmQd5sSI5u2Ws= github.com/Azure/go-autorest/autorest v0.11.3/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= +github.com/Azure/go-autorest/autorest v0.11.10 h1:j5sGbX7uj1ieYYkQ3Mpvewd4DCsEQ+ZeJpqnSM9pjnM= +github.com/Azure/go-autorest/autorest v0.11.10/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= github.com/Azure/go-autorest/autorest/adal v0.9.0 h1:SigMbuFNuKgc1xcGhaeapbh+8fgsu+GxgDRFyg7f5lM= github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= +github.com/Azure/go-autorest/autorest/adal v0.9.5 h1:Y3bBUV4rTuxenJJs41HU3qmqsb+auo+a3Lz+PlJPpL0= +github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= github.com/Azure/go-autorest/autorest/azure/cli v0.4.0 h1:Ml+UCrnlKD+cJmSzrZ/RDcDw86NjkRUpnFh7V5JUhzU= github.com/Azure/go-autorest/autorest/azure/cli v0.4.0/go.mod h1:JljT387FplPzBA31vUcvsetLKF3pec5bdAxjVU4kI2s= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.2 h1:dMOmEJfkLKW/7JsokJqkyoYSgmR08hi9KrhjZb+JALY= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.2/go.mod h1:7qkJkT+j6b+hIpzMOwPChJhTqS8VbsqqgULzMNRugoM= github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= github.com/Azure/go-autorest/autorest/mocks v0.4.0 h1:z20OWOSG5aCye0HEkDp6TPmP17ZcfeMxPi6HnSALa8c= github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/to v0.4.0 h1:oXVqrxakqqV1UZdSazDOPOLvOIz+XA683u8EctwboHk= github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= github.com/Azure/go-autorest/autorest/validation v0.3.0 h1:3I9AAI63HfcLtphd9g39ruUwRI+Ca+z/f36KHPFRUss= @@ -63,6 +72,8 @@ github.com/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TR github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk= +github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= @@ -96,6 +107,10 @@ github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/U github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-azure-helpers v0.12.0 h1:7D0mFSyP3EfHu1ySubserIsnUWY87HMzzTWOB7ASwRU= github.com/hashicorp/go-azure-helpers v0.12.0/go.mod h1:Zc3v4DNeX6PDdy7NljlYpnrdac1++qNW0I4U+ofGwpg= +github.com/hashicorp/go-azure-helpers v0.13.0 h1:Gm1g5atSCHhQUoNGAotLB1o5mzg01RXi/zFQjDGGoiA= +github.com/hashicorp/go-azure-helpers v0.13.0/go.mod h1:NifBbLJtyUxdQrRVmIfr0VykEXZIlq3YfHFpFdyp7qY= +github.com/hashicorp/go-azure-helpers v0.13.1-0.20201118193114-9a87bedaab4e h1:HgaNYUTkyArNsOFYl0zULpJwBfQydcZ0J8zUZJzmf2s= +github.com/hashicorp/go-azure-helpers v0.13.1-0.20201118193114-9a87bedaab4e/go.mod h1:rNqsniDSSRU2jBJrrtXVNhgZChqrrfWyHKAmXFIOTZQ= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= @@ -115,6 +130,8 @@ github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= +github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -211,6 +228,9 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E= +golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= diff --git a/internal/clients/builder.go b/internal/clients/builder.go index f4d882e1e..a8256ed86 100644 --- a/internal/clients/builder.go +++ b/internal/clients/builder.go @@ -19,7 +19,7 @@ type ClientBuilder struct { // Build is a helper method which returns a fully instantiated *AadClient based on the auth Config's current settings. func (b *ClientBuilder) Build(ctx context.Context) (*AadClient, error) { - env, err := authentication.AzureEnvironmentByNameFromEndpoint(ctx, b.AuthConfig.MetadataURL, b.AuthConfig.Environment) + env, err := authentication.AzureEnvironmentByNameFromEndpoint(ctx, b.AuthConfig.MetadataHost, b.AuthConfig.Environment) if err != nil { return nil, err } @@ -36,7 +36,6 @@ func (b *ClientBuilder) Build(ctx context.Context) (*AadClient, error) { // client declarations: client := AadClient{ - SubscriptionID: b.AuthConfig.SubscriptionID, ClientID: b.AuthConfig.ClientID, ObjectID: objectID, TenantID: b.AuthConfig.TenantID, diff --git a/internal/clients/client.go b/internal/clients/client.go index 21b1b43e3..4272b58a2 100644 --- a/internal/clients/client.go +++ b/internal/clients/client.go @@ -13,7 +13,6 @@ type AadClient struct { // todo move this to an "Account" struct as in azurerm? ClientID string ObjectID string - SubscriptionID string TenantID string TerraformVersion string Environment azure.Environment diff --git a/internal/provider/provider.go b/internal/provider/provider.go index a0f64a69f..a2278495f 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -146,8 +146,7 @@ func providerConfigure(p *schema.Provider) schema.ConfigureFunc { ClientID: d.Get("client_id").(string), ClientSecret: d.Get("client_secret").(string), TenantID: d.Get("tenant_id").(string), - SubscriptionID: d.Get("tenant_id").(string), // TODO: delete in v1.1 - MetadataURL: d.Get("metadata_host").(string), + MetadataHost: d.Get("metadata_host").(string), Environment: d.Get("environment").(string), MsiEndpoint: d.Get("msi_endpoint").(string), ClientCertPassword: d.Get("client_certificate_password").(string), @@ -158,37 +157,34 @@ func providerConfigure(p *schema.Provider) schema.ConfigureFunc { SupportsClientSecretAuth: true, SupportsManagedServiceIdentity: d.Get("use_msi").(bool), SupportsAzureCliToken: true, - //TenantOnly: true, // TODO: enable in v1.1 + TenantOnly: true, } - config, err := builder.Build() - if err != nil { - return nil, fmt.Errorf("building AzureAD Client: %s", err) - } - - terraformVersion := p.TerraformVersion - if terraformVersion == "" { - // Terraform 0.12 introduced this field to the protocol - // We can therefore assume that if it's missing it's 0.10 or 0.11 - terraformVersion = "0.11+compatible" - } + return buildClient(p, builder) + } +} - clientBuilder := clients.ClientBuilder{ - AuthConfig: config, - TerraformVersion: terraformVersion, - } +func buildClient(p *schema.Provider, b *authentication.Builder) (*clients.AadClient, error) { + config, err := b.Build() + if err != nil { + return nil, fmt.Errorf("building AzureAD Client: %s", err) + } - client, err := clientBuilder.Build(p.StopContext()) - if err != nil { - return nil, err - } + clientBuilder := clients.ClientBuilder{ + AuthConfig: config, + TerraformVersion: p.TerraformVersion, + } - // replaces the context between tests - p.MetaReset = func() error { //nolint unparam - client.StopContext = p.StopContext() - return nil - } + client, err := clientBuilder.Build(p.StopContext()) + if err != nil { + return nil, err + } - return client, nil + // replaces the context between tests + p.MetaReset = func() error { //nolint unparam + client.StopContext = p.StopContext() + return nil } + + return client, nil } diff --git a/internal/provider/provider_test.go b/internal/provider/provider_test.go index 6a1be270c..bfc21614e 100644 --- a/internal/provider/provider_test.go +++ b/internal/provider/provider_test.go @@ -3,7 +3,9 @@ package provider import ( "testing" + "github.com/hashicorp/go-azure-helpers/authentication" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/terraform" ) func TestProvider(t *testing.T) { @@ -15,3 +17,52 @@ func TestProvider(t *testing.T) { func TestProvider_impl(t *testing.T) { var _ = AzureADProvider() } + +func TestAccProvider_cliAuth(t *testing.T) { + provider := AzureADProvider().(*schema.Provider) + provider.ConfigureFunc = func(d *schema.ResourceData) (interface{}, error) { + + // Support only Azure CLI authentication + builder := &authentication.Builder{ + TenantID: d.Get("tenant_id").(string), + MetadataHost: d.Get("metadata_host").(string), + Environment: d.Get("environment").(string), + SupportsAzureCliToken: true, + TenantOnly: true, + } + + return buildClient(provider, builder) + } + + err := provider.Configure(terraform.NewResourceConfigRaw(nil)) + if err != nil { + t.Fatalf("err: %s", err) + } +} + +func TestAccProvider_servicePrincipalAuth(t *testing.T) { + provider := AzureADProvider().(*schema.Provider) + provider.ConfigureFunc = func(d *schema.ResourceData) (interface{}, error) { + + // Support only Service Principal authentication (certificate or secret) + builder := &authentication.Builder{ + ClientID: d.Get("client_id").(string), + ClientSecret: d.Get("client_secret").(string), + TenantID: d.Get("tenant_id").(string), + MetadataHost: d.Get("metadata_host").(string), + Environment: d.Get("environment").(string), + ClientCertPassword: d.Get("client_certificate_password").(string), + ClientCertPath: d.Get("client_certificate_path").(string), + SupportsClientCertAuth: true, + SupportsClientSecretAuth: true, + TenantOnly: true, + } + + return buildClient(provider, builder) + } + + err := provider.Configure(terraform.NewResourceConfigRaw(nil)) + if err != nil { + t.Fatalf("err: %s", err) + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/version/version.go b/vendor/github.com/Azure/azure-sdk-for-go/version/version.go index 058279423..f064a9492 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/version/version.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/version/version.go @@ -18,4 +18,4 @@ package version // Changes may cause incorrect behavior and will be lost if the code is regenerated. // Number contains the semantic version of this SDK. -const Number = "v45.0.0" +const Number = "v47.1.0" diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go b/vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go index 914f8af5e..9daa4b58b 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go +++ b/vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go @@ -222,6 +222,10 @@ func CheckForUserCompletionWithContext(ctx context.Context, sender Sender, code case "code_expired": return nil, ErrDeviceCodeExpired default: + // return a more meaningful error message if available + if token.ErrorDescription != nil { + return nil, fmt.Errorf("%s %s: %s", logPrefix, *token.Error, *token.ErrorDescription) + } return nil, ErrDeviceGeneric } } diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/go.mod b/vendor/github.com/Azure/go-autorest/autorest/adal/go.mod index 02a3d39ff..abcc27d4c 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/go.mod +++ b/vendor/github.com/Azure/go-autorest/autorest/adal/go.mod @@ -5,8 +5,8 @@ go 1.12 require ( github.com/Azure/go-autorest v14.2.0+incompatible github.com/Azure/go-autorest/autorest/date v0.3.0 - github.com/Azure/go-autorest/autorest/mocks v0.4.0 + github.com/Azure/go-autorest/autorest/mocks v0.4.1 github.com/Azure/go-autorest/tracing v0.6.0 - github.com/dgrijalva/jwt-go v3.2.0+incompatible - golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 + github.com/form3tech-oss/jwt-go v3.2.2+incompatible + golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 ) diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/go.sum b/vendor/github.com/Azure/go-autorest/autorest/adal/go.sum index bbda1a9a9..9d55b0f59 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/go.sum +++ b/vendor/github.com/Azure/go-autorest/autorest/adal/go.sum @@ -2,16 +2,16 @@ github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.4.0 h1:z20OWOSG5aCye0HEkDp6TPmP17ZcfeMxPi6HnSALa8c= -github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/mocks v0.4.1 h1:K0laFcLE6VLTOwNgSxaGbUcLPuGXlNkbVvq4cW4nIHk= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= -github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk= +github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 h1:hb9wdF1z5waM+dSIICn1l0DkLVDT3hqhhQsDNUmHPRE= +golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/persist.go b/vendor/github.com/Azure/go-autorest/autorest/adal/persist.go index 9e15f2751..2a974a39b 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/persist.go +++ b/vendor/github.com/Azure/go-autorest/autorest/adal/persist.go @@ -15,11 +15,24 @@ package adal // limitations under the License. import ( + "crypto/rsa" + "crypto/x509" "encoding/json" + "errors" "fmt" "io/ioutil" "os" "path/filepath" + + "golang.org/x/crypto/pkcs12" +) + +var ( + // ErrMissingCertificate is returned when no local certificate is found in the provided PFX data. + ErrMissingCertificate = errors.New("adal: certificate missing") + + // ErrMissingPrivateKey is returned when no private key is found in the provided PFX data. + ErrMissingPrivateKey = errors.New("adal: private key missing") ) // LoadToken restores a Token object from a file located at 'path'. @@ -71,3 +84,52 @@ func SaveToken(path string, mode os.FileMode, token Token) error { } return nil } + +// DecodePfxCertificateData extracts the x509 certificate and RSA private key from the provided PFX data. +// The PFX data must contain a private key along with a certificate whose public key matches that of the +// private key or an error is returned. +// If the private key is not password protected pass the empty string for password. +func DecodePfxCertificateData(pfxData []byte, password string) (*x509.Certificate, *rsa.PrivateKey, error) { + blocks, err := pkcs12.ToPEM(pfxData, password) + if err != nil { + return nil, nil, err + } + // first extract the private key + var priv *rsa.PrivateKey + for _, block := range blocks { + if block.Type == "PRIVATE KEY" { + priv, err = x509.ParsePKCS1PrivateKey(block.Bytes) + if err != nil { + return nil, nil, err + } + break + } + } + if priv == nil { + return nil, nil, ErrMissingPrivateKey + } + // now find the certificate with the matching public key of our private key + var cert *x509.Certificate + for _, block := range blocks { + if block.Type == "CERTIFICATE" { + pcert, err := x509.ParseCertificate(block.Bytes) + if err != nil { + return nil, nil, err + } + certKey, ok := pcert.PublicKey.(*rsa.PublicKey) + if !ok { + // keep looking + continue + } + if priv.E == certKey.E && priv.N.Cmp(certKey.N) == 0 { + // found a match + cert = pcert + break + } + } + } + if cert == nil { + return nil, nil, ErrMissingCertificate + } + return cert, priv, nil +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/token.go b/vendor/github.com/Azure/go-autorest/autorest/adal/token.go index c026f7d12..b83f16a49 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/token.go +++ b/vendor/github.com/Azure/go-autorest/autorest/adal/token.go @@ -35,7 +35,7 @@ import ( "time" "github.com/Azure/go-autorest/autorest/date" - "github.com/dgrijalva/jwt-go" + "github.com/form3tech-oss/jwt-go" ) const ( @@ -62,6 +62,9 @@ const ( // msiEndpoint is the well known endpoint for getting MSI authentications tokens msiEndpoint = "http://169.254.169.254/metadata/identity/oauth2/token" + // the API version to use for the MSI endpoint + msiAPIVersion = "2018-02-01" + // the default number of attempts to refresh an MSI authentication token defaultMaxMSIRefreshAttempts = 5 @@ -70,6 +73,9 @@ const ( // asMSISecretEnv is the environment variable used to store the request secret on App Service and Functions asMSISecretEnv = "MSI_SECRET" + + // the API version to use for the App Service MSI endpoint + appServiceAPIVersion = "2017-09-01" ) // OAuthTokenProvider is an interface which should be implemented by an access token retriever @@ -354,6 +360,7 @@ type ServicePrincipalToken struct { customRefreshFunc TokenRefresh refreshCallbacks []TokenRefreshCallback // MaxMSIRefreshAttempts is the maximum number of attempts to refresh an MSI token. + // Settings this to a value less than 1 will use the default value. MaxMSIRefreshAttempts int } @@ -650,6 +657,8 @@ func GetMSIVMEndpoint() (string, error) { return msiEndpoint, nil } +// NOTE: this only indicates if the ASE environment credentials have been set +// which does not necessarily mean that the caller is authenticating via ASE! func isAppService() bool { _, asMSIEndpointEnvExists := os.LookupEnv(asMSIEndpointEnv) _, asMSISecretEnvExists := os.LookupEnv(asMSISecretEnv) @@ -678,16 +687,22 @@ func GetMSIEndpoint() (string, error) { // NewServicePrincipalTokenFromMSI creates a ServicePrincipalToken via the MSI VM Extension. // It will use the system assigned identity when creating the token. func NewServicePrincipalTokenFromMSI(msiEndpoint, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - return newServicePrincipalTokenFromMSI(msiEndpoint, resource, nil, callbacks...) + return newServicePrincipalTokenFromMSI(msiEndpoint, resource, nil, nil, callbacks...) } // NewServicePrincipalTokenFromMSIWithUserAssignedID creates a ServicePrincipalToken via the MSI VM Extension. -// It will use the specified user assigned identity when creating the token. +// It will use the clientID of specified user assigned identity when creating the token. func NewServicePrincipalTokenFromMSIWithUserAssignedID(msiEndpoint, resource string, userAssignedID string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - return newServicePrincipalTokenFromMSI(msiEndpoint, resource, &userAssignedID, callbacks...) + return newServicePrincipalTokenFromMSI(msiEndpoint, resource, &userAssignedID, nil, callbacks...) +} + +// NewServicePrincipalTokenFromMSIWithIdentityResourceID creates a ServicePrincipalToken via the MSI VM Extension. +// It will use the azure resource id of user assigned identity when creating the token. +func NewServicePrincipalTokenFromMSIWithIdentityResourceID(msiEndpoint, resource string, identityResourceID string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { + return newServicePrincipalTokenFromMSI(msiEndpoint, resource, nil, &identityResourceID, callbacks...) } -func newServicePrincipalTokenFromMSI(msiEndpoint, resource string, userAssignedID *string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { +func newServicePrincipalTokenFromMSI(msiEndpoint, resource string, userAssignedID *string, identityResourceID *string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { if err := validateStringParam(msiEndpoint, "msiEndpoint"); err != nil { return nil, err } @@ -699,6 +714,11 @@ func newServicePrincipalTokenFromMSI(msiEndpoint, resource string, userAssignedI return nil, err } } + if identityResourceID != nil { + if err := validateStringParam(*identityResourceID, "identityResourceID"); err != nil { + return nil, err + } + } // We set the oauth config token endpoint to be MSI's endpoint msiEndpointURL, err := url.Parse(msiEndpoint) if err != nil { @@ -709,13 +729,16 @@ func newServicePrincipalTokenFromMSI(msiEndpoint, resource string, userAssignedI v.Set("resource", resource) // App Service MSI currently only supports token API version 2017-09-01 if isAppService() { - v.Set("api-version", "2017-09-01") + v.Set("api-version", appServiceAPIVersion) } else { - v.Set("api-version", "2018-02-01") + v.Set("api-version", msiAPIVersion) } if userAssignedID != nil { v.Set("client_id", *userAssignedID) } + if identityResourceID != nil { + v.Set("mi_res_id", *identityResourceID) + } msiEndpointURL.RawQuery = v.Encode() spt := &ServicePrincipalToken{ @@ -836,11 +859,28 @@ func (spt *ServicePrincipalToken) getGrantType() string { } func isIMDS(u url.URL) bool { - imds, err := url.Parse(msiEndpoint) + return isMSIEndpoint(u) == true || isASEEndpoint(u) == true +} + +func isMSIEndpoint(endpoint url.URL) bool { + msi, err := url.Parse(msiEndpoint) if err != nil { return false } - return (u.Host == imds.Host && u.Path == imds.Path) || isAppService() + return endpoint.Host == msi.Host && endpoint.Path == msi.Path +} + +func isASEEndpoint(endpoint url.URL) bool { + aseEndpoint, err := GetMSIAppServiceEndpoint() + if err != nil { + // app service environment isn't enabled + return false + } + ase, err := url.Parse(aseEndpoint) + if err != nil { + return false + } + return endpoint.Host == ase.Host && endpoint.Path == ase.Path } func (spt *ServicePrincipalToken) refreshInternal(ctx context.Context, resource string) error { @@ -859,7 +899,7 @@ func (spt *ServicePrincipalToken) refreshInternal(ctx context.Context, resource } req.Header.Add("User-Agent", UserAgent()) // Add header when runtime is on App Service or Functions - if isAppService() { + if isASEEndpoint(spt.inner.OauthConfig.TokenEndpoint) { asMSISecret, _ := os.LookupEnv(asMSISecretEnv) req.Header.Add("Secret", asMSISecret) } @@ -901,6 +941,14 @@ func (spt *ServicePrincipalToken) refreshInternal(ctx context.Context, resource } var resp *http.Response + if isMSIEndpoint(spt.inner.OauthConfig.TokenEndpoint) { + resp, err = getMSIEndpoint(ctx, spt.sender) + if err != nil { + // return a TokenRefreshError here so that we don't keep retrying + return newTokenRefreshError(fmt.Sprintf("the MSI endpoint is not available. Failed HTTP request to MSI endpoint: %v", err), nil) + } + resp.Body.Close() + } if isIMDS(spt.inner.OauthConfig.TokenEndpoint) { resp, err = retryForIMDS(spt.sender, req, spt.MaxMSIRefreshAttempts) } else { @@ -973,6 +1021,11 @@ func retryForIMDS(sender Sender, req *http.Request, maxAttempts int) (resp *http attempt := 0 delay := time.Duration(0) + // maxAttempts is user-specified, ensure that its value is greater than zero else no request will be made + if maxAttempts < 1 { + maxAttempts = defaultMaxMSIRefreshAttempts + } + for attempt < maxAttempts { if resp != nil && resp.Body != nil { io.Copy(ioutil.Discard, resp.Body) @@ -1134,3 +1187,12 @@ func NewMultiTenantServicePrincipalToken(multiTenantCfg MultiTenantOAuthConfig, } return &m, nil } + +// MSIAvailable returns true if the MSI endpoint is available for authentication. +func MSIAvailable(ctx context.Context, sender Sender) bool { + resp, err := getMSIEndpoint(ctx, sender) + if err == nil { + resp.Body.Close() + } + return err == nil +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/token_1.13.go b/vendor/github.com/Azure/go-autorest/autorest/adal/token_1.13.go new file mode 100644 index 000000000..45e01a7ee --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/adal/token_1.13.go @@ -0,0 +1,36 @@ +// +build go1.13 + +// Copyright 2017 Microsoft Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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. + +package adal + +import ( + "context" + "net/http" + "time" +) + +func getMSIEndpoint(ctx context.Context, sender Sender) (*http.Response, error) { + // this cannot fail, the return sig is due to legacy reasons + msiEndpoint, _ := GetMSIVMEndpoint() + tempCtx, cancel := context.WithTimeout(ctx, 500*time.Millisecond) + defer cancel() + // http.NewRequestWithContext() was added in Go 1.13 + req, _ := http.NewRequestWithContext(tempCtx, http.MethodGet, msiEndpoint, nil) + q := req.URL.Query() + q.Add("api-version", msiAPIVersion) + req.URL.RawQuery = q.Encode() + return sender.Do(req) +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/token_legacy.go b/vendor/github.com/Azure/go-autorest/autorest/adal/token_legacy.go new file mode 100644 index 000000000..6f7ad8078 --- /dev/null +++ b/vendor/github.com/Azure/go-autorest/autorest/adal/token_legacy.go @@ -0,0 +1,36 @@ +// +build !go1.13 + +// Copyright 2017 Microsoft Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// 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. + +package adal + +import ( + "context" + "net/http" + "time" +) + +func getMSIEndpoint(ctx context.Context, sender Sender) (*http.Response, error) { + // this cannot fail, the return sig is due to legacy reasons + msiEndpoint, _ := GetMSIVMEndpoint() + tempCtx, cancel := context.WithTimeout(ctx, 500*time.Millisecond) + defer cancel() + req, _ := http.NewRequest(http.MethodGet, msiEndpoint, nil) + req = req.WithContext(tempCtx) + q := req.URL.Query() + q.Add("api-version", msiAPIVersion) + req.URL.RawQuery = q.Encode() + return sender.Do(req) +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/authorization.go b/vendor/github.com/Azure/go-autorest/autorest/authorization.go index 15138b642..1226c4111 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/authorization.go +++ b/vendor/github.com/Azure/go-autorest/autorest/authorization.go @@ -299,18 +299,24 @@ type MultiTenantServicePrincipalTokenAuthorizer interface { // NewMultiTenantServicePrincipalTokenAuthorizer crates a BearerAuthorizer using the given token provider func NewMultiTenantServicePrincipalTokenAuthorizer(tp adal.MultitenantOAuthTokenProvider) MultiTenantServicePrincipalTokenAuthorizer { - return &multiTenantSPTAuthorizer{tp: tp} + return NewMultiTenantBearerAuthorizer(tp) } -type multiTenantSPTAuthorizer struct { +// MultiTenantBearerAuthorizer implements bearer authorization across multiple tenants. +type MultiTenantBearerAuthorizer struct { tp adal.MultitenantOAuthTokenProvider } +// NewMultiTenantBearerAuthorizer creates a MultiTenantBearerAuthorizer using the given token provider. +func NewMultiTenantBearerAuthorizer(tp adal.MultitenantOAuthTokenProvider) *MultiTenantBearerAuthorizer { + return &MultiTenantBearerAuthorizer{tp: tp} +} + // WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header using the // primary token along with the auxiliary authorization header using the auxiliary tokens. // // By default, the token will be automatically refreshed through the Refresher interface. -func (mt multiTenantSPTAuthorizer) WithAuthorization() PrepareDecorator { +func (mt *MultiTenantBearerAuthorizer) WithAuthorization() PrepareDecorator { return func(p Preparer) Preparer { return PreparerFunc(func(r *http.Request) (*http.Request, error) { r, err := p.Prepare(r) @@ -340,3 +346,8 @@ func (mt multiTenantSPTAuthorizer) WithAuthorization() PrepareDecorator { }) } } + +// TokenProvider returns the underlying MultitenantOAuthTokenProvider for this authorizer. +func (mt *MultiTenantBearerAuthorizer) TokenProvider() adal.MultitenantOAuthTokenProvider { + return mt.tp +} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/cli/go.mod b/vendor/github.com/Azure/go-autorest/autorest/azure/cli/go.mod index 087f737e9..7e06a8bb7 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/cli/go.mod +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/cli/go.mod @@ -4,7 +4,7 @@ go 1.12 require ( github.com/Azure/go-autorest v14.2.0+incompatible - github.com/Azure/go-autorest/autorest/adal v0.9.0 + github.com/Azure/go-autorest/autorest/adal v0.9.5 github.com/Azure/go-autorest/autorest/date v0.3.0 github.com/dimchansky/utfbom v1.1.0 github.com/mitchellh/go-homedir v1.1.0 diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/cli/go.sum b/vendor/github.com/Azure/go-autorest/autorest/azure/cli/go.sum index 90d0dd239..f2f970684 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/cli/go.sum +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/cli/go.sum @@ -1,21 +1,22 @@ github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest/adal v0.9.0 h1:SigMbuFNuKgc1xcGhaeapbh+8fgsu+GxgDRFyg7f5lM= -github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= +github.com/Azure/go-autorest/autorest/adal v0.9.5 h1:Y3bBUV4rTuxenJJs41HU3qmqsb+auo+a3Lz+PlJPpL0= +github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.4.0 h1:z20OWOSG5aCye0HEkDp6TPmP17ZcfeMxPi6HnSALa8c= -github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/mocks v0.4.1 h1:K0laFcLE6VLTOwNgSxaGbUcLPuGXlNkbVvq4cW4nIHk= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= -github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TRo4= github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= +github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk= +github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 h1:hb9wdF1z5waM+dSIICn1l0DkLVDT3hqhhQsDNUmHPRE= +golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/environments.go b/vendor/github.com/Azure/go-autorest/autorest/azure/environments.go index 3e9f74aa3..9bbc0899e 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/environments.go +++ b/vendor/github.com/Azure/go-autorest/autorest/azure/environments.go @@ -46,6 +46,8 @@ type ResourceIdentifier struct { Batch string `json:"batch"` OperationalInsights string `json:"operationalInsights"` Storage string `json:"storage"` + Synapse string `json:"synapse"` + ServiceBus string `json:"serviceBus"` } // Environment represents a set of endpoints for each of Azure's Clouds. @@ -72,6 +74,7 @@ type Environment struct { CosmosDBDNSSuffix string `json:"cosmosDBDNSSuffix"` TokenAudience string `json:"tokenAudience"` APIManagementHostNameSuffix string `json:"apiManagementHostNameSuffix"` + SynapseEndpointSuffix string `json:"synapseEndpointSuffix"` ResourceIdentifiers ResourceIdentifier `json:"resourceIdentifiers"` } @@ -100,6 +103,7 @@ var ( CosmosDBDNSSuffix: "documents.azure.com", TokenAudience: "https://management.azure.com/", APIManagementHostNameSuffix: "azure-api.net", + SynapseEndpointSuffix: "dev.azuresynapse.net", ResourceIdentifiers: ResourceIdentifier{ Graph: "https://graph.windows.net/", KeyVault: "https://vault.azure.net", @@ -107,6 +111,8 @@ var ( Batch: "https://batch.core.windows.net/", OperationalInsights: "https://api.loganalytics.io", Storage: "https://storage.azure.com/", + Synapse: "https://dev.azuresynapse.net", + ServiceBus: "https://servicebus.azure.net/", }, } @@ -134,6 +140,7 @@ var ( CosmosDBDNSSuffix: "documents.azure.us", TokenAudience: "https://management.usgovcloudapi.net/", APIManagementHostNameSuffix: "azure-api.us", + SynapseEndpointSuffix: NotAvailable, ResourceIdentifiers: ResourceIdentifier{ Graph: "https://graph.windows.net/", KeyVault: "https://vault.usgovcloudapi.net", @@ -141,6 +148,8 @@ var ( Batch: "https://batch.core.usgovcloudapi.net/", OperationalInsights: "https://api.loganalytics.us", Storage: "https://storage.azure.com/", + Synapse: NotAvailable, + ServiceBus: "https://servicebus.azure.net/", }, } @@ -168,6 +177,7 @@ var ( CosmosDBDNSSuffix: "documents.azure.cn", TokenAudience: "https://management.chinacloudapi.cn/", APIManagementHostNameSuffix: "azure-api.cn", + SynapseEndpointSuffix: "dev.azuresynapse.azure.cn", ResourceIdentifiers: ResourceIdentifier{ Graph: "https://graph.chinacloudapi.cn/", KeyVault: "https://vault.azure.cn", @@ -175,6 +185,8 @@ var ( Batch: "https://batch.chinacloudapi.cn/", OperationalInsights: NotAvailable, Storage: "https://storage.azure.com/", + Synapse: "https://dev.azuresynapse.net", + ServiceBus: "https://servicebus.azure.net/", }, } @@ -202,6 +214,7 @@ var ( CosmosDBDNSSuffix: "documents.microsoftazure.de", TokenAudience: "https://management.microsoftazure.de/", APIManagementHostNameSuffix: NotAvailable, + SynapseEndpointSuffix: NotAvailable, ResourceIdentifiers: ResourceIdentifier{ Graph: "https://graph.cloudapi.de/", KeyVault: "https://vault.microsoftazure.de", @@ -209,6 +222,8 @@ var ( Batch: "https://batch.cloudapi.de/", OperationalInsights: NotAvailable, Storage: "https://storage.azure.com/", + Synapse: NotAvailable, + ServiceBus: "https://servicebus.azure.net/", }, } ) diff --git a/vendor/github.com/Azure/go-autorest/autorest/go.mod b/vendor/github.com/Azure/go-autorest/autorest/go.mod index b66c78da2..75a534f10 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/go.mod +++ b/vendor/github.com/Azure/go-autorest/autorest/go.mod @@ -4,9 +4,9 @@ go 1.12 require ( github.com/Azure/go-autorest v14.2.0+incompatible - github.com/Azure/go-autorest/autorest/adal v0.9.0 - github.com/Azure/go-autorest/autorest/mocks v0.4.0 + github.com/Azure/go-autorest/autorest/adal v0.9.5 + github.com/Azure/go-autorest/autorest/mocks v0.4.1 github.com/Azure/go-autorest/logger v0.2.0 github.com/Azure/go-autorest/tracing v0.6.0 - golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 + golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 ) diff --git a/vendor/github.com/Azure/go-autorest/autorest/go.sum b/vendor/github.com/Azure/go-autorest/autorest/go.sum index 96d2ad0fc..fa27c68d1 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/go.sum +++ b/vendor/github.com/Azure/go-autorest/autorest/go.sum @@ -1,21 +1,21 @@ github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest/adal v0.9.0 h1:SigMbuFNuKgc1xcGhaeapbh+8fgsu+GxgDRFyg7f5lM= -github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= +github.com/Azure/go-autorest/autorest/adal v0.9.5 h1:Y3bBUV4rTuxenJJs41HU3qmqsb+auo+a3Lz+PlJPpL0= +github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.4.0 h1:z20OWOSG5aCye0HEkDp6TPmP17ZcfeMxPi6HnSALa8c= -github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/mocks v0.4.1 h1:K0laFcLE6VLTOwNgSxaGbUcLPuGXlNkbVvq4cW4nIHk= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/logger v0.2.0 h1:e4RVHVZKC5p6UANLJHkM4OfR1UKZPj8Wt8Pcx+3oqrE= github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= -github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk= +github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 h1:hb9wdF1z5waM+dSIICn1l0DkLVDT3hqhhQsDNUmHPRE= +golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/vendor/github.com/Azure/go-autorest/autorest/preparer.go b/vendor/github.com/Azure/go-autorest/autorest/preparer.go index 6e8ed64eb..98574a415 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/preparer.go +++ b/vendor/github.com/Azure/go-autorest/autorest/preparer.go @@ -127,10 +127,7 @@ func WithHeader(header string, value string) PrepareDecorator { return PreparerFunc(func(r *http.Request) (*http.Request, error) { r, err := p.Prepare(r) if err == nil { - if r.Header == nil { - r.Header = make(http.Header) - } - r.Header.Set(http.CanonicalHeaderKey(header), value) + setHeader(r, http.CanonicalHeaderKey(header), value) } return r, err }) @@ -230,7 +227,7 @@ func AsPost() PrepareDecorator { return WithMethod("POST") } func AsPut() PrepareDecorator { return WithMethod("PUT") } // WithBaseURL returns a PrepareDecorator that populates the http.Request with a url.URL constructed -// from the supplied baseUrl. +// from the supplied baseUrl. Query parameters will be encoded as required. func WithBaseURL(baseURL string) PrepareDecorator { return func(p Preparer) Preparer { return PreparerFunc(func(r *http.Request) (*http.Request, error) { @@ -241,11 +238,16 @@ func WithBaseURL(baseURL string) PrepareDecorator { return r, err } if u.Scheme == "" { - err = fmt.Errorf("autorest: No scheme detected in URL %s", baseURL) + return r, fmt.Errorf("autorest: No scheme detected in URL %s", baseURL) } - if err == nil { - r.URL = u + if u.RawQuery != "" { + q, err := url.ParseQuery(u.RawQuery) + if err != nil { + return r, err + } + u.RawQuery = q.Encode() } + r.URL = u } return r, err }) @@ -290,10 +292,7 @@ func WithFormData(v url.Values) PrepareDecorator { if err == nil { s := v.Encode() - if r.Header == nil { - r.Header = make(http.Header) - } - r.Header.Set(http.CanonicalHeaderKey(headerContentType), mimeTypeFormPost) + setHeader(r, http.CanonicalHeaderKey(headerContentType), mimeTypeFormPost) r.ContentLength = int64(len(s)) r.Body = ioutil.NopCloser(strings.NewReader(s)) } @@ -329,10 +328,7 @@ func WithMultiPartFormData(formDataParameters map[string]interface{}) PrepareDec if err = writer.Close(); err != nil { return r, err } - if r.Header == nil { - r.Header = make(http.Header) - } - r.Header.Set(http.CanonicalHeaderKey(headerContentType), writer.FormDataContentType()) + setHeader(r, http.CanonicalHeaderKey(headerContentType), writer.FormDataContentType()) r.Body = ioutil.NopCloser(bytes.NewReader(body.Bytes())) r.ContentLength = int64(body.Len()) return r, err @@ -437,6 +433,7 @@ func WithXML(v interface{}) PrepareDecorator { bytesWithHeader := []byte(withHeader) r.ContentLength = int64(len(bytesWithHeader)) + setHeader(r, headerContentLength, fmt.Sprintf("%d", len(bytesWithHeader))) r.Body = ioutil.NopCloser(bytes.NewReader(bytesWithHeader)) } } diff --git a/vendor/github.com/Azure/go-autorest/autorest/sender.go b/vendor/github.com/Azure/go-autorest/autorest/sender.go index 704f3e55e..78610ef20 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/sender.go +++ b/vendor/github.com/Azure/go-autorest/autorest/sender.go @@ -23,11 +23,29 @@ import ( "net/http" "net/http/cookiejar" "strconv" + "sync" "time" "github.com/Azure/go-autorest/tracing" ) +// there is one sender per TLS renegotiation type, i.e. count of tls.RenegotiationSupport enums +const defaultSendersCount = 3 + +type defaultSender struct { + sender Sender + init *sync.Once +} + +// each type of sender will be created on demand in sender() +var defaultSenders [defaultSendersCount]defaultSender + +func init() { + for i := 0; i < defaultSendersCount; i++ { + defaultSenders[i].init = &sync.Once{} + } +} + // used as a key type in context.WithValue() type ctxSendDecorators struct{} @@ -107,26 +125,31 @@ func SendWithSender(s Sender, r *http.Request, decorators ...SendDecorator) (*ht } func sender(renengotiation tls.RenegotiationSupport) Sender { - // Use behaviour compatible with DefaultTransport, but require TLS minimum version. - defaultTransport := http.DefaultTransport.(*http.Transport) - transport := &http.Transport{ - Proxy: defaultTransport.Proxy, - DialContext: defaultTransport.DialContext, - MaxIdleConns: defaultTransport.MaxIdleConns, - IdleConnTimeout: defaultTransport.IdleConnTimeout, - TLSHandshakeTimeout: defaultTransport.TLSHandshakeTimeout, - ExpectContinueTimeout: defaultTransport.ExpectContinueTimeout, - TLSClientConfig: &tls.Config{ - MinVersion: tls.VersionTLS12, - Renegotiation: renengotiation, - }, - } - var roundTripper http.RoundTripper = transport - if tracing.IsEnabled() { - roundTripper = tracing.NewTransport(transport) - } - j, _ := cookiejar.New(nil) - return &http.Client{Jar: j, Transport: roundTripper} + // note that we can't init defaultSenders in init() since it will + // execute before calling code has had a chance to enable tracing + defaultSenders[renengotiation].init.Do(func() { + // Use behaviour compatible with DefaultTransport, but require TLS minimum version. + defaultTransport := http.DefaultTransport.(*http.Transport) + transport := &http.Transport{ + Proxy: defaultTransport.Proxy, + DialContext: defaultTransport.DialContext, + MaxIdleConns: defaultTransport.MaxIdleConns, + IdleConnTimeout: defaultTransport.IdleConnTimeout, + TLSHandshakeTimeout: defaultTransport.TLSHandshakeTimeout, + ExpectContinueTimeout: defaultTransport.ExpectContinueTimeout, + TLSClientConfig: &tls.Config{ + MinVersion: tls.VersionTLS12, + Renegotiation: renengotiation, + }, + } + var roundTripper http.RoundTripper = transport + if tracing.IsEnabled() { + roundTripper = tracing.NewTransport(transport) + } + j, _ := cookiejar.New(nil) + defaultSenders[renengotiation].sender = &http.Client{Jar: j, Transport: roundTripper} + }) + return defaultSenders[renengotiation].sender } // AfterDelay returns a SendDecorator that delays for the passed time.Duration before diff --git a/vendor/github.com/Azure/go-autorest/autorest/utility.go b/vendor/github.com/Azure/go-autorest/autorest/utility.go index 67baab2ce..416041c3f 100644 --- a/vendor/github.com/Azure/go-autorest/autorest/utility.go +++ b/vendor/github.com/Azure/go-autorest/autorest/utility.go @@ -237,3 +237,10 @@ func DrainResponseBody(resp *http.Response) error { } return nil } + +func setHeader(r *http.Request, key, value string) { + if r.Header == nil { + r.Header = make(http.Header) + } + r.Header.Set(key, value) +} diff --git a/vendor/github.com/dgrijalva/jwt-go/.gitignore b/vendor/github.com/form3tech-oss/jwt-go/.gitignore similarity index 69% rename from vendor/github.com/dgrijalva/jwt-go/.gitignore rename to vendor/github.com/form3tech-oss/jwt-go/.gitignore index 80bed650e..c0e81a8d9 100644 --- a/vendor/github.com/dgrijalva/jwt-go/.gitignore +++ b/vendor/github.com/form3tech-oss/jwt-go/.gitignore @@ -1,4 +1,5 @@ .DS_Store bin +.idea/ diff --git a/vendor/github.com/dgrijalva/jwt-go/.travis.yml b/vendor/github.com/form3tech-oss/jwt-go/.travis.yml similarity index 65% rename from vendor/github.com/dgrijalva/jwt-go/.travis.yml rename to vendor/github.com/form3tech-oss/jwt-go/.travis.yml index 1027f56cd..3c7fb7e1a 100644 --- a/vendor/github.com/dgrijalva/jwt-go/.travis.yml +++ b/vendor/github.com/form3tech-oss/jwt-go/.travis.yml @@ -5,9 +5,8 @@ script: - go test -v ./... go: - - 1.3 - - 1.4 - - 1.5 - - 1.6 - - 1.7 + - 1.12 + - 1.13 + - 1.14 + - 1.15 - tip diff --git a/vendor/github.com/dgrijalva/jwt-go/LICENSE b/vendor/github.com/form3tech-oss/jwt-go/LICENSE similarity index 100% rename from vendor/github.com/dgrijalva/jwt-go/LICENSE rename to vendor/github.com/form3tech-oss/jwt-go/LICENSE diff --git a/vendor/github.com/dgrijalva/jwt-go/MIGRATION_GUIDE.md b/vendor/github.com/form3tech-oss/jwt-go/MIGRATION_GUIDE.md similarity index 100% rename from vendor/github.com/dgrijalva/jwt-go/MIGRATION_GUIDE.md rename to vendor/github.com/form3tech-oss/jwt-go/MIGRATION_GUIDE.md diff --git a/vendor/github.com/dgrijalva/jwt-go/README.md b/vendor/github.com/form3tech-oss/jwt-go/README.md similarity index 89% rename from vendor/github.com/dgrijalva/jwt-go/README.md rename to vendor/github.com/form3tech-oss/jwt-go/README.md index d358d881b..d7749077f 100644 --- a/vendor/github.com/dgrijalva/jwt-go/README.md +++ b/vendor/github.com/form3tech-oss/jwt-go/README.md @@ -9,7 +9,7 @@ A [go](http://www.golang.org) (or 'golang' for search engine friendliness) imple **SECURITY NOTICE:** Some older versions of Go have a security issue in the cryotp/elliptic. Recommendation is to upgrade to at least 1.8.3. See issue #216 for more detail. -**SECURITY NOTICE:** It's important that you [validate the `alg` presented is what you expect](https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/). This library attempts to make it easy to do the right thing by requiring key types match the expected alg, but you should take the extra step to verify it in your usage. See the examples provided. +**SECURITY NOTICE:** It's important that you [validate the `alg` presented is what you expect](https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/). This library attempts to make it easy to do the right thing by requiring key types match the expected alg, but you should take the extra step to verify it in your usage. See the examples provided. ## What the heck is a JWT? @@ -19,7 +19,7 @@ In short, it's a signed JSON object that does something useful (for example, aut The first part is called the header. It contains the necessary information for verifying the last part, the signature. For example, which encryption method was used for signing and what key was used. -The part in the middle is the interesting bit. It's called the Claims and contains the actual stuff you care about. Refer to [the RFC](http://self-issued.info/docs/draft-jones-json-web-token.html) for information about reserved keys and the proper way to add your own. +The part in the middle is the interesting bit. It's called the Claims and contains the actual stuff you care about. Refer to [the RFC](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html) for information about reserved keys and the proper way to add your own. ## What's in the box? @@ -37,7 +37,7 @@ See [the project documentation](https://godoc.org/github.com/dgrijalva/jwt-go) f This library publishes all the necessary components for adding your own signing methods. Simply implement the `SigningMethod` interface and register a factory method using `RegisterSigningMethod`. -Here's an example of an extension that integrates with the Google App Engine signing tools: https://github.com/someone1/gcp-jwt-go +Here's an example of an extension that integrates with multiple Google Cloud Platform signing tools (AppEngine, IAM API, Cloud KMS): https://github.com/someone1/gcp-jwt-go ## Compliance @@ -93,6 +93,10 @@ Without going too far down the rabbit hole, here's a description of the interact * OAuth defines several options for passing around authentication data. One popular method is called a "bearer token". A bearer token is simply a string that _should_ only be held by an authenticated user. Thus, simply presenting this token proves your identity. You can probably derive from here why a JWT might make a good bearer token. * Because bearer tokens are used for authentication, it's important they're kept secret. This is why transactions that use bearer tokens typically happen over SSL. +### Troubleshooting + +This library uses descriptive error messages whenever possible. If you are not getting the expected result, have a look at the errors. The most common place people get stuck is providing the correct type of key to the parser. See the above section on signing methods and key types. + ## More Documentation can be found [on godoc.org](http://godoc.org/github.com/dgrijalva/jwt-go). diff --git a/vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md b/vendor/github.com/form3tech-oss/jwt-go/VERSION_HISTORY.md similarity index 100% rename from vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md rename to vendor/github.com/form3tech-oss/jwt-go/VERSION_HISTORY.md diff --git a/vendor/github.com/dgrijalva/jwt-go/claims.go b/vendor/github.com/form3tech-oss/jwt-go/claims.go similarity index 93% rename from vendor/github.com/dgrijalva/jwt-go/claims.go rename to vendor/github.com/form3tech-oss/jwt-go/claims.go index f0228f02e..624890666 100644 --- a/vendor/github.com/dgrijalva/jwt-go/claims.go +++ b/vendor/github.com/form3tech-oss/jwt-go/claims.go @@ -16,7 +16,7 @@ type Claims interface { // https://tools.ietf.org/html/rfc7519#section-4.1 // See examples for how to use this with your own claim types type StandardClaims struct { - Audience string `json:"aud,omitempty"` + Audience []string `json:"aud,omitempty"` ExpiresAt int64 `json:"exp,omitempty"` Id string `json:"jti,omitempty"` IssuedAt int64 `json:"iat,omitempty"` @@ -90,15 +90,17 @@ func (c *StandardClaims) VerifyNotBefore(cmp int64, req bool) bool { // ----- helpers -func verifyAud(aud string, cmp string, required bool) bool { - if aud == "" { +func verifyAud(aud []string, cmp string, required bool) bool { + if len(aud) == 0 { return !required } - if subtle.ConstantTimeCompare([]byte(aud), []byte(cmp)) != 0 { - return true - } else { - return false + + for _, a := range aud { + if subtle.ConstantTimeCompare([]byte(a), []byte(cmp)) != 0 { + return true + } } + return false } func verifyExp(exp int64, now int64, required bool) bool { diff --git a/vendor/github.com/dgrijalva/jwt-go/doc.go b/vendor/github.com/form3tech-oss/jwt-go/doc.go similarity index 100% rename from vendor/github.com/dgrijalva/jwt-go/doc.go rename to vendor/github.com/form3tech-oss/jwt-go/doc.go diff --git a/vendor/github.com/dgrijalva/jwt-go/ecdsa.go b/vendor/github.com/form3tech-oss/jwt-go/ecdsa.go similarity index 100% rename from vendor/github.com/dgrijalva/jwt-go/ecdsa.go rename to vendor/github.com/form3tech-oss/jwt-go/ecdsa.go diff --git a/vendor/github.com/dgrijalva/jwt-go/ecdsa_utils.go b/vendor/github.com/form3tech-oss/jwt-go/ecdsa_utils.go similarity index 93% rename from vendor/github.com/dgrijalva/jwt-go/ecdsa_utils.go rename to vendor/github.com/form3tech-oss/jwt-go/ecdsa_utils.go index d19624b72..db9f4be7d 100644 --- a/vendor/github.com/dgrijalva/jwt-go/ecdsa_utils.go +++ b/vendor/github.com/form3tech-oss/jwt-go/ecdsa_utils.go @@ -25,7 +25,9 @@ func ParseECPrivateKeyFromPEM(key []byte) (*ecdsa.PrivateKey, error) { // Parse the key var parsedKey interface{} if parsedKey, err = x509.ParseECPrivateKey(block.Bytes); err != nil { - return nil, err + if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil { + return nil, err + } } var pkey *ecdsa.PrivateKey diff --git a/vendor/github.com/dgrijalva/jwt-go/errors.go b/vendor/github.com/form3tech-oss/jwt-go/errors.go similarity index 100% rename from vendor/github.com/dgrijalva/jwt-go/errors.go rename to vendor/github.com/form3tech-oss/jwt-go/errors.go diff --git a/vendor/github.com/dgrijalva/jwt-go/hmac.go b/vendor/github.com/form3tech-oss/jwt-go/hmac.go similarity index 100% rename from vendor/github.com/dgrijalva/jwt-go/hmac.go rename to vendor/github.com/form3tech-oss/jwt-go/hmac.go diff --git a/vendor/github.com/dgrijalva/jwt-go/map_claims.go b/vendor/github.com/form3tech-oss/jwt-go/map_claims.go similarity index 94% rename from vendor/github.com/dgrijalva/jwt-go/map_claims.go rename to vendor/github.com/form3tech-oss/jwt-go/map_claims.go index 291213c46..90ab6bea3 100644 --- a/vendor/github.com/dgrijalva/jwt-go/map_claims.go +++ b/vendor/github.com/form3tech-oss/jwt-go/map_claims.go @@ -13,7 +13,15 @@ type MapClaims map[string]interface{} // Compares the aud claim against cmp. // If required is false, this method will return true if the value matches or is unset func (m MapClaims) VerifyAudience(cmp string, req bool) bool { - aud, _ := m["aud"].(string) + aud, ok := m["aud"].([]string) + if !ok { + strAud, ok := m["aud"].(string) + if !ok { + return false + } + aud = append(aud, strAud) + } + return verifyAud(aud, cmp, req) } diff --git a/vendor/github.com/dgrijalva/jwt-go/none.go b/vendor/github.com/form3tech-oss/jwt-go/none.go similarity index 100% rename from vendor/github.com/dgrijalva/jwt-go/none.go rename to vendor/github.com/form3tech-oss/jwt-go/none.go diff --git a/vendor/github.com/dgrijalva/jwt-go/parser.go b/vendor/github.com/form3tech-oss/jwt-go/parser.go similarity index 100% rename from vendor/github.com/dgrijalva/jwt-go/parser.go rename to vendor/github.com/form3tech-oss/jwt-go/parser.go diff --git a/vendor/github.com/dgrijalva/jwt-go/rsa.go b/vendor/github.com/form3tech-oss/jwt-go/rsa.go similarity index 100% rename from vendor/github.com/dgrijalva/jwt-go/rsa.go rename to vendor/github.com/form3tech-oss/jwt-go/rsa.go diff --git a/vendor/github.com/dgrijalva/jwt-go/rsa_pss.go b/vendor/github.com/form3tech-oss/jwt-go/rsa_pss.go similarity index 71% rename from vendor/github.com/dgrijalva/jwt-go/rsa_pss.go rename to vendor/github.com/form3tech-oss/jwt-go/rsa_pss.go index 10ee9db8a..c01470864 100644 --- a/vendor/github.com/dgrijalva/jwt-go/rsa_pss.go +++ b/vendor/github.com/form3tech-oss/jwt-go/rsa_pss.go @@ -12,9 +12,14 @@ import ( type SigningMethodRSAPSS struct { *SigningMethodRSA Options *rsa.PSSOptions + // VerifyOptions is optional. If set overrides Options for rsa.VerifyPPS. + // Used to accept tokens signed with rsa.PSSSaltLengthAuto, what doesn't follow + // https://tools.ietf.org/html/rfc7518#section-3.5 but was used previously. + // See https://github.com/dgrijalva/jwt-go/issues/285#issuecomment-437451244 for details. + VerifyOptions *rsa.PSSOptions } -// Specific instances for RS/PS and company +// Specific instances for RS/PS and company. var ( SigningMethodPS256 *SigningMethodRSAPSS SigningMethodPS384 *SigningMethodRSAPSS @@ -24,13 +29,15 @@ var ( func init() { // PS256 SigningMethodPS256 = &SigningMethodRSAPSS{ - &SigningMethodRSA{ + SigningMethodRSA: &SigningMethodRSA{ Name: "PS256", Hash: crypto.SHA256, }, - &rsa.PSSOptions{ + Options: &rsa.PSSOptions{ + SaltLength: rsa.PSSSaltLengthEqualsHash, + }, + VerifyOptions: &rsa.PSSOptions{ SaltLength: rsa.PSSSaltLengthAuto, - Hash: crypto.SHA256, }, } RegisterSigningMethod(SigningMethodPS256.Alg(), func() SigningMethod { @@ -39,13 +46,15 @@ func init() { // PS384 SigningMethodPS384 = &SigningMethodRSAPSS{ - &SigningMethodRSA{ + SigningMethodRSA: &SigningMethodRSA{ Name: "PS384", Hash: crypto.SHA384, }, - &rsa.PSSOptions{ + Options: &rsa.PSSOptions{ + SaltLength: rsa.PSSSaltLengthEqualsHash, + }, + VerifyOptions: &rsa.PSSOptions{ SaltLength: rsa.PSSSaltLengthAuto, - Hash: crypto.SHA384, }, } RegisterSigningMethod(SigningMethodPS384.Alg(), func() SigningMethod { @@ -54,13 +63,15 @@ func init() { // PS512 SigningMethodPS512 = &SigningMethodRSAPSS{ - &SigningMethodRSA{ + SigningMethodRSA: &SigningMethodRSA{ Name: "PS512", Hash: crypto.SHA512, }, - &rsa.PSSOptions{ + Options: &rsa.PSSOptions{ + SaltLength: rsa.PSSSaltLengthEqualsHash, + }, + VerifyOptions: &rsa.PSSOptions{ SaltLength: rsa.PSSSaltLengthAuto, - Hash: crypto.SHA512, }, } RegisterSigningMethod(SigningMethodPS512.Alg(), func() SigningMethod { @@ -94,7 +105,12 @@ func (m *SigningMethodRSAPSS) Verify(signingString, signature string, key interf hasher := m.Hash.New() hasher.Write([]byte(signingString)) - return rsa.VerifyPSS(rsaKey, m.Hash, hasher.Sum(nil), sig, m.Options) + opts := m.Options + if m.VerifyOptions != nil { + opts = m.VerifyOptions + } + + return rsa.VerifyPSS(rsaKey, m.Hash, hasher.Sum(nil), sig, opts) } // Implements the Sign method from SigningMethod diff --git a/vendor/github.com/dgrijalva/jwt-go/rsa_utils.go b/vendor/github.com/form3tech-oss/jwt-go/rsa_utils.go similarity index 95% rename from vendor/github.com/dgrijalva/jwt-go/rsa_utils.go rename to vendor/github.com/form3tech-oss/jwt-go/rsa_utils.go index a5ababf95..14c78c292 100644 --- a/vendor/github.com/dgrijalva/jwt-go/rsa_utils.go +++ b/vendor/github.com/form3tech-oss/jwt-go/rsa_utils.go @@ -8,7 +8,7 @@ import ( ) var ( - ErrKeyMustBePEMEncoded = errors.New("Invalid Key: Key must be PEM encoded PKCS1 or PKCS8 private key") + ErrKeyMustBePEMEncoded = errors.New("Invalid Key: Key must be a PEM encoded PKCS1 or PKCS8 key") ErrNotRSAPrivateKey = errors.New("Key is not a valid RSA private key") ErrNotRSAPublicKey = errors.New("Key is not a valid RSA public key") ) diff --git a/vendor/github.com/dgrijalva/jwt-go/signing_method.go b/vendor/github.com/form3tech-oss/jwt-go/signing_method.go similarity index 100% rename from vendor/github.com/dgrijalva/jwt-go/signing_method.go rename to vendor/github.com/form3tech-oss/jwt-go/signing_method.go diff --git a/vendor/github.com/dgrijalva/jwt-go/token.go b/vendor/github.com/form3tech-oss/jwt-go/token.go similarity index 100% rename from vendor/github.com/dgrijalva/jwt-go/token.go rename to vendor/github.com/form3tech-oss/jwt-go/token.go diff --git a/vendor/github.com/hashicorp/go-azure-helpers/authentication/auth_method_azure_cli_token.go b/vendor/github.com/hashicorp/go-azure-helpers/authentication/auth_method_azure_cli_token.go index 3ba86865e..27606e230 100644 --- a/vendor/github.com/hashicorp/go-azure-helpers/authentication/auth_method_azure_cli_token.go +++ b/vendor/github.com/hashicorp/go-azure-helpers/authentication/auth_method_azure_cli_token.go @@ -12,15 +12,18 @@ import ( "github.com/Azure/go-autorest/autorest/adal" "github.com/Azure/go-autorest/autorest/azure/cli" "github.com/hashicorp/go-multierror" + "github.com/hashicorp/go-version" ) type azureCLIProfile struct { - subscription *cli.Subscription + // CLI "subscriptions" are really "accounts" that can represent either a subscription (with tenant) or _just_ a tenant + account *cli.Subscription clientId string environment string subscriptionId string tenantId string + tenantOnly bool } type azureCliTokenAuth struct { @@ -30,23 +33,40 @@ type azureCliTokenAuth struct { func (a azureCliTokenAuth) build(b Builder) (authMethod, error) { auth := azureCliTokenAuth{ + profile: &azureCLIProfile{ subscriptionId: b.SubscriptionID, tenantId: b.TenantID, + tenantOnly: b.TenantOnly, clientId: "04b07795-8ddb-461a-bbee-02f9e1bf7b46", // fixed first party client id for Az CLI }, servicePrincipalAuthDocsLink: b.ClientSecretDocsLink, } - sub, err := obtainSubscription(b.SubscriptionID) - if err != nil { - return nil, fmt.Errorf("obtain subscription(%s) from Azure CLI: %+v", b.SubscriptionID, err) + if err := auth.checkAzVersion(); err != nil { + return nil, err + } + + var acc *cli.Subscription + if auth.profile.tenantOnly { + var err error + acc, err = obtainTenant(b.TenantID) + if err != nil { + return nil, fmt.Errorf("obtain tenant(%s) from Azure CLI: %+v", b.TenantID, err) + } + auth.profile.account = acc + } else { + var err error + acc, err = obtainSubscription(b.SubscriptionID) + if err != nil { + return nil, fmt.Errorf("obtain subscription(%s) from Azure CLI: %+v", b.SubscriptionID, err) + } + auth.profile.account = acc } - auth.profile.subscription = sub // Authenticating as a Service Principal doesn't return all of the information we need for authentication purposes // as such Service Principal authentication is supported using the specific auth method - if sub.User == nil || !strings.EqualFold(sub.User.Type, "user") { + if acc.User == nil || !strings.EqualFold(acc.User.Type, "user") { return nil, fmt.Errorf(`Authenticating using the Azure CLI is only supported as a User (not a Service Principal). To authenticate to Azure using a Service Principal, you can use the separate 'Authenticate using a Service Principal' @@ -56,14 +76,14 @@ Alternatively you can authenticate using the Azure CLI by using a User Account.` } // Populate fields - if auth.profile.subscriptionId == "" { - auth.profile.subscriptionId = sub.ID + if !b.TenantOnly && auth.profile.subscriptionId == "" { + auth.profile.subscriptionId = acc.ID } if auth.profile.tenantId == "" { - auth.profile.tenantId = sub.TenantID + auth.profile.tenantId = acc.TenantID } // always pull the environment from the Azure CLI, since the Access Token's associated with it - auth.profile.environment = normalizeEnvironmentName(sub.EnvironmentName) + auth.profile.environment = normalizeEnvironmentName(acc.EnvironmentName) return auth, nil } @@ -78,7 +98,13 @@ func (a azureCliTokenAuth) getAuthorizationToken(sender autorest.Sender, oauth * } // the Azure CLI appears to cache these, so to maintain compatibility with the interface this method is intentionally not on the pointer - token, err := obtainAuthorizationToken(endpoint, a.profile.subscriptionId) + var token *cli.Token + var err error + if a.profile.tenantOnly { + token, err = obtainAuthorizationToken(endpoint, "", a.profile.tenantId) + } else { + token, err = obtainAuthorizationToken(endpoint, a.profile.subscriptionId, "") + } if err != nil { return nil, fmt.Errorf("Error obtaining Authorization Token from the Azure CLI: %s", err) } @@ -94,7 +120,13 @@ func (a azureCliTokenAuth) getAuthorizationToken(sender autorest.Sender, oauth * } var refreshFunc adal.TokenRefresh = func(ctx context.Context, resource string) (*adal.Token, error) { - token, err := obtainAuthorizationToken(resource, a.profile.subscriptionId) + var token *cli.Token + var err error + if a.profile.tenantOnly { + token, err = obtainAuthorizationToken(resource, "", a.profile.tenantId) + } else { + token, err = obtainAuthorizationToken(resource, a.profile.subscriptionId, "") + } if err != nil { return nil, err } @@ -147,7 +179,7 @@ func (a azureCliTokenAuth) validate() error { err = multierror.Append(err, fmt.Errorf(errorMessageFmt, "Client ID")) } - if a.profile.subscriptionId == "" { + if !a.profile.tenantOnly && a.profile.subscriptionId == "" { err = multierror.Append(err, fmt.Errorf(errorMessageFmt, "Subscription ID")) } @@ -158,6 +190,50 @@ func (a azureCliTokenAuth) validate() error { return err.ErrorOrNil() } +func (a azureCliTokenAuth) checkAzVersion() error { + // Azure CLI v2.0.79 is the earliest version to have a `version` command + var minimumVersion string + if a.profile.tenantOnly { + // v2.0.81 introduced the `--tenant` option to the `account get-access-token` subcommand + minimumVersion = "2.0.81" + } else { + minimumVersion = "2.0.79" + } + + var cliVersion *struct { + AzureCli *string `json:"azure-cli"` + AzureCliCore *string `json:"azure-cli-core"` + AzureCliTelemetry *string `json:"azure-cli-telemetry"` + Extensions *interface{} `json:"extensions"` + } + err := jsonUnmarshalAzCmd(&cliVersion, "version", "-o=json") + if err != nil { + return fmt.Errorf("Please ensure you have installed Azure CLI version %s or newer. Error parsing json result from the Azure CLI: %v.", minimumVersion, err) + } + + if cliVersion.AzureCli == nil { + return fmt.Errorf("Could not detect Azure CLI version. Please ensure you have installed Azure CLI version %s or newer.", minimumVersion) + } + + actual, err := version.NewVersion(*cliVersion.AzureCli) + if err != nil { + return fmt.Errorf("Could not parse detected Azure CLI version: %+v", err) + } + + supported, err := version.NewVersion(minimumVersion) + if err != nil { + return fmt.Errorf("Could not parse supported Azure CLI version: %+v", err) + } + + if supported.LessThanOrEqual(actual) { + return nil + } + + return fmt.Errorf(`Authenticating using the Azure CLI requires version %[1]s but Terraform detected version %[2]s. + +Please install v%[1]s or greater and ensure the correct version is in your path.`, supported.String(), actual.String()) +} + func obtainAuthenticatedObjectID() (string, error) { var json struct { @@ -172,9 +248,14 @@ func obtainAuthenticatedObjectID() (string, error) { return json.ObjectId, nil } -func obtainAuthorizationToken(endpoint string, subscriptionId string) (*cli.Token, error) { +func obtainAuthorizationToken(endpoint string, subscriptionId string, tenantId string) (*cli.Token, error) { var token cli.Token - err := jsonUnmarshalAzCmd(&token, "account", "get-access-token", "--resource", endpoint, "--subscription", subscriptionId, "-o=json") + var err error + if tenantId != "" { + err = jsonUnmarshalAzCmd(&token, "account", "get-access-token", "--resource", endpoint, "--tenant", tenantId, "-o=json") + } else { + err = jsonUnmarshalAzCmd(&token, "account", "get-access-token", "--resource", endpoint, "--subscription", subscriptionId, "-o=json") + } if err != nil { return nil, fmt.Errorf("Error parsing json result from the Azure CLI: %v", err) } @@ -182,21 +263,57 @@ func obtainAuthorizationToken(endpoint string, subscriptionId string) (*cli.Toke return &token, nil } -// obtainSubscription return a subscription object of the specified subscriptionId. -// If the subscriptionId is empty, it returns the default subscription. +// obtainSubscription returns a Subscription object of the specified subscriptionId. +// If the subscriptionId is empty, it selects the default subscription. func obtainSubscription(subscriptionId string) (*cli.Subscription, error) { - var sub cli.Subscription + var acc cli.Subscription cmd := make([]string, 0) cmd = []string{"account", "show", "-o=json"} if subscriptionId != "" { cmd = append(cmd, "-s", subscriptionId) } - err := jsonUnmarshalAzCmd(&sub, cmd...) + err := jsonUnmarshalAzCmd(&acc, cmd...) if err != nil { return nil, fmt.Errorf("Error parsing json result from the Azure CLI: %v", err) } - return &sub, nil + return &acc, nil +} + +// obtainTenant returns a Subscription object having the specified tenantId. +// If the tenantId is empty, it selects the default subscription. +// This works with `az login --allow-no-subscriptions` +func obtainTenant(tenantId string) (*cli.Subscription, error) { + var acc cli.Subscription + if tenantId == "" { + cmd := make([]string, 0) + cmd = []string{"account", "show", "-o=json"} + err := jsonUnmarshalAzCmd(&acc, cmd...) + if err != nil { + return nil, fmt.Errorf("Error parsing json result from the Azure CLI: %v", err) + } + } else { + var accs []cli.Subscription + cmd := make([]string, 0) + cmd = []string{"account", "list", "-o=json"} + err := jsonUnmarshalAzCmd(&accs, cmd...) + if err != nil { + return nil, fmt.Errorf("Error parsing json result from the Azure CLI: %v", err) + } + + for _, a := range accs { + if a.TenantID == tenantId { + acc = a + break + } + } + + if acc.TenantID == "" { + return nil, fmt.Errorf("Tenant %q was not found", tenantId) + } + } + + return &acc, nil } func jsonUnmarshalAzCmd(i interface{}, arg ...string) error { @@ -209,20 +326,22 @@ func jsonUnmarshalAzCmd(i interface{}, arg ...string) error { cmd.Stdout = &stdout if err := cmd.Start(); err != nil { - return fmt.Errorf("Error launching Azure CLI: %+v", err) + err := fmt.Errorf("Error launching Azure CLI: %+v", err) + if stdErrStr := stderr.String(); stdErrStr != "" { + err = fmt.Errorf("%s: %s", err, strings.TrimSpace(stdErrStr)) + } + return err } if err := cmd.Wait(); err != nil { - return fmt.Errorf("Error waiting for the Azure CLI: %+v", err) - } - - stdOutStr := stdout.String() - stdErrStr := stderr.String() - if stdErrStr != "" { - return fmt.Errorf("Error retrieving running Azure CLI: %s", strings.TrimSpace(stdErrStr)) + err := fmt.Errorf("Error waiting for the Azure CLI: %+v", err) + if stdErrStr := stderr.String(); stdErrStr != "" { + err = fmt.Errorf("%s: %s", err, strings.TrimSpace(stdErrStr)) + } + return err } - if err := json.Unmarshal([]byte(stdOutStr), &i); err != nil { + if err := json.Unmarshal([]byte(stdout.String()), &i); err != nil { return fmt.Errorf("Error unmarshaling the result of Azure CLI: %v", err) } diff --git a/vendor/github.com/hashicorp/go-azure-helpers/authentication/auth_method_azure_cli_token_multi_tenant.go b/vendor/github.com/hashicorp/go-azure-helpers/authentication/auth_method_azure_cli_token_multi_tenant.go new file mode 100644 index 000000000..19c1af2d2 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-helpers/authentication/auth_method_azure_cli_token_multi_tenant.go @@ -0,0 +1,194 @@ +package authentication + +import ( + "context" + "fmt" + + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/adal" + "github.com/Azure/go-autorest/autorest/azure/cli" + "github.com/hashicorp/go-multierror" +) + +type azureCliTokenMultiTenantAuth struct { + profile *azureCLIProfileMultiTenant + servicePrincipalAuthDocsLink string +} + +func (a azureCliTokenMultiTenantAuth) build(b Builder) (authMethod, error) { + auth := azureCliTokenMultiTenantAuth{ + profile: &azureCLIProfileMultiTenant{ + clientId: b.ClientID, + environment: b.Environment, + subscriptionId: b.SubscriptionID, + tenantId: b.TenantID, + auxiliaryTenantIDs: b.AuxiliaryTenantIDs, + }, + servicePrincipalAuthDocsLink: b.ClientSecretDocsLink, + } + profilePath, err := cli.ProfilePath() + if err != nil { + return nil, fmt.Errorf("Error loading the Profile Path from the Azure CLI: %+v", err) + } + + profile, err := cli.LoadProfile(profilePath) + if err != nil { + return nil, fmt.Errorf("Azure CLI Authorization Profile was not found. Please ensure the Azure CLI is installed and then log-in with `az login`.") + } + + auth.profile.profile = profile + + // Authenticating as a Service Principal doesn't return all of the information we need for authentication purposes + // as such Service Principal authentication is supported using the specific auth method + if authenticatedAsAUser := auth.profile.verifyAuthenticatedAsAUser(); !authenticatedAsAUser { + return nil, fmt.Errorf(`Authenticating using the Azure CLI is only supported as a User (not a Service Principal). + +To authenticate to Azure using a Service Principal, you can use the separate 'Authenticate using a Service Principal' +auth method - instructions for which can be found here: %s + +Alternatively you can authenticate using the Azure CLI by using a User Account.`, auth.servicePrincipalAuthDocsLink) + } + + err = auth.profile.populateFields() + if err != nil { + return nil, fmt.Errorf("Error retrieving the Profile from the Azure CLI: %s Please re-authenticate using `az login`.", err) + } + + err = auth.profile.populateClientId() + if err != nil { + return nil, fmt.Errorf("Error populating Client ID from the Azure CLI: %+v", err) + } + + return auth, nil +} + +func (a azureCliTokenMultiTenantAuth) isApplicable(b Builder) bool { + return b.SupportsAzureCliToken && b.SupportsAuxiliaryTenants && (len(b.AuxiliaryTenantIDs) > 0) +} + +func (a azureCliTokenMultiTenantAuth) getAuthorizationToken(sender autorest.Sender, oauth *OAuthConfig, endpoint string) (autorest.Authorizer, error) { + if oauth.MultiTenantOauth == nil { + return nil, fmt.Errorf("Error getting Authorization Token for cli auth: an MultiTenantOauth token wasn't configured correctly; please file a bug with more details") + } + + m := adal.MultiTenantServicePrincipalToken{ + AuxiliaryTokens: make([]*adal.ServicePrincipalToken, len(a.profile.auxiliaryTenantIDs)), + } + + // the Azure CLI appears to cache these, so to maintain compatibility with the interface this method is intentionally not on the pointer + primaryToken, err := obtainAuthorizationTokenByTenant(endpoint, a.profile.tenantId) + if err != nil { + return nil, fmt.Errorf("Error obtaining Authorization Token from the Azure CLI: %s", err) + } + + adalToken, err := primaryToken.ToADALToken() + if err != nil { + return nil, fmt.Errorf("Error converting Authorization Token to an ADAL Token: %s", err) + } + + spt, err := adal.NewServicePrincipalTokenFromManualToken(*oauth.OAuth, a.profile.clientId, endpoint, adalToken) + if err != nil { + return nil, err + } + + var refreshFunc adal.TokenRefresh = func(ctx context.Context, resource string) (*adal.Token, error) { + token, err := obtainAuthorizationToken(resource, a.profile.subscriptionId, "") + if err != nil { + return nil, err + } + + adalToken, err := token.ToADALToken() + if err != nil { + return nil, err + } + + return &adalToken, nil + } + + spt.SetCustomRefreshFunc(refreshFunc) + + m.PrimaryToken = spt + for t := range a.profile.auxiliaryTenantIDs { + token, err := obtainAuthorizationTokenByTenant(endpoint, a.profile.auxiliaryTenantIDs[t]) + if err != nil { + return nil, fmt.Errorf("Error obtaining Authorization Token from the Azure CLI: %s", err) + } + + adalToken, err := token.ToADALToken() + if err != nil { + return nil, fmt.Errorf("Error converting Authorization Token to an ADAL Token: %s", err) + } + + aux, err := adal.NewServicePrincipalTokenFromManualToken(*oauth.OAuth, a.profile.clientId, endpoint, adalToken) + if err != nil { + return nil, err + } + + aux.SetCustomRefreshFunc(refreshFunc) + + m.AuxiliaryTokens[t] = aux + } + + auth := autorest.NewMultiTenantServicePrincipalTokenAuthorizer(&m) + return auth, nil +} + +func (a azureCliTokenMultiTenantAuth) name() string { + return "Obtaining a Multi-tenant token from the Azure CLI" +} + +func (a azureCliTokenMultiTenantAuth) populateConfig(c *Config) error { + c.ClientID = a.profile.clientId + c.TenantID = a.profile.tenantId + c.Environment = a.profile.environment + c.SubscriptionID = a.profile.subscriptionId + + c.GetAuthenticatedObjectID = func(ctx context.Context) (string, error) { + objectId, err := obtainAuthenticatedObjectID() + if err != nil { + return "", err + } + + return objectId, nil + } + + return nil +} + +func (a azureCliTokenMultiTenantAuth) validate() error { + var err *multierror.Error + + errorMessageFmt := "A %s was not found in your Azure CLI Credentials.\n\nPlease login to the Azure CLI again via `az login`" + + if a.profile == nil { + return fmt.Errorf("Azure CLI Profile is nil - this is an internal error and should be reported.") + } + + if a.profile.clientId == "" { + err = multierror.Append(err, fmt.Errorf(errorMessageFmt, "Client ID")) + } + + if a.profile.subscriptionId == "" { + err = multierror.Append(err, fmt.Errorf(errorMessageFmt, "Subscription ID")) + } + + if a.profile.tenantId == "" { + err = multierror.Append(err, fmt.Errorf(errorMessageFmt, "Tenant ID")) + } + + if len(a.profile.auxiliaryTenantIDs) == 0 { + err = multierror.Append(err, fmt.Errorf("Aux Tenant IDs missing from Multi Tenant configuration")) + } + + return err.ErrorOrNil() +} + +func obtainAuthorizationTokenByTenant(endpoint string, tenantId string) (*cli.Token, error) { + var token cli.Token + err := jsonUnmarshalAzCmd(&token, "account", "get-access-token", "--resource", endpoint, "--tenant", tenantId, "--only-show-errors", "-o=json") + if err != nil { + return nil, fmt.Errorf("Error parsing json result from the Azure CLI: %v", err) + } + + return &token, nil +} diff --git a/vendor/github.com/hashicorp/go-azure-helpers/authentication/auth_method_client_cert.go b/vendor/github.com/hashicorp/go-azure-helpers/authentication/auth_method_client_cert.go index 14e455cc0..f9a880179 100644 --- a/vendor/github.com/hashicorp/go-azure-helpers/authentication/auth_method_client_cert.go +++ b/vendor/github.com/hashicorp/go-azure-helpers/authentication/auth_method_client_cert.go @@ -5,8 +5,6 @@ import ( "crypto/x509" "fmt" "io/ioutil" - "os" - "strings" "github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest/adal" @@ -20,6 +18,7 @@ type servicePrincipalClientCertificateAuth struct { clientCertPassword string subscriptionId string tenantId string + tenantOnly bool } func (a servicePrincipalClientCertificateAuth) build(b Builder) (authMethod, error) { @@ -29,6 +28,7 @@ func (a servicePrincipalClientCertificateAuth) build(b Builder) (authMethod, err clientCertPassword: b.ClientCertPassword, subscriptionId: b.SubscriptionID, tenantId: b.TenantID, + tenantOnly: b.TenantOnly, } return method, nil } @@ -46,13 +46,8 @@ func (a servicePrincipalClientCertificateAuth) getAuthorizationToken(sender auto return nil, fmt.Errorf("Error getting Authorization Token for client cert: an OAuth token wasn't configured correctly; please file a bug with more details") } - certificateData, err := ioutil.ReadFile(a.clientCertPath) - if err != nil { - return nil, fmt.Errorf("Error reading Client Certificate %q: %v", a.clientCertPath, err) - } - // Get the certificate and private key from pfx file - certificate, rsaPrivateKey, err := decodePkcs12(certificateData, a.clientCertPassword) + certificate, rsaPrivateKey, err := decodePkcs12File(a.clientCertPath, a.clientCertPassword) if err != nil { return nil, fmt.Errorf("Error decoding pkcs12 certificate: %v", err) } @@ -84,7 +79,7 @@ func (a servicePrincipalClientCertificateAuth) validate() error { fmtErrorMessage := "A %s must be configured when authenticating as a Service Principal using a Client Certificate." - if a.subscriptionId == "" { + if !a.tenantOnly && a.subscriptionId == "" { err = multierror.Append(err, fmt.Errorf(fmtErrorMessage, "Subscription ID")) } @@ -95,16 +90,11 @@ func (a servicePrincipalClientCertificateAuth) validate() error { if a.clientCertPath == "" { err = multierror.Append(err, fmt.Errorf(fmtErrorMessage, "Client Certificate Path")) } else { - if strings.HasSuffix(strings.ToLower(a.clientCertPath), ".pfx") { - // ensure it exists on disk - _, fileErr := os.Stat(a.clientCertPath) - if os.IsNotExist(fileErr) { - err = multierror.Append(err, fmt.Errorf("Error locating Client Certificate specified at %q: %s", a.clientCertPath, fileErr)) - } - - // we're intentionally /not/ checking it's an actual PFX file at this point, as that happens in the getAuthorizationToken - } else { - err = multierror.Append(err, fmt.Errorf("The Client Certificate Path is not a *.pfx file: %q", a.clientCertPath)) + + // validate the certificate path is a valid pfx file + _, _, derr := decodePkcs12File(a.clientCertPath, a.clientCertPassword) + if derr != nil { + err = multierror.Append(err, fmt.Errorf("The Client Certificate Path is not a valid pfx file: %v", derr)) } } @@ -115,8 +105,13 @@ func (a servicePrincipalClientCertificateAuth) validate() error { return err.ErrorOrNil() } -func decodePkcs12(pkcs []byte, password string) (*x509.Certificate, *rsa.PrivateKey, error) { - privateKey, certificate, err := pkcs12.Decode(pkcs, password) +func decodePkcs12File(f string, password string) (*x509.Certificate, *rsa.PrivateKey, error) { + certificateData, err := ioutil.ReadFile(f) + if err != nil { + return nil, nil, fmt.Errorf("Error reading Client Certificate %q: %v", f, err) + } + + privateKey, certificate, err := pkcs12.Decode(certificateData, password) if err != nil { return nil, nil, err } diff --git a/vendor/github.com/hashicorp/go-azure-helpers/authentication/auth_method_client_secret.go b/vendor/github.com/hashicorp/go-azure-helpers/authentication/auth_method_client_secret.go index 36aaed352..23b12b8b7 100644 --- a/vendor/github.com/hashicorp/go-azure-helpers/authentication/auth_method_client_secret.go +++ b/vendor/github.com/hashicorp/go-azure-helpers/authentication/auth_method_client_secret.go @@ -13,6 +13,7 @@ type servicePrincipalClientSecretAuth struct { clientSecret string subscriptionId string tenantId string + tenantOnly bool } func (a servicePrincipalClientSecretAuth) build(b Builder) (authMethod, error) { @@ -21,6 +22,7 @@ func (a servicePrincipalClientSecretAuth) build(b Builder) (authMethod, error) { clientSecret: b.ClientSecret, subscriptionId: b.SubscriptionID, tenantId: b.TenantID, + tenantOnly: b.TenantOnly, } return method, nil } @@ -58,7 +60,7 @@ func (a servicePrincipalClientSecretAuth) validate() error { fmtErrorMessage := "A %s must be configured when authenticating as a Service Principal using a Client Secret." - if a.subscriptionId == "" { + if !a.tenantOnly && a.subscriptionId == "" { err = multierror.Append(err, fmt.Errorf(fmtErrorMessage, "Subscription ID")) } if a.clientId == "" { diff --git a/vendor/github.com/hashicorp/go-azure-helpers/authentication/auth_method_client_secret_multi_tenant.go b/vendor/github.com/hashicorp/go-azure-helpers/authentication/auth_method_client_secret_multi_tenant.go index c435a74f4..914f7700f 100644 --- a/vendor/github.com/hashicorp/go-azure-helpers/authentication/auth_method_client_secret_multi_tenant.go +++ b/vendor/github.com/hashicorp/go-azure-helpers/authentication/auth_method_client_secret_multi_tenant.go @@ -13,6 +13,7 @@ type servicePrincipalClientSecretMultiTenantAuth struct { clientSecret string subscriptionId string tenantId string + tenantOnly bool auxiliaryTenantIDs []string } @@ -22,6 +23,7 @@ func (a servicePrincipalClientSecretMultiTenantAuth) build(b Builder) (authMetho clientSecret: b.ClientSecret, subscriptionId: b.SubscriptionID, tenantId: b.TenantID, + tenantOnly: b.TenantOnly, auxiliaryTenantIDs: b.AuxiliaryTenantIDs, } return method, nil @@ -65,7 +67,7 @@ func (a servicePrincipalClientSecretMultiTenantAuth) validate() error { fmtErrorMessage := "A %s must be configured when authenticating as a Service Principal using a Multi Tenant Client Secret." - if a.subscriptionId == "" { + if !a.tenantOnly && a.subscriptionId == "" { err = multierror.Append(err, fmt.Errorf(fmtErrorMessage, "Subscription ID")) } if a.clientId == "" { diff --git a/vendor/github.com/hashicorp/go-azure-helpers/authentication/azure_cli_access_token.go b/vendor/github.com/hashicorp/go-azure-helpers/authentication/azure_cli_access_token.go new file mode 100644 index 000000000..43362dbda --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-helpers/authentication/azure_cli_access_token.go @@ -0,0 +1,42 @@ +package authentication + +import ( + "fmt" + "log" + "strings" + + "github.com/Azure/go-autorest/autorest/adal" + "github.com/Azure/go-autorest/autorest/azure/cli" +) + +type azureCliAccessToken struct { + ClientID string + AccessToken *adal.Token +} + +func findValidAccessTokenForTenant(tokens []cli.Token, tenantId string) (*azureCliAccessToken, error) { + for _, accessToken := range tokens { + token, err := accessToken.ToADALToken() + if err != nil { + return nil, fmt.Errorf("[DEBUG] Error converting access token to token: %+v", err) + } + + if !strings.Contains(accessToken.Resource, "management") { + log.Printf("[DEBUG] Resource %q isn't a management domain", accessToken.Resource) + continue + } + + if !strings.HasSuffix(accessToken.Authority, tenantId) { + log.Printf("[DEBUG] Resource %q isn't for the correct Tenant", accessToken.Resource) + continue + } + + validAccessToken := azureCliAccessToken{ + ClientID: accessToken.ClientID, + AccessToken: &token, + } + return &validAccessToken, nil + } + + return nil, fmt.Errorf("No Access Token was found for the Tenant ID %q", tenantId) +} \ No newline at end of file diff --git a/vendor/github.com/hashicorp/go-azure-helpers/authentication/azure_cli_profile_multi_tenant.go b/vendor/github.com/hashicorp/go-azure-helpers/authentication/azure_cli_profile_multi_tenant.go new file mode 100644 index 000000000..31a09d466 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-helpers/authentication/azure_cli_profile_multi_tenant.go @@ -0,0 +1,45 @@ +package authentication + +import ( + "strings" + + "github.com/Azure/go-autorest/autorest/azure/cli" +) + +type azureCLIProfileMultiTenant struct { + profile cli.Profile + + clientId string + environment string + subscriptionId string + tenantId string + auxiliaryTenantIDs []string +} + +func (a *azureCLIProfileMultiTenant) populateFields() error { + // ensure we know the Subscription ID - since it's needed for everything else + if a.subscriptionId == "" { + err := a.populateSubscriptionID() + if err != nil { + return err + } + } + + // always pull the environment from the Azure CLI, since the Access Token's associated with it + return a.populateEnvironment() +} + +func (a *azureCLIProfileMultiTenant) verifyAuthenticatedAsAUser() bool { + for _, subscription := range a.profile.Subscriptions { + if subscription.User == nil { + continue + } + + authenticatedAsAUser := strings.EqualFold(subscription.User.Type, "user") + if authenticatedAsAUser { + return true + } + } + + return false +} diff --git a/vendor/github.com/hashicorp/go-azure-helpers/authentication/azure_cli_profile_multi_tenant_population.go b/vendor/github.com/hashicorp/go-azure-helpers/authentication/azure_cli_profile_multi_tenant_population.go new file mode 100644 index 000000000..2282713e0 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-helpers/authentication/azure_cli_profile_multi_tenant_population.go @@ -0,0 +1,81 @@ +package authentication + +import ( + "fmt" + "strings" + + "github.com/Azure/go-autorest/autorest/azure/cli" +) + +func (a *azureCLIProfileMultiTenant) populateSubscriptionID() error { + subscriptionId, err := a.findDefaultSubscriptionId() + if err != nil { + return err + } + + a.subscriptionId = subscriptionId + return nil +} + +func (a *azureCLIProfileMultiTenant) populateTenantID() error { + subscription, err := a.findSubscription(a.subscriptionId) + if err != nil { + return err + } + + a.tenantId = subscription.TenantID + return nil +} + +func (a *azureCLIProfileMultiTenant) populateClientId() error { + // we can now pull out the ClientID and the Access Token to use from the Access Token + tokensPath, err := cli.AccessTokensPath() + if err != nil { + return fmt.Errorf("Error loading the Tokens Path from the Azure CLI: %+v", err) + } + + tokens, err := cli.LoadTokens(tokensPath) + if err != nil { + return fmt.Errorf("No Authorization Tokens were found - please ensure the Azure CLI is installed and then log-in with `az login`.") + } + + validToken, err := findValidAccessTokenForTenant(tokens, a.tenantId) + if err != nil { + return fmt.Errorf("No Authorization Tokens were found - please re-authenticate using `az login`.") + } + + token := *validToken + a.clientId = token.ClientID + + return nil +} + +func (a *azureCLIProfileMultiTenant) populateEnvironment() error { + subscription, err := a.findSubscription(a.subscriptionId) + if err != nil { + return err + } + + a.environment = normalizeEnvironmentName(subscription.EnvironmentName) + return nil +} + +func (a azureCLIProfileMultiTenant) findDefaultSubscriptionId() (string, error) { + for _, subscription := range a.profile.Subscriptions { + if subscription.IsDefault { + return subscription.ID, nil + } + } + + return "", fmt.Errorf("No Subscription was Marked as Default in the Azure Profile.") +} + +func (a azureCLIProfileMultiTenant) findSubscription(subscriptionId string) (*cli.Subscription, error) { + for _, subscription := range a.profile.Subscriptions { + if strings.EqualFold(subscription.ID, subscriptionId) { + return &subscription, nil + } + } + + return nil, fmt.Errorf("Subscription %q was not found in your Azure CLI credentials. Please verify it exists in `az account list`.", subscriptionId) +} diff --git a/vendor/github.com/hashicorp/go-azure-helpers/authentication/azure_sp_objectid.go b/vendor/github.com/hashicorp/go-azure-helpers/authentication/azure_sp_objectid.go index f6beb8a74..5f3017119 100644 --- a/vendor/github.com/hashicorp/go-azure-helpers/authentication/azure_sp_objectid.go +++ b/vendor/github.com/hashicorp/go-azure-helpers/authentication/azure_sp_objectid.go @@ -3,13 +3,14 @@ package authentication import ( "context" "fmt" + "github.com/Azure/azure-sdk-for-go/services/graphrbac/1.6/graphrbac" "github.com/hashicorp/go-azure-helpers/sender" ) func buildServicePrincipalObjectIDFunc(c *Config) func(ctx context.Context) (string, error) { return func(ctx context.Context) (string, error) { - env, err := AzureEnvironmentByNameFromEndpoint(ctx, c.MetadataURL, c.Environment) + env, err := AzureEnvironmentByNameFromEndpoint(ctx, c.MetadataHost, c.Environment) if err != nil { return "", err } diff --git a/vendor/github.com/hashicorp/go-azure-helpers/authentication/builder.go b/vendor/github.com/hashicorp/go-azure-helpers/authentication/builder.go index 122fe1767..4c75ac51a 100644 --- a/vendor/github.com/hashicorp/go-azure-helpers/authentication/builder.go +++ b/vendor/github.com/hashicorp/go-azure-helpers/authentication/builder.go @@ -17,8 +17,9 @@ type Builder struct { ClientID string SubscriptionID string TenantID string + TenantOnly bool Environment string - MetadataURL string + MetadataHost string // Auxiliary tenant IDs used for multi tenant auth SupportsAuxiliaryTenants bool @@ -55,7 +56,7 @@ func (b Builder) Build() (*Config, error) { TenantID: b.TenantID, AuxiliaryTenantIDs: b.AuxiliaryTenantIDs, Environment: b.Environment, - MetadataURL: b.MetadataURL, + MetadataHost: b.MetadataHost, CustomResourceManagerEndpoint: b.CustomResourceManagerEndpoint, } @@ -66,6 +67,7 @@ func (b Builder) Build() (*Config, error) { servicePrincipalClientSecretMultiTenantAuth{}, servicePrincipalClientSecretAuth{}, managedServiceIdentityAuth{}, + azureCliTokenMultiTenantAuth{}, azureCliTokenAuth{}, } diff --git a/vendor/github.com/hashicorp/go-azure-helpers/authentication/config.go b/vendor/github.com/hashicorp/go-azure-helpers/authentication/config.go index 98c68536f..ab3c876b9 100644 --- a/vendor/github.com/hashicorp/go-azure-helpers/authentication/config.go +++ b/vendor/github.com/hashicorp/go-azure-helpers/authentication/config.go @@ -18,7 +18,7 @@ type Config struct { TenantID string AuxiliaryTenantIDs []string Environment string - MetadataURL string + MetadataHost string GetAuthenticatedObjectID func(context.Context) (string, error) AuthenticatedAsAServicePrincipal bool diff --git a/vendor/github.com/hashicorp/go-version/.travis.yml b/vendor/github.com/hashicorp/go-version/.travis.yml deleted file mode 100644 index 01c5dc219..000000000 --- a/vendor/github.com/hashicorp/go-version/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: go - -go: - - 1.2 - - 1.3 - - 1.4 - - 1.9 - - "1.10" - - 1.11 - - 1.12 - -script: - - go test diff --git a/vendor/github.com/hashicorp/go-version/README.md b/vendor/github.com/hashicorp/go-version/README.md index 6f3a15ce7..851a337be 100644 --- a/vendor/github.com/hashicorp/go-version/README.md +++ b/vendor/github.com/hashicorp/go-version/README.md @@ -1,5 +1,6 @@ # Versioning Library for Go -[![Build Status](https://travis-ci.org/hashicorp/go-version.svg?branch=master)](https://travis-ci.org/hashicorp/go-version) +[![Build Status](https://circleci.com/gh/hashicorp/go-version/tree/master.svg?style=svg)](https://circleci.com/gh/hashicorp/go-version/tree/master) +[![GoDoc](https://godoc.org/github.com/hashicorp/go-version?status.svg)](https://godoc.org/github.com/hashicorp/go-version) go-version is a library for parsing versions and version constraints, and verifying versions against a set of constraints. go-version diff --git a/vendor/github.com/hashicorp/go-version/version.go b/vendor/github.com/hashicorp/go-version/version.go index 1032c5606..09703e8e6 100644 --- a/vendor/github.com/hashicorp/go-version/version.go +++ b/vendor/github.com/hashicorp/go-version/version.go @@ -280,6 +280,10 @@ func comparePrereleases(v string, other string) int { // Equal tests if two versions are equal. func (v *Version) Equal(o *Version) bool { + if v == nil || o == nil { + return v == o + } + return v.Compare(o) == 0 } @@ -288,7 +292,7 @@ func (v *Version) GreaterThan(o *Version) bool { return v.Compare(o) > 0 } -// GreaterThanOrEqualTo tests if this version is greater than or equal to another version. +// GreaterThanOrEqual tests if this version is greater than or equal to another version. func (v *Version) GreaterThanOrEqual(o *Version) bool { return v.Compare(o) >= 0 } @@ -298,7 +302,7 @@ func (v *Version) LessThan(o *Version) bool { return v.Compare(o) < 0 } -// LessThanOrEqualTo tests if this version is less than or equal to another version. +// LessThanOrEqual tests if this version is less than or equal to another version. func (v *Version) LessThanOrEqual(o *Version) bool { return v.Compare(o) <= 0 } diff --git a/vendor/golang.org/x/crypto/pkcs12/pkcs12.go b/vendor/golang.org/x/crypto/pkcs12/pkcs12.go index 3e2ce6940..3a89bdb3e 100644 --- a/vendor/golang.org/x/crypto/pkcs12/pkcs12.go +++ b/vendor/golang.org/x/crypto/pkcs12/pkcs12.go @@ -30,6 +30,8 @@ var ( oidFriendlyName = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 9, 20}) oidLocalKeyID = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 9, 21}) oidMicrosoftCSPName = asn1.ObjectIdentifier([]int{1, 3, 6, 1, 4, 1, 311, 17, 1}) + + errUnknownAttributeOID = errors.New("pkcs12: unknown attribute OID") ) type pfxPdu struct { @@ -104,6 +106,11 @@ func unmarshal(in []byte, out interface{}) error { } // ToPEM converts all "safe bags" contained in pfxData to PEM blocks. +// Unknown attributes are discarded. +// +// Note that although the returned PEM blocks for private keys have type +// "PRIVATE KEY", the bytes are not encoded according to PKCS #8, but according +// to PKCS #1 for RSA keys and SEC 1 for ECDSA keys. func ToPEM(pfxData []byte, password string) ([]*pem.Block, error) { encodedPassword, err := bmpString(password) if err != nil { @@ -135,6 +142,9 @@ func convertBag(bag *safeBag, password []byte) (*pem.Block, error) { for _, attribute := range bag.Attributes { k, v, err := convertAttribute(&attribute) + if err == errUnknownAttributeOID { + continue + } if err != nil { return nil, err } @@ -188,7 +198,7 @@ func convertAttribute(attribute *pkcs12Attribute) (key, value string, err error) key = "Microsoft CSP Name" isString = true default: - return "", "", errors.New("pkcs12: unknown attribute with OID " + attribute.Id.String()) + return "", "", errUnknownAttributeOID } if isString { diff --git a/vendor/golang.org/x/crypto/ssh/client_auth.go b/vendor/golang.org/x/crypto/ssh/client_auth.go index f3265655e..c611aeb68 100644 --- a/vendor/golang.org/x/crypto/ssh/client_auth.go +++ b/vendor/golang.org/x/crypto/ssh/client_auth.go @@ -471,7 +471,7 @@ func (cb KeyboardInteractiveChallenge) auth(session []byte, user string, c packe } if len(answers) != len(prompts) { - return authFailure, nil, errors.New("ssh: not enough answers from keyboard-interactive callback") + return authFailure, nil, fmt.Errorf("ssh: incorrect number of answers from keyboard-interactive callback %d (expected %d)", len(answers), len(prompts)) } responseLength := 1 + 4 for _, a := range answers { diff --git a/vendor/golang.org/x/crypto/ssh/kex.go b/vendor/golang.org/x/crypto/ssh/kex.go index 7eedb209f..766e92939 100644 --- a/vendor/golang.org/x/crypto/ssh/kex.go +++ b/vendor/golang.org/x/crypto/ssh/kex.go @@ -557,8 +557,6 @@ type dhGEXSHA struct { hashFunc crypto.Hash } -const numMRTests = 64 - const ( dhGroupExchangeMinimumBits = 2048 dhGroupExchangePreferredBits = 2048 @@ -602,15 +600,8 @@ func (gex dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshake gex.p = kexDHGexGroup.P gex.g = kexDHGexGroup.G - // Check if p is safe by verifing that p and (p-1)/2 are primes - one := big.NewInt(1) - var pHalf = &big.Int{} - pHalf.Rsh(gex.p, 1) - if !gex.p.ProbablyPrime(numMRTests) || !pHalf.ProbablyPrime(numMRTests) { - return nil, fmt.Errorf("ssh: server provided gex p is not safe") - } - // Check if g is safe by verifing that g > 1 and g < p - 1 + one := big.NewInt(1) var pMinusOne = &big.Int{} pMinusOne.Sub(gex.p, one) if gex.g.Cmp(one) != 1 && gex.g.Cmp(pMinusOne) != -1 { @@ -618,6 +609,8 @@ func (gex dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshake } // Send GexInit + var pHalf = &big.Int{} + pHalf.Rsh(gex.p, 1) x, err := rand.Int(randSource, pHalf) if err != nil { return nil, err diff --git a/vendor/modules.txt b/vendor/modules.txt index 53882ede1..4825be0f5 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -6,17 +6,17 @@ cloud.google.com/go/internal/optional cloud.google.com/go/internal/trace cloud.google.com/go/internal/version cloud.google.com/go/storage -# github.com/Azure/azure-sdk-for-go v45.0.0+incompatible +# github.com/Azure/azure-sdk-for-go v47.1.0+incompatible github.com/Azure/azure-sdk-for-go/services/graphrbac/1.6/graphrbac github.com/Azure/azure-sdk-for-go/version # github.com/Azure/go-autorest v14.2.0+incompatible github.com/Azure/go-autorest -# github.com/Azure/go-autorest/autorest v0.11.3 +# github.com/Azure/go-autorest/autorest v0.11.10 github.com/Azure/go-autorest/autorest github.com/Azure/go-autorest/autorest/azure -# github.com/Azure/go-autorest/autorest/adal v0.9.0 +# github.com/Azure/go-autorest/autorest/adal v0.9.5 github.com/Azure/go-autorest/autorest/adal -# github.com/Azure/go-autorest/autorest/azure/cli v0.4.0 +# github.com/Azure/go-autorest/autorest/azure/cli v0.4.2 github.com/Azure/go-autorest/autorest/azure/cli # github.com/Azure/go-autorest/autorest/date v0.3.0 github.com/Azure/go-autorest/autorest/date @@ -80,12 +80,12 @@ github.com/bgentry/go-netrc/netrc github.com/bgentry/speakeasy # github.com/davecgh/go-spew v1.1.1 github.com/davecgh/go-spew/spew -# github.com/dgrijalva/jwt-go v3.2.0+incompatible -github.com/dgrijalva/jwt-go # github.com/dimchansky/utfbom v1.1.0 github.com/dimchansky/utfbom # github.com/fatih/color v1.7.0 github.com/fatih/color +# github.com/form3tech-oss/jwt-go v3.2.2+incompatible +github.com/form3tech-oss/jwt-go # github.com/golang/protobuf v1.3.2 github.com/golang/protobuf/proto github.com/golang/protobuf/protoc-gen-go/descriptor @@ -105,7 +105,7 @@ github.com/google/uuid github.com/googleapis/gax-go/v2 # github.com/hashicorp/errwrap v1.0.0 github.com/hashicorp/errwrap -# github.com/hashicorp/go-azure-helpers v0.12.0 +# github.com/hashicorp/go-azure-helpers v0.13.0 => /Users/tom/go/src/github.com/hashicorp/go-azure-helpers github.com/hashicorp/go-azure-helpers/authentication github.com/hashicorp/go-azure-helpers/response github.com/hashicorp/go-azure-helpers/sender @@ -125,7 +125,7 @@ github.com/hashicorp/go-plugin/internal/plugin github.com/hashicorp/go-safetemp # github.com/hashicorp/go-uuid v1.0.1 github.com/hashicorp/go-uuid -# github.com/hashicorp/go-version v1.2.0 +# github.com/hashicorp/go-version v1.2.1 github.com/hashicorp/go-version # github.com/hashicorp/golang-lru v0.5.1 github.com/hashicorp/golang-lru/simplelru @@ -273,7 +273,7 @@ go.opencensus.io/trace go.opencensus.io/trace/internal go.opencensus.io/trace/propagation go.opencensus.io/trace/tracestate -# golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 +# golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 golang.org/x/crypto/bcrypt golang.org/x/crypto/blowfish golang.org/x/crypto/cast5