Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #42 RADIUS authentication support for push, append, challenge/response modes #48

Merged
merged 10 commits into from
Jan 15, 2021
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Current products supported:

- [Install](#install)
- [MacOS](#macos)
- [Windows & Linux](#windows-or-linux)
- [Windows or Linux](#windows-or-linux)
- [Usage](#usage)
- [Command-Line Interface (CLI)](#command-line-interface-cli)
- [logon](#logon)
Expand Down Expand Up @@ -101,7 +101,7 @@ $ cybr logon -u username -a cyberark-or-ldap -b https://pvwa.example.com
|-b|--base-url|☑||URL to /PasswordVault|https://pvwa.example.com|
|-i|--insecure-tls||false|Whether to validate TLS|false|

Logon to the PAS REST API as the username you provide using the authentication method you choose. At this time, only `cyberark` and `ldap` authentication methods are supported.
Logon to the PAS REST API as the username you provide using the authentication method you choose. At this time, only `cyberark`, `ldap`, `radius` authentication methods are supported. If your RADIUS server is configured for challenge/response, you will first be prompted for your `password` followed by your `one-time passcode`.

Upon successful logon, a file will be created in your user's home directory at `.cybr/config`. It is an encoded file that cannot be read in plain-text. This holds your current session information.

Expand Down
8 changes: 2 additions & 6 deletions cmd/logoff.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,13 @@ var logoffCmd = &cobra.Command{
if err != nil {
log.Fatalf("Failed to read configuration file. %s", err)
}
// Logoff the PAS REST API
err = client.Logoff()
if err != nil {
log.Fatalf("Failed to log off. %s", err)
return
}
// Remove the config file written to local file system
err = client.RemoveConfig()
if err != nil {
log.Fatalf("Failed to remove configuration file. %s", err)
}
// Logoff the PAS REST API
_ = client.Logoff()
infamousjoeg marked this conversation as resolved.
Show resolved Hide resolved

fmt.Println("Successfully logged off PAS.")
},
Expand Down
25 changes: 21 additions & 4 deletions cmd/logon.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cmd
import (
"fmt"
"log"
"strings"
"syscall"

pasapi "github.com/infamousjoeg/cybr-cli/pkg/cybr/api"
Expand Down Expand Up @@ -53,9 +54,25 @@ var logonCmd = &cobra.Command{
}

err = client.Logon(credentials)
if err != nil {
if err != nil && !strings.Contains(err.Error(), "ITATS542I") {
log.Fatalf("Failed to Logon to the PVWA. %s", err)
return
}

// if error contains challenge error code, deal with OTPCode here instead and redo client.Logon()
if err != nil {
// Get secret value from STDIN
fmt.Print("Enter one-time passcode: ")
byteOTPCode, err := terminal.ReadPassword(int(syscall.Stdin))
credentials.Password = string(byteOTPCode)
fmt.Println()
if err != nil {
log.Fatalln("An error occurred trying to read one-time passcode from " +
"Stdin. Exiting...")
}
err = client.Logon(credentials)
if err != nil {
log.Fatalf("Failed to respond to challenge. Possible timeout occurred. %s", err)
}
}

err = client.SetConfig()
Expand All @@ -71,10 +88,10 @@ var logonCmd = &cobra.Command{
func init() {
logonCmd.Flags().StringVarP(&Username, "username", "u", "", "Username to logon PAS REST API using")
logonCmd.MarkFlagRequired("username")
logonCmd.Flags().StringVarP(&AuthenticationType, "auth-type", "a", "", "Authentication method to logon using")
logonCmd.Flags().StringVarP(&AuthenticationType, "auth-type", "a", "", "Authentication method to logon using [cyberark|ldap|radius]")
logonCmd.MarkFlagRequired("authType")
logonCmd.Flags().BoolVarP(&InsecureTLS, "insecure-tls", "i", false, "If detected, TLS will not be verified")
logonCmd.Flags().StringVarP(&BaseURL, "base-url", "b", "", "Base URL to send Logon request to")
logonCmd.Flags().StringVarP(&BaseURL, "base-url", "b", "", "Base URL to send Logon request to [https://pvwa.example.com]")
logonCmd.MarkFlagRequired("base-url")
rootCmd.AddCommand(logonCmd)
}
1 change: 1 addition & 0 deletions pkg/cybr/api/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ func (c *Client) Logon(req LogonRequest) error {
return err
}

// Handle cyberark, ldap, and radius push, append & challenge/response authentication methods
url := fmt.Sprintf("%s/PasswordVault/api/auth/%s/logon", c.BaseURL, c.AuthType)
token, err := httpJson.SendRequestRaw(url, "POST", "", req, c.InsecureTLS, c.Logger)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion pkg/cybr/api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func getUserHomeDir() (string, error) {

// IsValid checks to make sure that the authentication method chosen is valid
func (c *Client) IsValid() error {
if c.AuthType == "cyberark" || c.AuthType == "ldap" {
if c.AuthType == "cyberark" || c.AuthType == "ldap" || c.AuthType == "radius" {
return nil
}
return fmt.Errorf("Invalid auth type '%s'", c.AuthType)
Expand Down