wip: debugging issue
This commit is contained in:
113
cmd/spt/decrypt.go
Normal file
113
cmd/spt/decrypt.go
Normal 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
65
cmd/spt/encrypt.go
Normal 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
|
||||
}
|
||||
140
cmd/spt/spt.go
140
cmd/spt/spt.go
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user