pgpass.go (1338B)
1 package pgpass 2 3 import ( 4 "bufio" 5 "os" 6 "path/filepath" 7 "strings" 8 9 "github.com/lib/pq/internal/pqutil" 10 ) 11 12 func PasswordFromPgpass(passfile, user, password, host, port, dbname string) string { 13 if password != "" { // Do not process .pgpass if a password was supplied. 14 return password 15 } 16 17 filename := pqutil.Pgpass(passfile) 18 if filename == "" { 19 return "" 20 } 21 22 fp, err := os.Open(filename) 23 if err != nil { 24 return "" 25 } 26 defer fp.Close() 27 28 scan := bufio.NewScanner(fp) 29 for scan.Scan() { 30 line := scan.Text() 31 if len(line) == 0 || line[0] == '#' { 32 continue 33 } 34 split := splitFields(line) 35 if len(split) != 5 { 36 continue 37 } 38 39 socket := host == "" || filepath.IsAbs(host) || strings.HasPrefix(host, "@") 40 if (split[0] == "*" || split[0] == host || (split[0] == "localhost" && socket)) && 41 (split[1] == "*" || split[1] == port) && 42 (split[2] == "*" || split[2] == dbname) && 43 (split[3] == "*" || split[3] == user) { 44 return split[4] 45 } 46 } 47 48 return "" 49 } 50 51 func splitFields(s string) []string { 52 var ( 53 fs = make([]string, 0, 5) 54 f = make([]rune, 0, len(s)) 55 esc bool 56 ) 57 for _, c := range s { 58 switch { 59 case esc: 60 f, esc = append(f, c), false 61 case c == '\\': 62 esc = true 63 case c == ':': 64 fs, f = append(fs, string(f)), f[:0] 65 default: 66 f = append(f, c) 67 } 68 } 69 return append(fs, string(f)) 70 }