github.com/vmware/govmomi@v0.51.0/cli/about/cert.go (about) 1 // © Broadcom. All Rights Reserved. 2 // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 // SPDX-License-Identifier: Apache-2.0 4 5 package about 6 7 import ( 8 "context" 9 "encoding/pem" 10 "flag" 11 "fmt" 12 "io" 13 "net/http" 14 "os" 15 16 "github.com/vmware/govmomi/cli" 17 "github.com/vmware/govmomi/cli/flags" 18 "github.com/vmware/govmomi/object" 19 "github.com/vmware/govmomi/vim25/soap" 20 ) 21 22 type cert struct { 23 *flags.ClientFlag 24 *flags.OutputFlag 25 26 show bool 27 thumbprint bool 28 } 29 30 func init() { 31 cli.Register("about.cert", &cert{}) 32 } 33 34 func (cmd *cert) Register(ctx context.Context, f *flag.FlagSet) { 35 cmd.ClientFlag, ctx = flags.NewClientFlag(ctx) 36 cmd.ClientFlag.Register(ctx, f) 37 38 cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx) 39 cmd.OutputFlag.Register(ctx, f) 40 41 f.BoolVar(&cmd.show, "show", false, "Show PEM encoded server certificate only") 42 f.BoolVar(&cmd.thumbprint, "thumbprint", false, "Output host hash and thumbprint only") 43 } 44 45 func (cmd *cert) Description() string { 46 return `Display TLS certificate info for HOST. 47 48 If the HOST certificate cannot be verified, about.cert will return with exit code 60 (as curl does). 49 If the '-k' flag is provided, about.cert will return with exit code 0 in this case. 50 The SHA1 thumbprint can also be used as '-thumbprint' for the 'host.add' and 'cluster.add' commands. 51 52 Examples: 53 govc about.cert -k -json | jq -r .thumbprintSHA1 54 govc about.cert -k -show | sudo tee /usr/local/share/ca-certificates/host.crt 55 govc about.cert -k -thumbprint | tee -a ~/.govmomi/known_hosts` 56 } 57 58 func (cmd *cert) Process(ctx context.Context) error { 59 if err := cmd.ClientFlag.Process(ctx); err != nil { 60 return err 61 } 62 if err := cmd.OutputFlag.Process(ctx); err != nil { 63 return err 64 } 65 return nil 66 } 67 68 type certResult struct { 69 cmd *cert 70 info object.HostCertificateInfo 71 } 72 73 func (r *certResult) Write(w io.Writer) error { 74 if r.cmd.show { 75 return pem.Encode(w, &pem.Block{Type: "CERTIFICATE", Bytes: r.info.Certificate.Raw}) 76 } 77 78 if r.cmd.thumbprint { 79 u := r.cmd.Session.URL 80 _, err := fmt.Fprintf(w, "%s %s\n", u.Host, r.info.ThumbprintSHA256) 81 return err 82 } 83 84 return r.cmd.WriteResult(&r.info) 85 } 86 87 func (cmd *cert) Run(ctx context.Context, f *flag.FlagSet) error { 88 u := cmd.Session.URL 89 c := soap.NewClient(u, false) 90 t := c.Client.Transport.(*http.Transport) 91 r := certResult{cmd: cmd} 92 93 if err := cmd.SetRootCAs(c); err != nil { 94 return err 95 } 96 97 if err := r.info.FromURL(u, t.TLSClientConfig); err != nil { 98 return err 99 } 100 101 if r.info.Err != nil && !r.cmd.Session.Insecure { 102 cmd.Out = os.Stderr 103 // using same exit code as curl: 104 defer os.Exit(60) 105 } 106 107 return r.Write(cmd.Out) 108 }