Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# https://editorconfig.org
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

[*.go]
indent_style = tab

[*.{yml,yaml}]
Comment thread
EthanHeilman marked this conversation as resolved.
indent_style = space
indent_size = 2

[*.{json,md}]
indent_style = space
indent_size = 2
Comment thread
EthanHeilman marked this conversation as resolved.

[*.sh]
indent_style = space
indent_size = 2

[Makefile]
indent_style = tab
17 changes: 13 additions & 4 deletions commands/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ type LoginCmd struct {
ProviderArg string // OpenID Provider specification in the format: <issuer>,<client_id> or <issuer>,<client_id>,<client_secret> or <issuer>,<client_id>,<client_secret>,<scopes>
ProviderAliasArg string
KeyTypeArg KeyType
PrintKeyArg bool // Print private key and SSH cert instead of writing them to the filesystem
PrintKeyArg bool // Print the raw private key and SSH cert to stdout instead of writing them to the filesystem
InspectCertArg bool // Display a human-readable inspection of the generated SSH certificate (public information only)
SSHConfigured bool
Verbosity int // Default verbosity is 0, 1 is verbose, 2 is debug
RemoteRedirectURI string
Expand All @@ -117,7 +118,7 @@ type LoginCmd struct {
func NewLogin(autoRefreshArg bool, configPathArg string, createConfigArg bool, configureArg bool, logDirArg string,
sendAccessTokenArg bool, disableBrowserOpenArg bool, printIdTokenArg bool,
providerArg string, printKeyArg bool, keyPathArg string, providerAliasArg string, keyTypeArg KeyType,
remoteRedirectUri string,
remoteRedirectUri string, inspectCertArg bool,
) *LoginCmd {
return &LoginCmd{
Fs: afero.NewOsFs(),
Expand All @@ -132,6 +133,7 @@ func NewLogin(autoRefreshArg bool, configPathArg string, createConfigArg bool, c
KeyPathArg: keyPathArg,
ProviderArg: providerArg,
PrintKeyArg: printKeyArg,
InspectCertArg: inspectCertArg,
ProviderAliasArg: providerAliasArg,
KeyTypeArg: keyTypeArg,
RemoteRedirectURI: remoteRedirectUri,
Expand Down Expand Up @@ -511,7 +513,14 @@ func (l *LoginCmd) login(ctx context.Context, provider providers.OpenIdProvider,
return nil, fmt.Errorf("failed to format ID Token: %w", err)
}

fmt.Printf("id_token:\n%s\n", idTokenStr)
fmt.Fprintf(l.out(), "id_token:\n%s\n", idTokenStr)
}

if l.InspectCertArg {
inspect := NewInspectCmd(string(certBytes), l.out())
Comment thread
EthanHeilman marked this conversation as resolved.
if err := inspect.Run(); err != nil {
return nil, fmt.Errorf("failed to inspect SSH cert: %w", err)
}
}

idStr, err := IdentityString(*pkt)
Expand Down Expand Up @@ -865,7 +874,7 @@ func PrettyIdToken(pkt pktoken.PKToken) (string, error) {
if err != nil {
return "", err
}
idtJson, err := json.MarshalIndent(idt.GetClaims(), "", " ")
idtJson, err := json.MarshalIndent(idt.GetClaims(), "", " ")
if err != nil {
Comment thread
EthanHeilman marked this conversation as resolved.
return "", err
}
Expand Down
23 changes: 22 additions & 1 deletion commands/login_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,16 @@ func TestLoginCmd(t *testing.T) {
},
wantError: false,
},
{
name: "Good path InspectCert",
envVars: map[string]string{},
loginCmd: LoginCmd{
Verbosity: 0,
InspectCertArg: true,
LogDirArg: logDir,
},
wantError: false,
},
{
name: "Good path with SendAccessToken set in arg and config",
envVars: map[string]string{},
Expand Down Expand Up @@ -233,6 +243,17 @@ func TestLoginCmd(t *testing.T) {
require.Contains(t, gotLines[0], "cert-v01@openssh.com AAAA")
require.Contains(t, gotLines[1], "-----BEGIN OPENSSH PRIVATE KEY-----")
pubKeyBytes = []byte(gotLines[0])
} else if tt.loginCmd.InspectCertArg {
got := cliOutputBuffer.String()
require.Contains(t, got, "--- SSH Certificate Information ---")
require.Contains(t, got, "--- PKToken Structure ---")

homePath, err := os.UserHomeDir()
require.NoError(t, err)
// KeyTypeArg defaults to ECDSA so keys are written to id_ecdsa path
sshPubPath := filepath.Join(homePath, ".ssh", "id_ecdsa-cert.pub")
pubKeyBytes, err = afero.ReadFile(mockFs, sshPubPath)
require.NoError(t, err)
} else {
homePath, err := os.UserHomeDir()
require.NoError(t, err)
Expand Down Expand Up @@ -447,7 +468,7 @@ func TestNewLogin(t *testing.T) {
remoteRedirectURIArg := ""

loginCmd := NewLogin(autoRefresh, configPathArg, createConfig, configureArg, logDir,
sendAccessTokenArg, disableBrowserOpenArg, printIdTokenArg, providerArg, keyAsOutputArg, keyPathArg, providerAlias, keyTypeArg, remoteRedirectURIArg)
sendAccessTokenArg, disableBrowserOpenArg, printIdTokenArg, providerArg, keyAsOutputArg, keyPathArg, providerAlias, keyTypeArg, remoteRedirectURIArg, false)
require.NotNil(t, loginCmd)
}

Expand Down
12 changes: 10 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ Arguments:
var disableBrowserOpenArg bool
var printIdTokenArg bool
var printKeyArg bool
var inspectCertArg bool
var verboseArg bool
var keyPathArg string
var keyTypeArg commands.KeyType
var remoteRedirectURIArg string
Expand Down Expand Up @@ -188,9 +190,13 @@ Arguments:
providerAliasArg = args[0]
}

if verboseArg {
inspectCertArg = true
}
Comment thread
EthanHeilman marked this conversation as resolved.

login := commands.NewLogin(autoRefreshArg, configPathArg, createConfigArg, configureArg, logDirArg,
sendAccessTokenArg, disableBrowserOpenArg, printIdTokenArg, providerArg, printKeyArg, keyPathArg,
providerAliasArg, keyTypeArg, remoteRedirectURIArg)
providerAliasArg, keyTypeArg, remoteRedirectURIArg, inspectCertArg)
if err := login.Run(ctx); err != nil {
log.Println("Error executing login command:", err)
return err
Expand All @@ -210,7 +216,9 @@ Arguments:
loginCmd.Flags().BoolVar(&printIdTokenArg, "print-id-token", false, "Set this flag to print out the contents of the id_token. Useful for inspecting claims")
loginCmd.Flags().BoolVar(&sendAccessTokenArg, "send-access-token", false, "Set this flag to send the Access Token as well as the PK Token in the SSH cert. The Access Token is used to call the userinfo endpoint to get claims not included in the ID Token")
loginCmd.Flags().StringVar(&providerArg, "provider", "", "OpenID Provider specification in the format: <issuer>,<client_id> or <issuer>,<client_id>,<client_secret> or <issuer>,<client_id>,<client_secret>,<scopes>")
loginCmd.Flags().BoolVarP(&printKeyArg, "print-key", "p", false, "Print private key and SSH cert instead of writing them to the filesystem")
loginCmd.Flags().BoolVarP(&printKeyArg, "print-key", "p", false, "Print the raw private key and SSH cert to stdout instead of writing them to the filesystem")
loginCmd.Flags().BoolVar(&inspectCertArg, "inspect-cert", false, "Print a human-readable inspection of the generated SSH certificate (public information only)")
loginCmd.Flags().BoolVarP(&verboseArg, "verbose", "v", false, "Enable verbose output")
Comment thread
EthanHeilman marked this conversation as resolved.
loginCmd.Flags().StringVarP(&keyPathArg, "private-key-file", "i", "", "Path where private keys is written")
loginCmd.Flags().StringVar(&remoteRedirectURIArg, "remote-redirect-uri", "", "Remote redirect URI used for non-localhost redirects. This is an advanced option for embedding opkssh in server-side logic.")
loginCmd.Flags().VarP(enumflag.New(&keyTypeArg, "Key Type", map[commands.KeyType][]string{commands.ECDSA: {commands.ECDSA.String()}, commands.ED25519: {commands.ED25519.String()}}, enumflag.EnumCaseInsensitive), "key-type", "t", "Type of key to generate")
Expand Down
12 changes: 12 additions & 0 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,18 @@ func TestRun(t *testing.T) {
wantOutput: "error getting provider config for alias badalias",
wantExit: 1,
},
{
name: "Login Help flag shows inspect-cert",
args: []string{"opkssh", "login", "--help"},
wantOutput: "--inspect-cert",
wantExit: 0,
},
{
name: "Login Help flag shows verbose",
args: []string{"opkssh", "login", "--help"},
wantOutput: "-v, --verbose",
wantExit: 0,
Comment thread
EthanHeilman marked this conversation as resolved.
},
{
name: "Verify command fail on bad log file path",
args: []string{"opkssh", "verify", "arg1", "arg2", "arg3"},
Expand Down
Loading