i wrote some code
sophuwu sophie@skisiel.com
Thu, 05 Dec 2024 01:07:37 +0100
M
const.go
→
const.go
@@ -39,17 +39,6 @@ // of the password and the time allowed to enter it, allowing customisation
// ease of use and security const securityLevel = uint64(uint64((15<<2)|0b00)<<(8*4) | uint64((12<<2)|0b01)<<(8*3) | uint64((10<<2)|0b10)<<(8*2) | uint64((6<<2)|0b01)<<8 | uint64((6<<2)|0b10)) -// getSecurityLevel returns the number of digits and seconds allowed for a security level -func getSecurityLevel(i int) (int, int, error) { - - if i > 4 || i < 0 { - return 0, 0, Error("invalid security level") - } - u := (securityLevel & (255 << (8 * uint64(i)))) >> (8 * uint64(i)) - x := int(u & 0b11) - return int(u >> 2), (x*x*25)/10 + (225*x)/10 + 5, nil -} - func Error(text string) error { return &errorString{text} }
M
go.mod
→
go.mod
@@ -4,14 +4,13 @@ go 1.22.3
require ( github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc + github.com/disintegration/imaging v1.6.2 github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 github.com/hqbobo/text2pic v0.0.0-20180823042751-2479e146d720 github.com/pquerna/otp v1.4.0 - golang.org/x/image v0.16.0 ) require ( - github.com/disintegration/imaging v1.6.2 // indirect github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect - golang.org/x/text v0.15.0 // indirect + golang.org/x/image v0.16.0 // indirect )
M
go.sum
→
go.sum
@@ -21,5 +21,3 @@ golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.16.0 h1:9kloLAKhUufZhA12l5fwnx2NZW39/we1UhBesW433jw= golang.org/x/image v0.16.0/go.mod h1:ugSZItdV4nOxyqp56HmXwH0Ry0nBCpjnZdpDaIHdoPs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
M
otp.go
→
otp.go
@@ -20,6 +20,16 @@ ServiceHost = s
} } +// getSecurityLevel returns the number of digits and seconds allowed for a security level +func getSecurityLevel(i int) (otp.Digits, uint, uint, error) { + if i > 4 || i < 0 { + return 0, 0, 0, Error("invalid security level") + } + u := (securityLevel & (255 << (8 * uint64(i)))) >> (8 * uint64(i)) + x := uint(u & 0b11) + return otp.Digits(u >> 2), (x*x*25)/10 + (225*x)/10 + 5, x, nil +} + // OTP holds the information for the otp type OTP struct { Secret string@@ -30,26 +40,37 @@ // Users is a map of users to their otp keys for validation
var Users map[string]OTP // NewUser creates a new user -func NewUser(name string, SecurityLevel ...int) (QRcode, error) { +func NewUser(name string, securityLevel ...int) (QRcode, error) { if _, ok := Users[name]; ok { return QRcode{}, fmt.Errorf("user %s already exists", name) } - seclvl := SecurityLevelDefault - if len(SecurityLevel) > 0 { - seclvl = SecurityLevel[0] + + if len(securityLevel) == 0 { + securityLevel = []int{SecurityLevelDefault} + } + + digits, period, skew, e := getSecurityLevel(securityLevel[0]) + if e != nil { + return QRcode{}, e } + userOtp, e := totp.Generate(totp.GenerateOpts{ Issuer: ServiceHost, AccountName: name, - Digits: otp.Digits(seclvl >> 8), + Digits: digits, + Period: period, }) - if e != nil { return QRcode{}, e } + Users[name] = OTP{ Secret: userOtp.Secret(), - URL: userOtp.URL(), + Vals: totp.ValidateOpts{ + Period: period, + Digits: digits, + Skew: skew, + }, } q, e := GenQR(userOtp.URL(),