mirror of
https://github.com/wneessen/go-mail.git
synced 2024-11-09 23:42:55 +01:00
Replace math/rand with crypto/rand
Since the Windows tests were still failing, we are replacing the random number generation with math/rand with random string generation via crypto/rand
This commit is contained in:
parent
5bf0c10525
commit
8484e557d0
2 changed files with 80 additions and 7 deletions
12
msg.go
12
msg.go
|
@ -12,7 +12,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
ht "html/template"
|
ht "html/template"
|
||||||
"io"
|
"io"
|
||||||
"math/rand"
|
|
||||||
"mime"
|
"mime"
|
||||||
"net/mail"
|
"net/mail"
|
||||||
"os"
|
"os"
|
||||||
|
@ -357,12 +356,11 @@ func (m *Msg) SetMessageID() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
hn = "localhost.localdomain"
|
hn = "localhost.localdomain"
|
||||||
}
|
}
|
||||||
ct := time.Now().UnixNano()
|
rn, _ := randNum(100000000)
|
||||||
r := rand.New(rand.NewSource(ct))
|
rm, _ := randNum(10000)
|
||||||
rn := r.Int63()
|
rs, _ := randomStringSecure(25)
|
||||||
pid := os.Getpid() * (r.Intn(10000) + 1)
|
pid := os.Getpid() * rm
|
||||||
cts := fmt.Sprintf("%d", ct)
|
mid := fmt.Sprintf("%d.%d%d.%s@%s", pid, rn, rm, rs, hn)
|
||||||
mid := fmt.Sprintf("%d.%d.%s@%s", pid, rn, cts[:16], hn)
|
|
||||||
m.SetMessageIDWithValue(mid)
|
m.SetMessageIDWithValue(mid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
75
random.go
Normal file
75
random.go
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
// SPDX-FileCopyrightText: 2022 Winni Neessen <winni@neessen.dev>
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package mail
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Range of characters for the secure string generation
|
||||||
|
const cr = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
|
||||||
|
|
||||||
|
// Bitmask sizes for the string generators (based on 93 chars total)
|
||||||
|
const (
|
||||||
|
letterIdxBits = 7 // 7 bits to represent a letter index
|
||||||
|
letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
|
||||||
|
letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits
|
||||||
|
)
|
||||||
|
|
||||||
|
// randomStringSecure returns a random, n long string of characters. The character set is based
|
||||||
|
// on the s (special chars) and h (human readable) boolean arguments. This method uses the
|
||||||
|
// crypto/random package and therfore is cryptographically secure
|
||||||
|
func randomStringSecure(n int) (string, error) {
|
||||||
|
rs := strings.Builder{}
|
||||||
|
rs.Grow(n)
|
||||||
|
crl := len(cr)
|
||||||
|
|
||||||
|
rp := make([]byte, 8)
|
||||||
|
_, err := rand.Read(rp)
|
||||||
|
if err != nil {
|
||||||
|
return rs.String(), err
|
||||||
|
}
|
||||||
|
for i, c, r := n-1, binary.BigEndian.Uint64(rp), letterIdxMax; i >= 0; {
|
||||||
|
if r == 0 {
|
||||||
|
_, err := rand.Read(rp)
|
||||||
|
if err != nil {
|
||||||
|
return rs.String(), err
|
||||||
|
}
|
||||||
|
c, r = binary.BigEndian.Uint64(rp), letterIdxMax
|
||||||
|
}
|
||||||
|
if idx := int(c & letterIdxMask); idx < crl {
|
||||||
|
rs.WriteByte(cr[idx])
|
||||||
|
i--
|
||||||
|
}
|
||||||
|
c >>= letterIdxBits
|
||||||
|
r--
|
||||||
|
}
|
||||||
|
|
||||||
|
return rs.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// randNum returns a random number with a maximum value of n
|
||||||
|
func randNum(n int) (int, error) {
|
||||||
|
if n <= 0 {
|
||||||
|
return 0, fmt.Errorf("provided number is <= 0: %d", n)
|
||||||
|
}
|
||||||
|
mbi := big.NewInt(int64(n))
|
||||||
|
if !mbi.IsUint64() {
|
||||||
|
return 0, fmt.Errorf("big.NewInt() generation returned negative value: %d", mbi)
|
||||||
|
}
|
||||||
|
rn64, err := rand.Int(rand.Reader, mbi)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
rn := int(rn64.Int64())
|
||||||
|
if rn < 0 {
|
||||||
|
return 0, fmt.Errorf("generated random number does not fit as int64: %d", rn64)
|
||||||
|
}
|
||||||
|
return rn, nil
|
||||||
|
}
|
Loading…
Reference in a new issue