mirror of https://github.com/containers/podman.git
vendor latest c/common
Includes the default db backend changes. Signed-off-by: Paul Holzinger <pholzing@redhat.com>
This commit is contained in:
parent
040a4e4b1e
commit
8a52e638e6
7
go.mod
7
go.mod
|
|
@ -13,7 +13,7 @@ require (
|
|||
github.com/containernetworking/cni v1.1.2
|
||||
github.com/containernetworking/plugins v1.3.0
|
||||
github.com/containers/buildah v1.32.0
|
||||
github.com/containers/common v0.56.1-0.20231005124809-b4ef9cdeab5b
|
||||
github.com/containers/common v0.56.1-0.20231010150003-09776aa73db7
|
||||
github.com/containers/conmon v2.0.20+incompatible
|
||||
github.com/containers/gvisor-tap-vsock v0.7.1
|
||||
github.com/containers/image/v5 v5.28.0
|
||||
|
|
@ -88,7 +88,8 @@ require (
|
|||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||
github.com/chzyer/readline v1.5.1 // indirect
|
||||
github.com/containerd/cgroups/v3 v3.0.2 // indirect
|
||||
github.com/containerd/containerd v1.7.6 // indirect
|
||||
github.com/containerd/containerd v1.7.7 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect
|
||||
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect
|
||||
github.com/containers/luksy v0.0.0-20230808154129-d2d74a56682f // indirect
|
||||
|
|
@ -189,7 +190,7 @@ require (
|
|||
go.opentelemetry.io/otel/metric v1.16.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.16.0 // indirect
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/crypto v0.13.0 // indirect
|
||||
golang.org/x/crypto v0.14.0 // indirect
|
||||
golang.org/x/mod v0.12.0 // indirect
|
||||
golang.org/x/oauth2 v0.12.0 // indirect
|
||||
golang.org/x/tools v0.13.0 // indirect
|
||||
|
|
|
|||
14
go.sum
14
go.sum
|
|
@ -190,8 +190,8 @@ github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09Zvgq
|
|||
github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s=
|
||||
github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g=
|
||||
github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c=
|
||||
github.com/containerd/containerd v1.7.6 h1:oNAVsnhPoy4BTPQivLgTzI9Oleml9l/+eYIDYXRCYo8=
|
||||
github.com/containerd/containerd v1.7.6/go.mod h1:SY6lrkkuJT40BVNO37tlYTSnKJnP5AXBc0fhx0q+TJ4=
|
||||
github.com/containerd/containerd v1.7.7 h1:QOC2K4A42RQpcrZyptP6z9EJZnlHfHJUfZrAAHe15q4=
|
||||
github.com/containerd/containerd v1.7.7/go.mod h1:3c4XZv6VeT9qgf9GMTxNTMFxGJrGpI2vz1yk4ye+YY8=
|
||||
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
|
|
@ -216,6 +216,8 @@ github.com/containerd/imgcrypt v1.0.1/go.mod h1:mdd8cEPW7TPgNG4FpuP3sGBiQ7Yi/zak
|
|||
github.com/containerd/imgcrypt v1.0.4-0.20210301171431-0ae5c75f59ba/go.mod h1:6TNsg0ctmizkrOgXRNQjAPFWpMYRWuiB6dSF4Pfa5SA=
|
||||
github.com/containerd/imgcrypt v1.1.1-0.20210312161619-7ed62a527887/go.mod h1:5AZJNI6sLHJljKuI9IHnw1pWqo/F0nGDOuR9zgTs7ow=
|
||||
github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJrXQb0Dpc4ms=
|
||||
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
|
||||
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
|
||||
github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFYfE5+So4M5syatU0N0f0LbWpuqyMi4/BE8c=
|
||||
github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
|
||||
github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
|
||||
|
|
@ -249,8 +251,8 @@ github.com/containernetworking/plugins v1.3.0 h1:QVNXMT6XloyMUoO2wUOqWTC1hWFV62Q
|
|||
github.com/containernetworking/plugins v1.3.0/go.mod h1:Pc2wcedTQQCVuROOOaLBPPxrEXqqXBFt3cZ+/yVg6l0=
|
||||
github.com/containers/buildah v1.32.0 h1:uz5Rcf7lGeStj7iPTBgO4UdhQYZqMMzyt9suDf16k1k=
|
||||
github.com/containers/buildah v1.32.0/go.mod h1:sN3rA3DbnqekNz3bNdkqWduuirYDuMs54LUCOZOomBE=
|
||||
github.com/containers/common v0.56.1-0.20231005124809-b4ef9cdeab5b h1:LIHpr2o8WakQ48q2GAQZlMAG+zsVJPOQSLraxP7j9fI=
|
||||
github.com/containers/common v0.56.1-0.20231005124809-b4ef9cdeab5b/go.mod h1:8gifkvVxN1oOHJ9Yp/SHWcN6MlxdC0gZCF2+MaWjErc=
|
||||
github.com/containers/common v0.56.1-0.20231010150003-09776aa73db7 h1:Gx9i5pM2uXoIL3+QDuS3ddko+vGBCoRfisHchQV4K0g=
|
||||
github.com/containers/common v0.56.1-0.20231010150003-09776aa73db7/go.mod h1:UoUXLn51o0628B8h4MOdWGKYfS/y0e9mjizyfERMoes=
|
||||
github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg=
|
||||
github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
|
||||
github.com/containers/gvisor-tap-vsock v0.7.1 h1:+Rc+sOPplrkQb/BUXeN0ug8TxjgyrIqo/9P/eNS2A4c=
|
||||
|
|
@ -1122,8 +1124,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
|
|||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
|
||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
|
|
|
|||
|
|
@ -367,7 +367,7 @@ func makeRuntime(runtime *Runtime) (retErr error) {
|
|||
}
|
||||
runtime.state = state
|
||||
default:
|
||||
return fmt.Errorf("unrecognized state type passed (%v): %w", runtime.config.Engine.StateType, define.ErrInvalidArg)
|
||||
return fmt.Errorf("unrecognized state type passed (%v): %w", backend, define.ErrInvalidArg)
|
||||
}
|
||||
|
||||
// Grab config from the database so we can reset some defaults
|
||||
|
|
|
|||
149
vendor/github.com/containerd/containerd/log/context_deprecated.go
generated
vendored
Normal file
149
vendor/github.com/containerd/containerd/log/context_deprecated.go
generated
vendored
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package log
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/containerd/log"
|
||||
)
|
||||
|
||||
// G is a shorthand for [GetLogger].
|
||||
//
|
||||
// Deprecated: use [log.G].
|
||||
var G = log.G
|
||||
|
||||
// L is an alias for the standard logger.
|
||||
//
|
||||
// Deprecated: use [log.L].
|
||||
var L = log.L
|
||||
|
||||
// Fields type to pass to "WithFields".
|
||||
//
|
||||
// Deprecated: use [log.Fields].
|
||||
type Fields = log.Fields
|
||||
|
||||
// Entry is a logging entry.
|
||||
//
|
||||
// Deprecated: use [log.Entry].
|
||||
type Entry = log.Entry
|
||||
|
||||
// RFC3339NanoFixed is [time.RFC3339Nano] with nanoseconds padded using
|
||||
// zeros to ensure the formatted time is always the same number of
|
||||
// characters.
|
||||
//
|
||||
// Deprecated: use [log.RFC3339NanoFixed].
|
||||
const RFC3339NanoFixed = log.RFC3339NanoFixed
|
||||
|
||||
// Level is a logging level.
|
||||
//
|
||||
// Deprecated: use [log.Level].
|
||||
type Level = log.Level
|
||||
|
||||
// Supported log levels.
|
||||
const (
|
||||
// TraceLevel level.
|
||||
//
|
||||
// Deprecated: use [log.TraceLevel].
|
||||
TraceLevel Level = log.TraceLevel
|
||||
|
||||
// DebugLevel level.
|
||||
//
|
||||
// Deprecated: use [log.DebugLevel].
|
||||
DebugLevel Level = log.DebugLevel
|
||||
|
||||
// InfoLevel level.
|
||||
//
|
||||
// Deprecated: use [log.InfoLevel].
|
||||
InfoLevel Level = log.InfoLevel
|
||||
|
||||
// WarnLevel level.
|
||||
//
|
||||
// Deprecated: use [log.WarnLevel].
|
||||
WarnLevel Level = log.WarnLevel
|
||||
|
||||
// ErrorLevel level
|
||||
//
|
||||
// Deprecated: use [log.ErrorLevel].
|
||||
ErrorLevel Level = log.ErrorLevel
|
||||
|
||||
// FatalLevel level.
|
||||
//
|
||||
// Deprecated: use [log.FatalLevel].
|
||||
FatalLevel Level = log.FatalLevel
|
||||
|
||||
// PanicLevel level.
|
||||
//
|
||||
// Deprecated: use [log.PanicLevel].
|
||||
PanicLevel Level = log.PanicLevel
|
||||
)
|
||||
|
||||
// SetLevel sets log level globally. It returns an error if the given
|
||||
// level is not supported.
|
||||
//
|
||||
// Deprecated: use [log.SetLevel].
|
||||
func SetLevel(level string) error {
|
||||
return log.SetLevel(level)
|
||||
}
|
||||
|
||||
// GetLevel returns the current log level.
|
||||
//
|
||||
// Deprecated: use [log.GetLevel].
|
||||
func GetLevel() log.Level {
|
||||
return log.GetLevel()
|
||||
}
|
||||
|
||||
// OutputFormat specifies a log output format.
|
||||
//
|
||||
// Deprecated: use [log.OutputFormat].
|
||||
type OutputFormat = log.OutputFormat
|
||||
|
||||
// Supported log output formats.
|
||||
const (
|
||||
// TextFormat represents the text logging format.
|
||||
//
|
||||
// Deprecated: use [log.TextFormat].
|
||||
TextFormat log.OutputFormat = "text"
|
||||
|
||||
// JSONFormat represents the JSON logging format.
|
||||
//
|
||||
// Deprecated: use [log.JSONFormat].
|
||||
JSONFormat log.OutputFormat = "json"
|
||||
)
|
||||
|
||||
// SetFormat sets the log output format.
|
||||
//
|
||||
// Deprecated: use [log.SetFormat].
|
||||
func SetFormat(format OutputFormat) error {
|
||||
return log.SetFormat(format)
|
||||
}
|
||||
|
||||
// WithLogger returns a new context with the provided logger. Use in
|
||||
// combination with logger.WithField(s) for great effect.
|
||||
//
|
||||
// Deprecated: use [log.WithLogger].
|
||||
func WithLogger(ctx context.Context, logger *log.Entry) context.Context {
|
||||
return log.WithLogger(ctx, logger)
|
||||
}
|
||||
|
||||
// GetLogger retrieves the current logger from the context. If no logger is
|
||||
// available, the default logger is returned.
|
||||
//
|
||||
// Deprecated: use [log.GetLogger].
|
||||
func GetLogger(ctx context.Context) *log.Entry {
|
||||
return log.GetLogger(ctx)
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
linters:
|
||||
enable:
|
||||
- exportloopref # Checks for pointers to enclosing loop variables
|
||||
- gofmt
|
||||
- goimports
|
||||
- gosec
|
||||
- ineffassign
|
||||
- misspell
|
||||
- nolintlint
|
||||
- revive
|
||||
- staticcheck
|
||||
- tenv # Detects using os.Setenv instead of t.Setenv since Go 1.17
|
||||
- unconvert
|
||||
- unused
|
||||
- vet
|
||||
- dupword # Checks for duplicate words in the source code
|
||||
disable:
|
||||
- errcheck
|
||||
|
||||
run:
|
||||
timeout: 5m
|
||||
skip-dirs:
|
||||
- api
|
||||
- cluster
|
||||
- design
|
||||
- docs
|
||||
- docs/man
|
||||
- releases
|
||||
- reports
|
||||
- test # e2e scripts
|
||||
|
|
@ -0,0 +1,191 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
https://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright The containerd Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# log
|
||||
|
||||
A Go package providing a common logging interface across containerd repositories and a way for clients to use and configure logging in containerd packages.
|
||||
|
||||
This package is not intended to be used as a standalone logging package outside of the containerd ecosystem and is intended as an interface wrapper around a logging implementation.
|
||||
In the future this package may be replaced with a common go logging interface.
|
||||
|
||||
## Project details
|
||||
|
||||
**log** is a containerd sub-project, licensed under the [Apache 2.0 license](./LICENSE).
|
||||
As a containerd sub-project, you will find the:
|
||||
* [Project governance](https://github.com/containerd/project/blob/main/GOVERNANCE.md),
|
||||
* [Maintainers](https://github.com/containerd/project/blob/main/MAINTAINERS),
|
||||
* and [Contributing guidelines](https://github.com/containerd/project/blob/main/CONTRIBUTING.md)
|
||||
|
||||
information in our [`containerd/project`](https://github.com/containerd/project) repository.
|
||||
|
||||
|
|
@ -212,6 +212,11 @@ func parseAAParserVersion(output string) (int, error) {
|
|||
words := strings.Split(lines[0], " ")
|
||||
version := words[len(words)-1]
|
||||
|
||||
// trim "-beta1" suffix from version="3.0.0-beta1" if exists
|
||||
version = strings.SplitN(version, "-", 2)[0]
|
||||
// also trim "~..." suffix used historically (https://gitlab.com/apparmor/apparmor/-/commit/bca67d3d27d219d11ce8c9cc70612bd637f88c10)
|
||||
version = strings.SplitN(version, "~", 2)[0]
|
||||
|
||||
// split by major minor version
|
||||
v := strings.Split(version, ".")
|
||||
if len(v) == 0 || len(v) > 3 {
|
||||
|
|
|
|||
|
|
@ -30,24 +30,6 @@ const (
|
|||
bindirPrefix = "$BINDIR"
|
||||
)
|
||||
|
||||
// RuntimeStateStore is a constant indicating which state store implementation
|
||||
// should be used by engine
|
||||
type RuntimeStateStore int
|
||||
|
||||
const (
|
||||
// InvalidStateStore is an invalid state store
|
||||
InvalidStateStore RuntimeStateStore = iota
|
||||
// InMemoryStateStore is an in-memory state that will not persist data
|
||||
// on containers and pods between engine instances or after system
|
||||
// reboot
|
||||
InMemoryStateStore RuntimeStateStore = iota
|
||||
// SQLiteStateStore is a state backed by a SQLite database
|
||||
// It is presently disabled
|
||||
SQLiteStateStore RuntimeStateStore = iota
|
||||
// BoltDBStateStore is a state backed by a BoltDB database
|
||||
BoltDBStateStore RuntimeStateStore = iota
|
||||
)
|
||||
|
||||
var validImageVolumeModes = []string{_typeBind, "tmpfs", "ignore"}
|
||||
|
||||
// ProxyEnv is a list of Proxy Environment variables
|
||||
|
|
@ -483,13 +465,6 @@ type EngineConfig struct {
|
|||
// readiness using the SD_NOTIFY mechanism.
|
||||
SDNotify bool `toml:"-"`
|
||||
|
||||
// StateType is the type of the backing state store. Avoid using multiple
|
||||
// values for this with the same containers/storage configuration on the
|
||||
// same system. Different state types do not interact, and each will see a
|
||||
// separate set of containers, which may cause conflicts in
|
||||
// containers/storage. As such this is not exposed via the config file.
|
||||
StateType RuntimeStateStore `toml:"-"`
|
||||
|
||||
// ServiceTimeout is the number of seconds to wait without a connection
|
||||
// before the `podman system service` times out and exits
|
||||
ServiceTimeout uint `toml:"service_timeout,omitempty,omitzero"`
|
||||
|
|
|
|||
|
|
@ -454,10 +454,14 @@ default_sysctls = [
|
|||
# short-name aliases defined in containers-registries.conf(5).
|
||||
#compat_api_enforce_docker_hub = true
|
||||
|
||||
# The database backend of Podman. Supported values are "boltdb" (default) and
|
||||
# "sqlite". Please run `podman-system-reset` prior to changing the database
|
||||
# The database backend of Podman. Supported values are "" (default), "boltdb"
|
||||
# and "sqlite". An empty value means it will check whenever a boltdb already
|
||||
# exists and use it when it does, otherwise it will use sqlite as default
|
||||
# (e.g. new installs). This allows for backwards compatibility with older versions.
|
||||
# Please run `podman-system-reset` prior to changing the database
|
||||
# backend of an existing deployment, to make sure Podman can operate correctly.
|
||||
#database_backend="boltdb"
|
||||
#
|
||||
#database_backend = ""
|
||||
|
||||
# Specify the keys sequence used to detach a container.
|
||||
# Format is a single character [a-Z] or a comma separated sequence of
|
||||
|
|
|
|||
|
|
@ -29,10 +29,14 @@
|
|||
#
|
||||
#base_hosts_file = ""
|
||||
|
||||
# The database backend of Podman. Supported values are "boltdb" (default) and
|
||||
# "sqlite". Please run `podman-system-reset` prior to changing the database
|
||||
# The database backend of Podman. Supported values are "" (default), "boltdb"
|
||||
# and "sqlite". An empty value means it will check whenever a boltdb already
|
||||
# exists and use it when it does, otherwise it will use sqlite as default
|
||||
# (e.g. new installs). This allows for backwards compatibility with older versions.
|
||||
# Please run `podman-system-reset` prior to changing the database
|
||||
# backend of an existing deployment, to make sure Podman can operate correctly.
|
||||
#database_backend="boltdb"
|
||||
#
|
||||
#database_backend = ""
|
||||
|
||||
# List of default capabilities for containers. If it is empty or commented out,
|
||||
# the default capabilities defined in the container engine will be added.
|
||||
|
|
|
|||
|
|
@ -13,6 +13,12 @@ const (
|
|||
// SQLite backend.
|
||||
DBBackendSQLite
|
||||
|
||||
// DBBackendDefault describes that no explicit backend has been set.
|
||||
// It should default to sqlite unless there is already an existing boltdb,
|
||||
// this allows for backwards compatibility on upgrades. The actual detection
|
||||
// logic must live in podman as we only know there were to look for the file.
|
||||
DBBackendDefault
|
||||
|
||||
stringBoltDB = "boltdb"
|
||||
stringSQLite = "sqlite"
|
||||
)
|
||||
|
|
@ -24,6 +30,8 @@ func (d DBBackend) String() string {
|
|||
return stringBoltDB
|
||||
case DBBackendSQLite:
|
||||
return stringSQLite
|
||||
case DBBackendDefault:
|
||||
return ""
|
||||
default:
|
||||
return fmt.Sprintf("unsupported database backend: %d", d)
|
||||
}
|
||||
|
|
@ -32,7 +40,7 @@ func (d DBBackend) String() string {
|
|||
// Validate returns whether the DBBackend is supported.
|
||||
func (d DBBackend) Validate() error {
|
||||
switch d {
|
||||
case DBBackendBoltDB, DBBackendSQLite:
|
||||
case DBBackendBoltDB, DBBackendSQLite, DBBackendDefault:
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("unsupported database backend: %d", d)
|
||||
|
|
@ -49,12 +57,9 @@ func ParseDBBackend(raw string) (DBBackend, error) {
|
|||
return DBBackendBoltDB, nil
|
||||
case stringSQLite:
|
||||
return DBBackendSQLite, nil
|
||||
case "":
|
||||
return DBBackendDefault, nil
|
||||
default:
|
||||
return DBBackendUnsupported, fmt.Errorf("unsupported database backend: %q", raw)
|
||||
}
|
||||
}
|
||||
|
||||
// DBBackend returns the configured database backend.
|
||||
func (c *Config) DBBackend() (DBBackend, error) {
|
||||
return ParseDBBackend(c.Engine.DBBackend)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,8 +120,6 @@ const (
|
|||
CgroupfsCgroupsManager = "cgroupfs"
|
||||
// DefaultApparmorProfile specifies the default apparmor profile for the container.
|
||||
DefaultApparmorProfile = apparmor.Profile
|
||||
// DefaultDBBackend specifies the default database backend to be used by Podman.
|
||||
DefaultDBBackend = DBBackendBoltDB
|
||||
// DefaultHostsFile is the default path to the hosts file.
|
||||
DefaultHostsFile = "/etc/hosts"
|
||||
// SystemdCgroupsManager represents systemd native cgroup manager.
|
||||
|
|
@ -317,7 +315,6 @@ func defaultEngineConfig() (*EngineConfig, error) {
|
|||
c.HooksDir = DefaultHooksDirs
|
||||
c.ImageDefaultTransport = _defaultTransport
|
||||
c.ImageVolumeMode = _defaultImageVolumeMode
|
||||
c.StateType = BoltDBStateStore
|
||||
|
||||
c.ImageBuildFormat = "oci"
|
||||
|
||||
|
|
@ -424,7 +421,6 @@ func defaultEngineConfig() (*EngineConfig, error) {
|
|||
"/run/current-system/sw/bin/conmonrs",
|
||||
}
|
||||
c.PullPolicy = DefaultPullPolicy
|
||||
c.DBBackend = stringBoltDB
|
||||
c.RuntimeSupportsJSON = []string{
|
||||
"crun",
|
||||
"runc",
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build go1.11 && gc && !purego
|
||||
// +build go1.11,gc,!purego
|
||||
//go:build gc && !purego
|
||||
// +build gc,!purego
|
||||
|
||||
package chacha20
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build go1.11 && gc && !purego
|
||||
// +build go1.11,gc,!purego
|
||||
//go:build gc && !purego
|
||||
// +build gc,!purego
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build (!arm64 && !s390x && !ppc64le) || (arm64 && !go1.11) || !gc || purego
|
||||
// +build !arm64,!s390x,!ppc64le arm64,!go1.11 !gc purego
|
||||
//go:build (!arm64 && !s390x && !ppc64le) || !gc || purego
|
||||
// +build !arm64,!s390x,!ppc64le !gc purego
|
||||
|
||||
package chacha20
|
||||
|
||||
|
|
|
|||
|
|
@ -121,11 +121,11 @@ func (d *state) padAndPermute(dsbyte byte) {
|
|||
copyOut(d, d.buf)
|
||||
}
|
||||
|
||||
// Write absorbs more data into the hash's state. It produces an error
|
||||
// if more data is written to the ShakeHash after writing
|
||||
// Write absorbs more data into the hash's state. It panics if any
|
||||
// output has already been read.
|
||||
func (d *state) Write(p []byte) (written int, err error) {
|
||||
if d.state != spongeAbsorbing {
|
||||
panic("sha3: write to sponge after read")
|
||||
panic("sha3: Write after Read")
|
||||
}
|
||||
if d.buf == nil {
|
||||
d.buf = d.storage.asBytes()[:0]
|
||||
|
|
@ -182,12 +182,16 @@ func (d *state) Read(out []byte) (n int, err error) {
|
|||
}
|
||||
|
||||
// Sum applies padding to the hash state and then squeezes out the desired
|
||||
// number of output bytes.
|
||||
// number of output bytes. It panics if any output has already been read.
|
||||
func (d *state) Sum(in []byte) []byte {
|
||||
if d.state != spongeAbsorbing {
|
||||
panic("sha3: Sum after Read")
|
||||
}
|
||||
|
||||
// Make a copy of the original hash so that caller can keep writing
|
||||
// and summing.
|
||||
dup := d.clone()
|
||||
hash := make([]byte, dup.outputLen)
|
||||
hash := make([]byte, dup.outputLen, 64) // explicit cap to allow stack allocation
|
||||
dup.Read(hash)
|
||||
return append(in, hash...)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ type asmState struct {
|
|||
buf []byte // care must be taken to ensure cap(buf) is a multiple of rate
|
||||
rate int // equivalent to block size
|
||||
storage [3072]byte // underlying storage for buf
|
||||
outputLen int // output length if fixed, 0 if not
|
||||
outputLen int // output length for full security
|
||||
function code // KIMD/KLMD function code
|
||||
state spongeDirection // whether the sponge is absorbing or squeezing
|
||||
}
|
||||
|
|
@ -72,8 +72,10 @@ func newAsmState(function code) *asmState {
|
|||
s.outputLen = 64
|
||||
case shake_128:
|
||||
s.rate = 168
|
||||
s.outputLen = 32
|
||||
case shake_256:
|
||||
s.rate = 136
|
||||
s.outputLen = 64
|
||||
default:
|
||||
panic("sha3: unrecognized function code")
|
||||
}
|
||||
|
|
@ -108,7 +110,7 @@ func (s *asmState) resetBuf() {
|
|||
// It never returns an error.
|
||||
func (s *asmState) Write(b []byte) (int, error) {
|
||||
if s.state != spongeAbsorbing {
|
||||
panic("sha3: write to sponge after read")
|
||||
panic("sha3: Write after Read")
|
||||
}
|
||||
length := len(b)
|
||||
for len(b) > 0 {
|
||||
|
|
@ -192,8 +194,8 @@ func (s *asmState) Read(out []byte) (n int, err error) {
|
|||
// Sum appends the current hash to b and returns the resulting slice.
|
||||
// It does not change the underlying hash state.
|
||||
func (s *asmState) Sum(b []byte) []byte {
|
||||
if s.outputLen == 0 {
|
||||
panic("sha3: cannot call Sum on SHAKE functions")
|
||||
if s.state != spongeAbsorbing {
|
||||
panic("sha3: Sum after Read")
|
||||
}
|
||||
|
||||
// Copy the state to preserve the original.
|
||||
|
|
|
|||
|
|
@ -17,26 +17,25 @@ package sha3
|
|||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"hash"
|
||||
"io"
|
||||
)
|
||||
|
||||
// ShakeHash defines the interface to hash functions that
|
||||
// support arbitrary-length output.
|
||||
// ShakeHash defines the interface to hash functions that support
|
||||
// arbitrary-length output. When used as a plain [hash.Hash], it
|
||||
// produces minimum-length outputs that provide full-strength generic
|
||||
// security.
|
||||
type ShakeHash interface {
|
||||
// Write absorbs more data into the hash's state. It panics if input is
|
||||
// written to it after output has been read from it.
|
||||
io.Writer
|
||||
hash.Hash
|
||||
|
||||
// Read reads more output from the hash; reading affects the hash's
|
||||
// state. (ShakeHash.Read is thus very different from Hash.Sum)
|
||||
// It never returns an error.
|
||||
// It never returns an error, but subsequent calls to Write or Sum
|
||||
// will panic.
|
||||
io.Reader
|
||||
|
||||
// Clone returns a copy of the ShakeHash in its current state.
|
||||
Clone() ShakeHash
|
||||
|
||||
// Reset resets the ShakeHash to its initial state.
|
||||
Reset()
|
||||
}
|
||||
|
||||
// cSHAKE specific context
|
||||
|
|
@ -81,8 +80,8 @@ func leftEncode(value uint64) []byte {
|
|||
return b[i-1:]
|
||||
}
|
||||
|
||||
func newCShake(N, S []byte, rate int, dsbyte byte) ShakeHash {
|
||||
c := cshakeState{state: &state{rate: rate, dsbyte: dsbyte}}
|
||||
func newCShake(N, S []byte, rate, outputLen int, dsbyte byte) ShakeHash {
|
||||
c := cshakeState{state: &state{rate: rate, outputLen: outputLen, dsbyte: dsbyte}}
|
||||
|
||||
// leftEncode returns max 9 bytes
|
||||
c.initBlock = make([]byte, 0, 9*2+len(N)+len(S))
|
||||
|
|
@ -119,7 +118,7 @@ func NewShake128() ShakeHash {
|
|||
if h := newShake128Asm(); h != nil {
|
||||
return h
|
||||
}
|
||||
return &state{rate: rate128, dsbyte: dsbyteShake}
|
||||
return &state{rate: rate128, outputLen: 32, dsbyte: dsbyteShake}
|
||||
}
|
||||
|
||||
// NewShake256 creates a new SHAKE256 variable-output-length ShakeHash.
|
||||
|
|
@ -129,7 +128,7 @@ func NewShake256() ShakeHash {
|
|||
if h := newShake256Asm(); h != nil {
|
||||
return h
|
||||
}
|
||||
return &state{rate: rate256, dsbyte: dsbyteShake}
|
||||
return &state{rate: rate256, outputLen: 64, dsbyte: dsbyteShake}
|
||||
}
|
||||
|
||||
// NewCShake128 creates a new instance of cSHAKE128 variable-output-length ShakeHash,
|
||||
|
|
@ -142,7 +141,7 @@ func NewCShake128(N, S []byte) ShakeHash {
|
|||
if len(N) == 0 && len(S) == 0 {
|
||||
return NewShake128()
|
||||
}
|
||||
return newCShake(N, S, rate128, dsbyteCShake)
|
||||
return newCShake(N, S, rate128, 32, dsbyteCShake)
|
||||
}
|
||||
|
||||
// NewCShake256 creates a new instance of cSHAKE256 variable-output-length ShakeHash,
|
||||
|
|
@ -155,7 +154,7 @@ func NewCShake256(N, S []byte) ShakeHash {
|
|||
if len(N) == 0 && len(S) == 0 {
|
||||
return NewShake256()
|
||||
}
|
||||
return newCShake(N, S, rate256, dsbyteCShake)
|
||||
return newCShake(N, S, rate256, 64, dsbyteCShake)
|
||||
}
|
||||
|
||||
// ShakeSum128 writes an arbitrary-length digest of data into hash.
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import (
|
|||
"bytes"
|
||||
"crypto/dsa"
|
||||
"crypto/ecdsa"
|
||||
"crypto/ed25519"
|
||||
"crypto/elliptic"
|
||||
"crypto/rsa"
|
||||
"encoding/base64"
|
||||
|
|
@ -26,7 +27,6 @@ import (
|
|||
"math/big"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/crypto/ed25519"
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ package agent
|
|||
import (
|
||||
"crypto/dsa"
|
||||
"crypto/ecdsa"
|
||||
"crypto/ed25519"
|
||||
"crypto/elliptic"
|
||||
"crypto/rsa"
|
||||
"encoding/binary"
|
||||
|
|
@ -16,7 +17,6 @@ import (
|
|||
"log"
|
||||
"math/big"
|
||||
|
||||
"golang.org/x/crypto/ed25519"
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -16,8 +16,9 @@ import (
|
|||
|
||||
// Certificate algorithm names from [PROTOCOL.certkeys]. These values can appear
|
||||
// in Certificate.Type, PublicKey.Type, and ClientConfig.HostKeyAlgorithms.
|
||||
// Unlike key algorithm names, these are not passed to AlgorithmSigner and don't
|
||||
// appear in the Signature.Format field.
|
||||
// Unlike key algorithm names, these are not passed to AlgorithmSigner nor
|
||||
// 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"
|
||||
|
|
@ -255,10 +256,17 @@ func NewCertSigner(cert *Certificate, signer Signer) (Signer, error) {
|
|||
return nil, errors.New("ssh: signer and cert have different public key")
|
||||
}
|
||||
|
||||
if algorithmSigner, ok := signer.(AlgorithmSigner); ok {
|
||||
switch s := signer.(type) {
|
||||
case MultiAlgorithmSigner:
|
||||
return &multiAlgorithmSigner{
|
||||
AlgorithmSigner: &algorithmOpenSSHCertSigner{
|
||||
&openSSHCertSigner{cert, signer}, s},
|
||||
supportedAlgorithms: s.Algorithms(),
|
||||
}, nil
|
||||
case AlgorithmSigner:
|
||||
return &algorithmOpenSSHCertSigner{
|
||||
&openSSHCertSigner{cert, signer}, algorithmSigner}, nil
|
||||
} else {
|
||||
&openSSHCertSigner{cert, signer}, s}, nil
|
||||
default:
|
||||
return &openSSHCertSigner{cert, signer}, nil
|
||||
}
|
||||
}
|
||||
|
|
@ -432,7 +440,9 @@ func (c *CertChecker) CheckCert(principal string, cert *Certificate) error {
|
|||
}
|
||||
|
||||
// SignCert signs the certificate with an authority, setting the Nonce,
|
||||
// SignatureKey, and Signature fields.
|
||||
// SignatureKey, and Signature fields. If the authority implements the
|
||||
// MultiAlgorithmSigner interface the first algorithm in the list is used. This
|
||||
// is useful if you want to sign with a specific algorithm.
|
||||
func (c *Certificate) SignCert(rand io.Reader, authority Signer) error {
|
||||
c.Nonce = make([]byte, 32)
|
||||
if _, err := io.ReadFull(rand, c.Nonce); err != nil {
|
||||
|
|
@ -440,8 +450,20 @@ func (c *Certificate) SignCert(rand io.Reader, authority Signer) error {
|
|||
}
|
||||
c.SignatureKey = authority.PublicKey()
|
||||
|
||||
// Default to KeyAlgoRSASHA512 for ssh-rsa signers.
|
||||
if v, ok := authority.(AlgorithmSigner); ok && v.PublicKey().Type() == KeyAlgoRSA {
|
||||
if v, ok := authority.(MultiAlgorithmSigner); ok {
|
||||
if len(v.Algorithms()) == 0 {
|
||||
return errors.New("the provided authority has no signature algorithm")
|
||||
}
|
||||
// Use the first algorithm in the list.
|
||||
sig, err := v.SignWithAlgorithm(rand, c.bytesForSigning(), v.Algorithms()[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Signature = sig
|
||||
return nil
|
||||
} else if v, ok := authority.(AlgorithmSigner); ok && v.PublicKey().Type() == KeyAlgoRSA {
|
||||
// Default to KeyAlgoRSASHA512 for ssh-rsa signers.
|
||||
// TODO: consider using KeyAlgoRSASHA256 as default.
|
||||
sig, err := v.SignWithAlgorithm(rand, c.bytesForSigning(), KeyAlgoRSASHA512)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -71,7 +71,9 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error {
|
|||
for auth := AuthMethod(new(noneAuth)); auth != nil; {
|
||||
ok, methods, err := auth.auth(sessionID, config.User, c.transport, config.Rand, extensions)
|
||||
if err != nil {
|
||||
return err
|
||||
// We return the error later if there is no other method left to
|
||||
// try.
|
||||
ok = authFailure
|
||||
}
|
||||
if ok == authSuccess {
|
||||
// success
|
||||
|
|
@ -101,6 +103,12 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if auth == nil && err != nil {
|
||||
// We have an error and there are no other authentication methods to
|
||||
// try, so we return it.
|
||||
return err
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("ssh: unable to authenticate, attempted methods %v, no supported methods remain", tried)
|
||||
}
|
||||
|
|
@ -217,21 +225,45 @@ func (cb publicKeyCallback) method() string {
|
|||
return "publickey"
|
||||
}
|
||||
|
||||
func pickSignatureAlgorithm(signer Signer, extensions map[string][]byte) (as AlgorithmSigner, algo string) {
|
||||
func pickSignatureAlgorithm(signer Signer, extensions map[string][]byte) (MultiAlgorithmSigner, string, error) {
|
||||
var as MultiAlgorithmSigner
|
||||
keyFormat := signer.PublicKey().Type()
|
||||
|
||||
// Like in sendKexInit, if the public key implements AlgorithmSigner we
|
||||
// assume it supports all algorithms, otherwise only the key format one.
|
||||
as, ok := signer.(AlgorithmSigner)
|
||||
if !ok {
|
||||
return algorithmSignerWrapper{signer}, keyFormat
|
||||
// If the signer implements MultiAlgorithmSigner we use the algorithms it
|
||||
// support, if it implements AlgorithmSigner we assume it supports all
|
||||
// algorithms, otherwise only the key format one.
|
||||
switch s := signer.(type) {
|
||||
case MultiAlgorithmSigner:
|
||||
as = s
|
||||
case AlgorithmSigner:
|
||||
as = &multiAlgorithmSigner{
|
||||
AlgorithmSigner: s,
|
||||
supportedAlgorithms: algorithmsForKeyFormat(underlyingAlgo(keyFormat)),
|
||||
}
|
||||
default:
|
||||
as = &multiAlgorithmSigner{
|
||||
AlgorithmSigner: algorithmSignerWrapper{signer},
|
||||
supportedAlgorithms: []string{underlyingAlgo(keyFormat)},
|
||||
}
|
||||
}
|
||||
|
||||
getFallbackAlgo := func() (string, error) {
|
||||
// Fallback to use if there is no "server-sig-algs" extension or a
|
||||
// common algorithm cannot be found. We use the public key format if the
|
||||
// MultiAlgorithmSigner supports it, otherwise we return an error.
|
||||
if !contains(as.Algorithms(), underlyingAlgo(keyFormat)) {
|
||||
return "", fmt.Errorf("ssh: no common public key signature algorithm, server only supports %q for key type %q, signer only supports %v",
|
||||
underlyingAlgo(keyFormat), keyFormat, as.Algorithms())
|
||||
}
|
||||
return keyFormat, nil
|
||||
}
|
||||
|
||||
extPayload, ok := extensions["server-sig-algs"]
|
||||
if !ok {
|
||||
// If there is no "server-sig-algs" extension, fall back to the key
|
||||
// format algorithm.
|
||||
return as, keyFormat
|
||||
// If there is no "server-sig-algs" extension use the fallback
|
||||
// algorithm.
|
||||
algo, err := getFallbackAlgo()
|
||||
return as, algo, err
|
||||
}
|
||||
|
||||
// The server-sig-algs extension only carries underlying signature
|
||||
|
|
@ -245,15 +277,22 @@ func pickSignatureAlgorithm(signer Signer, extensions map[string][]byte) (as Alg
|
|||
}
|
||||
}
|
||||
|
||||
keyAlgos := algorithmsForKeyFormat(keyFormat)
|
||||
// Filter algorithms based on those supported by MultiAlgorithmSigner.
|
||||
var keyAlgos []string
|
||||
for _, algo := range algorithmsForKeyFormat(keyFormat) {
|
||||
if contains(as.Algorithms(), underlyingAlgo(algo)) {
|
||||
keyAlgos = append(keyAlgos, algo)
|
||||
}
|
||||
}
|
||||
|
||||
algo, err := findCommon("public key signature algorithm", keyAlgos, serverAlgos)
|
||||
if err != nil {
|
||||
// If there is no overlap, try the key anyway with the key format
|
||||
// algorithm, to support servers that fail to list all supported
|
||||
// algorithms.
|
||||
return as, keyFormat
|
||||
// If there is no overlap, return the fallback algorithm to support
|
||||
// servers that fail to list all supported algorithms.
|
||||
algo, err := getFallbackAlgo()
|
||||
return as, algo, err
|
||||
}
|
||||
return as, algo
|
||||
return as, algo, nil
|
||||
}
|
||||
|
||||
func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand io.Reader, extensions map[string][]byte) (authResult, []string, error) {
|
||||
|
|
@ -267,10 +306,17 @@ func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand
|
|||
return authFailure, nil, err
|
||||
}
|
||||
var methods []string
|
||||
var errSigAlgo error
|
||||
for _, signer := range signers {
|
||||
pub := signer.PublicKey()
|
||||
as, algo := pickSignatureAlgorithm(signer, extensions)
|
||||
|
||||
as, algo, err := pickSignatureAlgorithm(signer, extensions)
|
||||
if err != nil && errSigAlgo == nil {
|
||||
// If we cannot negotiate a signature algorithm store the first
|
||||
// error so we can return it to provide a more meaningful message if
|
||||
// no other signers work.
|
||||
errSigAlgo = err
|
||||
continue
|
||||
}
|
||||
ok, err := validateKey(pub, algo, user, c)
|
||||
if err != nil {
|
||||
return authFailure, nil, err
|
||||
|
|
@ -317,22 +363,12 @@ func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand
|
|||
// contain the "publickey" method, do not attempt to authenticate with any
|
||||
// other keys. According to RFC 4252 Section 7, the latter can occur when
|
||||
// additional authentication methods are required.
|
||||
if success == authSuccess || !containsMethod(methods, cb.method()) {
|
||||
if success == authSuccess || !contains(methods, cb.method()) {
|
||||
return success, methods, err
|
||||
}
|
||||
}
|
||||
|
||||
return authFailure, methods, nil
|
||||
}
|
||||
|
||||
func containsMethod(methods []string, method string) bool {
|
||||
for _, m := range methods {
|
||||
if m == method {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
return authFailure, methods, errSigAlgo
|
||||
}
|
||||
|
||||
// validateKey validates the key provided is acceptable to the server.
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ others.
|
|||
|
||||
References:
|
||||
|
||||
[PROTOCOL]: https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL?rev=HEAD
|
||||
[PROTOCOL.certkeys]: http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys?rev=HEAD
|
||||
[SSH-PARAMETERS]: http://www.iana.org/assignments/ssh-parameters/ssh-parameters.xml#ssh-parameters-1
|
||||
|
||||
|
|
|
|||
|
|
@ -461,19 +461,24 @@ func (t *handshakeTransport) sendKexInit() error {
|
|||
isServer := len(t.hostKeys) > 0
|
||||
if isServer {
|
||||
for _, k := range t.hostKeys {
|
||||
// If k is an AlgorithmSigner, presume it supports all signature algorithms
|
||||
// associated with the key format. (Ideally AlgorithmSigner would have a
|
||||
// method to advertise supported algorithms, but it doesn't. This means that
|
||||
// adding support for a new algorithm is a breaking change, as we will
|
||||
// immediately negotiate it even if existing implementations don't support
|
||||
// it. If that ever happens, we'll have to figure something out.)
|
||||
// If k is not an AlgorithmSigner, we can only assume it only supports the
|
||||
// algorithms that matches the key format. (This means that Sign can't pick
|
||||
// a different default.)
|
||||
// If k is a MultiAlgorithmSigner, we restrict the signature
|
||||
// algorithms. If k is a AlgorithmSigner, presume it supports all
|
||||
// signature algorithms associated with the key format. If k is not
|
||||
// an AlgorithmSigner, we can only assume it only supports the
|
||||
// algorithms that matches the key format. (This means that Sign
|
||||
// can't pick a different default).
|
||||
keyFormat := k.PublicKey().Type()
|
||||
if _, ok := k.(AlgorithmSigner); ok {
|
||||
|
||||
switch s := k.(type) {
|
||||
case MultiAlgorithmSigner:
|
||||
for _, algo := range algorithmsForKeyFormat(keyFormat) {
|
||||
if contains(s.Algorithms(), underlyingAlgo(algo)) {
|
||||
msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, algo)
|
||||
}
|
||||
}
|
||||
case AlgorithmSigner:
|
||||
msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, algorithmsForKeyFormat(keyFormat)...)
|
||||
} else {
|
||||
default:
|
||||
msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, keyFormat)
|
||||
}
|
||||
}
|
||||
|
|
@ -642,16 +647,20 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
|
|||
|
||||
// On the server side, after the first SSH_MSG_NEWKEYS, send a SSH_MSG_EXT_INFO
|
||||
// message with the server-sig-algs extension if the client supports it. See
|
||||
// RFC 8308, Sections 2.4 and 3.1.
|
||||
// RFC 8308, Sections 2.4 and 3.1, and [PROTOCOL], Section 1.9.
|
||||
if !isClient && firstKeyExchange && contains(clientInit.KexAlgos, "ext-info-c") {
|
||||
extInfo := &extInfoMsg{
|
||||
NumExtensions: 1,
|
||||
Payload: make([]byte, 0, 4+15+4+len(supportedPubKeyAuthAlgosList)),
|
||||
NumExtensions: 2,
|
||||
Payload: make([]byte, 0, 4+15+4+len(supportedPubKeyAuthAlgosList)+4+16+4+1),
|
||||
}
|
||||
extInfo.Payload = appendInt(extInfo.Payload, len("server-sig-algs"))
|
||||
extInfo.Payload = append(extInfo.Payload, "server-sig-algs"...)
|
||||
extInfo.Payload = appendInt(extInfo.Payload, len(supportedPubKeyAuthAlgosList))
|
||||
extInfo.Payload = append(extInfo.Payload, supportedPubKeyAuthAlgosList...)
|
||||
extInfo.Payload = appendInt(extInfo.Payload, len("ping@openssh.com"))
|
||||
extInfo.Payload = append(extInfo.Payload, "ping@openssh.com"...)
|
||||
extInfo.Payload = appendInt(extInfo.Payload, 1)
|
||||
extInfo.Payload = append(extInfo.Payload, "0"...)
|
||||
if err := t.conn.writePacket(Marshal(extInfo)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -685,9 +694,16 @@ func (a algorithmSignerWrapper) SignWithAlgorithm(rand io.Reader, data []byte, a
|
|||
|
||||
func pickHostKey(hostKeys []Signer, algo string) AlgorithmSigner {
|
||||
for _, k := range hostKeys {
|
||||
if s, ok := k.(MultiAlgorithmSigner); ok {
|
||||
if !contains(s.Algorithms(), underlyingAlgo(algo)) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if algo == k.PublicKey().Type() {
|
||||
return algorithmSignerWrapper{k}
|
||||
}
|
||||
|
||||
k, ok := k.(AlgorithmSigner)
|
||||
if !ok {
|
||||
continue
|
||||
|
|
|
|||
|
|
@ -11,13 +11,16 @@ import (
|
|||
"crypto/cipher"
|
||||
"crypto/dsa"
|
||||
"crypto/ecdsa"
|
||||
"crypto/ed25519"
|
||||
"crypto/elliptic"
|
||||
"crypto/md5"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/sha256"
|
||||
"crypto/x509"
|
||||
"encoding/asn1"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
|
|
@ -26,7 +29,6 @@ import (
|
|||
"math/big"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/crypto/ed25519"
|
||||
"golang.org/x/crypto/ssh/internal/bcrypt_pbkdf"
|
||||
)
|
||||
|
||||
|
|
@ -295,6 +297,18 @@ func MarshalAuthorizedKey(key PublicKey) []byte {
|
|||
return b.Bytes()
|
||||
}
|
||||
|
||||
// MarshalPrivateKey returns a PEM block with the private key serialized in the
|
||||
// OpenSSH format.
|
||||
func MarshalPrivateKey(key crypto.PrivateKey, comment string) (*pem.Block, error) {
|
||||
return marshalOpenSSHPrivateKey(key, comment, unencryptedOpenSSHMarshaler)
|
||||
}
|
||||
|
||||
// MarshalPrivateKeyWithPassphrase returns a PEM block holding the encrypted
|
||||
// private key serialized in the OpenSSH format.
|
||||
func MarshalPrivateKeyWithPassphrase(key crypto.PrivateKey, comment string, passphrase []byte) (*pem.Block, error) {
|
||||
return marshalOpenSSHPrivateKey(key, comment, passphraseProtectedOpenSSHMarshaler(passphrase))
|
||||
}
|
||||
|
||||
// PublicKey represents a public key using an unspecified algorithm.
|
||||
//
|
||||
// Some PublicKeys provided by this package also implement CryptoPublicKey.
|
||||
|
|
@ -321,7 +335,7 @@ type CryptoPublicKey interface {
|
|||
|
||||
// A Signer can create signatures that verify against a public key.
|
||||
//
|
||||
// Some Signers provided by this package also implement AlgorithmSigner.
|
||||
// Some Signers provided by this package also implement MultiAlgorithmSigner.
|
||||
type Signer interface {
|
||||
// PublicKey returns the associated PublicKey.
|
||||
PublicKey() PublicKey
|
||||
|
|
@ -336,9 +350,9 @@ type Signer interface {
|
|||
// An AlgorithmSigner is a Signer that also supports specifying an algorithm to
|
||||
// use for signing.
|
||||
//
|
||||
// An AlgorithmSigner can't advertise the algorithms it supports, so it should
|
||||
// be prepared to be invoked with every algorithm supported by the public key
|
||||
// format.
|
||||
// An AlgorithmSigner can't advertise the algorithms it supports, unless it also
|
||||
// implements MultiAlgorithmSigner, so it should be prepared to be invoked with
|
||||
// every algorithm supported by the public key format.
|
||||
type AlgorithmSigner interface {
|
||||
Signer
|
||||
|
||||
|
|
@ -349,6 +363,75 @@ type AlgorithmSigner interface {
|
|||
SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error)
|
||||
}
|
||||
|
||||
// MultiAlgorithmSigner is an AlgorithmSigner that also reports the algorithms
|
||||
// supported by that signer.
|
||||
type MultiAlgorithmSigner interface {
|
||||
AlgorithmSigner
|
||||
|
||||
// Algorithms returns the available algorithms in preference order. The list
|
||||
// must not be empty, and it must not include certificate types.
|
||||
Algorithms() []string
|
||||
}
|
||||
|
||||
// NewSignerWithAlgorithms returns a signer restricted to the specified
|
||||
// algorithms. The algorithms must be set in preference order. The list must not
|
||||
// be empty, and it must not include certificate types. An error is returned if
|
||||
// the specified algorithms are incompatible with the public key type.
|
||||
func NewSignerWithAlgorithms(signer AlgorithmSigner, algorithms []string) (MultiAlgorithmSigner, error) {
|
||||
if len(algorithms) == 0 {
|
||||
return nil, errors.New("ssh: please specify at least one valid signing algorithm")
|
||||
}
|
||||
var signerAlgos []string
|
||||
supportedAlgos := algorithmsForKeyFormat(underlyingAlgo(signer.PublicKey().Type()))
|
||||
if s, ok := signer.(*multiAlgorithmSigner); ok {
|
||||
signerAlgos = s.Algorithms()
|
||||
} else {
|
||||
signerAlgos = supportedAlgos
|
||||
}
|
||||
|
||||
for _, algo := range algorithms {
|
||||
if !contains(supportedAlgos, algo) {
|
||||
return nil, fmt.Errorf("ssh: algorithm %q is not supported for key type %q",
|
||||
algo, signer.PublicKey().Type())
|
||||
}
|
||||
if !contains(signerAlgos, algo) {
|
||||
return nil, fmt.Errorf("ssh: algorithm %q is restricted for the provided signer", algo)
|
||||
}
|
||||
}
|
||||
return &multiAlgorithmSigner{
|
||||
AlgorithmSigner: signer,
|
||||
supportedAlgorithms: algorithms,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type multiAlgorithmSigner struct {
|
||||
AlgorithmSigner
|
||||
supportedAlgorithms []string
|
||||
}
|
||||
|
||||
func (s *multiAlgorithmSigner) Algorithms() []string {
|
||||
return s.supportedAlgorithms
|
||||
}
|
||||
|
||||
func (s *multiAlgorithmSigner) isAlgorithmSupported(algorithm string) bool {
|
||||
if algorithm == "" {
|
||||
algorithm = underlyingAlgo(s.PublicKey().Type())
|
||||
}
|
||||
for _, algo := range s.supportedAlgorithms {
|
||||
if algorithm == algo {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *multiAlgorithmSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
|
||||
if !s.isAlgorithmSupported(algorithm) {
|
||||
return nil, fmt.Errorf("ssh: algorithm %q is not supported: %v", algorithm, s.supportedAlgorithms)
|
||||
}
|
||||
return s.AlgorithmSigner.SignWithAlgorithm(rand, data, algorithm)
|
||||
}
|
||||
|
||||
type rsaPublicKey rsa.PublicKey
|
||||
|
||||
func (r *rsaPublicKey) Type() string {
|
||||
|
|
@ -512,6 +595,10 @@ func (k *dsaPrivateKey) Sign(rand io.Reader, data []byte) (*Signature, error) {
|
|||
return k.SignWithAlgorithm(rand, data, k.PublicKey().Type())
|
||||
}
|
||||
|
||||
func (k *dsaPrivateKey) Algorithms() []string {
|
||||
return []string{k.PublicKey().Type()}
|
||||
}
|
||||
|
||||
func (k *dsaPrivateKey) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
|
||||
if algorithm != "" && algorithm != k.PublicKey().Type() {
|
||||
return nil, fmt.Errorf("ssh: unsupported signature algorithm %s", algorithm)
|
||||
|
|
@ -961,13 +1048,16 @@ func (s *wrappedSigner) Sign(rand io.Reader, data []byte) (*Signature, error) {
|
|||
return s.SignWithAlgorithm(rand, data, s.pubKey.Type())
|
||||
}
|
||||
|
||||
func (s *wrappedSigner) Algorithms() []string {
|
||||
return algorithmsForKeyFormat(s.pubKey.Type())
|
||||
}
|
||||
|
||||
func (s *wrappedSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
|
||||
if algorithm == "" {
|
||||
algorithm = s.pubKey.Type()
|
||||
}
|
||||
|
||||
supportedAlgos := algorithmsForKeyFormat(s.pubKey.Type())
|
||||
if !contains(supportedAlgos, algorithm) {
|
||||
if !contains(s.Algorithms(), algorithm) {
|
||||
return nil, fmt.Errorf("ssh: unsupported signature algorithm %q for key format %q", algorithm, s.pubKey.Type())
|
||||
}
|
||||
|
||||
|
|
@ -1241,28 +1331,106 @@ func passphraseProtectedOpenSSHKey(passphrase []byte) openSSHDecryptFunc {
|
|||
}
|
||||
}
|
||||
|
||||
func unencryptedOpenSSHMarshaler(privKeyBlock []byte) ([]byte, string, string, string, error) {
|
||||
key := generateOpenSSHPadding(privKeyBlock, 8)
|
||||
return key, "none", "none", "", nil
|
||||
}
|
||||
|
||||
func passphraseProtectedOpenSSHMarshaler(passphrase []byte) openSSHEncryptFunc {
|
||||
return func(privKeyBlock []byte) ([]byte, string, string, string, error) {
|
||||
salt := make([]byte, 16)
|
||||
if _, err := rand.Read(salt); err != nil {
|
||||
return nil, "", "", "", err
|
||||
}
|
||||
|
||||
opts := struct {
|
||||
Salt []byte
|
||||
Rounds uint32
|
||||
}{salt, 16}
|
||||
|
||||
// Derive key to encrypt the private key block.
|
||||
k, err := bcrypt_pbkdf.Key(passphrase, salt, int(opts.Rounds), 32+aes.BlockSize)
|
||||
if err != nil {
|
||||
return nil, "", "", "", err
|
||||
}
|
||||
|
||||
// Add padding matching the block size of AES.
|
||||
keyBlock := generateOpenSSHPadding(privKeyBlock, aes.BlockSize)
|
||||
|
||||
// Encrypt the private key using the derived secret.
|
||||
|
||||
dst := make([]byte, len(keyBlock))
|
||||
key, iv := k[:32], k[32:]
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, "", "", "", err
|
||||
}
|
||||
|
||||
stream := cipher.NewCTR(block, iv)
|
||||
stream.XORKeyStream(dst, keyBlock)
|
||||
|
||||
return dst, "aes256-ctr", "bcrypt", string(Marshal(opts)), nil
|
||||
}
|
||||
}
|
||||
|
||||
const privateKeyAuthMagic = "openssh-key-v1\x00"
|
||||
|
||||
type openSSHDecryptFunc func(CipherName, KdfName, KdfOpts string, PrivKeyBlock []byte) ([]byte, error)
|
||||
type openSSHEncryptFunc func(PrivKeyBlock []byte) (ProtectedKeyBlock []byte, cipherName, kdfName, kdfOptions string, err error)
|
||||
|
||||
type openSSHEncryptedPrivateKey struct {
|
||||
CipherName string
|
||||
KdfName string
|
||||
KdfOpts string
|
||||
NumKeys uint32
|
||||
PubKey []byte
|
||||
PrivKeyBlock []byte
|
||||
}
|
||||
|
||||
type openSSHPrivateKey struct {
|
||||
Check1 uint32
|
||||
Check2 uint32
|
||||
Keytype string
|
||||
Rest []byte `ssh:"rest"`
|
||||
}
|
||||
|
||||
type openSSHRSAPrivateKey struct {
|
||||
N *big.Int
|
||||
E *big.Int
|
||||
D *big.Int
|
||||
Iqmp *big.Int
|
||||
P *big.Int
|
||||
Q *big.Int
|
||||
Comment string
|
||||
Pad []byte `ssh:"rest"`
|
||||
}
|
||||
|
||||
type openSSHEd25519PrivateKey struct {
|
||||
Pub []byte
|
||||
Priv []byte
|
||||
Comment string
|
||||
Pad []byte `ssh:"rest"`
|
||||
}
|
||||
|
||||
type openSSHECDSAPrivateKey struct {
|
||||
Curve string
|
||||
Pub []byte
|
||||
D *big.Int
|
||||
Comment string
|
||||
Pad []byte `ssh:"rest"`
|
||||
}
|
||||
|
||||
// parseOpenSSHPrivateKey parses an OpenSSH private key, using the decrypt
|
||||
// function to unwrap the encrypted portion. unencryptedOpenSSHKey can be used
|
||||
// as the decrypt function to parse an unencrypted private key. See
|
||||
// https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key.
|
||||
func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.PrivateKey, error) {
|
||||
const magic = "openssh-key-v1\x00"
|
||||
if len(key) < len(magic) || string(key[:len(magic)]) != magic {
|
||||
if len(key) < len(privateKeyAuthMagic) || string(key[:len(privateKeyAuthMagic)]) != privateKeyAuthMagic {
|
||||
return nil, errors.New("ssh: invalid openssh private key format")
|
||||
}
|
||||
remaining := key[len(magic):]
|
||||
|
||||
var w struct {
|
||||
CipherName string
|
||||
KdfName string
|
||||
KdfOpts string
|
||||
NumKeys uint32
|
||||
PubKey []byte
|
||||
PrivKeyBlock []byte
|
||||
}
|
||||
remaining := key[len(privateKeyAuthMagic):]
|
||||
|
||||
var w openSSHEncryptedPrivateKey
|
||||
if err := Unmarshal(remaining, &w); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -1284,13 +1452,7 @@ func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.Priv
|
|||
return nil, err
|
||||
}
|
||||
|
||||
pk1 := struct {
|
||||
Check1 uint32
|
||||
Check2 uint32
|
||||
Keytype string
|
||||
Rest []byte `ssh:"rest"`
|
||||
}{}
|
||||
|
||||
var pk1 openSSHPrivateKey
|
||||
if err := Unmarshal(privKeyBlock, &pk1); err != nil || pk1.Check1 != pk1.Check2 {
|
||||
if w.CipherName != "none" {
|
||||
return nil, x509.IncorrectPasswordError
|
||||
|
|
@ -1300,18 +1462,7 @@ func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.Priv
|
|||
|
||||
switch pk1.Keytype {
|
||||
case KeyAlgoRSA:
|
||||
// https://github.com/openssh/openssh-portable/blob/master/sshkey.c#L2760-L2773
|
||||
key := struct {
|
||||
N *big.Int
|
||||
E *big.Int
|
||||
D *big.Int
|
||||
Iqmp *big.Int
|
||||
P *big.Int
|
||||
Q *big.Int
|
||||
Comment string
|
||||
Pad []byte `ssh:"rest"`
|
||||
}{}
|
||||
|
||||
var key openSSHRSAPrivateKey
|
||||
if err := Unmarshal(pk1.Rest, &key); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -1337,13 +1488,7 @@ func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.Priv
|
|||
|
||||
return pk, nil
|
||||
case KeyAlgoED25519:
|
||||
key := struct {
|
||||
Pub []byte
|
||||
Priv []byte
|
||||
Comment string
|
||||
Pad []byte `ssh:"rest"`
|
||||
}{}
|
||||
|
||||
var key openSSHEd25519PrivateKey
|
||||
if err := Unmarshal(pk1.Rest, &key); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -1360,14 +1505,7 @@ func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.Priv
|
|||
copy(pk, key.Priv)
|
||||
return &pk, nil
|
||||
case KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521:
|
||||
key := struct {
|
||||
Curve string
|
||||
Pub []byte
|
||||
D *big.Int
|
||||
Comment string
|
||||
Pad []byte `ssh:"rest"`
|
||||
}{}
|
||||
|
||||
var key openSSHECDSAPrivateKey
|
||||
if err := Unmarshal(pk1.Rest, &key); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -1415,6 +1553,131 @@ func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.Priv
|
|||
}
|
||||
}
|
||||
|
||||
func marshalOpenSSHPrivateKey(key crypto.PrivateKey, comment string, encrypt openSSHEncryptFunc) (*pem.Block, error) {
|
||||
var w openSSHEncryptedPrivateKey
|
||||
var pk1 openSSHPrivateKey
|
||||
|
||||
// Random check bytes.
|
||||
var check uint32
|
||||
if err := binary.Read(rand.Reader, binary.BigEndian, &check); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pk1.Check1 = check
|
||||
pk1.Check2 = check
|
||||
w.NumKeys = 1
|
||||
|
||||
// Use a []byte directly on ed25519 keys.
|
||||
if k, ok := key.(*ed25519.PrivateKey); ok {
|
||||
key = *k
|
||||
}
|
||||
|
||||
switch k := key.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
E := new(big.Int).SetInt64(int64(k.PublicKey.E))
|
||||
// Marshal public key:
|
||||
// E and N are in reversed order in the public and private key.
|
||||
pubKey := struct {
|
||||
KeyType string
|
||||
E *big.Int
|
||||
N *big.Int
|
||||
}{
|
||||
KeyAlgoRSA,
|
||||
E, k.PublicKey.N,
|
||||
}
|
||||
w.PubKey = Marshal(pubKey)
|
||||
|
||||
// Marshal private key.
|
||||
key := openSSHRSAPrivateKey{
|
||||
N: k.PublicKey.N,
|
||||
E: E,
|
||||
D: k.D,
|
||||
Iqmp: k.Precomputed.Qinv,
|
||||
P: k.Primes[0],
|
||||
Q: k.Primes[1],
|
||||
Comment: comment,
|
||||
}
|
||||
pk1.Keytype = KeyAlgoRSA
|
||||
pk1.Rest = Marshal(key)
|
||||
case ed25519.PrivateKey:
|
||||
pub := make([]byte, ed25519.PublicKeySize)
|
||||
priv := make([]byte, ed25519.PrivateKeySize)
|
||||
copy(pub, k[32:])
|
||||
copy(priv, k)
|
||||
|
||||
// Marshal public key.
|
||||
pubKey := struct {
|
||||
KeyType string
|
||||
Pub []byte
|
||||
}{
|
||||
KeyAlgoED25519, pub,
|
||||
}
|
||||
w.PubKey = Marshal(pubKey)
|
||||
|
||||
// Marshal private key.
|
||||
key := openSSHEd25519PrivateKey{
|
||||
Pub: pub,
|
||||
Priv: priv,
|
||||
Comment: comment,
|
||||
}
|
||||
pk1.Keytype = KeyAlgoED25519
|
||||
pk1.Rest = Marshal(key)
|
||||
case *ecdsa.PrivateKey:
|
||||
var curve, keyType string
|
||||
switch name := k.Curve.Params().Name; name {
|
||||
case "P-256":
|
||||
curve = "nistp256"
|
||||
keyType = KeyAlgoECDSA256
|
||||
case "P-384":
|
||||
curve = "nistp384"
|
||||
keyType = KeyAlgoECDSA384
|
||||
case "P-521":
|
||||
curve = "nistp521"
|
||||
keyType = KeyAlgoECDSA521
|
||||
default:
|
||||
return nil, errors.New("ssh: unhandled elliptic curve " + name)
|
||||
}
|
||||
|
||||
pub := elliptic.Marshal(k.Curve, k.PublicKey.X, k.PublicKey.Y)
|
||||
|
||||
// Marshal public key.
|
||||
pubKey := struct {
|
||||
KeyType string
|
||||
Curve string
|
||||
Pub []byte
|
||||
}{
|
||||
keyType, curve, pub,
|
||||
}
|
||||
w.PubKey = Marshal(pubKey)
|
||||
|
||||
// Marshal private key.
|
||||
key := openSSHECDSAPrivateKey{
|
||||
Curve: curve,
|
||||
Pub: pub,
|
||||
D: k.D,
|
||||
Comment: comment,
|
||||
}
|
||||
pk1.Keytype = keyType
|
||||
pk1.Rest = Marshal(key)
|
||||
default:
|
||||
return nil, fmt.Errorf("ssh: unsupported key type %T", k)
|
||||
}
|
||||
|
||||
var err error
|
||||
// Add padding and encrypt the key if necessary.
|
||||
w.PrivKeyBlock, w.CipherName, w.KdfName, w.KdfOpts, err = encrypt(Marshal(pk1))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b := Marshal(w)
|
||||
block := &pem.Block{
|
||||
Type: "OPENSSH PRIVATE KEY",
|
||||
Bytes: append([]byte(privateKeyAuthMagic), b...),
|
||||
}
|
||||
return block, nil
|
||||
}
|
||||
|
||||
func checkOpenSSHKeyPadding(pad []byte) error {
|
||||
for i, b := range pad {
|
||||
if int(b) != i+1 {
|
||||
|
|
@ -1424,6 +1687,13 @@ func checkOpenSSHKeyPadding(pad []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func generateOpenSSHPadding(block []byte, blockSize int) []byte {
|
||||
for i, l := 0, len(block); (l+i)%blockSize != 0; i++ {
|
||||
block = append(block, byte(i+1))
|
||||
}
|
||||
return block
|
||||
}
|
||||
|
||||
// FingerprintLegacyMD5 returns the user presentation of the key's
|
||||
// fingerprint as described by RFC 4716 section 4.
|
||||
func FingerprintLegacyMD5(pubKey PublicKey) string {
|
||||
|
|
|
|||
|
|
@ -349,6 +349,20 @@ type userAuthGSSAPIError struct {
|
|||
LanguageTag string
|
||||
}
|
||||
|
||||
// Transport layer OpenSSH extension. See [PROTOCOL], section 1.9
|
||||
const msgPing = 192
|
||||
|
||||
type pingMsg struct {
|
||||
Data string `sshtype:"192"`
|
||||
}
|
||||
|
||||
// Transport layer OpenSSH extension. See [PROTOCOL], section 1.9
|
||||
const msgPong = 193
|
||||
|
||||
type pongMsg struct {
|
||||
Data string `sshtype:"193"`
|
||||
}
|
||||
|
||||
// typeTags returns the possible type bytes for the given reflect.Type, which
|
||||
// should be a struct. The possible values are separated by a '|' character.
|
||||
func typeTags(structType reflect.Type) (tags []byte) {
|
||||
|
|
|
|||
|
|
@ -231,6 +231,12 @@ func (m *mux) onePacket() error {
|
|||
return m.handleChannelOpen(packet)
|
||||
case msgGlobalRequest, msgRequestSuccess, msgRequestFailure:
|
||||
return m.handleGlobalPacket(packet)
|
||||
case msgPing:
|
||||
var msg pingMsg
|
||||
if err := Unmarshal(packet, &msg); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal ping@openssh.com message: %w", err)
|
||||
}
|
||||
return m.sendMessage(pongMsg(msg))
|
||||
}
|
||||
|
||||
// assume a channel packet.
|
||||
|
|
|
|||
|
|
@ -576,7 +576,16 @@ userAuthLoop:
|
|||
if !ok || len(payload) > 0 {
|
||||
return nil, parseError(msgUserAuthRequest)
|
||||
}
|
||||
|
||||
// Ensure the declared public key algo is compatible with the
|
||||
// decoded one. This check will ensure we don't accept e.g.
|
||||
// ssh-rsa-cert-v01@openssh.com algorithm with ssh-rsa public
|
||||
// key type. The algorithm and public key type must be
|
||||
// consistent: both must be certificate algorithms, or neither.
|
||||
if !contains(algorithmsForKeyFormat(pubKey.Type()), algo) {
|
||||
authErr = fmt.Errorf("ssh: public key type %q not compatible with selected algorithm %q",
|
||||
pubKey.Type(), algo)
|
||||
break
|
||||
}
|
||||
// Ensure the public key algo and signature algo
|
||||
// are supported. Compare the private key
|
||||
// algorithm name that corresponds to algo with
|
||||
|
|
|
|||
|
|
@ -111,12 +111,15 @@ github.com/container-orchestrated-devices/container-device-interface/specs-go
|
|||
# github.com/containerd/cgroups/v3 v3.0.2
|
||||
## explicit; go 1.18
|
||||
github.com/containerd/cgroups/v3/cgroup1/stats
|
||||
# github.com/containerd/containerd v1.7.6
|
||||
# github.com/containerd/containerd v1.7.7
|
||||
## explicit; go 1.19
|
||||
github.com/containerd/containerd/errdefs
|
||||
github.com/containerd/containerd/log
|
||||
github.com/containerd/containerd/pkg/userns
|
||||
github.com/containerd/containerd/platforms
|
||||
# github.com/containerd/log v0.1.0
|
||||
## explicit; go 1.20
|
||||
github.com/containerd/log
|
||||
# github.com/containerd/stargz-snapshotter/estargz v0.14.3
|
||||
## explicit; go 1.19
|
||||
github.com/containerd/stargz-snapshotter/estargz
|
||||
|
|
@ -164,7 +167,7 @@ github.com/containers/buildah/pkg/sshagent
|
|||
github.com/containers/buildah/pkg/util
|
||||
github.com/containers/buildah/pkg/volumes
|
||||
github.com/containers/buildah/util
|
||||
# github.com/containers/common v0.56.1-0.20231005124809-b4ef9cdeab5b
|
||||
# github.com/containers/common v0.56.1-0.20231010150003-09776aa73db7
|
||||
## explicit; go 1.18
|
||||
github.com/containers/common/libimage
|
||||
github.com/containers/common/libimage/define
|
||||
|
|
@ -1059,7 +1062,7 @@ go.opentelemetry.io/otel/trace
|
|||
# golang.org/x/arch v0.3.0
|
||||
## explicit; go 1.17
|
||||
golang.org/x/arch/x86/x86asm
|
||||
# golang.org/x/crypto v0.13.0
|
||||
# golang.org/x/crypto v0.14.0
|
||||
## explicit; go 1.17
|
||||
golang.org/x/crypto/argon2
|
||||
golang.org/x/crypto/blake2b
|
||||
|
|
|
|||
Loading…
Reference in New Issue