122 lines
3.3 KiB
Go
122 lines
3.3 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"git.julianfamily.org/keepassgo/internal/browserbridge"
|
|
)
|
|
|
|
func main() {
|
|
if len(os.Args) > 1 {
|
|
switch strings.TrimSpace(os.Args[1]) {
|
|
case "install-native-host":
|
|
if err := runInstallNativeHost(os.Args[2:]); err != nil {
|
|
fail(err)
|
|
}
|
|
return
|
|
case "status":
|
|
if err := runStatus(os.Args[2:]); err != nil {
|
|
fail(err)
|
|
}
|
|
return
|
|
}
|
|
}
|
|
if err := runNativeMessage(); err != nil {
|
|
_ = browserbridge.WriteResponse(os.Stdout, browserbridge.Response{Success: false, Error: err.Error()})
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
func runInstallNativeHost(args []string) error {
|
|
fs := flag.NewFlagSet("install-native-host", flag.ContinueOnError)
|
|
browserName := fs.String("browser", string(browserbridge.BrowserFirefox), "target browser: firefox, chrome, chromium")
|
|
binaryPath := fs.String("binary", "", "path to keepassgo-browser-bridge binary")
|
|
extensionID := fs.String("extension-id", "", "browser extension id (required for chrome/chromium)")
|
|
outputPath := fs.String("output", "", "native host manifest output path")
|
|
if err := fs.Parse(args); err != nil {
|
|
return err
|
|
}
|
|
path := strings.TrimSpace(*binaryPath)
|
|
if path == "" {
|
|
resolved, err := defaultBinaryPath()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
path = resolved
|
|
}
|
|
installed, err := browserbridge.InstallManifest(browserbridge.Browser(strings.TrimSpace(*browserName)), path, strings.TrimSpace(*extensionID), strings.TrimSpace(*outputPath))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
fmt.Fprintln(os.Stdout, installed)
|
|
return nil
|
|
}
|
|
|
|
func runStatus(args []string) error {
|
|
fs := flag.NewFlagSet("status", flag.ContinueOnError)
|
|
grpcAddr := fs.String("grpc-addr", browserbridge.DefaultGRPCAddress, "KeePassGO local gRPC address")
|
|
token := fs.String("token", "", "KeePassGO API bearer token")
|
|
if err := fs.Parse(args); err != nil {
|
|
return err
|
|
}
|
|
req := browserbridge.Request{
|
|
Action: "status",
|
|
GRPCAddress: strings.TrimSpace(*grpcAddr),
|
|
BearerToken: strings.TrimSpace(*token),
|
|
}
|
|
connCfg, err := req.Connection()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
conn, client, ctx, err := browserbridge.Dial(context.Background(), connCfg)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer func() { _ = conn.Close() }()
|
|
resp := browserbridge.HandleRequest(ctx, req, client)
|
|
enc := json.NewEncoder(os.Stdout)
|
|
enc.SetIndent("", " ")
|
|
return enc.Encode(resp)
|
|
}
|
|
|
|
func runNativeMessage() error {
|
|
req, err := browserbridge.ReadRequest(os.Stdin)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
connCfg, err := req.Connection()
|
|
if err != nil {
|
|
return browserbridge.WriteResponse(os.Stdout, browserbridge.Response{Success: false, Error: err.Error()})
|
|
}
|
|
conn, client, ctx, err := browserbridge.Dial(context.Background(), connCfg)
|
|
if err != nil {
|
|
return browserbridge.WriteResponse(os.Stdout, browserbridge.Response{Success: false, Error: err.Error()})
|
|
}
|
|
defer func() { _ = conn.Close() }()
|
|
return browserbridge.WriteResponse(os.Stdout, browserbridge.HandleRequest(ctx, req, client))
|
|
}
|
|
|
|
func defaultBinaryPath() (string, error) {
|
|
self, err := os.Executable()
|
|
if err == nil && strings.TrimSpace(self) != "" {
|
|
return self, nil
|
|
}
|
|
self, err = exec.LookPath("keepassgo-browser-bridge")
|
|
if err == nil {
|
|
return self, nil
|
|
}
|
|
return filepath.Abs("./keepassgo-browser-bridge")
|
|
}
|
|
|
|
func fail(err error) {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|