mirror of
https://github.com/rwinkhart/libmutton.git
synced 2026-08-27 20:36:29 -04:00
Make adjustments for easier CGO integration
This commit is contained in:
+3
-2
@@ -31,7 +31,8 @@ func Entry(vanityPath string, timestamp int64) error {
|
||||
// AllPasswordEntries adds age data for all un-aged entries containing passwords.
|
||||
// Each entry is aged with a random timestamp from within the last year to prevent
|
||||
// all entries having their passwords expire at the same time.
|
||||
func AllPasswordEntries(forceReage bool) error {
|
||||
// Leave rcwPassword nil to use RCW demonization.
|
||||
func AllPasswordEntries(forceReage bool, rcwPassword []byte) error {
|
||||
allVanityPaths, _, err := synccommon.WalkEntryDir()
|
||||
if err != nil {
|
||||
return errors.New("unable to walk entry directory: " + err.Error())
|
||||
@@ -48,7 +49,7 @@ func AllPasswordEntries(forceReage bool) error {
|
||||
}
|
||||
}
|
||||
|
||||
decSlice, err := crypt.DecryptFileToSlice(global.EntryRoot + vanityPath)
|
||||
decSlice, err := crypt.DecryptFileToSlice(global.EntryRoot+vanityPath, rcwPassword)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+3
-2
@@ -13,7 +13,8 @@ import (
|
||||
|
||||
// CopyShortcut (given a path) decrypts an
|
||||
// entry and copies a field to the clipboard.
|
||||
func CopyShortcut(realPath string, field int) error {
|
||||
// Leave rcwPassword nil to use RCW demonization.
|
||||
func CopyShortcut(realPath string, field int, rcwPassword []byte) error {
|
||||
// ensure realPath exists and is a file
|
||||
_, err := back.TargetIsFile(realPath, true)
|
||||
if err != nil {
|
||||
@@ -21,7 +22,7 @@ func CopyShortcut(realPath string, field int) error {
|
||||
}
|
||||
|
||||
// decrypt entry
|
||||
decSlice, err := crypt.DecryptFileToSlice(realPath)
|
||||
decSlice, err := crypt.DecryptFileToSlice(realPath, rcwPassword)
|
||||
if err != nil {
|
||||
return errors.New("unable to decrypt entry: " + err.Error())
|
||||
}
|
||||
|
||||
+3
-2
@@ -10,7 +10,8 @@ import (
|
||||
// GetOldEntryData decrypts and returns old entry data (with all required lines present).
|
||||
// This is a wrapper around the DecryptFileToSlice function that ensures all required lines are present in the returned slice.
|
||||
// This makes it ideal for editing entries, as it guarantees at least a baseline slice length.
|
||||
func GetOldEntryData(realPath string, field int) ([]string, error) {
|
||||
// Leave rcwPassword nil to use RCW demonization.
|
||||
func GetOldEntryData(realPath string, field int, rcwPassword []byte) ([]string, error) {
|
||||
// ensure realPath exists and is a file
|
||||
_, err := back.TargetIsFile(realPath, true)
|
||||
if err != nil {
|
||||
@@ -18,7 +19,7 @@ func GetOldEntryData(realPath string, field int) ([]string, error) {
|
||||
}
|
||||
|
||||
// read old entry data
|
||||
decryptedEntry, err := crypt.DecryptFileToSlice(realPath)
|
||||
decryptedEntry, err := crypt.DecryptFileToSlice(realPath, rcwPassword)
|
||||
if err != nil {
|
||||
return nil, errors.New("unable to decrypt entry: " + err.Error())
|
||||
}
|
||||
|
||||
+3
-2
@@ -19,8 +19,9 @@ import (
|
||||
|
||||
// WriteEntry writes entryData to an encrypted file at realPath.
|
||||
// If the entry contains an updated password, an age file is also created.
|
||||
func WriteEntry(realPath string, decSlice []string, passwordIsNew bool) error {
|
||||
err := os.WriteFile(realPath, crypt.EncryptBytes([]byte(strings.Join(decSlice, "\n"))), 0600)
|
||||
// Leave rcwPassword nil to use RCW demonization.
|
||||
func WriteEntry(realPath string, decSlice []string, passwordIsNew bool, rcwPassword []byte) error {
|
||||
err := os.WriteFile(realPath, crypt.EncryptBytes([]byte(strings.Join(decSlice, "\n")), rcwPassword), 0600)
|
||||
if err != nil {
|
||||
return errors.New("unable to write to file: " + err.Error())
|
||||
}
|
||||
|
||||
+29
-20
@@ -13,7 +13,6 @@ import (
|
||||
"github.com/rwinkhart/rcw/wrappers"
|
||||
)
|
||||
|
||||
var Daemonize = true
|
||||
var RetryPassword = true
|
||||
|
||||
// RCWDArgument reads the password from stdin and caches it via an RCW daemon.
|
||||
@@ -25,23 +24,29 @@ func RCWDArgument() {
|
||||
daemon.Start([]byte(password))
|
||||
}
|
||||
|
||||
// DecryptFileToSlice decrypts an RCW wrapped file and returns the contents as a slice of (trimmed) strings.
|
||||
func DecryptFileToSlice(realPath string) ([]string, error) {
|
||||
// DecryptFileToSlice decrypts an RCW wrapped file
|
||||
// and returns the contents as a slice of (trimmed) strings.
|
||||
// Leave rcwPassword nil to use RCW demonization.
|
||||
func DecryptFileToSlice(realPath string, rcwPassword []byte) ([]string, error) {
|
||||
// read encrypted file
|
||||
encBytes, err := os.ReadFile(realPath)
|
||||
if err != nil {
|
||||
return nil, errors.New("unable to open \"" + realPath + "\" for decryption: " + err.Error())
|
||||
}
|
||||
|
||||
// decrypt data using RCW daemon
|
||||
password := launchRCWDProcess()
|
||||
if password == nil {
|
||||
// if daemon is already running, use it to decrypt the data
|
||||
// if no password was provided, assume daemon mode
|
||||
if rcwPassword == nil {
|
||||
rcwPassword = launchRCWDProcess()
|
||||
// if rcwPassword is still nil, the daemon is already running;
|
||||
// use it to encrypt the data
|
||||
if rcwPassword == nil {
|
||||
return strings.Split(string(daemon.GetDec(encBytes)), "\n"), nil
|
||||
}
|
||||
// if the daemon is not already running, use wrappers.Decrypt
|
||||
// directly to avoid waiting for socket file creation
|
||||
decBytes, err := wrappers.Decrypt(encBytes, password)
|
||||
}
|
||||
|
||||
// if the daemon is not being used/was not already running,
|
||||
// use wrappers.Decrypt directly to avoid waiting for socket file creation
|
||||
decBytes, err := wrappers.Decrypt(encBytes, rcwPassword)
|
||||
if err != nil {
|
||||
return nil, errors.New("unable to decrypt \"" + realPath + "\": " + err.Error())
|
||||
}
|
||||
@@ -49,22 +54,28 @@ func DecryptFileToSlice(realPath string) ([]string, error) {
|
||||
}
|
||||
|
||||
// EncryptBytes encrypts a byte slice using RCW and returns the encrypted data.
|
||||
func EncryptBytes(decBytes []byte) []byte {
|
||||
password := launchRCWDProcess()
|
||||
if password == nil {
|
||||
// if daemon is already running, use it to encrypt the data
|
||||
// Leave rcwPassword nil to use RCW demonization.
|
||||
func EncryptBytes(decBytes, rcwPassword []byte) []byte {
|
||||
// if no rcwPassword was provided, assume daemon mode
|
||||
if rcwPassword == nil {
|
||||
rcwPassword = launchRCWDProcess()
|
||||
// if rcwPassword is still nil, the daemon is already running;
|
||||
// use it to encrypt the data
|
||||
if rcwPassword == nil {
|
||||
return daemon.GetEnc(decBytes)
|
||||
}
|
||||
// if the daemon is not already running, use wrappers.Encrypt
|
||||
// directly to avoid waiting for socket file creation
|
||||
return wrappers.Encrypt(decBytes, password)
|
||||
}
|
||||
|
||||
// if the daemon is not being used/was not already running,
|
||||
// use wrappers.Encrypt directly to avoid waiting for socket file creation
|
||||
return wrappers.Encrypt(decBytes, rcwPassword)
|
||||
}
|
||||
|
||||
// launchRCWDProcess launches an RCW daemon to cache a password.
|
||||
// If the daemon is not already running OR if not running in daemonize mode,
|
||||
// it collects and returns the password (otherwise returns nil).
|
||||
func launchRCWDProcess() []byte {
|
||||
if Daemonize && daemon.IsOpen() {
|
||||
if daemon.IsOpen() {
|
||||
return nil
|
||||
}
|
||||
var password []byte
|
||||
@@ -81,12 +92,10 @@ func launchRCWDProcess() []byte {
|
||||
password = global.GetPassword("RCW Password:")
|
||||
}
|
||||
|
||||
if Daemonize {
|
||||
cmd := exec.Command(os.Args[0], "startrcwd")
|
||||
cmd.SysProcAttr = global.GetSysProcAttr()
|
||||
_ = back.WriteToStdin(cmd, string(password))
|
||||
_ = cmd.Start()
|
||||
}
|
||||
|
||||
return password
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/rwinkhart/libmutton
|
||||
|
||||
go 1.25.5
|
||||
go 1.25.6
|
||||
|
||||
require (
|
||||
github.com/pkg/sftp v1.13.10
|
||||
@@ -8,6 +8,7 @@ require (
|
||||
github.com/rwinkhart/go-boilerplate v0.1.1
|
||||
github.com/rwinkhart/rcw v0.2.4
|
||||
golang.org/x/crypto v0.46.0
|
||||
golang.org/x/sys v0.40.0
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -15,7 +16,6 @@ require (
|
||||
github.com/boombuler/barcode v1.1.0 // indirect
|
||||
github.com/kr/fs v0.1.0 // indirect
|
||||
github.com/rwinkhart/peercred-mini v0.1.2 // indirect
|
||||
golang.org/x/sys v0.40.0 // indirect
|
||||
)
|
||||
|
||||
replace golang.org/x/sys => github.com/rwinkhart/sys v0.40.0
|
||||
|
||||
@@ -13,7 +13,6 @@ These are as follows:
|
||||
|
||||
## Required Global Variable Manipulation
|
||||
- `global.GetPassword` must be set to allow for different types of clients (CLI, GUI, TUI) to prompt for the password in the most appropriate way.
|
||||
- `crypt.Daemonize`, true by default, determines whether to make use of the RCW daemon for password caching. This may be best to disable for interactive clients.
|
||||
- `crypt.RetryPassword`, true by default, determines whether the crypt package should verify user-typed passwords and re-prompt if needed. Turn this off to handle this uniquely in the client.
|
||||
|
||||
## Required Arguments
|
||||
|
||||
Reference in New Issue
Block a user