Skip to content

Commit 17bde95

Browse files
committed
initial commit
0 parents  commit 17bde95

File tree

7 files changed

+1316
-0
lines changed

7 files changed

+1316
-0
lines changed

.gitignore

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Compiled Object files, Static and Dynamic libs (Shared Objects)
2+
*.o
3+
*.a
4+
*.so
5+
6+
# Folders
7+
_obj
8+
_test
9+
10+
# Architecture specific extensions/prefixes
11+
*.[568vq]
12+
[568vq].out
13+
14+
*.cgo1.go
15+
*.cgo2.c
16+
_cgo_defun.c
17+
_cgo_gotypes.go
18+
_cgo_export.*
19+
20+
_testmain.go
21+
22+
*.exe
23+
*.test
24+
*.prof
25+
moolticute_ssh-agent

LICENSE

+674
Large diffs are not rendered by default.

Makefile

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
APPNAME = moolticute-cli
3+
4+
TAGS = ""
5+
BUILD_FLAGS = "-v"
6+
7+
.PHONY: build clean
8+
9+
build: $(GENERATED)
10+
go install $(BUILD_FLAGS) -ldflags '$(LDFLAGS)' -tags '$(TAGS)'
11+
cp '$(GOPATH)/bin/$(APPNAME)' .
12+
13+
clean:
14+
go clean -i ./...
15+
16+

