refactor: Wszystkie pakiety przeniesione do internal
This commit is contained in:
		
							
								
								
									
										65
									
								
								internal/pass/crypt.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								internal/pass/crypt.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
			
		||||
package pass
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"os"
 | 
			
		||||
 | 
			
		||||
	"filippo.io/age"
 | 
			
		||||
	"filippo.io/age/armor"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func DecryptFile(password []byte, file string) ([]byte, error) {
 | 
			
		||||
	identity, err := age.NewScryptIdentity(string(password))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("błąd przetwarzania hasła: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	fd, err := os.Open(file)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("błąd otwarcia pliku: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	defer fd.Close()
 | 
			
		||||
 | 
			
		||||
	in := armor.NewReader(fd)
 | 
			
		||||
 | 
			
		||||
	r, err := age.Decrypt(in, identity)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("błąd deszyfrowania #01: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	out := &bytes.Buffer{}
 | 
			
		||||
	if _, err := io.Copy(out, r); err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("błąd deszyfrowania #02: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	return out.Bytes(), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func EncryptFile(password []byte, file string, data []byte) error {
 | 
			
		||||
	recipient, err := age.NewScryptRecipient(string(password))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("błąd przetwarzania hasła: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	fd, err := os.OpenFile(file, os.O_WRONLY | os.O_CREATE | os.O_EXCL, 0o600)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("błąd tworzenia pliku: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	defer fd.Close()
 | 
			
		||||
 | 
			
		||||
	out := armor.NewWriter(fd) // armor
 | 
			
		||||
	defer out.Close()
 | 
			
		||||
 | 
			
		||||
	w, err := age.Encrypt(out, recipient)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("błąd szyfrowania #01: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	_, err = w.Write(data)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("błąd szyfrowania #02: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	err = w.Close()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("błąd szyfrowania #03: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										80
									
								
								internal/pass/pass.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								internal/pass/pass.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
			
		||||
package pass
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"fmt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type pgpassrow struct {
 | 
			
		||||
	hostname string
 | 
			
		||||
	port     string
 | 
			
		||||
	database string
 | 
			
		||||
	username string
 | 
			
		||||
	password string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type PassDb struct {
 | 
			
		||||
	db []pgpassrow
 | 
			
		||||
	cache map[string]*pgpassrow
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Load(file string, master []byte) (*PassDb, error) {
 | 
			
		||||
 | 
			
		||||
	data, err := DecryptFile(master, file)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	lines := bytes.Split(data, []byte{'\n'})
 | 
			
		||||
 | 
			
		||||
	var rows []pgpassrow
 | 
			
		||||
 | 
			
		||||
	for i, line := range lines {
 | 
			
		||||
		line = bytes.TrimRight(line, "\n\r \t")
 | 
			
		||||
		if len(line) == 0 || line[0] == byte('#') {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		fields := bytes.Split(line, []byte{':'})
 | 
			
		||||
		if len(fields) != 5 {
 | 
			
		||||
			return nil, fmt.Errorf("błąd w pliku hasłeł %s:%d: niewłaściwa liczba pól", file, i)
 | 
			
		||||
		}
 | 
			
		||||
		rows = append(rows, pgpassrow{
 | 
			
		||||
			hostname: string(fields[0]),
 | 
			
		||||
			port:     string(fields[1]),
 | 
			
		||||
			database: string(fields[2]),
 | 
			
		||||
			username: string(fields[3]),
 | 
			
		||||
			password: string(fields[4]),
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &PassDb{
 | 
			
		||||
		db: rows,
 | 
			
		||||
		cache: make(map[string]*pgpassrow),
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func match(value string, pattern string) bool {
 | 
			
		||||
	return pattern == "*" || pattern == value
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (self *PassDb) FindPassword(host string, port uint, database string, user string) string {
 | 
			
		||||
	myport := fmt.Sprintf("%d", port)
 | 
			
		||||
	key := fmt.Sprintf("%s:%s:%s:%s", host, myport, database, user)
 | 
			
		||||
	cached, ok := self.cache[key]
 | 
			
		||||
	if ok {
 | 
			
		||||
		return cached.password
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// pierwszy pasujący do wzorca
 | 
			
		||||
	for i := range self.db {
 | 
			
		||||
		if match(host, self.db[i].hostname) &&
 | 
			
		||||
			match(myport, self.db[i].port) &&
 | 
			
		||||
			match(database, self.db[i].database) &&
 | 
			
		||||
			match(user, self.db[i].username) {
 | 
			
		||||
 | 
			
		||||
				self.cache[key] = &self.db[i]
 | 
			
		||||
				return self.db[i].password
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										55
									
								
								internal/pass/term.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								internal/pass/term.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
			
		||||
package pass
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"log"
 | 
			
		||||
	"os"
 | 
			
		||||
 | 
			
		||||
	"baal.ar76.eu/x/pub/multisql/internal/cfg"
 | 
			
		||||
	"golang.org/x/term"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func GetMasterPass(askPass bool) []byte {
 | 
			
		||||
	if askPass {
 | 
			
		||||
		res, err := termGetPassword("Podaj hasło")
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Fatalln("Nie udało się wczytać hasła z konsoli")
 | 
			
		||||
		}
 | 
			
		||||
		return res
 | 
			
		||||
	}
 | 
			
		||||
	password := os.Getenv(cfg.MULTISQLPASS)
 | 
			
		||||
 | 
			
		||||
	if password != "" {
 | 
			
		||||
		return []byte(password)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	log.Fatalf("Nieustalone hasło. Użyj flagi -P lub ustaw hasło w zmiennej %s", cfg.MULTISQLPASS)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func EnterMasterPass() []byte {
 | 
			
		||||
	p1, err := termGetPassword("Podaj nowe hasło (min 8 znaków)")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatalf("Błąd wczytywania hasła: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	if len(p1) < 8 {
 | 
			
		||||
		log.Fatalf("podano zbyt krótkie hasło")
 | 
			
		||||
	}
 | 
			
		||||
	p2, err := termGetPassword("Powtórz nowe hasło")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatalf("Błąd wczytywania hasła: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	if !bytes.Equal(p1, p2) {
 | 
			
		||||
		log.Fatalf("podane hasła są różne")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return p1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func termGetPassword(prompt string) ([]byte, error) {
 | 
			
		||||
	fmt.Fprintf(os.Stderr, "%s: ", prompt)
 | 
			
		||||
	passwd, err := term.ReadPassword(int(os.Stdin.Fd()))
 | 
			
		||||
	fmt.Fprintln(os.Stderr)
 | 
			
		||||
	return passwd, err
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user