Skip to content

Commit

Permalink
Merge pull request openziti#1522 from openziti/allow.totp.domain.config
Browse files Browse the repository at this point in the history
fixes openziti#1416 allows totp provisioning URL domain to be configured
  • Loading branch information
andrewpmartinez authored Jun 14, 2023
2 parents d28d8bc + 07bd7c2 commit 6cc47c6
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 2 deletions.
53 changes: 53 additions & 0 deletions controller/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/openziti/identity"
"github.com/pkg/errors"
"net"
"net/url"
"os"
"reflect"
"strconv"
Expand All @@ -51,6 +52,8 @@ const (
DefaultHttpReadTimeout = 5000 * time.Millisecond
DefaultHttpReadHeaderTimeout = 5000 * time.Millisecond
DefaultHttpWriteTimeout = 100000 * time.Millisecond

DefaultTotpDomain = "openziti.io"
)

type Enrollment struct {
Expand All @@ -65,6 +68,10 @@ type EnrollmentOption struct {
Duration time.Duration
}

type Totp struct {
Hostname string
}

type Api struct {
SessionTimeout time.Duration
ActivityUpdateBatchSize int
Expand All @@ -83,6 +90,7 @@ type Config struct {

caPems *bytes.Buffer
caPemsOnce sync.Once
Totp Totp
}

type HttpTimeouts struct {
Expand Down Expand Up @@ -133,6 +141,47 @@ func (c *Config) RefreshCaPems() {
c.caPems = CalculateCaPems(c.caPems)
}

func (c *Config) loadTotpSection(edgeConfigMap map[any]any) error {
c.Totp = Totp{}
c.Totp.Hostname = DefaultTotpDomain

if value, found := edgeConfigMap["totp"]; found {
if value == nil {
return nil
}

totpMap := value.(map[interface{}]interface{})

if totpMap != nil {
if hostnameVal, found := totpMap["hostname"]; found {

if hostnameVal == nil {
return nil
}

if hostname, ok := hostnameVal.(string); ok {
testUrl := "https://" + hostname
parsedUrl, err := url.Parse(testUrl)

if err != nil {
return fmt.Errorf("could not parse URL: %w", err)
}

if parsedUrl.Hostname() != hostname {
return fmt.Errorf("invalid hostname in [edge.totp.hostname]: %s", hostname)
}

c.Totp.Hostname = hostname
} else {
return fmt.Errorf("[edge.totp.hostname] must be a string")
}
}
}
}

return nil
}

func (c *Config) loadApiSection(edgeConfigMap map[interface{}]interface{}) error {
c.Api = Api{}
c.Api.HttpTimeouts = *DefaultHttpTimeouts()
Expand Down Expand Up @@ -367,6 +416,10 @@ func LoadFromMap(configMap map[interface{}]interface{}) (*Config, error) {
return nil, err
}

if err = edgeConfig.loadTotpSection(edgeConfigMap); err != nil {
return nil, err
}

if err = edgeConfig.loadEnrollmentSection(edgeConfigMap); err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion controller/model/mfa_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ func (self *MfaManager) GetProvisioningUrl(mfa *Mfa) string {
WindowSize: WindowSizeTOTP,
UTC: true,
}
return otcConfig.ProvisionURIWithIssuer(mfa.Identity.Name, "ziti.dev")
return otcConfig.ProvisionURIWithIssuer(mfa.Identity.Name, self.env.GetConfig().Totp.Hostname)
}

func (self *MfaManager) RecreateRecoveryCodes(mfa *Mfa, ctx *change.Context) error {
Expand Down
3 changes: 2 additions & 1 deletion tests/mfa_ziti_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,8 @@ func Test_MFA(t *testing.T) {
mfaUrl, err := url.Parse(provisionString)
ctx.Req.NoError(err)
ctx.Req.Equal(mfaUrl.Host, "totp")
ctx.Req.Equal(mfaUrl.Path, "/ziti.dev:"+mfaStartedIdentityName)

ctx.Req.Equal(mfaUrl.Path, "/"+ctx.EdgeController.AppEnv.Config.Totp.Hostname+":"+mfaStartedIdentityName)
ctx.Req.Equal(mfaUrl.Scheme, "otpauth")
})
})
Expand Down

0 comments on commit 6cc47c6

Please sign in to comment.