maddy

Fork https://github.com/foxcpp/maddy

git clone git://git.lin.moe/go/maddy.git

  1/*
  2Maddy Mail Server - Composable all-in-one email server.
  3Copyright © 2019-2020 Max Mazurov <fox.cpp@disroot.org>, Maddy Mail Server contributors
  4
  5This program is free software: you can redistribute it and/or modify
  6it under the terms of the GNU General Public License as published by
  7the Free Software Foundation, either version 3 of the License, or
  8(at your option) any later version.
  9
 10This program is distributed in the hope that it will be useful,
 11but WITHOUT ANY WARRANTY; without even the implied warranty of
 12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13GNU General Public License for more details.
 14
 15You should have received a copy of the GNU General Public License
 16along with this program.  If not, see <https://www.gnu.org/licenses/>.
 17*/
 18
 19package remote
 20
 21import (
 22	"github.com/foxcpp/maddy/framework/config"
 23	modconfig "github.com/foxcpp/maddy/framework/config/module"
 24	"github.com/foxcpp/maddy/framework/module"
 25)
 26
 27// PolicyGroup is a module container for a group of Policy implementations.
 28//
 29// It allows to share a set of policy configurations between remote target
 30// instances using named configuration blocks (module instances) system.
 31//
 32// It is registered globally under the name 'mx_auth'. This is also the name of
 33// corresponding remote target configuration directive. The object does not
 34// implement any standard module interfaces besides module.Module and is
 35// specific to the remote target.
 36type PolicyGroup struct {
 37	L        []module.MXAuthPolicy
 38	instName string
 39	pols     map[string]module.MXAuthPolicy
 40}
 41
 42func (pg *PolicyGroup) Init(cfg *config.Map) error {
 43	var debugLog bool
 44	cfg.Bool("debug", true, false, &debugLog)
 45	cfg.AllowUnknown()
 46	other, err := cfg.Process()
 47	if err != nil {
 48		return err
 49	}
 50
 51	// Policies have defined application order since some of them depend on
 52	// results of other policies. We first initialize them in the order they
 53	// are defined in and then reorder depending on the needed order.
 54
 55	for _, block := range other {
 56		if _, ok := pg.pols[block.Name]; ok {
 57			return config.NodeErr(block, "duplicate policy block: %v", block.Name)
 58		}
 59
 60		var policy module.MXAuthPolicy
 61		err := modconfig.ModuleFromNode("mx_auth", append([]string{block.Name}, block.Args...), block, cfg.Globals, &policy)
 62		if err != nil {
 63			return err
 64		}
 65
 66		pg.pols[block.Name] = policy
 67	}
 68
 69	for _, name := range [...]string{
 70		"mtasts",
 71		// sts_preload should go after mtasts so it will take not effect if
 72		// MXLevel is already MX_MTASTS.
 73		"sts_preload",
 74		"dane",
 75		"dnssec",
 76		// localPolicy should be the last one, since it considers levels defined by
 77		// other policies.
 78		"local_policy",
 79	} {
 80		policy, ok := pg.pols[name]
 81		if !ok {
 82			continue
 83		}
 84		pg.L = append(pg.L, policy)
 85	}
 86
 87	return nil
 88}
 89
 90func (PolicyGroup) Name() string {
 91	return "mx_auth"
 92}
 93
 94func (pg PolicyGroup) InstanceName() string {
 95	return pg.instName
 96}
 97
 98func init() {
 99	module.Register("mx_auth", func(_, instName string, _, _ []string) (module.Module, error) {
100		return &PolicyGroup{
101			instName: instName,
102			pols:     map[string]module.MXAuthPolicy{},
103		}, nil
104	})
105}