diff --git a/go.mod b/go.mod index 954ee70..60d095d 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,8 @@ go 1.24.2 require ( github.com/BurntSushi/toml v1.5.0 - github.com/canonical/lxd v0.0.0-20250521083810-5973602f3c07 - github.com/cloudbase/garm-provider-common v0.1.5-0.20250417155201-8ef03502d06e + github.com/canonical/lxd v0.0.0-20250619222212-79e5fb724a99 + github.com/cloudbase/garm-provider-common v0.1.5 github.com/gorilla/websocket v1.5.4-0.20240702125206-a62d9d2a8413 github.com/juju/clock v1.1.1 github.com/juju/retry v1.0.1 @@ -18,12 +18,12 @@ require ( github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/buger/jsonparser v1.1.1 // indirect github.com/go-jose/go-jose/v4 v4.1.0 // indirect - github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/mailru/easyjson v0.9.0 // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/zitadel/logging v0.6.2 // indirect - github.com/zitadel/oidc/v3 v3.38.1 // indirect + github.com/zitadel/oidc/v3 v3.39.0 // indirect github.com/zitadel/schema v1.3.1 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/otel v1.36.0 // indirect @@ -46,19 +46,19 @@ require ( github.com/minio/sio v0.4.1 // indirect github.com/muhlemmer/gu v0.3.1 // indirect github.com/pkg/sftp v1.13.9 // indirect - github.com/pkg/xattr v0.4.10 // indirect + github.com/pkg/xattr v0.4.11 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - golang.org/x/crypto v0.38.0 // indirect - golang.org/x/net v0.40.0 // indirect + golang.org/x/crypto v0.39.0 // indirect + golang.org/x/net v0.41.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect golang.org/x/sys v0.33.0 // indirect golang.org/x/term v0.32.0 // indirect - golang.org/x/text v0.25.0 // indirect + golang.org/x/text v0.26.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 71a8258..cb0050d 100644 --- a/go.sum +++ b/go.sum @@ -6,10 +6,10 @@ github.com/bmatcuk/doublestar/v4 v4.8.1 h1:54Bopc5c2cAvhLRAzqOGCYHYyhcDHsFF4wWIR github.com/bmatcuk/doublestar/v4 v4.8.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= -github.com/canonical/lxd v0.0.0-20250521083810-5973602f3c07 h1:8AJtIK98mFoWPrrg3p9uXtwb06hMwcziO0TSr0spTUk= -github.com/canonical/lxd v0.0.0-20250521083810-5973602f3c07/go.mod h1:npKjgy12aAG2m8DBK6JuX3pCakrs6h9TvFGh1dNuNzk= -github.com/cloudbase/garm-provider-common v0.1.5-0.20250417155201-8ef03502d06e h1:giq2Prk9I/ez1dc4/r9jivf2jbhjX9apZ41TWQ5g3qE= -github.com/cloudbase/garm-provider-common v0.1.5-0.20250417155201-8ef03502d06e/go.mod h1:sSrTBtTc0q72MZdmS9EuLLdDhkmXZAqAwRIgEK0TqUo= +github.com/canonical/lxd v0.0.0-20250619222212-79e5fb724a99 h1:iZUoo20oLtmB/3u1vZ86djlwDY4XDqG19K/bkvprWao= +github.com/canonical/lxd v0.0.0-20250619222212-79e5fb724a99/go.mod h1:EJhP7sF2fUMTf5U7pJFvxsRnBZA8j9EhUOWbBdtFWFc= +github.com/cloudbase/garm-provider-common v0.1.5 h1:aJL646l+VnZceQ2grbDYhWfxYpaQR2/QsUSD76kSZVs= +github.com/cloudbase/garm-provider-common v0.1.5/go.mod h1:2O51WbcfqRx5fDHyyJgIFq7KdTZZnefsM+aoOchyleU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -23,8 +23,8 @@ github.com/go-chi/chi/v5 v5.2.1/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hH github.com/go-jose/go-jose/v4 v4.1.0 h1:cYSYxd3pw5zd2FSXk2vGdn9igQU2PS8MuxrCOCl0FdY= github.com/go-jose/go-jose/v4 v4.1.0/go.mod h1:GG/vqmYm3Von2nYiB2vGTXzdoNKE5tix5tuc6iAd+sw= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -79,8 +79,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.13.9 h1:4NGkvGudBL7GteO3m6qnaQ4pC0Kvf0onSVc9gR3EWBw= github.com/pkg/sftp v1.13.9/go.mod h1:OBN7bVXdstkFFN/gdnHPUb5TE8eb8G1Rp9wCItqjkkA= -github.com/pkg/xattr v0.4.10 h1:Qe0mtiNFHQZ296vRgUjRCoPHPqH7VdTOrZx3g0T+pGA= -github.com/pkg/xattr v0.4.10/go.mod h1:di8WF84zAKk8jzR1UBTEWh9AUlIZZ7M/JNt8e9B6ktU= +github.com/pkg/xattr v0.4.11 h1:DA7usy0rTMNMGvm06b5LhZUwiPj708D89S8DkXpMB1E= +github.com/pkg/xattr v0.4.11/go.mod h1:di8WF84zAKk8jzR1UBTEWh9AUlIZZ7M/JNt8e9B6ktU= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -114,8 +114,8 @@ github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zitadel/logging v0.6.2 h1:MW2kDDR0ieQynPZ0KIZPrh9ote2WkxfBif5QoARDQcU= github.com/zitadel/logging v0.6.2/go.mod h1:z6VWLWUkJpnNVDSLzrPSQSQyttysKZ6bCRongw0ROK4= -github.com/zitadel/oidc/v3 v3.38.1 h1:VTf1Bv/33UbSwJnIWbfEIdpUGYKfoHetuBNIqVTcjvA= -github.com/zitadel/oidc/v3 v3.38.1/go.mod h1:muukzAasaWmn3vBwEVMglJfuTE0PKCvLJGombPwXIRw= +github.com/zitadel/oidc/v3 v3.39.0 h1:WK3eNqmgshiYo1oEqONfXXbPbve+Qzgjl8KhKDFUvxc= +github.com/zitadel/oidc/v3 v3.39.0/go.mod h1:JwdgdU/WxkmBtWuE8/pEjAbDTWXxJGqBix/gUoeEig4= github.com/zitadel/schema v1.3.1 h1:QT3kwiRIRXXLVAs6gCK/u044WmUVh6IlbLXUsn6yRQU= github.com/zitadel/schema v1.3.1/go.mod h1:071u7D2LQacy1HAN+YnMd/mx1qVE2isb0Mjeqg46xnU= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= @@ -132,8 +132,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= -golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= +golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= +golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -147,8 +147,8 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= -golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= +golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= +golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -194,8 +194,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= -golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= +golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= +golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= diff --git a/vendor/github.com/canonical/lxd/client/connection.go b/vendor/github.com/canonical/lxd/client/connection.go index 8dc39a6..bfa517c 100644 --- a/vendor/github.com/canonical/lxd/client/connection.go +++ b/vendor/github.com/canonical/lxd/client/connection.go @@ -8,6 +8,7 @@ import ( "net/url" "os" "path/filepath" + "slices" "strings" "time" @@ -361,6 +362,55 @@ func ConnectDevLXDWithContext(ctx context.Context, socketPath string, args *Conn }, nil } +// ConnectDevLXDHTTPWithContext lets you connect to devLXD over a VM socket. +func ConnectDevLXDHTTPWithContext(ctx context.Context, args *ConnectionArgs, client *http.Client) (DevLXDServer, error) { + logger.Debug("Connecting to a devLXD over a VM socket") + + // Use empty args if not specified. + if args == nil { + args = &ConnectionArgs{} + } + + httpBaseURL, err := url.Parse("https://custom.socket") + if err != nil { + return nil, err + } + + ctxConnected, ctxConnectedCancel := context.WithCancel(context.Background()) + + // Initialize the client. + server := ProtocolDevLXD{ + ctx: ctx, + httpBaseURL: *httpBaseURL, + httpUserAgent: args.UserAgent, + ctxConnected: ctxConnected, + ctxConnectedCancel: ctxConnectedCancel, + eventListenerManager: newEventListenerManager(ctx), + } + + // Setup the HTTP client. + if client != nil { + // If the http.Transport has a TLSClientConfig, it indicates that the + // connection is using vsock. + transport, ok := client.Transport.(*http.Transport) + if ok && transport != nil && transport.TLSClientConfig != nil { + server.isDevLXDOverVsock = true + } + + server.http = client + } + + // Test the connection. + if !args.SkipGetServer { + _, err := server.GetState() + if err != nil { + return nil, err + } + } + + return &server, nil +} + // Internal function called by ConnectLXD and ConnectPublicLXD. func httpsLXD(ctx context.Context, requestURL string, args *ConnectionArgs) (InstanceServer, error) { // Use empty args if not specified @@ -387,7 +437,7 @@ func httpsLXD(ctx context.Context, requestURL string, args *ConnectionArgs) (Ins eventListenerManager: newEventListenerManager(ctx), } - if shared.ValueInSlice(args.AuthType, []string{api.AuthenticationMethodOIDC}) { + if slices.Contains([]string{api.AuthenticationMethodOIDC}, args.AuthType) { server.RequireAuthenticated(true) } diff --git a/vendor/github.com/canonical/lxd/client/devlxd.go b/vendor/github.com/canonical/lxd/client/devlxd.go index 436c840..b7c896b 100644 --- a/vendor/github.com/canonical/lxd/client/devlxd.go +++ b/vendor/github.com/canonical/lxd/client/devlxd.go @@ -34,6 +34,9 @@ type ProtocolDevLXD struct { httpUserAgent string eventListenerManager *eventListenerManager + + // isDevLXDOverVsock indicates whether the devLXD connection is over vsock. + isDevLXDOverVsock bool } // GetConnectionInfo returns the basic connection information used to interact with the server. @@ -132,6 +135,20 @@ func (r *ProtocolDevLXD) rawQuery(method string, url string, data any, ETag stri defer resp.Body.Close() + // If client is connected over vsock, the response is expected to be in LXD format (api.Response). + if r.isDevLXDOverVsock { + resp, etag, err := lxdParseResponse(resp) + if err != nil { + return nil, "", err + } + + return &api.DevLXDResponse{ + Content: resp.Metadata, + StatusCode: resp.StatusCode, + }, etag, nil + } + + // Otherwise, parse the response as a devLXD response. return devLXDParseResponse(resp) } diff --git a/vendor/github.com/canonical/lxd/client/devlxd_config.go b/vendor/github.com/canonical/lxd/client/devlxd_config.go index facb86e..32bdcb0 100644 --- a/vendor/github.com/canonical/lxd/client/devlxd_config.go +++ b/vendor/github.com/canonical/lxd/client/devlxd_config.go @@ -1,14 +1,15 @@ package lxd import ( + "encoding/json" "net/http" "strings" "github.com/canonical/lxd/shared/api" ) -// GetConfig retrieves a guest's configuration as a map. -func (r *ProtocolDevLXD) GetConfig() (map[string]string, error) { +// GetConfigURLs retrieves a list of configuration key paths. +func (r *ProtocolDevLXD) GetConfigURLs() ([]string, error) { var keyPaths []string // Fetch list of config key url paths. @@ -17,6 +18,16 @@ func (r *ProtocolDevLXD) GetConfig() (map[string]string, error) { return nil, err } + return keyPaths, nil +} + +// GetConfig retrieves a guest's configuration as a map. +func (r *ProtocolDevLXD) GetConfig() (map[string]string, error) { + keyPaths, err := r.GetConfigURLs() + if err != nil { + return nil, err + } + // Iterate over key paths and fetch their values. config := make(map[string]string, len(keyPaths)) for _, path := range keyPaths { @@ -46,5 +57,17 @@ func (r *ProtocolDevLXD) GetConfigByKey(key string) (string, error) { return "", err } + if r.isDevLXDOverVsock { + var value string + + // The returned string value is JSON encoded. + err = json.Unmarshal(resp.Content, &value) + if err != nil { + return "", err + } + + return value, nil + } + return string(resp.Content), nil } diff --git a/vendor/github.com/canonical/lxd/client/devlxd_metadata.go b/vendor/github.com/canonical/lxd/client/devlxd_metadata.go index 87fed13..0b7912a 100644 --- a/vendor/github.com/canonical/lxd/client/devlxd_metadata.go +++ b/vendor/github.com/canonical/lxd/client/devlxd_metadata.go @@ -1,6 +1,7 @@ package lxd import ( + "encoding/json" "net/http" ) @@ -11,5 +12,17 @@ func (r *ProtocolDevLXD) GetMetadata() (metadata string, err error) { return "", err } + if r.isDevLXDOverVsock { + var metadata string + + // The returned string value is JSON encoded. + err = json.Unmarshal(resp.Content, &metadata) + if err != nil { + return "", err + } + + return metadata, nil + } + return string(resp.Content), nil } diff --git a/vendor/github.com/canonical/lxd/client/devlxd_ubuntu_pro.go b/vendor/github.com/canonical/lxd/client/devlxd_ubuntu_pro.go index 9f50c30..52c43fe 100644 --- a/vendor/github.com/canonical/lxd/client/devlxd_ubuntu_pro.go +++ b/vendor/github.com/canonical/lxd/client/devlxd_ubuntu_pro.go @@ -7,8 +7,8 @@ import ( ) // GetUbuntuPro retrieves the guest's Ubuntu Pro settings. -func (r *ProtocolDevLXD) GetUbuntuPro() (*api.UbuntuProSettings, error) { - var info api.UbuntuProSettings +func (r *ProtocolDevLXD) GetUbuntuPro() (*api.DevLXDUbuntuProSettings, error) { + var info api.DevLXDUbuntuProSettings _, err := r.queryStruct(http.MethodGet, "/ubuntu-pro", nil, "", &info) if err != nil { @@ -19,8 +19,8 @@ func (r *ProtocolDevLXD) GetUbuntuPro() (*api.UbuntuProSettings, error) { } // CreateUbuntuProToken creates a new Ubuntu Pro token. -func (r *ProtocolDevLXD) CreateUbuntuProToken() (*api.UbuntuProGuestTokenResponse, error) { - var token api.UbuntuProGuestTokenResponse +func (r *ProtocolDevLXD) CreateUbuntuProToken() (*api.DevLXDUbuntuProGuestTokenResponse, error) { + var token api.DevLXDUbuntuProGuestTokenResponse _, err := r.queryStruct(http.MethodPost, "/ubuntu-pro/token", nil, "", &token) if err != nil { diff --git a/vendor/github.com/canonical/lxd/client/events.go b/vendor/github.com/canonical/lxd/client/events.go index 516a571..947ffc3 100644 --- a/vendor/github.com/canonical/lxd/client/events.go +++ b/vendor/github.com/canonical/lxd/client/events.go @@ -4,12 +4,12 @@ import ( "context" "encoding/json" "errors" + "slices" "sync" "time" "github.com/gorilla/websocket" - "github.com/canonical/lxd/shared" "github.com/canonical/lxd/shared/api" "github.com/canonical/lxd/shared/revert" ) @@ -258,7 +258,7 @@ func (m *eventListenerManager) getEvents(ctxConnected context.Context, websocket for _, listener := range m.eventListeners[listener.projectName] { listener.targetsLock.Lock() for _, target := range listener.targets { - if target.types != nil && !shared.ValueInSlice(event.Type, target.types) { + if target.types != nil && !slices.Contains(target.types, event.Type) { continue } diff --git a/vendor/github.com/canonical/lxd/client/interfaces.go b/vendor/github.com/canonical/lxd/client/interfaces.go index 965ec13..d19d409 100644 --- a/vendor/github.com/canonical/lxd/client/interfaces.go +++ b/vendor/github.com/canonical/lxd/client/interfaces.go @@ -481,7 +481,8 @@ type DevLXDServer interface { UpdateState(state api.DevLXDPut) error // DevLXD config. - GetConfig() (map[string]string, error) + GetConfig() (config map[string]string, err error) + GetConfigURLs() (keyPaths []string, err error) GetConfigByKey(key string) (string, error) // DevLXD metadata. @@ -497,8 +498,8 @@ type DevLXDServer interface { GetImageFile(fingerprint string, req ImageFileRequest) (resp *ImageFileResponse, err error) // DevLXD Ubuntu Pro. - GetUbuntuPro() (*api.UbuntuProSettings, error) - CreateUbuntuProToken() (*api.UbuntuProGuestTokenResponse, error) + GetUbuntuPro() (*api.DevLXDUbuntuProSettings, error) + CreateUbuntuProToken() (*api.DevLXDUbuntuProGuestTokenResponse, error) // Internal functions (for internal use) RawQuery(method string, path string, data any, queryETag string) (resp *api.DevLXDResponse, ETag string, err error) diff --git a/vendor/github.com/canonical/lxd/client/lxd.go b/vendor/github.com/canonical/lxd/client/lxd.go index 6e893b1..b287189 100644 --- a/vendor/github.com/canonical/lxd/client/lxd.go +++ b/vendor/github.com/canonical/lxd/client/lxd.go @@ -9,12 +9,12 @@ import ( "io" "net/http" neturl "net/url" + "slices" "strings" "time" "github.com/gorilla/websocket" - "github.com/canonical/lxd/shared" "github.com/canonical/lxd/shared/api" "github.com/canonical/lxd/shared/logger" "github.com/canonical/lxd/shared/tcp" @@ -82,7 +82,7 @@ func (r *ProtocolLXD) GetConnectionInfo() (*ConnectionInfo, error) { } url := "https://" + addr - if !shared.ValueInSlice(url, urls) { + if !slices.Contains(urls, url) { urls = append(urls, url) } } diff --git a/vendor/github.com/canonical/lxd/client/lxd_containers.go b/vendor/github.com/canonical/lxd/client/lxd_containers.go index be5014e..c5efe72 100644 --- a/vendor/github.com/canonical/lxd/client/lxd_containers.go +++ b/vendor/github.com/canonical/lxd/client/lxd_containers.go @@ -7,6 +7,7 @@ import ( "io" "net/http" "net/url" + "slices" "strconv" "strings" @@ -330,7 +331,7 @@ func (r *ProtocolLXD) CopyContainer(source InstanceServer, container api.Contain } } - if shared.ValueInSlice(args.Mode, []string{"push", "relay"}) { + if slices.Contains([]string{"push", "relay"}, args.Mode) { if !r.HasExtension("container_push") { return nil, errors.New("The target server is missing the required \"container_push\" API extension") } @@ -1083,7 +1084,7 @@ func (r *ProtocolLXD) CopyContainerSnapshot(source InstanceServer, containerName // Process the copy arguments if args != nil { // Quick checks. - if shared.ValueInSlice(args.Mode, []string{"push", "relay"}) { + if slices.Contains([]string{"push", "relay"}, args.Mode) { if !r.HasExtension("container_push") { return nil, errors.New("The target server is missing the required \"container_push\" API extension") } diff --git a/vendor/github.com/canonical/lxd/client/lxd_images.go b/vendor/github.com/canonical/lxd/client/lxd_images.go index 13e41cd..1352749 100644 --- a/vendor/github.com/canonical/lxd/client/lxd_images.go +++ b/vendor/github.com/canonical/lxd/client/lxd_images.go @@ -11,6 +11,7 @@ import ( "net/http" "net/url" "os" + "slices" "strconv" "strings" "time" @@ -309,7 +310,7 @@ func lxdDownloadImage(fingerprint string, uri string, userAgent string, do func( return nil, err } - if !shared.ValueInSlice(part.FormName(), []string{"rootfs", "rootfs.img"}) { + if !slices.Contains([]string{"rootfs", "rootfs.img"}, part.FormName()) { return nil, errors.New("Invalid multipart image") } diff --git a/vendor/github.com/canonical/lxd/client/lxd_instances.go b/vendor/github.com/canonical/lxd/client/lxd_instances.go index 0cdc2c2..296474a 100644 --- a/vendor/github.com/canonical/lxd/client/lxd_instances.go +++ b/vendor/github.com/canonical/lxd/client/lxd_instances.go @@ -11,6 +11,7 @@ import ( "net/http" "net/url" "path/filepath" + "slices" "strconv" "strings" @@ -860,7 +861,7 @@ func (r *ProtocolLXD) CopyInstance(source InstanceServer, instance api.Instance, } } - if shared.ValueInSlice(args.Mode, []string{"push", "relay"}) { + if slices.Contains([]string{"push", "relay"}, args.Mode) { if !r.HasExtension("container_push") { return nil, errors.New("The target server is missing the required \"container_push\" API extension") } @@ -1970,7 +1971,7 @@ func (r *ProtocolLXD) CopyInstanceSnapshot(source InstanceServer, instanceName s // Process the copy arguments if args != nil { // Quick checks. - if shared.ValueInSlice(args.Mode, []string{"push", "relay"}) { + if slices.Contains([]string{"push", "relay"}, args.Mode) { err := r.CheckExtension("container_push") if err != nil { return nil, err diff --git a/vendor/github.com/canonical/lxd/client/lxd_server.go b/vendor/github.com/canonical/lxd/client/lxd_server.go index 7f7ff39..f5aa1f2 100644 --- a/vendor/github.com/canonical/lxd/client/lxd_server.go +++ b/vendor/github.com/canonical/lxd/client/lxd_server.go @@ -4,6 +4,7 @@ import ( "fmt" "io" "net/http" + "slices" "github.com/canonical/lxd/shared" "github.com/canonical/lxd/shared/api" @@ -62,7 +63,7 @@ func (r *ProtocolLXD) HasExtension(extension string) bool { return true } - return shared.ValueInSlice(extension, r.server.APIExtensions) + return slices.Contains(r.server.APIExtensions, extension) } // CheckExtension checks if the server has the specified extension. diff --git a/vendor/github.com/canonical/lxd/shared/api/cluster.go b/vendor/github.com/canonical/lxd/shared/api/cluster.go index a775266..7a3cf31 100644 --- a/vendor/github.com/canonical/lxd/shared/api/cluster.go +++ b/vendor/github.com/canonical/lxd/shared/api/cluster.go @@ -285,6 +285,8 @@ type ClusterMemberStatePost struct { Action string `json:"action" yaml:"action"` // Override the configured evacuation mode. + // Valid modes for the "evacuate" action are "stop", "migrate", and "live-migrate". + // Valid modes for the "restore" action are "skip". // Example: stop // // API extension: clustering_evacuation_mode diff --git a/vendor/github.com/canonical/lxd/shared/api/devlxd.go b/vendor/github.com/canonical/lxd/shared/api/devlxd.go index 153d150..35f3880 100644 --- a/vendor/github.com/canonical/lxd/shared/api/devlxd.go +++ b/vendor/github.com/canonical/lxd/shared/api/devlxd.go @@ -39,11 +39,11 @@ type DevLXDGet struct { Location string `json:"location" yaml:"location"` } -// UbuntuProGuestTokenResponse contains the expected fields of proAPIGetGuestTokenV1 that must be passed back to +// DevLXDUbuntuProGuestTokenResponse contains the expected fields of proAPIGetGuestTokenV1 that must be passed back to // the guest for pro attachment to succeed. // // API extension: ubuntu_pro_guest_attach. -type UbuntuProGuestTokenResponse struct { +type DevLXDUbuntuProGuestTokenResponse struct { // Expires denotes the time at which the token will expire. // // Example: 2025-03-23T20:00:00-04:00 @@ -60,10 +60,10 @@ type UbuntuProGuestTokenResponse struct { ID string `json:"id"` } -// UbuntuProSettings contains Ubuntu Pro settings relevant to LXD. +// DevLXDUbuntuProSettings contains Ubuntu Pro settings relevant to LXD. // // API extension: ubuntu_pro_guest_attach. -type UbuntuProSettings struct { +type DevLXDUbuntuProSettings struct { // GuestAttach indicates the availability of ubuntu pro guest attachment. // // Example: on diff --git a/vendor/github.com/canonical/lxd/shared/api/error.go b/vendor/github.com/canonical/lxd/shared/api/error.go index c2eb902..33b91b1 100644 --- a/vendor/github.com/canonical/lxd/shared/api/error.go +++ b/vendor/github.com/canonical/lxd/shared/api/error.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "net/http" + "slices" ) // NewGenericStatusError returns a new StatusError with the given status code. @@ -77,10 +78,8 @@ func StatusErrorMatch(err error, matchStatusCodes ...int) (int, bool) { return statusCode, true } - for _, s := range matchStatusCodes { - if statusCode == s { - return statusCode, true - } + if slices.Contains(matchStatusCodes, statusCode) { + return statusCode, true } } diff --git a/vendor/github.com/canonical/lxd/shared/api/init.go b/vendor/github.com/canonical/lxd/shared/api/init.go index 9cf9536..12f677d 100644 --- a/vendor/github.com/canonical/lxd/shared/api/init.go +++ b/vendor/github.com/canonical/lxd/shared/api/init.go @@ -45,11 +45,11 @@ type InitLocalPreseed struct { // // API extension: preseed. type InitNetworksProjectPost struct { - NetworksPost `yaml:",inline"` + NetworksPost `yaml:",inline"` //nolint:musttag // Project in which the network will reside // Example: "default" - Project string + Project string `json:"Project" yaml:"project"` } // InitStorageVolumesProjectPost represents the fields of a new LXD storage volume along with its associated pool. diff --git a/vendor/github.com/canonical/lxd/shared/api/instance.go b/vendor/github.com/canonical/lxd/shared/api/instance.go index 8f7606d..3d90806 100644 --- a/vendor/github.com/canonical/lxd/shared/api/instance.go +++ b/vendor/github.com/canonical/lxd/shared/api/instance.go @@ -132,19 +132,19 @@ type InstancePost struct { // Example: {"security.nesting": "true"} // // API extension: instance_move_config - Config map[string]string + Config map[string]string `json:"Config" yaml:"config"` // Instance devices. // Example: {"root": {"type": "disk", "pool": "default", "path": "/"}} // // API extension: instance_move_config - Devices map[string]map[string]string + Devices map[string]map[string]string `json:"Devices" yaml:"devices"` // List of profiles applied to the instance. // Example: ["default"] // // API extension: instance_move_config - Profiles []string + Profiles []string `json:"Profiles" yaml:"profiles"` // Whether the instances's snapshot should receive target instances profile on copy // Example: true @@ -227,7 +227,7 @@ type InstanceRebuildPost struct { // // API extension: instances. type Instance struct { - WithEntitlements `yaml:",inline"` + WithEntitlements `yaml:",inline"` //nolint:musttag // Instance name // Example: foo diff --git a/vendor/github.com/canonical/lxd/shared/api/instance_backup.go b/vendor/github.com/canonical/lxd/shared/api/instance_backup.go index 7b3fc07..ac85628 100644 --- a/vendor/github.com/canonical/lxd/shared/api/instance_backup.go +++ b/vendor/github.com/canonical/lxd/shared/api/instance_backup.go @@ -42,7 +42,7 @@ type InstanceBackupsPost struct { // Example: 1 // // API extension: backup_metadata_version - Version uint32 + Version uint32 `json:"version" yaml:"version"` } // InstanceBackup represents a LXD instance backup. diff --git a/vendor/github.com/canonical/lxd/shared/api/network.go b/vendor/github.com/canonical/lxd/shared/api/network.go index 02d34e9..fca08f3 100644 --- a/vendor/github.com/canonical/lxd/shared/api/network.go +++ b/vendor/github.com/canonical/lxd/shared/api/network.go @@ -6,7 +6,7 @@ package api // // API extension: network. type NetworksPost struct { - NetworkPut `yaml:",inline"` + NetworkPut `yaml:",inline"` //nolint:musttag // The name of the new network // Example: lxdbr1 diff --git a/vendor/github.com/canonical/lxd/shared/api/profile.go b/vendor/github.com/canonical/lxd/shared/api/profile.go index 63022e2..89beb6c 100644 --- a/vendor/github.com/canonical/lxd/shared/api/profile.go +++ b/vendor/github.com/canonical/lxd/shared/api/profile.go @@ -41,7 +41,7 @@ type ProfilePut struct { // // swagger:model type Profile struct { - WithEntitlements `yaml:",inline"` + WithEntitlements `yaml:",inline"` //nolint:musttag // The profile name // Read only: true diff --git a/vendor/github.com/canonical/lxd/shared/api/storage_pool.go b/vendor/github.com/canonical/lxd/shared/api/storage_pool.go index 0ba5935..f9e4f68 100644 --- a/vendor/github.com/canonical/lxd/shared/api/storage_pool.go +++ b/vendor/github.com/canonical/lxd/shared/api/storage_pool.go @@ -38,7 +38,7 @@ type StoragePoolsPost struct { // // API extension: storage. type StoragePool struct { - WithEntitlements `yaml:",inline"` + WithEntitlements `yaml:",inline"` //nolint:musttag // Storage pool name // Example: local diff --git a/vendor/github.com/canonical/lxd/shared/api/storage_pool_bucket.go b/vendor/github.com/canonical/lxd/shared/api/storage_pool_bucket.go index 7b99a40..d3710d4 100644 --- a/vendor/github.com/canonical/lxd/shared/api/storage_pool_bucket.go +++ b/vendor/github.com/canonical/lxd/shared/api/storage_pool_bucket.go @@ -40,7 +40,7 @@ type StorageBucketPut struct { // // API extension: storage_buckets. type StorageBucket struct { - WithEntitlements `yaml:",inline"` + WithEntitlements `yaml:",inline"` //nolint:musttag // Bucket name // Example: foo diff --git a/vendor/github.com/canonical/lxd/shared/api/storage_pool_volume.go b/vendor/github.com/canonical/lxd/shared/api/storage_pool_volume.go index 3d48946..6371adb 100644 --- a/vendor/github.com/canonical/lxd/shared/api/storage_pool_volume.go +++ b/vendor/github.com/canonical/lxd/shared/api/storage_pool_volume.go @@ -102,7 +102,7 @@ type StorageVolumePostTarget struct { // // API extension: storage. type StorageVolume struct { - WithEntitlements `yaml:",inline"` + WithEntitlements `yaml:",inline"` //nolint:musttag // Volume name // Example: foo diff --git a/vendor/github.com/canonical/lxd/shared/api/storage_pool_volume_backup.go b/vendor/github.com/canonical/lxd/shared/api/storage_pool_volume_backup.go index 4af4eb0..9cf9a95 100644 --- a/vendor/github.com/canonical/lxd/shared/api/storage_pool_volume_backup.go +++ b/vendor/github.com/canonical/lxd/shared/api/storage_pool_volume_backup.go @@ -61,7 +61,7 @@ type StoragePoolVolumeBackupsPost struct { // Example: 1 // // API extension: backup_metadata_version - Version uint32 + Version uint32 `json:"version" yaml:"version"` } // StoragePoolVolumeBackupPost represents the fields available for the renaming of a volume backup diff --git a/vendor/github.com/canonical/lxd/shared/ioprogress/tracker.go b/vendor/github.com/canonical/lxd/shared/ioprogress/tracker.go index 8342921..ce5091d 100644 --- a/vendor/github.com/canonical/lxd/shared/ioprogress/tracker.go +++ b/vendor/github.com/canonical/lxd/shared/ioprogress/tracker.go @@ -61,10 +61,7 @@ func (pt *ProgressTracker) update(n int) { var progressInt int64 if pt.Length > 0 { pt.percentage = percentage - progressInt = int64(1 + int(percentage)) - if progressInt > 100 { - progressInt = 100 - } + progressInt = min(int64(1+int(percentage)), 100) } else { progressInt = pt.total diff --git a/vendor/github.com/canonical/lxd/shared/osarch/architectures.go b/vendor/github.com/canonical/lxd/shared/osarch/architectures.go index 341e2dc..bc73284 100644 --- a/vendor/github.com/canonical/lxd/shared/osarch/architectures.go +++ b/vendor/github.com/canonical/lxd/shared/osarch/architectures.go @@ -2,10 +2,11 @@ package osarch import ( "fmt" + "slices" ) const ( - ARCH_UNKNOWN = 0 + ARCH_UNKNOWN = 0 //nolint:revive ARCH_32BIT_INTEL_X86 = 1 ARCH_64BIT_INTEL_X86 = 2 ARCH_32BIT_ARMV7_LITTLE_ENDIAN = 3 @@ -94,44 +95,47 @@ var architectureSupportedPersonalities = map[int][]int{ ARCH_64BIT_LOONGARCH: {}, } +// ArchitectureDefault represents the default architecture. const ArchitectureDefault = "x86_64" +// ArchitectureName returns the local hardware architecture name. func ArchitectureName(arch int) (string, error) { - arch_name, exists := architectureNames[arch] + name, exists := architectureNames[arch] if exists { - return arch_name, nil + return name, nil } return "unknown", fmt.Errorf("Architecture isn't supported: %d", arch) } -func ArchitectureId(arch string) (int, error) { - for arch_id, arch_name := range architectureNames { - if arch_name == arch { - return arch_id, nil +// ArchitectureId returns the architecture ID for a given architecture name or alias. +func ArchitectureId(arch string) (int, error) { //nolint:revive + for id, name := range architectureNames { + if name == arch { + return id, nil } } - for arch_id, arch_aliases := range architectureAliases { - for _, arch_name := range arch_aliases { - if arch_name == arch { - return arch_id, nil - } + for id, aliases := range architectureAliases { + if slices.Contains(aliases, arch) { + return id, nil } } return ARCH_UNKNOWN, fmt.Errorf("Architecture isn't supported: %s", arch) } +// ArchitecturePersonality returns the personality for a given architecture ID. func ArchitecturePersonality(arch int) (string, error) { - arch_personality, exists := architecturePersonalities[arch] + personality, exists := architecturePersonalities[arch] if exists { - return arch_personality, nil + return personality, nil } return "", fmt.Errorf("Architecture isn't supported: %d", arch) } +// ArchitecturePersonalities returns the list of supported personalities for a given architecture ID. func ArchitecturePersonalities(arch int) ([]int, error) { personalities, exists := architectureSupportedPersonalities[arch] if exists { diff --git a/vendor/github.com/canonical/lxd/shared/proxy.go b/vendor/github.com/canonical/lxd/shared/proxy.go index 44d634e..645df67 100644 --- a/vendor/github.com/canonical/lxd/shared/proxy.go +++ b/vendor/github.com/canonical/lxd/shared/proxy.go @@ -30,6 +30,7 @@ type envOnce struct { val string } +// Get retrieves the value of the first non-empty environment variable. func (e *envOnce) Get() string { e.once.Do(e.init) return e.val @@ -44,13 +45,17 @@ func (e *envOnce) init() { } } -// This is basically the same as golang's ProxyFromEnvironment, except it +// ProxyFromEnvironment minic's golang's ProxyFromEnvironment, except it // doesn't fall back to http_proxy when https_proxy isn't around, which is // incorrect behavior. It still respects HTTP_PROXY, HTTPS_PROXY, and NO_PROXY. func ProxyFromEnvironment(req *http.Request) (*url.URL, error) { return ProxyFromConfig("", "", "")(req) } +// ProxyFromConfig returns the URL with which the request should be +// proxied, based on the provided httpsProxy, httpProxy, and noProxy +// values. If httpsProxy or httpProxy is empty, it will fall back to the +// environment variables HTTPS_PROXY, HTTP_PROXY, and NO_PROXY respectively. func ProxyFromConfig(httpsProxy string, httpProxy string, noProxy string) func(req *http.Request) (*url.URL, error) { return func(req *http.Request) (*url.URL, error) { var proxy, port string @@ -149,7 +154,7 @@ func useProxy(addr string, noProxy string) (bool, error) { addr = addr[:strings.LastIndex(addr, ":")] } - for _, p := range strings.Split(noProxy, ",") { + for p := range strings.SplitSeq(noProxy, ",") { p = strings.ToLower(strings.TrimSpace(p)) if len(p) == 0 { continue diff --git a/vendor/github.com/canonical/lxd/shared/simplestreams/products.go b/vendor/github.com/canonical/lxd/shared/simplestreams/products.go index 82d4be7..685bc72 100644 --- a/vendor/github.com/canonical/lxd/shared/simplestreams/products.go +++ b/vendor/github.com/canonical/lxd/shared/simplestreams/products.go @@ -219,7 +219,7 @@ func (s *Products) ToLXD() ([]api.Image, map[string][][]string) { // Add the provided aliases if product.Aliases != "" { image.Aliases = []api.ImageAlias{} - for _, entry := range strings.Split(product.Aliases, ",") { + for entry := range strings.SplitSeq(product.Aliases, ",") { image.Aliases = append(image.Aliases, api.ImageAlias{Name: entry}) } } diff --git a/vendor/github.com/canonical/lxd/shared/util.go b/vendor/github.com/canonical/lxd/shared/util.go index 4d44af8..6cad54d 100644 --- a/vendor/github.com/canonical/lxd/shared/util.go +++ b/vendor/github.com/canonical/lxd/shared/util.go @@ -13,6 +13,7 @@ import ( "fmt" "hash" "io" + "maps" "net/http" "net/url" "os" @@ -22,6 +23,7 @@ import ( "reflect" "regexp" "runtime" + "slices" "strconv" "strings" "time" @@ -333,7 +335,7 @@ func ParseLXDFileHeaders(headers http.Header) (*LXDFileHeaders, error) { filetype = "file" } - if !ValueInSlice(filetype, []string{"file", "symlink", "directory"}) { + if !slices.Contains([]string{"file", "symlink", "directory"}, filetype) { return nil, fmt.Errorf("Invalid file type: %q", filetype) } @@ -345,7 +347,7 @@ func ParseLXDFileHeaders(headers http.Header) (*LXDFileHeaders, error) { write = "overwrite" } - if !ValueInSlice(write, []string{"overwrite", "append"}) { + if !slices.Contains([]string{"overwrite", "append"}, write) { return nil, fmt.Errorf("Invalid file write mode: %q", write) } @@ -355,13 +357,14 @@ func ParseLXDFileHeaders(headers http.Header) (*LXDFileHeaders, error) { modifyPermHeader := headers.Get("X-LXD-modify-perm") + modifyPermFields := []string{"uid", "gid", "mode"} if modifyPermHeader != "" { - for _, perm := range strings.Split(modifyPermHeader, ",") { + for perm := range strings.SplitSeq(modifyPermHeader, ",") { UIDModifyExisting = UIDModifyExisting || perm == "uid" GIDModifyExisting = GIDModifyExisting || perm == "gid" modeModifyExisting = modeModifyExisting || perm == "mode" - if !ValueInSlice(perm, []string{"uid", "gid", "mode"}) { + if !slices.Contains(modifyPermFields, perm) { return nil, fmt.Errorf("Invalid modify-perm field: %q", perm) } } @@ -721,17 +724,6 @@ func HasKey[K comparable, V any](key K, m map[K]V) bool { return found } -// ValueInSlice returns true if key is in list. -func ValueInSlice[T comparable](key T, list []T) bool { - for _, entry := range list { - if entry == key { - return true - } - } - - return false -} - // StringPrefixInSlice returns true if any element in the list has the given prefix. func StringPrefixInSlice(key string, list []string) bool { for _, entry := range list { @@ -752,13 +744,13 @@ func RemoveElementsFromSlice[T comparable](list []T, elements ...T) []T { for j := len(list) - 1; j >= 0; j-- { if element == list[j] { match = true - list = append(list[:j], list[j+1:]...) + list = slices.Delete(list, j, j+1) break } } if match { - elements = append(elements[:i], elements[i+1:]...) + elements = slices.Delete(elements, i, i+1) } } @@ -781,7 +773,7 @@ func IsTrue(value string) bool { return true } - return ValueInSlice(strings.ToLower(value), []string{"true", "yes", "on"}) + return slices.Contains([]string{"true", "yes", "on"}, strings.ToLower(value)) } // IsTrueOrEmpty returns true if value is empty or if IsTrue() returns true. @@ -795,7 +787,7 @@ func IsFalse(value string) bool { return true } - return ValueInSlice(strings.ToLower(value), []string{"false", "no", "off"}) + return slices.Contains([]string{"false", "no", "off"}, strings.ToLower(value)) } // IsFalseOrEmpty returns true if value is empty or if IsFalse() returns true. @@ -1135,7 +1127,7 @@ func TryRunCommand(name string, arg ...string) (string, error) { var err error var output string - for i := 0; i < 20; i++ { + for range 20 { output, err = RunCommand(name, arg...) if err == nil { break @@ -1500,9 +1492,7 @@ func ApplyDeviceOverrides(localDevices map[string]map[string]string, profileDevi _, isLocalDevice := localDevices[deviceName] if isLocalDevice { // Apply overrides to local device. - for k, v := range deviceOverrides[deviceName] { - localDevices[deviceName][k] = v - } + maps.Copy(localDevices[deviceName], deviceOverrides[deviceName]) } else { // Check device exists in expanded profile devices. profileDeviceConfig, found := profileDevices[deviceName] @@ -1510,9 +1500,7 @@ func ApplyDeviceOverrides(localDevices map[string]map[string]string, profileDevi return nil, fmt.Errorf("Cannot override config for device %q: Device not found in profile devices", deviceName) } - for k, v := range deviceOverrides[deviceName] { - profileDeviceConfig[k] = v - } + maps.Copy(profileDeviceConfig, deviceOverrides[deviceName]) localDevices[deviceName] = profileDeviceConfig } diff --git a/vendor/github.com/canonical/lxd/shared/util_linux.go b/vendor/github.com/canonical/lxd/shared/util_linux.go index e4a2a53..c0204ab 100644 --- a/vendor/github.com/canonical/lxd/shared/util_linux.go +++ b/vendor/github.com/canonical/lxd/shared/util_linux.go @@ -213,7 +213,7 @@ func Uname() (*Utsname, error) { func intArrayToString(arr any) string { slice := reflect.ValueOf(arr) s := "" - for i := 0; i < slice.Len(); i++ { + for i := range slice.Len() { val := slice.Index(i) valInt := int64(-1) diff --git a/vendor/github.com/canonical/lxd/shared/version/api.go b/vendor/github.com/canonical/lxd/shared/version/api.go index 8ce2306..0b7e803 100644 --- a/vendor/github.com/canonical/lxd/shared/version/api.go +++ b/vendor/github.com/canonical/lxd/shared/version/api.go @@ -450,6 +450,7 @@ var APIExtensions = []string{ "network_acls_all_projects", "networks_all_projects", "clustering_restore_skip_mode", + "disk_io_threads_virtiofsd", } // APIExtensionsCount returns the number of available API extensions. diff --git a/vendor/github.com/canonical/lxd/shared/version/flex.go b/vendor/github.com/canonical/lxd/shared/version/flex.go index b8ac7fb..468c269 100644 --- a/vendor/github.com/canonical/lxd/shared/version/flex.go +++ b/vendor/github.com/canonical/lxd/shared/version/flex.go @@ -1,7 +1,7 @@ package version // Version contains the LXD version number. -var Version = "6.3" +var Version = "6.4" // IsLTSVersion indicates this is an LTS version of LXD. var IsLTSVersion = false diff --git a/vendor/github.com/go-logr/logr/.golangci.yaml b/vendor/github.com/go-logr/logr/.golangci.yaml index 0cffafa..0ed62c1 100644 --- a/vendor/github.com/go-logr/logr/.golangci.yaml +++ b/vendor/github.com/go-logr/logr/.golangci.yaml @@ -1,26 +1,28 @@ +version: "2" + run: timeout: 1m tests: true linters: - disable-all: true - enable: + default: none + enable: # please keep this alphabetized + - asasalint - asciicheck + - copyloopvar + - dupl - errcheck - forcetypeassert + - goconst - gocritic - - gofmt - - goimports - - gosimple - govet - ineffassign - misspell + - musttag - revive - staticcheck - - typecheck - unused issues: - exclude-use-default: false max-issues-per-linter: 0 max-same-issues: 10 diff --git a/vendor/github.com/go-logr/logr/funcr/funcr.go b/vendor/github.com/go-logr/logr/funcr/funcr.go index 30568e7..b22c57d 100644 --- a/vendor/github.com/go-logr/logr/funcr/funcr.go +++ b/vendor/github.com/go-logr/logr/funcr/funcr.go @@ -77,7 +77,7 @@ func newSink(fn func(prefix, args string), formatter Formatter) logr.LogSink { write: fn, } // For skipping fnlogger.Info and fnlogger.Error. - l.Formatter.AddCallDepth(1) + l.AddCallDepth(1) // via Formatter return l } @@ -164,17 +164,17 @@ type fnlogger struct { } func (l fnlogger) WithName(name string) logr.LogSink { - l.Formatter.AddName(name) + l.AddName(name) // via Formatter return &l } func (l fnlogger) WithValues(kvList ...any) logr.LogSink { - l.Formatter.AddValues(kvList) + l.AddValues(kvList) // via Formatter return &l } func (l fnlogger) WithCallDepth(depth int) logr.LogSink { - l.Formatter.AddCallDepth(depth) + l.AddCallDepth(depth) // via Formatter return &l } diff --git a/vendor/github.com/pkg/xattr/xattr_solaris.go b/vendor/github.com/pkg/xattr/xattr_solaris.go index 7c98b4a..2823bca 100644 --- a/vendor/github.com/pkg/xattr/xattr_solaris.go +++ b/vendor/github.com/pkg/xattr/xattr_solaris.go @@ -4,8 +4,8 @@ package xattr import ( + "errors" "os" - "syscall" "golang.org/x/sys/unix" ) @@ -17,10 +17,11 @@ const ( XATTR_CREATE = 0x1 XATTR_REPLACE = 0x2 - // ENOATTR is not exported by the syscall package on Linux, because it is - // an alias for ENODATA. We export it here so it is available on all - // our supported platforms. - ENOATTR = syscall.ENODATA + // ENOATTR is not defined on Solaris. When attempting to open an + // extended attribute that doesn't exist, we'll get ENOENT. For + // compatibility with other platforms, we make ENOATTR available as + // an alias of unix.ENOENT. + ENOATTR = unix.ENOENT ) func getxattr(path string, name string, data []byte) (int, error) { @@ -132,7 +133,13 @@ func llistxattr(path string, data []byte) (int, error) { func flistxattr(f *os.File, data []byte) (int, error) { fd, err := unix.Openat(int(f.Fd()), ".", unix.O_RDONLY|unix.O_XATTR, 0) if err != nil { - return 0, unix.ENOTSUP + // When attempting to list extended attributes on a filesystem + // that doesn't support them (like as UFS and tmpfs), we'll get + // EINVAL. Translate this error to the more conventional ENOTSUP. + if errors.Is(err, unix.EINVAL) { + return 0, unix.ENOTSUP + } + return 0, err } xf := os.NewFile(uintptr(fd), f.Name()) defer func() { diff --git a/vendor/github.com/zitadel/oidc/v3/pkg/oidc/session.go b/vendor/github.com/zitadel/oidc/v3/pkg/oidc/session.go index b470d1e..39f9f08 100644 --- a/vendor/github.com/zitadel/oidc/v3/pkg/oidc/session.go +++ b/vendor/github.com/zitadel/oidc/v3/pkg/oidc/session.go @@ -1,10 +1,12 @@ package oidc // EndSessionRequest for the RP-Initiated Logout according to: -//https://openid.net/specs/openid-connect-rpinitiated-1_0.html#RPLogout +// https://openid.net/specs/openid-connect-rpinitiated-1_0.html#RPLogout type EndSessionRequest struct { - IdTokenHint string `schema:"id_token_hint"` - ClientID string `schema:"client_id"` - PostLogoutRedirectURI string `schema:"post_logout_redirect_uri"` - State string `schema:"state"` + IdTokenHint string `schema:"id_token_hint"` + LogoutHint string `schema:"logout_hint"` + ClientID string `schema:"client_id"` + PostLogoutRedirectURI string `schema:"post_logout_redirect_uri"` + State string `schema:"state"` + UILocales Locales `schema:"ui_locales"` } diff --git a/vendor/github.com/zitadel/oidc/v3/pkg/oidc/types.go b/vendor/github.com/zitadel/oidc/v3/pkg/oidc/types.go index 9b307bc..33ad2d5 100644 --- a/vendor/github.com/zitadel/oidc/v3/pkg/oidc/types.go +++ b/vendor/github.com/zitadel/oidc/v3/pkg/oidc/types.go @@ -115,6 +115,14 @@ func ParseLocales(locales []string) Locales { return out } +func (l Locales) String() string { + tags := make([]string, len(l)) + for i, tag := range l { + tags[i] = tag.String() + } + return strings.Join(tags, " ") +} + // UnmarshalText implements the [encoding.TextUnmarshaler] interface. // It decodes an unquoted space seperated string into Locales. // Undefined language tags in the input are ignored and ommited from @@ -231,6 +239,9 @@ func NewEncoder() *schema.Encoder { e.RegisterEncoder(SpaceDelimitedArray{}, func(value reflect.Value) string { return value.Interface().(SpaceDelimitedArray).String() }) + e.RegisterEncoder(Locales{}, func(value reflect.Value) string { + return value.Interface().(Locales).String() + }) return e } diff --git a/vendor/golang.org/x/crypto/bcrypt/bcrypt.go b/vendor/golang.org/x/crypto/bcrypt/bcrypt.go index dc93118..3e7f8df 100644 --- a/vendor/golang.org/x/crypto/bcrypt/bcrypt.go +++ b/vendor/golang.org/x/crypto/bcrypt/bcrypt.go @@ -50,7 +50,7 @@ func (ih InvalidHashPrefixError) Error() string { type InvalidCostError int func (ic InvalidCostError) Error() string { - return fmt.Sprintf("crypto/bcrypt: cost %d is outside allowed range (%d,%d)", int(ic), MinCost, MaxCost) + return fmt.Sprintf("crypto/bcrypt: cost %d is outside allowed inclusive range %d..%d", int(ic), MinCost, MaxCost) } const ( diff --git a/vendor/golang.org/x/crypto/ssh/certs.go b/vendor/golang.org/x/crypto/ssh/certs.go index 27d0e14..a3dc629 100644 --- a/vendor/golang.org/x/crypto/ssh/certs.go +++ b/vendor/golang.org/x/crypto/ssh/certs.go @@ -20,14 +20,19 @@ import ( // returned by MultiAlgorithmSigner and don't appear in the Signature.Format // field. const ( - CertAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com" - CertAlgoDSAv01 = "ssh-dss-cert-v01@openssh.com" - CertAlgoECDSA256v01 = "ecdsa-sha2-nistp256-cert-v01@openssh.com" - CertAlgoECDSA384v01 = "ecdsa-sha2-nistp384-cert-v01@openssh.com" - CertAlgoECDSA521v01 = "ecdsa-sha2-nistp521-cert-v01@openssh.com" - CertAlgoSKECDSA256v01 = "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com" - CertAlgoED25519v01 = "ssh-ed25519-cert-v01@openssh.com" - CertAlgoSKED25519v01 = "sk-ssh-ed25519-cert-v01@openssh.com" + CertAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com" + // Deprecated: DSA is only supported at insecure key sizes, and was removed + // from major implementations. + CertAlgoDSAv01 = InsecureCertAlgoDSAv01 + // Deprecated: DSA is only supported at insecure key sizes, and was removed + // from major implementations. + InsecureCertAlgoDSAv01 = "ssh-dss-cert-v01@openssh.com" + CertAlgoECDSA256v01 = "ecdsa-sha2-nistp256-cert-v01@openssh.com" + CertAlgoECDSA384v01 = "ecdsa-sha2-nistp384-cert-v01@openssh.com" + CertAlgoECDSA521v01 = "ecdsa-sha2-nistp521-cert-v01@openssh.com" + CertAlgoSKECDSA256v01 = "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com" + CertAlgoED25519v01 = "ssh-ed25519-cert-v01@openssh.com" + CertAlgoSKED25519v01 = "sk-ssh-ed25519-cert-v01@openssh.com" // CertAlgoRSASHA256v01 and CertAlgoRSASHA512v01 can't appear as a // Certificate.Type (or PublicKey.Type), but only in @@ -485,16 +490,16 @@ func (c *Certificate) SignCert(rand io.Reader, authority Signer) error { // // This map must be kept in sync with the one in agent/client.go. var certKeyAlgoNames = map[string]string{ - CertAlgoRSAv01: KeyAlgoRSA, - CertAlgoRSASHA256v01: KeyAlgoRSASHA256, - CertAlgoRSASHA512v01: KeyAlgoRSASHA512, - CertAlgoDSAv01: KeyAlgoDSA, - CertAlgoECDSA256v01: KeyAlgoECDSA256, - CertAlgoECDSA384v01: KeyAlgoECDSA384, - CertAlgoECDSA521v01: KeyAlgoECDSA521, - CertAlgoSKECDSA256v01: KeyAlgoSKECDSA256, - CertAlgoED25519v01: KeyAlgoED25519, - CertAlgoSKED25519v01: KeyAlgoSKED25519, + CertAlgoRSAv01: KeyAlgoRSA, + CertAlgoRSASHA256v01: KeyAlgoRSASHA256, + CertAlgoRSASHA512v01: KeyAlgoRSASHA512, + InsecureCertAlgoDSAv01: InsecureKeyAlgoDSA, + CertAlgoECDSA256v01: KeyAlgoECDSA256, + CertAlgoECDSA384v01: KeyAlgoECDSA384, + CertAlgoECDSA521v01: KeyAlgoECDSA521, + CertAlgoSKECDSA256v01: KeyAlgoSKECDSA256, + CertAlgoED25519v01: KeyAlgoED25519, + CertAlgoSKED25519v01: KeyAlgoSKED25519, } // underlyingAlgo returns the signature algorithm associated with algo (which is diff --git a/vendor/golang.org/x/crypto/ssh/cipher.go b/vendor/golang.org/x/crypto/ssh/cipher.go index 741e984..6a5b582 100644 --- a/vendor/golang.org/x/crypto/ssh/cipher.go +++ b/vendor/golang.org/x/crypto/ssh/cipher.go @@ -58,11 +58,11 @@ func newRC4(key, iv []byte) (cipher.Stream, error) { type cipherMode struct { keySize int ivSize int - create func(key, iv []byte, macKey []byte, algs directionAlgorithms) (packetCipher, error) + create func(key, iv []byte, macKey []byte, algs DirectionAlgorithms) (packetCipher, error) } -func streamCipherMode(skip int, createFunc func(key, iv []byte) (cipher.Stream, error)) func(key, iv []byte, macKey []byte, algs directionAlgorithms) (packetCipher, error) { - return func(key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) { +func streamCipherMode(skip int, createFunc func(key, iv []byte) (cipher.Stream, error)) func(key, iv []byte, macKey []byte, algs DirectionAlgorithms) (packetCipher, error) { + return func(key, iv, macKey []byte, algs DirectionAlgorithms) (packetCipher, error) { stream, err := createFunc(key, iv) if err != nil { return nil, err @@ -98,36 +98,36 @@ func streamCipherMode(skip int, createFunc func(key, iv []byte) (cipher.Stream, var cipherModes = map[string]*cipherMode{ // Ciphers from RFC 4344, which introduced many CTR-based ciphers. Algorithms // are defined in the order specified in the RFC. - "aes128-ctr": {16, aes.BlockSize, streamCipherMode(0, newAESCTR)}, - "aes192-ctr": {24, aes.BlockSize, streamCipherMode(0, newAESCTR)}, - "aes256-ctr": {32, aes.BlockSize, streamCipherMode(0, newAESCTR)}, + CipherAES128CTR: {16, aes.BlockSize, streamCipherMode(0, newAESCTR)}, + CipherAES192CTR: {24, aes.BlockSize, streamCipherMode(0, newAESCTR)}, + CipherAES256CTR: {32, aes.BlockSize, streamCipherMode(0, newAESCTR)}, // Ciphers from RFC 4345, which introduces security-improved arcfour ciphers. // They are defined in the order specified in the RFC. - "arcfour128": {16, 0, streamCipherMode(1536, newRC4)}, - "arcfour256": {32, 0, streamCipherMode(1536, newRC4)}, + InsecureCipherRC4128: {16, 0, streamCipherMode(1536, newRC4)}, + InsecureCipherRC4256: {32, 0, streamCipherMode(1536, newRC4)}, // Cipher defined in RFC 4253, which describes SSH Transport Layer Protocol. // Note that this cipher is not safe, as stated in RFC 4253: "Arcfour (and // RC4) has problems with weak keys, and should be used with caution." // RFC 4345 introduces improved versions of Arcfour. - "arcfour": {16, 0, streamCipherMode(0, newRC4)}, + InsecureCipherRC4: {16, 0, streamCipherMode(0, newRC4)}, // AEAD ciphers - gcm128CipherID: {16, 12, newGCMCipher}, - gcm256CipherID: {32, 12, newGCMCipher}, - chacha20Poly1305ID: {64, 0, newChaCha20Cipher}, + CipherAES128GCM: {16, 12, newGCMCipher}, + CipherAES256GCM: {32, 12, newGCMCipher}, + CipherChaCha20Poly1305: {64, 0, newChaCha20Cipher}, // CBC mode is insecure and so is not included in the default config. // (See https://www.ieee-security.org/TC/SP2013/papers/4977a526.pdf). If absolutely // needed, it's possible to specify a custom Config to enable it. // You should expect that an active attacker can recover plaintext if // you do. - aes128cbcID: {16, aes.BlockSize, newAESCBCCipher}, + InsecureCipherAES128CBC: {16, aes.BlockSize, newAESCBCCipher}, // 3des-cbc is insecure and is not included in the default // config. - tripledescbcID: {24, des.BlockSize, newTripleDESCBCCipher}, + InsecureCipherTripleDESCBC: {24, des.BlockSize, newTripleDESCBCCipher}, } // prefixLen is the length of the packet prefix that contains the packet length @@ -307,7 +307,7 @@ type gcmCipher struct { buf []byte } -func newGCMCipher(key, iv, unusedMacKey []byte, unusedAlgs directionAlgorithms) (packetCipher, error) { +func newGCMCipher(key, iv, unusedMacKey []byte, unusedAlgs DirectionAlgorithms) (packetCipher, error) { c, err := aes.NewCipher(key) if err != nil { return nil, err @@ -429,7 +429,7 @@ type cbcCipher struct { oracleCamouflage uint32 } -func newCBCCipher(c cipher.Block, key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) { +func newCBCCipher(c cipher.Block, key, iv, macKey []byte, algs DirectionAlgorithms) (packetCipher, error) { cbc := &cbcCipher{ mac: macModes[algs.MAC].new(macKey), decrypter: cipher.NewCBCDecrypter(c, iv), @@ -443,7 +443,7 @@ func newCBCCipher(c cipher.Block, key, iv, macKey []byte, algs directionAlgorith return cbc, nil } -func newAESCBCCipher(key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) { +func newAESCBCCipher(key, iv, macKey []byte, algs DirectionAlgorithms) (packetCipher, error) { c, err := aes.NewCipher(key) if err != nil { return nil, err @@ -457,7 +457,7 @@ func newAESCBCCipher(key, iv, macKey []byte, algs directionAlgorithms) (packetCi return cbc, nil } -func newTripleDESCBCCipher(key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) { +func newTripleDESCBCCipher(key, iv, macKey []byte, algs DirectionAlgorithms) (packetCipher, error) { c, err := des.NewTripleDESCipher(key) if err != nil { return nil, err @@ -635,8 +635,6 @@ func (c *cbcCipher) writeCipherPacket(seqNum uint32, w io.Writer, rand io.Reader return nil } -const chacha20Poly1305ID = "chacha20-poly1305@openssh.com" - // chacha20Poly1305Cipher implements the chacha20-poly1305@openssh.com // AEAD, which is described here: // @@ -650,7 +648,7 @@ type chacha20Poly1305Cipher struct { buf []byte } -func newChaCha20Cipher(key, unusedIV, unusedMACKey []byte, unusedAlgs directionAlgorithms) (packetCipher, error) { +func newChaCha20Cipher(key, unusedIV, unusedMACKey []byte, unusedAlgs DirectionAlgorithms) (packetCipher, error) { if len(key) != 64 { panic(len(key)) } diff --git a/vendor/golang.org/x/crypto/ssh/client.go b/vendor/golang.org/x/crypto/ssh/client.go index fd8c497..3307978 100644 --- a/vendor/golang.org/x/crypto/ssh/client.go +++ b/vendor/golang.org/x/crypto/ssh/client.go @@ -110,6 +110,7 @@ func (c *connection) clientHandshake(dialAddress string, config *ClientConfig) e } c.sessionID = c.transport.getSessionID() + c.algorithms = c.transport.getAlgorithms() return c.clientAuthenticate(config) } diff --git a/vendor/golang.org/x/crypto/ssh/common.go b/vendor/golang.org/x/crypto/ssh/common.go index 7e9c2cb..0415d33 100644 --- a/vendor/golang.org/x/crypto/ssh/common.go +++ b/vendor/golang.org/x/crypto/ssh/common.go @@ -10,6 +10,7 @@ import ( "fmt" "io" "math" + "slices" "sync" _ "crypto/sha1" @@ -24,69 +25,258 @@ const ( serviceSSH = "ssh-connection" ) -// supportedCiphers lists ciphers we support but might not recommend. -var supportedCiphers = []string{ - "aes128-ctr", "aes192-ctr", "aes256-ctr", - "aes128-gcm@openssh.com", gcm256CipherID, - chacha20Poly1305ID, - "arcfour256", "arcfour128", "arcfour", - aes128cbcID, - tripledescbcID, -} - -// preferredCiphers specifies the default preference for ciphers. -var preferredCiphers = []string{ - "aes128-gcm@openssh.com", gcm256CipherID, - chacha20Poly1305ID, - "aes128-ctr", "aes192-ctr", "aes256-ctr", -} - -// supportedKexAlgos specifies the supported key-exchange algorithms in -// preference order. -var supportedKexAlgos = []string{ - kexAlgoCurve25519SHA256, kexAlgoCurve25519SHA256LibSSH, - // P384 and P521 are not constant-time yet, but since we don't - // reuse ephemeral keys, using them for ECDH should be OK. - kexAlgoECDH256, kexAlgoECDH384, kexAlgoECDH521, - kexAlgoDH14SHA256, kexAlgoDH16SHA512, kexAlgoDH14SHA1, - kexAlgoDH1SHA1, -} +// The ciphers currently or previously implemented by this library, to use in +// [Config.Ciphers]. For a list, see the [Algorithms.Ciphers] returned by +// [SupportedAlgorithms] or [InsecureAlgorithms]. +const ( + CipherAES128GCM = "aes128-gcm@openssh.com" + CipherAES256GCM = "aes256-gcm@openssh.com" + CipherChaCha20Poly1305 = "chacha20-poly1305@openssh.com" + CipherAES128CTR = "aes128-ctr" + CipherAES192CTR = "aes192-ctr" + CipherAES256CTR = "aes256-ctr" + InsecureCipherAES128CBC = "aes128-cbc" + InsecureCipherTripleDESCBC = "3des-cbc" + InsecureCipherRC4 = "arcfour" + InsecureCipherRC4128 = "arcfour128" + InsecureCipherRC4256 = "arcfour256" +) -// serverForbiddenKexAlgos contains key exchange algorithms, that are forbidden -// for the server half. -var serverForbiddenKexAlgos = map[string]struct{}{ - kexAlgoDHGEXSHA1: {}, // server half implementation is only minimal to satisfy the automated tests - kexAlgoDHGEXSHA256: {}, // server half implementation is only minimal to satisfy the automated tests -} +// The key exchanges currently or previously implemented by this library, to use +// in [Config.KeyExchanges]. For a list, see the +// [Algorithms.KeyExchanges] returned by [SupportedAlgorithms] or +// [InsecureAlgorithms]. +const ( + InsecureKeyExchangeDH1SHA1 = "diffie-hellman-group1-sha1" + InsecureKeyExchangeDH14SHA1 = "diffie-hellman-group14-sha1" + KeyExchangeDH14SHA256 = "diffie-hellman-group14-sha256" + KeyExchangeDH16SHA512 = "diffie-hellman-group16-sha512" + KeyExchangeECDHP256 = "ecdh-sha2-nistp256" + KeyExchangeECDHP384 = "ecdh-sha2-nistp384" + KeyExchangeECDHP521 = "ecdh-sha2-nistp521" + KeyExchangeCurve25519 = "curve25519-sha256" + InsecureKeyExchangeDHGEXSHA1 = "diffie-hellman-group-exchange-sha1" + KeyExchangeDHGEXSHA256 = "diffie-hellman-group-exchange-sha256" + // KeyExchangeMLKEM768X25519 is supported from Go 1.24. + KeyExchangeMLKEM768X25519 = "mlkem768x25519-sha256" + + // An alias for KeyExchangeCurve25519SHA256. This kex ID will be added if + // KeyExchangeCurve25519SHA256 is requested for backward compatibility with + // OpenSSH versions up to 7.2. + keyExchangeCurve25519LibSSH = "curve25519-sha256@libssh.org" +) -// preferredKexAlgos specifies the default preference for key-exchange -// algorithms in preference order. The diffie-hellman-group16-sha512 algorithm -// is disabled by default because it is a bit slower than the others. -var preferredKexAlgos = []string{ - kexAlgoCurve25519SHA256, kexAlgoCurve25519SHA256LibSSH, - kexAlgoECDH256, kexAlgoECDH384, kexAlgoECDH521, - kexAlgoDH14SHA256, kexAlgoDH14SHA1, -} +// The message authentication code (MAC) currently or previously implemented by +// this library, to use in [Config.MACs]. For a list, see the +// [Algorithms.MACs] returned by [SupportedAlgorithms] or +// [InsecureAlgorithms]. +const ( + HMACSHA256ETM = "hmac-sha2-256-etm@openssh.com" + HMACSHA512ETM = "hmac-sha2-512-etm@openssh.com" + HMACSHA256 = "hmac-sha2-256" + HMACSHA512 = "hmac-sha2-512" + HMACSHA1 = "hmac-sha1" + InsecureHMACSHA196 = "hmac-sha1-96" +) -// supportedHostKeyAlgos specifies the supported host-key algorithms (i.e. methods -// of authenticating servers) in preference order. -var supportedHostKeyAlgos = []string{ - CertAlgoRSASHA256v01, CertAlgoRSASHA512v01, - CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, - CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoED25519v01, +var ( + // supportedKexAlgos specifies key-exchange algorithms implemented by this + // package in preference order, excluding those with security issues. + supportedKexAlgos = []string{ + KeyExchangeCurve25519, + KeyExchangeECDHP256, + KeyExchangeECDHP384, + KeyExchangeECDHP521, + KeyExchangeDH14SHA256, + KeyExchangeDH16SHA512, + KeyExchangeDHGEXSHA256, + } + // defaultKexAlgos specifies the default preference for key-exchange + // algorithms in preference order. + defaultKexAlgos = []string{ + KeyExchangeCurve25519, + KeyExchangeECDHP256, + KeyExchangeECDHP384, + KeyExchangeECDHP521, + KeyExchangeDH14SHA256, + InsecureKeyExchangeDH14SHA1, + } + // insecureKexAlgos specifies key-exchange algorithms implemented by this + // package and which have security issues. + insecureKexAlgos = []string{ + InsecureKeyExchangeDH14SHA1, + InsecureKeyExchangeDH1SHA1, + InsecureKeyExchangeDHGEXSHA1, + } + // supportedCiphers specifies cipher algorithms implemented by this package + // in preference order, excluding those with security issues. + supportedCiphers = []string{ + CipherAES128GCM, + CipherAES256GCM, + CipherChaCha20Poly1305, + CipherAES128CTR, + CipherAES192CTR, + CipherAES256CTR, + } + // defaultCiphers specifies the default preference for ciphers algorithms + // in preference order. + defaultCiphers = supportedCiphers + // insecureCiphers specifies cipher algorithms implemented by this + // package and which have security issues. + insecureCiphers = []string{ + InsecureCipherAES128CBC, + InsecureCipherTripleDESCBC, + InsecureCipherRC4256, + InsecureCipherRC4128, + InsecureCipherRC4, + } + // supportedMACs specifies MAC algorithms implemented by this package in + // preference order, excluding those with security issues. + supportedMACs = []string{ + HMACSHA256ETM, + HMACSHA512ETM, + HMACSHA256, + HMACSHA512, + HMACSHA1, + } + // defaultMACs specifies the default preference for MAC algorithms in + // preference order. + defaultMACs = []string{ + HMACSHA256ETM, + HMACSHA512ETM, + HMACSHA256, + HMACSHA512, + HMACSHA1, + InsecureHMACSHA196, + } + // insecureMACs specifies MAC algorithms implemented by this + // package and which have security issues. + insecureMACs = []string{ + InsecureHMACSHA196, + } + // supportedHostKeyAlgos specifies the supported host-key algorithms (i.e. + // methods of authenticating servers) implemented by this package in + // preference order, excluding those with security issues. + supportedHostKeyAlgos = []string{ + CertAlgoRSASHA256v01, + CertAlgoRSASHA512v01, + CertAlgoECDSA256v01, + CertAlgoECDSA384v01, + CertAlgoECDSA521v01, + CertAlgoED25519v01, + KeyAlgoRSASHA256, + KeyAlgoRSASHA512, + KeyAlgoECDSA256, + KeyAlgoECDSA384, + KeyAlgoECDSA521, + KeyAlgoED25519, + } + // defaultHostKeyAlgos specifies the default preference for host-key + // algorithms in preference order. + defaultHostKeyAlgos = []string{ + CertAlgoRSASHA256v01, + CertAlgoRSASHA512v01, + CertAlgoRSAv01, + InsecureCertAlgoDSAv01, + CertAlgoECDSA256v01, + CertAlgoECDSA384v01, + CertAlgoECDSA521v01, + CertAlgoED25519v01, + KeyAlgoECDSA256, + KeyAlgoECDSA384, + KeyAlgoECDSA521, + KeyAlgoRSASHA256, + KeyAlgoRSASHA512, + KeyAlgoRSA, + InsecureKeyAlgoDSA, + KeyAlgoED25519, + } + // insecureHostKeyAlgos specifies host-key algorithms implemented by this + // package and which have security issues. + insecureHostKeyAlgos = []string{ + KeyAlgoRSA, + InsecureKeyAlgoDSA, + CertAlgoRSAv01, + InsecureCertAlgoDSAv01, + } + // supportedPubKeyAuthAlgos specifies the supported client public key + // authentication algorithms. Note that this doesn't include certificate + // types since those use the underlying algorithm. Order is irrelevant. + supportedPubKeyAuthAlgos = []string{ + KeyAlgoED25519, + KeyAlgoSKED25519, + KeyAlgoSKECDSA256, + KeyAlgoECDSA256, + KeyAlgoECDSA384, + KeyAlgoECDSA521, + KeyAlgoRSASHA256, + KeyAlgoRSASHA512, + } - KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521, - KeyAlgoRSASHA256, KeyAlgoRSASHA512, - KeyAlgoRSA, KeyAlgoDSA, + // defaultPubKeyAuthAlgos specifies the preferred client public key + // authentication algorithms. This list is sent to the client if it supports + // the server-sig-algs extension. Order is irrelevant. + defaultPubKeyAuthAlgos = []string{ + KeyAlgoED25519, + KeyAlgoSKED25519, + KeyAlgoSKECDSA256, + KeyAlgoECDSA256, + KeyAlgoECDSA384, + KeyAlgoECDSA521, + KeyAlgoRSASHA256, + KeyAlgoRSASHA512, + KeyAlgoRSA, + InsecureKeyAlgoDSA, + } + // insecurePubKeyAuthAlgos specifies client public key authentication + // algorithms implemented by this package and which have security issues. + insecurePubKeyAuthAlgos = []string{ + KeyAlgoRSA, + InsecureKeyAlgoDSA, + } +) - KeyAlgoED25519, +// NegotiatedAlgorithms defines algorithms negotiated between client and server. +type NegotiatedAlgorithms struct { + KeyExchange string + HostKey string + Read DirectionAlgorithms + Write DirectionAlgorithms +} + +// Algorithms defines a set of algorithms that can be configured in the client +// or server config for negotiation during a handshake. +type Algorithms struct { + KeyExchanges []string + Ciphers []string + MACs []string + HostKeys []string + PublicKeyAuths []string +} + +// SupportedAlgorithms returns algorithms currently implemented by this package, +// excluding those with security issues, which are returned by +// InsecureAlgorithms. The algorithms listed here are in preference order. +func SupportedAlgorithms() Algorithms { + return Algorithms{ + Ciphers: slices.Clone(supportedCiphers), + MACs: slices.Clone(supportedMACs), + KeyExchanges: slices.Clone(supportedKexAlgos), + HostKeys: slices.Clone(supportedHostKeyAlgos), + PublicKeyAuths: slices.Clone(supportedPubKeyAuthAlgos), + } } -// supportedMACs specifies a default set of MAC algorithms in preference order. -// This is based on RFC 4253, section 6.4, but with hmac-md5 variants removed -// because they have reached the end of their useful life. -var supportedMACs = []string{ - "hmac-sha2-256-etm@openssh.com", "hmac-sha2-512-etm@openssh.com", "hmac-sha2-256", "hmac-sha2-512", "hmac-sha1", "hmac-sha1-96", +// InsecureAlgorithms returns algorithms currently implemented by this package +// and which have security issues. +func InsecureAlgorithms() Algorithms { + return Algorithms{ + KeyExchanges: slices.Clone(insecureKexAlgos), + Ciphers: slices.Clone(insecureCiphers), + MACs: slices.Clone(insecureMACs), + HostKeys: slices.Clone(insecureHostKeyAlgos), + PublicKeyAuths: slices.Clone(insecurePubKeyAuthAlgos), + } } var supportedCompressions = []string{compressionNone} @@ -94,13 +284,13 @@ var supportedCompressions = []string{compressionNone} // hashFuncs keeps the mapping of supported signature algorithms to their // respective hashes needed for signing and verification. var hashFuncs = map[string]crypto.Hash{ - KeyAlgoRSA: crypto.SHA1, - KeyAlgoRSASHA256: crypto.SHA256, - KeyAlgoRSASHA512: crypto.SHA512, - KeyAlgoDSA: crypto.SHA1, - KeyAlgoECDSA256: crypto.SHA256, - KeyAlgoECDSA384: crypto.SHA384, - KeyAlgoECDSA521: crypto.SHA512, + KeyAlgoRSA: crypto.SHA1, + KeyAlgoRSASHA256: crypto.SHA256, + KeyAlgoRSASHA512: crypto.SHA512, + InsecureKeyAlgoDSA: crypto.SHA1, + KeyAlgoECDSA256: crypto.SHA256, + KeyAlgoECDSA384: crypto.SHA384, + KeyAlgoECDSA521: crypto.SHA512, // KeyAlgoED25519 doesn't pre-hash. KeyAlgoSKECDSA256: crypto.SHA256, KeyAlgoSKED25519: crypto.SHA256, @@ -135,18 +325,6 @@ func isRSACert(algo string) bool { return isRSA(algo) } -// supportedPubKeyAuthAlgos specifies the supported client public key -// authentication algorithms. Note that this doesn't include certificate types -// since those use the underlying algorithm. This list is sent to the client if -// it supports the server-sig-algs extension. Order is irrelevant. -var supportedPubKeyAuthAlgos = []string{ - KeyAlgoED25519, - KeyAlgoSKED25519, KeyAlgoSKECDSA256, - KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521, - KeyAlgoRSASHA256, KeyAlgoRSASHA512, KeyAlgoRSA, - KeyAlgoDSA, -} - // unexpectedMessageError results when the SSH message that we received didn't // match what we wanted. func unexpectedMessageError(expected, got uint8) error { @@ -169,20 +347,21 @@ func findCommon(what string, client []string, server []string) (common string, e return "", fmt.Errorf("ssh: no common algorithm for %s; client offered: %v, server offered: %v", what, client, server) } -// directionAlgorithms records algorithm choices in one direction (either read or write) -type directionAlgorithms struct { +// DirectionAlgorithms defines the algorithms negotiated in one direction +// (either read or write). +type DirectionAlgorithms struct { Cipher string MAC string - Compression string + compression string } // rekeyBytes returns a rekeying intervals in bytes. -func (a *directionAlgorithms) rekeyBytes() int64 { +func (a *DirectionAlgorithms) rekeyBytes() int64 { // According to RFC 4344 block ciphers should rekey after // 2^(BLOCKSIZE/4) blocks. For all AES flavors BLOCKSIZE is // 128. switch a.Cipher { - case "aes128-ctr", "aes192-ctr", "aes256-ctr", gcm128CipherID, gcm256CipherID, aes128cbcID: + case CipherAES128CTR, CipherAES192CTR, CipherAES256CTR, CipherAES128GCM, CipherAES256GCM, InsecureCipherAES128CBC: return 16 * (1 << 32) } @@ -192,32 +371,25 @@ func (a *directionAlgorithms) rekeyBytes() int64 { } var aeadCiphers = map[string]bool{ - gcm128CipherID: true, - gcm256CipherID: true, - chacha20Poly1305ID: true, -} - -type algorithms struct { - kex string - hostKey string - w directionAlgorithms - r directionAlgorithms + CipherAES128GCM: true, + CipherAES256GCM: true, + CipherChaCha20Poly1305: true, } -func findAgreedAlgorithms(isClient bool, clientKexInit, serverKexInit *kexInitMsg) (algs *algorithms, err error) { - result := &algorithms{} +func findAgreedAlgorithms(isClient bool, clientKexInit, serverKexInit *kexInitMsg) (algs *NegotiatedAlgorithms, err error) { + result := &NegotiatedAlgorithms{} - result.kex, err = findCommon("key exchange", clientKexInit.KexAlgos, serverKexInit.KexAlgos) + result.KeyExchange, err = findCommon("key exchange", clientKexInit.KexAlgos, serverKexInit.KexAlgos) if err != nil { return } - result.hostKey, err = findCommon("host key", clientKexInit.ServerHostKeyAlgos, serverKexInit.ServerHostKeyAlgos) + result.HostKey, err = findCommon("host key", clientKexInit.ServerHostKeyAlgos, serverKexInit.ServerHostKeyAlgos) if err != nil { return } - stoc, ctos := &result.w, &result.r + stoc, ctos := &result.Write, &result.Read if isClient { ctos, stoc = stoc, ctos } @@ -246,12 +418,12 @@ func findAgreedAlgorithms(isClient bool, clientKexInit, serverKexInit *kexInitMs } } - ctos.Compression, err = findCommon("client to server compression", clientKexInit.CompressionClientServer, serverKexInit.CompressionClientServer) + ctos.compression, err = findCommon("client to server compression", clientKexInit.CompressionClientServer, serverKexInit.CompressionClientServer) if err != nil { return } - stoc.Compression, err = findCommon("server to client compression", clientKexInit.CompressionServerClient, serverKexInit.CompressionServerClient) + stoc.compression, err = findCommon("server to client compression", clientKexInit.CompressionServerClient, serverKexInit.CompressionServerClient) if err != nil { return } @@ -297,7 +469,7 @@ func (c *Config) SetDefaults() { c.Rand = rand.Reader } if c.Ciphers == nil { - c.Ciphers = preferredCiphers + c.Ciphers = defaultCiphers } var ciphers []string for _, c := range c.Ciphers { @@ -309,19 +481,22 @@ func (c *Config) SetDefaults() { c.Ciphers = ciphers if c.KeyExchanges == nil { - c.KeyExchanges = preferredKexAlgos + c.KeyExchanges = defaultKexAlgos } var kexs []string for _, k := range c.KeyExchanges { if kexAlgoMap[k] != nil { // Ignore the KEX if we have no kexAlgoMap definition. kexs = append(kexs, k) + if k == KeyExchangeCurve25519 && !contains(c.KeyExchanges, keyExchangeCurve25519LibSSH) { + kexs = append(kexs, keyExchangeCurve25519LibSSH) + } } } c.KeyExchanges = kexs if c.MACs == nil { - c.MACs = supportedMACs + c.MACs = defaultMACs } var macs []string for _, m := range c.MACs { diff --git a/vendor/golang.org/x/crypto/ssh/connection.go b/vendor/golang.org/x/crypto/ssh/connection.go index 8f345ee..613a71a 100644 --- a/vendor/golang.org/x/crypto/ssh/connection.go +++ b/vendor/golang.org/x/crypto/ssh/connection.go @@ -74,6 +74,13 @@ type Conn interface { // Disconnect } +// AlgorithmsConnMetadata is a ConnMetadata that can return the algorithms +// negotiated between client and server. +type AlgorithmsConnMetadata interface { + ConnMetadata + Algorithms() NegotiatedAlgorithms +} + // DiscardRequests consumes and rejects all requests from the // passed-in channel. func DiscardRequests(in <-chan *Request) { @@ -106,6 +113,7 @@ type sshConn struct { sessionID []byte clientVersion []byte serverVersion []byte + algorithms NegotiatedAlgorithms } func dup(src []byte) []byte { @@ -141,3 +149,7 @@ func (c *sshConn) ClientVersion() []byte { func (c *sshConn) ServerVersion() []byte { return dup(c.serverVersion) } + +func (c *sshConn) Algorithms() NegotiatedAlgorithms { + return c.algorithms +} diff --git a/vendor/golang.org/x/crypto/ssh/handshake.go b/vendor/golang.org/x/crypto/ssh/handshake.go index b6bf546..a90bfe3 100644 --- a/vendor/golang.org/x/crypto/ssh/handshake.go +++ b/vendor/golang.org/x/crypto/ssh/handshake.go @@ -38,7 +38,7 @@ type keyingTransport interface { // prepareKeyChange sets up a key change. The key change for a // direction will be effected if a msgNewKeys message is sent // or received. - prepareKeyChange(*algorithms, *kexResult) error + prepareKeyChange(*NegotiatedAlgorithms, *kexResult) error // setStrictMode sets the strict KEX mode, notably triggering // sequence number resets on sending or receiving msgNewKeys. @@ -115,7 +115,7 @@ type handshakeTransport struct { bannerCallback BannerCallback // Algorithms agreed in the last key exchange. - algorithms *algorithms + algorithms *NegotiatedAlgorithms // Counters exclusively owned by readLoop. readPacketsLeft uint32 @@ -164,7 +164,7 @@ func newClientTransport(conn keyingTransport, clientVersion, serverVersion []byt if config.HostKeyAlgorithms != nil { t.hostKeyAlgorithms = config.HostKeyAlgorithms } else { - t.hostKeyAlgorithms = supportedHostKeyAlgos + t.hostKeyAlgorithms = defaultHostKeyAlgos } go t.readLoop() go t.kexLoop() @@ -184,6 +184,10 @@ func (t *handshakeTransport) getSessionID() []byte { return t.sessionID } +func (t *handshakeTransport) getAlgorithms() NegotiatedAlgorithms { + return *t.algorithms +} + // waitSession waits for the session to be established. This should be // the first thing to call after instantiating handshakeTransport. func (t *handshakeTransport) waitSession() error { @@ -290,7 +294,7 @@ func (t *handshakeTransport) resetWriteThresholds() { if t.config.RekeyThreshold > 0 { t.writeBytesLeft = int64(t.config.RekeyThreshold) } else if t.algorithms != nil { - t.writeBytesLeft = t.algorithms.w.rekeyBytes() + t.writeBytesLeft = t.algorithms.Write.rekeyBytes() } else { t.writeBytesLeft = 1 << 30 } @@ -407,7 +411,7 @@ func (t *handshakeTransport) resetReadThresholds() { if t.config.RekeyThreshold > 0 { t.readBytesLeft = int64(t.config.RekeyThreshold) } else if t.algorithms != nil { - t.readBytesLeft = t.algorithms.r.rekeyBytes() + t.readBytesLeft = t.algorithms.Read.rekeyBytes() } else { t.readBytesLeft = 1 << 30 } @@ -700,9 +704,9 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error { } } - kex, ok := kexAlgoMap[t.algorithms.kex] + kex, ok := kexAlgoMap[t.algorithms.KeyExchange] if !ok { - return fmt.Errorf("ssh: unexpected key exchange algorithm %v", t.algorithms.kex) + return fmt.Errorf("ssh: unexpected key exchange algorithm %v", t.algorithms.KeyExchange) } var result *kexResult @@ -809,12 +813,12 @@ func pickHostKey(hostKeys []Signer, algo string) AlgorithmSigner { } func (t *handshakeTransport) server(kex kexAlgorithm, magics *handshakeMagics) (*kexResult, error) { - hostKey := pickHostKey(t.hostKeys, t.algorithms.hostKey) + hostKey := pickHostKey(t.hostKeys, t.algorithms.HostKey) if hostKey == nil { return nil, errors.New("ssh: internal error: negotiated unsupported signature type") } - r, err := kex.Server(t.conn, t.config.Rand, magics, hostKey, t.algorithms.hostKey) + r, err := kex.Server(t.conn, t.config.Rand, magics, hostKey, t.algorithms.HostKey) return r, err } @@ -829,7 +833,7 @@ func (t *handshakeTransport) client(kex kexAlgorithm, magics *handshakeMagics) ( return nil, err } - if err := verifyHostKeySignature(hostKey, t.algorithms.hostKey, result); err != nil { + if err := verifyHostKeySignature(hostKey, t.algorithms.HostKey, result); err != nil { return nil, err } diff --git a/vendor/golang.org/x/crypto/ssh/kex.go b/vendor/golang.org/x/crypto/ssh/kex.go index 8a05f79..cf388a9 100644 --- a/vendor/golang.org/x/crypto/ssh/kex.go +++ b/vendor/golang.org/x/crypto/ssh/kex.go @@ -20,21 +20,18 @@ import ( ) const ( - kexAlgoDH1SHA1 = "diffie-hellman-group1-sha1" - kexAlgoDH14SHA1 = "diffie-hellman-group14-sha1" - kexAlgoDH14SHA256 = "diffie-hellman-group14-sha256" - kexAlgoDH16SHA512 = "diffie-hellman-group16-sha512" - kexAlgoECDH256 = "ecdh-sha2-nistp256" - kexAlgoECDH384 = "ecdh-sha2-nistp384" - kexAlgoECDH521 = "ecdh-sha2-nistp521" - kexAlgoCurve25519SHA256LibSSH = "curve25519-sha256@libssh.org" - kexAlgoCurve25519SHA256 = "curve25519-sha256" - - // For the following kex only the client half contains a production - // ready implementation. The server half only consists of a minimal - // implementation to satisfy the automated tests. - kexAlgoDHGEXSHA1 = "diffie-hellman-group-exchange-sha1" - kexAlgoDHGEXSHA256 = "diffie-hellman-group-exchange-sha256" + // This is the group called diffie-hellman-group1-sha1 in RFC 4253 and + // Oakley Group 2 in RFC 2409. + oakleyGroup2 = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF" + // This is the group called diffie-hellman-group14-sha1 in RFC 4253 and + // Oakley Group 14 in RFC 3526. + oakleyGroup14 = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF" + // This is the group called diffie-hellman-group15-sha512 in RFC 8268 and + // Oakley Group 15 in RFC 3526. + oakleyGroup15 = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF" + // This is the group called diffie-hellman-group16-sha512 in RFC 8268 and + // Oakley Group 16 in RFC 3526. + oakleyGroup16 = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF" ) // kexResult captures the outcome of a key exchange. @@ -402,53 +399,46 @@ func ecHash(curve elliptic.Curve) crypto.Hash { var kexAlgoMap = map[string]kexAlgorithm{} func init() { - // This is the group called diffie-hellman-group1-sha1 in - // RFC 4253 and Oakley Group 2 in RFC 2409. - p, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF", 16) - kexAlgoMap[kexAlgoDH1SHA1] = &dhGroup{ + p, _ := new(big.Int).SetString(oakleyGroup2, 16) + kexAlgoMap[InsecureKeyExchangeDH1SHA1] = &dhGroup{ g: new(big.Int).SetInt64(2), p: p, pMinus1: new(big.Int).Sub(p, bigOne), hashFunc: crypto.SHA1, } - // This are the groups called diffie-hellman-group14-sha1 and - // diffie-hellman-group14-sha256 in RFC 4253 and RFC 8268, - // and Oakley Group 14 in RFC 3526. - p, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", 16) + p, _ = new(big.Int).SetString(oakleyGroup14, 16) group14 := &dhGroup{ g: new(big.Int).SetInt64(2), p: p, pMinus1: new(big.Int).Sub(p, bigOne), } - kexAlgoMap[kexAlgoDH14SHA1] = &dhGroup{ + kexAlgoMap[InsecureKeyExchangeDH14SHA1] = &dhGroup{ g: group14.g, p: group14.p, pMinus1: group14.pMinus1, hashFunc: crypto.SHA1, } - kexAlgoMap[kexAlgoDH14SHA256] = &dhGroup{ + kexAlgoMap[KeyExchangeDH14SHA256] = &dhGroup{ g: group14.g, p: group14.p, pMinus1: group14.pMinus1, hashFunc: crypto.SHA256, } - // This is the group called diffie-hellman-group16-sha512 in RFC - // 8268 and Oakley Group 16 in RFC 3526. - p, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF", 16) + p, _ = new(big.Int).SetString(oakleyGroup16, 16) - kexAlgoMap[kexAlgoDH16SHA512] = &dhGroup{ + kexAlgoMap[KeyExchangeDH16SHA512] = &dhGroup{ g: new(big.Int).SetInt64(2), p: p, pMinus1: new(big.Int).Sub(p, bigOne), hashFunc: crypto.SHA512, } - kexAlgoMap[kexAlgoECDH521] = &ecdh{elliptic.P521()} - kexAlgoMap[kexAlgoECDH384] = &ecdh{elliptic.P384()} - kexAlgoMap[kexAlgoECDH256] = &ecdh{elliptic.P256()} - kexAlgoMap[kexAlgoCurve25519SHA256] = &curve25519sha256{} - kexAlgoMap[kexAlgoCurve25519SHA256LibSSH] = &curve25519sha256{} - kexAlgoMap[kexAlgoDHGEXSHA1] = &dhGEXSHA{hashFunc: crypto.SHA1} - kexAlgoMap[kexAlgoDHGEXSHA256] = &dhGEXSHA{hashFunc: crypto.SHA256} + kexAlgoMap[KeyExchangeECDHP521] = &ecdh{elliptic.P521()} + kexAlgoMap[KeyExchangeECDHP384] = &ecdh{elliptic.P384()} + kexAlgoMap[KeyExchangeECDHP256] = &ecdh{elliptic.P256()} + kexAlgoMap[KeyExchangeCurve25519] = &curve25519sha256{} + kexAlgoMap[keyExchangeCurve25519LibSSH] = &curve25519sha256{} + kexAlgoMap[InsecureKeyExchangeDHGEXSHA1] = &dhGEXSHA{hashFunc: crypto.SHA1} + kexAlgoMap[KeyExchangeDHGEXSHA256] = &dhGEXSHA{hashFunc: crypto.SHA256} } // curve25519sha256 implements the curve25519-sha256 (formerly known as @@ -601,9 +591,9 @@ const ( func (gex *dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshakeMagics) (*kexResult, error) { // Send GexRequest kexDHGexRequest := kexDHGexRequestMsg{ - MinBits: dhGroupExchangeMinimumBits, - PreferedBits: dhGroupExchangePreferredBits, - MaxBits: dhGroupExchangeMaximumBits, + MinBits: dhGroupExchangeMinimumBits, + PreferredBits: dhGroupExchangePreferredBits, + MaxBits: dhGroupExchangeMaximumBits, } if err := c.writePacket(Marshal(&kexDHGexRequest)); err != nil { return nil, err @@ -690,9 +680,7 @@ func (gex *dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshak } // Server half implementation of the Diffie Hellman Key Exchange with SHA1 and SHA256. -// -// This is a minimal implementation to satisfy the automated tests. -func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv AlgorithmSigner, algo string) (result *kexResult, err error) { +func (gex *dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv AlgorithmSigner, algo string) (result *kexResult, err error) { // Receive GexRequest packet, err := c.readPacket() if err != nil { @@ -702,13 +690,32 @@ func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshake if err = Unmarshal(packet, &kexDHGexRequest); err != nil { return } + // We check that the request received is valid and that the MaxBits + // requested are at least equal to our supported minimum. This is the same + // check done in OpenSSH: + // https://github.com/openssh/openssh-portable/blob/80a2f64b/kexgexs.c#L94 + // + // Furthermore, we also check that the required MinBits are less than or + // equal to 4096 because we can use up to Oakley Group 16. + if kexDHGexRequest.MaxBits < kexDHGexRequest.MinBits || kexDHGexRequest.PreferredBits < kexDHGexRequest.MinBits || + kexDHGexRequest.MaxBits < kexDHGexRequest.PreferredBits || kexDHGexRequest.MaxBits < dhGroupExchangeMinimumBits || + kexDHGexRequest.MinBits > 4096 { + return nil, fmt.Errorf("ssh: DH GEX request out of range, min: %d, max: %d, preferred: %d", kexDHGexRequest.MinBits, + kexDHGexRequest.MaxBits, kexDHGexRequest.PreferredBits) + } + + var p *big.Int + // We hardcode sending Oakley Group 14 (2048 bits), Oakley Group 15 (3072 + // bits) or Oakley Group 16 (4096 bits), based on the requested max size. + if kexDHGexRequest.MaxBits < 3072 { + p, _ = new(big.Int).SetString(oakleyGroup14, 16) + } else if kexDHGexRequest.MaxBits < 4096 { + p, _ = new(big.Int).SetString(oakleyGroup15, 16) + } else { + p, _ = new(big.Int).SetString(oakleyGroup16, 16) + } - // Send GexGroup - // This is the group called diffie-hellman-group14-sha1 in RFC - // 4253 and Oakley Group 14 in RFC 3526. - p, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", 16) g := big.NewInt(2) - msg := &kexDHGexGroupMsg{ P: p, G: g, @@ -746,9 +753,9 @@ func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshake h := gex.hashFunc.New() magics.write(h) writeString(h, hostKeyBytes) - binary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMinimumBits)) - binary.Write(h, binary.BigEndian, uint32(dhGroupExchangePreferredBits)) - binary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMaximumBits)) + binary.Write(h, binary.BigEndian, kexDHGexRequest.MinBits) + binary.Write(h, binary.BigEndian, kexDHGexRequest.PreferredBits) + binary.Write(h, binary.BigEndian, kexDHGexRequest.MaxBits) writeInt(h, p) writeInt(h, g) writeInt(h, kexDHGexInit.X) diff --git a/vendor/golang.org/x/crypto/ssh/keys.go b/vendor/golang.org/x/crypto/ssh/keys.go index 98e6706..566e09d 100644 --- a/vendor/golang.org/x/crypto/ssh/keys.go +++ b/vendor/golang.org/x/crypto/ssh/keys.go @@ -36,14 +36,19 @@ import ( // ClientConfig.HostKeyAlgorithms, Signature.Format, or as AlgorithmSigner // arguments. const ( - KeyAlgoRSA = "ssh-rsa" - KeyAlgoDSA = "ssh-dss" - KeyAlgoECDSA256 = "ecdsa-sha2-nistp256" - KeyAlgoSKECDSA256 = "sk-ecdsa-sha2-nistp256@openssh.com" - KeyAlgoECDSA384 = "ecdsa-sha2-nistp384" - KeyAlgoECDSA521 = "ecdsa-sha2-nistp521" - KeyAlgoED25519 = "ssh-ed25519" - KeyAlgoSKED25519 = "sk-ssh-ed25519@openssh.com" + KeyAlgoRSA = "ssh-rsa" + // Deprecated: DSA is only supported at insecure key sizes, and was removed + // from major implementations. + KeyAlgoDSA = InsecureKeyAlgoDSA + // Deprecated: DSA is only supported at insecure key sizes, and was removed + // from major implementations. + InsecureKeyAlgoDSA = "ssh-dss" + KeyAlgoECDSA256 = "ecdsa-sha2-nistp256" + KeyAlgoSKECDSA256 = "sk-ecdsa-sha2-nistp256@openssh.com" + KeyAlgoECDSA384 = "ecdsa-sha2-nistp384" + KeyAlgoECDSA521 = "ecdsa-sha2-nistp521" + KeyAlgoED25519 = "ssh-ed25519" + KeyAlgoSKED25519 = "sk-ssh-ed25519@openssh.com" // KeyAlgoRSASHA256 and KeyAlgoRSASHA512 are only public key algorithms, not // public key formats, so they can't appear as a PublicKey.Type. The @@ -67,7 +72,7 @@ func parsePubKey(in []byte, algo string) (pubKey PublicKey, rest []byte, err err switch algo { case KeyAlgoRSA: return parseRSA(in) - case KeyAlgoDSA: + case InsecureKeyAlgoDSA: return parseDSA(in) case KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521: return parseECDSA(in) @@ -77,7 +82,7 @@ func parsePubKey(in []byte, algo string) (pubKey PublicKey, rest []byte, err err return parseED25519(in) case KeyAlgoSKED25519: return parseSKEd25519(in) - case CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoSKECDSA256v01, CertAlgoED25519v01, CertAlgoSKED25519v01: + case CertAlgoRSAv01, InsecureCertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoSKECDSA256v01, CertAlgoED25519v01, CertAlgoSKED25519v01: cert, err := parseCert(in, certKeyAlgoNames[algo]) if err != nil { return nil, nil, err diff --git a/vendor/golang.org/x/crypto/ssh/mac.go b/vendor/golang.org/x/crypto/ssh/mac.go index 06a1b27..de2639d 100644 --- a/vendor/golang.org/x/crypto/ssh/mac.go +++ b/vendor/golang.org/x/crypto/ssh/mac.go @@ -47,22 +47,22 @@ func (t truncatingMAC) Size() int { func (t truncatingMAC) BlockSize() int { return t.hmac.BlockSize() } var macModes = map[string]*macMode{ - "hmac-sha2-512-etm@openssh.com": {64, true, func(key []byte) hash.Hash { + HMACSHA512ETM: {64, true, func(key []byte) hash.Hash { return hmac.New(sha512.New, key) }}, - "hmac-sha2-256-etm@openssh.com": {32, true, func(key []byte) hash.Hash { + HMACSHA256ETM: {32, true, func(key []byte) hash.Hash { return hmac.New(sha256.New, key) }}, - "hmac-sha2-512": {64, false, func(key []byte) hash.Hash { + HMACSHA512: {64, false, func(key []byte) hash.Hash { return hmac.New(sha512.New, key) }}, - "hmac-sha2-256": {32, false, func(key []byte) hash.Hash { + HMACSHA256: {32, false, func(key []byte) hash.Hash { return hmac.New(sha256.New, key) }}, - "hmac-sha1": {20, false, func(key []byte) hash.Hash { + HMACSHA1: {20, false, func(key []byte) hash.Hash { return hmac.New(sha1.New, key) }}, - "hmac-sha1-96": {20, false, func(key []byte) hash.Hash { + InsecureHMACSHA196: {20, false, func(key []byte) hash.Hash { return truncatingMAC{12, hmac.New(sha1.New, key)} }}, } diff --git a/vendor/golang.org/x/crypto/ssh/messages.go b/vendor/golang.org/x/crypto/ssh/messages.go index 118427b..251b9d0 100644 --- a/vendor/golang.org/x/crypto/ssh/messages.go +++ b/vendor/golang.org/x/crypto/ssh/messages.go @@ -122,9 +122,9 @@ type kexDHGexReplyMsg struct { const msgKexDHGexRequest = 34 type kexDHGexRequestMsg struct { - MinBits uint32 `sshtype:"34"` - PreferedBits uint32 - MaxBits uint32 + MinBits uint32 `sshtype:"34"` + PreferredBits uint32 + MaxBits uint32 } // See RFC 4253, section 10. diff --git a/vendor/golang.org/x/crypto/ssh/mlkem.go b/vendor/golang.org/x/crypto/ssh/mlkem.go index 40681dd..657e107 100644 --- a/vendor/golang.org/x/crypto/ssh/mlkem.go +++ b/vendor/golang.org/x/crypto/ssh/mlkem.go @@ -19,19 +19,15 @@ import ( "golang.org/x/crypto/curve25519" ) -const ( - kexAlgoMLKEM768xCurve25519SHA256 = "mlkem768x25519-sha256" -) - func init() { // After Go 1.24rc1 mlkem swapped the order of return values of Encapsulate. // See #70950. if runtime.Version() == "go1.24rc1" { return } - supportedKexAlgos = slices.Insert(supportedKexAlgos, 0, kexAlgoMLKEM768xCurve25519SHA256) - preferredKexAlgos = slices.Insert(preferredKexAlgos, 0, kexAlgoMLKEM768xCurve25519SHA256) - kexAlgoMap[kexAlgoMLKEM768xCurve25519SHA256] = &mlkem768WithCurve25519sha256{} + supportedKexAlgos = slices.Insert(supportedKexAlgos, 0, KeyExchangeMLKEM768X25519) + defaultKexAlgos = slices.Insert(defaultKexAlgos, 0, KeyExchangeMLKEM768X25519) + kexAlgoMap[KeyExchangeMLKEM768X25519] = &mlkem768WithCurve25519sha256{} } // mlkem768WithCurve25519sha256 implements the hybrid ML-KEM768 with diff --git a/vendor/golang.org/x/crypto/ssh/server.go b/vendor/golang.org/x/crypto/ssh/server.go index 1839ddc..98679ba 100644 --- a/vendor/golang.org/x/crypto/ssh/server.go +++ b/vendor/golang.org/x/crypto/ssh/server.go @@ -243,22 +243,15 @@ func NewServerConn(c net.Conn, config *ServerConfig) (*ServerConn, <-chan NewCha fullConf.MaxAuthTries = 6 } if len(fullConf.PublicKeyAuthAlgorithms) == 0 { - fullConf.PublicKeyAuthAlgorithms = supportedPubKeyAuthAlgos + fullConf.PublicKeyAuthAlgorithms = defaultPubKeyAuthAlgos } else { for _, algo := range fullConf.PublicKeyAuthAlgorithms { - if !contains(supportedPubKeyAuthAlgos, algo) { + if !contains(SupportedAlgorithms().PublicKeyAuths, algo) && !contains(InsecureAlgorithms().PublicKeyAuths, algo) { c.Close() return nil, nil, nil, fmt.Errorf("ssh: unsupported public key authentication algorithm %s", algo) } } } - // Check if the config contains any unsupported key exchanges - for _, kex := range fullConf.KeyExchanges { - if _, ok := serverForbiddenKexAlgos[kex]; ok { - c.Close() - return nil, nil, nil, fmt.Errorf("ssh: unsupported key exchange %s for server", kex) - } - } s := &connection{ sshConn: sshConn{conn: c}, @@ -315,6 +308,7 @@ func (s *connection) serverHandshake(config *ServerConfig) (*Permissions, error) // We just did the key change, so the session ID is established. s.sessionID = s.transport.getSessionID() + s.algorithms = s.transport.getAlgorithms() var packet []byte if packet, err = s.transport.readPacket(); err != nil { diff --git a/vendor/golang.org/x/crypto/ssh/transport.go b/vendor/golang.org/x/crypto/ssh/transport.go index 0424d2d..6636198 100644 --- a/vendor/golang.org/x/crypto/ssh/transport.go +++ b/vendor/golang.org/x/crypto/ssh/transport.go @@ -16,13 +16,6 @@ import ( // wire. No message decoding is done, to minimize the impact on timing. const debugTransport = false -const ( - gcm128CipherID = "aes128-gcm@openssh.com" - gcm256CipherID = "aes256-gcm@openssh.com" - aes128cbcID = "aes128-cbc" - tripledescbcID = "3des-cbc" -) - // packetConn represents a transport that implements packet based // operations. type packetConn interface { @@ -92,14 +85,14 @@ func (t *transport) setInitialKEXDone() { // prepareKeyChange sets up key material for a keychange. The key changes in // both directions are triggered by reading and writing a msgNewKey packet // respectively. -func (t *transport) prepareKeyChange(algs *algorithms, kexResult *kexResult) error { - ciph, err := newPacketCipher(t.reader.dir, algs.r, kexResult) +func (t *transport) prepareKeyChange(algs *NegotiatedAlgorithms, kexResult *kexResult) error { + ciph, err := newPacketCipher(t.reader.dir, algs.Read, kexResult) if err != nil { return err } t.reader.pendingKeyChange <- ciph - ciph, err = newPacketCipher(t.writer.dir, algs.w, kexResult) + ciph, err = newPacketCipher(t.writer.dir, algs.Write, kexResult) if err != nil { return err } @@ -259,7 +252,7 @@ var ( // setupKeys sets the cipher and MAC keys from kex.K, kex.H and sessionId, as // described in RFC 4253, section 6.4. direction should either be serverKeys // (to setup server->client keys) or clientKeys (for client->server keys). -func newPacketCipher(d direction, algs directionAlgorithms, kex *kexResult) (packetCipher, error) { +func newPacketCipher(d direction, algs DirectionAlgorithms, kex *kexResult) (packetCipher, error) { cipherMode := cipherModes[algs.Cipher] iv := make([]byte, cipherMode.ivSize) diff --git a/vendor/modules.txt b/vendor/modules.txt index 5db3591..cea56b5 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -8,7 +8,7 @@ github.com/bahlo/generic-list-go # github.com/buger/jsonparser v1.1.1 ## explicit; go 1.13 github.com/buger/jsonparser -# github.com/canonical/lxd v0.0.0-20250521083810-5973602f3c07 +# github.com/canonical/lxd v0.0.0-20250619222212-79e5fb724a99 ## explicit; go 1.24.2 github.com/canonical/lxd/client github.com/canonical/lxd/shared @@ -24,7 +24,7 @@ github.com/canonical/lxd/shared/termios github.com/canonical/lxd/shared/units github.com/canonical/lxd/shared/version github.com/canonical/lxd/shared/ws -# github.com/cloudbase/garm-provider-common v0.1.5-0.20250417155201-8ef03502d06e +# github.com/cloudbase/garm-provider-common v0.1.5 ## explicit; go 1.23.0 github.com/cloudbase/garm-provider-common/cloudconfig github.com/cloudbase/garm-provider-common/defaults @@ -49,7 +49,7 @@ github.com/flosch/pongo2 github.com/go-jose/go-jose/v4 github.com/go-jose/go-jose/v4/cipher github.com/go-jose/go-jose/v4/json -# github.com/go-logr/logr v1.4.2 +# github.com/go-logr/logr v1.4.3 ## explicit; go 1.18 github.com/go-logr/logr github.com/go-logr/logr/funcr @@ -106,7 +106,7 @@ github.com/pkg/errors github.com/pkg/sftp github.com/pkg/sftp/internal/encoding/ssh/filexfer github.com/pkg/sftp/internal/encoding/ssh/filexfer/openssh -# github.com/pkg/xattr v0.4.10 +# github.com/pkg/xattr v0.4.11 ## explicit; go 1.14 github.com/pkg/xattr # github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 @@ -144,7 +144,7 @@ github.com/xeipuuv/gojsonschema # github.com/zitadel/logging v0.6.2 ## explicit; go 1.23.7 github.com/zitadel/logging -# github.com/zitadel/oidc/v3 v3.38.1 +# github.com/zitadel/oidc/v3 v3.39.0 ## explicit; go 1.23.7 github.com/zitadel/oidc/v3/pkg/client github.com/zitadel/oidc/v3/pkg/client/rp @@ -180,7 +180,7 @@ go.opentelemetry.io/otel/trace go.opentelemetry.io/otel/trace/embedded go.opentelemetry.io/otel/trace/internal/telemetry go.opentelemetry.io/otel/trace/noop -# golang.org/x/crypto v0.38.0 +# golang.org/x/crypto v0.39.0 ## explicit; go 1.23.0 golang.org/x/crypto/bcrypt golang.org/x/crypto/blowfish @@ -192,7 +192,7 @@ golang.org/x/crypto/internal/alias golang.org/x/crypto/internal/poly1305 golang.org/x/crypto/ssh golang.org/x/crypto/ssh/internal/bcrypt_pbkdf -# golang.org/x/net v0.40.0 +# golang.org/x/net v0.41.0 ## explicit; go 1.23.0 golang.org/x/net/internal/socks golang.org/x/net/proxy @@ -210,7 +210,7 @@ golang.org/x/sys/windows # golang.org/x/term v0.32.0 ## explicit; go 1.23.0 golang.org/x/term -# golang.org/x/text v0.25.0 +# golang.org/x/text v0.26.0 ## explicit; go 1.23.0 golang.org/x/text/cases golang.org/x/text/internal