// Retrieves OTP from user and validates it with Vault server. Also, if -verify // option is chosen, a echo request message is sent to Vault instead of OTP. If // a proper echo message is responded, the verification will be successful. func Run(args []string) error { for _, arg := range args { if arg == "-v" || arg == "-version" || arg == "--version" { fmt.Println(formattedVersion()) return nil } } var configFilePath string var verify bool flags := flag.NewFlagSet("ssh-helper", flag.ContinueOnError) flags.StringVar(&configFilePath, "config-file", "", "") flags.BoolVar(&verify, "verify", false, "") flags.Usage = func() { fmt.Printf("%s\n", Help()) os.Exit(0) } if err := flags.Parse(args); err != nil { return err } args = flags.Args() if configFilePath == "" { return fmt.Errorf("missing config-file") } // Load the configuration for this helper config, err := api.LoadSSHAgentConfig(configFilePath) if err != nil { return err } // Get an http client to interact with Vault server based on the configuration client, err := config.NewClient() if err != nil { return err } // Logging SSH mount point since SSH backend mount point at Vault server // can vary and helper has no way of knowing it automatically. Agent reads // the mount point from the configuration file and uses the same to talk // to Vault. In case of errors, this can be used for debugging. // // If mount point is not mentioned in the config file, default mount point // of the SSH backend will be used. log.Printf("[INFO] Using SSH Mount point: %s", config.SSHMountPoint) var otp string if verify { otp = api.VerifyEchoRequest } else { // Reading the one-time-password from the prompt. This is enabled // by supplying 'expose_authtok' option to pam module config. otpBytes, err := ioutil.ReadAll(os.Stdin) if err != nil { return err } // Removing the terminator otp = strings.TrimSuffix(string(otpBytes), string('\x00')) } // If OTP is echo request, this will be a verify request. Otherwise, this // will be a OTP validation request. return helper.VerifyOTP(&helper.SSHVerifyRequest{ Client: client, MountPoint: config.SSHMountPoint, OTP: otp, Config: config, }) }
// Retrieves OTP from user and validates it with Vault server. Also, if -verify // option is chosen, a echo request message is sent to Vault instead of OTP. If // a proper echo message is responded, the verification will be successful. func Run(args []string) error { for _, arg := range args { if arg == "version" || arg == "-v" || arg == "-version" || arg == "--version" { fmt.Println(formattedVersion()) return nil } } var config string var dev, verifyOnly bool flags := flag.NewFlagSet("ssh-helper", flag.ContinueOnError) flags.StringVar(&config, "config", "", "") flags.BoolVar(&verifyOnly, "verify-only", false, "") flags.BoolVar(&dev, "dev", false, "") flags.Usage = func() { fmt.Printf("%s\n", Help()) os.Exit(0) } if err := flags.Parse(args); err != nil { return err } args = flags.Args() if len(config) == 0 { return fmt.Errorf("at least one config path must be specified with -config") } // Load the configuration for this helper clientConfig, err := api.LoadSSHHelperConfig(config) if err != nil { return err } if dev { log.Printf("==> WARNING: Dev mode is enabled!") if strings.HasPrefix(strings.ToLower(clientConfig.VaultAddr), "https://") { return fmt.Errorf("unsupported scheme in 'dev' mode") } clientConfig.CACert = "" clientConfig.CAPath = "" } else if strings.HasPrefix(strings.ToLower(clientConfig.VaultAddr), "http://") { return fmt.Errorf("unsupported scheme. use 'dev' mode") } // Get an http client to interact with Vault server based on the configuration client, err := clientConfig.NewClient() if err != nil { return err } // Logging SSH mount point since SSH backend mount point at Vault server // can vary and helper has no way of knowing it automatically. ssh-helper reads // the mount point from the configuration file and uses the same to talk // to Vault. In case of errors, this can be used for debugging. // // If mount point is not mentioned in the config file, default mount point // of the SSH backend will be used. log.Printf("[INFO] using SSH mount point: %s", clientConfig.SSHMountPoint) var otp string if verifyOnly { otp = api.VerifyEchoRequest } else { // Reading the one-time-password from the prompt. This is enabled // by supplying 'expose_authtok' option to pam module config. otpBytes, err := ioutil.ReadAll(os.Stdin) if err != nil { return err } // Removing the terminator otp = strings.TrimSuffix(string(otpBytes), string('\x00')) } // If OTP is echo request, this will be a verify request. Otherwise, this // will be a OTP validation request. return helper.VerifyOTP(&helper.SSHVerifyRequest{ Client: client, MountPoint: clientConfig.SSHMountPoint, OTP: otp, Config: clientConfig, }) }