README.md

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
Moolticute CLI tool
2+
====================
3+
4+
[![License](https://img.shields.io/badge/license-GPLv3%2B-blue.svg)](http://www.gnu.org/licenses/gpl.html)
5+
6+
This tool is a command line tool to interact with a running moolticute daemon. It allows to retrieve credentials from a CLI.
7+
8+
### Installation ###
9+
10+
Install go if needed. Add `$GOPATH/bin` to your path.
11+
12+
```
13+
go get github.com/raoulh/moolticute-cli
14+
```
15+
16+
### Usage ###
17+
18+
```
19+
moolticute-cli --help
20+
```
21+
22+
> Warning! This project is a work in progress!

cmd.go

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"encoding/base64"
6+
"fmt"
7+
"io/ioutil"
8+
"os"
9+
)
10+
11+
const (
12+
maxFileSize = 524288
13+
)
14+
15+
func processLoginCmd(subCmd, context, login, pwd, desc string, printDesc bool) (err error) {
16+
17+
m := &MoolticuteMsg{
18+
Data: MsgData{
19+
Service: context,
20+
Login: login,
21+
},
22+
}
23+
24+
if subCmd == "get" {
25+
m.Msg = "get_credential"
26+
} else if subCmd == "set" {
27+
m.Msg = "set_credential"
28+
m.Data.Password = pwd
29+
m.Data.Description = desc
30+
}
31+
32+
res, err := McSendQuery(m)
33+
if err != nil {
34+
return err
35+
}
36+
37+
if subCmd == "get" {
38+
if printDesc {
39+
fmt.Println(res.Description)
40+
} else {
41+
fmt.Println(res.Password)
42+
}
43+
} else if subCmd == "set" {
44+
fmt.Println(green(CharCheck), "Done")
45+
}
46+
47+
return
48+
}
49+
50+
func processDataCmd(subCmd, context, filename string, progressFunc ProgressCb) (err error) {
51+
52+
m := &MoolticuteMsg{
53+
Data: MsgData{
54+
Service: context,
55+
},
56+
}
57+
58+
if subCmd == "get" {
59+
m.Msg = "get_data_node"
60+
} else if subCmd == "set" {
61+
m.Msg = "set_data_node"
62+
63+
//open file and encode to base64
64+
finfo, err := os.Stat(filename)
65+
if err != nil {
66+
return fmt.Errorf("Failed to get file info: %v", err)
67+
}
68+
if finfo.Size() > maxFileSize {
69+
return fmt.Errorf("File is too big for beeing saved into the mooltipass :(")
70+
}
71+
72+
b, err := ioutil.ReadFile(filename)
73+
if err != nil {
74+
return fmt.Errorf("Failed to read file: %v", err)
75+
}
76+
77+
m.Data.NodeData = base64.StdEncoding.EncodeToString(b)
78+
}
79+
80+
res, err := McSendQueryProgress(m, progressFunc)
81+
if err != nil {
82+
return err
83+
}
84+
85+
if subCmd == "get" {
86+
//decode the base64
87+
bdec, err := base64.StdEncoding.DecodeString(res.NodeData)
88+
if err != nil {
89+
err = fmt.Errorf("Failed to base64 decode data:", err)
90+
return err
91+
}
92+
93+
b := bytes.NewBuffer(bdec)
94+
b.WriteTo(os.Stdout)
95+
96+
} else if subCmd == "set" {
97+
fmt.Println(green(CharCheck), "Done")
98+
}
99+
100+
return
101+
}

main.go

+165
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
// +build go1.7
2+
3+
package main
4+
5+
import (
6+
"fmt"
7+
"io/ioutil"
8+
"log"
9+
"os"
10+
"runtime"
11+
12+
"github.com/fatih/color"
13+
"github.com/jawher/mow.cli"
14+
"github.com/k-takata/go-iscygpty"
15+
"github.com/mattn/go-isatty"
16+
"github.com/raoulh/go-progress"
17+
)
18+
19+
const (
20+
CharStar = "\u2737"
21+
CharAbort = "\u2718"
22+
CharCheck = "\u2714"
23+
CharWarning = "\u26A0"
24+
CharArrow = "\u2012\u25b6"
25+
CharVertLine = "\u2502"
26+
)
27+
28+
var (
29+
blue = color.New(color.FgBlue).SprintFunc()
30+
errorRed = color.New(color.FgRed).SprintFunc()
31+
errorBgRed = color.New(color.BgRed, color.FgBlack).SprintFunc()
32+
green = color.New(color.FgGreen).SprintFunc()
33+
cyan = color.New(color.FgCyan).SprintFunc()
34+
bgCyan = color.New(color.FgWhite).SprintFunc()
35+
)
36+
37+
var (
38+
mcUrl *string
39+
debugOpt *bool
40+
41+
optContext *string
42+
optLogin *string
43+
optPass *string
44+
optDesc *string
45+
optPrintDesc *bool
46+
optFilename *string
47+
48+
isTerminal bool
49+
progressBar *progress.ProgressBar
50+
)
51+
52+
func exit(err error, exit int) {
53+
fmt.Fprintln(os.Stderr, errorRed(CharAbort), err)
54+
cli.Exit(exit)
55+
}
56+
57+
func checkLog() {
58+
if !*debugOpt {
59+
//completely disable debug output
60+
log.SetFlags(0)
61+
log.SetOutput(ioutil.Discard)
62+
}
63+
}
64+
65+
func addDefaultArgs(cmd *cli.Cmd) {
66+
mcUrl = cmd.StringOpt("m moolticute_url", MOOLTICUTE_DAEMON_URL, "Use a different url for connecting to moolticute")
67+
debugOpt = cmd.BoolOpt("debug", false, "Add debug log to stdout")
68+
}
69+
70+
func main() {
71+
runtime.GOMAXPROCS(runtime.NumCPU())
72+
73+
// fix for cygwin terminal
74+
if iscygpty.IsCygwinPty(os.Stdout.Fd()) || isatty.IsTerminal(os.Stdout.Fd()) {
75+
color.NoColor = false
76+
isTerminal = true
77+
}
78+
79+
app := cli.App("moolticute-cli", "Command line tool to interact with a mooltipass device through a moolticute daemon")
80+
81+
app.Command("login", "Manage credentials stored in the device", func(cmd *cli.Cmd) {
82+
cmd.Command("get", "Get a password for given context", func(cmd *cli.Cmd) {
83+
optContext = cmd.StringArg("CONTEXT", "", "Context to work on")
84+
optLogin = cmd.StringArg("LOGIN", "", "Login to use")
85+
addDefaultArgs(cmd)
86+
optPrintDesc = cmd.BoolOpt("d description", false, "Output service description instead of password")
87+
cmd.Spec = "CONTEXT LOGIN [OPTIONS]"
88+
89+
cmd.Action = func() {
90+
checkLog()
91+
92+
if err := processLoginCmd("get", *optContext, *optLogin, "", "", *optPrintDesc); err != nil {
93+
exit(err, 1)
94+
}
95+
}
96+
})
97+
cmd.Command("set", "Add or update a context", func(cmd *cli.Cmd) {
98+
optContext = cmd.StringArg("CONTEXT", "", "Context to work on")
99+
optLogin = cmd.StringArg("LOGIN", "", "Login to set")
100+
optPass = cmd.StringArg("PASS", "", "Password to set")
101+
optDesc = cmd.StringArg("DESC", "", "Description to set")
102+
addDefaultArgs(cmd)
103+
cmd.Spec = "CONTEXT LOGIN PASS [DESC] [OPTIONS]"
104+
105+
cmd.Action = func() {
106+
checkLog()
107+
108+
if err := processLoginCmd("set", *optContext, *optLogin, *optPass, *optDesc, false); err != nil {
109+
exit(err, 1)
110+
}
111+
}
112+
})
113+
})
114+
115+
app.Command("data", "Import & export small files stored in the device", func(cmd *cli.Cmd) {
116+
cmd.Command("get", "Retrieve data for given context", func(cmd *cli.Cmd) {
117+
optContext = cmd.StringArg("CONTEXT", "", "Context to work on")
118+
addDefaultArgs(cmd)
119+
cmd.Spec = "CONTEXT [OPTIONS]"
120+
121+
cmd.Action = func() {
122+
checkLog()
123+
124+
if err := processDataCmd("get", *optContext, "", progressFunc); err != nil {
125+
exit(err, 1)
126+
}
127+
}
128+
})
129+
cmd.Command("set", "Add or update data for given context", func(cmd *cli.Cmd) {
130+
optContext = cmd.StringArg("CONTEXT", "", "Context to work on")
131+
optFilename = cmd.StringArg("FILENAME", "", "File to save in the device")
132+
addDefaultArgs(cmd)
133+
cmd.Spec = "CONTEXT FILENAME [OPTIONS]"
134+
135+
cmd.Action = func() {
136+
checkLog()
137+
138+
if err := processDataCmd("set", *optContext, *optFilename, progressFunc); err != nil {
139+
exit(err, 1)
140+
}
141+
}
142+
})
143+
})
144+
145+
app.Command("parameters", "Get/Set device parameters", func(cmd *cli.Cmd) {
146+
checkLog()
147+
})
148+
149+
if err := app.Run(os.Args); err != nil {
150+
exit(err, 1)
151+
}
152+
}
153+
154+
func progressFunc(total, current int) {
155+
if !isTerminal {
156+
return
157+
}
158+
159+
if progressBar == nil {
160+
progressBar = progress.New(total)
161+
progressBar.Format = progress.ProgressFormats[2]
162+
}
163+
164+
progressBar.Set(current)
165+
}

0 commit comments

Comments
 (0)