This commit is contained in:
Frank Denis 2018-01-11 02:11:54 +01:00
parent 80e5bb5eb2
commit 735213f45a
4 changed files with 26 additions and 29 deletions

View File

@ -4,10 +4,10 @@ import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"errors" "errors"
"log"
"strings" "strings"
"time" "time"
"github.com/golang/glog"
"github.com/jedisct1/xsecretbox" "github.com/jedisct1/xsecretbox"
"github.com/miekg/dns" "github.com/miekg/dns"
"golang.org/x/crypto/ed25519" "golang.org/x/crypto/ed25519"
@ -41,15 +41,15 @@ func FetchCurrentCert(proxy *Proxy, proto string, pk ed25519.PublicKey, serverAd
for _, answerRr := range in.Answer { for _, answerRr := range in.Answer {
binCert, err := packTxtString(strings.Join(answerRr.(*dns.TXT).Txt, "")) binCert, err := packTxtString(strings.Join(answerRr.(*dns.TXT).Txt, ""))
if err != nil { if err != nil {
log.Printf("[%v] Unable to unpack the certificate\n", providerName) glog.Warningf("[%v] Unable to unpack the certificate", providerName)
continue continue
} }
if len(binCert) < 124 { if len(binCert) < 124 {
log.Printf("[%v] Certificate too short\n", providerName) glog.Warningf("[%v] Certificate too short", providerName)
continue continue
} }
if !bytes.Equal(binCert[:4], CertMagic[:4]) { if !bytes.Equal(binCert[:4], CertMagic[:4]) {
log.Printf("[%v] Invalid cert magic\n", providerName) glog.Warningf("[%v] Invalid cert magic", providerName)
continue continue
} }
cryptoConstruction := CryptoConstruction(0) cryptoConstruction := CryptoConstruction(0)
@ -59,36 +59,36 @@ func FetchCurrentCert(proxy *Proxy, proto string, pk ed25519.PublicKey, serverAd
case 0x0002: case 0x0002:
cryptoConstruction = XChacha20Poly1305 cryptoConstruction = XChacha20Poly1305
default: default:
log.Printf("[%v] Unsupported crypto construction\n", providerName) glog.Infof("[%v] Unsupported crypto construction", providerName)
continue continue
} }
signature := binCert[8:72] signature := binCert[8:72]
signed := binCert[72:] signed := binCert[72:]
if !ed25519.Verify(pk, signed, signature) { if !ed25519.Verify(pk, signed, signature) {
log.Printf("[%v] Incorrect signature\n", providerName) glog.Warningf("[%v] Incorrect signature", providerName)
continue continue
} }
serial := binary.BigEndian.Uint32(binCert[112:116]) serial := binary.BigEndian.Uint32(binCert[112:116])
tsBegin := binary.BigEndian.Uint32(binCert[116:120]) tsBegin := binary.BigEndian.Uint32(binCert[116:120])
tsEnd := binary.BigEndian.Uint32(binCert[120:124]) tsEnd := binary.BigEndian.Uint32(binCert[120:124])
if now > tsEnd || now < tsBegin { if now > tsEnd || now < tsBegin {
log.Printf("[%v] Certificate not valid at the current date\n", providerName) glog.Infof("[%v] Certificate not valid at the current date", providerName)
continue continue
} }
if serial < highestSerial { if serial < highestSerial {
log.Printf("[%v] Superseded by a previous certificate\n", providerName) glog.Infof("[%v] Superseded by a previous certificate", providerName)
continue continue
} }
if serial == highestSerial { if serial == highestSerial {
if cryptoConstruction < certInfo.CryptoConstruction { if cryptoConstruction < certInfo.CryptoConstruction {
log.Printf("[%v] Keeping the previous, preferred crypto construction", providerName) glog.Infof("[%v] Keeping the previous, preferred crypto construction", providerName)
continue continue
} else { } else {
log.Printf("[%v] Upgrading the construction from %v to %v\n", providerName, certInfo.CryptoConstruction, cryptoConstruction) glog.Infof("[%v] Upgrading the construction from %v to %v", providerName, certInfo.CryptoConstruction, cryptoConstruction)
} }
} }
if cryptoConstruction != XChacha20Poly1305 && cryptoConstruction != XSalsa20Poly1305 { if cryptoConstruction != XChacha20Poly1305 && cryptoConstruction != XSalsa20Poly1305 {
log.Printf("[%v] Cryptographic construction %v not supported\n", providerName, cryptoConstruction) glog.Warningf("[%v] Cryptographic construction %v not supported", providerName, cryptoConstruction)
continue continue
} }
var serverPk [32]byte var serverPk [32]byte
@ -97,7 +97,7 @@ func FetchCurrentCert(proxy *Proxy, proto string, pk ed25519.PublicKey, serverAd
if cryptoConstruction == XChacha20Poly1305 { if cryptoConstruction == XChacha20Poly1305 {
sharedKey, err = xsecretbox.SharedKey(proxy.proxySecretKey, serverPk) sharedKey, err = xsecretbox.SharedKey(proxy.proxySecretKey, serverPk)
if err != nil { if err != nil {
log.Printf("[%v] Weak public key\n", providerName) glog.Warningf("[%v] Weak public key", providerName)
continue continue
} }
} else { } else {
@ -108,7 +108,7 @@ func FetchCurrentCert(proxy *Proxy, proto string, pk ed25519.PublicKey, serverAd
certInfo.CryptoConstruction = cryptoConstruction certInfo.CryptoConstruction = cryptoConstruction
copy(certInfo.ServerPk[:], serverPk[:]) copy(certInfo.ServerPk[:], serverPk[:])
copy(certInfo.MagicQuery[:], binCert[104:112]) copy(certInfo.MagicQuery[:], binCert[104:112])
log.Printf("[%v] Valid cert found: %x\n", providerName, certInfo.ServerPk) glog.Infof("[%v] Valid cert found: [%x]", providerName, certInfo.ServerPk)
} }
if certInfo.CryptoConstruction == UndefinedConstruction { if certInfo.CryptoConstruction == UndefinedConstruction {
return certInfo, errors.New("No useable certificate found") return certInfo, errors.New("No useable certificate found")

View File

@ -4,10 +4,10 @@ import (
"errors" "errors"
"flag" "flag"
"fmt" "fmt"
"log"
"time" "time"
"github.com/BurntSushi/toml" "github.com/BurntSushi/toml"
"github.com/golang/glog"
) )
type Config struct { type Config struct {
@ -53,7 +53,7 @@ func ConfigLoad(proxy *Proxy, config_file string) error {
flag.Parse() flag.Parse()
config := newConfig() config := newConfig()
if _, err := toml.DecodeFile(*configFile, &config); err != nil { if _, err := toml.DecodeFile(*configFile, &config); err != nil {
log.Println(err) glog.Error(err)
return err return err
} }
proxy.timeout = time.Duration(config.Timeout) * time.Millisecond proxy.timeout = time.Duration(config.Timeout) * time.Millisecond

View File

@ -2,11 +2,10 @@ package main
import ( import (
"crypto/rand" "crypto/rand"
"fmt"
"log"
"net" "net"
"time" "time"
"github.com/golang/glog"
"golang.org/x/crypto/curve25519" "golang.org/x/crypto/curve25519"
) )
@ -30,7 +29,6 @@ type Proxy struct {
} }
func main() { func main() {
log.SetFlags(0)
proxy := Proxy{} proxy := Proxy{}
if err := ConfigLoad(&proxy, "dnscrypt-proxy.toml"); err != nil { if err := ConfigLoad(&proxy, "dnscrypt-proxy.toml"); err != nil {
panic(err) panic(err)
@ -44,7 +42,7 @@ func main() {
func (proxy *Proxy) StartProxy() { func (proxy *Proxy) StartProxy() {
proxy.questionSizeEstimator = NewQuestionSizeEstimator() proxy.questionSizeEstimator = NewQuestionSizeEstimator()
if _, err := rand.Read(proxy.proxySecretKey[:]); err != nil { if _, err := rand.Read(proxy.proxySecretKey[:]); err != nil {
log.Fatal(err) glog.Fatal(err)
} }
curve25519.ScalarBaseMult(&proxy.proxyPublicKey, &proxy.proxySecretKey) curve25519.ScalarBaseMult(&proxy.proxyPublicKey, &proxy.proxySecretKey)
for _, registeredServer := range proxy.registeredServers { for _, registeredServer := range proxy.registeredServers {
@ -53,17 +51,17 @@ func (proxy *Proxy) StartProxy() {
for _, listenAddrStr := range proxy.listenAddresses { for _, listenAddrStr := range proxy.listenAddresses {
listenUDPAddr, err := net.ResolveUDPAddr("udp", listenAddrStr) listenUDPAddr, err := net.ResolveUDPAddr("udp", listenAddrStr)
if err != nil { if err != nil {
log.Fatal(err) glog.Fatal(err)
} }
listenTCPAddr, err := net.ResolveTCPAddr("tcp", listenAddrStr) listenTCPAddr, err := net.ResolveTCPAddr("tcp", listenAddrStr)
if err != nil { if err != nil {
log.Fatal(err) glog.Fatal(err)
} }
if err := proxy.udpListener(listenUDPAddr); err != nil { if err := proxy.udpListener(listenUDPAddr); err != nil {
log.Fatal(err) glog.Fatal(err)
} }
if err := proxy.tcpListener(listenTCPAddr); err != nil { if err := proxy.tcpListener(listenTCPAddr); err != nil {
log.Fatal(err) glog.Fatal(err)
} }
} }
for { for {
@ -79,7 +77,7 @@ func (proxy *Proxy) udpListener(listenAddr *net.UDPAddr) error {
} }
go func() { go func() {
defer clientPc.Close() defer clientPc.Close()
fmt.Printf("Now listening to %v [UDP]\n", listenAddr) glog.Infof("Now listening to %v [UDP]", listenAddr)
for { for {
buffer := make([]byte, MaxDNSPacketSize-1) buffer := make([]byte, MaxDNSPacketSize-1)
length, clientAddr, err := clientPc.ReadFrom(buffer) length, clientAddr, err := clientPc.ReadFrom(buffer)
@ -102,7 +100,7 @@ func (proxy *Proxy) tcpListener(listenAddr *net.TCPAddr) error {
} }
go func() { go func() {
defer acceptPc.Close() defer acceptPc.Close()
fmt.Printf("Now listening to %v [TCP]\n", listenAddr) glog.Infof("Now listening to %v [TCP]", listenAddr)
for { for {
clientPc, err := acceptPc.Accept() clientPc, err := acceptPc.Accept()
if err != nil { if err != nil {

View File

@ -2,8 +2,6 @@ package main
import ( import (
"encoding/hex" "encoding/hex"
"fmt"
"log"
"math/rand" "math/rand"
"net" "net"
"strings" "strings"
@ -11,6 +9,7 @@ import (
"time" "time"
"github.com/VividCortex/ewma" "github.com/VividCortex/ewma"
"github.com/golang/glog"
"golang.org/x/crypto/ed25519" "golang.org/x/crypto/ed25519"
) )
@ -77,7 +76,7 @@ func (serversInfo *ServersInfo) registerServer(proxy *Proxy, name string, stamp
} }
func (serversInfo *ServersInfo) refresh(proxy *Proxy) { func (serversInfo *ServersInfo) refresh(proxy *Proxy) {
fmt.Println("Refreshing certificates") glog.Infof("Refreshing certificates")
serversInfo.RLock() serversInfo.RLock()
registeredServers := serversInfo.registeredServers registeredServers := serversInfo.registeredServers
serversInfo.RUnlock() serversInfo.RUnlock()
@ -108,7 +107,7 @@ func (serversInfo *ServersInfo) getOne() *ServerInfo {
func (serversInfo *ServersInfo) fetchServerInfo(proxy *Proxy, name string, stamp ServerStamp) (ServerInfo, error) { func (serversInfo *ServersInfo) fetchServerInfo(proxy *Proxy, name string, stamp ServerStamp) (ServerInfo, error) {
serverPk, err := hex.DecodeString(strings.Replace(stamp.serverPkStr, ":", "", -1)) serverPk, err := hex.DecodeString(strings.Replace(stamp.serverPkStr, ":", "", -1))
if err != nil || len(serverPk) != ed25519.PublicKeySize { if err != nil || len(serverPk) != ed25519.PublicKeySize {
log.Fatal("Invalid public key") glog.Fatal("Unsupported public key: [%v]", serverPk)
} }
certInfo, err := FetchCurrentCert(proxy, proxy.mainProto, serverPk, stamp.serverAddrStr, stamp.providerName) certInfo, err := FetchCurrentCert(proxy, proxy.mainProto, serverPk, stamp.serverAddrStr, stamp.providerName)
if err != nil { if err != nil {