mirror of
https://github.com/mjl-/mox.git
synced 2024-12-26 08:23:48 +03:00
fix bug with concurrent math/rand.Rand.Read
firstly by using crypto/rand in those cases. and secondly by putting a lock around the Read (though it isn't used at the moment). found while working while implementing sending tls reports.
This commit is contained in:
parent
d02ac0cb86
commit
2535f351ed
7 changed files with 38 additions and 15 deletions
|
@ -272,7 +272,7 @@ func RemoveEvaluationsDomain(ctx context.Context, domain dns.Domain) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var jitterRand = mox.NewRand()
|
var jitterRand = mox.NewPseudoRand()
|
||||||
|
|
||||||
// time to sleep until next whole hour t, replaced by tests.
|
// time to sleep until next whole hour t, replaced by tests.
|
||||||
// Jitter so we don't cause load at exactly whole hours, other processes may
|
// Jitter so we don't cause load at exactly whole hours, other processes may
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
package mox
|
package mox
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
cryptorand "crypto/rand"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
)
|
)
|
||||||
|
|
||||||
var messageIDRand = NewRand()
|
|
||||||
|
|
||||||
// MessageIDGen returns a generated unique random Message-Id value, excluding <>.
|
// MessageIDGen returns a generated unique random Message-Id value, excluding <>.
|
||||||
func MessageIDGen(smtputf8 bool) string {
|
func MessageIDGen(smtputf8 bool) string {
|
||||||
buf := make([]byte, 16)
|
buf := make([]byte, 16)
|
||||||
messageIDRand.Read(buf)
|
cryptorand.Read(buf)
|
||||||
return base64.RawURLEncoding.EncodeToString(buf) + "@" + Conf.Static.HostnameDomain.XName(smtputf8)
|
return base64.RawURLEncoding.EncodeToString(buf) + "@" + Conf.Static.HostnameDomain.XName(smtputf8)
|
||||||
}
|
}
|
||||||
|
|
19
mox-/rand.go
19
mox-/rand.go
|
@ -5,11 +5,24 @@ import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
mathrand "math/rand"
|
mathrand "math/rand"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewRand returns a new PRNG seeded with random bytes from crypto/rand.
|
type rand struct {
|
||||||
func NewRand() *mathrand.Rand {
|
*mathrand.Rand
|
||||||
return mathrand.New(mathrand.NewSource(CryptoRandInt()))
|
sync.Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPseudoRand returns a new PRNG seeded with random bytes from crypto/rand.
|
||||||
|
func NewPseudoRand() *rand {
|
||||||
|
return &rand{Rand: mathrand.New(mathrand.NewSource(CryptoRandInt()))}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read can be called concurrently.
|
||||||
|
func (r *rand) Read(buf []byte) (int, error) {
|
||||||
|
r.Lock()
|
||||||
|
defer r.Unlock()
|
||||||
|
return r.Rand.Read(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CryptoRandInt returns a cryptographically random number.
|
// CryptoRandInt returns a cryptographically random number.
|
||||||
|
|
|
@ -61,7 +61,7 @@ var (
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
var jitter = mox.NewRand()
|
var jitter = mox.NewPseudoRand()
|
||||||
|
|
||||||
var DBTypes = []any{Msg{}} // Types stored in DB.
|
var DBTypes = []any{Msg{}} // Types stored in DB.
|
||||||
var DB *bstore.DB // Exported for making backups.
|
var DB *bstore.DB // Exported for making backups.
|
||||||
|
|
|
@ -40,11 +40,19 @@ import (
|
||||||
var moxService string
|
var moxService string
|
||||||
|
|
||||||
func pwgen() string {
|
func pwgen() string {
|
||||||
rand := mox.NewRand()
|
|
||||||
chars := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*-_;:,<.>/"
|
chars := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*-_;:,<.>/"
|
||||||
s := ""
|
s := ""
|
||||||
|
buf := make([]byte, 1)
|
||||||
for i := 0; i < 12; i++ {
|
for i := 0; i < 12; i++ {
|
||||||
s += string(chars[rand.Intn(len(chars))])
|
for {
|
||||||
|
cryptorand.Read(buf)
|
||||||
|
i := int(buf[0])
|
||||||
|
if i+len(chars) > 255 {
|
||||||
|
continue // Prevent bias.
|
||||||
|
}
|
||||||
|
s += string(chars[i%len(chars)])
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,7 +168,7 @@ var (
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
var jitterRand = mox.NewRand()
|
var jitterRand = mox.NewPseudoRand()
|
||||||
|
|
||||||
func durationDefault(delay *time.Duration, def time.Duration) time.Duration {
|
func durationDefault(delay *time.Duration, def time.Duration) time.Duration {
|
||||||
if delay == nil {
|
if delay == nil {
|
||||||
|
|
|
@ -24,6 +24,7 @@ package store
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
|
cryptorand "crypto/rand"
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding"
|
"encoding"
|
||||||
|
@ -74,8 +75,6 @@ var (
|
||||||
ErrAccountUnknown = errors.New("no such account")
|
ErrAccountUnknown = errors.New("no such account")
|
||||||
)
|
)
|
||||||
|
|
||||||
var subjectpassRand = mox.NewRand()
|
|
||||||
|
|
||||||
var DefaultInitialMailboxes = config.InitialMailboxes{
|
var DefaultInitialMailboxes = config.InitialMailboxes{
|
||||||
SpecialUse: config.SpecialUseMailboxes{
|
SpecialUse: config.SpecialUseMailboxes{
|
||||||
Sent: "Sent",
|
Sent: "Sent",
|
||||||
|
@ -1460,8 +1459,12 @@ func (a *Account) Subjectpass(email string) (key string, err error) {
|
||||||
}
|
}
|
||||||
key = ""
|
key = ""
|
||||||
const chars = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
const chars = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
for i := 0; i < 16; i++ {
|
buf := make([]byte, 16)
|
||||||
key += string(chars[subjectpassRand.Intn(len(chars))])
|
if _, err := cryptorand.Read(buf); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, b := range buf {
|
||||||
|
key += string(chars[int(b)%len(chars)])
|
||||||
}
|
}
|
||||||
v.Key = key
|
v.Key = key
|
||||||
return tx.Insert(&v)
|
return tx.Insert(&v)
|
||||||
|
|
Loading…
Reference in a new issue