mirror of
https://github.com/ssh-vault/ssh-vault.git
synced 2025-07-31 05:24:22 +03:00
cache, http client, vault
This commit is contained in:
50
cache.go
Normal file
50
cache.go
Normal file
@ -0,0 +1,50 @@
|
||||
package sshvault
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type cache struct {
|
||||
dir string
|
||||
}
|
||||
|
||||
func Cache() *cache {
|
||||
usr, _ := user.Current()
|
||||
sv := filepath.Join(usr.HomeDir, ".ssh-vault", "keys")
|
||||
if _, err := os.Stat(sv); os.IsNotExist(err) {
|
||||
os.MkdirAll(sv, os.ModePerm)
|
||||
}
|
||||
return &cache{sv}
|
||||
}
|
||||
|
||||
func (c *cache) Get(u string) (string, error) {
|
||||
uKey := fmt.Sprintf("%s/%s.key", c.dir, u)
|
||||
if c.isFile(uKey) {
|
||||
// read from file and return
|
||||
}
|
||||
key, err := GetKey(u)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = ioutil.WriteFile(uKey, []byte(key), 0644)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
return key, nil
|
||||
}
|
||||
|
||||
func (c *cache) isFile(path string) bool {
|
||||
f, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if m := f.Mode(); !m.IsDir() && m.IsRegular() && m&400 != 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
@ -4,6 +4,8 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
|
||||
sv "github.com/ssh-vault/ssh-vault"
|
||||
)
|
||||
@ -11,22 +13,58 @@ import (
|
||||
var version string
|
||||
|
||||
func main() {
|
||||
parser := &sv.Parse{}
|
||||
var (
|
||||
k = flag.String("k", "~/.ssh/id_rsa.pub", "public `ssh key`")
|
||||
u = flag.String("u", "", "GitHub `username`")
|
||||
options = []string{"create", "decrypt", "edit", "encrypt", "view"}
|
||||
v = flag.Bool("v", false, fmt.Sprintf("Print version: %s", version))
|
||||
)
|
||||
|
||||
// flag set
|
||||
fs := flag.NewFlagSet(os.Args[0], flag.ExitOnError)
|
||||
fs.Usage = parser.Usage(fs)
|
||||
|
||||
err := sv.ParseArgs(parser, fs)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
flag.Usage = func() {
|
||||
fmt.Fprintf(os.Stderr, "Usage: %s [-k key] [-u user] [create|decrypt|edit|encrypt|view] vault\n\n%s\n%s\n%s\n%s\n%s\n%s\n\n",
|
||||
os.Args[0],
|
||||
" Options:",
|
||||
" create creates a new vault",
|
||||
" decrypt decrypt a file",
|
||||
" edit open an existing vault",
|
||||
" encrypt encrypt a file",
|
||||
" view open an existing vault")
|
||||
flag.PrintDefaults()
|
||||
}
|
||||
|
||||
// if -v print version
|
||||
if (fs.Lookup("v")).Value.(flag.Getter).Get().(bool) {
|
||||
flag.Parse()
|
||||
|
||||
if *v {
|
||||
fmt.Printf("%s\n", version)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
if flag.NArg() < 1 {
|
||||
fmt.Printf("Missing option, use (\"%s -h\") for help.\n", os.Args[0])
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
exit := true
|
||||
for _, v := range options {
|
||||
if flag.Arg(0) == v {
|
||||
exit = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if exit {
|
||||
fmt.Printf("Invalid option, use (\"%s -h\") for help.\n", os.Args[0])
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if flag.NArg() < 2 {
|
||||
fmt.Printf("Missing vault name, use (\"%s -h\") for help.\n", os.Args[0])
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
usr, _ := user.Current()
|
||||
if (*k)[:2] == "~/" {
|
||||
*k = filepath.Join(usr.HomeDir, (*k)[2:])
|
||||
}
|
||||
|
||||
sv.New(*k, *u, flag.Arg(0), flag.Arg(1))
|
||||
}
|
||||
|
11
flags.go
11
flags.go
@ -1,11 +0,0 @@
|
||||
package sshvault
|
||||
|
||||
// Flags available command flags
|
||||
type Flags struct {
|
||||
Version bool
|
||||
Create string
|
||||
Decrypt string
|
||||
Edit string
|
||||
Encrypt string
|
||||
View string
|
||||
}
|
35
getkey.go
Normal file
35
getkey.go
Normal file
@ -0,0 +1,35 @@
|
||||
package sshvault
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/textproto"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const GITHUB = "https://github.com"
|
||||
|
||||
func GetKey(u string) (string, error) {
|
||||
client := &http.Client{}
|
||||
// create a new request
|
||||
req, _ := http.NewRequest("GET", fmt.Sprintf("%s/%s.keys",
|
||||
GITHUB,
|
||||
u),
|
||||
nil)
|
||||
req.Header.Set("User-Agent", "ssh-vault")
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
reader := bufio.NewReader(res.Body)
|
||||
tp := textproto.NewReader(reader)
|
||||
for {
|
||||
if line, err := tp.ReadLine(); err != nil {
|
||||
return "", err
|
||||
} else if strings.HasPrefix(line, "ssh-") {
|
||||
return line, nil
|
||||
}
|
||||
}
|
||||
}
|
106
parser.go
106
parser.go
@ -1,106 +0,0 @@
|
||||
package sshvault
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// Parser interface
|
||||
type Parser interface {
|
||||
Parse(fs *flag.FlagSet) (*Flags, error)
|
||||
isDir(path string) bool
|
||||
isFile(path string) bool
|
||||
}
|
||||
|
||||
// Parse implements parser
|
||||
type Parse struct {
|
||||
Flags
|
||||
}
|
||||
|
||||
// Parse parse the command line flags
|
||||
func (p *Parse) Parse(fs *flag.FlagSet) (*Flags, error) {
|
||||
fs.BoolVar(&p.Flags.Version, "v", false, "Print version")
|
||||
fs.StringVar(&p.Flags.Create, "c", "", "create vault")
|
||||
|
||||
err := fs.Parse(os.Args[1:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &p.Flags, nil
|
||||
}
|
||||
func (p *Parse) Usage(fs *flag.FlagSet) func() {
|
||||
return func() {
|
||||
fmt.Fprintf(os.Stderr, "Usage: %s [create|decrypt|edit|encrypt|view] [-k key] [-u user] vault\n\n", os.Args[0])
|
||||
var flags []string
|
||||
fs.VisitAll(func(f *flag.Flag) {
|
||||
flags = append(flags, f.Name)
|
||||
})
|
||||
sort.Strings(flags)
|
||||
for _, v := range flags {
|
||||
f := fs.Lookup(v)
|
||||
s := fmt.Sprintf(" -%s", f.Name)
|
||||
name, usage := flag.UnquoteUsage(f)
|
||||
if len(name) > 0 {
|
||||
s += " " + name
|
||||
}
|
||||
if len(s) <= 4 {
|
||||
s += "\t"
|
||||
} else {
|
||||
s += "\n \t"
|
||||
}
|
||||
s += usage
|
||||
fmt.Fprintf(os.Stderr, "%s\n", s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Parse) isDir(path string) bool {
|
||||
f, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if m := f.Mode(); m.IsDir() && m&400 != 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *Parse) isFile(path string) bool {
|
||||
f, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if m := f.Mode(); !m.IsDir() && m.IsRegular() && m&400 != 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *Parse) checkWrkdir(dir string) (err error) {
|
||||
if !p.isDir(dir) {
|
||||
err = fmt.Errorf("-d %q does not exist or has wrong permissions, use (\"%s -h\") for help.", dir, os.Args[0])
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ParseArgs parse command arguments
|
||||
func ParseArgs(p Parser, fs *flag.FlagSet) (err error) {
|
||||
flags, err := p.Parse(fs)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// if -v
|
||||
if flags.Version {
|
||||
return
|
||||
}
|
||||
|
||||
// if no args
|
||||
if len(fs.Args()) < 1 {
|
||||
err = fmt.Errorf("Missing user, use (\"%s -h\") for help.", os.Args[0])
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
24
vault.go
Normal file
24
vault.go
Normal file
@ -0,0 +1,24 @@
|
||||
package sshvault
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Vault structure
|
||||
type Vault struct {
|
||||
key string
|
||||
user string
|
||||
option string
|
||||
vault string
|
||||
}
|
||||
|
||||
// New initialize vault parameters
|
||||
func New(k, u, o, v string) error {
|
||||
cache := Cache()
|
||||
if u != "" {
|
||||
path, err := cache.Get(u)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("path = %+v\n", path)
|
||||
}
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user