feat-use-new-passwd (#1095)

implements a new password system that includes preferred hash + complexity to automatically rehash on login if needed.

~~This is using argon2i but i can add support for argon2id.~~

now prefers argon2id per comments on #1093

closes #1093

Co-authored-by: Jon Lundy <jon@xuu.cc>
Co-authored-by: James Mills <prologic@shortcircuit.net.au>
Reviewed-on: #1095
Reviewed-by: lyse <lyse@noreply@mills.io>
Reviewed-by: James Mills <james@mills.io>
pull/1097/head
xuu 2 months ago
parent 1c10cf95ec
commit b0f72b9e9b
  1. 2
      CHANGELOG.md
  2. 12
      go.mod
  3. 44
      go.sum
  4. 31
      internal/api.go
  5. 16
      internal/login_handlers.go
  6. 8
      internal/manage_handlers.go
  7. 4
      internal/password_handlers.go
  8. 12
      internal/passwords/passwords.go
  9. 75
      internal/passwords/scrypt_passwords.go
  10. 4
      internal/register_handler.go
  11. 12
      internal/server.go
  12. 4
      internal/settings_handlers.go

@ -556,7 +556,7 @@
### Bug Fixes
* Fix bug in setting tokens for passwrod reset and magiclink auth
* Fix bug in setting tokens for password reset and magiclink auth
* Fix minor bug in TTLCache.get()
* Fix cached tokens to be deleted after use
* Fix token expiry check on password reset form

@ -22,7 +22,6 @@ require (
github.com/disintegration/gift v1.2.1
github.com/disintegration/imageorient v0.0.0-20180920195336-8147d86e83ec
github.com/dustin/go-humanize v1.0.0
github.com/elithrar/simple-scrypt v1.3.0
github.com/gabstv/merger v1.0.1
github.com/gavv/httpexpect/v2 v2.3.1
github.com/go-mail/mail v2.3.1+incompatible
@ -70,11 +69,11 @@ require (
go.yarn.social/client v0.0.0-20221026065557-81f92f9fecbc
go.yarn.social/lextwt v0.0.0-20221203211349-536564c27b3e
go.yarn.social/types v0.0.0-20221027173319-2d00e96a95c1
golang.org/x/crypto v0.3.0
golang.org/x/net v0.2.0
golang.org/x/crypto v0.4.0
golang.org/x/net v0.3.0
golang.org/x/sync v0.1.0
golang.org/x/term v0.2.0
golang.org/x/text v0.4.0
golang.org/x/term v0.3.0
golang.org/x/text v0.5.0
gopkg.in/yaml.v2 v2.4.0
willnorris.com/go/microformats v1.1.1
)
@ -154,6 +153,7 @@ require (
github.com/rivo/uniseg v0.4.3 // indirect
github.com/sergi/go-diff v1.0.0 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/sour-is/go-passwd v0.1.0
github.com/spf13/afero v1.9.3 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
@ -169,7 +169,7 @@ require (
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect
golang.org/x/exp v0.0.0-20221126150942-6ab00d035af9 // indirect
golang.org/x/image v0.1.0 // indirect
golang.org/x/sys v0.2.0 // indirect
golang.org/x/sys v0.3.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect

@ -54,12 +54,8 @@ github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g=
github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8=
github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
@ -120,8 +116,6 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
github.com/bits-and-blooms/bitset v1.3.3 h1:R1XWiopGiXf66xygsiLpzLo67xEYvMkHw3w+rCOSAwg=
github.com/bits-and-blooms/bitset v1.3.3/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
github.com/bits-and-blooms/bitset v1.4.0 h1:+YZ8ePm+He2pU3dZlIZiOeAKfrBkXi1lSrXJ/Xzgbu8=
github.com/bits-and-blooms/bitset v1.4.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
@ -154,10 +148,8 @@ github.com/blugelabs/query_string v0.3.0/go.mod h1:H0YFWhYAf8/xcv1zoswoUC8kM/fE9
github.com/caio/go-tdigest v3.1.0+incompatible h1:uoVMJ3Q5lXmVLCCqaMGHLBWnbGoN6Lpu7OAUPR60cds=
github.com/caio/go-tdigest v3.1.0+incompatible/go.mod h1:sHQM/ubZStBUmF1WbB8FAm8q9GjDajLC5T7ydxE3JHI=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
@ -203,8 +195,6 @@ github.com/disintegration/imageorient v0.0.0-20180920195336-8147d86e83ec h1:YrB6
github.com/disintegration/imageorient v0.0.0-20180920195336-8147d86e83ec/go.mod h1:K0KBFIr1gWu/C1Gp10nFAcAE4hsB7JxE6OgLijrJ8Sk=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/elithrar/simple-scrypt v1.3.0 h1:KIlOlxdoQf9JWKl5lMAJ28SY2URB0XTRDn2TckyzAZg=
github.com/elithrar/simple-scrypt v1.3.0/go.mod h1:U2XQRI95XHY0St410VE3UjT7vuKb1qPwrl/EJwEqnZo=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
@ -259,8 +249,6 @@ github.com/go-playground/validator/v10 v10.9.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSG
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/goccy/go-yaml v1.9.6 h1:KhAu1zf9JXnm3vbG49aDE0E5uEBUsM4uwD31/58ZWyI=
github.com/goccy/go-yaml v1.9.6/go.mod h1:JubOolP3gh0HpiBc4BLRD4YmjEjHAmIIB2aaXKkTfoE=
github.com/goccy/go-yaml v1.9.7 h1:D/Vx+JITklB1ugSkncB4BNR67M3X6AKs9+rqVeo3ddw=
github.com/goccy/go-yaml v1.9.7/go.mod h1:JubOolP3gh0HpiBc4BLRD4YmjEjHAmIIB2aaXKkTfoE=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
@ -401,8 +389,6 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4=
github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU=
github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
@ -414,7 +400,6 @@ github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK
github.com/imkira/go-interpol v1.0.0 h1:HrmLyvOLJyjR0YofMw8QGdCIuYOs4TJUBDNU5sJC09E=
github.com/imkira/go-interpol v1.0.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
@ -491,6 +476,7 @@ github.com/marksalpeter/sugar v0.0.0-20160713164314-a69afe358ea8 h1:1gRDEC07kIwB
github.com/marksalpeter/sugar v0.0.0-20160713164314-a69afe358ea8/go.mod h1:Pbl6laGVgJOzt66fx/Zxwth5NhgKzyTysQDDqNJxZ3c=
github.com/marksalpeter/token/v2 v2.0.0 h1:kFg3wSxVzozCH3tUFgcAV3Lao8ngz7sdqE+tUUywbPw=
github.com/marksalpeter/token/v2 v2.0.0/go.mod h1:nCWqOuuJXwlt9mi++BPGtRGXPlaItkTZrZGtN4SqhE8=
github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
@ -569,8 +555,6 @@ github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCko
github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU=
github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o=
github.com/petermattis/goid v0.0.0-20221018141743-354ef7f2fd21 h1:PfiCACRd+dzB+gLQAY3ZekMo/56XZ1haOzEguVZ1ZYE=
github.com/petermattis/goid v0.0.0-20221018141743-354ef7f2fd21/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
github.com/petermattis/goid v0.0.0-20221202122410-a449aaf35945 h1:93/WCXPsxmAhOlA/6/PU9aqYkCVssc370u2DdBGTEq8=
github.com/petermattis/goid v0.0.0-20221202122410-a449aaf35945/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
@ -672,6 +656,10 @@ github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYl
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/sour-is/go-passwd v0.0.1 h1:q8HOJ4hXzAhI5ysZm6xQn7gY2DV/toj8Q8TaDaCK7XQ=
github.com/sour-is/go-passwd v0.0.1/go.mod h1:6AmjTFW3oh3Yi4G46+xfukBx6PfGS+xTdbWFY8c4GJY=
github.com/sour-is/go-passwd v0.1.0 h1:t4ZPhN89/erESdcaZUF+R12VWD413+/DoILYCGGYFuY=
github.com/sour-is/go-passwd v0.1.0/go.mod h1:6AmjTFW3oh3Yi4G46+xfukBx6PfGS+xTdbWFY8c4GJY=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
@ -790,8 +778,6 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
go.yarn.social/client v0.0.0-20221026065557-81f92f9fecbc h1:2NyyP+dsr0Z3g2b585pKOBNkPPrJx6VTCTLSXdU3PAY=
go.yarn.social/client v0.0.0-20221026065557-81f92f9fecbc/go.mod h1:yihDO7q8YbxV2oVnqpNjj6vFlmjnDfDed2MLdYe1Z6k=
go.yarn.social/lextwt v0.0.0-20221117015533-607acebf6e6b h1:zjJ4eMu587eCFLRKIRWbTIidqins/3/XbcNRCybxJQ8=
go.yarn.social/lextwt v0.0.0-20221117015533-607acebf6e6b/go.mod h1:XcveSVLWxkBBW32VEAnewBcnEYw8O2Vb/xqJmXC54Hs=
go.yarn.social/lextwt v0.0.0-20221203211349-536564c27b3e h1:3aWjw20jwH9E4mARvA7jY8lZuvnMMAHwtEBQuKAW/+4=
go.yarn.social/lextwt v0.0.0-20221203211349-536564c27b3e/go.mod h1:XcveSVLWxkBBW32VEAnewBcnEYw8O2Vb/xqJmXC54Hs=
go.yarn.social/types v0.0.0-20221025190911-9524f5b4a743/go.mod h1:XN+G4HprNn/Gp7OF2zveqsCRSWFCHtOaIRh2GlcK+U4=
@ -808,7 +794,6 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
@ -816,8 +801,9 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A=
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8=
golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -832,8 +818,6 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20200228211341-fcea875c7e85/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
golang.org/x/exp v0.0.0-20221114191408-850992195362 h1:NoHlPRbyl1VFI6FjwHtPQCN7wAMXI6cKcqrmXhOOfBQ=
golang.org/x/exp v0.0.0-20221114191408-850992195362/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/exp v0.0.0-20221126150942-6ab00d035af9 h1:yZNXmy+j/JpX19vZkVktWqAo7Gny4PBWYYK3zskGpx4=
golang.org/x/exp v0.0.0-20221126150942-6ab00d035af9/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
@ -917,8 +901,9 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.3.0 h1:VWL6FNY2bEEmsGVKabSlHu5Irp34xmMRoqb/9lF9lxk=
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -1020,13 +1005,15 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0 h1:z85xZCsEl7bi/KwbNADeBYoOP0++7W1ipu+aGnpwzRM=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI=
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -1036,8 +1023,9 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -1253,8 +1241,6 @@ gorm.io/driver/sqlite v1.1.3 h1:BYfdVuZB5He/u9dt4qDpZqiqDJ6KhPqs5QUqsr/Eeuc=
gorm.io/driver/sqlite v1.1.3/go.mod h1:AKDgRWk8lcSQSw+9kxCJnX/yySj8G3rdwYlU57cB45c=
gorm.io/gorm v1.20.1/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
gorm.io/gorm v1.20.6/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
gorm.io/gorm v1.24.1 h1:CgvzRniUdG67hBAzsxDGOAuq4Te1osVMYsa1eQbd4fs=
gorm.io/gorm v1.24.1/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
gorm.io/gorm v1.24.2 h1:9wR6CFD+G8nOusLdvkZelOEhpJVwwHzpQOUM+REd6U0=
gorm.io/gorm v1.24.2/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

@ -21,12 +21,12 @@ import (
jwt "github.com/dgrijalva/jwt-go"
"github.com/julienschmidt/httprouter"
log "github.com/sirupsen/logrus"
"github.com/sour-is/go-passwd"
"github.com/vcraescu/go-paginator"
"github.com/vcraescu/go-paginator/adapter"
"go.mills.io/tasks"
"git.mills.io/prologic/bitcask"
"git.mills.io/yarnsocial/yarn/internal/passwords"
"go.yarn.social/types"
)
@ -62,12 +62,12 @@ type API struct {
cache *Cache
archive Archiver
db Store
pm passwords.Passwords
pm *passwd.Passwd
tasks *tasks.Dispatcher
}
// NewAPI ...
func NewAPI(router *Router, config *Config, cache *Cache, archive Archiver, db Store, pm passwords.Passwords, tasks *tasks.Dispatcher) *API {
func NewAPI(router *Router, config *Config, cache *Cache, archive Archiver, db Store, pm *passwd.Passwd, tasks *tasks.Dispatcher) *API {
api := &API{router, config, cache, archive, db, pm, tasks}
api.initRoutes()
@ -282,10 +282,10 @@ func (a *API) RegisterEndpoint() httprouter.Handle {
return
}
hash, err := a.pm.CreatePassword(password)
hash, err := a.pm.Passwd([]byte(password), nil)
if err != nil {
log.WithError(err).Error("error creating password hash")
http.Error(w, "Passwrod Creation Failed", http.StatusInternalServerError)
http.Error(w, "Password Creation Failed", http.StatusInternalServerError)
return
}
@ -293,7 +293,7 @@ func (a *API) RegisterEndpoint() httprouter.Handle {
user := &User{
Username: username,
Password: hash,
Password: string(hash),
Recovery: recoveryHash,
URL: URLForUser(a.config.BaseURL, username),
CreatedAt: time.Now(),
@ -344,7 +344,7 @@ func (a *API) AuthEndpoint() httprouter.Handle {
}
// Validate cleartext password against KDF hash
err = a.pm.CheckPassword(user.Password, password)
_, err = a.pm.Passwd([]byte(password), []byte(user.Password))
if err != nil {
// #239: Throttle failed login attempts and lock user account.
failed := failures.Inc(user.Username)
@ -355,6 +355,19 @@ func (a *API) AuthEndpoint() httprouter.Handle {
return
}
// Check if password needs to be upgraded.
if !a.pm.IsPreferred([]byte(user.Password)) {
pass, _ := a.pm.Passwd([]byte(password), nil)
user.Password = string(pass)
// Save upgraded user password
if err := a.db.SetUser(username, user); err != nil {
log.WithError(err).Error("error saving user object")
http.Error(w, "User Update Failed", http.StatusInternalServerError)
return
}
}
// #239: Throttle failed login attempts and lock user account.
failures.Reset(user.Username)
@ -797,14 +810,14 @@ func (a *API) SettingsEndpoint() httprouter.Handle {
}
if password != "" {
hash, err := a.pm.CreatePassword(password)
hash, err := a.pm.Passwd([]byte(password), nil)
if err != nil {
log.WithError(err).Error("error creating password hash")
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
user.Password = hash
user.Password = string(hash)
}
if avatarFile != nil {

@ -70,7 +70,7 @@ func (s *Server) LoginHandler() httprouter.Handle {
}
// Validate cleartext password against KDF hash
err = s.pm.CheckPassword(user.Password, password)
_, err = s.pm.Passwd([]byte(password), []byte(user.Password))
if err != nil {
// #239: Throttle failed login attempts and lock user account.
failed := failures.Inc(user.Username)
@ -83,6 +83,20 @@ func (s *Server) LoginHandler() httprouter.Handle {
return
}
// Check if password needs to be upgraded.
if !s.pm.IsPreferred([]byte(user.Password)) {
pass, _ := s.pm.Passwd([]byte(password), nil)
user.Password = string(pass)
// Save upgraded user password
if err := s.db.SetUser(username, user); err != nil {
ctx.Error = true
ctx.Message = s.tr(ctx, "ErrorSetUser")
s.render("error", w, ctx)
return
}
}
// #239: Throttle failed login attempts and lock user account.
failures.Reset(user.Username)

@ -250,7 +250,7 @@ func (s *Server) AddUserHandler() httprouter.Handle {
return
}
hash, err := s.pm.CreatePassword(password)
hash, err := s.pm.Passwd([]byte(password), nil)
if err != nil {
log.WithError(err).Error("error creating password hash")
http.Error(w, err.Error(), http.StatusInternalServerError)
@ -262,7 +262,7 @@ func (s *Server) AddUserHandler() httprouter.Handle {
user := NewUser()
user.Username = username
user.Recovery = recoveryHash
user.Password = hash
user.Password = string(hash)
user.URL = URLForUser(s.config.BaseURL, username)
user.CreatedAt = time.Now()
@ -536,7 +536,7 @@ func (s *Server) RstUserHandler() httprouter.Handle {
newPassword := GenerateRandomToken()
hash, err := s.pm.CreatePassword(newPassword)
hash, err := s.pm.Passwd([]byte(newPassword), nil)
if err != nil {
ctx.Error = true
ctx.Message = s.tr(ctx, "ErrorInvalidPassword")
@ -544,7 +544,7 @@ func (s *Server) RstUserHandler() httprouter.Handle {
return
}
user.Password = hash
user.Password = string(hash)
// Save user
if err := s.db.SetUser(username, user); err != nil {

@ -229,7 +229,7 @@ func (s *Server) NewPasswordHandler() httprouter.Handle {
// Reset password
if password != "" {
hash, err := s.pm.CreatePassword(password)
hash, err := s.pm.Passwd([]byte(password), nil)
if err != nil {
ctx.Error = true
ctx.Message = s.tr(ctx, "ErrorGetUser")
@ -237,7 +237,7 @@ func (s *Server) NewPasswordHandler() httprouter.Handle {
return
}
user.Password = hash
user.Password = string(hash)
// Save user
if err := s.db.SetUser(username, user); err != nil {

@ -1,12 +0,0 @@
// Copyright 2020-present Yarn.social
// SPDX-License-Identifier: AGPL-3.0-or-later
package passwords
// Passwords is an interface for creating and verifying secure passwords
// An implementation must implement all methods and it is up to the impl
// which underlying crypto to use for hasing cleartext passwrods.
type Passwords interface {
CreatePassword(password string) (string, error)
CheckPassword(hash, password string) error
}

@ -1,75 +0,0 @@
// Copyright 2020-present Yarn.social
// SPDX-License-Identifier: AGPL-3.0-or-later
package passwords
import (
"time"
scrypt "github.com/elithrar/simple-scrypt"
log "github.com/sirupsen/logrus"
)
const (
// DefaultMaxTimeout default max timeout in ms
DefaultMaxTimeout = 500 * time.Millisecond
// DefaultMaxMemory default max memory in MB
DefaultMaxMemory = 64
)
// Options ...
type Options struct {
maxTimeout time.Duration
maxMemory int
}
// NewOptions ...
func NewOptions(maxTimeout time.Duration, maxMemory int) *Options {
return &Options{maxTimeout, maxMemory}
}
// ScryptPasswords ...
type ScryptPasswords struct {
options *Options
params scrypt.Params
}
// NewScryptPasswords ...
func NewScryptPasswords(options *Options) Passwords {
if options == nil {
options = &Options{}
}
if options.maxTimeout == 0 {
options.maxTimeout = DefaultMaxTimeout
}
if options.maxMemory == 0 {
options.maxMemory = DefaultMaxMemory
}
log.Info("calibrating scrypt parameters ...")
params, err := scrypt.Calibrate(
options.maxTimeout,
options.maxMemory,
scrypt.DefaultParams,
)
if err != nil {
log.Fatalf("error calibrating scrypt params: %s", err)
}
log.WithField("params", params).Info("scrypt params")
return &ScryptPasswords{options, params}
}
// CreatePassword ...
func (sp *ScryptPasswords) CreatePassword(password string) (string, error) {
hash, err := scrypt.GenerateFromPassword([]byte(password), sp.params)
return string(hash), err
}
// CheckPassword ...
func (sp *ScryptPasswords) CheckPassword(hash, password string) error {
return scrypt.CompareHashAndPassword([]byte(hash), []byte(password))
}

@ -90,7 +90,7 @@ func (s *Server) RegisterHandler() httprouter.Handle {
return
}
hash, err := s.pm.CreatePassword(password)
hash, err := s.pm.Passwd([]byte(password), nil)
if err != nil {
log.WithError(err).Error("error creating password hash")
http.Error(w, err.Error(), http.StatusInternalServerError)
@ -101,7 +101,7 @@ func (s *Server) RegisterHandler() httprouter.Handle {
user := NewUser()
user.Username = username
user.Password = hash
user.Password = string(hash)
user.Recovery = recoveryHash
user.URL = URLForUser(s.config.BaseURL, username)
user.CreatedAt = time.Now()

@ -29,6 +29,9 @@ import (
metricsMiddlewarePrometheus "github.com/slok/go-http-metrics/metrics/prometheus"
metricsMiddleware "github.com/slok/go-http-metrics/middleware"
httproutermiddleware "github.com/slok/go-http-metrics/middleware/httprouter"
"github.com/sour-is/go-passwd"
"github.com/sour-is/go-passwd/pkg/argon2"
"github.com/sour-is/go-passwd/pkg/scrypt"
"github.com/unrolled/logger"
"golang.org/x/crypto/acme/autocert"
"willnorris.com/go/microformats"
@ -36,7 +39,6 @@ import (
"git.mills.io/yarnsocial/yarn"
"git.mills.io/yarnsocial/yarn/internal/auth"
"git.mills.io/yarnsocial/yarn/internal/indieweb"
"git.mills.io/yarnsocial/yarn/internal/passwords"
"git.mills.io/yarnsocial/yarn/internal/session"
"go.mills.io/tasks"
"go.yarn.social/types"
@ -93,7 +95,7 @@ type Server struct {
api *API
// Passwords
pm passwords.Passwords
pm *passwd.Passwd
// Translator
translator *Translator
@ -1033,7 +1035,11 @@ func NewServer(bind string, options ...Option) (*Server, error) {
tasks := tasks.NewDispatcher(10, 100) // TODO: Make this configurable?
pm := passwords.NewScryptPasswords(nil)
pm := passwd.New(
argon2.Argon2id, // preferred.
argon2.Argon2i,
scrypt.Simple,
)
sc := NewSessionStore(db, config.SessionCacheTTL)

@ -82,14 +82,14 @@ func (s *Server) SettingsHandler() httprouter.Handle {
}
if password != "" {
hash, err := s.pm.CreatePassword(password)
hash, err := s.pm.Passwd([]byte(password), nil)
if err != nil {
log.WithError(err).Error("error creating password hash")
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
user.Password = hash
user.Password = string(hash)
}
if avatarFile != nil {

Loading…
Cancel
Save