little update.
This commit is contained in:
parent
4d60e5918d
commit
260386bcac
28 changed files with 1070 additions and 50 deletions
125
libmxclient/determinant/mxpassfile/mxpassfile.go
Normal file
125
libmxclient/determinant/mxpassfile/mxpassfile.go
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
package mxpassfile
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// inspired by https://github.com/jackc/pgpassfile
|
||||
|
||||
// Entry represents a line in a MX passfile.
|
||||
type Entry struct {
|
||||
Matrixhost string
|
||||
Localpart string
|
||||
Domain string
|
||||
Token string
|
||||
}
|
||||
|
||||
// Passfile is the in memory data structure representing a MX passfile.
|
||||
type Passfile struct {
|
||||
Entries []*Entry
|
||||
}
|
||||
|
||||
// ReadPassfile reads the file at path and parses it into a Passfile.
|
||||
func readPassfile(path string) (*Passfile, error) {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
return ParsePassfile(f)
|
||||
}
|
||||
|
||||
// ParsePassfile reads r and parses it into a Passfile.
|
||||
func ParsePassfile(r io.Reader) (*Passfile, error) {
|
||||
passfile := &Passfile{}
|
||||
|
||||
scanner := bufio.NewScanner(r)
|
||||
for scanner.Scan() {
|
||||
entry := parseLine(scanner.Text())
|
||||
if entry != nil {
|
||||
passfile.Entries = append(passfile.Entries, entry)
|
||||
}
|
||||
}
|
||||
|
||||
return passfile, scanner.Err()
|
||||
}
|
||||
|
||||
// parseLine parses a line into an *Entry. It returns nil on comment lines or any other unparsable
|
||||
// line.
|
||||
func parseLine(line string) *Entry {
|
||||
const (
|
||||
tmpBackslash = "\r"
|
||||
tmpPipe = "\n"
|
||||
)
|
||||
|
||||
line = strings.TrimSpace(line)
|
||||
|
||||
if strings.HasPrefix(line, "#") {
|
||||
return nil
|
||||
}
|
||||
|
||||
line = strings.ReplaceAll(line, `\\`, tmpBackslash)
|
||||
line = strings.ReplaceAll(line, `\|`, tmpPipe)
|
||||
|
||||
parts := strings.Split(line, "|")
|
||||
if len(parts) != 4 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Unescape escaped colons and backslashes
|
||||
for i := range parts {
|
||||
parts[i] = strings.ReplaceAll(parts[i], tmpBackslash, `\`)
|
||||
parts[i] = strings.ReplaceAll(parts[i], tmpPipe, `|`)
|
||||
parts[i] = strings.TrimSpace(parts[i])
|
||||
}
|
||||
|
||||
return &Entry{
|
||||
Matrixhost: parts[0],
|
||||
Localpart: parts[1],
|
||||
Domain: parts[2],
|
||||
Token: parts[3],
|
||||
}
|
||||
}
|
||||
|
||||
func isWild(s string) bool {
|
||||
if s == "" || s == "*" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func superCMP(s1, s2 string) bool {
|
||||
if isWild(s1) || isWild(s2) {
|
||||
return true
|
||||
}
|
||||
//fmt.Printf("sCMP: '%s' '%s'\n", s1, s2)
|
||||
return s1 == s2
|
||||
}
|
||||
|
||||
// FindPassword finds the password for the provided synapsehost, localpart, and domain. An empty
|
||||
// string will be returned if no match is found.
|
||||
func (pf *Passfile) FindPassword(matrixhost, localpart, domain string) string {
|
||||
for _, e := range pf.Entries {
|
||||
if (e.Matrixhost == "*" || e.Matrixhost == matrixhost) &&
|
||||
(e.Localpart == "*" || e.Localpart == localpart) &&
|
||||
(e.Domain == "*" || e.Domain == domain) {
|
||||
return e.Token
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (pf *Passfile) FindPasswordFill(matrixhost, localpart, domain string) *Entry {
|
||||
for _, e := range pf.Entries {
|
||||
if superCMP(e.Matrixhost, matrixhost) &&
|
||||
superCMP(e.Localpart, localpart) &&
|
||||
superCMP(e.Domain, domain) {
|
||||
return e
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue