Add initial authenticated connection work
This commit is contained in:
parent
f3196863bb
commit
cf6221c080
35 changed files with 513 additions and 328 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -3,4 +3,5 @@ goldwarden
|
|||
__pycache__
|
||||
.flatpak-builder
|
||||
flatpak-pip-generator
|
||||
repo
|
||||
repo
|
||||
__debug*
|
||||
|
|
@ -10,7 +10,6 @@ import (
|
|||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
|
@ -114,7 +113,7 @@ func makeAuthenticatedHTTPRequest(ctx context.Context, req *http.Request, recv i
|
|||
return &errStatusCode{res.StatusCode, body}
|
||||
}
|
||||
if err := json.Unmarshal(body, recv); err != nil {
|
||||
fmt.Fprintln(os.Stderr, string(body))
|
||||
fmt.Println(string(body))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ type RuntimeConfig struct {
|
|||
UseMemguard bool
|
||||
SSHAgentSocketPath string
|
||||
GoldwardenSocketPath string
|
||||
DaemonAuthToken string
|
||||
}
|
||||
|
||||
type ConfigFile struct {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ type CallingContext struct {
|
|||
ParentProcessPid int
|
||||
GrandParentProcessPid int
|
||||
Error bool
|
||||
Authenticated bool
|
||||
}
|
||||
|
||||
func GetCallingContext(connection net.Conn) CallingContext {
|
||||
|
|
@ -30,6 +31,7 @@ func GetCallingContext(connection net.Conn) CallingContext {
|
|||
ParentProcessPid: 0,
|
||||
GrandParentProcessPid: 0,
|
||||
Error: true,
|
||||
Authenticated: false,
|
||||
}
|
||||
if err != nil {
|
||||
return errorContext
|
||||
|
|
|
|||
|
|
@ -65,6 +65,10 @@ func (s *SessionStore) verifySession(ctx sockets.CallingContext, sessionType Ses
|
|||
|
||||
// with session
|
||||
func GetPermission(sessionType SessionType, ctx sockets.CallingContext, config *config.Config) (bool, error) {
|
||||
if ctx.Authenticated {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
log.Info("Checking permission for " + ctx.ProcessName + " with session type " + string(sessionType))
|
||||
var actionDescription = ""
|
||||
biometricsApprovalType := biometrics.AccessVault
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import (
|
|||
"github.com/quexten/goldwarden/agent/processsecurity"
|
||||
"github.com/quexten/goldwarden/agent/sockets"
|
||||
"github.com/quexten/goldwarden/agent/ssh"
|
||||
"github.com/quexten/goldwarden/agent/systemauth"
|
||||
"github.com/quexten/goldwarden/agent/vault"
|
||||
"github.com/quexten/goldwarden/ipc/messages"
|
||||
"github.com/quexten/goldwarden/logging"
|
||||
|
|
@ -44,7 +45,7 @@ func writeError(c net.Conn, errMsg error) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func serveAgentSession(c net.Conn, ctx context.Context, vault *vault.Vault, cfg *config.Config) {
|
||||
func serveAgentSession(c net.Conn, vault *vault.Vault, cfg *config.Config) {
|
||||
for {
|
||||
buf := make([]byte, 1024*1024)
|
||||
nr, err := c.Read(buf)
|
||||
|
|
@ -61,7 +62,38 @@ func serveAgentSession(c net.Conn, ctx context.Context, vault *vault.Vault, cfg
|
|||
continue
|
||||
}
|
||||
|
||||
responseBytes := []byte{}
|
||||
if msg.Type == messages.MessageTypeForEmptyPayload(messages.SessionAuthRequest{}) {
|
||||
log.Info("Received session auth request")
|
||||
req := messages.ParsePayload(msg).(messages.SessionAuthRequest)
|
||||
fmt.Println("Daemontoken", cfg.ConfigFile.RuntimeConfig.DaemonAuthToken)
|
||||
fmt.Println("Token", req.Token)
|
||||
fmt.Println(len(cfg.ConfigFile.RuntimeConfig.DaemonAuthToken), len(req.Token))
|
||||
payload := messages.SessionAuthResponse{
|
||||
Verified: cfg.ConfigFile.RuntimeConfig.DaemonAuthToken == req.Token,
|
||||
}
|
||||
log.Info("Verified: %t", payload.Verified)
|
||||
callingContext := sockets.GetCallingContext(c)
|
||||
systemauth.CreatePinSession(callingContext)
|
||||
|
||||
responsePayload, err := messages.IPCMessageFromPayload(payload)
|
||||
if err != nil {
|
||||
writeError(c, err)
|
||||
continue
|
||||
}
|
||||
payloadBytes, err := json.Marshal(responsePayload)
|
||||
if err != nil {
|
||||
writeError(c, err)
|
||||
continue
|
||||
}
|
||||
|
||||
_, err = c.Write(payloadBytes)
|
||||
if err != nil {
|
||||
log.Error("Failed writing to socket " + err.Error())
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
var responseBytes []byte
|
||||
if action, actionFound := actions.AgentActionsRegistry.Get(msg.Type); actionFound {
|
||||
callingContext := sockets.GetCallingContext(c)
|
||||
payload, err := action(msg, cfg, vault, &callingContext)
|
||||
|
|
@ -291,7 +323,7 @@ func StartUnixAgent(path string, runtimeConfig config.RuntimeConfig) error {
|
|||
|
||||
l, err := net.Listen("unix", path)
|
||||
if err != nil {
|
||||
println("listen error", err.Error())
|
||||
fmt.Println("listen error", err.Error())
|
||||
return err
|
||||
}
|
||||
defer l.Close()
|
||||
|
|
@ -301,10 +333,11 @@ func StartUnixAgent(path string, runtimeConfig config.RuntimeConfig) error {
|
|||
for {
|
||||
fd, err := l.Accept()
|
||||
if err != nil {
|
||||
println("accept error", err.Error())
|
||||
fmt.Println("accept error", err.Error())
|
||||
}
|
||||
fmt.Println("Accepted connection")
|
||||
|
||||
go serveAgentSession(fd, ctx, vault, &cfg)
|
||||
go serveAgentSession(fd, vault, &cfg)
|
||||
}
|
||||
}()
|
||||
|
||||
|
|
|
|||
|
|
@ -10,9 +10,10 @@ import (
|
|||
)
|
||||
|
||||
var autofillCmd = &cobra.Command{
|
||||
Use: "autotype",
|
||||
Short: "Autotype credentials",
|
||||
Long: `Autotype credentials`,
|
||||
Hidden: true,
|
||||
Use: "autotype",
|
||||
Short: "Autotype credentials",
|
||||
Long: `Autotype credentials`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
username, _ := cmd.Flags().GetString("username")
|
||||
// get pasword from env
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
|
|
@ -30,12 +31,12 @@ var setApiUrlCmd = &cobra.Command{
|
|||
switch result.(type) {
|
||||
case messages.ActionResponse:
|
||||
if result.(messages.ActionResponse).Success {
|
||||
println("Done")
|
||||
fmt.Println("Done")
|
||||
} else {
|
||||
println("Setting api url failed: " + result.(messages.ActionResponse).Message)
|
||||
fmt.Println("Setting api url failed: " + result.(messages.ActionResponse).Message)
|
||||
}
|
||||
default:
|
||||
println("Wrong IPC response type")
|
||||
fmt.Println("Wrong IPC response type")
|
||||
}
|
||||
|
||||
},
|
||||
|
|
@ -63,12 +64,12 @@ var setIdentityURLCmd = &cobra.Command{
|
|||
switch result.(type) {
|
||||
case messages.ActionResponse:
|
||||
if result.(messages.ActionResponse).Success {
|
||||
println("Done")
|
||||
fmt.Println("Done")
|
||||
} else {
|
||||
println("Setting identity url failed: " + result.(messages.ActionResponse).Message)
|
||||
fmt.Println("Setting identity url failed: " + result.(messages.ActionResponse).Message)
|
||||
}
|
||||
default:
|
||||
println("Wrong IPC response type")
|
||||
fmt.Println("Wrong IPC response type")
|
||||
}
|
||||
|
||||
},
|
||||
|
|
@ -96,12 +97,12 @@ var setNotificationsURLCmd = &cobra.Command{
|
|||
switch result.(type) {
|
||||
case messages.ActionResponse:
|
||||
if result.(messages.ActionResponse).Success {
|
||||
println("Done")
|
||||
fmt.Println("Done")
|
||||
} else {
|
||||
println("Setting notifications url failed: " + result.(messages.ActionResponse).Message)
|
||||
fmt.Println("Setting notifications url failed: " + result.(messages.ActionResponse).Message)
|
||||
}
|
||||
default:
|
||||
println("Wrong IPC response type")
|
||||
fmt.Println("Wrong IPC response type")
|
||||
}
|
||||
|
||||
},
|
||||
|
|
@ -129,12 +130,12 @@ var setVaultURLCmd = &cobra.Command{
|
|||
switch result.(type) {
|
||||
case messages.ActionResponse:
|
||||
if result.(messages.ActionResponse).Success {
|
||||
println("Done")
|
||||
fmt.Println("Done")
|
||||
} else {
|
||||
println("Setting vault url failed: " + result.(messages.ActionResponse).Message)
|
||||
fmt.Println("Setting vault url failed: " + result.(messages.ActionResponse).Message)
|
||||
}
|
||||
default:
|
||||
println("Wrong IPC response type")
|
||||
fmt.Println("Wrong IPC response type")
|
||||
}
|
||||
|
||||
},
|
||||
|
|
@ -162,12 +163,12 @@ var setURLsAutomaticallyCmd = &cobra.Command{
|
|||
switch result.(type) {
|
||||
case messages.ActionResponse:
|
||||
if result.(messages.ActionResponse).Success {
|
||||
println("Done")
|
||||
fmt.Println("Done")
|
||||
} else {
|
||||
println("Setting urls automatically failed: " + result.(messages.ActionResponse).Message)
|
||||
fmt.Println("Setting urls automatically failed: " + result.(messages.ActionResponse).Message)
|
||||
}
|
||||
default:
|
||||
println("Wrong IPC response type")
|
||||
fmt.Println("Wrong IPC response type")
|
||||
}
|
||||
|
||||
},
|
||||
|
|
@ -188,14 +189,15 @@ var getEnvironmentCmd = &cobra.Command{
|
|||
|
||||
switch result := result.(type) {
|
||||
case messages.GetConfigEnvironmentResponse:
|
||||
fmt.Println("{")
|
||||
fmt.Println(" \"api\": \"" + result.ApiURL + "\",")
|
||||
fmt.Println(" \"identity\": \"" + result.IdentityURL + "\",")
|
||||
fmt.Println(" \"notifications\": \"" + result.NotificationsURL + "\",")
|
||||
fmt.Println(" \"vault\": \"" + result.VaultURL + "\"")
|
||||
fmt.Println("}")
|
||||
response := map[string]string{}
|
||||
response["api"] = result.ApiURL
|
||||
response["identity"] = result.IdentityURL
|
||||
response["notifications"] = result.NotificationsURL
|
||||
response["vault"] = result.VaultURL
|
||||
responseJSON, _ := json.Marshal(response)
|
||||
fmt.Println(string(responseJSON))
|
||||
default:
|
||||
println("Wrong IPC response type")
|
||||
fmt.Println("Wrong IPC response type")
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
@ -226,12 +228,12 @@ var setApiClientIDCmd = &cobra.Command{
|
|||
switch result.(type) {
|
||||
case messages.ActionResponse:
|
||||
if result.(messages.ActionResponse).Success {
|
||||
println("Done")
|
||||
fmt.Println("Done")
|
||||
} else {
|
||||
println("Setting api client id failed: " + result.(messages.ActionResponse).Message)
|
||||
fmt.Println("Setting api client id failed: " + result.(messages.ActionResponse).Message)
|
||||
}
|
||||
default:
|
||||
println("Wrong IPC response type")
|
||||
fmt.Println("Wrong IPC response type")
|
||||
}
|
||||
|
||||
},
|
||||
|
|
@ -263,12 +265,12 @@ var setApiSecretCmd = &cobra.Command{
|
|||
switch result.(type) {
|
||||
case messages.ActionResponse:
|
||||
if result.(messages.ActionResponse).Success {
|
||||
println("Done")
|
||||
fmt.Println("Done")
|
||||
} else {
|
||||
println("Setting api secret failed: " + result.(messages.ActionResponse).Message)
|
||||
fmt.Println("Setting api secret failed: " + result.(messages.ActionResponse).Message)
|
||||
}
|
||||
default:
|
||||
println("Wrong IPC response type")
|
||||
fmt.Println("Wrong IPC response type")
|
||||
}
|
||||
|
||||
},
|
||||
|
|
@ -289,13 +291,14 @@ var getRuntimeConfigCmd = &cobra.Command{
|
|||
|
||||
switch result := result.(type) {
|
||||
case messages.GetRuntimeConfigResponse:
|
||||
fmt.Println("{")
|
||||
fmt.Println(" \"useMemguard\": " + fmt.Sprintf("%t", result.UseMemguard) + ",")
|
||||
fmt.Println(" \"SSHAgentSocketPath\": \"" + result.SSHAgentSocketPath + "\",")
|
||||
fmt.Println(" \"goldwardenSocketPath\": \"" + result.GoldwardenSocketPath + "\"")
|
||||
fmt.Println("}")
|
||||
response := map[string]interface{}{}
|
||||
response["useMemguard"] = result.UseMemguard
|
||||
response["SSHAgentSocketPath"] = result.SSHAgentSocketPath
|
||||
response["goldwardenSocketPath"] = result.GoldwardenSocketPath
|
||||
responseJSON, _ := json.Marshal(response)
|
||||
fmt.Println(string(responseJSON))
|
||||
default:
|
||||
println("Wrong IPC response type")
|
||||
fmt.Println("Wrong IPC response type")
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,11 +19,11 @@ var daemonizeCmd = &cobra.Command{
|
|||
sshDisabled := runtimeConfig.DisableSSHAgent
|
||||
|
||||
if websocketDisabled {
|
||||
println("Websocket disabled")
|
||||
fmt.Println("Websocket disabled")
|
||||
}
|
||||
|
||||
if sshDisabled {
|
||||
println("SSH agent disabled")
|
||||
fmt.Println("SSH agent disabled")
|
||||
}
|
||||
|
||||
cleanup := func() {
|
||||
|
|
|
|||
10
cmd/login.go
10
cmd/login.go
|
|
@ -4,6 +4,8 @@ Copyright © 2023 NAME HERE <EMAIL ADDRESS>
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/quexten/goldwarden/ipc/messages"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
|
@ -17,7 +19,7 @@ var loginCmd = &cobra.Command{
|
|||
request := messages.DoLoginRequest{}
|
||||
email, _ := cmd.Flags().GetString("email")
|
||||
if email == "" {
|
||||
println("Error: No email specified")
|
||||
fmt.Println("Error: No email specified")
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -34,12 +36,12 @@ var loginCmd = &cobra.Command{
|
|||
switch result.(type) {
|
||||
case messages.ActionResponse:
|
||||
if result.(messages.ActionResponse).Success {
|
||||
println("Logged in")
|
||||
fmt.Println("Logged in")
|
||||
} else {
|
||||
println("Login failed: " + result.(messages.ActionResponse).Message)
|
||||
fmt.Println("Login failed: " + result.(messages.ActionResponse).Message)
|
||||
}
|
||||
default:
|
||||
println("Wrong IPC response type for login")
|
||||
fmt.Println("Wrong IPC response type for login")
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ var getLoginCmd = &cobra.Command{
|
|||
}
|
||||
break
|
||||
case messages.ActionResponse:
|
||||
println("Error: " + resp.(messages.ActionResponse).Message)
|
||||
fmt.Println("Error: " + resp.(messages.ActionResponse).Message)
|
||||
return
|
||||
}
|
||||
},
|
||||
|
|
|
|||
12
cmd/pin.go
12
cmd/pin.go
|
|
@ -1,6 +1,8 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/quexten/goldwarden/ipc/messages"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
|
@ -25,12 +27,12 @@ var setPinCmd = &cobra.Command{
|
|||
switch result.(type) {
|
||||
case messages.ActionResponse:
|
||||
if result.(messages.ActionResponse).Success {
|
||||
println("Pin updated")
|
||||
fmt.Println("Pin updated")
|
||||
} else {
|
||||
println("Pin updating failed: " + result.(messages.ActionResponse).Message)
|
||||
fmt.Println("Pin updating failed: " + result.(messages.ActionResponse).Message)
|
||||
}
|
||||
default:
|
||||
println("Wrong response type")
|
||||
fmt.Println("Wrong response type")
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
@ -48,9 +50,9 @@ var pinStatusCmd = &cobra.Command{
|
|||
|
||||
switch result.(type) {
|
||||
case messages.ActionResponse:
|
||||
println("Pin status: " + result.(messages.ActionResponse).Message)
|
||||
fmt.Println("Pin status: " + result.(messages.ActionResponse).Message)
|
||||
default:
|
||||
println("Wrong response type")
|
||||
fmt.Println("Wrong response type")
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/quexten/goldwarden/agent"
|
||||
|
|
@ -62,8 +63,8 @@ func loginIfRequired() error {
|
|||
|
||||
func handleSendToAgentError(err error) {
|
||||
if err != nil {
|
||||
println("Error: " + err.Error())
|
||||
println("Is the daemon running?")
|
||||
fmt.Println("Error: " + err.Error())
|
||||
fmt.Println("Is the daemon running?")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ Copyright © 2023 NAME HERE <EMAIL ADDRESS>
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
|
|
@ -19,7 +20,7 @@ var runCmd = &cobra.Command{
|
|||
The variables are stored as a secure note. Consult the documentation for more information.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if len(args) < 1 {
|
||||
println("Error: No command specified")
|
||||
fmt.Println("Error: No command specified")
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -43,7 +44,7 @@ var runCmd = &cobra.Command{
|
|||
env = append(env, key+"="+value)
|
||||
}
|
||||
case messages.ActionResponse:
|
||||
println("Error: " + result.(messages.ActionResponse).Message)
|
||||
fmt.Println("Error: " + result.(messages.ActionResponse).Message)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ var sendCreateCmd = &cobra.Command{
|
|||
fmt.Println("Send created: " + result.(messages.CreateSendResponse).URL)
|
||||
break
|
||||
case messages.ActionResponse:
|
||||
println("Error: " + result.(messages.ActionResponse).Message)
|
||||
fmt.Println("Error: " + result.(messages.ActionResponse).Message)
|
||||
return
|
||||
}
|
||||
},
|
||||
|
|
|
|||
60
cmd/session.go
Normal file
60
cmd/session.go
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/quexten/goldwarden/ipc/messages"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// sessionCmd represents the run command
|
||||
var sessionCmd = &cobra.Command{
|
||||
Use: "session",
|
||||
Hidden: true,
|
||||
Short: "Starts a new session",
|
||||
Long: `Starts a new session.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
for {
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
text, _ := reader.ReadString('\n')
|
||||
text = strings.TrimSuffix(text, "\n")
|
||||
args := strings.Split(text, " ")
|
||||
rootCmd.SetArgs(args)
|
||||
rootCmd.Execute()
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
var pinentry = &cobra.Command{
|
||||
Use: "pinentry",
|
||||
Hidden: true,
|
||||
Short: "Registers as a pinentry program",
|
||||
Long: `Registers as a pinentry program.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
var authenticateSession = &cobra.Command{
|
||||
Use: "authenticate-session",
|
||||
Hidden: true,
|
||||
Short: "Authenticates a session",
|
||||
Long: `Authenticates a session.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
token := args[0]
|
||||
response, err := commandClient.SendToAgent(messages.SessionAuthRequest{Token: token})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println(response.(messages.SessionAuthResponse).Verified)
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(sessionCmd)
|
||||
rootCmd.AddCommand(pinentry)
|
||||
rootCmd.AddCommand(authenticateSession)
|
||||
}
|
||||
|
|
@ -47,7 +47,7 @@ var sshAddCmd = &cobra.Command{
|
|||
}
|
||||
break
|
||||
case messages.ActionResponse:
|
||||
println("Error: " + result.(messages.ActionResponse).Message)
|
||||
fmt.Println("Error: " + result.(messages.ActionResponse).Message)
|
||||
return
|
||||
}
|
||||
},
|
||||
|
|
@ -74,7 +74,7 @@ var listSSHCmd = &cobra.Command{
|
|||
}
|
||||
break
|
||||
case messages.ActionResponse:
|
||||
println("Error: " + result.(messages.ActionResponse).Message)
|
||||
fmt.Println("Error: " + result.(messages.ActionResponse).Message)
|
||||
return
|
||||
}
|
||||
},
|
||||
|
|
|
|||
40
cmd/vault.go
40
cmd/vault.go
|
|
@ -1,6 +1,7 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
|
|
@ -30,12 +31,12 @@ var unlockCmd = &cobra.Command{
|
|||
switch result.(type) {
|
||||
case messages.ActionResponse:
|
||||
if result.(messages.ActionResponse).Success {
|
||||
println("Unlocked")
|
||||
fmt.Println("Unlocked")
|
||||
} else {
|
||||
println("Not unlocked: " + result.(messages.ActionResponse).Message)
|
||||
fmt.Println("Not unlocked: " + result.(messages.ActionResponse).Message)
|
||||
}
|
||||
default:
|
||||
println("Wrong response type")
|
||||
fmt.Println("Wrong response type")
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
@ -56,12 +57,12 @@ var lockCmd = &cobra.Command{
|
|||
switch result.(type) {
|
||||
case messages.ActionResponse:
|
||||
if result.(messages.ActionResponse).Success {
|
||||
println("Locked")
|
||||
fmt.Println("Locked")
|
||||
} else {
|
||||
println("Not locked: " + result.(messages.ActionResponse).Message)
|
||||
fmt.Println("Not locked: " + result.(messages.ActionResponse).Message)
|
||||
}
|
||||
default:
|
||||
println("Wrong response type")
|
||||
fmt.Println("Wrong response type")
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
@ -82,12 +83,12 @@ var purgeCmd = &cobra.Command{
|
|||
switch result.(type) {
|
||||
case messages.ActionResponse:
|
||||
if result.(messages.ActionResponse).Success {
|
||||
println("Purged")
|
||||
fmt.Println("Purged")
|
||||
} else {
|
||||
println("Not purged: " + result.(messages.ActionResponse).Message)
|
||||
fmt.Println("Not purged: " + result.(messages.ActionResponse).Message)
|
||||
}
|
||||
default:
|
||||
println("Wrong response type")
|
||||
fmt.Println("Wrong response type")
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
@ -107,18 +108,19 @@ var statusCmd = &cobra.Command{
|
|||
|
||||
switch result.(type) {
|
||||
case messages.VaultStatusResponse:
|
||||
response := map[string]interface{}{}
|
||||
status := result.(messages.VaultStatusResponse)
|
||||
fmt.Println("{")
|
||||
fmt.Println(" \"locked\":", status.Locked, ",")
|
||||
fmt.Println(" \"loginEntries\":", status.NumberOfLogins, ",")
|
||||
fmt.Println(" \"noteEntries\":", status.NumberOfNotes, ",")
|
||||
fmt.Println(" \"lastSynced\": \"" + time.Unix(status.LastSynced, 0).String() + "\",")
|
||||
fmt.Println(" \"websocketConnected\":", status.WebsockedConnected, ",")
|
||||
fmt.Println(" \"pinSet\":", status.PinSet, ",")
|
||||
fmt.Println(" \"loggedIn\":", status.LoggedIn)
|
||||
fmt.Println("}")
|
||||
response["locked"] = status.Locked
|
||||
response["loginEntries"] = status.NumberOfLogins
|
||||
response["noteEntries"] = status.NumberOfNotes
|
||||
response["lastSynced"] = time.Unix(status.LastSynced, 0).String()
|
||||
response["websocketConnected"] = status.WebsockedConnected
|
||||
response["pinSet"] = status.PinSet
|
||||
response["loggedIn"] = status.LoggedIn
|
||||
responseJSON, _ := json.Marshal(response)
|
||||
fmt.Println(string(responseJSON))
|
||||
default:
|
||||
println("Wrong response type")
|
||||
fmt.Println("Wrong response type")
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
|||
31
ipc/messages/session.go
Normal file
31
ipc/messages/session.go
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
package messages
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
type SessionAuthRequest struct {
|
||||
Token string
|
||||
}
|
||||
|
||||
type SessionAuthResponse struct {
|
||||
Verified bool
|
||||
}
|
||||
|
||||
func init() {
|
||||
registerPayloadParser(func(payload []byte) (interface{}, error) {
|
||||
var req SessionAuthRequest
|
||||
err := json.Unmarshal(payload, &req)
|
||||
if err != nil {
|
||||
panic("Unmarshal: " + err.Error())
|
||||
}
|
||||
return req, nil
|
||||
}, SessionAuthRequest{})
|
||||
|
||||
registerPayloadParser(func(payload []byte) (interface{}, error) {
|
||||
var req SessionAuthResponse
|
||||
err := json.Unmarshal(payload, &req)
|
||||
if err != nil {
|
||||
panic("Unmarshal: " + err.Error())
|
||||
}
|
||||
return req, nil
|
||||
}, SessionAuthResponse{})
|
||||
}
|
||||
4
main.go
4
main.go
|
|
@ -1,6 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
|
|
@ -36,6 +37,7 @@ func main() {
|
|||
UseMemguard: os.Getenv("GOLDWARDEN_NO_MEMGUARD") != "true",
|
||||
SSHAgentSocketPath: os.Getenv("GOLDWARDEN_SSH_AUTH_SOCK"),
|
||||
GoldwardenSocketPath: os.Getenv("GOLDWARDEN_SOCKET_PATH"),
|
||||
DaemonAuthToken: os.Getenv("GOLDWARDEN_DAEMON_AUTH_TOKEN"),
|
||||
|
||||
ConfigDirectory: configPath,
|
||||
}
|
||||
|
|
@ -62,7 +64,7 @@ func main() {
|
|||
userHome, _ := os.UserHomeDir()
|
||||
runtimeConfig.ConfigDirectory = userHome + "/.var/app/com.quexten.Goldwarden/config/goldwarden.json"
|
||||
runtimeConfig.ConfigDirectory = strings.ReplaceAll(runtimeConfig.ConfigDirectory, "~", userHome)
|
||||
println("Flatpak Config directory: " + runtimeConfig.ConfigDirectory)
|
||||
fmt.Println("Flatpak Config directory: " + runtimeConfig.ConfigDirectory)
|
||||
runtimeConfig.SSHAgentSocketPath = userHome + "/.var/app/com.quexten.Goldwarden/data/ssh-auth-sock"
|
||||
runtimeConfig.GoldwardenSocketPath = userHome + "/.var/app/com.quexten.Goldwarden/data/goldwarden.sock"
|
||||
}
|
||||
|
|
|
|||
184
ui/goldwarden.py
184
ui/goldwarden.py
|
|
@ -1,184 +0,0 @@
|
|||
import subprocess
|
||||
import json
|
||||
import os
|
||||
|
||||
# if flatpak
|
||||
if os.path.exists("/app/bin/goldwarden"):
|
||||
BINARY_PATH = "/app/bin/goldwarden"
|
||||
else:
|
||||
res = subprocess.run(["which", "goldwarden"])
|
||||
BINARY_PATH = res.stdout.decode("utf-8").strip()
|
||||
|
||||
def set_api_url(url):
|
||||
restic_cmd = f"{BINARY_PATH} config set-api-url {url}"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
|
||||
def set_identity_url(url):
|
||||
restic_cmd = f"{BINARY_PATH} config set-identity-url {url}"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
|
||||
def set_notification_url(url):
|
||||
restic_cmd = f"{BINARY_PATH} config set-notifications-url {url}"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
|
||||
def set_vault_url(url):
|
||||
restic_cmd = f"{BINARY_PATH} config set-vault-url {url}"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed err", result.stderr)
|
||||
|
||||
def set_url(url):
|
||||
restic_cmd = f"{BINARY_PATH} config set-url {url}"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed err", result.stderr)
|
||||
|
||||
def get_environment():
|
||||
restic_cmd = f"{BINARY_PATH} config get-environment"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
return None
|
||||
try:
|
||||
result_text = result.stdout
|
||||
print(result_text)
|
||||
return json.loads(result_text)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return None
|
||||
|
||||
def set_client_id(client_id):
|
||||
restic_cmd = f"{BINARY_PATH} config set-client-id \"{client_id}\""
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed err", result.stderr)
|
||||
|
||||
def set_client_secret(client_secret):
|
||||
restic_cmd = f"{BINARY_PATH} config set-client-secret \"{client_secret}\""
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed err", result.stderr)
|
||||
|
||||
def login_with_password(email, password):
|
||||
restic_cmd = f"{BINARY_PATH} vault login --email {email}"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
if len(result.stderr.strip()) > 0:
|
||||
print(result.stderr)
|
||||
if "password" in result.stderr:
|
||||
return "badpass"
|
||||
else:
|
||||
if "Logged in" in result.stderr:
|
||||
print("ok")
|
||||
return "ok"
|
||||
return "error"
|
||||
print("ok")
|
||||
return "ok"
|
||||
|
||||
def login_passwordless(email):
|
||||
restic_cmd = f"{BINARY_PATH} vault login --email {email} --passwordless"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
|
||||
def is_pin_enabled():
|
||||
restic_cmd = f"{BINARY_PATH} vault pin status"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
# check if contains enabled
|
||||
return "enabled" in result.stderr
|
||||
|
||||
def enable_pin():
|
||||
restic_cmd = f"{BINARY_PATH} vault pin set"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
|
||||
def unlock():
|
||||
restic_cmd = f"{BINARY_PATH} vault unlock"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
|
||||
def lock():
|
||||
restic_cmd = f"{BINARY_PATH} vault lock"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
|
||||
def purge():
|
||||
restic_cmd = f"{BINARY_PATH} vault purge"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
|
||||
def get_vault_status():
|
||||
restic_cmd = f"{BINARY_PATH} vault status"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
try:
|
||||
return json.loads(result.stdout)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return None
|
||||
|
||||
def get_vault_logins():
|
||||
restic_cmd = f"{BINARY_PATH} logins list"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
try:
|
||||
return json.loads(result.stdout)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return None
|
||||
|
||||
def get_runtime_config():
|
||||
restic_cmd = f"{BINARY_PATH} config get-runtime-config"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
return None
|
||||
try:
|
||||
return json.loads(result.stdout)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return None
|
||||
|
||||
def autotype(username, password):
|
||||
# environment
|
||||
env = os.environ.copy()
|
||||
env["PASSWORD"] = password
|
||||
restic_cmd = f"{BINARY_PATH} autotype --username {username}"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True, env=env)
|
||||
print(result.stderr)
|
||||
print(result.stdout)
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
|
||||
def is_daemon_running():
|
||||
restic_cmd = f"{BINARY_PATH} vault status"
|
||||
result = subprocess.run(restic_cmd.split(), capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
return False
|
||||
daemon_not_running = ("daemon running?" in result.stderr or "daemon running" in result.stderr)
|
||||
return not daemon_not_running
|
||||
|
||||
def run_daemon():
|
||||
restic_cmd = f"{BINARY_PATH} daemonize"
|
||||
# print while running
|
||||
result = subprocess.Popen(restic_cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
if result.returncode != 0:
|
||||
print("Failed err", result.stderr)
|
||||
for line in result.stdout:
|
||||
print(line.decode("utf-8"))
|
||||
result.wait()
|
||||
print("quitting goldwarden daemon")
|
||||
return result.returncode
|
||||
53
ui/main.py
53
ui/main.py
|
|
@ -1,53 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
import time
|
||||
import subprocess
|
||||
from tendo import singleton
|
||||
import monitors.dbus_autofill_monitor
|
||||
import sys
|
||||
import goldwarden
|
||||
from threading import Thread
|
||||
import os
|
||||
|
||||
isflatpak = os.path.exists("/.flatpak-info")
|
||||
pathprefix = "/app/bin/" if isflatpak else "./"
|
||||
|
||||
try:
|
||||
subprocess.Popen(["python3", f'{pathprefix}background.py'], start_new_session=True)
|
||||
except:
|
||||
pass
|
||||
|
||||
is_hidden = "--hidden" in sys.argv
|
||||
|
||||
if not is_hidden:
|
||||
try:
|
||||
subprocess.Popen(["python3", f'{pathprefix}settings.py'], start_new_session=True)
|
||||
except:
|
||||
subprocess.Popen(["python3", f'{pathprefix}settings.py'], start_new_session=True)
|
||||
pass
|
||||
|
||||
try:
|
||||
me = singleton.SingleInstance()
|
||||
except:
|
||||
exit()
|
||||
|
||||
def run_daemon():
|
||||
# todo: do a proper check
|
||||
if is_hidden:
|
||||
time.sleep(20)
|
||||
print("IS daemon running", goldwarden.is_daemon_running())
|
||||
if not goldwarden.is_daemon_running():
|
||||
print("running daemon")
|
||||
goldwarden.run_daemon()
|
||||
print("daemon running")
|
||||
|
||||
thread = Thread(target=run_daemon)
|
||||
thread.start()
|
||||
|
||||
def on_autofill():
|
||||
subprocess.Popen(["python3", f'{pathprefix}autofill.py'], start_new_session=True)
|
||||
|
||||
monitors.dbus_autofill_monitor.on_autofill = lambda: on_autofill()
|
||||
monitors.dbus_autofill_monitor.run_daemon()
|
||||
|
||||
while True:
|
||||
time.sleep(60)
|
||||
3
ui/src/goldwarden_ui_main.py
Normal file
3
ui/src/goldwarden_ui_main.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import linux.main as linux_main
|
||||
|
||||
linux_main.main()
|
||||
59
ui/src/linux/main.py
Normal file
59
ui/src/linux/main.py
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
#!/usr/bin/python
|
||||
import time
|
||||
import subprocess
|
||||
from tendo import singleton
|
||||
from .monitors import dbus_autofill_monitor
|
||||
from .monitors import dbus_monitor
|
||||
import sys
|
||||
from services import goldwarden
|
||||
from threading import Thread
|
||||
import os
|
||||
import secrets
|
||||
import time
|
||||
import os
|
||||
|
||||
root_path = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir, os.pardir))
|
||||
|
||||
def main():
|
||||
token = secrets.token_hex(32)
|
||||
print("token", token)
|
||||
if not os.environ.get("GOLDWARDEN_DAEMON_AUTH_TOKEN") == None:
|
||||
token = os.environ["GOLDWARDEN_DAEMON_AUTH_TOKEN"]
|
||||
|
||||
# check if already running
|
||||
try:
|
||||
me = singleton.SingleInstance()
|
||||
except:
|
||||
import dbus
|
||||
|
||||
bus = dbus.SessionBus()
|
||||
the_object = bus.get_objeect("com.quexten.Goldwarden.dbus", "/com/quexten/Goldwarden")
|
||||
the_interface = dbus.Interface(the_object, "com.quexten.Goldwarden.Settings")
|
||||
reply = the_interface.settings()
|
||||
exit()
|
||||
|
||||
# start daemons
|
||||
dbus_autofill_monitor.run_daemon() # todo: remove after migration
|
||||
dbus_monitor.run_daemon(token)
|
||||
|
||||
if not "--hidden" in sys.argv:
|
||||
subprocess.Popen(["python3", "-m", "src.ui.settings"], cwd=root_path, start_new_session=True)
|
||||
|
||||
# try:
|
||||
# subprocess.Popen(["python3", f'{source_path}/background.py'], start_new_session=True)
|
||||
# except Exception as e:
|
||||
# pass
|
||||
|
||||
while True:
|
||||
time.sleep(60)
|
||||
|
||||
|
||||
# def run_daemon():
|
||||
# # todo: do a proper check
|
||||
# if is_hidden:
|
||||
# time.sleep(20)
|
||||
# print("IS daemon running", goldwarden.is_daemon_running())
|
||||
# if not goldwarden.is_daemon_running():
|
||||
# print("running daemon")
|
||||
# goldwarden.run_daemon()
|
||||
# print("daemon running")
|
||||
|
|
@ -19,8 +19,13 @@ class GoldwardenDBUSService(dbus.service.Object):
|
|||
on_autofill()
|
||||
return ""
|
||||
|
||||
def run_daemon():
|
||||
def daemon():
|
||||
DBusGMainLoop(set_as_default=True)
|
||||
service = GoldwardenDBUSService()
|
||||
from gi.repository import GLib, GObject as gobject
|
||||
gobject.MainLoop().run()
|
||||
|
||||
def run_daemon():
|
||||
thread = Thread(target=daemon)
|
||||
thread.start()
|
||||
|
||||
41
ui/src/linux/monitors/dbus_monitor.py
Normal file
41
ui/src/linux/monitors/dbus_monitor.py
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
from gi.repository import Gtk
|
||||
import dbus
|
||||
import dbus.service
|
||||
from dbus.mainloop.glib import DBusGMainLoop
|
||||
from threading import Thread
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
root_path = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir, os.pardir, os.pardir))
|
||||
daemon_token = None
|
||||
|
||||
class GoldwardenDBUSService(dbus.service.Object):
|
||||
def __init__(self):
|
||||
bus_name = dbus.service.BusName('com.quexten.Goldwarden.ui', bus=dbus.SessionBus())
|
||||
dbus.service.Object.__init__(self, bus_name, '/com/quexten/Goldwarden/ui')
|
||||
|
||||
@dbus.service.method('com.quexten.Goldwarden.ui.QuickAccess')
|
||||
def quickaccess(self):
|
||||
p = subprocess.Popen(["python3", "-m", "src.ui.quickaccess"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, cwd=root_path, start_new_session=True)
|
||||
print("writing token")
|
||||
p.stdin.write(f"{daemon_token}\n".encode())
|
||||
p.stdin.flush()
|
||||
print("reading token")
|
||||
return ""
|
||||
|
||||
@dbus.service.method('com.quexten.Goldwarden.ui.Settings')
|
||||
def settings(self):
|
||||
subprocess.Popen(["python3", "-m", "src.ui.settings"], cwd=root_path, start_new_session=True)
|
||||
return ""
|
||||
|
||||
def daemon():
|
||||
DBusGMainLoop(set_as_default=True)
|
||||
service = GoldwardenDBUSService()
|
||||
from gi.repository import GLib, GObject as gobject
|
||||
gobject.MainLoop().run()
|
||||
|
||||
def run_daemon(token):
|
||||
global daemon_token
|
||||
daemon_token = token
|
||||
thread = Thread(target=daemon)
|
||||
thread.start()
|
||||
159
ui/src/services/goldwarden.py
Normal file
159
ui/src/services/goldwarden.py
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
import subprocess
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
BINARY_PATHS = [
|
||||
"/app/bin/goldwarden",
|
||||
"/usr/bin/goldwarden",
|
||||
str(Path.home()) + "/go/src/github.com/quexten/goldwarden/goldwarden"
|
||||
]
|
||||
|
||||
authenticated_connection = None
|
||||
|
||||
def create_authenticated_connection(token):
|
||||
global authenticated_connection
|
||||
BINARY_PATH = None
|
||||
for path in BINARY_PATHS:
|
||||
if os.path.exists(path):
|
||||
BINARY_PATH = path
|
||||
break
|
||||
if BINARY_PATH == None:
|
||||
raise Exception("Could not find goldwarden binary")
|
||||
authenticated_connection = subprocess.Popen([f"{BINARY_PATH}", "session"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
|
||||
if not token == None:
|
||||
authenticated_connection.stdin.write("authenticate-session " + token + "\n")
|
||||
authenticated_connection.stdin.flush()
|
||||
# read entire message
|
||||
result = authenticated_connection.stdout.readline()
|
||||
if "true" not in result:
|
||||
raise Exception("Failed to authenticate")
|
||||
|
||||
def send_authenticated_command(cmd):
|
||||
if authenticated_connection == None:
|
||||
print("No daemon connection running, please restart the application completely.")
|
||||
return ""
|
||||
|
||||
print("sending command", cmd)
|
||||
authenticated_connection.stdin.write(cmd + "\n")
|
||||
authenticated_connection.stdin.flush()
|
||||
result = authenticated_connection.stdout.readline()
|
||||
print("result", result)
|
||||
return result
|
||||
|
||||
def set_api_url(url):
|
||||
send_authenticated_command(f"config set-api-url {url}")
|
||||
|
||||
def set_identity_url(url):
|
||||
send_authenticated_command(f"config set-identity-url {url}")
|
||||
|
||||
def set_notification_url(url):
|
||||
send_authenticated_command(f"config set-notifications-url {url}")
|
||||
|
||||
def set_vault_url(url):
|
||||
send_authenticated_command(f"config set-vault-url {url}")
|
||||
|
||||
def set_url(url):
|
||||
send_authenticated_command(f"config set-url {url}")
|
||||
|
||||
def get_environment():
|
||||
result = send_authenticated_command(f"config get-environment")
|
||||
try:
|
||||
return json.loads(result)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return None
|
||||
|
||||
def set_client_id(client_id):
|
||||
send_authenticated_command(f"config set-client-id \"{client_id}\"")
|
||||
|
||||
def set_client_secret(client_secret):
|
||||
send_authenticated_command(f"config set-client-secret \"{client_secret}\"")
|
||||
|
||||
def login_with_password(email, password):
|
||||
result = send_authenticated_command(f"vault login --email {email}")
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
if len(result.stderr.strip()) > 0:
|
||||
print(result.stderr)
|
||||
if "password" in result.stderr:
|
||||
return "badpass"
|
||||
else:
|
||||
if "Logged in" in result.stderr:
|
||||
print("ok")
|
||||
return "ok"
|
||||
return "error"
|
||||
print("ok")
|
||||
return "ok"
|
||||
|
||||
def login_passwordless(email):
|
||||
send_authenticated_command(f"vault login --email {email} --passwordless")
|
||||
|
||||
def is_pin_enabled():
|
||||
result = send_authenticated_command("vault pin status")
|
||||
return "enabled" in result
|
||||
|
||||
def enable_pin():
|
||||
send_authenticated_command(f"vault pin set")
|
||||
|
||||
def unlock():
|
||||
send_authenticated_command(f"vault unlock")
|
||||
|
||||
def lock():
|
||||
send_authenticated_command(f"vault lock")
|
||||
|
||||
def purge():
|
||||
send_authenticated_command(f"vault purge")
|
||||
|
||||
def get_vault_status():
|
||||
result = send_authenticated_command(f"vault status")
|
||||
try:
|
||||
return json.loads(result)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return None
|
||||
|
||||
def get_vault_logins():
|
||||
result = send_authenticated_command(f"logins list")
|
||||
if result.returncode != 0:
|
||||
raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
try:
|
||||
return json.loads(result)
|
||||
except Exception as e:
|
||||
return None
|
||||
|
||||
def get_runtime_config():
|
||||
result = send_authenticated_command(f"config get-runtime-config")
|
||||
print(result)
|
||||
try:
|
||||
return json.loads(result)
|
||||
except Exception as e:
|
||||
return None
|
||||
|
||||
# def autotype(username, password):
|
||||
# # environment
|
||||
# env = os.environ.copy()
|
||||
# env["PASSWORD"] = password
|
||||
# restic_cmd = f"{BINARY_PATH} autotype --username {username}"
|
||||
# result = subprocess.run(restic_cmd.split(), capture_output=True, text=True, env=env)
|
||||
# print(result.stderr)
|
||||
# print(result.stdout)
|
||||
# if result.returncode != 0:
|
||||
# raise Exception("Failed to initialize repository, err", result.stderr)
|
||||
|
||||
def is_daemon_running():
|
||||
result = send_authenticated_command(f"vault status")
|
||||
daemon_not_running = ("daemon running" in result)
|
||||
return not daemon_not_running
|
||||
|
||||
# def run_daemon():
|
||||
# restic_cmd = f"daemonize"
|
||||
# # print while running
|
||||
# result = subprocess.Popen(restic_cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
# if result.returncode != 0:
|
||||
# print("Failed err", result.stderr)
|
||||
# for line in result.stdout:
|
||||
# print(line.decode("utf-8"))
|
||||
# result.wait()
|
||||
# print("quitting goldwarden daemon")
|
||||
# return result.returncode
|
||||
|
|
@ -4,14 +4,17 @@ gi.require_version('Adw', '1')
|
|||
import gc
|
||||
import time
|
||||
from gi.repository import Gtk, Adw, GLib, Notify, Gdk
|
||||
import goldwarden
|
||||
import clipboard
|
||||
from ..services import goldwarden
|
||||
from ..linux import clipboard
|
||||
from threading import Thread
|
||||
import sys
|
||||
import os
|
||||
import totp
|
||||
from ..services import totp
|
||||
Notify.init("Goldwarden")
|
||||
|
||||
token = sys.stdin.readline()
|
||||
goldwarden.create_authenticated_connection(token)
|
||||
|
||||
class MyApp(Adw.Application):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
|
@ -85,6 +88,9 @@ class MainWindow(Gtk.ApplicationWindow):
|
|||
|
||||
keycont = Gtk.EventControllerKey()
|
||||
def handle_keypress(cotroller, keyval, keycode, state, user_data):
|
||||
# if ctrl is pressed
|
||||
if state == 4:
|
||||
print("ctrl")
|
||||
if keycode == 36:
|
||||
print("enter")
|
||||
self.hide()
|
||||
|
|
@ -130,7 +136,8 @@ class MainWindow(Gtk.ApplicationWindow):
|
|||
self.history_list.get_style_context().add_class("boxed-list")
|
||||
self.box.append(self.history_list)
|
||||
self.set_default_size(700, 700)
|
||||
self.set_title("Goldwarden")
|
||||
# self.set_title("Goldwarden")
|
||||
self.set_title(token)
|
||||
|
||||
app = MyApp(application_id="com.quexten.Goldwarden.autofill-menu")
|
||||
app.run(sys.argv)
|
||||
|
|
@ -6,12 +6,14 @@ gi.require_version('Adw', '1')
|
|||
import gc
|
||||
|
||||
from gi.repository import Gtk, Adw, GLib, Gdk
|
||||
import goldwarden
|
||||
from ..services import goldwarden
|
||||
from threading import Thread
|
||||
import subprocess
|
||||
import components
|
||||
from . import components
|
||||
import os
|
||||
|
||||
goldwarden.create_authenticated_connection(None)
|
||||
|
||||
class SettingsWinvdow(Gtk.ApplicationWindow):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
|
@ -201,6 +203,7 @@ class SettingsWinvdow(Gtk.ApplicationWindow):
|
|||
|
||||
pin_set = goldwarden.is_pin_enabled()
|
||||
status = goldwarden.get_vault_status()
|
||||
print("status", status)
|
||||
runtimeCfg = goldwarden.get_runtime_config()
|
||||
if runtimeCfg != None:
|
||||
self.ssh_row.set_subtitle("Listening at "+runtimeCfg["SSHAgentSocketPath"])
|
||||
Loading…
Reference in a new issue