checking in
This commit is contained in:
34
common/consts.go
Normal file
34
common/consts.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
`os`
|
||||
`syscall`
|
||||
`time`
|
||||
)
|
||||
|
||||
const (
|
||||
/*
|
||||
DefaultTimePeriod is the default time period for TOTP.
|
||||
|
||||
See [RFC 6238 § 4.1], [RFC 6238 § 4.1], [RFC 6238 § 6], and [RFC 6238 Appendix A].
|
||||
|
||||
[RFC 6238 § 4.1]: https://datatracker.ietf.org/doc/html/rfc6238#section-4.1
|
||||
[RFC 6238 § 5.2]: https://datatracker.ietf.org/doc/html/rfc6238#section-5.2
|
||||
[RFC 6238 § 6]: https://datatracker.ietf.org/doc/html/rfc6238#section-6
|
||||
[RFC 6238 Appendix A]: https://datatracker.ietf.org/doc/html/rfc6238#appendix-A
|
||||
*/
|
||||
DefaultTimePeriod time.Duration = time.Second * 30
|
||||
|
||||
// VaultRepl is used to replace any invalid characters in a name.
|
||||
VaultRepl rune = '_'
|
||||
)
|
||||
|
||||
var (
|
||||
// ProgEndSigs are used to trap signals and gracefully quit. Note that these don't really have a Windows equivalent.
|
||||
ProgEndSigs []os.Signal = []os.Signal{
|
||||
os.Interrupt, // SIGINT, signal 2 (ctrl+c)
|
||||
syscall.SIGQUIT, // signal 3 (ctrl + \\) (SIGINT but with coredump)
|
||||
os.Kill, // SIGKILL, signal 9 (useless to capture since the program can't ignore/trap it)
|
||||
syscall.SIGTERM, // signal 15 (`kill` default)
|
||||
}
|
||||
)
|
||||
145
common/funcs.go
Normal file
145
common/funcs.go
Normal file
@@ -0,0 +1,145 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
`math`
|
||||
`time`
|
||||
)
|
||||
|
||||
/*
|
||||
CurrentTimeStep returns the current time step using the given
|
||||
[time.Duration] `period`.
|
||||
|
||||
If `period` is equal to time.Duration(0), it will be set to [DefaultTimePeriod].
|
||||
*/
|
||||
func CurrentTimeStep(period time.Duration) (ts int64) {
|
||||
return TimeStepFromTime(time.Now(), period)
|
||||
}
|
||||
|
||||
/*
|
||||
OffsetTimeStep is like [CurrentTimeStep] but returns the time step next/previous
|
||||
to the current specified by `offset` (`offset` may be negative or positive).
|
||||
*/
|
||||
func OffsetTimeStep(period time.Duration, offset int64) (ts int64) {
|
||||
|
||||
var offsetDuration time.Duration
|
||||
|
||||
period = normalizePeriod(period)
|
||||
|
||||
offsetDuration = period * time.Duration(offset)
|
||||
|
||||
ts = TimeStepFromTime(time.Now().Add(offsetDuration), period)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
OffsetTimeStepToTime is like [TimeStepToTime] but returns the next/previous
|
||||
time range in relation to time step `ts` specified by `offset` (`offset` may be negative or positive).
|
||||
*/
|
||||
func OffsetTimeStepToTime(ts int64, period time.Duration, offset int64) (start, end time.Time) {
|
||||
return TimeStepToTime(ts+offset, period)
|
||||
}
|
||||
|
||||
/*
|
||||
TimeStepFromTime returns a time step (see [RFC 6238 § 1.2], [RFC 6238 § 5.2])
|
||||
from a provided generation time `t` as a [time.Time] and a life length
|
||||
`period` as a [time.Duration].
|
||||
|
||||
If `period` is equal to time.Duration(0), it will be set to [DefaultTimePeriod].
|
||||
|
||||
[RFC 6238 § 1.2]: https://datatracker.ietf.org/doc/html/rfc6238#section-1.2
|
||||
[RFC 6238 § 5.2]: https://datatracker.ietf.org/doc/html/rfc6238#section-5.2
|
||||
*/
|
||||
func TimeStepFromTime(t time.Time, period time.Duration) (ts int64) {
|
||||
|
||||
period = normalizePeriod(period)
|
||||
|
||||
ts = int64(math.Floor(float64(t.Unix()) / period.Seconds()))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
TimeStepToTime returns a [time.Time] `start` and `end` from a time step `ts`
|
||||
and a lifetime period `period` (as a [time.Duration]).
|
||||
|
||||
If `period` is equal to time.Duration(0), it will be set to [DefaultTimePeriod].
|
||||
*/
|
||||
func TimeStepToTime(ts int64, period time.Duration) (start, end time.Time) {
|
||||
|
||||
var fromEpoch time.Duration
|
||||
|
||||
period = normalizePeriod(period)
|
||||
fromEpoch = (time.Second * time.Duration(ts*int64(period.Seconds()))).Truncate(time.Second)
|
||||
|
||||
start = time.Unix(0, 0).Add(fromEpoch).Truncate(time.Second)
|
||||
end = start.Add(period).Truncate(time.Second)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// VaultEscape is used to normalize a string to a Vault-safe name (for e.g. secrets).
|
||||
func VaultEscape(s *string) {
|
||||
|
||||
var c rune
|
||||
var idx int
|
||||
var last rune
|
||||
var norm []rune
|
||||
var reduced []rune = make([]rune, 0)
|
||||
|
||||
if s == nil {
|
||||
return
|
||||
}
|
||||
norm = make([]rune, 0, len(*s))
|
||||
|
||||
// https://github.com/hashicorp/vault/issues/5645#issuecomment-434404750
|
||||
// It seems they relaxed this a bit since then, as hyphens and periods are also allowed.
|
||||
// https://github.com/hashicorp/vault/blob/main/sdk/framework/path.go#L26
|
||||
// At time of writing, the regex is: (?P<name>\\w(([\\w-.@]+)?\\w)?)
|
||||
// Per comments: "alphanumeric characters along with -, . and @."
|
||||
for _, c = range *s {
|
||||
// If it's "safe" chars, it's fine
|
||||
if (c == '-' || c == '.') || // 0x2d, 0x2e
|
||||
(c >= '0' && c <= '9') || // 0x30 to 0x39
|
||||
(c == '@') || // 0x40
|
||||
(c >= 'A' && c <= 'Z') || // 0x41 to 0x5a
|
||||
(c == '_') || // 0x5f
|
||||
(c >= 'a' && c <= 'z') { // 0x61 to 0x7a
|
||||
norm = append(norm, c)
|
||||
continue
|
||||
}
|
||||
// Otherwise normalize it to a safe char
|
||||
norm = append(norm, VaultRepl)
|
||||
}
|
||||
|
||||
// And remove repeating sequential replacers.
|
||||
for idx, c = range norm[:] {
|
||||
if idx == 0 {
|
||||
last = c
|
||||
reduced = append(reduced, c)
|
||||
continue
|
||||
}
|
||||
if c == last && last == VaultRepl {
|
||||
continue
|
||||
}
|
||||
reduced = append(reduced, c)
|
||||
last = c
|
||||
}
|
||||
|
||||
*s = string(reduced)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// normalizedPeriod returns `period` if non-zero, otherwise [DefaultTimePeriod].
|
||||
func normalizePeriod(period time.Duration) (normalized time.Duration) {
|
||||
|
||||
if period != time.Duration(0) {
|
||||
normalized = period
|
||||
return
|
||||
}
|
||||
|
||||
normalized = DefaultTimePeriod
|
||||
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user