Add some target fields and move some things around (#3879)

In preparation for putting proxy code in the api package this creates some necessary fields in the target output and it pre-moves credential parsing and proxy handshake code to their new places. This will make the diff for the actual proxy code move quite a bit smaller.

Co-authored-by: Johan Brandhorst-Satzkorn <johan.brandhorst@gmail.com>
This commit is contained in:
Jeff MitchellandJohan Brandhorst-Satzkorn authored and GitHub committed 2023-10-22 20:48:54 -04:00
1 parent 82b3f202c0
commit fb4a5a98dc
27 files changed
+733 -444

No files matched your search

+10 -8
View File
@@ -3,6 +3,7 @@ module github.com/hashicorp/boundary/api
go 1.19
require (
github.com/hashicorp/boundary/sdk v0.0.38-0.20231020201735-7958b5ab8112
github.com/hashicorp/go-cleanhttp v0.5.2
github.com/hashicorp/go-kms-wrapping/v2 v2.0.9
github.com/hashicorp/go-retryablehttp v0.7.2
@@ -19,18 +20,19 @@ require (
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.14.1 // indirect
github.com/hashicorp/go-hclog v1.4.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/eventlogger v0.1.2-0.20230428153751-cca445805f24 // indirect
github.com/hashicorp/eventlogger/filters/encrypt v0.1.8-0.20230428153751-cca445805f24 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect
github.com/hashicorp/go-sockaddr v1.0.2 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/pointerstructure v1.2.1 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.6.2 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
golang.org/x/crypto v0.6.0 // indirect
google.golang.org/genproto v0.0.0-20230227214838-9b19f0bdc514 // indirect
golang.org/x/crypto v0.14.0 // indirect
google.golang.org/genproto v0.0.0-20230303212802-e74f57abe488 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
+93 -23
View File
@@ -1,97 +1,164 @@
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g=
github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w=
github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho=
github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/hashicorp/boundary/sdk v0.0.38-0.20231020201735-7958b5ab8112 h1:mRwMQffT7N6MIdJ3ofGqZyA4WoF8tYgIH5VFeTtDpNg=
github.com/hashicorp/boundary/sdk v0.0.38-0.20231020201735-7958b5ab8112/go.mod h1:KKhN2Hax1SFl6owEMh89umWlWU7S2v3z1QhSBUJfU1A=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/eventlogger v0.1.2-0.20230428153751-cca445805f24 h1:vtCJgcxwDMFrpUgVMfjtwXY1YqvHbj8pNA7GsXYEoLg=
github.com/hashicorp/eventlogger v0.1.2-0.20230428153751-cca445805f24/go.mod h1://CHt6/j+Q2lc0NlUB5af4aS2M0c0aVBg9/JfcpAyhM=
github.com/hashicorp/eventlogger/filters/encrypt v0.1.8-0.20230428153751-cca445805f24 h1:mopKPTxSaVr24uSysyRwywTDs85L5b05qqZvEkWa0qc=
github.com/hashicorp/eventlogger/filters/encrypt v0.1.8-0.20230428153751-cca445805f24/go.mod h1:EQPLoX6CONA9BSYUovTQBHfPGE91g7wOxv03sO29FzY=
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-hclog v1.4.0 h1:ctuWFGrhFha8BnnzxqeRGidlEcQkDyL5u8J8t5eA11I=
github.com/hashicorp/go-hclog v1.4.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c=
github.com/hashicorp/go-kms-wrapping/plugin/v2 v2.0.4 h1:8z+Zi0uLYXONkxwWb/D7O5t1IUucB6Ft3uvSOa950bM=
github.com/hashicorp/go-kms-wrapping/v2 v2.0.9 h1:JpCvi97NMA+saNqO8ovQcGoRbBq6P5ZZlJqvOsW5ick=
github.com/hashicorp/go-kms-wrapping/v2 v2.0.9/go.mod h1:NtMaPhqSlfQ72XWDD2g80o8HI8RKkowIB8/WZHMyPY4=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/go-plugin v1.4.9 h1:ESiK220/qE0aGxWdzKIvRH69iLiuN/PjoLTm69RoWtU=
github.com/hashicorp/go-retryablehttp v0.7.2 h1:AcYqCvkpalPnPF2pn0KamgwamS42TqUDDYFRKq/RAd0=
github.com/hashicorp/go-retryablehttp v0.7.2/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
github.com/hashicorp/go-secure-stdlib/base62 v0.1.1/go.mod h1:EdWO6czbmthiwZ3/PUsDV+UD1D5IRU4ActiaWGwt0Yw=
github.com/hashicorp/go-secure-stdlib/base62 v0.1.2 h1:ET4pqyjiGmY09R5y+rSd70J2w45CtbWDNvGqWp/R3Ng=
github.com/hashicorp/go-secure-stdlib/configutil/v2 v2.0.9 h1:YZ01/aiARPneDUryzjiPGvr3pmjCSC+1WBZKI1P7I7k=
github.com/hashicorp/go-secure-stdlib/listenerutil v0.1.6 h1:rOmnqOSUBn5opme1Kh9OXO8qWd0KztO+f02vvCwCc/w=
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.7 h1:UpiO20jno/eV1eVZcxqWnUohyKRe1g8FPV/xH1s/2qs=
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.7/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8=
github.com/hashicorp/go-secure-stdlib/pluginutil/v2 v2.0.4 h1:IU2iGcvthrJ53rPbQU6B4+iVs/cLPO89ti5dd2XEj3k=
github.com/hashicorp/go-secure-stdlib/reloadutil v0.1.1 h1:SMGUnbpAcat8rIKHkBPjfv81yC46a8eCNZ2hsR2l1EI=
github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U=
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts=
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4=
github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.2 h1:phcbL8urUzF/kxA/Oj6awENaRwfWsjP59GW7u2qlDyY=
github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc=
github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A=
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU=
github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
github.com/jefferai/isbadcipher v0.0.0-20190226160619-51d2077c035f h1:E87tDTVS5W65euzixn7clSzK66puSt1H4I5SC0EmHH4=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/cli v1.1.5 h1:OxRIeJXpAMztws/XHlN2vu6imG5Dpq+j61AzAX5fLng=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/pointerstructure v1.2.1 h1:ZhBBeX8tSlRpu/FFhXH4RC4OJzFlqsQhoHZAz4x7TIw=
github.com/mitchellh/pointerstructure v1.2.1/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo=
github.com/rogpeppe/go-internal v1.6.2 h1:aIihoIOHCiLZHxyoNQ+ABL4NKhFTgKLBdMLyEAh98m0=
github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.uber.org/goleak v1.0.0 h1:qsup4IcBdlmsnGfqyLl4Ntn3C2XCCuKAE7DwHpScyUo=
go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20210101214203-2dba1e4ea05c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto v0.0.0-20230227214838-9b19f0bdc514 h1:rtNKfB++wz5mtDY2t5C8TXlU5y52ojSu7tZo0z7u8eQ=
google.golang.org/genproto v0.0.0-20230227214838-9b19f0bdc514/go.mod h1:TvhZT5f700eVlTNwND1xoEZQeWTB2RY/65kplwl/bFA=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto v0.0.0-20230303212802-e74f57abe488 h1:QQF+HdiI4iocoxUjjpLgvTYDHKm99C/VtTBFnfiCJos=
google.golang.org/genproto v0.0.0-20230303212802-e74f57abe488/go.mod h1:TvhZT5f700eVlTNwND1xoEZQeWTB2RY/65kplwl/bFA=
google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc=
google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
@@ -100,7 +167,10 @@ google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
mvdan.cc/gofumpt v0.1.1/go.mod h1:yXG1r1WqZVKWbVRtBWKWX9+CxGYfA51nSomhM0woR48=
+135
View File
@@ -0,0 +1,135 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package proxy
import (
"errors"
"github.com/hashicorp/boundary/api/targets"
"github.com/mitchellh/mapstructure"
)
const (
usernamePasswordCredentialType = "username_password"
sshPrivateKeyCredentialType = "ssh_private_key"
)
// UsernamePassword contains username and password credentials
type UsernamePassword struct {
Username string `mapstructure:"username"`
Password string `mapstructure:"password"`
Raw *targets.SessionCredential
// Consumed can be set by the caller to indicate that the credential has
// been used, e.g. displayed to the user
Consumed bool
}
// SshPrivateKey contains the username and private key with optional passphrase
// for the key
type SshPrivateKey struct {
Username string `mapstructure:"username"`
PrivateKey string `mapstructure:"private_key"`
Passphrase string `mapstructure:"private_key_passphrase"`
Raw *targets.SessionCredential
// Consumed can be set by the caller to indicate that the credential has
// been used, e.g. displayed to the user
Consumed bool
}
type Credentials struct {
UsernamePassword []UsernamePassword
SshPrivateKey []SshPrivateKey
// Unspecified are credentials that do not match one of the types above
Unspecified []*targets.SessionCredential
}
func (c Credentials) UnconsumedSessionCredentials() []*targets.SessionCredential {
out := make([]*targets.SessionCredential, 0, len(c.SshPrivateKey)+len(c.UsernamePassword)+len(c.Unspecified))
// Unspecified credentials cannot be consumed
out = append(out, c.Unspecified...)
for _, c := range c.SshPrivateKey {
if !c.Consumed {
out = append(out, c.Raw)
}
}
for _, c := range c.UsernamePassword {
if !c.Consumed {
out = append(out, c.Raw)
}
}
return out
}
func ParseCredentials(creds []*targets.SessionCredential) (Credentials, error) {
if creds == nil {
return Credentials{}, nil
}
var out Credentials
for _, cred := range creds {
if cred.CredentialSource == nil {
return Credentials{}, errors.New("missing credential source")
}
var upCred UsernamePassword
var spkCred SshPrivateKey
switch cred.CredentialSource.CredentialType {
case usernamePasswordCredentialType:
// Decode attributes from credential struct
if err := mapstructure.Decode(cred.Credential, &upCred); err != nil {
return Credentials{}, err
}
if upCred.Username != "" && upCred.Password != "" {
upCred.Raw = cred
out.UsernamePassword = append(out.UsernamePassword, upCred)
continue
}
case sshPrivateKeyCredentialType:
// Decode attributes from credential struct
if err := mapstructure.Decode(cred.Credential, &spkCred); err != nil {
return Credentials{}, err
}
if spkCred.Username != "" && spkCred.PrivateKey != "" {
spkCred.Raw = cred
out.SshPrivateKey = append(out.SshPrivateKey, spkCred)
continue
}
}
// Credential type is unspecified, make a best effort attempt to parse
// a credential from the Decoded field if it exists
if cred.Secret != nil && cred.Secret.Decoded != nil {
// Attempt unmarshaling into username password creds
if err := mapstructure.Decode(cred.Secret.Decoded, &upCred); err != nil {
return Credentials{}, err
}
if upCred.Username != "" && upCred.Password != "" {
upCred.Raw = cred
out.UsernamePassword = append(out.UsernamePassword, upCred)
continue
}
// Attempt unmarshaling into ssh private key creds
if err := mapstructure.Decode(cred.Secret.Decoded, &spkCred); err != nil {
return Credentials{}, err
}
if spkCred.Username != "" && spkCred.PrivateKey != "" {
spkCred.Raw = cred
out.SshPrivateKey = append(out.SshPrivateKey, spkCred)
continue
}
}
// We could not parse the credential
out.Unspecified = append(out.Unspecified, cred)
}
return out, nil
}
+629
View File
@@ -0,0 +1,629 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package proxy
import (
"testing"
"github.com/hashicorp/boundary/api/targets"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
const (
staticSubtype = "static"
vaultSubtype = "vault"
vaultGenericLibrarySubtype = "vault-generic"
vaultSshCertificateLibrarySubtype = "vault-ssh-certificate"
)
var (
typedUsernamePassword = &targets.SessionCredential{
CredentialSource: &targets.CredentialSource{
CredentialType: usernamePasswordCredentialType,
},
Credential: map[string]any{
"username": "user",
"password": "pass",
},
}
typedSshPrivateKey = &targets.SessionCredential{
CredentialSource: &targets.CredentialSource{
CredentialType: sshPrivateKeyCredentialType,
},
Credential: map[string]any{
"username": "user",
"private_key": "my-pk",
},
}
vaultUsernamePasswordDeprecatedSubtype = &targets.SessionCredential{
CredentialSource: &targets.CredentialSource{
Type: vaultSubtype,
},
Secret: &targets.SessionSecret{
Decoded: map[string]any{
"username": "vault-decoded-user",
"password": "vault-decoded-pass",
},
},
}
vaultSshPrivateKeyDeprecatedSubtype = &targets.SessionCredential{
CredentialSource: &targets.CredentialSource{
Type: vaultSubtype,
},
Secret: &targets.SessionSecret{
Decoded: map[string]any{
"username": "vault-decoded-user",
"private_key": "vault-decoded-pk",
},
},
}
vaultUsernamePassword = &targets.SessionCredential{
CredentialSource: &targets.CredentialSource{
Type: vaultGenericLibrarySubtype,
},
Secret: &targets.SessionSecret{
Decoded: map[string]any{
"username": "vault-decoded-user",
"password": "vault-decoded-pass",
},
},
}
vaultSshPrivateKey = &targets.SessionCredential{
CredentialSource: &targets.CredentialSource{
Type: vaultGenericLibrarySubtype,
},
Secret: &targets.SessionSecret{
Decoded: map[string]any{
"username": "vault-decoded-user",
"private_key": "vault-decoded-pk",
},
},
}
unknownUsernamePassword = &targets.SessionCredential{
CredentialSource: &targets.CredentialSource{},
Secret: &targets.SessionSecret{
Decoded: map[string]any{
"username": "unknown-decoded-user",
"password": "unknown-decoded-pass",
},
},
}
unknownSshPrivateKey = &targets.SessionCredential{
CredentialSource: &targets.CredentialSource{},
Secret: &targets.SessionSecret{
Decoded: map[string]any{
"username": "unknown-decoded-user",
"private_key": "unknown-decoded-pk",
},
},
}
staticUsernamePassword = &targets.SessionCredential{
CredentialSource: &targets.CredentialSource{
Type: staticSubtype,
},
Secret: &targets.SessionSecret{
Decoded: map[string]any{
"username": "static-decoded-user",
"password": "static-decoded-pass",
},
},
}
staticSshPrivateKey = &targets.SessionCredential{
CredentialSource: &targets.CredentialSource{
Type: staticSubtype,
},
Secret: &targets.SessionSecret{
Decoded: map[string]any{
"username": "static-decoded-user",
"private_key": "static-decoded-pk",
},
},
}
staticKv = &targets.SessionCredential{
CredentialSource: &targets.CredentialSource{
Type: staticSubtype,
CredentialType: "json",
CredentialStoreId: "csst_id",
Description: "test",
Name: "test Unspecified json cred",
Id: "credjson_id",
},
Secret: &targets.SessionSecret{
Decoded: map[string]any{
"secret": map[string]any{
"username": "password",
},
},
},
}
UnspecifiedCred = &targets.SessionCredential{
CredentialSource: &targets.CredentialSource{
Type: staticSubtype,
},
Secret: &targets.SessionSecret{
Decoded: map[string]any{
"username": "decoded-user",
"some-value": "decoded-some-value",
},
},
}
UnspecifiedCred1 = &targets.SessionCredential{
CredentialSource: &targets.CredentialSource{
Type: staticSubtype,
},
Secret: &targets.SessionSecret{
Decoded: map[string]any{
"username": "decoded-user",
"some-value1": "decoded-some-value1",
},
},
}
)
func Test_parseCredentials(t *testing.T) {
tests := []struct {
name string
creds []*targets.SessionCredential
wantCreds Credentials
wantErr bool
}{
{
name: "no-creds",
wantErr: false,
},
{
name: "no-credential-source",
creds: []*targets.SessionCredential{
{
Secret: &targets.SessionSecret{
Decoded: map[string]any{
"username": "decoded-user",
"private_key": "decoded-pk",
},
},
},
},
wantErr: true,
},
{
name: "username-password-typed",
creds: []*targets.SessionCredential{
typedUsernamePassword,
},
wantCreds: Credentials{
UsernamePassword: []UsernamePassword{
{
Username: "user",
Password: "pass",
Raw: typedUsernamePassword,
},
},
},
wantErr: false,
},
{
name: "ssh-private-key-typed",
creds: []*targets.SessionCredential{
typedSshPrivateKey,
},
wantCreds: Credentials{
SshPrivateKey: []SshPrivateKey{
{
Username: "user",
PrivateKey: "my-pk",
Raw: typedSshPrivateKey,
},
},
},
wantErr: false,
},
{
name: "vault-username-password-decoded",
creds: []*targets.SessionCredential{
vaultUsernamePassword,
},
wantCreds: Credentials{
UsernamePassword: []UsernamePassword{
{
Username: "vault-decoded-user",
Password: "vault-decoded-pass",
Raw: vaultUsernamePassword,
},
},
},
wantErr: false,
},
{
name: "vault-private-key-decoded",
creds: []*targets.SessionCredential{
vaultSshPrivateKey,
},
wantCreds: Credentials{
SshPrivateKey: []SshPrivateKey{
{
Username: "vault-decoded-user",
PrivateKey: "vault-decoded-pk",
Raw: vaultSshPrivateKey,
},
},
},
wantErr: false,
},
{
name: "vault-deprecated-username-password-decoded",
creds: []*targets.SessionCredential{
vaultUsernamePasswordDeprecatedSubtype,
},
wantCreds: Credentials{
UsernamePassword: []UsernamePassword{
{
Username: "vault-decoded-user",
Password: "vault-decoded-pass",
Raw: vaultUsernamePasswordDeprecatedSubtype,
},
},
},
wantErr: false,
},
{
name: "vault-deprecated-private-key-decoded",
creds: []*targets.SessionCredential{
vaultSshPrivateKeyDeprecatedSubtype,
},
wantCreds: Credentials{
SshPrivateKey: []SshPrivateKey{
{
Username: "vault-decoded-user",
PrivateKey: "vault-decoded-pk",
Raw: vaultSshPrivateKeyDeprecatedSubtype,
},
},
},
wantErr: false,
},
{
name: "unknown-username-password-decoded",
creds: []*targets.SessionCredential{
unknownUsernamePassword,
},
wantCreds: Credentials{
UsernamePassword: []UsernamePassword{
{
Username: "unknown-decoded-user",
Password: "unknown-decoded-pass",
Raw: unknownUsernamePassword,
},
},
},
wantErr: false,
},
{
name: "unknown-private-key-decoded",
creds: []*targets.SessionCredential{
unknownSshPrivateKey,
},
wantCreds: Credentials{
SshPrivateKey: []SshPrivateKey{
{
Username: "unknown-decoded-user",
PrivateKey: "unknown-decoded-pk",
Raw: unknownSshPrivateKey,
},
},
},
wantErr: false,
},
{
name: "static-username-password-decoded",
creds: []*targets.SessionCredential{
staticUsernamePassword,
},
wantCreds: Credentials{
UsernamePassword: []UsernamePassword{
{
Username: "static-decoded-user",
Password: "static-decoded-pass",
Raw: staticUsernamePassword,
},
},
},
wantErr: false,
},
{
name: "static-private-key-decoded",
creds: []*targets.SessionCredential{
staticSshPrivateKey,
},
wantCreds: Credentials{
SshPrivateKey: []SshPrivateKey{
{
Username: "static-decoded-user",
PrivateKey: "static-decoded-pk",
Raw: staticSshPrivateKey,
},
},
},
wantErr: false,
},
{
name: "Unspecified",
creds: []*targets.SessionCredential{
UnspecifiedCred,
},
wantCreds: Credentials{
Unspecified: []*targets.SessionCredential{
UnspecifiedCred,
},
},
wantErr: false,
},
{
name: "Unspecified-static-json",
creds: []*targets.SessionCredential{
staticKv,
},
wantCreds: Credentials{
Unspecified: []*targets.SessionCredential{
staticKv,
},
},
wantErr: false,
},
{
name: "mixed",
creds: []*targets.SessionCredential{
staticSshPrivateKey, UnspecifiedCred1, vaultSshPrivateKey, typedUsernamePassword,
UnspecifiedCred, vaultUsernamePassword, typedSshPrivateKey, staticUsernamePassword,
staticKv,
},
wantCreds: Credentials{
SshPrivateKey: []SshPrivateKey{
{
Username: "static-decoded-user",
PrivateKey: "static-decoded-pk",
Raw: staticSshPrivateKey,
},
{
Username: "vault-decoded-user",
PrivateKey: "vault-decoded-pk",
Raw: vaultSshPrivateKey,
},
{
Username: "user",
PrivateKey: "my-pk",
Raw: typedSshPrivateKey,
},
},
UsernamePassword: []UsernamePassword{
{
Username: "static-decoded-user",
Password: "static-decoded-pass",
Raw: staticUsernamePassword,
},
{
Username: "vault-decoded-user",
Password: "vault-decoded-pass",
Raw: vaultUsernamePassword,
},
{
Username: "user",
Password: "pass",
Raw: typedUsernamePassword,
},
},
Unspecified: []*targets.SessionCredential{
UnspecifiedCred, UnspecifiedCred1, staticKv,
},
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
creds, err := ParseCredentials(tt.creds)
if tt.wantErr {
require.Error(err)
assert.Empty(creds)
return
}
require.NoError(err)
assert.ElementsMatch(tt.wantCreds.UsernamePassword, creds.UsernamePassword)
assert.ElementsMatch(tt.wantCreds.SshPrivateKey, creds.SshPrivateKey)
assert.ElementsMatch(tt.wantCreds.Unspecified, creds.Unspecified)
})
}
}
func Test_unconsumedSessionCredentials(t *testing.T) {
tests := []struct {
name string
creds Credentials
wantCreds []*targets.SessionCredential
}{
{
name: "no-creds",
wantCreds: nil,
},
{
name: "spk-consumed",
creds: Credentials{
SshPrivateKey: []SshPrivateKey{
{
Raw: staticSshPrivateKey,
Consumed: true,
},
},
},
wantCreds: nil,
},
{
name: "spk",
creds: Credentials{
SshPrivateKey: []SshPrivateKey{
{
Raw: staticSshPrivateKey,
},
},
},
wantCreds: []*targets.SessionCredential{staticSshPrivateKey},
},
{
name: "up",
creds: Credentials{
UsernamePassword: []UsernamePassword{
{
Raw: vaultUsernamePassword,
},
},
},
wantCreds: []*targets.SessionCredential{vaultUsernamePassword},
},
{
name: "up-consumed",
creds: Credentials{
UsernamePassword: []UsernamePassword{
{
Raw: vaultUsernamePassword,
Consumed: true,
},
},
},
wantCreds: nil,
},
{
name: "Unspecified",
creds: Credentials{
Unspecified: []*targets.SessionCredential{UnspecifiedCred},
},
wantCreds: []*targets.SessionCredential{UnspecifiedCred},
},
{
name: "mixed",
creds: Credentials{
SshPrivateKey: []SshPrivateKey{
{
Raw: staticSshPrivateKey,
Consumed: true,
},
{
Raw: vaultSshPrivateKey,
},
{
Raw: typedSshPrivateKey,
},
},
UsernamePassword: []UsernamePassword{
{
Raw: staticUsernamePassword,
Consumed: true,
},
{
Raw: vaultUsernamePassword,
},
{
Raw: typedUsernamePassword,
Consumed: true,
},
},
Unspecified: []*targets.SessionCredential{UnspecifiedCred, UnspecifiedCred1},
},
wantCreds: []*targets.SessionCredential{
vaultSshPrivateKey, typedSshPrivateKey, vaultUsernamePassword, UnspecifiedCred, UnspecifiedCred1,
},
},
{
name: "mixed-all-consumed",
creds: Credentials{
SshPrivateKey: []SshPrivateKey{
{
Raw: staticSshPrivateKey,
Consumed: true,
},
{
Raw: vaultSshPrivateKey,
Consumed: true,
},
{
Raw: typedSshPrivateKey,
Consumed: true,
},
},
UsernamePassword: []UsernamePassword{
{
Raw: staticUsernamePassword,
Consumed: true,
},
{
Raw: vaultUsernamePassword,
Consumed: true,
},
{
Raw: typedUsernamePassword,
Consumed: true,
},
},
Unspecified: []*targets.SessionCredential{UnspecifiedCred, UnspecifiedCred1},
},
wantCreds: []*targets.SessionCredential{
UnspecifiedCred1, UnspecifiedCred,
},
},
{
name: "mixed-all-unconsumed",
creds: Credentials{
SshPrivateKey: []SshPrivateKey{
{
Raw: staticSshPrivateKey,
},
{
Raw: vaultSshPrivateKey,
},
{
Raw: typedSshPrivateKey,
},
},
UsernamePassword: []UsernamePassword{
{
Raw: staticUsernamePassword,
},
{
Raw: vaultUsernamePassword,
},
{
Raw: typedUsernamePassword,
},
},
Unspecified: []*targets.SessionCredential{UnspecifiedCred, UnspecifiedCred1},
},
wantCreds: []*targets.SessionCredential{
staticSshPrivateKey, UnspecifiedCred1, vaultSshPrivateKey, typedUsernamePassword,
UnspecifiedCred, vaultUsernamePassword, typedSshPrivateKey, staticUsernamePassword,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert := assert.New(t)
creds := tt.creds.UnconsumedSessionCredentials()
assert.ElementsMatch(tt.wantCreds, creds)
})
}
}
+57
View File
@@ -5,10 +5,17 @@ package targets
import (
"context"
"encoding/json"
"errors"
"fmt"
"net/url"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/scopes"
targetspb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/targets"
"github.com/mr-tron/base58"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
)
type SessionAuthorizationResult struct {
@@ -24,6 +31,56 @@ func (n SessionAuthorizationResult) GetResponse() *api.Response {
return n.response
}
func (n SessionAuthorizationResult) GetSessionAuthorization() (*SessionAuthorization, error) {
result, ok := n.GetItem().(*SessionAuthorization)
if !ok {
return nil, fmt.Errorf("unable to interpret session authorization result as session authorization data")
}
return result, nil
}
func (n SessionAuthorization) GetSessionAuthorizationData() (*SessionAuthorizationData, error) {
if n.AuthorizationToken == "" {
return nil, fmt.Errorf("authorization token is empty")
}
marshaled, err := base58.FastBase58Decoding(n.AuthorizationToken)
if err != nil {
return nil, fmt.Errorf("unable to base58-decode authorization token: %w", err)
}
if len(marshaled) == 0 {
return nil, errors.New("zero-length authorization information after decoding")
}
// Marshal using protojson and unmarshal using json, rather than statically
// copying
d := new(targetspb.SessionAuthorizationData)
if err := proto.Unmarshal(marshaled, d); err != nil {
return nil, fmt.Errorf("unable to unmarshal authorization data: %w", err)
}
jsBytes, err := protojson.MarshalOptions{
UseProtoNames: true,
EmitUnpopulated: false,
}.Marshal(d)
if err != nil {
return nil, fmt.Errorf("error marshaling decoded proto as json: %w", err)
}
ret := &SessionAuthorizationData{
Scope: &scopes.ScopeInfo{},
}
if err := json.Unmarshal(jsBytes, ret); err != nil {
return nil, fmt.Errorf("error unmashaling protojson bytes: %w", err)
}
ret.WorkerInfo = make([]*WorkerInfo, len(d.WorkerInfo))
for i, w := range d.WorkerInfo {
ret.WorkerInfo[i] = &WorkerInfo{
Address: w.Address,
}
}
return ret, nil
}
func (c *Client) AuthorizeSession(ctx context.Context, targetId string, opt ...Option) (*SessionAuthorizationResult, error) {
opts, apiOpts := getOpts(opt...)
+2
View File
@@ -21,5 +21,7 @@ type SessionAuthorization struct {
Type string `json:"type,omitempty"`
AuthorizationToken string `json:"authorization_token,omitempty"`
Endpoint string `json:"endpoint,omitempty"`
EndpointPort uint32 `json:"endpoint_port,omitempty"`
Expiration time.Time `json:"expiration,omitempty"`
Credentials []*SessionCredential `json:"credentials,omitempty"`
}
@@ -0,0 +1,28 @@
// Code generated by "make api"; DO NOT EDIT.
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package targets
import (
"time"
"github.com/hashicorp/boundary/api/scopes"
)
type SessionAuthorizationData struct {
SessionId string `json:"session_id,omitempty"`
TargetId string `json:"target_id,omitempty"`
Scope *scopes.ScopeInfo `json:"scope,omitempty"`
CreatedTime time.Time `json:"created_time,omitempty"`
Type string `json:"type,omitempty"`
ConnectionLimit int32 `json:"connection_limit,omitempty"`
EndpointPort uint32 `json:"endpoint_port,omitempty"`
Expiration time.Time `json:"expiration,omitempty"`
Certificate []byte `json:"certificate,omitempty"`
PrivateKey []byte `json:"private_key,omitempty"`
HostId string `json:"host_id,omitempty"`
Endpoint string `json:"endpoint,omitempty"`
WorkerInfo []*WorkerInfo `json:"worker_info,omitempty"`
DefaultClientPort uint32 `json:"default_client_port,omitempty"`
}