rename Namespace -> Vault

mv into seperate file
This commit is contained in:
2024-10-10 12:15:26 +02:00
parent e6d05290fc
commit 069fdf8215
5 changed files with 384 additions and 354 deletions

View File

@@ -37,8 +37,8 @@ var listCmd = &cobra.Command{
} }
var names []string var names []string
namespace := "root" vault := "root"
err = client.Call("Query.GetAllNames", &namespace, &names) err = client.Call("Query.GetAllNames", &vault, &names)
if err != nil { if err != nil {
Logger.Error(err) Logger.Error(err)
@@ -67,14 +67,14 @@ var generateCmd = &cobra.Command{
serviceName := args[0] serviceName := args[0]
var password *crypto.Password var password *crypto.Password
np := rpc.NamespaceService{ Namespace: "root", Service: serviceName } np := rpc.VaultService{ Vault: "root", Service: serviceName }
err = client.Call("Query.Generate", &np, &password) err = client.Call("Query.Generate", &np, &password)
if err != nil { if err != nil {
Logger.Error(err) Logger.Error(err)
} }
Logger.Info(*password) Logger.Info(password.Password)
}, },
} }
@@ -94,7 +94,7 @@ var showCmd = &cobra.Command{
serviceName := args[0] serviceName := args[0]
var password *crypto.Password var password *crypto.Password
np := rpc.NamespaceService{ Namespace: "root", Service: serviceName } np := rpc.VaultService{ Vault: "root", Service: serviceName }
err = client.Call("Query.Get", &np, &password) err = client.Call("Query.Get", &np, &password)
if err != nil { if err != nil {
@@ -106,14 +106,14 @@ var showCmd = &cobra.Command{
}, },
} }
var namespaceCmd = &cobra.Command{ var vaultCmd = &cobra.Command{
Use: "namespace", Use: "vault",
Short: "Add, delete or list namespaces", Short: "Add, delete or list vaults",
} }
var addNamespaceCmd = &cobra.Command{ var addVaultCmd = &cobra.Command{
Use: "add", Use: "add",
Short: "add a namespace", Short: "add a vault",
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
dbPath, _ := cmd.Flags().GetString("db") dbPath, _ := cmd.Flags().GetString("db")
@@ -124,23 +124,23 @@ var addNamespaceCmd = &cobra.Command{
return return
} }
namespace := args[0] vault := args[0]
var placeholder int var placeholder int
err = client.Call("Query.AddNamespace", &namespace, &placeholder) err = client.Call("Query.AddVault", &vault, &placeholder)
if err != nil { if err != nil {
Logger.Error(err) Logger.Error(err)
return return
} }
Logger.Infof("Namespace %s was added\n", namespace) Logger.Infof("Vault %s was added\n", vault)
}, },
} }
var deleteNamespaceCmd = &cobra.Command{ var deleteVaultCmd = &cobra.Command{
Use: "delete", Use: "delete",
Short: "delete a namespace", Short: "delete a vault",
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
dbPath, _ := cmd.Flags().GetString("db") dbPath, _ := cmd.Flags().GetString("db")
@@ -151,23 +151,23 @@ var deleteNamespaceCmd = &cobra.Command{
return return
} }
namespace := args[0] vault := args[0]
var placeholder int var placeholder int
err = client.Call("Query.DeleteNamespace", &namespace, &placeholder) err = client.Call("Query.DeleteVault", &vault, &placeholder)
if err != nil { if err != nil {
Logger.Error(err) Logger.Error(err)
return return
} }
Logger.Infof("Namespace %s was deleted\n", namespace) Logger.Infof("Vault %s was deleted\n", vault)
}, },
} }
var listNamespacesCmd = &cobra.Command{ var listVaultsCmd = &cobra.Command{
Use: "list", Use: "list",
Short: "list all namespaces", Short: "list all vaults",
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
dbPath, _ := cmd.Flags().GetString("db") dbPath, _ := cmd.Flags().GetString("db")
client, err := rpc.Receive(dbPath) client, err := rpc.Receive(dbPath)
@@ -178,14 +178,14 @@ var listNamespacesCmd = &cobra.Command{
} }
var reply []string var reply []string
err = client.Call("Query.ListNamespaces", 0, &reply) err = client.Call("Query.ListVaults", 0, &reply)
if err != nil { if err != nil {
Logger.Error(err) Logger.Error(err)
return return
} }
Logger.Info("Namespaces:") Logger.Info("Vaults:")
for _, ns := range reply { for _, ns := range reply {
Logger.Info(ns) Logger.Info(ns)
} }
@@ -230,19 +230,19 @@ var addPeerCmd = &cobra.Command{
return return
} }
var namespace string var vault string
var peerString string var peerString string
if len(args) == 1 { if len(args) == 1 {
namespace = "root" vault = "root"
peerString = args[0] peerString = args[0]
} else { } else {
namespace = args[0] vault = args[0]
peerString = args[1] peerString = args[1]
} }
var success *bool var success *bool
np := rpc.NamespacePeer{ Namespace: namespace, Peer: peerString } np := rpc.VaultPeer{ Vault: vault, Peer: peerString }
err = client.Call("Query.AddPeer", &np, &success) err = client.Call("Query.AddPeer", &np, &success)
if err != nil { if err != nil {
@@ -250,7 +250,11 @@ var addPeerCmd = &cobra.Command{
return return
} }
Logger.Info(*success) if *success {
Logger.Infof("Added peer: %s", peerString)
} else {
Logger.Infof("Could not add peer: %s", peerString)
}
}, },
} }
@@ -267,19 +271,19 @@ var removePeerCmd = &cobra.Command{
return return
} }
var namespace string var vault string
var peerString string var peerString string
if len(args) == 1 { if len(args) == 1 {
namespace = "root" vault = "root"
peerString = args[0] peerString = args[0]
} else { } else {
namespace = args[0] vault = args[0]
peerString = args[1] peerString = args[1]
} }
var success *bool var success *bool
np := rpc.NamespacePeer{ Namespace: namespace, Peer: peerString } np := rpc.VaultPeer{ Vault: vault, Peer: peerString }
err = client.Call("Query.DeletePeer", &np, &success) err = client.Call("Query.DeletePeer", &np, &success)
if err != nil { if err != nil {
@@ -287,7 +291,11 @@ var removePeerCmd = &cobra.Command{
return return
} }
Logger.Info(*success) if *success {
Logger.Infof("Removed peer: %s", peerString)
} else {
Logger.Infof("Could not find peer: %s", peerString)
}
}, },
} }
@@ -304,26 +312,30 @@ var deleteCmd = &cobra.Command{
return return
} }
var namespace string var vault string
var serviceName string var serviceName string
if len(args) == 1 { if len(args) == 1 {
namespace = "root" vault = "root"
serviceName = args[0] serviceName = args[0]
} else { } else {
namespace = args[0] vault = args[0]
serviceName = args[1] serviceName = args[1]
} }
var success *bool var success *bool
np := rpc.NamespaceService{ Namespace: namespace, Service: serviceName } np := rpc.VaultService{ Vault: vault, Service: serviceName }
err = client.Call("Query.Delete", &np, &success) err = client.Call("Query.Delete", &np, &success)
if err != nil { if err != nil {
Logger.Error(err) Logger.Error(err)
} }
Logger.Info(*success) if *success {
Logger.Infof("Deleted password: %s", serviceName)
} else {
Logger.Infof("Could not find password: %s", serviceName)
}
}, },
} }
@@ -336,20 +348,20 @@ func init() {
peerCmd.AddCommand(removePeerCmd) peerCmd.AddCommand(removePeerCmd)
peerCmd.AddCommand(infoCmd) peerCmd.AddCommand(infoCmd)
namespaceCmd.AddCommand(addNamespaceCmd) vaultCmd.AddCommand(addVaultCmd)
namespaceCmd.AddCommand(deleteNamespaceCmd) vaultCmd.AddCommand(deleteVaultCmd)
namespaceCmd.AddCommand(listNamespacesCmd) vaultCmd.AddCommand(listVaultsCmd)
rootCmd.AddCommand(listCmd) rootCmd.AddCommand(listCmd)
rootCmd.AddCommand(generateCmd) rootCmd.AddCommand(generateCmd)
rootCmd.AddCommand(showCmd) rootCmd.AddCommand(showCmd)
rootCmd.AddCommand(deleteCmd) rootCmd.AddCommand(deleteCmd)
rootCmd.AddCommand(peerCmd) rootCmd.AddCommand(peerCmd)
rootCmd.AddCommand(namespaceCmd) rootCmd.AddCommand(vaultCmd)
} }
func main() { func main() {
InitLogger(true) InitLogger(false)
if err := rootCmd.Execute(); err != nil { if err := rootCmd.Execute(); err != nil {
Logger.Error(err) Logger.Error(err)
os.Exit(1) os.Exit(1)

View File

@@ -85,10 +85,10 @@ func main() {
storageHandler.Config = Cfg storageHandler.Config = Cfg
storageHandler.ConfigPath = configPath storageHandler.ConfigPath = configPath
Logger.Infof("Setting up Namespaces...") Logger.Infof("Setting up Vaults...")
storageHandler.InitNamespaces() storageHandler.InitVaults()
for _, val := range storageHandler.Namespaces { for _, val := range storageHandler.Vaults {
defer val.Close() defer val.Close()
} }

View File

@@ -20,21 +20,21 @@ var StorageHandler *storage.StorageHandler
type Query int type Query int
type NamespaceService struct { type VaultService struct {
Namespace string Vault string
Service string Service string
} }
type NamespacePeer struct { type VaultPeer struct {
Namespace string Vault string
Peer string Peer string
} }
func (t *Query) Generate(np *NamespaceService, reply *crypto.Password) error { func (t *Query) Generate(np *VaultService, reply *crypto.Password) error {
val, ok := StorageHandler.Namespaces[np.Namespace] val, ok := StorageHandler.Vaults[np.Vault]
if !ok { if !ok {
return fmt.Errorf("Namespace does not exist") return fmt.Errorf("Vault does not exist")
} }
password := crypto.NewPassword(crypto.DEFAULT_LENGTH) password := crypto.NewPassword(crypto.DEFAULT_LENGTH)
@@ -59,12 +59,12 @@ func (t *Query) Generate(np *NamespaceService, reply *crypto.Password) error {
return nil return nil
} }
func (t *Query) Get(np *NamespaceService, reply *crypto.Password) error { func (t *Query) Get(np *VaultService, reply *crypto.Password) error {
namespace := np.Namespace vault := np.Vault
val, ok := StorageHandler.Namespaces[namespace] val, ok := StorageHandler.Vaults[vault]
if !ok { if !ok {
return fmt.Errorf("Namespace does not exist") return fmt.Errorf("Vault does not exist")
} }
v, err := val.GetPassword(np.Service) v, err := val.GetPassword(np.Service)
@@ -85,12 +85,12 @@ func (t *Query) GetPeerString(_ *int, result *string) error {
return nil return nil
} }
func (t *Query) AddPeer(np *NamespacePeer, success *bool) error { func (t *Query) AddPeer(np *VaultPeer, success *bool) error {
namespace := np.Namespace vault := np.Vault
val, ok := StorageHandler.Namespaces[namespace] val, ok := StorageHandler.Vaults[vault]
if !ok { if !ok {
return fmt.Errorf("Namespace does not exist") return fmt.Errorf("Vault does not exist")
} }
peer, err := storage.PeerFromString(np.Peer) peer, err := storage.PeerFromString(np.Peer)
@@ -107,12 +107,12 @@ func (t *Query) AddPeer(np *NamespacePeer, success *bool) error {
return nil return nil
} }
func (t *Query) DeletePeer(np *NamespacePeer, success *bool) error { func (t *Query) DeletePeer(np *VaultPeer, success *bool) error {
namespace := np.Namespace vault := np.Vault
val, ok := StorageHandler.Namespaces[namespace] val, ok := StorageHandler.Vaults[vault]
if !ok { if !ok {
return fmt.Errorf("Namespace does not exist") return fmt.Errorf("Vault does not exist")
} }
peer, err := storage.PeerFromString(np.Peer) peer, err := storage.PeerFromString(np.Peer)
@@ -129,12 +129,12 @@ func (t *Query) DeletePeer(np *NamespacePeer, success *bool) error {
return nil return nil
} }
func (t *Query) Delete(np *NamespaceService, success *bool) error { func (t *Query) Delete(np *VaultService, success *bool) error {
namespace := np.Namespace vault := np.Vault
val, ok := StorageHandler.Namespaces[namespace] val, ok := StorageHandler.Vaults[vault]
if !ok { if !ok {
return fmt.Errorf("Namespace does not exist") return fmt.Errorf("Vault does not exist")
} }
err := val.Delete(np.Service) err := val.Delete(np.Service)
@@ -147,25 +147,25 @@ func (t *Query) Delete(np *NamespaceService, success *bool) error {
return nil return nil
} }
func (t *Query) AddNamespace(namespace *string, _ *int) error { func (t *Query) AddVault(vault *string, _ *int) error {
_, err := StorageHandler.AddNamespace(*namespace) _, err := StorageHandler.AddVault(*vault)
return err return err
} }
func (t *Query) DeleteNamespace(namespace *string, _ *int) error { func (t *Query) DeleteVault(vault *string, _ *int) error {
err := StorageHandler.DeleteNamespace(*namespace) err := StorageHandler.DeleteVault(*vault)
return err return err
} }
func (t *Query) ListNamespaces(_ *int, reply *[]string) error { func (t *Query) ListVaults(_ *int, reply *[]string) error {
*reply = StorageHandler.ListNamespaces() *reply = StorageHandler.ListVaults()
return nil return nil
} }
func (t *Query) GetAllNames(namespace *string, reply *[]string) error { func (t *Query) GetAllNames(vault *string, reply *[]string) error {
Logger.Infof("Listing content of %s", *namespace) Logger.Infof("Listing content of %s", *vault)
val, ok := StorageHandler.Namespaces[*namespace] val, ok := StorageHandler.Vaults[*vault]
if !ok { if !ok {
return fmt.Errorf("Namesapce does not exist") return fmt.Errorf("Namesapce does not exist")

View File

@@ -11,7 +11,6 @@ import (
"sync" "sync"
"strings" "strings"
"github.com/ipfs/go-datastore/query"
"github.com/libp2p/go-libp2p" "github.com/libp2p/go-libp2p"
dht "github.com/libp2p/go-libp2p-kad-dht" dht "github.com/libp2p/go-libp2p-kad-dht"
pubsub "github.com/libp2p/go-libp2p-pubsub" pubsub "github.com/libp2p/go-libp2p-pubsub"
@@ -21,7 +20,6 @@ import (
"github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-libp2p/core/network"
//"github.com/libp2p/go-libp2p/core/peerstore" //"github.com/libp2p/go-libp2p/core/peerstore"
discovery "github.com/libp2p/go-libp2p/p2p/discovery/routing" discovery "github.com/libp2p/go-libp2p/p2p/discovery/routing"
ds "github.com/ipfs/go-datastore"
ipfslite "github.com/hsanjuan/ipfs-lite" ipfslite "github.com/hsanjuan/ipfs-lite"
"github.com/google/uuid" "github.com/google/uuid"
@@ -29,13 +27,10 @@ import (
badger "github.com/ipfs/go-ds-badger2" badger "github.com/ipfs/go-ds-badger2"
dsq "github.com/ipfs/go-datastore/query" dsq "github.com/ipfs/go-datastore/query"
crdt "github.com/ipfs/go-ds-crdt"
crypto "github.com/libp2p/go-libp2p/core/crypto" crypto "github.com/libp2p/go-libp2p/core/crypto"
routed "github.com/libp2p/go-libp2p/p2p/host/routed" routed "github.com/libp2p/go-libp2p/p2p/host/routed"
agelib "filippo.io/age" agelib "filippo.io/age"
password "github.com/k4lipso/pentapass/internal/crypto"
"github.com/k4lipso/pentapass/internal/crypto/age"
. "github.com/k4lipso/pentapass/internal/log" . "github.com/k4lipso/pentapass/internal/log"
) )
@@ -107,13 +102,13 @@ type Peer struct {
Key string `json:"Key"` Key string `json:"Key"`
} }
type NamespaceConfig struct { type VaultConfig struct {
Name string `json:"Name"` Name string `json:"Name"`
Id string `json:"Id"` Id string `json:"Id"`
Peers []Peer `json:"Peers"` Peers []Peer `json:"Peers"`
} }
type Config []NamespaceConfig type Config []VaultConfig
type WhitelistConnectionGater struct { type WhitelistConnectionGater struct {
@@ -148,7 +143,7 @@ func (wg *WhitelistConnectionGater) InterceptUpgraded(conn network.Conn) (allow
return wg.InterceptPeerDial(conn.RemotePeer()), 0 return wg.InterceptPeerDial(conn.RemotePeer()), 0
} }
func GetTrustedPeers(config []NamespaceConfig) map[string][]Peer { func GetTrustedPeers(config []VaultConfig) map[string][]Peer {
result := make(map[string][]Peer) result := make(map[string][]Peer)
for _, c := range config { for _, c := range config {
result[c.Id] = c.Peers result[c.Id] = c.Peers
@@ -161,16 +156,6 @@ func InitRootNs() {
//TODO: check if "SharedKeyRegistry" key exists, if not create //TODO: check if "SharedKeyRegistry" key exists, if not create
} }
type Namespace struct {
ID string
Datastore *crdt.Datastore
//Registry *sharedKeyRegistry
CancelFunc context.CancelFunc
ctx context.Context
Key *agelib.X25519Identity
TrustedPeers []Peer
}
func PeerFromString(str string) (Peer, error) { func PeerFromString(str string) (Peer, error) {
parts := strings.Split(str, "/") parts := strings.Split(str, "/")
@@ -182,183 +167,6 @@ func PeerFromString(str string) (Peer, error) {
return Peer{ Id: parts[0], Key: parts[1] }, nil return Peer{ Id: parts[0], Key: parts[1] }, nil
} }
func (n *Namespace) AddPeer(peer Peer) {
for _, CurrentPeer := range n.TrustedPeers {
if CurrentPeer.Id == peer.Id && CurrentPeer.Key == peer.Key {
return
}
}
n.TrustedPeers = append(n.TrustedPeers, peer)
}
func (n *Namespace) RemovePeer(peer Peer) {
var Peers []Peer
for _, CurrentPeer := range n.TrustedPeers {
if CurrentPeer.Id == peer.Id && CurrentPeer.Key == peer.Key {
continue
}
Peers = append(Peers, CurrentPeer)
}
n.TrustedPeers = Peers
}
func (n *Namespace) GetRecipients() []string {
var result []string
for _, peer := range n.TrustedPeers {
result = append(result, peer.Key)
}
return result
}
func (n *Namespace) Put(k string, v string) error {
key := ds.NewKey(k)
err := n.Datastore.Put(n.ctx, key, []byte(v))
if err != nil {
printErr(err)
}
return err
}
func (n *Namespace) Delete(k string) error {
key := ds.NewKey(k)
err := n.Datastore.Delete(n.ctx, key)
if err != nil {
printErr(err)
}
return err
}
func (n *Namespace) GetPassword(k string) (password.Password, error) {
v, err := n.Datastore.Get(n.ctx, ds.NewKey(k))
if err != nil {
printErr(err)
return password.Password{}, err
}
val, err := age.Decrypt(v, n.Key)
if err != nil {
printErr(err)
return password.Password{}, err
}
pw, err := password.GetPasswordFromJson(val)
if err != nil {
printErr(err)
return password.Password{}, err
}
return pw, nil
}
func (n *Namespace) Get(k string) (string, error) {
v, err := n.Datastore.Get(n.ctx, ds.NewKey(k))
if err != nil {
printErr(err)
return "", err
}
return string(v), nil
}
func (n *Namespace) GetAllNames() []string {
q := query.Query{}
results, err := n.Datastore.Query(n.ctx, q)
if err != nil {
printErr(err)
}
var result []string
for r := range results.Next() {
if r.Error != nil {
printErr(err)
continue
}
result = append(result, r.Key)
}
return result
}
func (n *Namespace) List() {
q := query.Query{}
results, err := n.Datastore.Query(n.ctx, q)
if err != nil {
printErr(err)
}
for r := range results.Next() {
if r.Error != nil {
printErr(err)
continue
}
val, err := age.Decrypt(r.Value, n.Key)
if err != nil {
printErr(err)
continue
}
Logger.Infof("[%s] -> %s\n", r.Key, string(val))
}
}
func (n *Namespace) GetAllPasswords() ([]password.Password, error) {
q := query.Query{}
results, err := n.Datastore.Query(n.ctx, q)
if err != nil {
return nil, fmt.Errorf("Error during GetAllPasswords: %s", err)
}
var result []password.Password
for r := range results.Next() {
if r.Error != nil {
printErr(err)
continue
}
val, err := age.Decrypt(r.Value, n.Key)
if err != nil {
printErr(err)
continue
}
pw, err := password.GetPasswordFromJson(val)
if err != nil {
printErr(err)
continue
}
result = append(result, pw)
}
return result, nil
}
func (n *Namespace) Close() {
n.CancelFunc()
n.Datastore.Close()
}
type StorageHandler struct { type StorageHandler struct {
Ctx context.Context Ctx context.Context
Store *badger.Datastore Store *badger.Datastore
@@ -366,8 +174,8 @@ type StorageHandler struct {
Ipfs *ipfslite.Peer Ipfs *ipfslite.Peer
PubSub *pubsub.PubSub PubSub *pubsub.PubSub
Key *agelib.X25519Identity Key *agelib.X25519Identity
Config []NamespaceConfig Config []VaultConfig
Namespaces map[string]*Namespace Vaults map[string]*Vault
ConfigPath string ConfigPath string
} }
@@ -385,21 +193,21 @@ func (s *StorageHandler) UpdateConfig() {
} }
func (s *StorageHandler) recreateConfig() { func (s *StorageHandler) recreateConfig() {
var newCfg []NamespaceConfig var newCfg []VaultConfig
for key, val := range s.Namespaces { for key, val := range s.Vaults {
newCfg = append(newCfg, NamespaceConfig{ newCfg = append(newCfg, VaultConfig{
Name: key, Name: key,
Id: val.ID, Id: val.ID,
Peers: val.TrustedPeers, Peers: val.TrustedPeers,
}) })
} }
s.Config = newCfg s.Config = newCfg
//for idx, namespaceConfig := range s.Config { //for idx, vaultConfig := range s.Config {
// s.Config[idx].Peers = s.Namespaces[namespaceConfig.Name].TrustedPeers // s.Config[idx].Peers = s.Vaults[vaultConfig.Name].TrustedPeers
//} //}
} }
func (s *StorageHandler) writeConfig(filename string, config []NamespaceConfig) error { func (s *StorageHandler) writeConfig(filename string, config []VaultConfig) error {
jsonData, err := json.Marshal(config) jsonData, err := json.Marshal(config)
if err != nil { if err != nil {
@@ -416,9 +224,9 @@ func (s *StorageHandler) writeConfig(filename string, config []NamespaceConfig)
return nil return nil
} }
func (s *StorageHandler) NewConfig(filename string) ([]NamespaceConfig, error) { func (s *StorageHandler) NewConfig(filename string) ([]VaultConfig, error) {
if _, err := os.Stat(filename); errors.Is(err, os.ErrNotExist) { if _, err := os.Stat(filename); errors.Is(err, os.ErrNotExist) {
err := s.writeConfig(filename, []NamespaceConfig{ err := s.writeConfig(filename, []VaultConfig{
{ {
Name: "root", Name: "root",
Id: uuid.New().String(), Id: uuid.New().String(),
@@ -442,7 +250,7 @@ func (s *StorageHandler) NewConfig(filename string) ([]NamespaceConfig, error) {
return nil, fmt.Errorf("Could not read config file: %s", err) return nil, fmt.Errorf("Could not read config file: %s", err)
} }
var result []NamespaceConfig var result []VaultConfig
err = json.Unmarshal(content, &result) err = json.Unmarshal(content, &result)
@@ -453,29 +261,29 @@ func (s *StorageHandler) NewConfig(filename string) ([]NamespaceConfig, error) {
return result, nil return result, nil
} }
func (s *StorageHandler) GetDefaultNamespace(Name string) *Namespace { func (s *StorageHandler) GetDefaultVault(Name string) *Vault {
return s.Namespaces["root"] return s.Vaults["root"]
} }
func (s *StorageHandler) InitNamespaces() { func (s *StorageHandler) InitVaults() {
NamespaceMap := make(map[string]*Namespace) VaultMap := make(map[string]*Vault)
for _, nsCfg := range s.Config { for _, nsCfg := range s.Config {
ns1, err := CreateNamespace(nsCfg.Id, s) ns1, err := CreateVault(nsCfg.Id, s)
if err != nil { if err != nil {
Logger.Fatal(err) Logger.Fatal(err)
} }
NamespaceMap[nsCfg.Name] = ns1 VaultMap[nsCfg.Name] = ns1
} }
s.Namespaces = NamespaceMap s.Vaults = VaultMap
} }
func IsTrustedPeer(ctx context.Context, id peer.ID, namespace string, config []NamespaceConfig) bool { func IsTrustedPeer(ctx context.Context, id peer.ID, vault string, config []VaultConfig) bool {
peerMap := GetTrustedPeers(config) peerMap := GetTrustedPeers(config)
val, ok := peerMap[namespace] val, ok := peerMap[vault]
if ok { if ok {
for _, v := range val { for _, v := range val {
@@ -498,100 +306,48 @@ func PrintDBContent(ctx context.Context, store *badger.Datastore) {
} }
} }
func (s *StorageHandler) ListNamespaces() []string { func (s *StorageHandler) ListVaults() []string {
var result []string var result []string
for k := range s.Namespaces { for k := range s.Vaults {
result = append(result, k) result = append(result, k)
} }
return result return result
} }
func (s *StorageHandler) DeleteNamespace(ID string) error { func (s *StorageHandler) DeleteVault(ID string) error {
ns, ok := s.Namespaces[ID] ns, ok := s.Vaults[ID]
if !ok { if !ok {
Logger.Debug("DeleteNamespace that does not exists") Logger.Debug("DeleteVault that does not exists")
return nil return nil
} }
delete(s.Namespaces, ID) delete(s.Vaults, ID)
ns.Close() ns.Close()
s.UpdateConfig() s.UpdateConfig()
return nil return nil
} }
func (s *StorageHandler) AddNamespace(Name string) (*Namespace, error) { func (s *StorageHandler) AddVault(Name string) (*Vault, error) {
ns, ok := s.Namespaces[Name] ns, ok := s.Vaults[Name]
if ok { if ok {
return ns, nil return ns, nil
} }
result, err := CreateNamespace(uuid.New().String(), s) result, err := CreateVault(uuid.New().String(), s)
if err != nil { if err != nil {
return nil, err return nil, err
} }
result.TrustedPeers = append(result.TrustedPeers, s.GetSelfPeer()) result.TrustedPeers = append(result.TrustedPeers, s.GetSelfPeer())
s.Namespaces[Name] = result s.Vaults[Name] = result
s.UpdateConfig() s.UpdateConfig()
return result, nil return result, nil
} }
func CreateNamespace(ID string, storageHandler *StorageHandler) (*Namespace, error) {
Logger.Infof("Creating Namespace %s\n", ID)
err := storageHandler.PubSub.RegisterTopicValidator(
ID, //== topicName
func(ctx context.Context, id peer.ID, msg *pubsub.Message) bool {
Logger.Debugf("PubSubmsg TOPIC: %s, PEER: %s\n", ID, id)
signer := msg.GetFrom()
trusted := IsTrustedPeer(ctx, signer, ID, storageHandler.Config)
if !trusted {
Logger.Debugf("discarded pubsub message from non trusted source %s\n", signer)
}
return trusted
},
)
if err != nil {
Logger.Errorf("error registering topic validator: %s", err)
}
psubCtx, psubCancel := context.WithCancel(storageHandler.Ctx)
pubsubBC, err := crdt.NewPubSubBroadcaster(psubCtx, storageHandler.PubSub, ID)
if err != nil {
Logger.Fatal(err)
}
opts := crdt.DefaultOptions()
//opts.Logger = Logger
opts.RebroadcastInterval = 5 * time.Second
opts.PutHook = func(k ds.Key, v []byte) {
Logger.Infof("Added: [%s]\n", k)
}
opts.DeleteHook = func(k ds.Key) {
Logger.Infof("Removed: [%s]\n", k)
}
crdt, err := crdt.New(storageHandler.Store, ds.NewKey(ID), storageHandler.Ipfs, pubsubBC, opts)
if err != nil {
Logger.Fatal(err)
psubCancel()
return nil, err
}
PeerMap := GetTrustedPeers(storageHandler.Config)
val, ok := PeerMap[ID]
if !ok {
Logger.Debug("namespace config does not contain any peers")
}
return &Namespace{ID: ID, Datastore: crdt, CancelFunc: psubCancel, ctx: storageHandler.Ctx, Key: storageHandler.Key, TrustedPeers: val}, nil
}
func initDHT(ctx context.Context, h host.Host) *dht.IpfsDHT { func initDHT(ctx context.Context, h host.Host) *dht.IpfsDHT {
// Start a DHT, for use in peer discovery. We can't just make a new DHT // Start a DHT, for use in peer discovery. We can't just make a new DHT

262
internal/storage/vault.go Normal file
View File

@@ -0,0 +1,262 @@
package storage
import (
"context"
"fmt"
"time"
"github.com/ipfs/go-datastore/query"
pubsub "github.com/libp2p/go-libp2p-pubsub"
"github.com/libp2p/go-libp2p/core/peer"
ds "github.com/ipfs/go-datastore"
crdt "github.com/ipfs/go-ds-crdt"
agelib "filippo.io/age"
password "github.com/k4lipso/pentapass/internal/crypto"
"github.com/k4lipso/pentapass/internal/crypto/age"
. "github.com/k4lipso/pentapass/internal/log"
)
type Vault struct {
ID string
Datastore *crdt.Datastore
//Registry *sharedKeyRegistry
CancelFunc context.CancelFunc
ctx context.Context
Key *agelib.X25519Identity
TrustedPeers []Peer
}
func (n *Vault) AddPeer(peer Peer) {
for _, CurrentPeer := range n.TrustedPeers {
if CurrentPeer.Id == peer.Id && CurrentPeer.Key == peer.Key {
return
}
}
n.TrustedPeers = append(n.TrustedPeers, peer)
}
func (n *Vault) RemovePeer(peer Peer) {
var Peers []Peer
for _, CurrentPeer := range n.TrustedPeers {
if CurrentPeer.Id == peer.Id && CurrentPeer.Key == peer.Key {
continue
}
Peers = append(Peers, CurrentPeer)
}
n.TrustedPeers = Peers
}
func (n *Vault) GetRecipients() []string {
var result []string
for _, peer := range n.TrustedPeers {
result = append(result, peer.Key)
}
return result
}
func (n *Vault) Put(k string, v string) error {
key := ds.NewKey(k)
err := n.Datastore.Put(n.ctx, key, []byte(v))
if err != nil {
printErr(err)
}
return err
}
func (n *Vault) Delete(k string) error {
key := ds.NewKey(k)
err := n.Datastore.Delete(n.ctx, key)
if err != nil {
printErr(err)
}
return err
}
func (n *Vault) GetPassword(k string) (password.Password, error) {
v, err := n.Datastore.Get(n.ctx, ds.NewKey(k))
if err != nil {
printErr(err)
return password.Password{}, err
}
val, err := age.Decrypt(v, n.Key)
if err != nil {
printErr(err)
return password.Password{}, err
}
pw, err := password.GetPasswordFromJson(val)
if err != nil {
printErr(err)
return password.Password{}, err
}
return pw, nil
}
func (n *Vault) Get(k string) (string, error) {
v, err := n.Datastore.Get(n.ctx, ds.NewKey(k))
if err != nil {
printErr(err)
return "", err
}
return string(v), nil
}
func (n *Vault) GetAllNames() []string {
q := query.Query{}
results, err := n.Datastore.Query(n.ctx, q)
if err != nil {
printErr(err)
}
var result []string
for r := range results.Next() {
if r.Error != nil {
printErr(err)
continue
}
result = append(result, r.Key)
}
return result
}
func (n *Vault) List() {
q := query.Query{}
results, err := n.Datastore.Query(n.ctx, q)
if err != nil {
printErr(err)
}
for r := range results.Next() {
if r.Error != nil {
printErr(err)
continue
}
val, err := age.Decrypt(r.Value, n.Key)
if err != nil {
printErr(err)
continue
}
Logger.Infof("[%s] -> %s\n", r.Key, string(val))
}
}
func (n *Vault) GetAllPasswords() ([]password.Password, error) {
q := query.Query{}
results, err := n.Datastore.Query(n.ctx, q)
if err != nil {
return nil, fmt.Errorf("Error during GetAllPasswords: %s", err)
}
var result []password.Password
for r := range results.Next() {
if r.Error != nil {
printErr(err)
continue
}
val, err := age.Decrypt(r.Value, n.Key)
if err != nil {
printErr(err)
continue
}
pw, err := password.GetPasswordFromJson(val)
if err != nil {
printErr(err)
continue
}
result = append(result, pw)
}
return result, nil
}
func (n *Vault) Close() {
n.CancelFunc()
n.Datastore.Close()
}
func CreateVault(ID string, storageHandler *StorageHandler) (*Vault, error) {
Logger.Infof("Creating Vault %s\n", ID)
err := storageHandler.PubSub.RegisterTopicValidator(
ID, //== topicName
func(ctx context.Context, id peer.ID, msg *pubsub.Message) bool {
if id == storageHandler.Host.ID() {
return false
}
Logger.Debugf("PubSubmsg TOPIC: %s, PEER: %s\n", ID, id)
trusted := IsTrustedPeer(ctx, id, ID, storageHandler.Config)
if !trusted {
Logger.Debugf("discarded pubsub message from non trusted source %s\n", id)
}
return trusted
},
)
if err != nil {
Logger.Errorf("error registering topic validator: %s", err)
}
psubCtx, psubCancel := context.WithCancel(storageHandler.Ctx)
pubsubBC, err := crdt.NewPubSubBroadcaster(psubCtx, storageHandler.PubSub, ID)
if err != nil {
Logger.Fatal(err)
}
opts := crdt.DefaultOptions()
//opts.Logger = Logger
opts.RebroadcastInterval = 5 * time.Second
opts.PutHook = func(k ds.Key, v []byte) {
Logger.Infof("Added: [%s]\n", k)
}
opts.DeleteHook = func(k ds.Key) {
Logger.Infof("Removed: [%s]\n", k)
}
crdt, err := crdt.New(storageHandler.Store, ds.NewKey(ID), storageHandler.Ipfs, pubsubBC, opts)
if err != nil {
Logger.Fatal(err)
psubCancel()
return nil, err
}
PeerMap := GetTrustedPeers(storageHandler.Config)
val, ok := PeerMap[ID]
if !ok {
Logger.Debug("vault config does not contain any peers")
}
return &Vault{ID: ID, Datastore: crdt, CancelFunc: psubCancel, ctx: storageHandler.Ctx, Key: storageHandler.Key, TrustedPeers: val}, nil
}