This repository has been archived by the owner on Feb 5, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
/
patch.go
executable file
·129 lines (105 loc) · 3.54 KB
/
patch.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package main
import (
"bytes"
"crypto/sha512"
"encoding/binary"
"encoding/hex"
"errors"
"fmt"
"io/ioutil"
)
// ModifyNwcConfig takes an original config, applies needed patches to the URL and such,
// updates the checksum and returns either nil, error or a patched config w/o error.
func ModifyNwcConfig(originalConfig []byte) ([]byte, error) {
if len(originalConfig) == 0 {
return nil, errors.New("config seems to be empty. double check you uploaded a file")
}
if len(originalConfig) != 1024 {
return nil, errors.New("invalid config size")
}
var config ConfigFormat
configReadingBuf := bytes.NewBuffer(originalConfig)
err := binary.Read(configReadingBuf, binary.BigEndian, &config)
if err != nil {
return nil, err
}
if bytes.Compare(config.Magic[:], ConfigMagic) != 0 {
return nil, errors.New("invalid magic")
}
// Figure out mlid
mlid := fmt.Sprintf("w%016d", config.FriendCode)
// Go ahead and push generated data.
mlchkid := RandStringBytesMaskImprSrc(32)
mlchkidByte := sha512.Sum512(append(salt, []byte(mlchkid)...))
mlchkidHash := hex.EncodeToString(mlchkidByte[:])
passwd := RandStringBytesMaskImprSrc(16)
passwdByte := sha512.Sum512(append(salt, []byte(passwd)...))
passwdHash := hex.EncodeToString(passwdByte[:])
// We can reuse the statement defined for normal account creation.
_, err = createAccountStmt.Exec(mlid, mlchkidHash, passwdHash)
if err != nil {
LogError("Error running account statement", err)
return nil, err
}
if global.Datadog {
err = dataDogClient.Incr("mail.accounts_registered", nil, 1)
if err != nil {
LogError("Unable to update accounts_registered.", err)
}
}
// Alright, now it's time to patch.
var newMailDomain [64]byte
copy(newMailDomain[:], []byte("@"+global.SendGridDomain))
config.MailDomain = newMailDomain
// Copy changed credentials
var newMlchkid [36]byte
copy(newMlchkid[:], []byte(mlchkid))
config.Mlchkid = newMlchkid
var newPasswd [32]byte
copy(newPasswd[:], []byte(passwd))
config.Passwd = newPasswd
// The following is extremely redundantly written. TODO: fix that?
var newAccountURL [128]byte
copy(newAccountURL[:], []byte(global.PatchBaseDomain+"/cgi-bin/account.cgi"))
config.AccountURL = newAccountURL
var newCheckURL [128]byte
copy(newCheckURL[:], []byte(global.PatchBaseDomain+"/cgi-bin/check.cgi"))
config.CheckURL = newCheckURL
var newRecieveURL [128]byte
copy(newRecieveURL[:], []byte(global.PatchBaseDomain+"/cgi-bin/receive.cgi"))
config.ReceiveURL = newRecieveURL
var newDeleteURL [128]byte
copy(newDeleteURL[:], []byte(global.PatchBaseDomain+"/cgi-bin/delete.cgi"))
config.DeleteURL = newDeleteURL
var newSendURL [128]byte
copy(newSendURL[:], []byte(global.PatchBaseDomain+"/cgi-bin/send.cgi"))
config.SendURL = newSendURL
// Enable title booting
config.TitleBooting = 1
// Read from struct to buffer
fileBuf := new(bytes.Buffer)
err = binary.Write(fileBuf, binary.BigEndian, config)
if err != nil {
return nil, err
}
patchedConfig, err := ioutil.ReadAll(fileBuf)
if err != nil {
return nil, err
}
var checksumInt uint32
// Checksum.
// We loop from 1020 to avoid current checksum.
// Take every 4 bytes, add 'er up!
for i := 0; i < 1020; i += 4 {
addition := binary.BigEndian.Uint32(patchedConfig[i : i+4])
checksumInt += addition
}
// Grab lower 32 bits of int
var finalChecksum uint32
finalChecksum = checksumInt & 0xFFFFFFFF
binaryChecksum := make([]byte, 4)
binary.BigEndian.PutUint32(binaryChecksum, finalChecksum)
// Update patched config checksum
copy(patchedConfig[1020:1024], binaryChecksum)
return patchedConfig, nil
}