diff --git a/config/krb5conf.go b/config/krb5conf.go index 47ca956b..9993bb99 100644 --- a/config/krb5conf.go +++ b/config/krb5conf.go @@ -555,24 +555,38 @@ func parseETypes(s []string, w bool) []int { // Parse a time duration string in the configuration to a golang time.Duration. func parseDuration(s string) (time.Duration, error) { s = strings.Replace(s, " ", "", -1) + + // handle Nd[NmNs] if strings.Contains(s, "d") { - s = strings.Replace(s, "d", "", -1) - // assume this is a round number for days... - days, err := strconv.ParseInt(s, 10, 32) + ds := strings.SplitN(s, "d", 2) + dn, err := strconv.ParseUint(ds[0], 10, 32) if err != nil { - return time.Duration(0), errors.New("Invalid time duration.") + return time.Duration(0), errors.New("invalid time duration.") + } + d := time.Duration(dn*24) * time.Hour + if ds[1] != "" { + dp, err := time.ParseDuration(ds[1]) + if err != nil { + return time.Duration(0), errors.New("invalid time duration.") + } + d = d + dp } - var secs = int(days) * 86400 - s = strconv.Itoa(secs) + return d, nil } + + // handle Nm[Ns] d, err := time.ParseDuration(s) if err == nil { return d, nil } + + // handle N v, err := strconv.ParseUint(s, 10, 32) if err == nil && v > 0 { return time.Duration(v) * time.Second, nil } + + // handle h:m[:s] if strings.Contains(s, ":") { t := strings.Split(s, ":") if 2 > len(t) || len(t) > 3 { diff --git a/config/krb5conf_test.go b/config/krb5conf_test.go index 047dc29c..0b2160ae 100644 --- a/config/krb5conf_test.go +++ b/config/krb5conf_test.go @@ -99,3 +99,31 @@ func TestLoad(t *testing.T) { assert.Equal(t, "TEST.GOKRB5", c.DomainRealm["test.gokrb5"], "Domain to realm mapping not as expected") } + +func TestParseDuration(t *testing.T) { + // https://web.mit.edu/kerberos/krb5-1.12/doc/basic/date_format.html#duration + hms, _ := time.ParseDuration("12h30m15s") + hm, _ := time.ParseDuration("12h30m") + h, _ := time.ParseDuration("12h") + var tests = []struct { + timeStr string + duration time.Duration + }{ + {"100", time.Duration(100) * time.Second}, + {"12:30", hm}, + {"12:30:15", hms}, + {"1d12h30m15s", time.Duration(24)*time.Hour + hms}, + {"1d12h30m", time.Duration(24)*time.Hour + hm}, + {"1d12h", time.Duration(24)*time.Hour + h}, + {"1d", time.Duration(24) * time.Hour}, + } + for _, test := range tests { + d, err := parseDuration(test.timeStr) + if err != nil { + t.Errorf("Error parsing %s: %v", test.timeStr, err) + } + assert.Equal(t, test.duration, d, "Duration not as expected for: "+test.timeStr) + + } + +}