func readConfigFile(in io.Reader) (pws map[int][]passEntry) {
	var (
		remotes               = 0
		nonGeneratedPasswords = 0
		tooShortPasswords     = 0
		generatedPasswords    = 0
	)
	pws = make(map[int][]passEntry)
	scanner := bufio.NewScanner(in)
	remote := "UNKNOWN"
	for scanner.Scan() {
		line := strings.TrimSpace(scanner.Text())
		if len(line) < 4 {
			continue
		}
		if line[0] == '[' && line[len(line)-1] == ']' {
			remote = line[1 : len(line)-1]
			remotes++
			continue
		}
		if strings.Contains(line, "RCLONE_ENCRYPT") {
			log.Fatalf("Can't read encrypted config files - please decrypt first")
		}
		if !strings.HasPrefix(line, "pass") {
			continue
		}
		equal := strings.IndexRune(line, '=')
		if equal < 0 {
			continue
		}
		key, value := strings.TrimSpace(line[:equal]), strings.TrimSpace(line[equal+1:])
		if len(value) == 0 {
			continue
		}
		if key == "pass" || key == "password" || key == "password2" {
			debugf("remote = %q, key = %q, value = %q", remote, key, value)
			pwString, err := obscure.Reveal(value)
			if err != nil {
				debugf("%s: %s = %q is not an obscured password: %v", remote, key, value, err)
				nonGeneratedPasswords++
				continue
			}
			pw, err := base64.RawURLEncoding.DecodeString(pwString)
			if err != nil {
				debugf("%s: obscured password %s = %q  was not generated by rclone: %v", remote, key, value, err)
				nonGeneratedPasswords++
				continue
			}
			if len(pw) < *minBits/8 {
				debugf("%s: IGNORING obscured password %s = %q is only %d bits (set with -min-bits)", remote, key, value, len(pw)*8)
				tooShortPasswords++
				continue
			}
			generatedPasswords++
			pws[len(pw)] = append(pws[len(pw)],
				passEntry{
					remote:   remote,
					pw:       pw,
					obscured: value,
				},
			)
		}
	}
	if err := scanner.Err(); err != nil {
		log.Fatal(err)
	}
	log.Printf("found %d remote definitions", remotes)
	log.Printf("found %d passwords generated by rclone config which need checking", generatedPasswords)
	log.Printf("ignored %d passwords not generated by rclone config", nonGeneratedPasswords)
	log.Printf("ignored %d passwords less than %d bits", tooShortPasswords, *minBits)
	return pws
}
read the config file and return candidate passwords grouped by length
package main
import (
	"bufio"
	"bytes"
	"encoding/base64"
	"flag"
	"fmt"
	"io"
	"log"
	"math/rand"
	"os"
	"runtime"
	"sort"
	"strings"
	"sync"
	"time"
	"github.com/rclone/rclone/fs/config/obscure"
)
const timeFormat = "2006-01-02 15:04:05"
var (
	startDate = flag.String("start-date", "2019-08-25 00:00:00", "Start date to search from")
	endDate   = flag.String("end-date", time.Now().Format(timeFormat), "End date to search to")
	minBits   = flag.Int("min-bits", 64, "Minimum number of bits to search in a password")
	verbose   = flag.Bool("verbose", false, "Set to print more things")
	version   = "development version"  
)
type passEntry struct {
	remote   string
	pw       []byte
	obscured string
}
type foundReport struct {
	mu    sync.Mutex
	found []passEntry
}
func newFoundReport() *foundReport {
	return &foundReport{}
}
func (report *foundReport) add(pw passEntry) {
	report.mu.Lock()
	defer report.mu.Unlock()
	report.found = append(report.found, pw)
}
func debugf(format string, v ...interface{}) {
	if *verbose {
		log.Printf(format, v...)
	}
}
func password(rng *rand.Rand, pw []byte) {
	n, err := rng.Read(pw)
	if err != nil {
		log.Fatalf("password read failed: %v", err)
	}
	if n != len(pw) {
		log.Fatalf("password short read: %d", n)
	}
}
func passString(pw []byte) string {
	return base64.RawURLEncoding.EncodeToString(pw)
}
func seedString(seed int64) string {
	return fmt.Sprintf("seed %d generated at %v", seed, time.Unix(seed, 0).Format(timeFormat))
}