Desuglify a bit
This commit is contained in:
parent
9ffa61c9e3
commit
60a58067c1
32
common.go
32
common.go
|
@ -1,7 +1,6 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -16,9 +15,9 @@ const (
|
|||
var (
|
||||
CertMagic = [4]byte{0x44, 0x4e, 0x53, 0x43}
|
||||
ServerMagic = [8]byte{0x72, 0x36, 0x66, 0x6e, 0x76, 0x57, 0x6a, 0x38}
|
||||
MinDNSPacketSize = uint(12)
|
||||
MaxDNSPacketSize = uint(4096)
|
||||
InitialMinQuestionSize = uint(128)
|
||||
MinDNSPacketSize = 12
|
||||
MaxDNSPacketSize = 4096
|
||||
InitialMinQuestionSize = 128
|
||||
TimeoutMin = 1 * time.Second
|
||||
TimeoutMax = 5 * time.Second
|
||||
)
|
||||
|
@ -26,28 +25,3 @@ var (
|
|||
func HasTCFlag(packet []byte) bool {
|
||||
return packet[2]&2 == 2
|
||||
}
|
||||
|
||||
func Pad(packet []byte, minSize uint) []byte {
|
||||
packet = append(packet, 0x80)
|
||||
for uint(len(packet)) < minSize {
|
||||
packet = append(packet, 0)
|
||||
}
|
||||
return packet
|
||||
}
|
||||
|
||||
func Unpad(packet []byte) ([]byte, error) {
|
||||
i := len(packet)
|
||||
for {
|
||||
if i == 0 {
|
||||
return nil, errors.New("Invalid padding (short packet)")
|
||||
}
|
||||
i--
|
||||
if packet[i] == 0x80 {
|
||||
break
|
||||
}
|
||||
if packet[i] != 0x00 {
|
||||
return nil, errors.New("Invalid padding (delimiter not found)")
|
||||
}
|
||||
}
|
||||
return packet[:i], nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
|
||||
"github.com/jedisct1/xsecretbox"
|
||||
)
|
||||
|
||||
const (
|
||||
NonceSize = xsecretbox.NonceSize
|
||||
HalfNonceSize = xsecretbox.NonceSize / 2
|
||||
TagSize = xsecretbox.TagSize
|
||||
)
|
||||
|
||||
func pad(packet []byte, minSize int) []byte {
|
||||
packet = append(packet, 0x80)
|
||||
for len(packet) < minSize {
|
||||
packet = append(packet, 0)
|
||||
}
|
||||
return packet
|
||||
}
|
||||
|
||||
func unpad(packet []byte) ([]byte, error) {
|
||||
for i := len(packet); ; {
|
||||
if i == 0 {
|
||||
return nil, errors.New("Invalid padding (short packet)")
|
||||
}
|
||||
i--
|
||||
if packet[i] == 0x80 {
|
||||
return packet[:i], nil
|
||||
} else if packet[i] != 0x00 {
|
||||
return nil, errors.New("Invalid padding (delimiter not found)")
|
||||
}
|
||||
}
|
||||
}
|
||||
func (proxy *Proxy) Crypt(serverInfo *ServerInfo, packet []byte) (encrypted []byte, clientNonce []byte) {
|
||||
nonce, clientNonce := make([]byte, NonceSize), make([]byte, HalfNonceSize)
|
||||
rand.Read(clientNonce)
|
||||
copy(nonce, clientNonce)
|
||||
encrypted = append(serverInfo.MagicQuery[:], proxy.proxyPublicKey[:]...)
|
||||
encrypted = append(encrypted, nonce[:HalfNonceSize]...)
|
||||
encrypted = xsecretbox.Seal(encrypted, nonce, pad(packet, proxy.minQuestionSize), serverInfo.SharedKey[:])
|
||||
return
|
||||
}
|
||||
|
||||
func (proxy *Proxy) Decrypt(serverInfo *ServerInfo, encrypted []byte, nonce []byte) ([]byte, error) {
|
||||
serverMagicLen := len(ServerMagic)
|
||||
responseHeaderLen := serverMagicLen + NonceSize
|
||||
if len(encrypted) < responseHeaderLen+TagSize+int(MinDNSPacketSize) ||
|
||||
!bytes.Equal(encrypted[:serverMagicLen], ServerMagic[:]) {
|
||||
return encrypted, errors.New("Short message")
|
||||
}
|
||||
serverNonce := encrypted[serverMagicLen:responseHeaderLen]
|
||||
if !bytes.Equal(nonce[:HalfNonceSize], serverNonce[:HalfNonceSize]) {
|
||||
return encrypted, errors.New("Unexpected nonce")
|
||||
}
|
||||
packet, err := xsecretbox.Open(nil, serverNonce, encrypted[responseHeaderLen:], serverInfo.SharedKey[:])
|
||||
if err != nil {
|
||||
return encrypted, errors.New("Incorrect tag")
|
||||
}
|
||||
packet, err = unpad(packet)
|
||||
if err != nil || len(packet) < MinDNSPacketSize {
|
||||
return encrypted, errors.New("Incorrect padding")
|
||||
}
|
||||
return packet, nil
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
@ -10,7 +9,6 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/jedisct1/xsecretbox"
|
||||
"golang.org/x/crypto/curve25519"
|
||||
"golang.org/x/crypto/ed25519"
|
||||
)
|
||||
|
@ -18,7 +16,7 @@ import (
|
|||
type Proxy struct {
|
||||
proxyPublicKey [32]byte
|
||||
proxySecretKey [32]byte
|
||||
minQuestionSize uint
|
||||
minQuestionSize int
|
||||
serversInfo []ServerInfo
|
||||
}
|
||||
|
||||
|
@ -88,14 +86,19 @@ type ServerInfo struct {
|
|||
TCPAddr *net.TCPAddr
|
||||
}
|
||||
|
||||
func (proxy *Proxy) adjustMinQuestionSize() {
|
||||
if MaxDNSPacketSize-proxy.minQuestionSize < proxy.minQuestionSize {
|
||||
proxy.minQuestionSize = MaxDNSPacketSize
|
||||
} else {
|
||||
proxy.minQuestionSize *= 2
|
||||
}
|
||||
}
|
||||
|
||||
func (proxy *Proxy) processIncomingQuery(serverInfo *ServerInfo, packet []byte, clientAddr net.Addr, clientPc net.PacketConn) {
|
||||
packet = Pad(packet, proxy.minQuestionSize)
|
||||
nonce := make([]byte, xsecretbox.NonceSize)
|
||||
rand.Read(nonce[0 : xsecretbox.NonceSize/2])
|
||||
encrypted := serverInfo.MagicQuery[:]
|
||||
encrypted = append(encrypted, proxy.proxyPublicKey[:]...)
|
||||
encrypted = append(encrypted, nonce[:xsecretbox.NonceSize/2]...)
|
||||
encrypted = xsecretbox.Seal(encrypted, nonce, packet, serverInfo.SharedKey[:])
|
||||
if len(packet) < MinDNSPacketSize {
|
||||
return
|
||||
}
|
||||
encrypted, clientNonce := proxy.Crypt(serverInfo, packet)
|
||||
pc, err := net.DialUDP("udp", nil, serverInfo.UDPAddr)
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -103,38 +106,21 @@ func (proxy *Proxy) processIncomingQuery(serverInfo *ServerInfo, packet []byte,
|
|||
defer pc.Close()
|
||||
pc.SetDeadline(time.Now().Add(serverInfo.Timeout))
|
||||
pc.Write(encrypted)
|
||||
buffer := make([]byte, MaxDNSPacketSize)
|
||||
length, err := pc.Read(buffer)
|
||||
|
||||
encrypted = make([]byte, MaxDNSPacketSize)
|
||||
length, err := pc.Read(encrypted)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
buffer = buffer[:length]
|
||||
serverMagicLen := len(ServerMagic)
|
||||
responseHeaderLen := serverMagicLen + xsecretbox.NonceSize
|
||||
if len(buffer) < responseHeaderLen+xsecretbox.TagSize ||
|
||||
!bytes.Equal(buffer[:serverMagicLen], ServerMagic[:]) {
|
||||
return
|
||||
}
|
||||
serverNonce := buffer[serverMagicLen:responseHeaderLen]
|
||||
if !bytes.Equal(nonce[:xsecretbox.NonceSize/2], serverNonce[:xsecretbox.NonceSize/2]) {
|
||||
return
|
||||
}
|
||||
decrypted, err := xsecretbox.Open(nil, serverNonce, buffer[responseHeaderLen:], serverInfo.SharedKey[:])
|
||||
encrypted = encrypted[:length]
|
||||
packet, err = proxy.Decrypt(serverInfo, encrypted, clientNonce)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
decrypted, err = Unpad(decrypted)
|
||||
if err != nil || uint(len(decrypted)) < MinDNSPacketSize {
|
||||
return
|
||||
clientPc.WriteTo(packet, clientAddr)
|
||||
if HasTCFlag(packet) {
|
||||
proxy.adjustMinQuestionSize()
|
||||
}
|
||||
if HasTCFlag(decrypted) {
|
||||
if MaxDNSPacketSize-proxy.minQuestionSize < proxy.minQuestionSize {
|
||||
proxy.minQuestionSize = MaxDNSPacketSize
|
||||
} else {
|
||||
proxy.minQuestionSize *= 2
|
||||
}
|
||||
}
|
||||
clientPc.WriteTo(decrypted, clientAddr)
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
|
Loading…
Reference in New Issue