author | Alberto Bertogli
<albertito@blitiri.com.ar> 2016-09-23 23:44:13 UTC |
committer | Alberto Bertogli
<albertito@blitiri.com.ar> 2016-10-09 23:51:04 UTC |
parent | 859d4733f8429e86dbf04af06f95848602c258f6 |
chasquid.go | +1 | -0 |
cmd/chasquid-userdb/chasquid-userdb.go | +0 | -92 |
cmd/chasquid-util/chasquid-util.go | +198 | -0 |
internal/aliases/aliases.go | +3 | -3 |
internal/config/config.go | +1 | -2 |
test/util/lib.sh | +2 | -4 |
diff --git a/chasquid.go b/chasquid.go index 462619e..ee60ef5 100644 --- a/chasquid.go +++ b/chasquid.go @@ -60,6 +60,7 @@ func main() { if err != nil { glog.Fatalf("Error reading config") } + config.LogConfig(conf) // Change to the config dir. // This allow us to use relative paths for configuration directories. diff --git a/cmd/chasquid-userdb/chasquid-userdb.go b/cmd/chasquid-userdb/chasquid-userdb.go deleted file mode 100644 index 8f6f7e6..0000000 --- a/cmd/chasquid-userdb/chasquid-userdb.go +++ /dev/null @@ -1,92 +0,0 @@ -package main - -import ( - "bytes" - "flag" - "fmt" - "os" - "syscall" - - "golang.org/x/crypto/ssh/terminal" - - "blitiri.com.ar/go/chasquid/internal/userdb" -) - -var ( - dbFname = flag.String("database", "", "database file") - adduser = flag.String("add_user", "", "user to add") - password = flag.String("password", "", - "password for the user to add (will prompt if missing)") - disableChecks = flag.Bool("dangerously_disable_checks", false, - "disable security checks - DANGEROUS, use for testing only") -) - -func main() { - flag.Parse() - - if *dbFname == "" { - fmt.Printf("database name missing, forgot --database?\n") - os.Exit(1) - } - - db, err := userdb.Load(*dbFname) - if err != nil { - if *adduser != "" && os.IsNotExist(err) { - fmt.Printf("creating database\n") - } else { - fmt.Printf("error loading database: %v\n", err) - os.Exit(1) - } - } - - if *adduser == "" { - fmt.Printf("database loaded\n") - return - } - - if *password == "" { - fmt.Printf("Password: ") - p1, err := terminal.ReadPassword(syscall.Stdin) - fmt.Printf("\n") - if err != nil { - fmt.Printf("error reading password: %v\n", err) - os.Exit(1) - } - - fmt.Printf("Confirm password: ") - p2, err := terminal.ReadPassword(syscall.Stdin) - fmt.Printf("\n") - if err != nil { - fmt.Printf("error reading password: %v\n", err) - os.Exit(1) - } - - if !bytes.Equal(p1, p2) { - fmt.Printf("passwords don't match\n") - os.Exit(1) - } - - *password = string(p1) - } - - if !*disableChecks { - if len(*password) < 8 { - fmt.Printf("password is too short\n") - os.Exit(1) - } - } - - err = db.AddUser(*adduser, *password) - if err != nil { - fmt.Printf("error adding user: %v\n", err) - os.Exit(1) - } - - err = db.Write() - if err != nil { - fmt.Printf("error writing database: %v\n", err) - os.Exit(1) - } - - fmt.Printf("added user\n") -} diff --git a/cmd/chasquid-util/chasquid-util.go b/cmd/chasquid-util/chasquid-util.go new file mode 100644 index 0000000..3d737e6 --- /dev/null +++ b/cmd/chasquid-util/chasquid-util.go @@ -0,0 +1,198 @@ +// chasquid-util is a command-line utility for chasquid-related operations. +package main + +import ( + "fmt" + "io/ioutil" + "os" + "syscall" + + "bytes" + + "blitiri.com.ar/go/chasquid/internal/aliases" + "blitiri.com.ar/go/chasquid/internal/config" + "blitiri.com.ar/go/chasquid/internal/userdb" + + "github.com/docopt/docopt-go" + "golang.org/x/crypto/ssh/terminal" +) + +// Usage, which doubles as parameter definitions thanks to docopt. +const usage = ` +Usage: + chasquid-util adduser <db> <username> [--password=<password>] + chasquid-util removeuser <db> <username> + chasquid-util authenticate <db> <username> [--password=<password>] + chasquid-util check-userdb <db> + chasquid-util aliases-resolve <configdir> <address> +` + +// Command-line arguments. +var args map[string]interface{} + +func main() { + args, _ = docopt.Parse(usage, nil, true, "", false) + + commands := map[string]func(){ + "adduser": AddUser, + "removeuser": RemoveUser, + "authenticate": Authenticate, + "check-userdb": CheckUserDB, + "aliases-resolve": AliasesResolve, + } + + for cmd, f := range commands { + if args[cmd].(bool) { + f() + } + } +} + +func Fatalf(s string, arg ...interface{}) { + fmt.Printf(s+"\n", arg...) + os.Exit(1) +} + +// chasquid-util check-userdb <db> +func CheckUserDB() { + _, err := userdb.Load(args["<db>"].(string)) + if err != nil { + Fatalf("Error loading database: %v", err) + } + + fmt.Println("Database loaded") +} + +// chasquid-util adduser <db> <username> [--password=<password>] +func AddUser() { + db, err := userdb.Load(args["<db>"].(string)) + if err != nil { + if os.IsNotExist(err) { + fmt.Println("Creating database") + } else { + Fatalf("Error loading database: %v", err) + } + } + + password := getPassword() + + err = db.AddUser(args["<username>"].(string), password) + if err != nil { + Fatalf("Error adding user: %v", err) + } + + err = db.Write() + if err != nil { + Fatalf("Error writing database: %v", err) + } + + fmt.Println("Added user") +} + +// chasquid-util authenticate <db> <username> [--password=<password>] +func Authenticate() { + db, err := userdb.Load(args["<db>"].(string)) + if err != nil { + Fatalf("Error loading database: %v", err) + } + + password := getPassword() + ok := db.Authenticate(args["<username>"].(string), password) + if ok { + fmt.Println("Authentication succeeded") + } else { + Fatalf("Authentication failed") + } +} + +func getPassword() string { + password, ok := args["--password"].(string) + if ok { + return password + } + + fmt.Printf("Password: ") + p1, err := terminal.ReadPassword(syscall.Stdin) + fmt.Printf("\n") + if err != nil { + Fatalf("Error reading password: %v\n", err) + } + + fmt.Printf("Confirm password: ") + p2, err := terminal.ReadPassword(syscall.Stdin) + fmt.Printf("\n") + if err != nil { + Fatalf("Error reading password: %v", err) + } + + if !bytes.Equal(p1, p2) { + Fatalf("Passwords don't match") + } + + return string(p1) +} + +// chasquid-util removeuser <db> <username> +func RemoveUser() { + db, err := userdb.Load(args["<db>"].(string)) + if err != nil { + Fatalf("Error loading database: %v", err) + } + + present := db.RemoveUser(args["<username>"].(string)) + if !present { + Fatalf("Unknown user") + } + + err = db.Write() + if err != nil { + Fatalf("Error writing database: %v", err) + } + + fmt.Println("Removed user") +} + +// chasquid-util aliases-resolve <configdir> <address> +func AliasesResolve() { + configDir := args["<configdir>"].(string) + conf, err := config.Load(configDir + "/chasquid.conf") + if err != nil { + Fatalf("Error reading config") + } + os.Chdir(configDir) + + r := aliases.NewResolver() + r.SuffixSep = conf.SuffixSeparators + r.DropChars = conf.DropCharacters + + domainDirs, err := ioutil.ReadDir("domains/") + if err != nil { + Fatalf("Error reading domains/ directory: %v", err) + } + if len(domainDirs) == 0 { + Fatalf("No domains found in config") + } + + for _, info := range domainDirs { + name := info.Name() + aliasfile := "domains/" + name + "/aliases" + r.AddDomain(name) + err := r.AddAliasesFile(name, aliasfile) + if err == nil { + fmt.Printf("%s: loaded %q\n", name, aliasfile) + } else if err != nil && os.IsNotExist(err) { + fmt.Printf("%s: no aliases file\n", name) + } else { + fmt.Printf("%s: error loading %q: %v\n", name, aliasfile, err) + } + } + + rcpts, err := r.Resolve(args["<address>"].(string)) + if err != nil { + Fatalf("Error resolving: %v", err) + } + for _, rcpt := range rcpts { + fmt.Printf("%v %s\n", rcpt.Type, rcpt.Addr) + } + +} diff --git a/internal/aliases/aliases.go b/internal/aliases/aliases.go index 1b37fa1..d251f48 100644 --- a/internal/aliases/aliases.go +++ b/internal/aliases/aliases.go @@ -69,11 +69,11 @@ type Recipient struct { Type RType } -type RType int +type RType string const ( - EMAIL RType = iota - PIPE + EMAIL RType = "(email)" + PIPE RType = "(pipe)" ) var ( diff --git a/internal/config/config.go b/internal/config/config.go index bbf4e0a..e815d03 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -62,11 +62,10 @@ func Load(path string) (*Config, error) { c.DataDir = "/var/lib/chasquid" } - logConfig(c) return c, nil } -func logConfig(c *Config) { +func LogConfig(c *Config) { glog.Infof("Configuration:") glog.Infof(" Hostname: %q", c.Hostname) glog.Infof(" Max data size (MB): %d", c.MaxDataSizeMb) diff --git a/test/util/lib.sh b/test/util/lib.sh index 3ea873e..f876039 100644 --- a/test/util/lib.sh +++ b/test/util/lib.sh @@ -35,10 +35,8 @@ function chasquid() { } function add_user() { - go run ${TBASE}/../../cmd/chasquid-userdb/chasquid-userdb.go \ - --database "config/domains/${1}/users" \ - --add_user "${2}" \ - --password "${3}" \ + go run ${TBASE}/../../cmd/chasquid-util/chasquid-util.go \ + adduser "config/domains/${1}/users" "${2}" --password "${3}" \ >> .add_user_logs }