1/*2Maddy Mail Server - Composable all-in-one email server.3Copyright © 2019-2020 Max Mazurov <fox.cpp@disroot.org>, Maddy Mail Server contributors45This program is free software: you can redistribute it and/or modify6it under the terms of the GNU General Public License as published by7the Free Software Foundation, either version 3 of the License, or8(at your option) any later version.910This program is distributed in the hope that it will be useful,11but WITHOUT ANY WARRANTY; without even the implied warranty of12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13GNU General Public License for more details.1415You should have received a copy of the GNU General Public License16along with this program. If not, see <https://www.gnu.org/licenses/>.17*/1819package remote2021import (22 "github.com/foxcpp/maddy/framework/config"23 modconfig "github.com/foxcpp/maddy/framework/config/module"24 "github.com/foxcpp/maddy/framework/module"25)2627// PolicyGroup is a module container for a group of Policy implementations.28//29// It allows to share a set of policy configurations between remote target30// instances using named configuration blocks (module instances) system.31//32// It is registered globally under the name 'mx_auth'. This is also the name of33// corresponding remote target configuration directive. The object does not34// implement any standard module interfaces besides module.Module and is35// specific to the remote target.36type PolicyGroup struct {37 L []module.MXAuthPolicy38 instName string39 pols map[string]module.MXAuthPolicy40}4142func (pg *PolicyGroup) Init(cfg *config.Map) error {43 var debugLog bool44 cfg.Bool("debug", true, false, &debugLog)45 cfg.AllowUnknown()46 other, err := cfg.Process()47 if err != nil {48 return err49 }5051 // Policies have defined application order since some of them depend on52 // results of other policies. We first initialize them in the order they53 // are defined in and then reorder depending on the needed order.5455 for _, block := range other {56 if _, ok := pg.pols[block.Name]; ok {57 return config.NodeErr(block, "duplicate policy block: %v", block.Name)58 }5960 var policy module.MXAuthPolicy61 err := modconfig.ModuleFromNode("mx_auth", append([]string{block.Name}, block.Args...), block, cfg.Globals, &policy)62 if err != nil {63 return err64 }6566 pg.pols[block.Name] = policy67 }6869 for _, name := range [...]string{70 "mtasts",71 // sts_preload should go after mtasts so it will take not effect if72 // MXLevel is already MX_MTASTS.73 "sts_preload",74 "dane",75 "dnssec",76 // localPolicy should be the last one, since it considers levels defined by77 // other policies.78 "local_policy",79 } {80 policy, ok := pg.pols[name]81 if !ok {82 continue83 }84 pg.L = append(pg.L, policy)85 }8687 return nil88}8990func (PolicyGroup) Name() string {91 return "mx_auth"92}9394func (pg PolicyGroup) InstanceName() string {95 return pg.instName96}9798func 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 }, nil104 })105}