aboutsummaryrefslogtreecommitdiff
path: root/vendor
diff options
context:
space:
mode:
authorCharlie Doern <cdoern@redhat.com>2022-08-23 11:04:54 -0400
committercdoern <cbdoer23@g.holycross.edu>2022-09-26 18:35:01 -0400
commit2e4e1bb97cdd0fbef7ada673fa97f6b4989998eb (patch)
treede2e77c1852b505891c11d4cecfac5a1945abf0d /vendor
parent5fc6d95a947bdf0e0bf013ee282c4a0f99b52a5a (diff)
downloadpodman-2e4e1bb97cdd0fbef7ada673fa97f6b4989998eb.tar.gz
podman-2e4e1bb97cdd0fbef7ada673fa97f6b4989998eb.tar.bz2
podman-2e4e1bb97cdd0fbef7ada673fa97f6b4989998eb.zip
podman machine ssh handling
add the key used in newly initialized machines to the user's known_hosts file. This ensures that golang will be able to ssh into the machine using podman-remote. Also, remove the /dev/null redirection for podman machine ssh's known_hosts file. resolves #15347 Signed-off-by: Charlie Doern <cdoern@redhat.com> Signed-off-by: cdoern <cbdoer23@g.holycross.edu>
Diffstat (limited to 'vendor')
-rw-r--r--vendor/github.com/containers/common/libimage/platform.go3
-rw-r--r--vendor/github.com/containers/common/pkg/config/config.go19
-rw-r--r--vendor/github.com/containers/common/pkg/ssh/connection_golang.go83
-rw-r--r--vendor/github.com/containers/common/pkg/ssh/types.go13
-rw-r--r--vendor/github.com/containers/common/pkg/ssh/utils.go5
-rw-r--r--vendor/modules.txt2
6 files changed, 98 insertions, 27 deletions
diff --git a/vendor/github.com/containers/common/libimage/platform.go b/vendor/github.com/containers/common/libimage/platform.go
index 736a193f6..274b2aa06 100644
--- a/vendor/github.com/containers/common/libimage/platform.go
+++ b/vendor/github.com/containers/common/libimage/platform.go
@@ -63,6 +63,9 @@ func toPlatformString(os, arch, variant string) string {
// * 2) a bool indicating whether architecture, os or variant were set (some callers need that to decide whether they need to throw an error)
// * 3) a fatal error that occurred prior to check for matches (e.g., storage errors etc.)
func (i *Image) matchesPlatform(ctx context.Context, os, arch, variant string) (error, bool, error) {
+ if err := i.isCorrupted(""); err != nil {
+ return err, false, nil
+ }
inspectInfo, err := i.inspectInfo(ctx)
if err != nil {
return nil, false, fmt.Errorf("inspecting image: %w", err)
diff --git a/vendor/github.com/containers/common/pkg/config/config.go b/vendor/github.com/containers/common/pkg/config/config.go
index 858f961b6..cde7cec53 100644
--- a/vendor/github.com/containers/common/pkg/config/config.go
+++ b/vendor/github.com/containers/common/pkg/config/config.go
@@ -613,6 +613,9 @@ type Destination struct {
// Identity file with ssh key, optional
Identity string `toml:"identity,omitempty"`
+
+ // isMachine describes if the remote destination is a machine.
+ IsMachine bool `toml:"is_machine,omitempty"`
}
// NewConfig creates a new Config. It starts with an empty config and, if
@@ -1235,32 +1238,32 @@ func Reload() (*Config, error) {
return defConfig()
}
-func (c *Config) ActiveDestination() (uri, identity string, err error) {
+func (c *Config) ActiveDestination() (uri, identity string, machine bool, err error) {
if uri, found := os.LookupEnv("CONTAINER_HOST"); found {
if v, found := os.LookupEnv("CONTAINER_SSHKEY"); found {
identity = v
}
- return uri, identity, nil
+ return uri, identity, false, nil
}
connEnv := os.Getenv("CONTAINER_CONNECTION")
switch {
case connEnv != "":
d, found := c.Engine.ServiceDestinations[connEnv]
if !found {
- return "", "", fmt.Errorf("environment variable CONTAINER_CONNECTION=%q service destination not found", connEnv)
+ return "", "", false, fmt.Errorf("environment variable CONTAINER_CONNECTION=%q service destination not found", connEnv)
}
- return d.URI, d.Identity, nil
+ return d.URI, d.Identity, d.IsMachine, nil
case c.Engine.ActiveService != "":
d, found := c.Engine.ServiceDestinations[c.Engine.ActiveService]
if !found {
- return "", "", fmt.Errorf("%q service destination not found", c.Engine.ActiveService)
+ return "", "", false, fmt.Errorf("%q service destination not found", c.Engine.ActiveService)
}
- return d.URI, d.Identity, nil
+ return d.URI, d.Identity, d.IsMachine, nil
case c.Engine.RemoteURI != "":
- return c.Engine.RemoteURI, c.Engine.RemoteIdentity, nil
+ return c.Engine.RemoteURI, c.Engine.RemoteIdentity, false, nil
}
- return "", "", errors.New("no service destination configured")
+ return "", "", false, errors.New("no service destination configured")
}
var (
diff --git a/vendor/github.com/containers/common/pkg/ssh/connection_golang.go b/vendor/github.com/containers/common/pkg/ssh/connection_golang.go
index a5c1be89c..8ec3c45ed 100644
--- a/vendor/github.com/containers/common/pkg/ssh/connection_golang.go
+++ b/vendor/github.com/containers/common/pkg/ssh/connection_golang.go
@@ -3,6 +3,7 @@ package ssh
import (
"bytes"
"encoding/json"
+ "errors"
"fmt"
"io"
"net"
@@ -70,7 +71,7 @@ func golangConnectionDial(options ConnectionDialOptions) (*ConnectionDialReport,
if err != nil {
return nil, err
}
- cfg, err := ValidateAndConfigure(uri, options.Identity)
+ cfg, err := ValidateAndConfigure(uri, options.Identity, options.InsecureIsMachineConnection)
if err != nil {
return nil, err
}
@@ -84,12 +85,15 @@ func golangConnectionDial(options ConnectionDialOptions) (*ConnectionDialReport,
}
func golangConnectionExec(options ConnectionExecOptions) (*ConnectionExecReport, error) {
+ if !strings.HasPrefix(options.Host, "ssh://") {
+ options.Host = "ssh://" + options.Host
+ }
_, uri, err := Validate(options.User, options.Host, options.Port, options.Identity)
if err != nil {
return nil, err
}
- cfg, err := ValidateAndConfigure(uri, options.Identity)
+ cfg, err := ValidateAndConfigure(uri, options.Identity, false)
if err != nil {
return nil, err
}
@@ -111,11 +115,15 @@ func golangConnectionScp(options ConnectionScpOptions) (*ConnectionScpReport, er
return nil, err
}
+ // removed for parsing
+ if !strings.HasPrefix(host, "ssh://") {
+ host = "ssh://" + host
+ }
_, uri, err := Validate(options.User, host, options.Port, options.Identity)
if err != nil {
return nil, err
}
- cfg, err := ValidateAndConfigure(uri, options.Identity)
+ cfg, err := ValidateAndConfigure(uri, options.Identity, false)
if err != nil {
return nil, err
}
@@ -209,7 +217,7 @@ func GetUserInfo(uri *url.URL) (*url.Userinfo, error) {
// ValidateAndConfigure will take a ssh url and an identity key (rsa and the like) and ensure the information given is valid
// iden iden can be blank to mean no identity key
// once the function validates the information it creates and returns an ssh.ClientConfig.
-func ValidateAndConfigure(uri *url.URL, iden string) (*ssh.ClientConfig, error) {
+func ValidateAndConfigure(uri *url.URL, iden string, insecureIsMachineConnection bool) (*ssh.ClientConfig, error) {
var signers []ssh.Signer
passwd, passwdSet := uri.User.Password()
if iden != "" { // iden might be blank if coming from image scp or if no validation is needed
@@ -272,23 +280,61 @@ func ValidateAndConfigure(uri *url.URL, iden string) (*ssh.ClientConfig, error)
if err != nil {
return nil, err
}
- keyFilePath := filepath.Join(homedir.Get(), ".ssh", "known_hosts")
- known, err := knownhosts.New(keyFilePath)
- if err != nil {
- return nil, fmt.Errorf("creating host key callback function for %s: %w", keyFilePath, err)
+
+ var callback ssh.HostKeyCallback
+ if insecureIsMachineConnection {
+ callback = ssh.InsecureIgnoreHostKey()
+ } else {
+ callback = ssh.HostKeyCallback(func(host string, remote net.Addr, pubKey ssh.PublicKey) error {
+ keyFilePath := filepath.Join(homedir.Get(), ".ssh", "known_hosts")
+ known, err := knownhosts.New(keyFilePath)
+ if err != nil {
+ if errors.Is(err, os.ErrNotExist) {
+ logrus.Warn("please create a known_hosts file. The next time this host is connected to, podman will add it to known_hosts")
+ return nil
+ }
+ return err
+ }
+ // we need to check if there is an error from reading known hosts for this public key and if there is an error, what is it, and why is it happening?
+ // if it is a key mismatch we want to error since we know the host using another key
+ // however, if it is a general error not because of a known key, we want to add our key to the known_hosts file
+ hErr := known(host, remote, pubKey)
+ var keyErr *knownhosts.KeyError
+ // if keyErr.Want is not empty, we are receiving a different key meaning the host is known but we are using the wrong key
+ as := errors.As(hErr, &keyErr)
+ switch {
+ case as && len(keyErr.Want) > 0:
+ logrus.Warnf("ssh host key mismatch for host %s, got key %s of type %s", host, ssh.FingerprintSHA256(pubKey), pubKey.Type())
+ return keyErr
+ // if keyErr.Want is empty that just means we do not know this host yet, add it.
+ case as && len(keyErr.Want) == 0:
+ // write to known_hosts
+ err := addKnownHostsEntry(host, pubKey)
+ if err != nil {
+ if os.IsNotExist(err) {
+ logrus.Warn("podman will soon require a known_hosts file to function properly.")
+ return nil
+ }
+ return err
+ }
+ case hErr != nil:
+ return hErr
+ }
+ return nil
+ })
}
cfg := &ssh.ClientConfig{
User: uri.User.Username(),
Auth: authMethods,
- HostKeyCallback: known,
+ HostKeyCallback: callback,
Timeout: tick,
}
return cfg, nil
}
func getUDS(uri *url.URL, iden string) (string, error) {
- cfg, err := ValidateAndConfigure(uri, iden)
+ cfg, err := ValidateAndConfigure(uri, iden, false)
if err != nil {
return "", fmt.Errorf("failed to validate: %w", err)
}
@@ -324,3 +370,20 @@ func getUDS(uri *url.URL, iden string) (string, error) {
}
return info.Host.RemoteSocket.Path, nil
}
+
+// addKnownHostsEntry adds (host, pubKey) to user’s known_hosts.
+func addKnownHostsEntry(host string, pubKey ssh.PublicKey) error {
+ hd := homedir.Get()
+ known := filepath.Join(hd, ".ssh", "known_hosts")
+ f, err := os.OpenFile(known, os.O_APPEND|os.O_WRONLY, 0o600)
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+ l := knownhosts.Line([]string{host}, pubKey)
+ if _, err = f.WriteString("\n" + l + "\n"); err != nil {
+ return err
+ }
+ logrus.Infof("key %s added to %s", ssh.FingerprintSHA256(pubKey), known)
+ return nil
+}
diff --git a/vendor/github.com/containers/common/pkg/ssh/types.go b/vendor/github.com/containers/common/pkg/ssh/types.go
index f22b5fba9..16512c43f 100644
--- a/vendor/github.com/containers/common/pkg/ssh/types.go
+++ b/vendor/github.com/containers/common/pkg/ssh/types.go
@@ -27,12 +27,13 @@ type ConnectionCreateOptions struct {
}
type ConnectionDialOptions struct {
- Host string
- Identity string
- User *url.Userinfo
- Port int
- Auth []string
- Timeout time.Duration
+ Host string
+ Identity string
+ User *url.Userinfo
+ Port int
+ Auth []string
+ Timeout time.Duration
+ InsecureIsMachineConnection bool
}
type ConnectionDialReport struct {
diff --git a/vendor/github.com/containers/common/pkg/ssh/utils.go b/vendor/github.com/containers/common/pkg/ssh/utils.go
index c15745015..b05105d9c 100644
--- a/vendor/github.com/containers/common/pkg/ssh/utils.go
+++ b/vendor/github.com/containers/common/pkg/ssh/utils.go
@@ -21,6 +21,7 @@ func Validate(user *url.Userinfo, path string, port int, identity string) (*conf
if strings.Contains(path, "/run") {
sock = strings.Split(path, "/run")[1]
}
+ // url.Parse NEEDS ssh://, if this ever fails or returns some nonsense, that is why.
uri, err := url.Parse(path)
if err != nil {
return nil, nil, err
@@ -33,9 +34,9 @@ func Validate(user *url.Userinfo, path string, port int, identity string) (*conf
if uri.Port() == "" {
if port != 0 {
- uri.Host = net.JoinHostPort(uri.Hostname(), strconv.Itoa(port))
+ uri.Host = net.JoinHostPort(uri.Host, strconv.Itoa(port))
} else {
- uri.Host = net.JoinHostPort(uri.Hostname(), "22")
+ uri.Host = net.JoinHostPort(uri.Host, "22")
}
}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 17e889387..222b70cd3 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -120,7 +120,7 @@ github.com/containers/buildah/pkg/rusage
github.com/containers/buildah/pkg/sshagent
github.com/containers/buildah/pkg/util
github.com/containers/buildah/util
-# github.com/containers/common v0.49.2-0.20220920205255-8062f81c5497
+# github.com/containers/common v0.49.2-0.20220926195839-590004b80685
## explicit; go 1.17
github.com/containers/common/libimage
github.com/containers/common/libimage/define