Compare commits

...

2 Commits

Author SHA1 Message Date
2fefbe5e6c add basic subcommands list,generate,show,delete 2024-10-07 14:51:05 +02:00
fcdad8c2a3 split into daemon and cli interface 2024-10-07 14:11:49 +02:00
7 changed files with 676 additions and 259 deletions

View File

@@ -1,296 +1,395 @@
package main package main
import ( import (
"bufio"
"context"
"flag" "flag"
"fmt" "fmt"
"os" "os"
"time"
"os/signal"
"strings"
"syscall"
pubsub "github.com/libp2p/go-libp2p-pubsub"
"github.com/libp2p/go-libp2p/core/peer"
ipfslite "github.com/hsanjuan/ipfs-lite"
badger "github.com/ipfs/go-ds-badger2"
logging "github.com/ipfs/go-log/v2" logging "github.com/ipfs/go-log/v2"
"github.com/spf13/cobra"
"github.com/k4lipso/pentapass/storage" "github.com/k4lipso/pentapass/rpc"
"github.com/k4lipso/pentapass/crypto/age"
"github.com/k4lipso/pentapass/crypto" "github.com/k4lipso/pentapass/crypto"
) )
var ( var (
topicNameFlag = flag.String("topicName", "akdjlask-23klaj2idalj2-ajl2kjd3i-2ldakjd2", "name of topic to join")
dbPath = flag.String("db", "./db", "db file path") dbPath = flag.String("db", "./db", "db file path")
nameSpace = flag.String("namespace", "crdt", "namespace")
logger = logging.Logger("globaldb") logger = logging.Logger("globaldb")
// topicName = "globaldb-example" // topicName = "globaldb-example"
// netTopic = "globaldb-example-net" // netTopic = "globaldb-example-net"
// config = "globaldb-example" // config = "globaldb-example"
) )
// Create the root command
var rootCmd = &cobra.Command{
Use: "ppass",
Short: "Interact with the Password Store",
}
// Create the 'list' subcommand
var listCmd = &cobra.Command{
Use: "list",
Short: "List all passwords",
Run: func(cmd *cobra.Command, args []string) {
//all, _ := cmd.Flags().GetBool("all")
dbPath, _ := cmd.Flags().GetString("db")
client, err := rpc.Receive(dbPath)
if err != nil {
fmt.Printf("dialing: %s\n", err)
return
}
var names []string
namespace := "root"
err = client.Call("Query.GetAllNames", &namespace, &names)
if err != nil {
fmt.Println(err)
}
for _, name := range names {
fmt.Println(name)
}
},
}
var generateCmd = &cobra.Command{
Use: "generate",
Short: "Generate a Password",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
dbPath, _ := cmd.Flags().GetString("db")
client, err := rpc.Receive(dbPath)
if err != nil {
fmt.Printf("dialing: %s\n", err)
return
}
serviceName := args[0]
var password *crypto.Password
np := rpc.NamespaceService{ Namespace: "root", Service: serviceName }
err = client.Call("Query.Generate", &np, &password)
if err != nil {
fmt.Println(err)
}
fmt.Println(*password)
},
}
var showCmd = &cobra.Command{
Use: "show",
Short: "show a Password",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
dbPath, _ := cmd.Flags().GetString("db")
client, err := rpc.Receive(dbPath)
if err != nil {
fmt.Printf("dialing: %s\n", err)
return
}
serviceName := args[0]
var password *crypto.Password
np := rpc.NamespaceService{ Namespace: "root", Service: serviceName }
err = client.Call("Query.Get", &np, &password)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(password.Password)
},
}
var deleteCmd = &cobra.Command{
Use: "delete",
Short: "delete a Password",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
dbPath, _ := cmd.Flags().GetString("db")
client, err := rpc.Receive(dbPath)
if err != nil {
fmt.Printf("dialing: %s\n", err)
return
}
serviceName := args[0]
var success *bool
np := rpc.NamespaceService{ Namespace: "root", Service: serviceName }
err = client.Call("Query.Delete", &np, &success)
if err != nil {
fmt.Println(err)
}
fmt.Println(*success)
},
}
func init() {
// Add flags to the 'list' command
//listCmd.Flags().BoolP("all", "a", false, "List all items")
rootCmd.PersistentFlags().String("db", "", "db path")
rootCmd.MarkPersistentFlagRequired("db")
// Add subcommands to the root command
rootCmd.AddCommand(listCmd)
rootCmd.AddCommand(generateCmd)
rootCmd.AddCommand(showCmd)
rootCmd.AddCommand(deleteCmd)
}
func main() { func main() {
flag.Parse() if err := rootCmd.Execute(); err != nil {
ctx := context.Background() fmt.Println(err)
data := *dbPath os.Exit(1)
key, err := age.LoadOrGenerateKeys(*dbPath + "/age.key")
if err != nil {
panic(err)
} }
fmt.Printf("AgeKey: %s\n", key.String()) //flag.Parse()
fmt.Printf("AgePublicKey: %s\n", key.Recipient().String())
//cipher, err := age.Encrypt([]byte("Test Message"), []string{key.Recipient().String()}) //client, err := rpc.Receive(*dbPath)
//fmt.Printf("Encrypted: %s\n", cipher)
//decrypted, err := age.Decrypt(cipher, key)
//fmt.Printf("Decrypted: %s\n", decrypted)
h, dht, err := storage.SetupLibp2pHost(ctx, *dbPath)
pid := h.ID().String()
fmt.Println(h.ID().String())
if err != nil {
panic(err)
}
ps, err := pubsub.NewGossipSub(ctx, h)
if err != nil {
panic(err)
}
//topic, err := ps.Join(*topicNameFlag)
//if err != nil { //if err != nil {
// panic(err) // fmt.Printf("dialing: %s\n", err)
// return
//} //}
go storage.DiscoverPeers(ctx, h, dht) //var names []string
//namespace := "root"
//err = client.Call("Query.GetAllNames", &namespace, &names)
store, err := badger.NewDatastore(data, &badger.DefaultOptions) //if err != nil {
if err != nil { // fmt.Println(err)
logger.Fatal(err) //}
}
defer store.Close()
ipfs, err := ipfslite.New(ctx, store, nil, h, dht, nil) //fmt.Println(names)
if err != nil {
logger.Fatal(err)
}
Cfg, err := storage.NewConfig(*dbPath + "/config.json") //var password *crypto.Password
//np := rpc.NamespaceService{ Namespace: "root", Service: "Test" }
//err = client.Call("Query.Generate", &np, &password)
if err != nil { //if err != nil {
logger.Fatal(err) // fmt.Println(err)
} //}
storageHandler := storage.StorageHandler{ //fmt.Println(*password)
Ctx: ctx ,
Store: store,
Host: h,
Ipfs: ipfs,
PubSub: ps,
Key: key,
Config: Cfg,
}
storageHandler.InitNamespaces() //var success bool
//err = client.Call("Query.Delete", &np, &success)
for _, val := range storageHandler.Namespaces { //if success == true {
defer val.Close() // fmt.Println("Deleted Test")
} //}
fmt.Printf(` //var password2 *crypto.Password
Peer ID: %s //err = client.Call("Query.Get", &np, &password2)
Listen address: %s
Topic: %s
Data Folder: %s
Ready! //if err != nil {
// fmt.Println(err)
// return
//}
Commands: //fmt.Println(*password2)
> list -> list items in the store // fmt.Printf(`
> get <key> -> get value for a key //Peer ID: %s
> put <key> <value> -> store value on a key //Listen address: %s
> exit -> quit //Topic: %s
//Data Folder: %s
//
`, //Ready!
pid, storage.Listen, *topicNameFlag, data, //
) //Commands:
//
if len(os.Args) > 1 && os.Args[1] == "daemon" { //> list -> list items in the store
fmt.Println("Running in daemon mode") //> get <key> -> get value for a key
go func() { //> put <key> <value> -> store value on a key
for { //> exit -> quit
fmt.Printf("%s - %d connected peers\n", time.Now().Format(time.Stamp), len(storage.ConnectedPeers(h))) //
time.Sleep(10 * time.Second) //
} //`,
}() // pid, storage.Listen, *topicNameFlag, data,
signalChan := make(chan os.Signal, 20) // )
signal.Notify( //
signalChan, // if len(os.Args) > 1 && os.Args[1] == "daemon" {
syscall.SIGINT, // fmt.Println("Running in daemon mode")
syscall.SIGTERM, // go func() {
syscall.SIGHUP, // for {
) // fmt.Printf("%s - %d connected peers\n", time.Now().Format(time.Stamp), len(storage.ConnectedPeers(h)))
<-signalChan // time.Sleep(10 * time.Second)
return // }
} // }()
// signalChan := make(chan os.Signal, 20)
fmt.Printf("> ") // signal.Notify(
scanner := bufio.NewScanner(os.Stdin) // signalChan,
for scanner.Scan() { // syscall.SIGINT,
text := scanner.Text() // syscall.SIGTERM,
fields := strings.Fields(text) // syscall.SIGHUP,
if len(fields) == 0 { // )
fmt.Printf("> ") // <-signalChan
continue // return
} // }
//
cmd := fields[0] // fmt.Printf("> ")
// scanner := bufio.NewScanner(os.Stdin)
switch cmd { // for scanner.Scan() {
case "exit", "quit": // text := scanner.Text()
return // fields := strings.Fields(text)
case "debug": // if len(fields) == 0 {
if len(fields) < 2 { // fmt.Printf("> ")
fmt.Println("debug <on/off/peers>") // continue
} // }
st := fields[1] //
switch st { // cmd := fields[0]
case "on": //
logging.SetLogLevel("globaldb", "debug") // switch cmd {
case "off": // case "exit", "quit":
logging.SetLogLevel("globaldb", "error") // return
case "peers": // case "debug":
for _, p := range storage.ConnectedPeers(h) { // if len(fields) < 2 {
addrs, err := peer.AddrInfoToP2pAddrs(p) // fmt.Println("debug <on/off/peers>")
if err != nil { // }
logger.Warn(err) // st := fields[1]
continue // switch st {
} // case "on":
for _, a := range addrs { // logging.SetLogLevel("globaldb", "debug")
fmt.Println(a) // case "off":
} // logging.SetLogLevel("globaldb", "error")
} // case "peers":
} // for _, p := range storage.ConnectedPeers(h) {
case "list": // addrs, err := peer.AddrInfoToP2pAddrs(p)
if len(fields) < 2 { // if err != nil {
fmt.Printf("Available Namespaces:\n") // logger.Warn(err)
for k := range storageHandler.Namespaces { // continue
fmt.Printf("%s\n", k) // }
} // for _, a := range addrs {
continue // fmt.Println(a)
} // }
// }
namespace := fields[1] // }
// case "list":
fmt.Printf("Listing content of %s", namespace) // if len(fields) < 2 {
// fmt.Printf("Available Namespaces:\n")
val, ok := storageHandler.Namespaces[namespace] // for k := range storageHandler.Namespaces {
// fmt.Printf("%s\n", k)
if !ok { // }
fmt.Println("Namespace does not exist") // continue
continue // }
} //
// namespace := fields[1]
val.List() //
case "get": // fmt.Printf("Listing content of %s", namespace)
if len(fields) < 3 { //
fmt.Println("get <namespace> <key>") // val, ok := storageHandler.Namespaces[namespace]
fmt.Println("> ") //
continue // if !ok {
} // fmt.Println("Namespace does not exist")
// continue
namespace := fields[1] // }
//
val, ok := storageHandler.Namespaces[namespace] // val.List()
// case "get":
if !ok { // if len(fields) < 3 {
fmt.Println("Namespace does not exist") // fmt.Println("get <namespace> <key>")
continue // fmt.Println("> ")
} // continue
// }
k := fields[2] //
v, err := val.Get(k) // namespace := fields[1]
if err != nil { //
printErr(err) // val, ok := storageHandler.Namespaces[namespace]
continue //
} // if !ok {
// fmt.Println("Namespace does not exist")
fmt.Printf("[%s] -> %s\n", k, string(v)) // continue
case "generate": // }
if len(fields) < 3 { //
fmt.Println("generate <namespace> <Service>") // k := fields[2]
fmt.Println("> ") // v, err := val.Get(k)
continue // if err != nil {
} // printErr(err)
// continue
namespace := fields[1] // }
//
val, ok := storageHandler.Namespaces[namespace] // fmt.Printf("[%s] -> %s\n", k, string(v))
// case "generate":
if !ok { // if len(fields) < 3 {
fmt.Println("Namespace does not exist") // fmt.Println("generate <namespace> <Service>")
continue // fmt.Println("> ")
} // continue
// }
service := fields[2] //
password := crypto.NewPassword() // namespace := fields[1]
password.Service = service //
// val, ok := storageHandler.Namespaces[namespace]
data, err := password.ToJson() //
if err != nil { // if !ok {
printErr(err) // fmt.Println("Namespace does not exist")
continue // continue
} // }
//
encryptedPassword, err := age.Encrypt(data, val.GetRecipients()) // service := fields[2]
if err != nil { // password := crypto.NewPassword()
printErr(err) // password.Service = service
continue //
} // data, err := password.ToJson()
// if err != nil {
err = val.Put(password.Id.String(), string(encryptedPassword)) // printErr(err)
if err != nil { // continue
printErr(err) // }
continue //
} // encryptedPassword, err := age.Encrypt(data, val.GetRecipients())
case "put": // if err != nil {
if len(fields) < 4 { // printErr(err)
fmt.Println("put <namespace> <key> <value>") // continue
fmt.Println("> ") // }
continue //
} // //err = val.Put(password.Id.String(), string(encryptedPassword))
// err = val.Put(password.Service, string(encryptedPassword))
namespace := fields[1] // if err != nil {
// printErr(err)
val, ok := storageHandler.Namespaces[namespace] // continue
// }
if !ok { // case "put":
fmt.Println("Namespace does not exist") // if len(fields) < 4 {
continue // fmt.Println("put <namespace> <key> <value>")
} // fmt.Println("> ")
// continue
// }
k := fields[2] //
v := strings.Join(fields[3:], " ") // namespace := fields[1]
err := val.Put(k, v) //
if err != nil { // val, ok := storageHandler.Namespaces[namespace]
printErr(err) //
continue // if !ok {
} // fmt.Println("Namespace does not exist")
} // continue
fmt.Printf("> ") // }
} //
//
// k := fields[2]
// v := strings.Join(fields[3:], " ")
// err := val.Put(k, v)
// if err != nil {
// printErr(err)
// continue
// }
// }
// fmt.Printf("> ")
// }
} }
func printErr(err error) { func printErr(err error) {

103
cmd/ppassd/ppassd.go Normal file
View File

@@ -0,0 +1,103 @@
package main
import (
"context"
"flag"
"fmt"
pubsub "github.com/libp2p/go-libp2p-pubsub"
ipfslite "github.com/hsanjuan/ipfs-lite"
badger "github.com/ipfs/go-ds-badger2"
logging "github.com/ipfs/go-log/v2"
"github.com/k4lipso/pentapass/storage"
"github.com/k4lipso/pentapass/rpc"
"github.com/k4lipso/pentapass/crypto/age"
)
var (
topicNameFlag = flag.String("topicName", "akdjlask-23klaj2idalj2-ajl2kjd3i-2ldakjd2", "name of topic to join")
dbPath = flag.String("db", "./db", "db file path")
nameSpace = flag.String("namespace", "crdt", "namespace")
logger = logging.Logger("globaldb")
// topicName = "globaldb-example"
// netTopic = "globaldb-example-net"
// config = "globaldb-example"
)
func main() {
flag.Parse()
ctx := context.Background()
data := *dbPath
key, err := age.LoadOrGenerateKeys(*dbPath + "/age.key")
if err != nil {
panic(err)
}
fmt.Printf("AgeKey: %s\n", key.String())
fmt.Printf("AgePublicKey: %s\n", key.Recipient().String())
//cipher, err := age.Encrypt([]byte("Test Message"), []string{key.Recipient().String()})
//fmt.Printf("Encrypted: %s\n", cipher)
//decrypted, err := age.Decrypt(cipher, key)
//fmt.Printf("Decrypted: %s\n", decrypted)
h, dht, err := storage.SetupLibp2pHost(ctx, *dbPath)
fmt.Println(h.ID().String())
if err != nil {
panic(err)
}
ps, err := pubsub.NewGossipSub(ctx, h)
if err != nil {
panic(err)
}
//topic, err := ps.Join(*topicNameFlag)
//if err != nil {
// panic(err)
//}
go storage.DiscoverPeers(ctx, h, dht)
store, err := badger.NewDatastore(data, &badger.DefaultOptions)
if err != nil {
logger.Fatal(err)
}
defer store.Close()
ipfs, err := ipfslite.New(ctx, store, nil, h, dht, nil)
if err != nil {
logger.Fatal(err)
}
Cfg, err := storage.NewConfig(*dbPath + "/config.json")
if err != nil {
logger.Fatal(err)
}
storageHandler := storage.StorageHandler{
Ctx: ctx ,
Store: store,
Host: h,
Ipfs: ipfs,
PubSub: ps,
Key: key,
Config: Cfg,
}
storageHandler.InitNamespaces()
for _, val := range storageHandler.Namespaces {
defer val.Close()
}
rpc.StorageHandler = &storageHandler
rpc.Serve(*dbPath)
}

View File

@@ -1,11 +1,14 @@
package crypto package crypto
import ( import (
"math/rand"
"encoding/json" "encoding/json"
"github.com/google/uuid" "github.com/google/uuid"
) )
const DEFAULT_LENGTH int = 25
type Password struct { type Password struct {
Service string `json:"Service"` Service string `json:"Service"`
Url string `json:"Url"` Url string `json:"Url"`
@@ -21,7 +24,7 @@ func (p *Password) ToJson() ([]byte, error) {
func GetPasswordFromJson(b []byte) (Password, error) { func GetPasswordFromJson(b []byte) (Password, error) {
var result Password var result Password
err := json.Unmarshal(b, result) err := json.Unmarshal(b, &result)
if err != nil { if err != nil {
return Password{}, err return Password{}, err
@@ -30,9 +33,20 @@ func GetPasswordFromJson(b []byte) (Password, error) {
return result, nil return result, nil
} }
func NewPassword() *Password { func NewPassword(length int) *Password {
return &Password{ return &Password{
Id: uuid.New(), Id: uuid.New(),
Password: GenerateRandomString(length),
} }
} }
func GenerateRandomString(length int) string {
charset := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
b := make([]byte, length)
for i := range b {
b[i] = charset[rand.Intn(len(charset))]
}
return string(b)
}

5
go.mod
View File

@@ -4,6 +4,7 @@ go 1.22.5
require ( require (
filippo.io/age v1.2.0 filippo.io/age v1.2.0
github.com/google/uuid v1.6.0
github.com/hsanjuan/ipfs-lite v1.8.2 github.com/hsanjuan/ipfs-lite v1.8.2
github.com/ipfs/go-datastore v0.6.0 github.com/ipfs/go-datastore v0.6.0
github.com/ipfs/go-ds-badger2 v0.1.3 github.com/ipfs/go-ds-badger2 v0.1.3
@@ -13,6 +14,7 @@ require (
github.com/libp2p/go-libp2p-kad-dht v0.25.2 github.com/libp2p/go-libp2p-kad-dht v0.25.2
github.com/libp2p/go-libp2p-pubsub v0.11.0 github.com/libp2p/go-libp2p-pubsub v0.11.0
github.com/multiformats/go-multiaddr v0.13.0 github.com/multiformats/go-multiaddr v0.13.0
github.com/spf13/cobra v0.0.5
) )
require ( require (
@@ -48,13 +50,13 @@ require (
github.com/golang/snappy v0.0.1 // indirect github.com/golang/snappy v0.0.1 // indirect
github.com/google/gopacket v1.1.19 // indirect github.com/google/gopacket v1.1.19 // indirect
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.5.3 // indirect github.com/gorilla/websocket v1.5.3 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/huin/goupnp v1.3.0 // indirect github.com/huin/goupnp v1.3.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/bbloom v0.0.4 // indirect
github.com/ipfs/boxo v0.21.0 // indirect github.com/ipfs/boxo v0.21.0 // indirect
github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect
@@ -138,6 +140,7 @@ require (
github.com/quic-go/webtransport-go v0.8.0 // indirect github.com/quic-go/webtransport-go v0.8.0 // indirect
github.com/raulk/go-watchdog v1.3.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/spf13/pflag v1.0.3 // indirect
github.com/stretchr/testify v1.9.0 // indirect github.com/stretchr/testify v1.9.0 // indirect
github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect

3
go.sum
View File

@@ -188,6 +188,7 @@ github.com/hsanjuan/ipfs-lite v1.8.2 h1:PwYpfvh4HpActJyP03O4k6QznBR3xd6NmRWeOSJu
github.com/hsanjuan/ipfs-lite v1.8.2/go.mod h1:PfY4I2whwnZBHviwoajNzwjSyR9IQIJHxkpPAc5SLxw= github.com/hsanjuan/ipfs-lite v1.8.2/go.mod h1:PfY4I2whwnZBHviwoajNzwjSyR9IQIJHxkpPAc5SLxw=
github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc=
github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
@@ -487,8 +488,10 @@ github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0b
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=

139
rpc/rpc.go Normal file
View File

@@ -0,0 +1,139 @@
package rpc
import (
"fmt"
"net"
"net/rpc"
"net/http"
"os"
"os/signal"
"syscall"
"github.com/k4lipso/pentapass/storage"
"github.com/k4lipso/pentapass/crypto"
"github.com/k4lipso/pentapass/crypto/age"
)
var StorageHandler *storage.StorageHandler
type Query int
type NamespaceService struct {
Namespace string
Service string
}
func (t *Query) Generate(np *NamespaceService, reply *crypto.Password) error {
val, ok := StorageHandler.Namespaces[np.Namespace]
if !ok {
return fmt.Errorf("Namespace does not exist")
}
password := crypto.NewPassword(crypto.DEFAULT_LENGTH)
password.Service = np.Service
data, err := password.ToJson()
if err != nil {
return err
}
encryptedPassword, err := age.Encrypt(data, val.GetRecipients())
if err != nil {
return err
}
err = val.Put(password.Service, string(encryptedPassword))
if err != nil {
return err
}
*reply = *password
return nil
}
func (t *Query) Get(np *NamespaceService, reply *crypto.Password) error {
namespace := np.Namespace
val, ok := StorageHandler.Namespaces[namespace]
if !ok {
return fmt.Errorf("Namespace does not exist")
}
v, err := val.GetPassword(np.Service)
if err != nil {
return err
}
*reply = v
return nil
}
//func (t *Query) Add(password *crypto.Password, reply *[]string) error {
// return nil
//}
func (t *Query) Delete(np *NamespaceService, success *bool) error {
namespace := np.Namespace
val, ok := StorageHandler.Namespaces[namespace]
if !ok {
return fmt.Errorf("Namespace does not exist")
}
err := val.Delete(np.Service)
if err != nil {
*success = false
return err
}
*success = true
return nil
}
func (t *Query) GetAllNames(namespace *string, reply *[]string) error {
fmt.Println("RPC Request: Query::LoadedTriggers")
fmt.Printf("Listing content of %s", *namespace)
val, ok := StorageHandler.Namespaces[*namespace]
if !ok {
return fmt.Errorf("Namesapce does not exist")
}
*reply = val.GetAllNames()
return nil
}
func Serve(path string) {
query := new(Query)
rpc.Register(query)
rpc.HandleHTTP()
l, err := net.Listen("unix", path + "/rpc_test.socket")
if err != nil {
fmt.Printf("Error while listening on unix socket: %s\n", err)
}
go http.Serve(l, nil)
sigc := make(chan os.Signal, 1)
signal.Notify(sigc, os.Interrupt, syscall.SIGTERM)
func(ln net.Listener, c chan os.Signal) {
sig := <-c
fmt.Printf("Caught signal %s: shutting down.\n", sig)
ln.Close()
os.Exit(0)
}(l, sigc)
}
func Receive(path string) (*rpc.Client, error) {
client, err := rpc.DialHTTP("unix", path + "/rpc_test.socket")
if err != nil {
fmt.Printf("Cant connect to RPC server: %s\n", err)
}
return client, err
}

View File

@@ -38,7 +38,7 @@ import (
) )
var ( var (
topicNameFlag = "afbjlask-23klaj2idalj2-ajl2kjd3i-2ldakjd2" topicNameFlag = "afbjlask-23klaj2idalj2-ajl2kjd3i-2ldakjd4"
logger = logging.Logger("globaldb") logger = logging.Logger("globaldb")
Listen = libp2p.ListenAddrStrings("/ip4/0.0.0.0/tcp/0") Listen = libp2p.ListenAddrStrings("/ip4/0.0.0.0/tcp/0")
) )
@@ -216,6 +216,42 @@ func (n *Namespace) Put(k string, v string) error {
return 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) { func (n *Namespace) Get(k string) (string, error) {
v, err := n.Datastore.Get(n.ctx, ds.NewKey(k)) v, err := n.Datastore.Get(n.ctx, ds.NewKey(k))
if err != nil { if err != nil {
@@ -226,6 +262,27 @@ func (n *Namespace) Get(k string) (string, error) {
return string(v), nil 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() { func (n *Namespace) List() {
q := query.Query{} q := query.Query{}
results, err := n.Datastore.Query(n.ctx, q) results, err := n.Datastore.Query(n.ctx, q)
@@ -375,8 +432,7 @@ func CreateNamespace(ID string, storageHandler StorageHandler) (*Namespace, erro
opts.Logger = logger opts.Logger = logger
opts.RebroadcastInterval = 5 * time.Second opts.RebroadcastInterval = 5 * time.Second
opts.PutHook = func(k ds.Key, v []byte) { opts.PutHook = func(k ds.Key, v []byte) {
fmt.Printf("Added: [%s] -> %s\n", k, string(v)) fmt.Printf("Added: [%s]\n", k)
} }
opts.DeleteHook = func(k ds.Key) { opts.DeleteHook = func(k ds.Key) {
fmt.Printf("Removed: [%s]\n", k) fmt.Printf("Removed: [%s]\n", k)