wip: debugging issue

This commit is contained in:
2023-07-23 22:00:52 +10:00
parent 7b29d8f6cc
commit 6c4b48873b
10 changed files with 373 additions and 46 deletions

113
cmd/spt/decrypt.go Normal file
View File

@@ -0,0 +1,113 @@
package spt
import (
"fmt"
"gitea.suyono.dev/suyono/simple-privacy-tool/privacy"
"io"
"os"
)
type decryptApp struct {
cApp
r *privacy.Reader
}
type stdoutWrapper struct {
file *os.File
}
func newDecryptApp(a *cApp) *decryptApp {
return &decryptApp{
cApp: *a,
}
}
func (d *decryptApp) GetPassphrase() (err error) {
var (
passphrase string
)
if passphrase, err = d.term.ReadPassword("input passphrase: "); err != nil {
return
}
d.passphrase = passphrase
return
}
func (d *decryptApp) ProcessFiles() (err error) {
d.r = privacy.NewPrivacyReader(d.srcFile)
if err = d.r.ReadMagic(); err != nil {
return
}
if err = d.r.GenerateKey(d.passphrase); err != nil {
return
}
if d.dstPath == "-" || d.srcPath == "-" {
w := stdoutWrapper{
file: d.dstFile,
}
if _, err = io.Copy(w, d.r); err != nil {
return
}
} else {
if _, err = io.Copy(d.dstFile, d.r); err != nil {
return
}
}
if err = d.dstFile.Close(); err != nil {
return
}
if err = d.srcFile.Close(); err != nil {
return
}
return
}
func (sw stdoutWrapper) ReadFrom(reader io.Reader) (n int64, err error) {
var (
nr int
rErr error
)
buf := make([]byte, 32768)
for {
if nr, err = reader.Read(buf); err != nil {
break
}
n += int64(nr)
if _, err = sw.file.Write(buf[:nr]); err != nil {
return n, fmt.Errorf("readfrom internal write: %w", err)
}
}
rErr = err
if nr > 0 {
n += int64(nr)
if nr > 32768 {
return n, fmt.Errorf("last piece length %d: %w", nr, err)
}
if _, err = sw.file.Write(buf[:nr]); err != nil {
return n, fmt.Errorf("readfrom internal write: %w", err)
}
}
if rErr == io.EOF || rErr == nil {
err = nil
} else {
err = rErr
}
return
}
func (sw stdoutWrapper) Write(b []byte) (n int, err error) {
return sw.file.Write(b)
}

65
cmd/spt/encrypt.go Normal file
View File

@@ -0,0 +1,65 @@
package spt
import (
"gitea.suyono.dev/suyono/simple-privacy-tool/privacy"
"io"
)
type encryptApp struct {
cApp
wc *privacy.WriteCloser
}
func newEncryptApp(a *cApp) *encryptApp {
return &encryptApp{
cApp: *a,
}
}
func (e *encryptApp) GetPassphrase() (err error) {
var (
passphrase string
verify string
)
if passphrase, err = e.term.ReadPassword("input passphrase: "); err != nil {
return
}
if verify, err = e.term.ReadPassword("verify - input passphrase: "); err != nil {
return
}
if passphrase != verify {
return ErrPassphraseMismatch
}
e.passphrase = passphrase
return nil
}
func (e *encryptApp) ProcessFiles() (err error) {
e.wc = privacy.NewPrivacyWriteCloser(e.dstFile, privacy.DefaultCipherMethod) //TODO: need to handle when custom keygen accepted
if err = e.wc.NewSalt(); err != nil {
return
}
if err = e.wc.GenerateKey(e.passphrase); err != nil {
return
}
if _, err = io.Copy(e.wc, e.srcFile); err != nil {
return
}
if err = e.wc.Close(); err != nil {
return
}
if err = e.srcFile.Close(); err != nil {
return
}
return
}

View File

@@ -1,10 +1,25 @@
package spt
import (
"errors"
tw "gitea.suyono.dev/suyono/terminal_wrapper"
"github.com/spf13/cobra"
"os"
)
type cApp struct {
term *tw.Terminal
srcPath string
dstPath string
srcFile *os.File
dstFile *os.File
passphrase string
}
var (
//ErrFatalError = errors.New("fatal error occurred")
ErrPassphraseMismatch = errors.New("mismatch passphrase")
rootCmd = &cobra.Command{
Use: "spt",
Short: "a simple tool to encrypt and decrypt file",
@@ -12,12 +27,14 @@ var (
encryptCmd = &cobra.Command{
Use: "encrypt",
Args: validatePositionalArgs,
RunE: encrypt,
}
decryptCmd = &cobra.Command{
Use: "decrypt",
RunE: decrypt,
Args: validatePositionalArgs,
}
)
@@ -29,24 +46,117 @@ func init() {
rootCmd.AddCommand(encryptCmd, decryptCmd)
}
func encrypt(cmd *cobra.Command, args []string) error {
//TODO: implementation
//// this is the sample of reading password
//fmt.Print("input passphrase: ")
//passwd, err := privacy.ReadPassword()
//if err != nil {
// return err
//}
//fmt.Println()
//
//fmt.Printf("password: %s\n", passwd)
//// end of sample
func validatePositionalArgs(cmd *cobra.Command, args []string) error {
if len(args) != 0 && len(args) != 2 {
//TODO: improve the error message
return errors.New("invalid arguments")
}
return nil
}
func decrypt(cmd *cobra.Command, args []string) error {
//TODO: implementation
func encrypt(cmd *cobra.Command, args []string) (err error) {
var (
terminal *tw.Terminal
app *cApp
eApp *encryptApp
)
if terminal, err = tw.MakeTerminal(os.Stderr); err != nil {
return
}
defer func() {
existingErr := err
if err = terminal.Restore(); err == nil && existingErr != nil {
err = existingErr
}
}()
app = &cApp{
term: terminal,
}
if err = app.ProcessArgs(args); err != nil {
return
}
eApp = newEncryptApp(app)
if err = eApp.GetPassphrase(); err != nil {
return
}
//TODO: process additional flags
if err = eApp.ProcessFiles(); err != nil {
return
}
return nil
}
func decrypt(cmd *cobra.Command, args []string) (err error) {
var (
terminal *tw.Terminal
app *cApp
dApp *decryptApp
)
if terminal, err = tw.MakeTerminal(os.Stderr); err != nil {
return
}
defer func() {
existingErr := err
if err = terminal.Restore(); err == nil && existingErr != nil {
err = existingErr
}
}()
app = &cApp{
term: terminal,
}
if err = app.ProcessArgs(args); err != nil {
return
}
dApp = newDecryptApp(app)
if err = dApp.GetPassphrase(); err != nil {
return
}
//TODO: process additional flags
if err = dApp.ProcessFiles(); err != nil {
return
}
return nil
}
func (a *cApp) ProcessArgs(args []string) (err error) {
if len(args) == 0 {
a.srcFile = os.Stdin
a.dstFile = os.Stdout
} else {
a.srcPath = args[0]
a.dstPath = args[1]
if a.srcPath == "-" {
a.srcFile = os.Stdin
} else {
if a.srcFile, err = os.Open(a.srcPath); err != nil {
return
}
}
if a.dstPath == "-" {
a.dstFile = os.Stdout
} else {
if a.dstFile, err = os.OpenFile(a.dstPath, os.O_CREATE|os.O_WRONLY, 0640); err != nil { //TODO: allow user to define the destination file permission
return
}
}
}
return
}