Skip to content

Commit

Permalink
Add QR Code functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
Steve Coffman committed Jul 2, 2019
1 parent 6fe4c76 commit fa138a7
Show file tree
Hide file tree
Showing 11 changed files with 208 additions and 78 deletions.
12 changes: 0 additions & 12 deletions aws-credential-helper.sh

This file was deleted.

34 changes: 21 additions & 13 deletions cmd/add.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
/*
Copyright © 2019 NAME HERE <EMAIL ADDRESS>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
The MIT License (MIT)
Copyright © 2019 StevenACoffman
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package cmd

Expand Down
57 changes: 36 additions & 21 deletions cmd/list.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
/*
Copyright © 2019 NAME HERE <EMAIL ADDRESS>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
The MIT License (MIT)
Copyright © 2019 StevenACoffman
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package cmd

Expand Down Expand Up @@ -56,7 +64,7 @@ func parseValue(line string) string {
return ""
}

// List lists secret, identified by service, from the keyring.
// List shows secret key names, identified by service, from the keyring.
func List(service string) (string, error) {
out, err := exec.Command(
execPathKeychain,
Expand All @@ -67,13 +75,18 @@ func List(service string) (string, error) {
}
outString := string(out)

lines := strings.FieldsFunc(outString, func(r rune) bool {
parseDump(outString)

return "", nil
}

func parseDump(keychainDump string) {
lines := strings.FieldsFunc(keychainDump, func(r rune) bool {
if r == '\n' {
return true
return true
}
return false
})

classMatches := false
account := ""
serviceMatches := false
Expand All @@ -90,15 +103,17 @@ func List(service string) (string, error) {
if strings.HasPrefix(line, "class:") {
classMatches = line == "class: \"genp\""
}
if strings.HasPrefix(line," \"acct\"<blob>=\"") {
if strings.HasPrefix(line, " \"acct\"<blob>=\"") {
account = parseValue(line)
}
if strings.HasPrefix(line, " \"svce\"<blob>=\"") {
if strings.HasPrefix(line, " \"svce\"<blob>=\"") {
serviceMatches = parseValue(line) == "keyfob"
}
}

return "",nil
// if the very last one was a match, this catches it
if classMatches && serviceMatches {
fmt.Println(account)
}
}

func init() {
Expand Down
44 changes: 26 additions & 18 deletions cmd/otp.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
/*
Copyright © 2019 NAME HERE <EMAIL ADDRESS>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
The MIT License (MIT)
Copyright © 2019 StevenACoffman
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package cmd

Expand All @@ -32,7 +40,7 @@ import (
// otpCmd represents the otp command
var otpCmd = &cobra.Command{
Use: "otp [key name]",
Short: "Generate a One Time Password",
Short: "Generate a One Time Password for the named key",
Long: `otp [key name] prints a two-factor authentication code from the key with the given name.
If -clip is specified, otp also copies to the code to the system clipboard.
With no arguments, otp prints two-factor authentication codes from all known time-based keys.
Expand All @@ -43,9 +51,9 @@ so it is important that the system clock have at least one-minute accuracy.`,
Run: func(cmd *cobra.Command, args []string) {

service := "keyfob"
user := args[0]
keyName := args[0]

codeText, err := generateTOTP(service, user)
codeText, err := generateTOTP(service, keyName)
if err != nil {
log.Fatal(err)
return
Expand All @@ -60,8 +68,8 @@ so it is important that the system clock have at least one-minute accuracy.`,
},
}

func generateTOTP(service, user string) (string, error) {
secret, err := keyring.Get(service, user)
func generateTOTP(service, keyName string) (string, error) {
secret, err := keyring.Get(service, keyName)
if err != nil {
return "", err
}
Expand Down
83 changes: 83 additions & 0 deletions cmd/qr.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
The MIT License (MIT)
Copyright © 2019 StevenACoffman
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package cmd

import (
"encoding/base32"
"fmt"
"github.com/mdp/qrterminal"
"github.com/spf13/cobra"
"github.com/zalando/go-keyring"
"log"
"os"
osUser "os/user"
)

// qrCmd represents the qr command
var qrCmd = &cobra.Command{
Use: "qr [key name]",
Short: "Generate a QR Code for the named key",
Long: `qr [key name] prints a QR Code for the key with the given name.
This can be useful for backing up QR Codes to Google Authenticator or Authy or whatever.`,

Run: func(cmd *cobra.Command, args []string) {

service := "keyfob"
keyName := args[0]

err := generateQRCode(service, keyName)
if err != nil {
log.Fatal(err)
return
}
},
}

func generateQRCode(service, keyName string) error {
secret, err := keyring.Get(service, keyName)
if err != nil {
return err
}
raw, err := decodeKey(secret)
if err != nil {
return fmt.Errorf("%s: malformed key", secret)
}

currentUser, err := osUser.Current()
if err != nil {
return err
}
uri := fmt.Sprintf("otpauth://totp/%s@%s?secret=%s&issuer=%s",
keyName+ ":" + currentUser.Username,
keyName,
base32.StdEncoding.EncodeToString(raw),
keyName,
)

qrterminal.Generate(uri, qrterminal.L, os.Stderr)
return nil
}
func init() {
rootCmd.AddCommand(qrCmd)
}
2 changes: 2 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/*
The MIT License (MIT)
Copyright © 2019 StevenACoffman
Permission is hereby granted, free of charge, to any person obtaining a copy
Expand Down
28 changes: 18 additions & 10 deletions cmd/vault.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
/*
Copyright © 2019 NAME HERE <EMAIL ADDRESS>
The MIT License (MIT)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Copyright © 2019 StevenACoffman
http://www.apache.org/licenses/LICENSE-2.0
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package cmd

Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/atotto/clipboard v0.1.2
github.com/danieljoos/wincred v1.0.2 // indirect
github.com/godbus/dbus v4.1.0+incompatible // indirect
github.com/mdp/qrterminal v1.0.1
github.com/mitchellh/go-homedir v1.1.0
github.com/spf13/cobra v0.0.5
github.com/spf13/viper v1.4.0
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mdp/qrterminal v1.0.1 h1:07+fzVDlPuBlXS8tB0ktTAyf+Lp1j2+2zK3fBOL5b7c=
github.com/mdp/qrterminal v1.0.1/go.mod h1:Z33WhxQe9B6CdW37HaVqcRKzP+kByF3q/qLxOGe12xQ=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
Expand Down Expand Up @@ -158,3 +160,5 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
rsc.io/qr v0.2.0 h1:6vBLea5/NRMVTz8V66gipeLycZMl/+UlFmk8DvqQ6WY=
rsc.io/qr v0.2.0/go.mod h1:IF+uZjkb9fqyeF/4tlBoynqmQxUoPfWEKh921coOuXs=
19 changes: 15 additions & 4 deletions install.sh
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
#!/usr/bin/env bash

# Script will snarf secrets from 2fa file
# Installing kefob

if [ ! -x "$(command -v keyfob)" ]; then
echo "keyfob is not installed, so I'm going to go grab the mac one for you"
wget -O - https://github.com/StevenACoffman/keyfob/releases/download/v0.3.0/keyfob_0.3.0_Darwin_x86_64.tar.gz | tar xzvf
mkdir -p /usr/local/bin
mv keyfob /usr/local/bin
if [! -x "(command -v brew)" ]; then
KEYFOB_RELEASE='0.3.0'
echo "Homebrew is not installed, so I'm going to grab the v${KEYFOB_RELEASE} current release from github"
wget -O - "https://github.com/StevenACoffman/keyfob/releases/download/v${KEYFOB_RELEASE}/keyfob_${KEYFOB_RELEASE}_Darwin_x86_64.tar.gz" | tar xzvf
mkdir -p /usr/local/bin
mv keyfob /usr/local/bin
else
echo "Using homebrew and tapping StevenACoffman/keyfob"
brew tap StevenACoffman/keyfob
brew install keyfob
fi

fi

filename="${HOME}/.2fa"

if [ -f $filename ]; then
echo "Snarfing secrets from 2fa for you"
cat $filename | while read line
do
SIZE="$(echo $line | awk '{print $2}')"
Expand Down
Loading

0 comments on commit fa138a7

Please sign in to comment.