1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
12 "git.arvados.org/arvados.git/lib/cloud"
13 "golang.org/x/crypto/ssh"
17 errBadInstanceSecret = errors.New("bad instance secret")
19 // filename on instance, as given to shell (quoted accordingly)
20 instanceSecretFilename = "/var/run/arvados-instance-secret"
21 instanceSecretLength = 40 // hex digits
24 type TagVerifier struct {
27 ReportVerified func(cloud.Instance)
30 func (tv TagVerifier) InitCommand() cloud.InitCommand {
31 return cloud.InitCommand(fmt.Sprintf("umask 0177 && echo -n %q >%s", tv.Secret, instanceSecretFilename))
34 func (tv TagVerifier) VerifyHostKey(pubKey ssh.PublicKey, client *ssh.Client) error {
35 if tv.ReportVerified != nil {
36 tv.ReportVerified(tv.Instance)
38 if err := tv.Instance.VerifyHostKey(pubKey, client); err != cloud.ErrNotImplemented || tv.Secret == "" {
39 // If the wrapped instance indicates it has a way to
40 // verify the key, return that decision.
43 session, err := client.NewSession()
48 var stdout, stderr bytes.Buffer
49 session.Stdin = bytes.NewBuffer(nil)
50 session.Stdout = &stdout
51 session.Stderr = &stderr
52 cmd := fmt.Sprintf("cat %s", instanceSecretFilename)
53 if u := tv.RemoteUser(); u != "root" {
56 err = session.Run(cmd)
60 if stdout.String() != tv.Secret {
61 return errBadInstanceSecret