mirror of
https://github.com/foxcpp/maddy.git
synced 2025-04-06 06:27:38 +03:00
* Change default files location as described in #27 * config: Change default config file name
115 lines
2.6 KiB
Go
115 lines
2.6 KiB
Go
package maddy
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/emersion/maddy/config"
|
|
"github.com/emersion/maddy/log"
|
|
"github.com/emersion/maddy/module"
|
|
)
|
|
|
|
type ExternalAuth struct {
|
|
modName string
|
|
instName string
|
|
helperPath string
|
|
|
|
Log log.Logger
|
|
}
|
|
|
|
func NewExternalAuth(modName, instName string) (module.Module, error) {
|
|
ea := &ExternalAuth{
|
|
modName: modName,
|
|
instName: instName,
|
|
Log: log.Logger{Name: modName},
|
|
}
|
|
|
|
return ea, nil
|
|
}
|
|
|
|
func (ea *ExternalAuth) Name() string {
|
|
return ea.modName
|
|
}
|
|
|
|
func (ea *ExternalAuth) InstanceName() string {
|
|
return ea.instName
|
|
}
|
|
|
|
func (ea *ExternalAuth) Init(cfg *config.Map) error {
|
|
cfg.Bool("debug", true, &ea.Log.Debug)
|
|
cfg.String("helper", false, false, "", &ea.helperPath)
|
|
if _, err := cfg.Process(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if ea.helperPath != "" {
|
|
ea.Log.Debugln("using helper:", ea.helperPath)
|
|
return nil
|
|
}
|
|
|
|
helperName := "maddy-auth-helper"
|
|
switch ea.modName {
|
|
case "pam":
|
|
helperName = "maddy-pam-helper"
|
|
case "shadow":
|
|
helperName = "maddy-shadow-helper"
|
|
}
|
|
|
|
ea.helperPath = filepath.Join(LibexecDirectory(cfg.Globals), helperName)
|
|
if _, err := os.Stat(ea.helperPath); err != nil {
|
|
return fmt.Errorf("no %s authentication support, %s is not found in %s and no custom path is set", ea.modName, LibexecDirectory(cfg.Globals), helperName)
|
|
}
|
|
|
|
ea.Log.Debugln("using helper:", ea.helperPath)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (ea *ExternalAuth) CheckPlain(username, password string) bool {
|
|
cmd := exec.Command(ea.helperPath)
|
|
stdin, err := cmd.StdinPipe()
|
|
if err != nil {
|
|
ea.Log.Println("failed to obtain stdin pipe for helper process:", err)
|
|
return false
|
|
}
|
|
|
|
if err := cmd.Start(); err != nil {
|
|
ea.Log.Println("failed to start helper process:", err)
|
|
return false
|
|
}
|
|
|
|
if _, err := io.WriteString(stdin, username+"\n"); err != nil {
|
|
ea.Log.Println("failed to write stdin of helper process:", err)
|
|
return false
|
|
}
|
|
if _, err := io.WriteString(stdin, password+"\n"); err != nil {
|
|
ea.Log.Println("failed to write stdin of helper process:", err)
|
|
return false
|
|
}
|
|
|
|
if err := cmd.Wait(); err != nil {
|
|
ea.Log.Debugln(err)
|
|
if exitErr, ok := err.(*exec.ExitError); ok {
|
|
// Exit code 1 is for authentication failure.
|
|
// Exit code 2 is for other errors.
|
|
if exitErr.ExitCode() == 2 {
|
|
ea.Log.Println(strings.TrimSpace(string(exitErr.Stderr)))
|
|
}
|
|
} else {
|
|
ea.Log.Println("failed to wait for helper process:", err)
|
|
}
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func init() {
|
|
module.Register("extauth", NewExternalAuth)
|
|
module.Register("pam", NewExternalAuth)
|
|
module.Register("shadow", NewExternalAuth)
|
|
}
|