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
|
||||
}
|
||||
|
||||
var jitterRand = mox.NewRand()
|
||||
var jitterRand = mox.NewPseudoRand()
|
||||
|
||||
// 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
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
package mox
|
||||
|
||||
import (
|
||||
cryptorand "crypto/rand"
|
||||
"encoding/base64"
|
||||
)
|
||||
|
||||
var messageIDRand = NewRand()
|
||||
|
||||
// MessageIDGen returns a generated unique random Message-Id value, excluding <>.
|
||||
func MessageIDGen(smtputf8 bool) string {
|
||||
buf := make([]byte, 16)
|
||||
messageIDRand.Read(buf)
|
||||
cryptorand.Read(buf)
|
||||
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"
|
||||
"fmt"
|
||||
mathrand "math/rand"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// NewRand returns a new PRNG seeded with random bytes from crypto/rand.
|
||||
func NewRand() *mathrand.Rand {
|
||||
return mathrand.New(mathrand.NewSource(CryptoRandInt()))
|
||||
type rand struct {
|
||||
*mathrand.Rand
|
||||
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.
|
||||
|
|
|
@ -61,7 +61,7 @@ var (
|
|||
)
|
||||
)
|
||||
|
||||
var jitter = mox.NewRand()
|
||||
var jitter = mox.NewPseudoRand()
|
||||
|
||||
var DBTypes = []any{Msg{}} // Types stored in DB.
|
||||
var DB *bstore.DB // Exported for making backups.
|
||||
|
|
|
@ -40,11 +40,19 @@ import (
|
|||
var moxService string
|
||||
|
||||
func pwgen() string {
|
||||
rand := mox.NewRand()
|
||||
chars := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*-_;:,<.>/"
|
||||
s := ""
|
||||
buf := make([]byte, 1)
|
||||
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
|
||||
}
|
||||
|
|
|
@ -168,7 +168,7 @@ var (
|
|||
)
|
||||
)
|
||||
|
||||
var jitterRand = mox.NewRand()
|
||||
var jitterRand = mox.NewPseudoRand()
|
||||
|
||||
func durationDefault(delay *time.Duration, def time.Duration) time.Duration {
|
||||
if delay == nil {
|
||||
|
|
|
@ -24,6 +24,7 @@ package store
|
|||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
cryptorand "crypto/rand"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
"encoding"
|
||||
|
@ -74,8 +75,6 @@ var (
|
|||
ErrAccountUnknown = errors.New("no such account")
|
||||
)
|
||||
|
||||
var subjectpassRand = mox.NewRand()
|
||||
|
||||
var DefaultInitialMailboxes = config.InitialMailboxes{
|
||||
SpecialUse: config.SpecialUseMailboxes{
|
||||
Sent: "Sent",
|
||||
|
@ -1460,8 +1459,12 @@ func (a *Account) Subjectpass(email string) (key string, err error) {
|
|||
}
|
||||
key = ""
|
||||
const chars = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
for i := 0; i < 16; i++ {
|
||||
key += string(chars[subjectpassRand.Intn(len(chars))])
|
||||
buf := make([]byte, 16)
|
||||
if _, err := cryptorand.Read(buf); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, b := range buf {
|
||||
key += string(chars[int(b)%len(chars)])
|
||||
}
|
||||
v.Key = key
|
||||
return tx.Insert(&v)
|
||||
|
|
Loading…
Reference in a new issue