diff --git a/go.mod b/go.mod index 553b3d04c..d60e21446 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,10 @@ module github.com/aquasecurity/fanal go 1.17 require ( + github.com/Azure/azure-sdk-for-go v61.2.0+incompatible + github.com/Azure/go-autorest/autorest v0.11.24 + github.com/Azure/go-autorest/autorest/adal v0.9.18 + github.com/Azure/go-autorest/autorest/azure/auth v0.5.2 github.com/BurntSushi/toml v1.0.0 github.com/GoogleCloudPlatform/docker-credential-gcr v1.5.0 github.com/alicebob/miniredis/v2 v2.17.0 @@ -38,8 +42,11 @@ require ( github.com/urfave/cli/v2 v2.3.0 go.etcd.io/bbolt v1.3.6 go.uber.org/zap v1.20.0 + golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce // indirect golang.org/x/mod v0.5.1 + golang.org/x/net v0.0.0-20220114011407-0dd24b26b47d // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c + golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 sigs.k8s.io/yaml v1.3.0 ) @@ -47,6 +54,11 @@ require ( require ( cloud.google.com/go v0.99.0 // indirect github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect + github.com/Azure/go-autorest v14.2.0+incompatible // indirect + github.com/Azure/go-autorest/autorest/azure/cli v0.4.1 // indirect + github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect + github.com/Azure/go-autorest/logger v0.2.1 // indirect + github.com/Azure/go-autorest/tracing v0.6.0 // indirect github.com/Microsoft/go-winio v0.5.1 // indirect github.com/Microsoft/hcsshim v0.8.23 // indirect github.com/OneOfOne/xxhash v1.2.8 // indirect @@ -66,6 +78,7 @@ require ( github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/dimchansky/utfbom v1.1.1 // indirect github.com/docker/cli v20.10.11+incompatible // indirect github.com/docker/distribution v2.7.1+incompatible // indirect github.com/docker/docker-credential-helpers v0.6.4 // indirect @@ -78,7 +91,7 @@ require ( github.com/gobwas/glob v0.2.3 // indirect github.com/gofrs/uuid v4.0.0+incompatible // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang-jwt/jwt/v4 v4.0.0 // indirect + github.com/golang-jwt/jwt/v4 v4.2.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/uuid v1.3.0 // indirect @@ -123,10 +136,7 @@ require ( go.opencensus.io v0.23.0 // indirect go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect - golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect - golang.org/x/net v0.0.0-20211216030914-fe4d6282115f // indirect golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect - golang.org/x/sys v0.0.0-20211205182925-97ca703d548d // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index 1ab2a1cbd..0480abcd5 100644 --- a/go.sum +++ b/go.sum @@ -75,6 +75,8 @@ github.com/Azure/azure-sdk-for-go v30.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9mo github.com/Azure/azure-sdk-for-go v35.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v38.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v42.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v61.2.0+incompatible h1:sSormXkfW0ov1vh6ihTBRQxdfg73fPqkccl50GbR9iM= +github.com/Azure/azure-sdk-for-go v61.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-service-bus-go v0.9.1/go.mod h1:yzBx6/BUGfjfeqbRZny9AQIbIe3AcV9WZbAdpkoXOa0= github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxwl2B6teiRqI0deQUvsw0= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= @@ -83,28 +85,41 @@ github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSW github.com/Azure/go-autorest v10.15.5+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest v12.0.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest v14.1.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +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.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0= github.com/Azure/go-autorest/autorest v0.9.6/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630= github.com/Azure/go-autorest/autorest v0.10.2/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630= github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= +github.com/Azure/go-autorest/autorest v0.11.6/go.mod h1:V6p3pKZx1KKkJubbxnDWrzNhEIfOy/pTGasLqzHIPHs= +github.com/Azure/go-autorest/autorest v0.11.24 h1:1fIGgHKqVm54KIPT+q8Zmd1QlVsmHqeUGso5qm2BqqE= +github.com/Azure/go-autorest/autorest v0.11.24/go.mod h1:G6kyRlFnTuSbEYkQGawPfsCswgme4iYf6rfSKUDzbCc= github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= github.com/Azure/go-autorest/autorest/adal v0.8.1/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= github.com/Azure/go-autorest/autorest/adal v0.8.3/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= 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.4/go.mod h1:/3SMAM86bP6wC9Ev35peQDUeqFZBMH07vvUOmg4z/fE= github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= +github.com/Azure/go-autorest/autorest/adal v0.9.18 h1:kLnPsRjzZZUF3K5REu/Kc+qMQrvuza2bwSnNdhmzLfQ= +github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= github.com/Azure/go-autorest/autorest/azure/auth v0.4.2/go.mod h1:90gmfKdlmKgfjUpnCEpOJzsUEjrWDSLwHIG73tSXddM= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.2 h1:R1pgoZkhXuv4+0ky9r3e5pcnRXWcXGIuPXpC/xkc7uI= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.2/go.mod h1:q98IH4qgc3eWM4/WOeR5+YPmBuy8Lq0jNRDwSM0CuFk= github.com/Azure/go-autorest/autorest/azure/cli v0.3.1/go.mod h1:ZG5p860J94/0kI9mNJVoIoLgXcirM2gF5i2kWloofxw= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.1 h1:jwcD1wURu0+hKceV04MubZmKLzwEYOCz6q4aOtVZ+Ng= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.1/go.mod h1:JfDgiIO1/RPu6z42AdQTyjOoCM2MFhLqSBDvMEkDgcg= github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= +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.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= 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/autorest/to v0.2.0/go.mod h1:GunWKJp1AEqgMaGLV+iocmRAJWqST1wQYhyyjXJ3SJc= github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= @@ -112,7 +127,10 @@ github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQ github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= +github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= +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/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= @@ -457,6 +475,7 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= +github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U= github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/docker/cli v0.0.0-20190925022749-754388324470/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= @@ -647,8 +666,9 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/golang-jwt/jwt/v4 v4.0.0 h1:RAqyYixv1p7uEnocuy8P1nru5wprCh/MH2BIlW5z5/o= github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-jwt/jwt/v4 v4.2.0 h1:besgBTC8w8HjP6NzQdxwKH9Z5oQMZ24ThTrHp3cZ8eU= +github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= @@ -1566,8 +1586,11 @@ golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce h1:Roh6XWxHFKrPgC/EQhVubSAGQ6Ozk6IdxHSzt1mR0EI= +golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1676,9 +1699,11 @@ golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211111083644-e5c967477495/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211118161319-6a13c67c3ce4/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211216030914-fe4d6282115f h1:hEYJvxw1lSnWIl8X9ofsYMklzaDs90JI2az5YMd4fPM= golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220114011407-0dd24b26b47d h1:1n1fc535VhN8SYtD4cDUyNlfpAF2ROMM9+11equK3hs= +golang.org/x/net v0.0.0-20220114011407-0dd24b26b47d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180724155351-3d292e4d0cdc/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1837,8 +1862,9 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211205182925-97ca703d548d h1:FjkYO/PPp4Wi0EAUOVLxePm7qVW4r4ctbWpURyuOD0E= golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf h1:MZ2shdL+ZM/XzY3ZGOnh4Nlpnxz5GSOhOmtHo3iPU6M= diff --git a/image/token/azure/auth.go b/image/token/azure/auth.go new file mode 100644 index 000000000..3a94db820 --- /dev/null +++ b/image/token/azure/auth.go @@ -0,0 +1,116 @@ +package azure + +import ( + "context" + "fmt" + "time" + + "golang.org/x/xerrors" + + "github.com/Azure/azure-sdk-for-go/profiles/preview/preview/containerregistry/runtime/containerregistry" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/adal" + "github.com/Azure/go-autorest/autorest/azure/auth" +) + +type ACRCredStore struct { + settings auth.EnvironmentSettings + exchangeScheme string + refreshTimeout time.Duration + exchangeTimeout time.Duration +} + +func NewACRCredStore() (*ACRCredStore, error) { + settings, err := auth.GetSettingsFromEnvironment() + if err != nil { + return nil, xerrors.Errorf("failed to get settings from environment: %w", err) + } + + return &ACRCredStore{ + settings: settings, + exchangeScheme: "https", + refreshTimeout: 45 * time.Second, + exchangeTimeout: 15 * time.Second, + }, nil +} + +func (a *ACRCredStore) SetActiveDirectoryEndpoint(uri string) { + a.settings.Environment.ActiveDirectoryEndpoint = uri +} + +func (a *ACRCredStore) SetExchangeScheme(scheme string) { + a.exchangeScheme = scheme +} + +func (a *ACRCredStore) getServicePrincipalToken() (*adal.ServicePrincipalToken, error) { + // 1.Client Credentials + if c, err := a.settings.GetClientCredentials(); err == nil { + oAuthConfig, err := adal.NewOAuthConfig(c.AADEndpoint, c.TenantID) + if err != nil { + return nil, xerrors.Errorf("OAuth config error: %w", err) + } + return adal.NewServicePrincipalToken(*oAuthConfig, c.ClientID, c.ClientSecret, c.Resource) + } + + // 2. Client Certificate + if _, err := a.settings.GetClientCertificate(); err == nil { + return nil, xerrors.New("authentication method clientCertificate currently unsupported") + } + + // 3. Username Password + if _, err := a.settings.GetUsernamePassword(); err == nil { + return nil, xerrors.New("authentication method username/password currently unsupported") + } + + // 4. MSI + config := a.settings.GetMSI() + opts := adal.ManagedIdentityOptions{IdentityResourceID: config.ClientID} + return adal.NewServicePrincipalTokenFromManagedIdentity(a.settings.Environment.ResourceManagerEndpoint, &opts) +} + +func (a *ACRCredStore) getRegistryRefreshToken(ctx context.Context, registry string, sp *adal.ServicePrincipalToken) (*string, error) { + token, repoClient, err := a.refresh(ctx, registry, sp) + if err != nil { + return nil, xerrors.Errorf("refresh error: %w", err) + } + + return a.exchange(ctx, registry, token, repoClient) +} + +func (a *ACRCredStore) refresh(ctx context.Context, registry string, sp *adal.ServicePrincipalToken) ( + adal.Token, containerregistry.RefreshTokensClient, error) { + ctx, cancel := context.WithTimeout(ctx, a.refreshTimeout) + defer cancel() + + err := sp.RefreshWithContext(ctx) + if err != nil { + return adal.Token{}, containerregistry.RefreshTokensClient{}, err + } + token := sp.Token() + repoClient := containerregistry.NewRefreshTokensClient(fmt.Sprintf("%s://%s", a.exchangeScheme, registry)) + repoClient.Authorizer = autorest.NewBearerAuthorizer(sp) + + return token, repoClient, nil +} + +func (a *ACRCredStore) exchange(ctx context.Context, registry string, token adal.Token, + repoClient containerregistry.RefreshTokensClient) (*string, error) { + tenantID := a.settings.Values[auth.TenantID] + ctx, cancel := context.WithTimeout(ctx, a.exchangeTimeout) + defer cancel() + + result, err := repoClient.GetFromExchange(ctx, "access_token", registry, tenantID, "", token.AccessToken) + if err != nil { + return nil, xerrors.Errorf("exchange error: %w", err) + } + + return result.RefreshToken, nil +} + +func (a *ACRCredStore) Get(ctx context.Context, registry string) (*string, error) { + sp, err := a.getServicePrincipalToken() + if err != nil { + return nil, xerrors.Errorf("service principal token error: %w", err) + } + return a.getRegistryRefreshToken(ctx, registry, sp) +} diff --git a/image/token/azure/auth_test.go b/image/token/azure/auth_test.go new file mode 100644 index 000000000..7cf1825ee --- /dev/null +++ b/image/token/azure/auth_test.go @@ -0,0 +1,106 @@ +package azure_test + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "net/http/httptest" + "strconv" + "strings" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/aquasecurity/fanal/image/token/azure" +) + +const ( + // msiEndpointEnv is the environment variable used to store the endpoint on App Service and Functions + msiEndpointEnv = "MSI_ENDPOINT" + + // the format for expires_on in UTC without AM/PM + expiresOnDateFormat = "1/2/2006 15:04:05 +00:00" +) + +func newTokenJSON(expiresIn string, expiresOn time.Time, resource string) string { + return fmt.Sprintf(`{ + "access_token" : "accessToken", + "expires_in" : %s, + "expires_on" : "%s", + "not_before" : "%s", + "resource" : "%s", + "token_type" : "Bearer", + "refresh_token": "FANAL123" + }`, + expiresIn, expiresOn.Format(expiresOnDateFormat), timeToDuration(expiresOn), resource) +} + +func timeToDuration(t time.Time) json.Number { + dur := t.Sub(time.Now().UTC()) + return json.Number(strconv.FormatInt(int64(dur.Round(time.Second).Seconds()), 10)) +} + +func tokenHandle(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(200) + w.Header().Add("Content-Type", "application/json") + + expiresOn := time.Now().UTC().Add(time.Hour) + fmt.Fprint(w, newTokenJSON("3600", expiresOn, "test")) +} + +func TestAzureTokenMSI(t *testing.T) { + mux := http.NewServeMux() + mux.HandleFunc("/metadata/identity/oauth2/token", tokenHandle) + mux.HandleFunc("/oauth2/exchange", tokenHandle) + + server := httptest.NewServer(mux) + t.Cleanup(server.Close) + + t.Setenv(msiEndpointEnv, fmt.Sprintf("%s/metadata/identity/oauth2/token", server.URL)) + + aa, err := azure.NewACRCredStore() + require.NoError(t, err) + + aa.SetExchangeScheme("http") + + token, err := aa.Get(context.Background(), strings.Replace(server.URL, "http://", "", -1)) + + require.NoError(t, err) + assert.Equal(t, *token, "FANAL123") +} + +func TestAzureTokenCredentials(t *testing.T) { + mux := http.NewServeMux() + mux.HandleFunc("/oauth2/exchange", tokenHandle) + mux.HandleFunc("/oauth2/token", tokenHandle) + + server := httptest.NewServer(mux) + t.Cleanup(server.Close) + + t.Setenv("AZURE_CLIENT_SECRET", "Test") + t.Setenv("AZURE_CLIENT_ID", "Test") + + aa, err := azure.NewACRCredStore() + require.Empty(t, err) + + aa.SetExchangeScheme("http") + aa.SetActiveDirectoryEndpoint(server.URL) + + token, err := aa.Get(context.Background(), strings.Replace(server.URL, "http://", "", -1)) + + require.NoError(t, err) + assert.Equal(t, *token, "FANAL123") +} + +func TestAzureTokenCredentialsError(t *testing.T) { + t.Setenv("AZURE_CLIENT_SECRET", "Test") + + aa, err := azure.NewACRCredStore() + require.NoError(t, err) + + _, err = aa.Get(context.Background(), "") + assert.Error(t, err) +} diff --git a/image/token/azure/azure.go b/image/token/azure/azure.go new file mode 100644 index 000000000..3c8686a21 --- /dev/null +++ b/image/token/azure/azure.go @@ -0,0 +1,36 @@ +package azure + +import ( + "context" + "strings" + + "golang.org/x/xerrors" + + "github.com/aquasecurity/fanal/types" +) + +type Registry struct { + domain string +} + +const azureURL = "azurecr.io" + +func (r *Registry) CheckOptions(domain string, _ types.DockerOption) error { + if !strings.HasSuffix(domain, azureURL) { + return xerrors.Errorf("Azure registry: %w", types.InvalidURLPattern) + } + r.domain = domain + return nil +} + +func (r *Registry) GetCredential(ctx context.Context) (string, string, error) { + credStore, err := NewACRCredStore() + if err != nil { + return "", "", xerrors.Errorf("ACR credential error: %w", err) + } + token, err := credStore.Get(ctx, r.domain) + if err != nil { + return "", "", xerrors.Errorf("unable to get a token: %w", err) + } + return "00000000-0000-0000-0000-000000000000", *token, err +} diff --git a/image/token/azure/azure_test.go b/image/token/azure/azure_test.go new file mode 100644 index 000000000..e79d793b5 --- /dev/null +++ b/image/token/azure/azure_test.go @@ -0,0 +1,39 @@ +package azure_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/aquasecurity/fanal/image/token/azure" + "github.com/aquasecurity/fanal/types" +) + +func TestRegistry_CheckOptions(t *testing.T) { + tests := []struct { + name string + domain string + wantErr string + }{ + { + name: "happy path", + domain: "test.azurecr.io", + }, + { + name: "invalidURL", + domain: "alpine:3.9", + wantErr: "Azure registry: invalid url pattern", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + r := azure.Registry{} + err := r.CheckOptions(tt.domain, types.DockerOption{}) + if tt.wantErr != "" { + assert.EqualError(t, err, tt.wantErr) + } else { + assert.NoError(t, err) + } + }) + } +} diff --git a/image/token/token.go b/image/token/token.go index f8ff1c830..b2d49d3aa 100644 --- a/image/token/token.go +++ b/image/token/token.go @@ -3,10 +3,12 @@ package token import ( "context" - "github.com/aquasecurity/fanal/image/token/ecr" - "github.com/aquasecurity/fanal/image/token/google" "github.com/google/go-containerregistry/pkg/authn" + "github.com/aquasecurity/fanal/image/token/azure" + "github.com/aquasecurity/fanal/image/token/ecr" + "github.com/aquasecurity/fanal/image/token/google" + "github.com/aquasecurity/fanal/log" "github.com/aquasecurity/fanal/types" ) @@ -17,6 +19,7 @@ var ( func init() { RegisterRegistry(&google.Registry{}) RegisterRegistry(&ecr.ECR{}) + RegisterRegistry(&azure.Registry{}) } type Registry interface { @@ -42,6 +45,7 @@ func GetToken(ctx context.Context, domain string, opt types.DockerOption) (auth username, password, err := registry.GetCredential(ctx) if err != nil { // only skip check registry if error occurred + log.Logger.Debug(err) break } return authn.Basic{Username: username, Password: password}