diff options
Diffstat (limited to 'vendor/github.com/rsc/letsencrypt/vendor/github.com')
105 files changed, 0 insertions, 27264 deletions
diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/.gitignore b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/.gitignore deleted file mode 100644 index 776cd950c..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -*.6 -tags -test.out -a.out diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/.travis.yml b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/.travis.yml deleted file mode 100644 index bb8b8d40b..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -language: go -sudo: false -go: - - 1.7.x - - 1.8.x - - tip - -before_install: - # don't use the miekg/dns when testing forks - - mkdir -p $GOPATH/src/github.com/miekg - - ln -s $TRAVIS_BUILD_DIR $GOPATH/src/github.com/miekg/ || true - -script: - - go test -race -v -bench=. diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/AUTHORS b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/AUTHORS deleted file mode 100644 index 196568352..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/AUTHORS +++ /dev/null @@ -1 +0,0 @@ -Miek Gieben <miek@miek.nl> diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/CONTRIBUTORS b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/CONTRIBUTORS deleted file mode 100644 index f77e8a895..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/CONTRIBUTORS +++ /dev/null @@ -1,9 +0,0 @@ -Alex A. Skinner -Andrew Tunnell-Jones -Ask Bjørn Hansen -Dave Cheney -Dusty Wilson -Marek Majkowski -Peter van Dijk -Omri Bahumi -Alex Sergeyev diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/COPYRIGHT b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/COPYRIGHT deleted file mode 100644 index 35702b10e..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/COPYRIGHT +++ /dev/null @@ -1,9 +0,0 @@ -Copyright 2009 The Go Authors. All rights reserved. Use of this source code -is governed by a BSD-style license that can be found in the LICENSE file. -Extensions of the original work are copyright (c) 2011 Miek Gieben - -Copyright 2011 Miek Gieben. All rights reserved. Use of this source code is -governed by a BSD-style license that can be found in the LICENSE file. - -Copyright 2014 CloudFlare. All rights reserved. Use of this source code is -governed by a BSD-style license that can be found in the LICENSE file. diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/LICENSE b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/LICENSE deleted file mode 100644 index 5763fa7fe..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/LICENSE +++ /dev/null @@ -1,32 +0,0 @@ -Extensions of the original work are copyright (c) 2011 Miek Gieben - -As this is fork of the official Go code the same license applies: - -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/README.md b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/README.md deleted file mode 100644 index 32a49cbf5..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/README.md +++ /dev/null @@ -1,162 +0,0 @@ -[![Build Status](https://travis-ci.org/miekg/dns.svg?branch=master)](https://travis-ci.org/miekg/dns) -[![](https://godoc.org/github.com/miekg/dns?status.svg)](https://godoc.org/github.com/miekg/dns) - -# Alternative (more granular) approach to a DNS library - -> Less is more. - -Complete and usable DNS library. All widely used Resource Records are -supported, including the DNSSEC types. It follows a lean and mean philosophy. -If there is stuff you should know as a DNS programmer there isn't a convenience -function for it. Server side and client side programming is supported, i.e. you -can build servers and resolvers with it. - -We try to keep the "master" branch as sane as possible and at the bleeding edge -of standards, avoiding breaking changes wherever reasonable. We support the last -two versions of Go, currently: 1.7 and 1.8. - -# Goals - -* KISS; -* Fast; -* Small API. If it's easy to code in Go, don't make a function for it. - -# Users - -A not-so-up-to-date-list-that-may-be-actually-current: - -* https://github.com/coredns/coredns -* https://cloudflare.com -* https://github.com/abh/geodns -* http://www.statdns.com/ -* http://www.dnsinspect.com/ -* https://github.com/chuangbo/jianbing-dictionary-dns -* http://www.dns-lg.com/ -* https://github.com/fcambus/rrda -* https://github.com/kenshinx/godns -* https://github.com/skynetservices/skydns -* https://github.com/hashicorp/consul -* https://github.com/DevelopersPL/godnsagent -* https://github.com/duedil-ltd/discodns -* https://github.com/StalkR/dns-reverse-proxy -* https://github.com/tianon/rawdns -* https://mesosphere.github.io/mesos-dns/ -* https://pulse.turbobytes.com/ -* https://play.google.com/store/apps/details?id=com.turbobytes.dig -* https://github.com/fcambus/statzone -* https://github.com/benschw/dns-clb-go -* https://github.com/corny/dnscheck for http://public-dns.info/ -* https://namesmith.io -* https://github.com/miekg/unbound -* https://github.com/miekg/exdns -* https://dnslookup.org -* https://github.com/looterz/grimd -* https://github.com/phamhongviet/serf-dns -* https://github.com/mehrdadrad/mylg -* https://github.com/bamarni/dockness -* https://github.com/fffaraz/microdns -* http://quilt.io -* https://github.com/ipdcode/hades (JD.COM) -* https://github.com/StackExchange/dnscontrol/ -* https://www.dnsperf.com/ -* https://dnssectest.net/ - -Send pull request if you want to be listed here. - -# Features - -* UDP/TCP queries, IPv4 and IPv6; -* RFC 1035 zone file parsing ($INCLUDE, $ORIGIN, $TTL and $GENERATE (for all record types) are supported; -* Fast: - * Reply speed around ~ 80K qps (faster hardware results in more qps); - * Parsing RRs ~ 100K RR/s, that's 5M records in about 50 seconds; -* Server side programming (mimicking the net/http package); -* Client side programming; -* DNSSEC: signing, validating and key generation for DSA, RSA and ECDSA; -* EDNS0, NSID, Cookies; -* AXFR/IXFR; -* TSIG, SIG(0); -* DNS over TLS: optional encrypted connection between client and server; -* DNS name compression; -* Depends only on the standard library. - -Have fun! - -Miek Gieben - 2010-2012 - <miek@miek.nl> - -# Building - -Building is done with the `go` tool. If you have setup your GOPATH -correctly, the following should work: - - go get github.com/miekg/dns - go build github.com/miekg/dns - -## Examples - -A short "how to use the API" is at the beginning of doc.go (this also will show -when you call `godoc github.com/miekg/dns`). - -Example programs can be found in the `github.com/miekg/exdns` repository. - -## Supported RFCs - -*all of them* - -* 103{4,5} - DNS standard -* 1348 - NSAP record (removed the record) -* 1982 - Serial Arithmetic -* 1876 - LOC record -* 1995 - IXFR -* 1996 - DNS notify -* 2136 - DNS Update (dynamic updates) -* 2181 - RRset definition - there is no RRset type though, just []RR -* 2537 - RSAMD5 DNS keys -* 2065 - DNSSEC (updated in later RFCs) -* 2671 - EDNS record -* 2782 - SRV record -* 2845 - TSIG record -* 2915 - NAPTR record -* 2929 - DNS IANA Considerations -* 3110 - RSASHA1 DNS keys -* 3225 - DO bit (DNSSEC OK) -* 340{1,2,3} - NAPTR record -* 3445 - Limiting the scope of (DNS)KEY -* 3597 - Unknown RRs -* 403{3,4,5} - DNSSEC + validation functions -* 4255 - SSHFP record -* 4343 - Case insensitivity -* 4408 - SPF record -* 4509 - SHA256 Hash in DS -* 4592 - Wildcards in the DNS -* 4635 - HMAC SHA TSIG -* 4701 - DHCID -* 4892 - id.server -* 5001 - NSID -* 5155 - NSEC3 record -* 5205 - HIP record -* 5702 - SHA2 in the DNS -* 5936 - AXFR -* 5966 - TCP implementation recommendations -* 6605 - ECDSA -* 6725 - IANA Registry Update -* 6742 - ILNP DNS -* 6840 - Clarifications and Implementation Notes for DNS Security -* 6844 - CAA record -* 6891 - EDNS0 update -* 6895 - DNS IANA considerations -* 6975 - Algorithm Understanding in DNSSEC -* 7043 - EUI48/EUI64 records -* 7314 - DNS (EDNS) EXPIRE Option -* 7828 - edns-tcp-keepalive EDNS0 Option -* 7553 - URI record -* 7858 - DNS over TLS: Initiation and Performance Considerations (draft) -* 7873 - Domain Name System (DNS) Cookies (draft-ietf-dnsop-cookies) -* xxxx - EDNS0 DNS Update Lease (draft) - -## Loosely based upon - -* `ldns` -* `NSD` -* `Net::DNS` -* `GRONG` diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/client.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/client.go deleted file mode 100644 index 301dab9c1..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/client.go +++ /dev/null @@ -1,467 +0,0 @@ -package dns - -// A client implementation. - -import ( - "bytes" - "crypto/tls" - "encoding/binary" - "io" - "net" - "time" -) - -const dnsTimeout time.Duration = 2 * time.Second -const tcpIdleTimeout time.Duration = 8 * time.Second - -// A Conn represents a connection to a DNS server. -type Conn struct { - net.Conn // a net.Conn holding the connection - UDPSize uint16 // minimum receive buffer for UDP messages - TsigSecret map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be fully qualified - rtt time.Duration - t time.Time - tsigRequestMAC string -} - -// A Client defines parameters for a DNS client. -type Client struct { - Net string // if "tcp" or "tcp-tls" (DNS over TLS) a TCP query will be initiated, otherwise an UDP one (default is "" for UDP) - UDPSize uint16 // minimum receive buffer for UDP messages - TLSConfig *tls.Config // TLS connection configuration - Timeout time.Duration // a cumulative timeout for dial, write and read, defaults to 0 (disabled) - overrides DialTimeout, ReadTimeout and WriteTimeout when non-zero - DialTimeout time.Duration // net.DialTimeout, defaults to 2 seconds - overridden by Timeout when that value is non-zero - ReadTimeout time.Duration // net.Conn.SetReadTimeout value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero - WriteTimeout time.Duration // net.Conn.SetWriteTimeout value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero - TsigSecret map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be fully qualified - SingleInflight bool // if true suppress multiple outstanding queries for the same Qname, Qtype and Qclass - group singleflight -} - -// Exchange performs a synchronous UDP query. It sends the message m to the address -// contained in a and waits for a reply. Exchange does not retry a failed query, nor -// will it fall back to TCP in case of truncation. -// See client.Exchange for more information on setting larger buffer sizes. -func Exchange(m *Msg, a string) (r *Msg, err error) { - var co *Conn - co, err = DialTimeout("udp", a, dnsTimeout) - if err != nil { - return nil, err - } - - defer co.Close() - - opt := m.IsEdns0() - // If EDNS0 is used use that for size. - if opt != nil && opt.UDPSize() >= MinMsgSize { - co.UDPSize = opt.UDPSize() - } - - co.SetWriteDeadline(time.Now().Add(dnsTimeout)) - if err = co.WriteMsg(m); err != nil { - return nil, err - } - - co.SetReadDeadline(time.Now().Add(dnsTimeout)) - r, err = co.ReadMsg() - if err == nil && r.Id != m.Id { - err = ErrId - } - return r, err -} - -// ExchangeConn performs a synchronous query. It sends the message m via the connection -// c and waits for a reply. The connection c is not closed by ExchangeConn. -// This function is going away, but can easily be mimicked: -// -// co := &dns.Conn{Conn: c} // c is your net.Conn -// co.WriteMsg(m) -// in, _ := co.ReadMsg() -// co.Close() -// -func ExchangeConn(c net.Conn, m *Msg) (r *Msg, err error) { - println("dns: this function is deprecated") - co := new(Conn) - co.Conn = c - if err = co.WriteMsg(m); err != nil { - return nil, err - } - r, err = co.ReadMsg() - if err == nil && r.Id != m.Id { - err = ErrId - } - return r, err -} - -// Exchange performs a synchronous query. It sends the message m to the address -// contained in a and waits for a reply. Basic use pattern with a *dns.Client: -// -// c := new(dns.Client) -// in, rtt, err := c.Exchange(message, "127.0.0.1:53") -// -// Exchange does not retry a failed query, nor will it fall back to TCP in -// case of truncation. -// It is up to the caller to create a message that allows for larger responses to be -// returned. Specifically this means adding an EDNS0 OPT RR that will advertise a larger -// buffer, see SetEdns0. Messages without an OPT RR will fallback to the historic limit -// of 512 bytes. -func (c *Client) Exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err error) { - if !c.SingleInflight { - return c.exchange(m, a) - } - // This adds a bunch of garbage, TODO(miek). - t := "nop" - if t1, ok := TypeToString[m.Question[0].Qtype]; ok { - t = t1 - } - cl := "nop" - if cl1, ok := ClassToString[m.Question[0].Qclass]; ok { - cl = cl1 - } - r, rtt, err, shared := c.group.Do(m.Question[0].Name+t+cl, func() (*Msg, time.Duration, error) { - return c.exchange(m, a) - }) - if r != nil && shared { - r = r.Copy() - } - if err != nil { - return r, rtt, err - } - return r, rtt, nil -} - -func (c *Client) dialTimeout() time.Duration { - if c.Timeout != 0 { - return c.Timeout - } - if c.DialTimeout != 0 { - return c.DialTimeout - } - return dnsTimeout -} - -func (c *Client) readTimeout() time.Duration { - if c.ReadTimeout != 0 { - return c.ReadTimeout - } - return dnsTimeout -} - -func (c *Client) writeTimeout() time.Duration { - if c.WriteTimeout != 0 { - return c.WriteTimeout - } - return dnsTimeout -} - -func (c *Client) exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err error) { - var co *Conn - network := "udp" - tls := false - - switch c.Net { - case "tcp-tls": - network = "tcp" - tls = true - case "tcp4-tls": - network = "tcp4" - tls = true - case "tcp6-tls": - network = "tcp6" - tls = true - default: - if c.Net != "" { - network = c.Net - } - } - - var deadline time.Time - if c.Timeout != 0 { - deadline = time.Now().Add(c.Timeout) - } - - if tls { - co, err = DialTimeoutWithTLS(network, a, c.TLSConfig, c.dialTimeout()) - } else { - co, err = DialTimeout(network, a, c.dialTimeout()) - } - - if err != nil { - return nil, 0, err - } - defer co.Close() - - opt := m.IsEdns0() - // If EDNS0 is used use that for size. - if opt != nil && opt.UDPSize() >= MinMsgSize { - co.UDPSize = opt.UDPSize() - } - // Otherwise use the client's configured UDP size. - if opt == nil && c.UDPSize >= MinMsgSize { - co.UDPSize = c.UDPSize - } - - co.TsigSecret = c.TsigSecret - co.SetWriteDeadline(deadlineOrTimeout(deadline, c.writeTimeout())) - if err = co.WriteMsg(m); err != nil { - return nil, 0, err - } - - co.SetReadDeadline(deadlineOrTimeout(deadline, c.readTimeout())) - r, err = co.ReadMsg() - if err == nil && r.Id != m.Id { - err = ErrId - } - return r, co.rtt, err -} - -// ReadMsg reads a message from the connection co. -// If the received message contains a TSIG record the transaction -// signature is verified. -func (co *Conn) ReadMsg() (*Msg, error) { - p, err := co.ReadMsgHeader(nil) - if err != nil { - return nil, err - } - - m := new(Msg) - if err := m.Unpack(p); err != nil { - // If ErrTruncated was returned, we still want to allow the user to use - // the message, but naively they can just check err if they don't want - // to use a truncated message - if err == ErrTruncated { - return m, err - } - return nil, err - } - if t := m.IsTsig(); t != nil { - if _, ok := co.TsigSecret[t.Hdr.Name]; !ok { - return m, ErrSecret - } - // Need to work on the original message p, as that was used to calculate the tsig. - err = TsigVerify(p, co.TsigSecret[t.Hdr.Name], co.tsigRequestMAC, false) - } - return m, err -} - -// ReadMsgHeader reads a DNS message, parses and populates hdr (when hdr is not nil). -// Returns message as a byte slice to be parsed with Msg.Unpack later on. -// Note that error handling on the message body is not possible as only the header is parsed. -func (co *Conn) ReadMsgHeader(hdr *Header) ([]byte, error) { - var ( - p []byte - n int - err error - ) - - switch t := co.Conn.(type) { - case *net.TCPConn, *tls.Conn: - r := t.(io.Reader) - - // First two bytes specify the length of the entire message. - l, err := tcpMsgLen(r) - if err != nil { - return nil, err - } - p = make([]byte, l) - n, err = tcpRead(r, p) - co.rtt = time.Since(co.t) - default: - if co.UDPSize > MinMsgSize { - p = make([]byte, co.UDPSize) - } else { - p = make([]byte, MinMsgSize) - } - n, err = co.Read(p) - co.rtt = time.Since(co.t) - } - - if err != nil { - return nil, err - } else if n < headerSize { - return nil, ErrShortRead - } - - p = p[:n] - if hdr != nil { - dh, _, err := unpackMsgHdr(p, 0) - if err != nil { - return nil, err - } - *hdr = dh - } - return p, err -} - -// tcpMsgLen is a helper func to read first two bytes of stream as uint16 packet length. -func tcpMsgLen(t io.Reader) (int, error) { - p := []byte{0, 0} - n, err := t.Read(p) - if err != nil { - return 0, err - } - - // As seen with my local router/switch, retursn 1 byte on the above read, - // resulting a a ShortRead. Just write it out (instead of loop) and read the - // other byte. - if n == 1 { - n1, err := t.Read(p[1:]) - if err != nil { - return 0, err - } - n += n1 - } - - if n != 2 { - return 0, ErrShortRead - } - l := binary.BigEndian.Uint16(p) - if l == 0 { - return 0, ErrShortRead - } - return int(l), nil -} - -// tcpRead calls TCPConn.Read enough times to fill allocated buffer. -func tcpRead(t io.Reader, p []byte) (int, error) { - n, err := t.Read(p) - if err != nil { - return n, err - } - for n < len(p) { - j, err := t.Read(p[n:]) - if err != nil { - return n, err - } - n += j - } - return n, err -} - -// Read implements the net.Conn read method. -func (co *Conn) Read(p []byte) (n int, err error) { - if co.Conn == nil { - return 0, ErrConnEmpty - } - if len(p) < 2 { - return 0, io.ErrShortBuffer - } - switch t := co.Conn.(type) { - case *net.TCPConn, *tls.Conn: - r := t.(io.Reader) - - l, err := tcpMsgLen(r) - if err != nil { - return 0, err - } - if l > len(p) { - return int(l), io.ErrShortBuffer - } - return tcpRead(r, p[:l]) - } - // UDP connection - n, err = co.Conn.Read(p) - if err != nil { - return n, err - } - return n, err -} - -// WriteMsg sends a message through the connection co. -// If the message m contains a TSIG record the transaction -// signature is calculated. -func (co *Conn) WriteMsg(m *Msg) (err error) { - var out []byte - if t := m.IsTsig(); t != nil { - mac := "" - if _, ok := co.TsigSecret[t.Hdr.Name]; !ok { - return ErrSecret - } - out, mac, err = TsigGenerate(m, co.TsigSecret[t.Hdr.Name], co.tsigRequestMAC, false) - // Set for the next read, although only used in zone transfers - co.tsigRequestMAC = mac - } else { - out, err = m.Pack() - } - if err != nil { - return err - } - co.t = time.Now() - if _, err = co.Write(out); err != nil { - return err - } - return nil -} - -// Write implements the net.Conn Write method. -func (co *Conn) Write(p []byte) (n int, err error) { - switch t := co.Conn.(type) { - case *net.TCPConn, *tls.Conn: - w := t.(io.Writer) - - lp := len(p) - if lp < 2 { - return 0, io.ErrShortBuffer - } - if lp > MaxMsgSize { - return 0, &Error{err: "message too large"} - } - l := make([]byte, 2, lp+2) - binary.BigEndian.PutUint16(l, uint16(lp)) - p = append(l, p...) - n, err := io.Copy(w, bytes.NewReader(p)) - return int(n), err - } - n, err = co.Conn.Write(p) - return n, err -} - -// Dial connects to the address on the named network. -func Dial(network, address string) (conn *Conn, err error) { - conn = new(Conn) - conn.Conn, err = net.Dial(network, address) - if err != nil { - return nil, err - } - return conn, nil -} - -// DialTimeout acts like Dial but takes a timeout. -func DialTimeout(network, address string, timeout time.Duration) (conn *Conn, err error) { - conn = new(Conn) - conn.Conn, err = net.DialTimeout(network, address, timeout) - if err != nil { - return nil, err - } - return conn, nil -} - -// DialWithTLS connects to the address on the named network with TLS. -func DialWithTLS(network, address string, tlsConfig *tls.Config) (conn *Conn, err error) { - conn = new(Conn) - conn.Conn, err = tls.Dial(network, address, tlsConfig) - if err != nil { - return nil, err - } - return conn, nil -} - -// DialTimeoutWithTLS acts like DialWithTLS but takes a timeout. -func DialTimeoutWithTLS(network, address string, tlsConfig *tls.Config, timeout time.Duration) (conn *Conn, err error) { - var dialer net.Dialer - dialer.Timeout = timeout - - conn = new(Conn) - conn.Conn, err = tls.DialWithDialer(&dialer, network, address, tlsConfig) - if err != nil { - return nil, err - } - return conn, nil -} - -func deadlineOrTimeout(deadline time.Time, timeout time.Duration) time.Time { - if deadline.IsZero() { - return time.Now().Add(timeout) - } - return deadline -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/client_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/client_test.go deleted file mode 100644 index dee585f36..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/client_test.go +++ /dev/null @@ -1,511 +0,0 @@ -package dns - -import ( - "crypto/tls" - "fmt" - "net" - "strconv" - "sync" - "testing" - "time" -) - -func TestClientSync(t *testing.T) { - HandleFunc("miek.nl.", HelloServer) - defer HandleRemove("miek.nl.") - - s, addrstr, err := RunLocalUDPServer("127.0.0.1:0") - if err != nil { - t.Fatalf("unable to run test server: %v", err) - } - defer s.Shutdown() - - m := new(Msg) - m.SetQuestion("miek.nl.", TypeSOA) - - c := new(Client) - r, _, err := c.Exchange(m, addrstr) - if err != nil { - t.Errorf("failed to exchange: %v", err) - } - if r != nil && r.Rcode != RcodeSuccess { - t.Errorf("failed to get an valid answer\n%v", r) - } - // And now with plain Exchange(). - r, err = Exchange(m, addrstr) - if err != nil { - t.Errorf("failed to exchange: %v", err) - } - if r == nil || r.Rcode != RcodeSuccess { - t.Errorf("failed to get an valid answer\n%v", r) - } -} - -func TestClientTLSSync(t *testing.T) { - HandleFunc("miek.nl.", HelloServer) - defer HandleRemove("miek.nl.") - - cert, err := tls.X509KeyPair(CertPEMBlock, KeyPEMBlock) - if err != nil { - t.Fatalf("unable to build certificate: %v", err) - } - - config := tls.Config{ - Certificates: []tls.Certificate{cert}, - } - - s, addrstr, err := RunLocalTLSServer("127.0.0.1:0", &config) - if err != nil { - t.Fatalf("unable to run test server: %v", err) - } - defer s.Shutdown() - - m := new(Msg) - m.SetQuestion("miek.nl.", TypeSOA) - - c := new(Client) - c.Net = "tcp-tls" - c.TLSConfig = &tls.Config{ - InsecureSkipVerify: true, - } - - r, _, err := c.Exchange(m, addrstr) - if err != nil { - t.Errorf("failed to exchange: %v", err) - } - if r != nil && r.Rcode != RcodeSuccess { - t.Errorf("failed to get an valid answer\n%v", r) - } -} - -func TestClientSyncBadID(t *testing.T) { - HandleFunc("miek.nl.", HelloServerBadID) - defer HandleRemove("miek.nl.") - - s, addrstr, err := RunLocalUDPServer("127.0.0.1:0") - if err != nil { - t.Fatalf("unable to run test server: %v", err) - } - defer s.Shutdown() - - m := new(Msg) - m.SetQuestion("miek.nl.", TypeSOA) - - c := new(Client) - if _, _, err := c.Exchange(m, addrstr); err != ErrId { - t.Errorf("did not find a bad Id") - } - // And now with plain Exchange(). - if _, err := Exchange(m, addrstr); err != ErrId { - t.Errorf("did not find a bad Id") - } -} - -func TestClientEDNS0(t *testing.T) { - HandleFunc("miek.nl.", HelloServer) - defer HandleRemove("miek.nl.") - - s, addrstr, err := RunLocalUDPServer("127.0.0.1:0") - if err != nil { - t.Fatalf("unable to run test server: %v", err) - } - defer s.Shutdown() - - m := new(Msg) - m.SetQuestion("miek.nl.", TypeDNSKEY) - - m.SetEdns0(2048, true) - - c := new(Client) - r, _, err := c.Exchange(m, addrstr) - if err != nil { - t.Errorf("failed to exchange: %v", err) - } - - if r != nil && r.Rcode != RcodeSuccess { - t.Errorf("failed to get an valid answer\n%v", r) - } -} - -// Validates the transmission and parsing of local EDNS0 options. -func TestClientEDNS0Local(t *testing.T) { - optStr1 := "1979:0x0707" - optStr2 := strconv.Itoa(EDNS0LOCALSTART) + ":0x0601" - - handler := func(w ResponseWriter, req *Msg) { - m := new(Msg) - m.SetReply(req) - - m.Extra = make([]RR, 1, 2) - m.Extra[0] = &TXT{Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello local edns"}} - - // If the local options are what we expect, then reflect them back. - ec1 := req.Extra[0].(*OPT).Option[0].(*EDNS0_LOCAL).String() - ec2 := req.Extra[0].(*OPT).Option[1].(*EDNS0_LOCAL).String() - if ec1 == optStr1 && ec2 == optStr2 { - m.Extra = append(m.Extra, req.Extra[0]) - } - - w.WriteMsg(m) - } - - HandleFunc("miek.nl.", handler) - defer HandleRemove("miek.nl.") - - s, addrstr, err := RunLocalUDPServer("127.0.0.1:0") - if err != nil { - t.Fatalf("unable to run test server: %s", err) - } - defer s.Shutdown() - - m := new(Msg) - m.SetQuestion("miek.nl.", TypeTXT) - - // Add two local edns options to the query. - ec1 := &EDNS0_LOCAL{Code: 1979, Data: []byte{7, 7}} - ec2 := &EDNS0_LOCAL{Code: EDNS0LOCALSTART, Data: []byte{6, 1}} - o := &OPT{Hdr: RR_Header{Name: ".", Rrtype: TypeOPT}, Option: []EDNS0{ec1, ec2}} - m.Extra = append(m.Extra, o) - - c := new(Client) - r, _, err := c.Exchange(m, addrstr) - if err != nil { - t.Errorf("failed to exchange: %s", err) - } - - if r != nil && r.Rcode != RcodeSuccess { - t.Error("failed to get a valid answer") - t.Logf("%v\n", r) - } - - txt := r.Extra[0].(*TXT).Txt[0] - if txt != "Hello local edns" { - t.Error("Unexpected result for miek.nl", txt, "!= Hello local edns") - } - - // Validate the local options in the reply. - got := r.Extra[1].(*OPT).Option[0].(*EDNS0_LOCAL).String() - if got != optStr1 { - t.Errorf("failed to get local edns0 answer; got %s, expected %s", got, optStr1) - t.Logf("%v\n", r) - } - - got = r.Extra[1].(*OPT).Option[1].(*EDNS0_LOCAL).String() - if got != optStr2 { - t.Errorf("failed to get local edns0 answer; got %s, expected %s", got, optStr2) - t.Logf("%v\n", r) - } -} - -// ExampleTsigSecret_updateLeaseTSIG shows how to update a lease signed with TSIG -func ExampleTsigSecret_updateLeaseTSIG() { - m := new(Msg) - m.SetUpdate("t.local.ip6.io.") - rr, _ := NewRR("t.local.ip6.io. 30 A 127.0.0.1") - rrs := make([]RR, 1) - rrs[0] = rr - m.Insert(rrs) - - leaseRr := new(OPT) - leaseRr.Hdr.Name = "." - leaseRr.Hdr.Rrtype = TypeOPT - e := new(EDNS0_UL) - e.Code = EDNS0UL - e.Lease = 120 - leaseRr.Option = append(leaseRr.Option, e) - m.Extra = append(m.Extra, leaseRr) - - c := new(Client) - m.SetTsig("polvi.", HmacMD5, 300, time.Now().Unix()) - c.TsigSecret = map[string]string{"polvi.": "pRZgBrBvI4NAHZYhxmhs/Q=="} - - _, _, err := c.Exchange(m, "127.0.0.1:53") - if err != nil { - panic(err) - } -} - -func TestClientConn(t *testing.T) { - HandleFunc("miek.nl.", HelloServer) - defer HandleRemove("miek.nl.") - - // This uses TCP just to make it slightly different than TestClientSync - s, addrstr, err := RunLocalTCPServer("127.0.0.1:0") - if err != nil { - t.Fatalf("unable to run test server: %v", err) - } - defer s.Shutdown() - - m := new(Msg) - m.SetQuestion("miek.nl.", TypeSOA) - - cn, err := Dial("tcp", addrstr) - if err != nil { - t.Errorf("failed to dial %s: %v", addrstr, err) - } - - err = cn.WriteMsg(m) - if err != nil { - t.Errorf("failed to exchange: %v", err) - } - r, err := cn.ReadMsg() - if r == nil || r.Rcode != RcodeSuccess { - t.Errorf("failed to get an valid answer\n%v", r) - } - - err = cn.WriteMsg(m) - if err != nil { - t.Errorf("failed to exchange: %v", err) - } - h := new(Header) - buf, err := cn.ReadMsgHeader(h) - if buf == nil { - t.Errorf("failed to get an valid answer\n%v", r) - } - if int(h.Bits&0xF) != RcodeSuccess { - t.Errorf("failed to get an valid answer in ReadMsgHeader\n%v", r) - } - if h.Ancount != 0 || h.Qdcount != 1 || h.Nscount != 0 || h.Arcount != 1 { - t.Errorf("expected to have question and additional in response; got something else: %+v", h) - } - if err = r.Unpack(buf); err != nil { - t.Errorf("unable to unpack message fully: %v", err) - } -} - -func TestTruncatedMsg(t *testing.T) { - m := new(Msg) - m.SetQuestion("miek.nl.", TypeSRV) - cnt := 10 - for i := 0; i < cnt; i++ { - r := &SRV{ - Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeSRV, Class: ClassINET, Ttl: 0}, - Port: uint16(i + 8000), - Target: "target.miek.nl.", - } - m.Answer = append(m.Answer, r) - - re := &A{ - Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeA, Class: ClassINET, Ttl: 0}, - A: net.ParseIP(fmt.Sprintf("127.0.0.%d", i)).To4(), - } - m.Extra = append(m.Extra, re) - } - buf, err := m.Pack() - if err != nil { - t.Errorf("failed to pack: %v", err) - } - - r := new(Msg) - if err = r.Unpack(buf); err != nil { - t.Errorf("unable to unpack message: %v", err) - } - if len(r.Answer) != cnt { - t.Errorf("answer count after regular unpack doesn't match: %d", len(r.Answer)) - } - if len(r.Extra) != cnt { - t.Errorf("extra count after regular unpack doesn't match: %d", len(r.Extra)) - } - - m.Truncated = true - buf, err = m.Pack() - if err != nil { - t.Errorf("failed to pack truncated: %v", err) - } - - r = new(Msg) - if err = r.Unpack(buf); err != nil && err != ErrTruncated { - t.Errorf("unable to unpack truncated message: %v", err) - } - if !r.Truncated { - t.Errorf("truncated message wasn't unpacked as truncated") - } - if len(r.Answer) != cnt { - t.Errorf("answer count after truncated unpack doesn't match: %d", len(r.Answer)) - } - if len(r.Extra) != cnt { - t.Errorf("extra count after truncated unpack doesn't match: %d", len(r.Extra)) - } - - // Now we want to remove almost all of the extra records - // We're going to loop over the extra to get the count of the size of all - // of them - off := 0 - buf1 := make([]byte, m.Len()) - for i := 0; i < len(m.Extra); i++ { - off, err = PackRR(m.Extra[i], buf1, off, nil, m.Compress) - if err != nil { - t.Errorf("failed to pack extra: %v", err) - } - } - - // Remove all of the extra bytes but 10 bytes from the end of buf - off -= 10 - buf1 = buf[:len(buf)-off] - - r = new(Msg) - if err = r.Unpack(buf1); err != nil && err != ErrTruncated { - t.Errorf("unable to unpack cutoff message: %v", err) - } - if !r.Truncated { - t.Error("truncated cutoff message wasn't unpacked as truncated") - } - if len(r.Answer) != cnt { - t.Errorf("answer count after cutoff unpack doesn't match: %d", len(r.Answer)) - } - if len(r.Extra) != 0 { - t.Errorf("extra count after cutoff unpack is not zero: %d", len(r.Extra)) - } - - // Now we want to remove almost all of the answer records too - buf1 = make([]byte, m.Len()) - as := 0 - for i := 0; i < len(m.Extra); i++ { - off1 := off - off, err = PackRR(m.Extra[i], buf1, off, nil, m.Compress) - as = off - off1 - if err != nil { - t.Errorf("failed to pack extra: %v", err) - } - } - - // Keep exactly one answer left - // This should still cause Answer to be nil - off -= as - buf1 = buf[:len(buf)-off] - - r = new(Msg) - if err = r.Unpack(buf1); err != nil && err != ErrTruncated { - t.Errorf("unable to unpack cutoff message: %v", err) - } - if !r.Truncated { - t.Error("truncated cutoff message wasn't unpacked as truncated") - } - if len(r.Answer) != 0 { - t.Errorf("answer count after second cutoff unpack is not zero: %d", len(r.Answer)) - } - - // Now leave only 1 byte of the question - // Since the header is always 12 bytes, we just need to keep 13 - buf1 = buf[:13] - - r = new(Msg) - err = r.Unpack(buf1) - if err == nil || err == ErrTruncated { - t.Errorf("error should not be ErrTruncated from question cutoff unpack: %v", err) - } - - // Finally, if we only have the header, we should still return an error - buf1 = buf[:12] - - r = new(Msg) - if err = r.Unpack(buf1); err == nil || err != ErrTruncated { - t.Errorf("error not ErrTruncated from header-only unpack: %v", err) - } -} - -func TestTimeout(t *testing.T) { - // Set up a dummy UDP server that won't respond - addr, err := net.ResolveUDPAddr("udp", "127.0.0.1:0") - if err != nil { - t.Fatalf("unable to resolve local udp address: %v", err) - } - conn, err := net.ListenUDP("udp", addr) - if err != nil { - t.Fatalf("unable to run test server: %v", err) - } - defer conn.Close() - addrstr := conn.LocalAddr().String() - - // Message to send - m := new(Msg) - m.SetQuestion("miek.nl.", TypeTXT) - - // Use a channel + timeout to ensure we don't get stuck if the - // Client Timeout is not working properly - done := make(chan struct{}) - - timeout := time.Millisecond - allowable := timeout + (10 * time.Millisecond) - abortAfter := timeout + (100 * time.Millisecond) - - start := time.Now() - - go func() { - c := &Client{Timeout: timeout} - _, _, err := c.Exchange(m, addrstr) - if err == nil { - t.Error("no timeout using Client") - } - done <- struct{}{} - }() - - select { - case <-done: - case <-time.After(abortAfter): - } - - length := time.Since(start) - - if length > allowable { - t.Errorf("exchange took longer (%v) than specified Timeout (%v)", length, timeout) - } -} - -// Check that responses from deduplicated requests aren't shared between callers -func TestConcurrentExchanges(t *testing.T) { - cases := make([]*Msg, 2) - cases[0] = new(Msg) - cases[1] = new(Msg) - cases[1].Truncated = true - for _, m := range cases { - block := make(chan struct{}) - waiting := make(chan struct{}) - - handler := func(w ResponseWriter, req *Msg) { - r := m.Copy() - r.SetReply(req) - - waiting <- struct{}{} - <-block - w.WriteMsg(r) - } - - HandleFunc("miek.nl.", handler) - defer HandleRemove("miek.nl.") - - s, addrstr, err := RunLocalUDPServer("127.0.0.1:0") - if err != nil { - t.Fatalf("unable to run test server: %s", err) - } - defer s.Shutdown() - - m := new(Msg) - m.SetQuestion("miek.nl.", TypeSRV) - c := &Client{ - SingleInflight: true, - } - r := make([]*Msg, 2) - - var wg sync.WaitGroup - wg.Add(len(r)) - for i := 0; i < len(r); i++ { - go func(i int) { - r[i], _, _ = c.Exchange(m.Copy(), addrstr) - wg.Done() - }(i) - } - select { - case <-waiting: - case <-time.After(time.Second): - t.FailNow() - } - close(block) - wg.Wait() - - if r[0] == r[1] { - t.Log("Got same response object, expected non-shared responses") - t.Fail() - } - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/clientconfig.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/clientconfig.go deleted file mode 100644 index 0a1f5a92c..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/clientconfig.go +++ /dev/null @@ -1,131 +0,0 @@ -package dns - -import ( - "bufio" - "os" - "strconv" - "strings" -) - -// ClientConfig wraps the contents of the /etc/resolv.conf file. -type ClientConfig struct { - Servers []string // servers to use - Search []string // suffixes to append to local name - Port string // what port to use - Ndots int // number of dots in name to trigger absolute lookup - Timeout int // seconds before giving up on packet - Attempts int // lost packets before giving up on server, not used in the package dns -} - -// ClientConfigFromFile parses a resolv.conf(5) like file and returns -// a *ClientConfig. -func ClientConfigFromFile(resolvconf string) (*ClientConfig, error) { - file, err := os.Open(resolvconf) - if err != nil { - return nil, err - } - defer file.Close() - c := new(ClientConfig) - scanner := bufio.NewScanner(file) - c.Servers = make([]string, 0) - c.Search = make([]string, 0) - c.Port = "53" - c.Ndots = 1 - c.Timeout = 5 - c.Attempts = 2 - - for scanner.Scan() { - if err := scanner.Err(); err != nil { - return nil, err - } - line := scanner.Text() - f := strings.Fields(line) - if len(f) < 1 { - continue - } - switch f[0] { - case "nameserver": // add one name server - if len(f) > 1 { - // One more check: make sure server name is - // just an IP address. Otherwise we need DNS - // to look it up. - name := f[1] - c.Servers = append(c.Servers, name) - } - - case "domain": // set search path to just this domain - if len(f) > 1 { - c.Search = make([]string, 1) - c.Search[0] = f[1] - } else { - c.Search = make([]string, 0) - } - - case "search": // set search path to given servers - c.Search = make([]string, len(f)-1) - for i := 0; i < len(c.Search); i++ { - c.Search[i] = f[i+1] - } - - case "options": // magic options - for i := 1; i < len(f); i++ { - s := f[i] - switch { - case len(s) >= 6 && s[:6] == "ndots:": - n, _ := strconv.Atoi(s[6:]) - if n < 1 { - n = 1 - } - c.Ndots = n - case len(s) >= 8 && s[:8] == "timeout:": - n, _ := strconv.Atoi(s[8:]) - if n < 1 { - n = 1 - } - c.Timeout = n - case len(s) >= 8 && s[:9] == "attempts:": - n, _ := strconv.Atoi(s[9:]) - if n < 1 { - n = 1 - } - c.Attempts = n - case s == "rotate": - /* not imp */ - } - } - } - } - return c, nil -} - -// NameList returns all of the names that should be queried based on the -// config. It is based off of go's net/dns name building, but it does not -// check the length of the resulting names. -func (c *ClientConfig) NameList(name string) []string { - // if this domain is already fully qualified, no append needed. - if IsFqdn(name) { - return []string{name} - } - - // Check to see if the name has more labels than Ndots. Do this before making - // the domain fully qualified. - hasNdots := CountLabel(name) > c.Ndots - // Make the domain fully qualified. - name = Fqdn(name) - - // Make a list of names based off search. - names := []string{} - - // If name has enough dots, try that first. - if hasNdots { - names = append(names, name) - } - for _, s := range c.Search { - names = append(names, Fqdn(name+s)) - } - // If we didn't have enough dots, try after suffixes. - if !hasNdots { - names = append(names, name) - } - return names -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/clientconfig_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/clientconfig_test.go deleted file mode 100644 index 7755a8a6f..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/clientconfig_test.go +++ /dev/null @@ -1,87 +0,0 @@ -package dns - -import ( - "io/ioutil" - "os" - "path/filepath" - "testing" -) - -const normal string = ` -# Comment -domain somedomain.com -nameserver 10.28.10.2 -nameserver 11.28.10.1 -` - -const missingNewline string = ` -domain somedomain.com -nameserver 10.28.10.2 -nameserver 11.28.10.1` // <- NOTE: NO newline. - -func testConfig(t *testing.T, data string) { - tempDir, err := ioutil.TempDir("", "") - if err != nil { - t.Fatalf("tempDir: %v", err) - } - defer os.RemoveAll(tempDir) - - path := filepath.Join(tempDir, "resolv.conf") - if err := ioutil.WriteFile(path, []byte(data), 0644); err != nil { - t.Fatalf("writeFile: %v", err) - } - cc, err := ClientConfigFromFile(path) - if err != nil { - t.Errorf("error parsing resolv.conf: %v", err) - } - if l := len(cc.Servers); l != 2 { - t.Errorf("incorrect number of nameservers detected: %d", l) - } - if l := len(cc.Search); l != 1 { - t.Errorf("domain directive not parsed correctly: %v", cc.Search) - } else { - if cc.Search[0] != "somedomain.com" { - t.Errorf("domain is unexpected: %v", cc.Search[0]) - } - } -} - -func TestNameserver(t *testing.T) { testConfig(t, normal) } -func TestMissingFinalNewLine(t *testing.T) { testConfig(t, missingNewline) } - -func TestNameList(t *testing.T) { - cfg := ClientConfig{ - Ndots: 1, - } - // fqdn should be only result returned - names := cfg.NameList("miek.nl.") - if len(names) != 1 { - t.Errorf("NameList returned != 1 names: %v", names) - } else if names[0] != "miek.nl." { - t.Errorf("NameList didn't return sent fqdn domain: %v", names[0]) - } - - cfg.Search = []string{ - "test", - } - // Sent domain has NDots and search - names = cfg.NameList("miek.nl") - if len(names) != 2 { - t.Errorf("NameList returned != 2 names: %v", names) - } else if names[0] != "miek.nl." { - t.Errorf("NameList didn't return sent domain first: %v", names[0]) - } else if names[1] != "miek.nl.test." { - t.Errorf("NameList didn't return search last: %v", names[1]) - } - - cfg.Ndots = 2 - // Sent domain has less than NDots and search - names = cfg.NameList("miek.nl") - if len(names) != 2 { - t.Errorf("NameList returned != 2 names: %v", names) - } else if names[0] != "miek.nl.test." { - t.Errorf("NameList didn't return search first: %v", names[0]) - } else if names[1] != "miek.nl." { - t.Errorf("NameList didn't return sent domain last: %v", names[1]) - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/compress_generate.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/compress_generate.go deleted file mode 100644 index 1a301e9f3..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/compress_generate.go +++ /dev/null @@ -1,184 +0,0 @@ -//+build ignore - -// compression_generate.go is meant to run with go generate. It will use -// go/{importer,types} to track down all the RR struct types. Then for each type -// it will look to see if there are (compressible) names, if so it will add that -// type to compressionLenHelperType and comressionLenSearchType which "fake" the -// compression so that Len() is fast. -package main - -import ( - "bytes" - "fmt" - "go/format" - "go/importer" - "go/types" - "log" - "os" -) - -var packageHdr = ` -// *** DO NOT MODIFY *** -// AUTOGENERATED BY go generate from compress_generate.go - -package dns - -` - -// getTypeStruct will take a type and the package scope, and return the -// (innermost) struct if the type is considered a RR type (currently defined as -// those structs beginning with a RR_Header, could be redefined as implementing -// the RR interface). The bool return value indicates if embedded structs were -// resolved. -func getTypeStruct(t types.Type, scope *types.Scope) (*types.Struct, bool) { - st, ok := t.Underlying().(*types.Struct) - if !ok { - return nil, false - } - if st.Field(0).Type() == scope.Lookup("RR_Header").Type() { - return st, false - } - if st.Field(0).Anonymous() { - st, _ := getTypeStruct(st.Field(0).Type(), scope) - return st, true - } - return nil, false -} - -func main() { - // Import and type-check the package - pkg, err := importer.Default().Import("github.com/miekg/dns") - fatalIfErr(err) - scope := pkg.Scope() - - domainTypes := map[string]bool{} // Types that have a domain name in them (either comressible or not). - cdomainTypes := map[string]bool{} // Types that have a compressible domain name in them (subset of domainType) - for _, name := range scope.Names() { - o := scope.Lookup(name) - if o == nil || !o.Exported() { - continue - } - st, _ := getTypeStruct(o.Type(), scope) - if st == nil { - continue - } - if name == "PrivateRR" { - continue - } - - if scope.Lookup("Type"+o.Name()) == nil && o.Name() != "RFC3597" { - log.Fatalf("Constant Type%s does not exist.", o.Name()) - } - - for i := 1; i < st.NumFields(); i++ { - if _, ok := st.Field(i).Type().(*types.Slice); ok { - if st.Tag(i) == `dns:"domain-name"` { - domainTypes[o.Name()] = true - } - if st.Tag(i) == `dns:"cdomain-name"` { - cdomainTypes[o.Name()] = true - domainTypes[o.Name()] = true - } - continue - } - - switch { - case st.Tag(i) == `dns:"domain-name"`: - domainTypes[o.Name()] = true - case st.Tag(i) == `dns:"cdomain-name"`: - cdomainTypes[o.Name()] = true - domainTypes[o.Name()] = true - } - } - } - - b := &bytes.Buffer{} - b.WriteString(packageHdr) - - // compressionLenHelperType - all types that have domain-name/cdomain-name can be used for compressing names - - fmt.Fprint(b, "func compressionLenHelperType(c map[string]int, r RR) {\n") - fmt.Fprint(b, "switch x := r.(type) {\n") - for name, _ := range domainTypes { - o := scope.Lookup(name) - st, _ := getTypeStruct(o.Type(), scope) - - fmt.Fprintf(b, "case *%s:\n", name) - for i := 1; i < st.NumFields(); i++ { - out := func(s string) { fmt.Fprintf(b, "compressionLenHelper(c, x.%s)\n", st.Field(i).Name()) } - - if _, ok := st.Field(i).Type().(*types.Slice); ok { - switch st.Tag(i) { - case `dns:"domain-name"`: - fallthrough - case `dns:"cdomain-name"`: - // For HIP we need to slice over the elements in this slice. - fmt.Fprintf(b, `for i := range x.%s { - compressionLenHelper(c, x.%s[i]) - } -`, st.Field(i).Name(), st.Field(i).Name()) - } - continue - } - - switch { - case st.Tag(i) == `dns:"cdomain-name"`: - fallthrough - case st.Tag(i) == `dns:"domain-name"`: - out(st.Field(i).Name()) - } - } - } - fmt.Fprintln(b, "}\n}\n\n") - - // compressionLenSearchType - search cdomain-tags types for compressible names. - - fmt.Fprint(b, "func compressionLenSearchType(c map[string]int, r RR) (int, bool) {\n") - fmt.Fprint(b, "switch x := r.(type) {\n") - for name, _ := range cdomainTypes { - o := scope.Lookup(name) - st, _ := getTypeStruct(o.Type(), scope) - - fmt.Fprintf(b, "case *%s:\n", name) - j := 1 - for i := 1; i < st.NumFields(); i++ { - out := func(s string, j int) { - fmt.Fprintf(b, "k%d, ok%d := compressionLenSearch(c, x.%s)\n", j, j, st.Field(i).Name()) - } - - // There are no slice types with names that can be compressed. - - switch { - case st.Tag(i) == `dns:"cdomain-name"`: - out(st.Field(i).Name(), j) - j++ - } - } - k := "k1" - ok := "ok1" - for i := 2; i < j; i++ { - k += fmt.Sprintf(" + k%d", i) - ok += fmt.Sprintf(" && ok%d", i) - } - fmt.Fprintf(b, "return %s, %s\n", k, ok) - } - fmt.Fprintln(b, "}\nreturn 0, false\n}\n\n") - - // gofmt - res, err := format.Source(b.Bytes()) - if err != nil { - b.WriteTo(os.Stderr) - log.Fatal(err) - } - - f, err := os.Create("zcompress.go") - fatalIfErr(err) - defer f.Close() - f.Write(res) -} - -func fatalIfErr(err error) { - if err != nil { - log.Fatal(err) - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dane.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dane.go deleted file mode 100644 index 8c4a14ef1..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dane.go +++ /dev/null @@ -1,43 +0,0 @@ -package dns - -import ( - "crypto/sha256" - "crypto/sha512" - "crypto/x509" - "encoding/hex" - "errors" -) - -// CertificateToDANE converts a certificate to a hex string as used in the TLSA or SMIMEA records. -func CertificateToDANE(selector, matchingType uint8, cert *x509.Certificate) (string, error) { - switch matchingType { - case 0: - switch selector { - case 0: - return hex.EncodeToString(cert.Raw), nil - case 1: - return hex.EncodeToString(cert.RawSubjectPublicKeyInfo), nil - } - case 1: - h := sha256.New() - switch selector { - case 0: - h.Write(cert.Raw) - return hex.EncodeToString(h.Sum(nil)), nil - case 1: - h.Write(cert.RawSubjectPublicKeyInfo) - return hex.EncodeToString(h.Sum(nil)), nil - } - case 2: - h := sha512.New() - switch selector { - case 0: - h.Write(cert.Raw) - return hex.EncodeToString(h.Sum(nil)), nil - case 1: - h.Write(cert.RawSubjectPublicKeyInfo) - return hex.EncodeToString(h.Sum(nil)), nil - } - } - return "", errors.New("dns: bad MatchingType or Selector") -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/defaults.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/defaults.go deleted file mode 100644 index c34890eec..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/defaults.go +++ /dev/null @@ -1,285 +0,0 @@ -package dns - -import ( - "errors" - "net" - "strconv" -) - -const hexDigit = "0123456789abcdef" - -// Everything is assumed in ClassINET. - -// SetReply creates a reply message from a request message. -func (dns *Msg) SetReply(request *Msg) *Msg { - dns.Id = request.Id - dns.Response = true - dns.Opcode = request.Opcode - if dns.Opcode == OpcodeQuery { - dns.RecursionDesired = request.RecursionDesired // Copy rd bit - dns.CheckingDisabled = request.CheckingDisabled // Copy cd bit - } - dns.Rcode = RcodeSuccess - if len(request.Question) > 0 { - dns.Question = make([]Question, 1) - dns.Question[0] = request.Question[0] - } - return dns -} - -// SetQuestion creates a question message, it sets the Question -// section, generates an Id and sets the RecursionDesired (RD) -// bit to true. -func (dns *Msg) SetQuestion(z string, t uint16) *Msg { - dns.Id = Id() - dns.RecursionDesired = true - dns.Question = make([]Question, 1) - dns.Question[0] = Question{z, t, ClassINET} - return dns -} - -// SetNotify creates a notify message, it sets the Question -// section, generates an Id and sets the Authoritative (AA) -// bit to true. -func (dns *Msg) SetNotify(z string) *Msg { - dns.Opcode = OpcodeNotify - dns.Authoritative = true - dns.Id = Id() - dns.Question = make([]Question, 1) - dns.Question[0] = Question{z, TypeSOA, ClassINET} - return dns -} - -// SetRcode creates an error message suitable for the request. -func (dns *Msg) SetRcode(request *Msg, rcode int) *Msg { - dns.SetReply(request) - dns.Rcode = rcode - return dns -} - -// SetRcodeFormatError creates a message with FormError set. -func (dns *Msg) SetRcodeFormatError(request *Msg) *Msg { - dns.Rcode = RcodeFormatError - dns.Opcode = OpcodeQuery - dns.Response = true - dns.Authoritative = false - dns.Id = request.Id - return dns -} - -// SetUpdate makes the message a dynamic update message. It -// sets the ZONE section to: z, TypeSOA, ClassINET. -func (dns *Msg) SetUpdate(z string) *Msg { - dns.Id = Id() - dns.Response = false - dns.Opcode = OpcodeUpdate - dns.Compress = false // BIND9 cannot handle compression - dns.Question = make([]Question, 1) - dns.Question[0] = Question{z, TypeSOA, ClassINET} - return dns -} - -// SetIxfr creates message for requesting an IXFR. -func (dns *Msg) SetIxfr(z string, serial uint32, ns, mbox string) *Msg { - dns.Id = Id() - dns.Question = make([]Question, 1) - dns.Ns = make([]RR, 1) - s := new(SOA) - s.Hdr = RR_Header{z, TypeSOA, ClassINET, defaultTtl, 0} - s.Serial = serial - s.Ns = ns - s.Mbox = mbox - dns.Question[0] = Question{z, TypeIXFR, ClassINET} - dns.Ns[0] = s - return dns -} - -// SetAxfr creates message for requesting an AXFR. -func (dns *Msg) SetAxfr(z string) *Msg { - dns.Id = Id() - dns.Question = make([]Question, 1) - dns.Question[0] = Question{z, TypeAXFR, ClassINET} - return dns -} - -// SetTsig appends a TSIG RR to the message. -// This is only a skeleton TSIG RR that is added as the last RR in the -// additional section. The Tsig is calculated when the message is being send. -func (dns *Msg) SetTsig(z, algo string, fudge uint16, timesigned int64) *Msg { - t := new(TSIG) - t.Hdr = RR_Header{z, TypeTSIG, ClassANY, 0, 0} - t.Algorithm = algo - t.Fudge = fudge - t.TimeSigned = uint64(timesigned) - t.OrigId = dns.Id - dns.Extra = append(dns.Extra, t) - return dns -} - -// SetEdns0 appends a EDNS0 OPT RR to the message. -// TSIG should always the last RR in a message. -func (dns *Msg) SetEdns0(udpsize uint16, do bool) *Msg { - e := new(OPT) - e.Hdr.Name = "." - e.Hdr.Rrtype = TypeOPT - e.SetUDPSize(udpsize) - if do { - e.SetDo() - } - dns.Extra = append(dns.Extra, e) - return dns -} - -// IsTsig checks if the message has a TSIG record as the last record -// in the additional section. It returns the TSIG record found or nil. -func (dns *Msg) IsTsig() *TSIG { - if len(dns.Extra) > 0 { - if dns.Extra[len(dns.Extra)-1].Header().Rrtype == TypeTSIG { - return dns.Extra[len(dns.Extra)-1].(*TSIG) - } - } - return nil -} - -// IsEdns0 checks if the message has a EDNS0 (OPT) record, any EDNS0 -// record in the additional section will do. It returns the OPT record -// found or nil. -func (dns *Msg) IsEdns0() *OPT { - // EDNS0 is at the end of the additional section, start there. - // We might want to change this to *only* look at the last two - // records. So we see TSIG and/or OPT - this a slightly bigger - // change though. - for i := len(dns.Extra) - 1; i >= 0; i-- { - if dns.Extra[i].Header().Rrtype == TypeOPT { - return dns.Extra[i].(*OPT) - } - } - return nil -} - -// IsDomainName checks if s is a valid domain name, it returns the number of -// labels and true, when a domain name is valid. Note that non fully qualified -// domain name is considered valid, in this case the last label is counted in -// the number of labels. When false is returned the number of labels is not -// defined. Also note that this function is extremely liberal; almost any -// string is a valid domain name as the DNS is 8 bit protocol. It checks if each -// label fits in 63 characters, but there is no length check for the entire -// string s. I.e. a domain name longer than 255 characters is considered valid. -func IsDomainName(s string) (labels int, ok bool) { - _, labels, err := packDomainName(s, nil, 0, nil, false) - return labels, err == nil -} - -// IsSubDomain checks if child is indeed a child of the parent. If child and parent -// are the same domain true is returned as well. -func IsSubDomain(parent, child string) bool { - // Entire child is contained in parent - return CompareDomainName(parent, child) == CountLabel(parent) -} - -// IsMsg sanity checks buf and returns an error if it isn't a valid DNS packet. -// The checking is performed on the binary payload. -func IsMsg(buf []byte) error { - // Header - if len(buf) < 12 { - return errors.New("dns: bad message header") - } - // Header: Opcode - // TODO(miek): more checks here, e.g. check all header bits. - return nil -} - -// IsFqdn checks if a domain name is fully qualified. -func IsFqdn(s string) bool { - l := len(s) - if l == 0 { - return false - } - return s[l-1] == '.' -} - -// IsRRset checks if a set of RRs is a valid RRset as defined by RFC 2181. -// This means the RRs need to have the same type, name, and class. Returns true -// if the RR set is valid, otherwise false. -func IsRRset(rrset []RR) bool { - if len(rrset) == 0 { - return false - } - if len(rrset) == 1 { - return true - } - rrHeader := rrset[0].Header() - rrType := rrHeader.Rrtype - rrClass := rrHeader.Class - rrName := rrHeader.Name - - for _, rr := range rrset[1:] { - curRRHeader := rr.Header() - if curRRHeader.Rrtype != rrType || curRRHeader.Class != rrClass || curRRHeader.Name != rrName { - // Mismatch between the records, so this is not a valid rrset for - //signing/verifying - return false - } - } - - return true -} - -// Fqdn return the fully qualified domain name from s. -// If s is already fully qualified, it behaves as the identity function. -func Fqdn(s string) string { - if IsFqdn(s) { - return s - } - return s + "." -} - -// Copied from the official Go code. - -// ReverseAddr returns the in-addr.arpa. or ip6.arpa. hostname of the IP -// address suitable for reverse DNS (PTR) record lookups or an error if it fails -// to parse the IP address. -func ReverseAddr(addr string) (arpa string, err error) { - ip := net.ParseIP(addr) - if ip == nil { - return "", &Error{err: "unrecognized address: " + addr} - } - if ip.To4() != nil { - return strconv.Itoa(int(ip[15])) + "." + strconv.Itoa(int(ip[14])) + "." + strconv.Itoa(int(ip[13])) + "." + - strconv.Itoa(int(ip[12])) + ".in-addr.arpa.", nil - } - // Must be IPv6 - buf := make([]byte, 0, len(ip)*4+len("ip6.arpa.")) - // Add it, in reverse, to the buffer - for i := len(ip) - 1; i >= 0; i-- { - v := ip[i] - buf = append(buf, hexDigit[v&0xF]) - buf = append(buf, '.') - buf = append(buf, hexDigit[v>>4]) - buf = append(buf, '.') - } - // Append "ip6.arpa." and return (buf already has the final .) - buf = append(buf, "ip6.arpa."...) - return string(buf), nil -} - -// String returns the string representation for the type t. -func (t Type) String() string { - if t1, ok := TypeToString[uint16(t)]; ok { - return t1 - } - return "TYPE" + strconv.Itoa(int(t)) -} - -// String returns the string representation for the class c. -func (c Class) String() string { - if c1, ok := ClassToString[uint16(c)]; ok { - return c1 - } - return "CLASS" + strconv.Itoa(int(c)) -} - -// String returns the string representation for the name n. -func (n Name) String() string { - return sprintName(string(n)) -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dns.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dns.go deleted file mode 100644 index b3292287c..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dns.go +++ /dev/null @@ -1,104 +0,0 @@ -package dns - -import "strconv" - -const ( - year68 = 1 << 31 // For RFC1982 (Serial Arithmetic) calculations in 32 bits. - defaultTtl = 3600 // Default internal TTL. - - DefaultMsgSize = 4096 // DefaultMsgSize is the standard default for messages larger than 512 bytes. - MinMsgSize = 512 // MinMsgSize is the minimal size of a DNS packet. - MaxMsgSize = 65535 // MaxMsgSize is the largest possible DNS packet. -) - -// Error represents a DNS error. -type Error struct{ err string } - -func (e *Error) Error() string { - if e == nil { - return "dns: <nil>" - } - return "dns: " + e.err -} - -// An RR represents a resource record. -type RR interface { - // Header returns the header of an resource record. The header contains - // everything up to the rdata. - Header() *RR_Header - // String returns the text representation of the resource record. - String() string - - // copy returns a copy of the RR - copy() RR - // len returns the length (in octets) of the uncompressed RR in wire format. - len() int - // pack packs an RR into wire format. - pack([]byte, int, map[string]int, bool) (int, error) -} - -// RR_Header is the header all DNS resource records share. -type RR_Header struct { - Name string `dns:"cdomain-name"` - Rrtype uint16 - Class uint16 - Ttl uint32 - Rdlength uint16 // Length of data after header. -} - -// Header returns itself. This is here to make RR_Header implements the RR interface. -func (h *RR_Header) Header() *RR_Header { return h } - -// Just to implement the RR interface. -func (h *RR_Header) copy() RR { return nil } - -func (h *RR_Header) copyHeader() *RR_Header { - r := new(RR_Header) - r.Name = h.Name - r.Rrtype = h.Rrtype - r.Class = h.Class - r.Ttl = h.Ttl - r.Rdlength = h.Rdlength - return r -} - -func (h *RR_Header) String() string { - var s string - - if h.Rrtype == TypeOPT { - s = ";" - // and maybe other things - } - - s += sprintName(h.Name) + "\t" - s += strconv.FormatInt(int64(h.Ttl), 10) + "\t" - s += Class(h.Class).String() + "\t" - s += Type(h.Rrtype).String() + "\t" - return s -} - -func (h *RR_Header) len() int { - l := len(h.Name) + 1 - l += 10 // rrtype(2) + class(2) + ttl(4) + rdlength(2) - return l -} - -// ToRFC3597 converts a known RR to the unknown RR representation from RFC 3597. -func (rr *RFC3597) ToRFC3597(r RR) error { - buf := make([]byte, r.len()*2) - off, err := PackRR(r, buf, 0, nil, false) - if err != nil { - return err - } - buf = buf[:off] - if int(r.Header().Rdlength) > off { - return ErrBuf - } - - rfc3597, _, err := unpackRFC3597(*r.Header(), buf, off-int(r.Header().Rdlength)) - if err != nil { - return err - } - *rr = *rfc3597.(*RFC3597) - return nil -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dns_bench_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dns_bench_test.go deleted file mode 100644 index bccc3d540..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dns_bench_test.go +++ /dev/null @@ -1,211 +0,0 @@ -package dns - -import ( - "net" - "testing" -) - -func BenchmarkMsgLength(b *testing.B) { - b.StopTimer() - makeMsg := func(question string, ans, ns, e []RR) *Msg { - msg := new(Msg) - msg.SetQuestion(Fqdn(question), TypeANY) - msg.Answer = append(msg.Answer, ans...) - msg.Ns = append(msg.Ns, ns...) - msg.Extra = append(msg.Extra, e...) - msg.Compress = true - return msg - } - name1 := "12345678901234567890123456789012345.12345678.123." - rrMx, _ := NewRR(name1 + " 3600 IN MX 10 " + name1) - msg := makeMsg(name1, []RR{rrMx, rrMx}, nil, nil) - b.StartTimer() - for i := 0; i < b.N; i++ { - msg.Len() - } -} - -func BenchmarkMsgLengthPack(b *testing.B) { - makeMsg := func(question string, ans, ns, e []RR) *Msg { - msg := new(Msg) - msg.SetQuestion(Fqdn(question), TypeANY) - msg.Answer = append(msg.Answer, ans...) - msg.Ns = append(msg.Ns, ns...) - msg.Extra = append(msg.Extra, e...) - msg.Compress = true - return msg - } - name1 := "12345678901234567890123456789012345.12345678.123." - rrMx, _ := NewRR(name1 + " 3600 IN MX 10 " + name1) - msg := makeMsg(name1, []RR{rrMx, rrMx}, nil, nil) - b.ResetTimer() - for i := 0; i < b.N; i++ { - _, _ = msg.Pack() - } -} - -func BenchmarkPackDomainName(b *testing.B) { - name1 := "12345678901234567890123456789012345.12345678.123." - buf := make([]byte, len(name1)+1) - b.ResetTimer() - for i := 0; i < b.N; i++ { - _, _ = PackDomainName(name1, buf, 0, nil, false) - } -} - -func BenchmarkUnpackDomainName(b *testing.B) { - name1 := "12345678901234567890123456789012345.12345678.123." - buf := make([]byte, len(name1)+1) - _, _ = PackDomainName(name1, buf, 0, nil, false) - b.ResetTimer() - for i := 0; i < b.N; i++ { - _, _, _ = UnpackDomainName(buf, 0) - } -} - -func BenchmarkUnpackDomainNameUnprintable(b *testing.B) { - name1 := "\x02\x02\x02\x025\x02\x02\x02\x02.12345678.123." - buf := make([]byte, len(name1)+1) - _, _ = PackDomainName(name1, buf, 0, nil, false) - b.ResetTimer() - for i := 0; i < b.N; i++ { - _, _, _ = UnpackDomainName(buf, 0) - } -} - -func BenchmarkCopy(b *testing.B) { - b.ReportAllocs() - m := new(Msg) - m.SetQuestion("miek.nl.", TypeA) - rr, _ := NewRR("miek.nl. 2311 IN A 127.0.0.1") - m.Answer = []RR{rr} - rr, _ = NewRR("miek.nl. 2311 IN NS 127.0.0.1") - m.Ns = []RR{rr} - rr, _ = NewRR("miek.nl. 2311 IN A 127.0.0.1") - m.Extra = []RR{rr} - - b.ResetTimer() - for i := 0; i < b.N; i++ { - m.Copy() - } -} - -func BenchmarkPackA(b *testing.B) { - a := &A{Hdr: RR_Header{Name: ".", Rrtype: TypeA, Class: ClassANY}, A: net.IPv4(127, 0, 0, 1)} - - buf := make([]byte, a.len()) - b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { - _, _ = PackRR(a, buf, 0, nil, false) - } -} - -func BenchmarkUnpackA(b *testing.B) { - a := &A{Hdr: RR_Header{Name: ".", Rrtype: TypeA, Class: ClassANY}, A: net.IPv4(127, 0, 0, 1)} - - buf := make([]byte, a.len()) - PackRR(a, buf, 0, nil, false) - a = nil - b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { - _, _, _ = UnpackRR(buf, 0) - } -} - -func BenchmarkPackMX(b *testing.B) { - m := &MX{Hdr: RR_Header{Name: ".", Rrtype: TypeA, Class: ClassANY}, Mx: "mx.miek.nl."} - - buf := make([]byte, m.len()) - b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { - _, _ = PackRR(m, buf, 0, nil, false) - } -} - -func BenchmarkUnpackMX(b *testing.B) { - m := &MX{Hdr: RR_Header{Name: ".", Rrtype: TypeA, Class: ClassANY}, Mx: "mx.miek.nl."} - - buf := make([]byte, m.len()) - PackRR(m, buf, 0, nil, false) - m = nil - b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { - _, _, _ = UnpackRR(buf, 0) - } -} - -func BenchmarkPackAAAAA(b *testing.B) { - aaaa, _ := NewRR(". IN A ::1") - - buf := make([]byte, aaaa.len()) - b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { - _, _ = PackRR(aaaa, buf, 0, nil, false) - } -} - -func BenchmarkUnpackAAAA(b *testing.B) { - aaaa, _ := NewRR(". IN A ::1") - - buf := make([]byte, aaaa.len()) - PackRR(aaaa, buf, 0, nil, false) - aaaa = nil - b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { - _, _, _ = UnpackRR(buf, 0) - } -} - -func BenchmarkPackMsg(b *testing.B) { - makeMsg := func(question string, ans, ns, e []RR) *Msg { - msg := new(Msg) - msg.SetQuestion(Fqdn(question), TypeANY) - msg.Answer = append(msg.Answer, ans...) - msg.Ns = append(msg.Ns, ns...) - msg.Extra = append(msg.Extra, e...) - msg.Compress = true - return msg - } - name1 := "12345678901234567890123456789012345.12345678.123." - rrMx, _ := NewRR(name1 + " 3600 IN MX 10 " + name1) - msg := makeMsg(name1, []RR{rrMx, rrMx}, nil, nil) - buf := make([]byte, 512) - b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { - _, _ = msg.PackBuffer(buf) - } -} - -func BenchmarkUnpackMsg(b *testing.B) { - makeMsg := func(question string, ans, ns, e []RR) *Msg { - msg := new(Msg) - msg.SetQuestion(Fqdn(question), TypeANY) - msg.Answer = append(msg.Answer, ans...) - msg.Ns = append(msg.Ns, ns...) - msg.Extra = append(msg.Extra, e...) - msg.Compress = true - return msg - } - name1 := "12345678901234567890123456789012345.12345678.123." - rrMx, _ := NewRR(name1 + " 3600 IN MX 10 " + name1) - msg := makeMsg(name1, []RR{rrMx, rrMx}, nil, nil) - msgBuf, _ := msg.Pack() - b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { - _ = msg.Unpack(msgBuf) - } -} - -func BenchmarkIdGeneration(b *testing.B) { - for i := 0; i < b.N; i++ { - _ = id() - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dns_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dns_test.go deleted file mode 100644 index dbfe25328..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dns_test.go +++ /dev/null @@ -1,450 +0,0 @@ -package dns - -import ( - "encoding/hex" - "net" - "testing" -) - -func TestPackUnpack(t *testing.T) { - out := new(Msg) - out.Answer = make([]RR, 1) - key := new(DNSKEY) - key = &DNSKEY{Flags: 257, Protocol: 3, Algorithm: RSASHA1} - key.Hdr = RR_Header{Name: "miek.nl.", Rrtype: TypeDNSKEY, Class: ClassINET, Ttl: 3600} - key.PublicKey = "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFqNDzr//kZ" - - out.Answer[0] = key - msg, err := out.Pack() - if err != nil { - t.Error("failed to pack msg with DNSKEY") - } - in := new(Msg) - if in.Unpack(msg) != nil { - t.Error("failed to unpack msg with DNSKEY") - } - - sig := new(RRSIG) - sig = &RRSIG{TypeCovered: TypeDNSKEY, Algorithm: RSASHA1, Labels: 2, - OrigTtl: 3600, Expiration: 4000, Inception: 4000, KeyTag: 34641, SignerName: "miek.nl.", - Signature: "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFqNDzr//kZ"} - sig.Hdr = RR_Header{Name: "miek.nl.", Rrtype: TypeRRSIG, Class: ClassINET, Ttl: 3600} - - out.Answer[0] = sig - msg, err = out.Pack() - if err != nil { - t.Error("failed to pack msg with RRSIG") - } - - if in.Unpack(msg) != nil { - t.Error("failed to unpack msg with RRSIG") - } -} - -func TestPackUnpack2(t *testing.T) { - m := new(Msg) - m.Extra = make([]RR, 1) - m.Answer = make([]RR, 1) - dom := "miek.nl." - rr := new(A) - rr.Hdr = RR_Header{Name: dom, Rrtype: TypeA, Class: ClassINET, Ttl: 0} - rr.A = net.IPv4(127, 0, 0, 1) - - x := new(TXT) - x.Hdr = RR_Header{Name: dom, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0} - x.Txt = []string{"heelalaollo"} - - m.Extra[0] = x - m.Answer[0] = rr - _, err := m.Pack() - if err != nil { - t.Error("Packing failed: ", err) - return - } -} - -func TestPackUnpack3(t *testing.T) { - m := new(Msg) - m.Extra = make([]RR, 2) - m.Answer = make([]RR, 1) - dom := "miek.nl." - rr := new(A) - rr.Hdr = RR_Header{Name: dom, Rrtype: TypeA, Class: ClassINET, Ttl: 0} - rr.A = net.IPv4(127, 0, 0, 1) - - x1 := new(TXT) - x1.Hdr = RR_Header{Name: dom, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0} - x1.Txt = []string{} - - x2 := new(TXT) - x2.Hdr = RR_Header{Name: dom, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0} - x2.Txt = []string{"heelalaollo"} - - m.Extra[0] = x1 - m.Extra[1] = x2 - m.Answer[0] = rr - b, err := m.Pack() - if err != nil { - t.Error("packing failed: ", err) - return - } - - var unpackMsg Msg - err = unpackMsg.Unpack(b) - if err != nil { - t.Error("unpacking failed") - return - } -} - -func TestBailiwick(t *testing.T) { - yes := map[string]string{ - "miek1.nl": "miek1.nl", - "miek.nl": "ns.miek.nl", - ".": "miek.nl", - } - for parent, child := range yes { - if !IsSubDomain(parent, child) { - t.Errorf("%s should be child of %s", child, parent) - t.Errorf("comparelabels %d", CompareDomainName(parent, child)) - t.Errorf("lenlabels %d %d", CountLabel(parent), CountLabel(child)) - } - } - no := map[string]string{ - "www.miek.nl": "ns.miek.nl", - "m\\.iek.nl": "ns.miek.nl", - "w\\.iek.nl": "w.iek.nl", - "p\\\\.iek.nl": "ns.p.iek.nl", // p\\.iek.nl , literal \ in domain name - "miek.nl": ".", - } - for parent, child := range no { - if IsSubDomain(parent, child) { - t.Errorf("%s should not be child of %s", child, parent) - t.Errorf("comparelabels %d", CompareDomainName(parent, child)) - t.Errorf("lenlabels %d %d", CountLabel(parent), CountLabel(child)) - } - } -} - -func TestPack(t *testing.T) { - rr := []string{"US. 86400 IN NSEC 0-.us. NS SOA RRSIG NSEC DNSKEY TYPE65534"} - m := new(Msg) - var err error - m.Answer = make([]RR, 1) - for _, r := range rr { - m.Answer[0], err = NewRR(r) - if err != nil { - t.Errorf("failed to create RR: %v", err) - continue - } - if _, err := m.Pack(); err != nil { - t.Errorf("packing failed: %v", err) - } - } - x := new(Msg) - ns, _ := NewRR("pool.ntp.org. 390 IN NS a.ntpns.org") - ns.(*NS).Ns = "a.ntpns.org" - x.Ns = append(m.Ns, ns) - x.Ns = append(m.Ns, ns) - x.Ns = append(m.Ns, ns) - // This crashes due to the fact the a.ntpns.org isn't a FQDN - // How to recover() from a remove panic()? - if _, err := x.Pack(); err == nil { - t.Error("packing should fail") - } - x.Answer = make([]RR, 1) - x.Answer[0], err = NewRR(rr[0]) - if _, err := x.Pack(); err == nil { - t.Error("packing should fail") - } - x.Question = make([]Question, 1) - x.Question[0] = Question{";sd#eddddséâèµââ
â¥âxzztsestxssweewwsssstx@s@Zåµe@cn.pool.ntp.org.", TypeA, ClassINET} - if _, err := x.Pack(); err == nil { - t.Error("packing should fail") - } -} - -func TestPackNAPTR(t *testing.T) { - for _, n := range []string{ - `apple.com. IN NAPTR 100 50 "se" "SIP+D2U" "" _sip._udp.apple.com.`, - `apple.com. IN NAPTR 90 50 "se" "SIP+D2T" "" _sip._tcp.apple.com.`, - `apple.com. IN NAPTR 50 50 "se" "SIPS+D2T" "" _sips._tcp.apple.com.`, - } { - rr, _ := NewRR(n) - msg := make([]byte, rr.len()) - if off, err := PackRR(rr, msg, 0, nil, false); err != nil { - t.Errorf("packing failed: %v", err) - t.Errorf("length %d, need more than %d", rr.len(), off) - } else { - t.Logf("buf size needed: %d", off) - } - } -} - -func TestCompressLength(t *testing.T) { - m := new(Msg) - m.SetQuestion("miek.nl", TypeMX) - ul := m.Len() - m.Compress = true - if ul != m.Len() { - t.Fatalf("should be equal") - } -} - -// Does the predicted length match final packed length? -func TestMsgCompressLength(t *testing.T) { - makeMsg := func(question string, ans, ns, e []RR) *Msg { - msg := new(Msg) - msg.SetQuestion(Fqdn(question), TypeANY) - msg.Answer = append(msg.Answer, ans...) - msg.Ns = append(msg.Ns, ns...) - msg.Extra = append(msg.Extra, e...) - msg.Compress = true - return msg - } - - name1 := "12345678901234567890123456789012345.12345678.123." - rrA, _ := NewRR(name1 + " 3600 IN A 192.0.2.1") - rrMx, _ := NewRR(name1 + " 3600 IN MX 10 " + name1) - tests := []*Msg{ - makeMsg(name1, []RR{rrA}, nil, nil), - makeMsg(name1, []RR{rrMx, rrMx}, nil, nil)} - - for _, msg := range tests { - predicted := msg.Len() - buf, err := msg.Pack() - if err != nil { - t.Error(err) - } - if predicted < len(buf) { - t.Errorf("predicted compressed length is wrong: predicted %s (len=%d) %d, actual %d", - msg.Question[0].Name, len(msg.Answer), predicted, len(buf)) - } - } -} - -func TestMsgLength(t *testing.T) { - makeMsg := func(question string, ans, ns, e []RR) *Msg { - msg := new(Msg) - msg.SetQuestion(Fqdn(question), TypeANY) - msg.Answer = append(msg.Answer, ans...) - msg.Ns = append(msg.Ns, ns...) - msg.Extra = append(msg.Extra, e...) - return msg - } - - name1 := "12345678901234567890123456789012345.12345678.123." - rrA, _ := NewRR(name1 + " 3600 IN A 192.0.2.1") - rrMx, _ := NewRR(name1 + " 3600 IN MX 10 " + name1) - tests := []*Msg{ - makeMsg(name1, []RR{rrA}, nil, nil), - makeMsg(name1, []RR{rrMx, rrMx}, nil, nil)} - - for _, msg := range tests { - predicted := msg.Len() - buf, err := msg.Pack() - if err != nil { - t.Error(err) - } - if predicted < len(buf) { - t.Errorf("predicted length is wrong: predicted %s (len=%d), actual %d", - msg.Question[0].Name, predicted, len(buf)) - } - } -} - -func TestMsgLength2(t *testing.T) { - // Serialized replies - var testMessages = []string{ - // google.com. IN A? - "064e81800001000b0004000506676f6f676c6503636f6d0000010001c00c00010001000000050004adc22986c00c00010001000000050004adc22987c00c00010001000000050004adc22988c00c00010001000000050004adc22989c00c00010001000000050004adc2298ec00c00010001000000050004adc22980c00c00010001000000050004adc22981c00c00010001000000050004adc22982c00c00010001000000050004adc22983c00c00010001000000050004adc22984c00c00010001000000050004adc22985c00c00020001000000050006036e7331c00cc00c00020001000000050006036e7332c00cc00c00020001000000050006036e7333c00cc00c00020001000000050006036e7334c00cc0d800010001000000050004d8ef200ac0ea00010001000000050004d8ef220ac0fc00010001000000050004d8ef240ac10e00010001000000050004d8ef260a0000290500000000050000", - // amazon.com. IN A? (reply has no EDNS0 record) - // TODO(miek): this one is off-by-one, need to find out why - //"6de1818000010004000a000806616d617a6f6e03636f6d0000010001c00c000100010000000500044815c2d4c00c000100010000000500044815d7e8c00c00010001000000050004b02062a6c00c00010001000000050004cdfbf236c00c000200010000000500140570646e733408756c747261646e73036f726700c00c000200010000000500150570646e733508756c747261646e7304696e666f00c00c000200010000000500160570646e733608756c747261646e7302636f02756b00c00c00020001000000050014036e7331037033310664796e656374036e657400c00c00020001000000050006036e7332c0cfc00c00020001000000050006036e7333c0cfc00c00020001000000050006036e7334c0cfc00c000200010000000500110570646e733108756c747261646e73c0dac00c000200010000000500080570646e7332c127c00c000200010000000500080570646e7333c06ec0cb00010001000000050004d04e461fc0eb00010001000000050004cc0dfa1fc0fd00010001000000050004d04e471fc10f00010001000000050004cc0dfb1fc12100010001000000050004cc4a6c01c121001c000100000005001020010502f3ff00000000000000000001c13e00010001000000050004cc4a6d01c13e001c0001000000050010261000a1101400000000000000000001", - // yahoo.com. IN A? - "fc2d81800001000300070008057961686f6f03636f6d0000010001c00c00010001000000050004628afd6dc00c00010001000000050004628bb718c00c00010001000000050004cebe242dc00c00020001000000050006036e7336c00cc00c00020001000000050006036e7338c00cc00c00020001000000050006036e7331c00cc00c00020001000000050006036e7332c00cc00c00020001000000050006036e7333c00cc00c00020001000000050006036e7334c00cc00c00020001000000050006036e7335c00cc07b0001000100000005000444b48310c08d00010001000000050004448eff10c09f00010001000000050004cb54dd35c0b100010001000000050004628a0b9dc0c30001000100000005000477a0f77cc05700010001000000050004ca2bdfaac06900010001000000050004caa568160000290500000000050000", - // microsoft.com. IN A? - "f4368180000100020005000b096d6963726f736f667403636f6d0000010001c00c0001000100000005000440040b25c00c0001000100000005000441373ac9c00c0002000100000005000e036e7331046d736674036e657400c00c00020001000000050006036e7332c04fc00c00020001000000050006036e7333c04fc00c00020001000000050006036e7334c04fc00c00020001000000050006036e7335c04fc04b000100010000000500044137253ec04b001c00010000000500102a010111200500000000000000010001c0650001000100000005000440043badc065001c00010000000500102a010111200600060000000000010001c07700010001000000050004d5c7b435c077001c00010000000500102a010111202000000000000000010001c08900010001000000050004cf2e4bfec089001c00010000000500102404f800200300000000000000010001c09b000100010000000500044137e28cc09b001c00010000000500102a010111200f000100000000000100010000290500000000050000", - // google.com. IN MX? - "724b8180000100050004000b06676f6f676c6503636f6d00000f0001c00c000f000100000005000c000a056173706d78016cc00cc00c000f0001000000050009001404616c7431c02ac00c000f0001000000050009001e04616c7432c02ac00c000f0001000000050009002804616c7433c02ac00c000f0001000000050009003204616c7434c02ac00c00020001000000050006036e7332c00cc00c00020001000000050006036e7333c00cc00c00020001000000050006036e7334c00cc00c00020001000000050006036e7331c00cc02a00010001000000050004adc2421bc02a001c00010000000500102a00145040080c01000000000000001bc04200010001000000050004adc2461bc05700010001000000050004adc2451bc06c000100010000000500044a7d8f1bc081000100010000000500044a7d191bc0ca00010001000000050004d8ef200ac09400010001000000050004d8ef220ac0a600010001000000050004d8ef240ac0b800010001000000050004d8ef260a0000290500000000050000", - // reddit.com. IN A? - "12b98180000100080000000c0672656464697403636f6d0000020001c00c0002000100000005000f046175733204616b616d036e657400c00c000200010000000500070475736534c02dc00c000200010000000500070475737733c02dc00c000200010000000500070475737735c02dc00c00020001000000050008056173696131c02dc00c00020001000000050008056173696139c02dc00c00020001000000050008056e73312d31c02dc00c0002000100000005000a076e73312d313935c02dc02800010001000000050004c30a242ec04300010001000000050004451f1d39c05600010001000000050004451f3bc7c0690001000100000005000460073240c07c000100010000000500046007fb81c090000100010000000500047c283484c090001c00010000000500102a0226f0006700000000000000000064c0a400010001000000050004c16c5b01c0a4001c000100000005001026001401000200000000000000000001c0b800010001000000050004c16c5bc3c0b8001c0001000000050010260014010002000000000000000000c30000290500000000050000", - } - - for i, hexData := range testMessages { - // we won't fail the decoding of the hex - input, _ := hex.DecodeString(hexData) - - m := new(Msg) - m.Unpack(input) - m.Compress = true - lenComp := m.Len() - b, _ := m.Pack() - pacComp := len(b) - m.Compress = false - lenUnComp := m.Len() - b, _ = m.Pack() - pacUnComp := len(b) - if pacComp+1 != lenComp { - t.Errorf("msg.Len(compressed)=%d actual=%d for test %d", lenComp, pacComp, i) - } - if pacUnComp+1 != lenUnComp { - t.Errorf("msg.Len(uncompressed)=%d actual=%d for test %d", lenUnComp, pacUnComp, i) - } - } -} - -func TestMsgLengthCompressionMalformed(t *testing.T) { - // SOA with empty hostmaster, which is illegal - soa := &SOA{Hdr: RR_Header{Name: ".", Rrtype: TypeSOA, Class: ClassINET, Ttl: 12345}, - Ns: ".", - Mbox: "", - Serial: 0, - Refresh: 28800, - Retry: 7200, - Expire: 604800, - Minttl: 60} - m := new(Msg) - m.Compress = true - m.Ns = []RR{soa} - m.Len() // Should not crash. -} - -func TestMsgCompressLength2(t *testing.T) { - msg := new(Msg) - msg.Compress = true - msg.SetQuestion(Fqdn("bliep."), TypeANY) - msg.Answer = append(msg.Answer, &SRV{Hdr: RR_Header{Name: "blaat.", Rrtype: 0x21, Class: 0x1, Ttl: 0x3c}, Port: 0x4c57, Target: "foo.bar."}) - msg.Extra = append(msg.Extra, &A{Hdr: RR_Header{Name: "foo.bar.", Rrtype: 0x1, Class: 0x1, Ttl: 0x3c}, A: net.IP{0xac, 0x11, 0x0, 0x3}}) - predicted := msg.Len() - buf, err := msg.Pack() - if err != nil { - t.Error(err) - } - if predicted != len(buf) { - t.Errorf("predicted compressed length is wrong: predicted %s (len=%d) %d, actual %d", - msg.Question[0].Name, len(msg.Answer), predicted, len(buf)) - } -} - -func TestToRFC3597(t *testing.T) { - a, _ := NewRR("miek.nl. IN A 10.0.1.1") - x := new(RFC3597) - x.ToRFC3597(a) - if x.String() != `miek.nl. 3600 CLASS1 TYPE1 \# 4 0a000101` { - t.Errorf("string mismatch, got: %s", x) - } - - b, _ := NewRR("miek.nl. IN MX 10 mx.miek.nl.") - x.ToRFC3597(b) - if x.String() != `miek.nl. 3600 CLASS1 TYPE15 \# 14 000a026d78046d69656b026e6c00` { - t.Errorf("string mismatch, got: %s", x) - } -} - -func TestNoRdataPack(t *testing.T) { - data := make([]byte, 1024) - for typ, fn := range TypeToRR { - r := fn() - *r.Header() = RR_Header{Name: "miek.nl.", Rrtype: typ, Class: ClassINET, Ttl: 16} - _, err := PackRR(r, data, 0, nil, false) - if err != nil { - t.Errorf("failed to pack RR with zero rdata: %s: %v", TypeToString[typ], err) - } - } -} - -func TestNoRdataUnpack(t *testing.T) { - data := make([]byte, 1024) - for typ, fn := range TypeToRR { - if typ == TypeSOA || typ == TypeTSIG { - // SOA, TSIG will not be seen (like this) in dyn. updates? - continue - } - r := fn() - *r.Header() = RR_Header{Name: "miek.nl.", Rrtype: typ, Class: ClassINET, Ttl: 16} - off, err := PackRR(r, data, 0, nil, false) - if err != nil { - // Should always works, TestNoDataPack should have caught this - t.Errorf("failed to pack RR: %v", err) - continue - } - rr, _, err := UnpackRR(data[:off], 0) - if err != nil { - t.Errorf("failed to unpack RR with zero rdata: %s: %v", TypeToString[typ], err) - } - t.Log(rr) - } -} - -func TestRdataOverflow(t *testing.T) { - rr := new(RFC3597) - rr.Hdr.Name = "." - rr.Hdr.Class = ClassINET - rr.Hdr.Rrtype = 65280 - rr.Rdata = hex.EncodeToString(make([]byte, 0xFFFF)) - buf := make([]byte, 0xFFFF*2) - if _, err := PackRR(rr, buf, 0, nil, false); err != nil { - t.Fatalf("maximum size rrdata pack failed: %v", err) - } - rr.Rdata += "00" - if _, err := PackRR(rr, buf, 0, nil, false); err != ErrRdata { - t.Fatalf("oversize rrdata pack didn't return ErrRdata - instead: %v", err) - } -} - -func TestCopy(t *testing.T) { - rr, _ := NewRR("miek.nl. 2311 IN A 127.0.0.1") // Weird TTL to avoid catching TTL - rr1 := Copy(rr) - if rr.String() != rr1.String() { - t.Fatalf("Copy() failed %s != %s", rr.String(), rr1.String()) - } -} - -func TestMsgCopy(t *testing.T) { - m := new(Msg) - m.SetQuestion("miek.nl.", TypeA) - rr, _ := NewRR("miek.nl. 2311 IN A 127.0.0.1") - m.Answer = []RR{rr} - rr, _ = NewRR("miek.nl. 2311 IN NS 127.0.0.1") - m.Ns = []RR{rr} - - m1 := m.Copy() - if m.String() != m1.String() { - t.Fatalf("Msg.Copy() failed %s != %s", m.String(), m1.String()) - } - - m1.Answer[0], _ = NewRR("somethingelse.nl. 2311 IN A 127.0.0.1") - if m.String() == m1.String() { - t.Fatalf("Msg.Copy() failed; change to copy changed template %s", m.String()) - } - - rr, _ = NewRR("miek.nl. 2311 IN A 127.0.0.2") - m1.Answer = append(m1.Answer, rr) - if m1.Ns[0].String() == m1.Answer[1].String() { - t.Fatalf("Msg.Copy() failed; append changed underlying array %s", m1.Ns[0].String()) - } -} - -func TestMsgPackBuffer(t *testing.T) { - var testMessages = []string{ - // news.ycombinator.com.in.escapemg.com. IN A, response - "586285830001000000010000046e6577730b79636f6d62696e61746f7203636f6d02696e086573636170656d6703636f6d0000010001c0210006000100000e10002c036e7332c02103646e730b67726f6f7665736861726bc02d77ed50e600002a3000000e1000093a8000000e10", - - // news.ycombinator.com.in.escapemg.com. IN A, question - "586201000001000000000000046e6577730b79636f6d62696e61746f7203636f6d02696e086573636170656d6703636f6d0000010001", - - "398781020001000000000000046e6577730b79636f6d62696e61746f7203636f6d0000010001", - } - - for i, hexData := range testMessages { - // we won't fail the decoding of the hex - input, _ := hex.DecodeString(hexData) - m := new(Msg) - if err := m.Unpack(input); err != nil { - t.Errorf("packet %d failed to unpack", i) - continue - } - t.Logf("packet %d %s", i, m.String()) - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dnssec.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dnssec.go deleted file mode 100644 index 3bd55388d..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dnssec.go +++ /dev/null @@ -1,720 +0,0 @@ -package dns - -import ( - "bytes" - "crypto" - "crypto/dsa" - "crypto/ecdsa" - "crypto/elliptic" - _ "crypto/md5" - "crypto/rand" - "crypto/rsa" - _ "crypto/sha1" - _ "crypto/sha256" - _ "crypto/sha512" - "encoding/asn1" - "encoding/binary" - "encoding/hex" - "math/big" - "sort" - "strings" - "time" -) - -// DNSSEC encryption algorithm codes. -const ( - _ uint8 = iota - RSAMD5 - DH - DSA - _ // Skip 4, RFC 6725, section 2.1 - RSASHA1 - DSANSEC3SHA1 - RSASHA1NSEC3SHA1 - RSASHA256 - _ // Skip 9, RFC 6725, section 2.1 - RSASHA512 - _ // Skip 11, RFC 6725, section 2.1 - ECCGOST - ECDSAP256SHA256 - ECDSAP384SHA384 - INDIRECT uint8 = 252 - PRIVATEDNS uint8 = 253 // Private (experimental keys) - PRIVATEOID uint8 = 254 -) - -// AlgorithmToString is a map of algorithm IDs to algorithm names. -var AlgorithmToString = map[uint8]string{ - RSAMD5: "RSAMD5", - DH: "DH", - DSA: "DSA", - RSASHA1: "RSASHA1", - DSANSEC3SHA1: "DSA-NSEC3-SHA1", - RSASHA1NSEC3SHA1: "RSASHA1-NSEC3-SHA1", - RSASHA256: "RSASHA256", - RSASHA512: "RSASHA512", - ECCGOST: "ECC-GOST", - ECDSAP256SHA256: "ECDSAP256SHA256", - ECDSAP384SHA384: "ECDSAP384SHA384", - INDIRECT: "INDIRECT", - PRIVATEDNS: "PRIVATEDNS", - PRIVATEOID: "PRIVATEOID", -} - -// StringToAlgorithm is the reverse of AlgorithmToString. -var StringToAlgorithm = reverseInt8(AlgorithmToString) - -// AlgorithmToHash is a map of algorithm crypto hash IDs to crypto.Hash's. -var AlgorithmToHash = map[uint8]crypto.Hash{ - RSAMD5: crypto.MD5, // Deprecated in RFC 6725 - RSASHA1: crypto.SHA1, - RSASHA1NSEC3SHA1: crypto.SHA1, - RSASHA256: crypto.SHA256, - ECDSAP256SHA256: crypto.SHA256, - ECDSAP384SHA384: crypto.SHA384, - RSASHA512: crypto.SHA512, -} - -// DNSSEC hashing algorithm codes. -const ( - _ uint8 = iota - SHA1 // RFC 4034 - SHA256 // RFC 4509 - GOST94 // RFC 5933 - SHA384 // Experimental - SHA512 // Experimental -) - -// HashToString is a map of hash IDs to names. -var HashToString = map[uint8]string{ - SHA1: "SHA1", - SHA256: "SHA256", - GOST94: "GOST94", - SHA384: "SHA384", - SHA512: "SHA512", -} - -// StringToHash is a map of names to hash IDs. -var StringToHash = reverseInt8(HashToString) - -// DNSKEY flag values. -const ( - SEP = 1 - REVOKE = 1 << 7 - ZONE = 1 << 8 -) - -// The RRSIG needs to be converted to wireformat with some of the rdata (the signature) missing. -type rrsigWireFmt struct { - TypeCovered uint16 - Algorithm uint8 - Labels uint8 - OrigTtl uint32 - Expiration uint32 - Inception uint32 - KeyTag uint16 - SignerName string `dns:"domain-name"` - /* No Signature */ -} - -// Used for converting DNSKEY's rdata to wirefmt. -type dnskeyWireFmt struct { - Flags uint16 - Protocol uint8 - Algorithm uint8 - PublicKey string `dns:"base64"` - /* Nothing is left out */ -} - -func divRoundUp(a, b int) int { - return (a + b - 1) / b -} - -// KeyTag calculates the keytag (or key-id) of the DNSKEY. -func (k *DNSKEY) KeyTag() uint16 { - if k == nil { - return 0 - } - var keytag int - switch k.Algorithm { - case RSAMD5: - // Look at the bottom two bytes of the modules, which the last - // item in the pubkey. We could do this faster by looking directly - // at the base64 values. But I'm lazy. - modulus, _ := fromBase64([]byte(k.PublicKey)) - if len(modulus) > 1 { - x := binary.BigEndian.Uint16(modulus[len(modulus)-2:]) - keytag = int(x) - } - default: - keywire := new(dnskeyWireFmt) - keywire.Flags = k.Flags - keywire.Protocol = k.Protocol - keywire.Algorithm = k.Algorithm - keywire.PublicKey = k.PublicKey - wire := make([]byte, DefaultMsgSize) - n, err := packKeyWire(keywire, wire) - if err != nil { - return 0 - } - wire = wire[:n] - for i, v := range wire { - if i&1 != 0 { - keytag += int(v) // must be larger than uint32 - } else { - keytag += int(v) << 8 - } - } - keytag += (keytag >> 16) & 0xFFFF - keytag &= 0xFFFF - } - return uint16(keytag) -} - -// ToDS converts a DNSKEY record to a DS record. -func (k *DNSKEY) ToDS(h uint8) *DS { - if k == nil { - return nil - } - ds := new(DS) - ds.Hdr.Name = k.Hdr.Name - ds.Hdr.Class = k.Hdr.Class - ds.Hdr.Rrtype = TypeDS - ds.Hdr.Ttl = k.Hdr.Ttl - ds.Algorithm = k.Algorithm - ds.DigestType = h - ds.KeyTag = k.KeyTag() - - keywire := new(dnskeyWireFmt) - keywire.Flags = k.Flags - keywire.Protocol = k.Protocol - keywire.Algorithm = k.Algorithm - keywire.PublicKey = k.PublicKey - wire := make([]byte, DefaultMsgSize) - n, err := packKeyWire(keywire, wire) - if err != nil { - return nil - } - wire = wire[:n] - - owner := make([]byte, 255) - off, err1 := PackDomainName(strings.ToLower(k.Hdr.Name), owner, 0, nil, false) - if err1 != nil { - return nil - } - owner = owner[:off] - // RFC4034: - // digest = digest_algorithm( DNSKEY owner name | DNSKEY RDATA); - // "|" denotes concatenation - // DNSKEY RDATA = Flags | Protocol | Algorithm | Public Key. - - var hash crypto.Hash - switch h { - case SHA1: - hash = crypto.SHA1 - case SHA256: - hash = crypto.SHA256 - case SHA384: - hash = crypto.SHA384 - case SHA512: - hash = crypto.SHA512 - default: - return nil - } - - s := hash.New() - s.Write(owner) - s.Write(wire) - ds.Digest = hex.EncodeToString(s.Sum(nil)) - return ds -} - -// ToCDNSKEY converts a DNSKEY record to a CDNSKEY record. -func (k *DNSKEY) ToCDNSKEY() *CDNSKEY { - c := &CDNSKEY{DNSKEY: *k} - c.Hdr = *k.Hdr.copyHeader() - c.Hdr.Rrtype = TypeCDNSKEY - return c -} - -// ToCDS converts a DS record to a CDS record. -func (d *DS) ToCDS() *CDS { - c := &CDS{DS: *d} - c.Hdr = *d.Hdr.copyHeader() - c.Hdr.Rrtype = TypeCDS - return c -} - -// Sign signs an RRSet. The signature needs to be filled in with the values: -// Inception, Expiration, KeyTag, SignerName and Algorithm. The rest is copied -// from the RRset. Sign returns a non-nill error when the signing went OK. -// There is no check if RRSet is a proper (RFC 2181) RRSet. If OrigTTL is non -// zero, it is used as-is, otherwise the TTL of the RRset is used as the -// OrigTTL. -func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error { - if k == nil { - return ErrPrivKey - } - // s.Inception and s.Expiration may be 0 (rollover etc.), the rest must be set - if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 { - return ErrKey - } - - rr.Hdr.Rrtype = TypeRRSIG - rr.Hdr.Name = rrset[0].Header().Name - rr.Hdr.Class = rrset[0].Header().Class - if rr.OrigTtl == 0 { // If set don't override - rr.OrigTtl = rrset[0].Header().Ttl - } - rr.TypeCovered = rrset[0].Header().Rrtype - rr.Labels = uint8(CountLabel(rrset[0].Header().Name)) - - if strings.HasPrefix(rrset[0].Header().Name, "*") { - rr.Labels-- // wildcard, remove from label count - } - - sigwire := new(rrsigWireFmt) - sigwire.TypeCovered = rr.TypeCovered - sigwire.Algorithm = rr.Algorithm - sigwire.Labels = rr.Labels - sigwire.OrigTtl = rr.OrigTtl - sigwire.Expiration = rr.Expiration - sigwire.Inception = rr.Inception - sigwire.KeyTag = rr.KeyTag - // For signing, lowercase this name - sigwire.SignerName = strings.ToLower(rr.SignerName) - - // Create the desired binary blob - signdata := make([]byte, DefaultMsgSize) - n, err := packSigWire(sigwire, signdata) - if err != nil { - return err - } - signdata = signdata[:n] - wire, err := rawSignatureData(rrset, rr) - if err != nil { - return err - } - - hash, ok := AlgorithmToHash[rr.Algorithm] - if !ok { - return ErrAlg - } - - h := hash.New() - h.Write(signdata) - h.Write(wire) - - signature, err := sign(k, h.Sum(nil), hash, rr.Algorithm) - if err != nil { - return err - } - - rr.Signature = toBase64(signature) - - return nil -} - -func sign(k crypto.Signer, hashed []byte, hash crypto.Hash, alg uint8) ([]byte, error) { - signature, err := k.Sign(rand.Reader, hashed, hash) - if err != nil { - return nil, err - } - - switch alg { - case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512: - return signature, nil - - case ECDSAP256SHA256, ECDSAP384SHA384: - ecdsaSignature := &struct { - R, S *big.Int - }{} - if _, err := asn1.Unmarshal(signature, ecdsaSignature); err != nil { - return nil, err - } - - var intlen int - switch alg { - case ECDSAP256SHA256: - intlen = 32 - case ECDSAP384SHA384: - intlen = 48 - } - - signature := intToBytes(ecdsaSignature.R, intlen) - signature = append(signature, intToBytes(ecdsaSignature.S, intlen)...) - return signature, nil - - // There is no defined interface for what a DSA backed crypto.Signer returns - case DSA, DSANSEC3SHA1: - // t := divRoundUp(divRoundUp(p.PublicKey.Y.BitLen(), 8)-64, 8) - // signature := []byte{byte(t)} - // signature = append(signature, intToBytes(r1, 20)...) - // signature = append(signature, intToBytes(s1, 20)...) - // rr.Signature = signature - } - - return nil, ErrAlg -} - -// Verify validates an RRSet with the signature and key. This is only the -// cryptographic test, the signature validity period must be checked separately. -// This function copies the rdata of some RRs (to lowercase domain names) for the validation to work. -func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error { - // First the easy checks - if !IsRRset(rrset) { - return ErrRRset - } - if rr.KeyTag != k.KeyTag() { - return ErrKey - } - if rr.Hdr.Class != k.Hdr.Class { - return ErrKey - } - if rr.Algorithm != k.Algorithm { - return ErrKey - } - if strings.ToLower(rr.SignerName) != strings.ToLower(k.Hdr.Name) { - return ErrKey - } - if k.Protocol != 3 { - return ErrKey - } - - // IsRRset checked that we have at least one RR and that the RRs in - // the set have consistent type, class, and name. Also check that type and - // class matches the RRSIG record. - if rrset[0].Header().Class != rr.Hdr.Class { - return ErrRRset - } - if rrset[0].Header().Rrtype != rr.TypeCovered { - return ErrRRset - } - - // RFC 4035 5.3.2. Reconstructing the Signed Data - // Copy the sig, except the rrsig data - sigwire := new(rrsigWireFmt) - sigwire.TypeCovered = rr.TypeCovered - sigwire.Algorithm = rr.Algorithm - sigwire.Labels = rr.Labels - sigwire.OrigTtl = rr.OrigTtl - sigwire.Expiration = rr.Expiration - sigwire.Inception = rr.Inception - sigwire.KeyTag = rr.KeyTag - sigwire.SignerName = strings.ToLower(rr.SignerName) - // Create the desired binary blob - signeddata := make([]byte, DefaultMsgSize) - n, err := packSigWire(sigwire, signeddata) - if err != nil { - return err - } - signeddata = signeddata[:n] - wire, err := rawSignatureData(rrset, rr) - if err != nil { - return err - } - - sigbuf := rr.sigBuf() // Get the binary signature data - if rr.Algorithm == PRIVATEDNS { // PRIVATEOID - // TODO(miek) - // remove the domain name and assume its ours? - } - - hash, ok := AlgorithmToHash[rr.Algorithm] - if !ok { - return ErrAlg - } - - switch rr.Algorithm { - case RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512, RSAMD5: - // TODO(mg): this can be done quicker, ie. cache the pubkey data somewhere?? - pubkey := k.publicKeyRSA() // Get the key - if pubkey == nil { - return ErrKey - } - - h := hash.New() - h.Write(signeddata) - h.Write(wire) - return rsa.VerifyPKCS1v15(pubkey, hash, h.Sum(nil), sigbuf) - - case ECDSAP256SHA256, ECDSAP384SHA384: - pubkey := k.publicKeyECDSA() - if pubkey == nil { - return ErrKey - } - - // Split sigbuf into the r and s coordinates - r := new(big.Int).SetBytes(sigbuf[:len(sigbuf)/2]) - s := new(big.Int).SetBytes(sigbuf[len(sigbuf)/2:]) - - h := hash.New() - h.Write(signeddata) - h.Write(wire) - if ecdsa.Verify(pubkey, h.Sum(nil), r, s) { - return nil - } - return ErrSig - - default: - return ErrAlg - } -} - -// ValidityPeriod uses RFC1982 serial arithmetic to calculate -// if a signature period is valid. If t is the zero time, the -// current time is taken other t is. Returns true if the signature -// is valid at the given time, otherwise returns false. -func (rr *RRSIG) ValidityPeriod(t time.Time) bool { - var utc int64 - if t.IsZero() { - utc = time.Now().UTC().Unix() - } else { - utc = t.UTC().Unix() - } - modi := (int64(rr.Inception) - utc) / year68 - mode := (int64(rr.Expiration) - utc) / year68 - ti := int64(rr.Inception) + (modi * year68) - te := int64(rr.Expiration) + (mode * year68) - return ti <= utc && utc <= te -} - -// Return the signatures base64 encodedig sigdata as a byte slice. -func (rr *RRSIG) sigBuf() []byte { - sigbuf, err := fromBase64([]byte(rr.Signature)) - if err != nil { - return nil - } - return sigbuf -} - -// publicKeyRSA returns the RSA public key from a DNSKEY record. -func (k *DNSKEY) publicKeyRSA() *rsa.PublicKey { - keybuf, err := fromBase64([]byte(k.PublicKey)) - if err != nil { - return nil - } - - // RFC 2537/3110, section 2. RSA Public KEY Resource Records - // Length is in the 0th byte, unless its zero, then it - // it in bytes 1 and 2 and its a 16 bit number - explen := uint16(keybuf[0]) - keyoff := 1 - if explen == 0 { - explen = uint16(keybuf[1])<<8 | uint16(keybuf[2]) - keyoff = 3 - } - pubkey := new(rsa.PublicKey) - - pubkey.N = big.NewInt(0) - shift := uint64((explen - 1) * 8) - expo := uint64(0) - for i := int(explen - 1); i > 0; i-- { - expo += uint64(keybuf[keyoff+i]) << shift - shift -= 8 - } - // Remainder - expo += uint64(keybuf[keyoff]) - if expo > (2<<31)+1 { - // Larger expo than supported. - // println("dns: F5 primes (or larger) are not supported") - return nil - } - pubkey.E = int(expo) - - pubkey.N.SetBytes(keybuf[keyoff+int(explen):]) - return pubkey -} - -// publicKeyECDSA returns the Curve public key from the DNSKEY record. -func (k *DNSKEY) publicKeyECDSA() *ecdsa.PublicKey { - keybuf, err := fromBase64([]byte(k.PublicKey)) - if err != nil { - return nil - } - pubkey := new(ecdsa.PublicKey) - switch k.Algorithm { - case ECDSAP256SHA256: - pubkey.Curve = elliptic.P256() - if len(keybuf) != 64 { - // wrongly encoded key - return nil - } - case ECDSAP384SHA384: - pubkey.Curve = elliptic.P384() - if len(keybuf) != 96 { - // Wrongly encoded key - return nil - } - } - pubkey.X = big.NewInt(0) - pubkey.X.SetBytes(keybuf[:len(keybuf)/2]) - pubkey.Y = big.NewInt(0) - pubkey.Y.SetBytes(keybuf[len(keybuf)/2:]) - return pubkey -} - -func (k *DNSKEY) publicKeyDSA() *dsa.PublicKey { - keybuf, err := fromBase64([]byte(k.PublicKey)) - if err != nil { - return nil - } - if len(keybuf) < 22 { - return nil - } - t, keybuf := int(keybuf[0]), keybuf[1:] - size := 64 + t*8 - q, keybuf := keybuf[:20], keybuf[20:] - if len(keybuf) != 3*size { - return nil - } - p, keybuf := keybuf[:size], keybuf[size:] - g, y := keybuf[:size], keybuf[size:] - pubkey := new(dsa.PublicKey) - pubkey.Parameters.Q = big.NewInt(0).SetBytes(q) - pubkey.Parameters.P = big.NewInt(0).SetBytes(p) - pubkey.Parameters.G = big.NewInt(0).SetBytes(g) - pubkey.Y = big.NewInt(0).SetBytes(y) - return pubkey -} - -type wireSlice [][]byte - -func (p wireSlice) Len() int { return len(p) } -func (p wireSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } -func (p wireSlice) Less(i, j int) bool { - _, ioff, _ := UnpackDomainName(p[i], 0) - _, joff, _ := UnpackDomainName(p[j], 0) - return bytes.Compare(p[i][ioff+10:], p[j][joff+10:]) < 0 -} - -// Return the raw signature data. -func rawSignatureData(rrset []RR, s *RRSIG) (buf []byte, err error) { - wires := make(wireSlice, len(rrset)) - for i, r := range rrset { - r1 := r.copy() - r1.Header().Ttl = s.OrigTtl - labels := SplitDomainName(r1.Header().Name) - // 6.2. Canonical RR Form. (4) - wildcards - if len(labels) > int(s.Labels) { - // Wildcard - r1.Header().Name = "*." + strings.Join(labels[len(labels)-int(s.Labels):], ".") + "." - } - // RFC 4034: 6.2. Canonical RR Form. (2) - domain name to lowercase - r1.Header().Name = strings.ToLower(r1.Header().Name) - // 6.2. Canonical RR Form. (3) - domain rdata to lowercase. - // NS, MD, MF, CNAME, SOA, MB, MG, MR, PTR, - // HINFO, MINFO, MX, RP, AFSDB, RT, SIG, PX, NXT, NAPTR, KX, - // SRV, DNAME, A6 - // - // RFC 6840 - Clarifications and Implementation Notes for DNS Security (DNSSEC): - // Section 6.2 of [RFC4034] also erroneously lists HINFO as a record - // that needs conversion to lowercase, and twice at that. Since HINFO - // records contain no domain names, they are not subject to case - // conversion. - switch x := r1.(type) { - case *NS: - x.Ns = strings.ToLower(x.Ns) - case *CNAME: - x.Target = strings.ToLower(x.Target) - case *SOA: - x.Ns = strings.ToLower(x.Ns) - x.Mbox = strings.ToLower(x.Mbox) - case *MB: - x.Mb = strings.ToLower(x.Mb) - case *MG: - x.Mg = strings.ToLower(x.Mg) - case *MR: - x.Mr = strings.ToLower(x.Mr) - case *PTR: - x.Ptr = strings.ToLower(x.Ptr) - case *MINFO: - x.Rmail = strings.ToLower(x.Rmail) - x.Email = strings.ToLower(x.Email) - case *MX: - x.Mx = strings.ToLower(x.Mx) - case *NAPTR: - x.Replacement = strings.ToLower(x.Replacement) - case *KX: - x.Exchanger = strings.ToLower(x.Exchanger) - case *SRV: - x.Target = strings.ToLower(x.Target) - case *DNAME: - x.Target = strings.ToLower(x.Target) - } - // 6.2. Canonical RR Form. (5) - origTTL - wire := make([]byte, r1.len()+1) // +1 to be safe(r) - off, err1 := PackRR(r1, wire, 0, nil, false) - if err1 != nil { - return nil, err1 - } - wire = wire[:off] - wires[i] = wire - } - sort.Sort(wires) - for i, wire := range wires { - if i > 0 && bytes.Equal(wire, wires[i-1]) { - continue - } - buf = append(buf, wire...) - } - return buf, nil -} - -func packSigWire(sw *rrsigWireFmt, msg []byte) (int, error) { - // copied from zmsg.go RRSIG packing - off, err := packUint16(sw.TypeCovered, msg, 0) - if err != nil { - return off, err - } - off, err = packUint8(sw.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(sw.Labels, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(sw.OrigTtl, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(sw.Expiration, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(sw.Inception, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(sw.KeyTag, msg, off) - if err != nil { - return off, err - } - off, err = PackDomainName(sw.SignerName, msg, off, nil, false) - if err != nil { - return off, err - } - return off, nil -} - -func packKeyWire(dw *dnskeyWireFmt, msg []byte) (int, error) { - // copied from zmsg.go DNSKEY packing - off, err := packUint16(dw.Flags, msg, 0) - if err != nil { - return off, err - } - off, err = packUint8(dw.Protocol, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(dw.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packStringBase64(dw.PublicKey, msg, off) - if err != nil { - return off, err - } - return off, nil -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dnssec_keygen.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dnssec_keygen.go deleted file mode 100644 index 5e4b7741a..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dnssec_keygen.go +++ /dev/null @@ -1,156 +0,0 @@ -package dns - -import ( - "crypto" - "crypto/dsa" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "crypto/rsa" - "math/big" -) - -// Generate generates a DNSKEY of the given bit size. -// The public part is put inside the DNSKEY record. -// The Algorithm in the key must be set as this will define -// what kind of DNSKEY will be generated. -// The ECDSA algorithms imply a fixed keysize, in that case -// bits should be set to the size of the algorithm. -func (k *DNSKEY) Generate(bits int) (crypto.PrivateKey, error) { - switch k.Algorithm { - case DSA, DSANSEC3SHA1: - if bits != 1024 { - return nil, ErrKeySize - } - case RSAMD5, RSASHA1, RSASHA256, RSASHA1NSEC3SHA1: - if bits < 512 || bits > 4096 { - return nil, ErrKeySize - } - case RSASHA512: - if bits < 1024 || bits > 4096 { - return nil, ErrKeySize - } - case ECDSAP256SHA256: - if bits != 256 { - return nil, ErrKeySize - } - case ECDSAP384SHA384: - if bits != 384 { - return nil, ErrKeySize - } - } - - switch k.Algorithm { - case DSA, DSANSEC3SHA1: - params := new(dsa.Parameters) - if err := dsa.GenerateParameters(params, rand.Reader, dsa.L1024N160); err != nil { - return nil, err - } - priv := new(dsa.PrivateKey) - priv.PublicKey.Parameters = *params - err := dsa.GenerateKey(priv, rand.Reader) - if err != nil { - return nil, err - } - k.setPublicKeyDSA(params.Q, params.P, params.G, priv.PublicKey.Y) - return priv, nil - case RSAMD5, RSASHA1, RSASHA256, RSASHA512, RSASHA1NSEC3SHA1: - priv, err := rsa.GenerateKey(rand.Reader, bits) - if err != nil { - return nil, err - } - k.setPublicKeyRSA(priv.PublicKey.E, priv.PublicKey.N) - return priv, nil - case ECDSAP256SHA256, ECDSAP384SHA384: - var c elliptic.Curve - switch k.Algorithm { - case ECDSAP256SHA256: - c = elliptic.P256() - case ECDSAP384SHA384: - c = elliptic.P384() - } - priv, err := ecdsa.GenerateKey(c, rand.Reader) - if err != nil { - return nil, err - } - k.setPublicKeyECDSA(priv.PublicKey.X, priv.PublicKey.Y) - return priv, nil - default: - return nil, ErrAlg - } -} - -// Set the public key (the value E and N) -func (k *DNSKEY) setPublicKeyRSA(_E int, _N *big.Int) bool { - if _E == 0 || _N == nil { - return false - } - buf := exponentToBuf(_E) - buf = append(buf, _N.Bytes()...) - k.PublicKey = toBase64(buf) - return true -} - -// Set the public key for Elliptic Curves -func (k *DNSKEY) setPublicKeyECDSA(_X, _Y *big.Int) bool { - if _X == nil || _Y == nil { - return false - } - var intlen int - switch k.Algorithm { - case ECDSAP256SHA256: - intlen = 32 - case ECDSAP384SHA384: - intlen = 48 - } - k.PublicKey = toBase64(curveToBuf(_X, _Y, intlen)) - return true -} - -// Set the public key for DSA -func (k *DNSKEY) setPublicKeyDSA(_Q, _P, _G, _Y *big.Int) bool { - if _Q == nil || _P == nil || _G == nil || _Y == nil { - return false - } - buf := dsaToBuf(_Q, _P, _G, _Y) - k.PublicKey = toBase64(buf) - return true -} - -// Set the public key (the values E and N) for RSA -// RFC 3110: Section 2. RSA Public KEY Resource Records -func exponentToBuf(_E int) []byte { - var buf []byte - i := big.NewInt(int64(_E)).Bytes() - if len(i) < 256 { - buf = make([]byte, 1, 1+len(i)) - buf[0] = uint8(len(i)) - } else { - buf = make([]byte, 3, 3+len(i)) - buf[0] = 0 - buf[1] = uint8(len(i) >> 8) - buf[2] = uint8(len(i)) - } - buf = append(buf, i...) - return buf -} - -// Set the public key for X and Y for Curve. The two -// values are just concatenated. -func curveToBuf(_X, _Y *big.Int, intlen int) []byte { - buf := intToBytes(_X, intlen) - buf = append(buf, intToBytes(_Y, intlen)...) - return buf -} - -// Set the public key for X and Y for Curve. The two -// values are just concatenated. -func dsaToBuf(_Q, _P, _G, _Y *big.Int) []byte { - t := divRoundUp(divRoundUp(_G.BitLen(), 8)-64, 8) - buf := []byte{byte(t)} - buf = append(buf, intToBytes(_Q, 20)...) - buf = append(buf, intToBytes(_P, 64+t*8)...) - buf = append(buf, intToBytes(_G, 64+t*8)...) - buf = append(buf, intToBytes(_Y, 64+t*8)...) - return buf -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dnssec_keyscan.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dnssec_keyscan.go deleted file mode 100644 index 4f8d830b8..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dnssec_keyscan.go +++ /dev/null @@ -1,249 +0,0 @@ -package dns - -import ( - "crypto" - "crypto/dsa" - "crypto/ecdsa" - "crypto/rsa" - "io" - "math/big" - "strconv" - "strings" -) - -// NewPrivateKey returns a PrivateKey by parsing the string s. -// s should be in the same form of the BIND private key files. -func (k *DNSKEY) NewPrivateKey(s string) (crypto.PrivateKey, error) { - if s == "" || s[len(s)-1] != '\n' { // We need a closing newline - return k.ReadPrivateKey(strings.NewReader(s+"\n"), "") - } - return k.ReadPrivateKey(strings.NewReader(s), "") -} - -// ReadPrivateKey reads a private key from the io.Reader q. The string file is -// only used in error reporting. -// The public key must be known, because some cryptographic algorithms embed -// the public inside the privatekey. -func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.PrivateKey, error) { - m, err := parseKey(q, file) - if m == nil { - return nil, err - } - if _, ok := m["private-key-format"]; !ok { - return nil, ErrPrivKey - } - if m["private-key-format"] != "v1.2" && m["private-key-format"] != "v1.3" { - return nil, ErrPrivKey - } - // TODO(mg): check if the pubkey matches the private key - algo, err := strconv.ParseUint(strings.SplitN(m["algorithm"], " ", 2)[0], 10, 8) - if err != nil { - return nil, ErrPrivKey - } - switch uint8(algo) { - case DSA: - priv, err := readPrivateKeyDSA(m) - if err != nil { - return nil, err - } - pub := k.publicKeyDSA() - if pub == nil { - return nil, ErrKey - } - priv.PublicKey = *pub - return priv, nil - case RSAMD5: - fallthrough - case RSASHA1: - fallthrough - case RSASHA1NSEC3SHA1: - fallthrough - case RSASHA256: - fallthrough - case RSASHA512: - priv, err := readPrivateKeyRSA(m) - if err != nil { - return nil, err - } - pub := k.publicKeyRSA() - if pub == nil { - return nil, ErrKey - } - priv.PublicKey = *pub - return priv, nil - case ECCGOST: - return nil, ErrPrivKey - case ECDSAP256SHA256: - fallthrough - case ECDSAP384SHA384: - priv, err := readPrivateKeyECDSA(m) - if err != nil { - return nil, err - } - pub := k.publicKeyECDSA() - if pub == nil { - return nil, ErrKey - } - priv.PublicKey = *pub - return priv, nil - default: - return nil, ErrPrivKey - } -} - -// Read a private key (file) string and create a public key. Return the private key. -func readPrivateKeyRSA(m map[string]string) (*rsa.PrivateKey, error) { - p := new(rsa.PrivateKey) - p.Primes = []*big.Int{nil, nil} - for k, v := range m { - switch k { - case "modulus", "publicexponent", "privateexponent", "prime1", "prime2": - v1, err := fromBase64([]byte(v)) - if err != nil { - return nil, err - } - switch k { - case "modulus": - p.PublicKey.N = big.NewInt(0) - p.PublicKey.N.SetBytes(v1) - case "publicexponent": - i := big.NewInt(0) - i.SetBytes(v1) - p.PublicKey.E = int(i.Int64()) // int64 should be large enough - case "privateexponent": - p.D = big.NewInt(0) - p.D.SetBytes(v1) - case "prime1": - p.Primes[0] = big.NewInt(0) - p.Primes[0].SetBytes(v1) - case "prime2": - p.Primes[1] = big.NewInt(0) - p.Primes[1].SetBytes(v1) - } - case "exponent1", "exponent2", "coefficient": - // not used in Go (yet) - case "created", "publish", "activate": - // not used in Go (yet) - } - } - return p, nil -} - -func readPrivateKeyDSA(m map[string]string) (*dsa.PrivateKey, error) { - p := new(dsa.PrivateKey) - p.X = big.NewInt(0) - for k, v := range m { - switch k { - case "private_value(x)": - v1, err := fromBase64([]byte(v)) - if err != nil { - return nil, err - } - p.X.SetBytes(v1) - case "created", "publish", "activate": - /* not used in Go (yet) */ - } - } - return p, nil -} - -func readPrivateKeyECDSA(m map[string]string) (*ecdsa.PrivateKey, error) { - p := new(ecdsa.PrivateKey) - p.D = big.NewInt(0) - // TODO: validate that the required flags are present - for k, v := range m { - switch k { - case "privatekey": - v1, err := fromBase64([]byte(v)) - if err != nil { - return nil, err - } - p.D.SetBytes(v1) - case "created", "publish", "activate": - /* not used in Go (yet) */ - } - } - return p, nil -} - -// parseKey reads a private key from r. It returns a map[string]string, -// with the key-value pairs, or an error when the file is not correct. -func parseKey(r io.Reader, file string) (map[string]string, error) { - s := scanInit(r) - m := make(map[string]string) - c := make(chan lex) - k := "" - // Start the lexer - go klexer(s, c) - for l := range c { - // It should alternate - switch l.value { - case zKey: - k = l.token - case zValue: - if k == "" { - return nil, &ParseError{file, "no private key seen", l} - } - //println("Setting", strings.ToLower(k), "to", l.token, "b") - m[strings.ToLower(k)] = l.token - k = "" - } - } - return m, nil -} - -// klexer scans the sourcefile and returns tokens on the channel c. -func klexer(s *scan, c chan lex) { - var l lex - str := "" // Hold the current read text - commt := false - key := true - x, err := s.tokenText() - defer close(c) - for err == nil { - l.column = s.position.Column - l.line = s.position.Line - switch x { - case ':': - if commt { - break - } - l.token = str - if key { - l.value = zKey - c <- l - // Next token is a space, eat it - s.tokenText() - key = false - str = "" - } else { - l.value = zValue - } - case ';': - commt = true - case '\n': - if commt { - // Reset a comment - commt = false - } - l.value = zValue - l.token = str - c <- l - str = "" - commt = false - key = true - default: - if commt { - break - } - str += string(x) - } - x, err = s.tokenText() - } - if len(str) > 0 { - // Send remainder - l.token = str - l.value = zValue - c <- l - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dnssec_privkey.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dnssec_privkey.go deleted file mode 100644 index 56f3ea934..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dnssec_privkey.go +++ /dev/null @@ -1,85 +0,0 @@ -package dns - -import ( - "crypto" - "crypto/dsa" - "crypto/ecdsa" - "crypto/rsa" - "math/big" - "strconv" -) - -const format = "Private-key-format: v1.3\n" - -// PrivateKeyString converts a PrivateKey to a string. This string has the same -// format as the private-key-file of BIND9 (Private-key-format: v1.3). -// It needs some info from the key (the algorithm), so its a method of the DNSKEY -// It supports rsa.PrivateKey, ecdsa.PrivateKey and dsa.PrivateKey -func (r *DNSKEY) PrivateKeyString(p crypto.PrivateKey) string { - algorithm := strconv.Itoa(int(r.Algorithm)) - algorithm += " (" + AlgorithmToString[r.Algorithm] + ")" - - switch p := p.(type) { - case *rsa.PrivateKey: - modulus := toBase64(p.PublicKey.N.Bytes()) - e := big.NewInt(int64(p.PublicKey.E)) - publicExponent := toBase64(e.Bytes()) - privateExponent := toBase64(p.D.Bytes()) - prime1 := toBase64(p.Primes[0].Bytes()) - prime2 := toBase64(p.Primes[1].Bytes()) - // Calculate Exponent1/2 and Coefficient as per: http://en.wikipedia.org/wiki/RSA#Using_the_Chinese_remainder_algorithm - // and from: http://code.google.com/p/go/issues/detail?id=987 - one := big.NewInt(1) - p1 := big.NewInt(0).Sub(p.Primes[0], one) - q1 := big.NewInt(0).Sub(p.Primes[1], one) - exp1 := big.NewInt(0).Mod(p.D, p1) - exp2 := big.NewInt(0).Mod(p.D, q1) - coeff := big.NewInt(0).ModInverse(p.Primes[1], p.Primes[0]) - - exponent1 := toBase64(exp1.Bytes()) - exponent2 := toBase64(exp2.Bytes()) - coefficient := toBase64(coeff.Bytes()) - - return format + - "Algorithm: " + algorithm + "\n" + - "Modulus: " + modulus + "\n" + - "PublicExponent: " + publicExponent + "\n" + - "PrivateExponent: " + privateExponent + "\n" + - "Prime1: " + prime1 + "\n" + - "Prime2: " + prime2 + "\n" + - "Exponent1: " + exponent1 + "\n" + - "Exponent2: " + exponent2 + "\n" + - "Coefficient: " + coefficient + "\n" - - case *ecdsa.PrivateKey: - var intlen int - switch r.Algorithm { - case ECDSAP256SHA256: - intlen = 32 - case ECDSAP384SHA384: - intlen = 48 - } - private := toBase64(intToBytes(p.D, intlen)) - return format + - "Algorithm: " + algorithm + "\n" + - "PrivateKey: " + private + "\n" - - case *dsa.PrivateKey: - T := divRoundUp(divRoundUp(p.PublicKey.Parameters.G.BitLen(), 8)-64, 8) - prime := toBase64(intToBytes(p.PublicKey.Parameters.P, 64+T*8)) - subprime := toBase64(intToBytes(p.PublicKey.Parameters.Q, 20)) - base := toBase64(intToBytes(p.PublicKey.Parameters.G, 64+T*8)) - priv := toBase64(intToBytes(p.X, 20)) - pub := toBase64(intToBytes(p.PublicKey.Y, 64+T*8)) - return format + - "Algorithm: " + algorithm + "\n" + - "Prime(p): " + prime + "\n" + - "Subprime(q): " + subprime + "\n" + - "Base(g): " + base + "\n" + - "Private_value(x): " + priv + "\n" + - "Public_value(y): " + pub + "\n" - - default: - return "" - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dnssec_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dnssec_test.go deleted file mode 100644 index ca085ed3b..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dnssec_test.go +++ /dev/null @@ -1,733 +0,0 @@ -package dns - -import ( - "crypto" - "crypto/ecdsa" - "crypto/rsa" - "reflect" - "strings" - "testing" - "time" -) - -func getKey() *DNSKEY { - key := new(DNSKEY) - key.Hdr.Name = "miek.nl." - key.Hdr.Class = ClassINET - key.Hdr.Ttl = 14400 - key.Flags = 256 - key.Protocol = 3 - key.Algorithm = RSASHA256 - key.PublicKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz" - return key -} - -func getSoa() *SOA { - soa := new(SOA) - soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0} - soa.Ns = "open.nlnetlabs.nl." - soa.Mbox = "miekg.atoom.net." - soa.Serial = 1293945905 - soa.Refresh = 14400 - soa.Retry = 3600 - soa.Expire = 604800 - soa.Minttl = 86400 - return soa -} - -func TestGenerateEC(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - key := new(DNSKEY) - key.Hdr.Rrtype = TypeDNSKEY - key.Hdr.Name = "miek.nl." - key.Hdr.Class = ClassINET - key.Hdr.Ttl = 14400 - key.Flags = 256 - key.Protocol = 3 - key.Algorithm = ECDSAP256SHA256 - privkey, _ := key.Generate(256) - t.Log(key.String()) - t.Log(key.PrivateKeyString(privkey)) -} - -func TestGenerateDSA(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - key := new(DNSKEY) - key.Hdr.Rrtype = TypeDNSKEY - key.Hdr.Name = "miek.nl." - key.Hdr.Class = ClassINET - key.Hdr.Ttl = 14400 - key.Flags = 256 - key.Protocol = 3 - key.Algorithm = DSA - privkey, _ := key.Generate(1024) - t.Log(key.String()) - t.Log(key.PrivateKeyString(privkey)) -} - -func TestGenerateRSA(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - key := new(DNSKEY) - key.Hdr.Rrtype = TypeDNSKEY - key.Hdr.Name = "miek.nl." - key.Hdr.Class = ClassINET - key.Hdr.Ttl = 14400 - key.Flags = 256 - key.Protocol = 3 - key.Algorithm = RSASHA256 - privkey, _ := key.Generate(1024) - t.Log(key.String()) - t.Log(key.PrivateKeyString(privkey)) -} - -func TestSecure(t *testing.T) { - soa := getSoa() - - sig := new(RRSIG) - sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0} - sig.TypeCovered = TypeSOA - sig.Algorithm = RSASHA256 - sig.Labels = 2 - sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05" - sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05" - sig.OrigTtl = 14400 - sig.KeyTag = 12051 - sig.SignerName = "miek.nl." - sig.Signature = "oMCbslaAVIp/8kVtLSms3tDABpcPRUgHLrOR48OOplkYo+8TeEGWwkSwaz/MRo2fB4FxW0qj/hTlIjUGuACSd+b1wKdH5GvzRJc2pFmxtCbm55ygAh4EUL0F6U5cKtGJGSXxxg6UFCQ0doJCmiGFa78LolaUOXImJrk6AFrGa0M=" - - key := new(DNSKEY) - key.Hdr.Name = "miek.nl." - key.Hdr.Class = ClassINET - key.Hdr.Ttl = 14400 - key.Flags = 256 - key.Protocol = 3 - key.Algorithm = RSASHA256 - key.PublicKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz" - - // It should validate. Period is checked separately, so this will keep on working - if sig.Verify(key, []RR{soa}) != nil { - t.Error("failure to validate") - } -} - -func TestSignature(t *testing.T) { - sig := new(RRSIG) - sig.Hdr.Name = "miek.nl." - sig.Hdr.Class = ClassINET - sig.Hdr.Ttl = 3600 - sig.TypeCovered = TypeDNSKEY - sig.Algorithm = RSASHA1 - sig.Labels = 2 - sig.OrigTtl = 4000 - sig.Expiration = 1000 //Thu Jan 1 02:06:40 CET 1970 - sig.Inception = 800 //Thu Jan 1 01:13:20 CET 1970 - sig.KeyTag = 34641 - sig.SignerName = "miek.nl." - sig.Signature = "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFqNDzr//kZ" - - // Should not be valid - if sig.ValidityPeriod(time.Now()) { - t.Error("should not be valid") - } - - sig.Inception = 315565800 //Tue Jan 1 10:10:00 CET 1980 - sig.Expiration = 4102477800 //Fri Jan 1 10:10:00 CET 2100 - if !sig.ValidityPeriod(time.Now()) { - t.Error("should be valid") - } -} - -func TestSignVerify(t *testing.T) { - // The record we want to sign - soa := new(SOA) - soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0} - soa.Ns = "open.nlnetlabs.nl." - soa.Mbox = "miekg.atoom.net." - soa.Serial = 1293945905 - soa.Refresh = 14400 - soa.Retry = 3600 - soa.Expire = 604800 - soa.Minttl = 86400 - - soa1 := new(SOA) - soa1.Hdr = RR_Header{"*.miek.nl.", TypeSOA, ClassINET, 14400, 0} - soa1.Ns = "open.nlnetlabs.nl." - soa1.Mbox = "miekg.atoom.net." - soa1.Serial = 1293945905 - soa1.Refresh = 14400 - soa1.Retry = 3600 - soa1.Expire = 604800 - soa1.Minttl = 86400 - - srv := new(SRV) - srv.Hdr = RR_Header{"srv.miek.nl.", TypeSRV, ClassINET, 14400, 0} - srv.Port = 1000 - srv.Weight = 800 - srv.Target = "web1.miek.nl." - - hinfo := &HINFO{ - Hdr: RR_Header{ - Name: "miek.nl.", - Rrtype: TypeHINFO, - Class: ClassINET, - Ttl: 3789, - }, - Cpu: "X", - Os: "Y", - } - - // With this key - key := new(DNSKEY) - key.Hdr.Rrtype = TypeDNSKEY - key.Hdr.Name = "miek.nl." - key.Hdr.Class = ClassINET - key.Hdr.Ttl = 14400 - key.Flags = 256 - key.Protocol = 3 - key.Algorithm = RSASHA256 - privkey, _ := key.Generate(512) - - // Fill in the values of the Sig, before signing - sig := new(RRSIG) - sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0} - sig.TypeCovered = soa.Hdr.Rrtype - sig.Labels = uint8(CountLabel(soa.Hdr.Name)) // works for all 3 - sig.OrigTtl = soa.Hdr.Ttl - sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05" - sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05" - sig.KeyTag = key.KeyTag() // Get the keyfrom the Key - sig.SignerName = key.Hdr.Name - sig.Algorithm = RSASHA256 - - for _, r := range []RR{soa, soa1, srv, hinfo} { - if err := sig.Sign(privkey.(*rsa.PrivateKey), []RR{r}); err != nil { - t.Error("failure to sign the record:", err) - continue - } - if err := sig.Verify(key, []RR{r}); err != nil { - t.Error("failure to validate") - continue - } - t.Logf("validated: %s", r.Header().Name) - } -} - -func Test65534(t *testing.T) { - t6 := new(RFC3597) - t6.Hdr = RR_Header{"miek.nl.", 65534, ClassINET, 14400, 0} - t6.Rdata = "505D870001" - key := new(DNSKEY) - key.Hdr.Name = "miek.nl." - key.Hdr.Rrtype = TypeDNSKEY - key.Hdr.Class = ClassINET - key.Hdr.Ttl = 14400 - key.Flags = 256 - key.Protocol = 3 - key.Algorithm = RSASHA256 - privkey, _ := key.Generate(1024) - - sig := new(RRSIG) - sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0} - sig.TypeCovered = t6.Hdr.Rrtype - sig.Labels = uint8(CountLabel(t6.Hdr.Name)) - sig.OrigTtl = t6.Hdr.Ttl - sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05" - sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05" - sig.KeyTag = key.KeyTag() - sig.SignerName = key.Hdr.Name - sig.Algorithm = RSASHA256 - if err := sig.Sign(privkey.(*rsa.PrivateKey), []RR{t6}); err != nil { - t.Error(err) - t.Error("failure to sign the TYPE65534 record") - } - if err := sig.Verify(key, []RR{t6}); err != nil { - t.Error(err) - t.Error("failure to validate") - } else { - t.Logf("validated: %s", t6.Header().Name) - } -} - -func TestDnskey(t *testing.T) { - pubkey, err := ReadRR(strings.NewReader(` -miek.nl. IN DNSKEY 256 3 10 AwEAAZuMCu2FdugHkTrXYgl5qixvcDw1aDDlvL46/xJKbHBAHY16fNUb2b65cwko2Js/aJxUYJbZk5dwCDZxYfrfbZVtDPQuc3o8QaChVxC7/JYz2AHc9qHvqQ1j4VrH71RWINlQo6VYjzN/BGpMhOZoZOEwzp1HfsOE3lNYcoWU1smL ;{id = 5240 (zsk), size = 1024b} -`), "Kmiek.nl.+010+05240.key") - if err != nil { - t.Fatal(err) - } - privStr := `Private-key-format: v1.3 -Algorithm: 10 (RSASHA512) -Modulus: m4wK7YV26AeROtdiCXmqLG9wPDVoMOW8vjr/EkpscEAdjXp81RvZvrlzCSjYmz9onFRgltmTl3AINnFh+t9tlW0M9C5zejxBoKFXELv8ljPYAdz2oe+pDWPhWsfvVFYg2VCjpViPM38EakyE5mhk4TDOnUd+w4TeU1hyhZTWyYs= -PublicExponent: AQAB -PrivateExponent: UfCoIQ/Z38l8vB6SSqOI/feGjHEl/fxIPX4euKf0D/32k30fHbSaNFrFOuIFmWMB3LimWVEs6u3dpbB9CQeCVg7hwU5puG7OtuiZJgDAhNeOnxvo5btp4XzPZrJSxR4WNQnwIiYWbl0aFlL1VGgHC/3By89ENZyWaZcMLW4KGWE= -Prime1: yxwC6ogAu8aVcDx2wg1V0b5M5P6jP8qkRFVMxWNTw60Vkn+ECvw6YAZZBHZPaMyRYZLzPgUlyYRd0cjupy4+fQ== -Prime2: xA1bF8M0RTIQ6+A11AoVG6GIR/aPGg5sogRkIZ7ID/sF6g9HMVU/CM2TqVEBJLRPp73cv6ZeC3bcqOCqZhz+pw== -Exponent1: xzkblyZ96bGYxTVZm2/vHMOXswod4KWIyMoOepK6B/ZPcZoIT6omLCgtypWtwHLfqyCz3MK51Nc0G2EGzg8rFQ== -Exponent2: Pu5+mCEb7T5F+kFNZhQadHUklt0JUHbi3hsEvVoHpEGSw3BGDQrtIflDde0/rbWHgDPM4WQY+hscd8UuTXrvLw== -Coefficient: UuRoNqe7YHnKmQzE6iDWKTMIWTuoqqrFAmXPmKQnC+Y+BQzOVEHUo9bXdDnoI9hzXP1gf8zENMYwYLeWpuYlFQ== -` - privkey, err := pubkey.(*DNSKEY).ReadPrivateKey(strings.NewReader(privStr), - "Kmiek.nl.+010+05240.private") - if err != nil { - t.Fatal(err) - } - if pubkey.(*DNSKEY).PublicKey != "AwEAAZuMCu2FdugHkTrXYgl5qixvcDw1aDDlvL46/xJKbHBAHY16fNUb2b65cwko2Js/aJxUYJbZk5dwCDZxYfrfbZVtDPQuc3o8QaChVxC7/JYz2AHc9qHvqQ1j4VrH71RWINlQo6VYjzN/BGpMhOZoZOEwzp1HfsOE3lNYcoWU1smL" { - t.Error("pubkey is not what we've read") - } - if pubkey.(*DNSKEY).PrivateKeyString(privkey) != privStr { - t.Error("privkey is not what we've read") - t.Errorf("%v", pubkey.(*DNSKEY).PrivateKeyString(privkey)) - } -} - -func TestTag(t *testing.T) { - key := new(DNSKEY) - key.Hdr.Name = "miek.nl." - key.Hdr.Rrtype = TypeDNSKEY - key.Hdr.Class = ClassINET - key.Hdr.Ttl = 3600 - key.Flags = 256 - key.Protocol = 3 - key.Algorithm = RSASHA256 - key.PublicKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz" - - tag := key.KeyTag() - if tag != 12051 { - t.Errorf("wrong key tag: %d for key %v", tag, key) - } -} - -func TestKeyRSA(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - key := new(DNSKEY) - key.Hdr.Name = "miek.nl." - key.Hdr.Rrtype = TypeDNSKEY - key.Hdr.Class = ClassINET - key.Hdr.Ttl = 3600 - key.Flags = 256 - key.Protocol = 3 - key.Algorithm = RSASHA256 - priv, _ := key.Generate(2048) - - soa := new(SOA) - soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0} - soa.Ns = "open.nlnetlabs.nl." - soa.Mbox = "miekg.atoom.net." - soa.Serial = 1293945905 - soa.Refresh = 14400 - soa.Retry = 3600 - soa.Expire = 604800 - soa.Minttl = 86400 - - sig := new(RRSIG) - sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0} - sig.TypeCovered = TypeSOA - sig.Algorithm = RSASHA256 - sig.Labels = 2 - sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05" - sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05" - sig.OrigTtl = soa.Hdr.Ttl - sig.KeyTag = key.KeyTag() - sig.SignerName = key.Hdr.Name - - if err := sig.Sign(priv.(*rsa.PrivateKey), []RR{soa}); err != nil { - t.Error("failed to sign") - return - } - if err := sig.Verify(key, []RR{soa}); err != nil { - t.Error("failed to verify") - } -} - -func TestKeyToDS(t *testing.T) { - key := new(DNSKEY) - key.Hdr.Name = "miek.nl." - key.Hdr.Rrtype = TypeDNSKEY - key.Hdr.Class = ClassINET - key.Hdr.Ttl = 3600 - key.Flags = 256 - key.Protocol = 3 - key.Algorithm = RSASHA256 - key.PublicKey = "AwEAAcNEU67LJI5GEgF9QLNqLO1SMq1EdoQ6E9f85ha0k0ewQGCblyW2836GiVsm6k8Kr5ECIoMJ6fZWf3CQSQ9ycWfTyOHfmI3eQ/1Covhb2y4bAmL/07PhrL7ozWBW3wBfM335Ft9xjtXHPy7ztCbV9qZ4TVDTW/Iyg0PiwgoXVesz" - - ds := key.ToDS(SHA1) - if strings.ToUpper(ds.Digest) != "B5121BDB5B8D86D0CC5FFAFBAAABE26C3E20BAC1" { - t.Errorf("wrong DS digest for SHA1\n%v", ds) - } -} - -func TestSignRSA(t *testing.T) { - pub := "miek.nl. IN DNSKEY 256 3 5 AwEAAb+8lGNCxJgLS8rYVer6EnHVuIkQDghdjdtewDzU3G5R7PbMbKVRvH2Ma7pQyYceoaqWZQirSj72euPWfPxQnMy9ucCylA+FuH9cSjIcPf4PqJfdupHk9X6EBYjxrCLY4p1/yBwgyBIRJtZtAqM3ceAH2WovEJD6rTtOuHo5AluJ" - - priv := `Private-key-format: v1.3 -Algorithm: 5 (RSASHA1) -Modulus: v7yUY0LEmAtLythV6voScdW4iRAOCF2N217APNTcblHs9sxspVG8fYxrulDJhx6hqpZlCKtKPvZ649Z8/FCczL25wLKUD4W4f1xKMhw9/g+ol926keT1foQFiPGsItjinX/IHCDIEhEm1m0Cozdx4AfZai8QkPqtO064ejkCW4k= -PublicExponent: AQAB -PrivateExponent: YPwEmwjk5HuiROKU4xzHQ6l1hG8Iiha4cKRG3P5W2b66/EN/GUh07ZSf0UiYB67o257jUDVEgwCuPJz776zfApcCB4oGV+YDyEu7Hp/rL8KcSN0la0k2r9scKwxTp4BTJT23zyBFXsV/1wRDK1A5NxsHPDMYi2SoK63Enm/1ptk= -Prime1: /wjOG+fD0ybNoSRn7nQ79udGeR1b0YhUA5mNjDx/x2fxtIXzygYk0Rhx9QFfDy6LOBvz92gbNQlzCLz3DJt5hw== -Prime2: wHZsJ8OGhkp5p3mrJFZXMDc2mbYusDVTA+t+iRPdS797Tj0pjvU2HN4vTnTj8KBQp6hmnY7dLp9Y1qserySGbw== -Exponent1: N0A7FsSRIg+IAN8YPQqlawoTtG1t1OkJ+nWrurPootScApX6iMvn8fyvw3p2k51rv84efnzpWAYiC8SUaQDNxQ== -Exponent2: SvuYRaGyvo0zemE3oS+WRm2scxR8eiA8WJGeOc+obwOKCcBgeZblXzfdHGcEC1KaOcetOwNW/vwMA46lpLzJNw== -Coefficient: 8+7ZN/JgByqv0NfULiFKTjtyegUcijRuyij7yNxYbCBneDvZGxJwKNi4YYXWx743pcAj4Oi4Oh86gcmxLs+hGw== -Created: 20110302104537 -Publish: 20110302104537 -Activate: 20110302104537` - - xk, _ := NewRR(pub) - k := xk.(*DNSKEY) - p, err := k.NewPrivateKey(priv) - if err != nil { - t.Error(err) - } - switch priv := p.(type) { - case *rsa.PrivateKey: - if 65537 != priv.PublicKey.E { - t.Error("exponenent should be 65537") - } - default: - t.Errorf("we should have read an RSA key: %v", priv) - } - if k.KeyTag() != 37350 { - t.Errorf("keytag should be 37350, got %d %v", k.KeyTag(), k) - } - - soa := new(SOA) - soa.Hdr = RR_Header{"miek.nl.", TypeSOA, ClassINET, 14400, 0} - soa.Ns = "open.nlnetlabs.nl." - soa.Mbox = "miekg.atoom.net." - soa.Serial = 1293945905 - soa.Refresh = 14400 - soa.Retry = 3600 - soa.Expire = 604800 - soa.Minttl = 86400 - - sig := new(RRSIG) - sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0} - sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05" - sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05" - sig.KeyTag = k.KeyTag() - sig.SignerName = k.Hdr.Name - sig.Algorithm = k.Algorithm - - sig.Sign(p.(*rsa.PrivateKey), []RR{soa}) - if sig.Signature != "D5zsobpQcmMmYsUMLxCVEtgAdCvTu8V/IEeP4EyLBjqPJmjt96bwM9kqihsccofA5LIJ7DN91qkCORjWSTwNhzCv7bMyr2o5vBZElrlpnRzlvsFIoAZCD9xg6ZY7ZyzUJmU6IcTwG4v3xEYajcpbJJiyaw/RqR90MuRdKPiBzSo=" { - t.Errorf("signature is not correct: %v", sig) - } -} - -func TestSignVerifyECDSA(t *testing.T) { - pub := `example.net. 3600 IN DNSKEY 257 3 14 ( - xKYaNhWdGOfJ+nPrL8/arkwf2EY3MDJ+SErKivBVSum1 - w/egsXvSADtNJhyem5RCOpgQ6K8X1DRSEkrbYQ+OB+v8 - /uX45NBwY8rp65F6Glur8I/mlVNgF6W/qTI37m40 )` - priv := `Private-key-format: v1.2 -Algorithm: 14 (ECDSAP384SHA384) -PrivateKey: WURgWHCcYIYUPWgeLmiPY2DJJk02vgrmTfitxgqcL4vwW7BOrbawVmVe0d9V94SR` - - eckey, err := NewRR(pub) - if err != nil { - t.Fatal(err) - } - privkey, err := eckey.(*DNSKEY).NewPrivateKey(priv) - if err != nil { - t.Fatal(err) - } - // TODO: Create separate test for this - ds := eckey.(*DNSKEY).ToDS(SHA384) - if ds.KeyTag != 10771 { - t.Fatal("wrong keytag on DS") - } - if ds.Digest != "72d7b62976ce06438e9c0bf319013cf801f09ecc84b8d7e9495f27e305c6a9b0563a9b5f4d288405c3008a946df983d6" { - t.Fatal("wrong DS Digest") - } - a, _ := NewRR("www.example.net. 3600 IN A 192.0.2.1") - sig := new(RRSIG) - sig.Hdr = RR_Header{"example.net.", TypeRRSIG, ClassINET, 14400, 0} - sig.Expiration, _ = StringToTime("20100909102025") - sig.Inception, _ = StringToTime("20100812102025") - sig.KeyTag = eckey.(*DNSKEY).KeyTag() - sig.SignerName = eckey.(*DNSKEY).Hdr.Name - sig.Algorithm = eckey.(*DNSKEY).Algorithm - - if sig.Sign(privkey.(*ecdsa.PrivateKey), []RR{a}) != nil { - t.Fatal("failure to sign the record") - } - - if err := sig.Verify(eckey.(*DNSKEY), []RR{a}); err != nil { - t.Fatalf("failure to validate:\n%s\n%s\n%s\n\n%s\n\n%v", - eckey.(*DNSKEY).String(), - a.String(), - sig.String(), - eckey.(*DNSKEY).PrivateKeyString(privkey), - err, - ) - } -} - -func TestSignVerifyECDSA2(t *testing.T) { - srv1, err := NewRR("srv.miek.nl. IN SRV 1000 800 0 web1.miek.nl.") - if err != nil { - t.Fatal(err) - } - srv := srv1.(*SRV) - - // With this key - key := new(DNSKEY) - key.Hdr.Rrtype = TypeDNSKEY - key.Hdr.Name = "miek.nl." - key.Hdr.Class = ClassINET - key.Hdr.Ttl = 14400 - key.Flags = 256 - key.Protocol = 3 - key.Algorithm = ECDSAP256SHA256 - privkey, err := key.Generate(256) - if err != nil { - t.Fatal("failure to generate key") - } - - // Fill in the values of the Sig, before signing - sig := new(RRSIG) - sig.Hdr = RR_Header{"miek.nl.", TypeRRSIG, ClassINET, 14400, 0} - sig.TypeCovered = srv.Hdr.Rrtype - sig.Labels = uint8(CountLabel(srv.Hdr.Name)) // works for all 3 - sig.OrigTtl = srv.Hdr.Ttl - sig.Expiration = 1296534305 // date -u '+%s' -d"2011-02-01 04:25:05" - sig.Inception = 1293942305 // date -u '+%s' -d"2011-01-02 04:25:05" - sig.KeyTag = key.KeyTag() // Get the keyfrom the Key - sig.SignerName = key.Hdr.Name - sig.Algorithm = ECDSAP256SHA256 - - if sig.Sign(privkey.(*ecdsa.PrivateKey), []RR{srv}) != nil { - t.Fatal("failure to sign the record") - } - - err = sig.Verify(key, []RR{srv}) - if err != nil { - t.Logf("failure to validate:\n%s\n%s\n%s\n\n%s\n\n%v", - key.String(), - srv.String(), - sig.String(), - key.PrivateKeyString(privkey), - err, - ) - } -} - -// Here the test vectors from the relevant RFCs are checked. -// rfc6605 6.1 -func TestRFC6605P256(t *testing.T) { - exDNSKEY := `example.net. 3600 IN DNSKEY 257 3 13 ( - GojIhhXUN/u4v54ZQqGSnyhWJwaubCvTmeexv7bR6edb - krSqQpF64cYbcB7wNcP+e+MAnLr+Wi9xMWyQLc8NAA== )` - exPriv := `Private-key-format: v1.2 -Algorithm: 13 (ECDSAP256SHA256) -PrivateKey: GU6SnQ/Ou+xC5RumuIUIuJZteXT2z0O/ok1s38Et6mQ=` - rrDNSKEY, err := NewRR(exDNSKEY) - if err != nil { - t.Fatal(err) - } - priv, err := rrDNSKEY.(*DNSKEY).NewPrivateKey(exPriv) - if err != nil { - t.Fatal(err) - } - - exDS := `example.net. 3600 IN DS 55648 13 2 ( - b4c8c1fe2e7477127b27115656ad6256f424625bf5c1 - e2770ce6d6e37df61d17 )` - rrDS, err := NewRR(exDS) - if err != nil { - t.Fatal(err) - } - ourDS := rrDNSKEY.(*DNSKEY).ToDS(SHA256) - if !reflect.DeepEqual(ourDS, rrDS.(*DS)) { - t.Errorf("DS record differs:\n%v\n%v", ourDS, rrDS.(*DS)) - } - - exA := `www.example.net. 3600 IN A 192.0.2.1` - exRRSIG := `www.example.net. 3600 IN RRSIG A 13 3 3600 ( - 20100909100439 20100812100439 55648 example.net. - qx6wLYqmh+l9oCKTN6qIc+bw6ya+KJ8oMz0YP107epXA - yGmt+3SNruPFKG7tZoLBLlUzGGus7ZwmwWep666VCw== )` - rrA, err := NewRR(exA) - if err != nil { - t.Fatal(err) - } - rrRRSIG, err := NewRR(exRRSIG) - if err != nil { - t.Fatal(err) - } - if err = rrRRSIG.(*RRSIG).Verify(rrDNSKEY.(*DNSKEY), []RR{rrA}); err != nil { - t.Errorf("failure to validate the spec RRSIG: %v", err) - } - - ourRRSIG := &RRSIG{ - Hdr: RR_Header{ - Ttl: rrA.Header().Ttl, - }, - KeyTag: rrDNSKEY.(*DNSKEY).KeyTag(), - SignerName: rrDNSKEY.(*DNSKEY).Hdr.Name, - Algorithm: rrDNSKEY.(*DNSKEY).Algorithm, - } - ourRRSIG.Expiration, _ = StringToTime("20100909100439") - ourRRSIG.Inception, _ = StringToTime("20100812100439") - err = ourRRSIG.Sign(priv.(*ecdsa.PrivateKey), []RR{rrA}) - if err != nil { - t.Fatal(err) - } - - if err = ourRRSIG.Verify(rrDNSKEY.(*DNSKEY), []RR{rrA}); err != nil { - t.Errorf("failure to validate our RRSIG: %v", err) - } - - // Signatures are randomized - rrRRSIG.(*RRSIG).Signature = "" - ourRRSIG.Signature = "" - if !reflect.DeepEqual(ourRRSIG, rrRRSIG.(*RRSIG)) { - t.Fatalf("RRSIG record differs:\n%v\n%v", ourRRSIG, rrRRSIG.(*RRSIG)) - } -} - -// rfc6605 6.2 -func TestRFC6605P384(t *testing.T) { - exDNSKEY := `example.net. 3600 IN DNSKEY 257 3 14 ( - xKYaNhWdGOfJ+nPrL8/arkwf2EY3MDJ+SErKivBVSum1 - w/egsXvSADtNJhyem5RCOpgQ6K8X1DRSEkrbYQ+OB+v8 - /uX45NBwY8rp65F6Glur8I/mlVNgF6W/qTI37m40 )` - exPriv := `Private-key-format: v1.2 -Algorithm: 14 (ECDSAP384SHA384) -PrivateKey: WURgWHCcYIYUPWgeLmiPY2DJJk02vgrmTfitxgqcL4vwW7BOrbawVmVe0d9V94SR` - rrDNSKEY, err := NewRR(exDNSKEY) - if err != nil { - t.Fatal(err) - } - priv, err := rrDNSKEY.(*DNSKEY).NewPrivateKey(exPriv) - if err != nil { - t.Fatal(err) - } - - exDS := `example.net. 3600 IN DS 10771 14 4 ( - 72d7b62976ce06438e9c0bf319013cf801f09ecc84b8 - d7e9495f27e305c6a9b0563a9b5f4d288405c3008a94 - 6df983d6 )` - rrDS, err := NewRR(exDS) - if err != nil { - t.Fatal(err) - } - ourDS := rrDNSKEY.(*DNSKEY).ToDS(SHA384) - if !reflect.DeepEqual(ourDS, rrDS.(*DS)) { - t.Fatalf("DS record differs:\n%v\n%v", ourDS, rrDS.(*DS)) - } - - exA := `www.example.net. 3600 IN A 192.0.2.1` - exRRSIG := `www.example.net. 3600 IN RRSIG A 14 3 3600 ( - 20100909102025 20100812102025 10771 example.net. - /L5hDKIvGDyI1fcARX3z65qrmPsVz73QD1Mr5CEqOiLP - 95hxQouuroGCeZOvzFaxsT8Glr74hbavRKayJNuydCuz - WTSSPdz7wnqXL5bdcJzusdnI0RSMROxxwGipWcJm )` - rrA, err := NewRR(exA) - if err != nil { - t.Fatal(err) - } - rrRRSIG, err := NewRR(exRRSIG) - if err != nil { - t.Fatal(err) - } - if err = rrRRSIG.(*RRSIG).Verify(rrDNSKEY.(*DNSKEY), []RR{rrA}); err != nil { - t.Errorf("failure to validate the spec RRSIG: %v", err) - } - - ourRRSIG := &RRSIG{ - Hdr: RR_Header{ - Ttl: rrA.Header().Ttl, - }, - KeyTag: rrDNSKEY.(*DNSKEY).KeyTag(), - SignerName: rrDNSKEY.(*DNSKEY).Hdr.Name, - Algorithm: rrDNSKEY.(*DNSKEY).Algorithm, - } - ourRRSIG.Expiration, _ = StringToTime("20100909102025") - ourRRSIG.Inception, _ = StringToTime("20100812102025") - err = ourRRSIG.Sign(priv.(*ecdsa.PrivateKey), []RR{rrA}) - if err != nil { - t.Fatal(err) - } - - if err = ourRRSIG.Verify(rrDNSKEY.(*DNSKEY), []RR{rrA}); err != nil { - t.Errorf("failure to validate our RRSIG: %v", err) - } - - // Signatures are randomized - rrRRSIG.(*RRSIG).Signature = "" - ourRRSIG.Signature = "" - if !reflect.DeepEqual(ourRRSIG, rrRRSIG.(*RRSIG)) { - t.Fatalf("RRSIG record differs:\n%v\n%v", ourRRSIG, rrRRSIG.(*RRSIG)) - } -} - -func TestInvalidRRSet(t *testing.T) { - goodRecords := make([]RR, 2) - goodRecords[0] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}} - goodRecords[1] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"_o/"}} - - // Generate key - keyname := "cloudflare.com." - key := &DNSKEY{ - Hdr: RR_Header{Name: keyname, Rrtype: TypeDNSKEY, Class: ClassINET, Ttl: 0}, - Algorithm: ECDSAP256SHA256, - Flags: ZONE, - Protocol: 3, - } - privatekey, err := key.Generate(256) - if err != nil { - t.Fatal(err.Error()) - } - - // Need to fill in: Inception, Expiration, KeyTag, SignerName and Algorithm - curTime := time.Now() - signature := &RRSIG{ - Inception: uint32(curTime.Unix()), - Expiration: uint32(curTime.Add(time.Hour).Unix()), - KeyTag: key.KeyTag(), - SignerName: keyname, - Algorithm: ECDSAP256SHA256, - } - - // Inconsistent name between records - badRecords := make([]RR, 2) - badRecords[0] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}} - badRecords[1] = &TXT{Hdr: RR_Header{Name: "nama.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"_o/"}} - - if IsRRset(badRecords) { - t.Fatal("Record set with inconsistent names considered valid") - } - - badRecords[0] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}} - badRecords[1] = &A{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeA, Class: ClassINET, Ttl: 0}} - - if IsRRset(badRecords) { - t.Fatal("Record set with inconsistent record types considered valid") - } - - badRecords[0] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}} - badRecords[1] = &TXT{Hdr: RR_Header{Name: "name.cloudflare.com.", Rrtype: TypeTXT, Class: ClassCHAOS, Ttl: 0}, Txt: []string{"_o/"}} - - if IsRRset(badRecords) { - t.Fatal("Record set with inconsistent record class considered valid") - } - - // Sign the good record set and then make sure verification fails on the bad record set - if err := signature.Sign(privatekey.(crypto.Signer), goodRecords); err != nil { - t.Fatal("Signing good records failed") - } - - if err := signature.Verify(key, badRecords); err != ErrRRset { - t.Fatal("Verification did not return ErrRRset with inconsistent records") - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/doc.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/doc.go deleted file mode 100644 index e38753d7d..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/doc.go +++ /dev/null @@ -1,251 +0,0 @@ -/* -Package dns implements a full featured interface to the Domain Name System. -Server- and client-side programming is supported. -The package allows complete control over what is send out to the DNS. The package -API follows the less-is-more principle, by presenting a small, clean interface. - -The package dns supports (asynchronous) querying/replying, incoming/outgoing zone transfers, -TSIG, EDNS0, dynamic updates, notifies and DNSSEC validation/signing. -Note that domain names MUST be fully qualified, before sending them, unqualified -names in a message will result in a packing failure. - -Resource records are native types. They are not stored in wire format. -Basic usage pattern for creating a new resource record: - - r := new(dns.MX) - r.Hdr = dns.RR_Header{Name: "miek.nl.", Rrtype: dns.TypeMX, - Class: dns.ClassINET, Ttl: 3600} - r.Preference = 10 - r.Mx = "mx.miek.nl." - -Or directly from a string: - - mx, err := dns.NewRR("miek.nl. 3600 IN MX 10 mx.miek.nl.") - -Or when the default TTL (3600) and class (IN) suit you: - - mx, err := dns.NewRR("miek.nl. MX 10 mx.miek.nl.") - -Or even: - - mx, err := dns.NewRR("$ORIGIN nl.\nmiek 1H IN MX 10 mx.miek") - -In the DNS messages are exchanged, these messages contain resource -records (sets). Use pattern for creating a message: - - m := new(dns.Msg) - m.SetQuestion("miek.nl.", dns.TypeMX) - -Or when not certain if the domain name is fully qualified: - - m.SetQuestion(dns.Fqdn("miek.nl"), dns.TypeMX) - -The message m is now a message with the question section set to ask -the MX records for the miek.nl. zone. - -The following is slightly more verbose, but more flexible: - - m1 := new(dns.Msg) - m1.Id = dns.Id() - m1.RecursionDesired = true - m1.Question = make([]dns.Question, 1) - m1.Question[0] = dns.Question{"miek.nl.", dns.TypeMX, dns.ClassINET} - -After creating a message it can be send. -Basic use pattern for synchronous querying the DNS at a -server configured on 127.0.0.1 and port 53: - - c := new(dns.Client) - in, rtt, err := c.Exchange(m1, "127.0.0.1:53") - -Suppressing multiple outstanding queries (with the same question, type and -class) is as easy as setting: - - c.SingleInflight = true - -If these "advanced" features are not needed, a simple UDP query can be send, -with: - - in, err := dns.Exchange(m1, "127.0.0.1:53") - -When this functions returns you will get dns message. A dns message consists -out of four sections. -The question section: in.Question, the answer section: in.Answer, -the authority section: in.Ns and the additional section: in.Extra. - -Each of these sections (except the Question section) contain a []RR. Basic -use pattern for accessing the rdata of a TXT RR as the first RR in -the Answer section: - - if t, ok := in.Answer[0].(*dns.TXT); ok { - // do something with t.Txt - } - -Domain Name and TXT Character String Representations - -Both domain names and TXT character strings are converted to presentation -form both when unpacked and when converted to strings. - -For TXT character strings, tabs, carriage returns and line feeds will be -converted to \t, \r and \n respectively. Back slashes and quotations marks -will be escaped. Bytes below 32 and above 127 will be converted to \DDD -form. - -For domain names, in addition to the above rules brackets, periods, -spaces, semicolons and the at symbol are escaped. - -DNSSEC - -DNSSEC (DNS Security Extension) adds a layer of security to the DNS. It -uses public key cryptography to sign resource records. The -public keys are stored in DNSKEY records and the signatures in RRSIG records. - -Requesting DNSSEC information for a zone is done by adding the DO (DNSSEC OK) bit -to a request. - - m := new(dns.Msg) - m.SetEdns0(4096, true) - -Signature generation, signature verification and key generation are all supported. - -DYNAMIC UPDATES - -Dynamic updates reuses the DNS message format, but renames three of -the sections. Question is Zone, Answer is Prerequisite, Authority is -Update, only the Additional is not renamed. See RFC 2136 for the gory details. - -You can set a rather complex set of rules for the existence of absence of -certain resource records or names in a zone to specify if resource records -should be added or removed. The table from RFC 2136 supplemented with the Go -DNS function shows which functions exist to specify the prerequisites. - - 3.2.4 - Table Of Metavalues Used In Prerequisite Section - - CLASS TYPE RDATA Meaning Function - -------------------------------------------------------------- - ANY ANY empty Name is in use dns.NameUsed - ANY rrset empty RRset exists (value indep) dns.RRsetUsed - NONE ANY empty Name is not in use dns.NameNotUsed - NONE rrset empty RRset does not exist dns.RRsetNotUsed - zone rrset rr RRset exists (value dep) dns.Used - -The prerequisite section can also be left empty. -If you have decided on the prerequisites you can tell what RRs should -be added or deleted. The next table shows the options you have and -what functions to call. - - 3.4.2.6 - Table Of Metavalues Used In Update Section - - CLASS TYPE RDATA Meaning Function - --------------------------------------------------------------- - ANY ANY empty Delete all RRsets from name dns.RemoveName - ANY rrset empty Delete an RRset dns.RemoveRRset - NONE rrset rr Delete an RR from RRset dns.Remove - zone rrset rr Add to an RRset dns.Insert - -TRANSACTION SIGNATURE - -An TSIG or transaction signature adds a HMAC TSIG record to each message sent. -The supported algorithms include: HmacMD5, HmacSHA1, HmacSHA256 and HmacSHA512. - -Basic use pattern when querying with a TSIG name "axfr." (note that these key names -must be fully qualified - as they are domain names) and the base64 secret -"so6ZGir4GPAqINNh9U5c3A==": - - c := new(dns.Client) - c.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="} - m := new(dns.Msg) - m.SetQuestion("miek.nl.", dns.TypeMX) - m.SetTsig("axfr.", dns.HmacMD5, 300, time.Now().Unix()) - ... - // When sending the TSIG RR is calculated and filled in before sending - -When requesting an zone transfer (almost all TSIG usage is when requesting zone transfers), with -TSIG, this is the basic use pattern. In this example we request an AXFR for -miek.nl. with TSIG key named "axfr." and secret "so6ZGir4GPAqINNh9U5c3A==" -and using the server 176.58.119.54: - - t := new(dns.Transfer) - m := new(dns.Msg) - t.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="} - m.SetAxfr("miek.nl.") - m.SetTsig("axfr.", dns.HmacMD5, 300, time.Now().Unix()) - c, err := t.In(m, "176.58.119.54:53") - for r := range c { ... } - -You can now read the records from the transfer as they come in. Each envelope is checked with TSIG. -If something is not correct an error is returned. - -Basic use pattern validating and replying to a message that has TSIG set. - - server := &dns.Server{Addr: ":53", Net: "udp"} - server.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="} - go server.ListenAndServe() - dns.HandleFunc(".", handleRequest) - - func handleRequest(w dns.ResponseWriter, r *dns.Msg) { - m := new(dns.Msg) - m.SetReply(r) - if r.IsTsig() != nil { - if w.TsigStatus() == nil { - // *Msg r has an TSIG record and it was validated - m.SetTsig("axfr.", dns.HmacMD5, 300, time.Now().Unix()) - } else { - // *Msg r has an TSIG records and it was not valided - } - } - w.WriteMsg(m) - } - -PRIVATE RRS - -RFC 6895 sets aside a range of type codes for private use. This range -is 65,280 - 65,534 (0xFF00 - 0xFFFE). When experimenting with new Resource Records these -can be used, before requesting an official type code from IANA. - -see http://miek.nl/2014/September/21/idn-and-private-rr-in-go-dns/ for more -information. - -EDNS0 - -EDNS0 is an extension mechanism for the DNS defined in RFC 2671 and updated -by RFC 6891. It defines an new RR type, the OPT RR, which is then completely -abused. -Basic use pattern for creating an (empty) OPT RR: - - o := new(dns.OPT) - o.Hdr.Name = "." // MUST be the root zone, per definition. - o.Hdr.Rrtype = dns.TypeOPT - -The rdata of an OPT RR consists out of a slice of EDNS0 (RFC 6891) -interfaces. Currently only a few have been standardized: EDNS0_NSID -(RFC 5001) and EDNS0_SUBNET (draft-vandergaast-edns-client-subnet-02). Note -that these options may be combined in an OPT RR. -Basic use pattern for a server to check if (and which) options are set: - - // o is a dns.OPT - for _, s := range o.Option { - switch e := s.(type) { - case *dns.EDNS0_NSID: - // do stuff with e.Nsid - case *dns.EDNS0_SUBNET: - // access e.Family, e.Address, etc. - } - } - -SIG(0) - -From RFC 2931: - - SIG(0) provides protection for DNS transactions and requests .... - ... protection for glue records, DNS requests, protection for message headers - on requests and responses, and protection of the overall integrity of a response. - -It works like TSIG, except that SIG(0) uses public key cryptography, instead of the shared -secret approach in TSIG. -Supported algorithms: DSA, ECDSAP256SHA256, ECDSAP384SHA384, RSASHA1, RSASHA256 and -RSASHA512. - -Signing subsequent messages in multi-message sessions is not implemented. -*/ -package dns diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dyn_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dyn_test.go deleted file mode 100644 index 09986a5e4..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/dyn_test.go +++ /dev/null @@ -1,3 +0,0 @@ -package dns - -// Find better solution diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/edns.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/edns.go deleted file mode 100644 index dbff3714c..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/edns.go +++ /dev/null @@ -1,597 +0,0 @@ -package dns - -import ( - "encoding/binary" - "encoding/hex" - "errors" - "fmt" - "net" - "strconv" -) - -// EDNS0 Option codes. -const ( - EDNS0LLQ = 0x1 // long lived queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01 - EDNS0UL = 0x2 // update lease draft: http://files.dns-sd.org/draft-sekar-dns-ul.txt - EDNS0NSID = 0x3 // nsid (RFC5001) - EDNS0DAU = 0x5 // DNSSEC Algorithm Understood - EDNS0DHU = 0x6 // DS Hash Understood - EDNS0N3U = 0x7 // NSEC3 Hash Understood - EDNS0SUBNET = 0x8 // client-subnet (RFC6891) - EDNS0EXPIRE = 0x9 // EDNS0 expire - EDNS0COOKIE = 0xa // EDNS0 Cookie - EDNS0TCPKEEPALIVE = 0xb // EDNS0 tcp keep alive (RFC7828) - EDNS0SUBNETDRAFT = 0x50fa // Don't use! Use EDNS0SUBNET - EDNS0LOCALSTART = 0xFDE9 // Beginning of range reserved for local/experimental use (RFC6891) - EDNS0LOCALEND = 0xFFFE // End of range reserved for local/experimental use (RFC6891) - _DO = 1 << 15 // dnssec ok -) - -// OPT is the EDNS0 RR appended to messages to convey extra (meta) information. -// See RFC 6891. -type OPT struct { - Hdr RR_Header - Option []EDNS0 `dns:"opt"` -} - -func (rr *OPT) String() string { - s := "\n;; OPT PSEUDOSECTION:\n; EDNS: version " + strconv.Itoa(int(rr.Version())) + "; " - if rr.Do() { - s += "flags: do; " - } else { - s += "flags: ; " - } - s += "udp: " + strconv.Itoa(int(rr.UDPSize())) - - for _, o := range rr.Option { - switch o.(type) { - case *EDNS0_NSID: - s += "\n; NSID: " + o.String() - h, e := o.pack() - var r string - if e == nil { - for _, c := range h { - r += "(" + string(c) + ")" - } - s += " " + r - } - case *EDNS0_SUBNET: - s += "\n; SUBNET: " + o.String() - if o.(*EDNS0_SUBNET).DraftOption { - s += " (draft)" - } - case *EDNS0_COOKIE: - s += "\n; COOKIE: " + o.String() - case *EDNS0_UL: - s += "\n; UPDATE LEASE: " + o.String() - case *EDNS0_LLQ: - s += "\n; LONG LIVED QUERIES: " + o.String() - case *EDNS0_DAU: - s += "\n; DNSSEC ALGORITHM UNDERSTOOD: " + o.String() - case *EDNS0_DHU: - s += "\n; DS HASH UNDERSTOOD: " + o.String() - case *EDNS0_N3U: - s += "\n; NSEC3 HASH UNDERSTOOD: " + o.String() - case *EDNS0_LOCAL: - s += "\n; LOCAL OPT: " + o.String() - } - } - return s -} - -func (rr *OPT) len() int { - l := rr.Hdr.len() - for i := 0; i < len(rr.Option); i++ { - l += 4 // Account for 2-byte option code and 2-byte option length. - lo, _ := rr.Option[i].pack() - l += len(lo) - } - return l -} - -// return the old value -> delete SetVersion? - -// Version returns the EDNS version used. Only zero is defined. -func (rr *OPT) Version() uint8 { - return uint8((rr.Hdr.Ttl & 0x00FF0000) >> 16) -} - -// SetVersion sets the version of EDNS. This is usually zero. -func (rr *OPT) SetVersion(v uint8) { - rr.Hdr.Ttl = rr.Hdr.Ttl&0xFF00FFFF | (uint32(v) << 16) -} - -// ExtendedRcode returns the EDNS extended RCODE field (the upper 8 bits of the TTL). -func (rr *OPT) ExtendedRcode() int { - return int((rr.Hdr.Ttl&0xFF000000)>>24) + 15 -} - -// SetExtendedRcode sets the EDNS extended RCODE field. -func (rr *OPT) SetExtendedRcode(v uint8) { - if v < RcodeBadVers { // Smaller than 16.. Use the 4 bits you have! - return - } - rr.Hdr.Ttl = rr.Hdr.Ttl&0x00FFFFFF | (uint32(v-15) << 24) -} - -// UDPSize returns the UDP buffer size. -func (rr *OPT) UDPSize() uint16 { - return rr.Hdr.Class -} - -// SetUDPSize sets the UDP buffer size. -func (rr *OPT) SetUDPSize(size uint16) { - rr.Hdr.Class = size -} - -// Do returns the value of the DO (DNSSEC OK) bit. -func (rr *OPT) Do() bool { - return rr.Hdr.Ttl&_DO == _DO -} - -// SetDo sets the DO (DNSSEC OK) bit. -// If we pass an argument, set the DO bit to that value. -// It is possible to pass 2 or more arguments. Any arguments after the 1st is silently ignored. -func (rr *OPT) SetDo(do ...bool) { - if len(do) == 1 { - if do[0] { - rr.Hdr.Ttl |= _DO - } else { - rr.Hdr.Ttl &^= _DO - } - } else { - rr.Hdr.Ttl |= _DO - } -} - -// EDNS0 defines an EDNS0 Option. An OPT RR can have multiple options appended to it. -type EDNS0 interface { - // Option returns the option code for the option. - Option() uint16 - // pack returns the bytes of the option data. - pack() ([]byte, error) - // unpack sets the data as found in the buffer. Is also sets - // the length of the slice as the length of the option data. - unpack([]byte) error - // String returns the string representation of the option. - String() string -} - -// EDNS0_NSID option is used to retrieve a nameserver -// identifier. When sending a request Nsid must be set to the empty string -// The identifier is an opaque string encoded as hex. -// Basic use pattern for creating an nsid option: -// -// o := new(dns.OPT) -// o.Hdr.Name = "." -// o.Hdr.Rrtype = dns.TypeOPT -// e := new(dns.EDNS0_NSID) -// e.Code = dns.EDNS0NSID -// e.Nsid = "AA" -// o.Option = append(o.Option, e) -type EDNS0_NSID struct { - Code uint16 // Always EDNS0NSID - Nsid string // This string needs to be hex encoded -} - -func (e *EDNS0_NSID) pack() ([]byte, error) { - h, err := hex.DecodeString(e.Nsid) - if err != nil { - return nil, err - } - return h, nil -} - -func (e *EDNS0_NSID) Option() uint16 { return EDNS0NSID } -func (e *EDNS0_NSID) unpack(b []byte) error { e.Nsid = hex.EncodeToString(b); return nil } -func (e *EDNS0_NSID) String() string { return string(e.Nsid) } - -// EDNS0_SUBNET is the subnet option that is used to give the remote nameserver -// an idea of where the client lives. It can then give back a different -// answer depending on the location or network topology. -// Basic use pattern for creating an subnet option: -// -// o := new(dns.OPT) -// o.Hdr.Name = "." -// o.Hdr.Rrtype = dns.TypeOPT -// e := new(dns.EDNS0_SUBNET) -// e.Code = dns.EDNS0SUBNET -// e.Family = 1 // 1 for IPv4 source address, 2 for IPv6 -// e.SourceNetmask = 32 // 32 for IPV4, 128 for IPv6 -// e.SourceScope = 0 -// e.Address = net.ParseIP("127.0.0.1").To4() // for IPv4 -// // e.Address = net.ParseIP("2001:7b8:32a::2") // for IPV6 -// o.Option = append(o.Option, e) -// -// Note: the spec (draft-ietf-dnsop-edns-client-subnet-00) has some insane logic -// for which netmask applies to the address. This code will parse all the -// available bits when unpacking (up to optlen). When packing it will apply -// SourceNetmask. If you need more advanced logic, patches welcome and good luck. -type EDNS0_SUBNET struct { - Code uint16 // Always EDNS0SUBNET - Family uint16 // 1 for IP, 2 for IP6 - SourceNetmask uint8 - SourceScope uint8 - Address net.IP - DraftOption bool // Set to true if using the old (0x50fa) option code -} - -func (e *EDNS0_SUBNET) Option() uint16 { - if e.DraftOption { - return EDNS0SUBNETDRAFT - } - return EDNS0SUBNET -} - -func (e *EDNS0_SUBNET) pack() ([]byte, error) { - b := make([]byte, 4) - binary.BigEndian.PutUint16(b[0:], e.Family) - b[2] = e.SourceNetmask - b[3] = e.SourceScope - switch e.Family { - case 1: - if e.SourceNetmask > net.IPv4len*8 { - return nil, errors.New("dns: bad netmask") - } - if len(e.Address.To4()) != net.IPv4len { - return nil, errors.New("dns: bad address") - } - ip := e.Address.To4().Mask(net.CIDRMask(int(e.SourceNetmask), net.IPv4len*8)) - needLength := (e.SourceNetmask + 8 - 1) / 8 // division rounding up - b = append(b, ip[:needLength]...) - case 2: - if e.SourceNetmask > net.IPv6len*8 { - return nil, errors.New("dns: bad netmask") - } - if len(e.Address) != net.IPv6len { - return nil, errors.New("dns: bad address") - } - ip := e.Address.Mask(net.CIDRMask(int(e.SourceNetmask), net.IPv6len*8)) - needLength := (e.SourceNetmask + 8 - 1) / 8 // division rounding up - b = append(b, ip[:needLength]...) - default: - return nil, errors.New("dns: bad address family") - } - return b, nil -} - -func (e *EDNS0_SUBNET) unpack(b []byte) error { - if len(b) < 4 { - return ErrBuf - } - e.Family = binary.BigEndian.Uint16(b) - e.SourceNetmask = b[2] - e.SourceScope = b[3] - switch e.Family { - case 1: - if e.SourceNetmask > net.IPv4len*8 || e.SourceScope > net.IPv4len*8 { - return errors.New("dns: bad netmask") - } - addr := make([]byte, net.IPv4len) - for i := 0; i < net.IPv4len && 4+i < len(b); i++ { - addr[i] = b[4+i] - } - e.Address = net.IPv4(addr[0], addr[1], addr[2], addr[3]) - case 2: - if e.SourceNetmask > net.IPv6len*8 || e.SourceScope > net.IPv6len*8 { - return errors.New("dns: bad netmask") - } - addr := make([]byte, net.IPv6len) - for i := 0; i < net.IPv6len && 4+i < len(b); i++ { - addr[i] = b[4+i] - } - e.Address = net.IP{addr[0], addr[1], addr[2], addr[3], addr[4], - addr[5], addr[6], addr[7], addr[8], addr[9], addr[10], - addr[11], addr[12], addr[13], addr[14], addr[15]} - default: - return errors.New("dns: bad address family") - } - return nil -} - -func (e *EDNS0_SUBNET) String() (s string) { - if e.Address == nil { - s = "<nil>" - } else if e.Address.To4() != nil { - s = e.Address.String() - } else { - s = "[" + e.Address.String() + "]" - } - s += "/" + strconv.Itoa(int(e.SourceNetmask)) + "/" + strconv.Itoa(int(e.SourceScope)) - return -} - -// The EDNS0_COOKIE option is used to add a DNS Cookie to a message. -// -// o := new(dns.OPT) -// o.Hdr.Name = "." -// o.Hdr.Rrtype = dns.TypeOPT -// e := new(dns.EDNS0_COOKIE) -// e.Code = dns.EDNS0COOKIE -// e.Cookie = "24a5ac.." -// o.Option = append(o.Option, e) -// -// The Cookie field consists out of a client cookie (RFC 7873 Section 4), that is -// always 8 bytes. It may then optionally be followed by the server cookie. The server -// cookie is of variable length, 8 to a maximum of 32 bytes. In other words: -// -// cCookie := o.Cookie[:16] -// sCookie := o.Cookie[16:] -// -// There is no guarantee that the Cookie string has a specific length. -type EDNS0_COOKIE struct { - Code uint16 // Always EDNS0COOKIE - Cookie string // Hex-encoded cookie data -} - -func (e *EDNS0_COOKIE) pack() ([]byte, error) { - h, err := hex.DecodeString(e.Cookie) - if err != nil { - return nil, err - } - return h, nil -} - -func (e *EDNS0_COOKIE) Option() uint16 { return EDNS0COOKIE } -func (e *EDNS0_COOKIE) unpack(b []byte) error { e.Cookie = hex.EncodeToString(b); return nil } -func (e *EDNS0_COOKIE) String() string { return e.Cookie } - -// The EDNS0_UL (Update Lease) (draft RFC) option is used to tell the server to set -// an expiration on an update RR. This is helpful for clients that cannot clean -// up after themselves. This is a draft RFC and more information can be found at -// http://files.dns-sd.org/draft-sekar-dns-ul.txt -// -// o := new(dns.OPT) -// o.Hdr.Name = "." -// o.Hdr.Rrtype = dns.TypeOPT -// e := new(dns.EDNS0_UL) -// e.Code = dns.EDNS0UL -// e.Lease = 120 // in seconds -// o.Option = append(o.Option, e) -type EDNS0_UL struct { - Code uint16 // Always EDNS0UL - Lease uint32 -} - -func (e *EDNS0_UL) Option() uint16 { return EDNS0UL } -func (e *EDNS0_UL) String() string { return strconv.FormatUint(uint64(e.Lease), 10) } - -// Copied: http://golang.org/src/pkg/net/dnsmsg.go -func (e *EDNS0_UL) pack() ([]byte, error) { - b := make([]byte, 4) - binary.BigEndian.PutUint32(b, e.Lease) - return b, nil -} - -func (e *EDNS0_UL) unpack(b []byte) error { - if len(b) < 4 { - return ErrBuf - } - e.Lease = binary.BigEndian.Uint32(b) - return nil -} - -// EDNS0_LLQ stands for Long Lived Queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01 -// Implemented for completeness, as the EDNS0 type code is assigned. -type EDNS0_LLQ struct { - Code uint16 // Always EDNS0LLQ - Version uint16 - Opcode uint16 - Error uint16 - Id uint64 - LeaseLife uint32 -} - -func (e *EDNS0_LLQ) Option() uint16 { return EDNS0LLQ } - -func (e *EDNS0_LLQ) pack() ([]byte, error) { - b := make([]byte, 18) - binary.BigEndian.PutUint16(b[0:], e.Version) - binary.BigEndian.PutUint16(b[2:], e.Opcode) - binary.BigEndian.PutUint16(b[4:], e.Error) - binary.BigEndian.PutUint64(b[6:], e.Id) - binary.BigEndian.PutUint32(b[14:], e.LeaseLife) - return b, nil -} - -func (e *EDNS0_LLQ) unpack(b []byte) error { - if len(b) < 18 { - return ErrBuf - } - e.Version = binary.BigEndian.Uint16(b[0:]) - e.Opcode = binary.BigEndian.Uint16(b[2:]) - e.Error = binary.BigEndian.Uint16(b[4:]) - e.Id = binary.BigEndian.Uint64(b[6:]) - e.LeaseLife = binary.BigEndian.Uint32(b[14:]) - return nil -} - -func (e *EDNS0_LLQ) String() string { - s := strconv.FormatUint(uint64(e.Version), 10) + " " + strconv.FormatUint(uint64(e.Opcode), 10) + - " " + strconv.FormatUint(uint64(e.Error), 10) + " " + strconv.FormatUint(uint64(e.Id), 10) + - " " + strconv.FormatUint(uint64(e.LeaseLife), 10) - return s -} - -type EDNS0_DAU struct { - Code uint16 // Always EDNS0DAU - AlgCode []uint8 -} - -func (e *EDNS0_DAU) Option() uint16 { return EDNS0DAU } -func (e *EDNS0_DAU) pack() ([]byte, error) { return e.AlgCode, nil } -func (e *EDNS0_DAU) unpack(b []byte) error { e.AlgCode = b; return nil } - -func (e *EDNS0_DAU) String() string { - s := "" - for i := 0; i < len(e.AlgCode); i++ { - if a, ok := AlgorithmToString[e.AlgCode[i]]; ok { - s += " " + a - } else { - s += " " + strconv.Itoa(int(e.AlgCode[i])) - } - } - return s -} - -type EDNS0_DHU struct { - Code uint16 // Always EDNS0DHU - AlgCode []uint8 -} - -func (e *EDNS0_DHU) Option() uint16 { return EDNS0DHU } -func (e *EDNS0_DHU) pack() ([]byte, error) { return e.AlgCode, nil } -func (e *EDNS0_DHU) unpack(b []byte) error { e.AlgCode = b; return nil } - -func (e *EDNS0_DHU) String() string { - s := "" - for i := 0; i < len(e.AlgCode); i++ { - if a, ok := HashToString[e.AlgCode[i]]; ok { - s += " " + a - } else { - s += " " + strconv.Itoa(int(e.AlgCode[i])) - } - } - return s -} - -type EDNS0_N3U struct { - Code uint16 // Always EDNS0N3U - AlgCode []uint8 -} - -func (e *EDNS0_N3U) Option() uint16 { return EDNS0N3U } -func (e *EDNS0_N3U) pack() ([]byte, error) { return e.AlgCode, nil } -func (e *EDNS0_N3U) unpack(b []byte) error { e.AlgCode = b; return nil } - -func (e *EDNS0_N3U) String() string { - // Re-use the hash map - s := "" - for i := 0; i < len(e.AlgCode); i++ { - if a, ok := HashToString[e.AlgCode[i]]; ok { - s += " " + a - } else { - s += " " + strconv.Itoa(int(e.AlgCode[i])) - } - } - return s -} - -type EDNS0_EXPIRE struct { - Code uint16 // Always EDNS0EXPIRE - Expire uint32 -} - -func (e *EDNS0_EXPIRE) Option() uint16 { return EDNS0EXPIRE } -func (e *EDNS0_EXPIRE) String() string { return strconv.FormatUint(uint64(e.Expire), 10) } - -func (e *EDNS0_EXPIRE) pack() ([]byte, error) { - b := make([]byte, 4) - b[0] = byte(e.Expire >> 24) - b[1] = byte(e.Expire >> 16) - b[2] = byte(e.Expire >> 8) - b[3] = byte(e.Expire) - return b, nil -} - -func (e *EDNS0_EXPIRE) unpack(b []byte) error { - if len(b) < 4 { - return ErrBuf - } - e.Expire = binary.BigEndian.Uint32(b) - return nil -} - -// The EDNS0_LOCAL option is used for local/experimental purposes. The option -// code is recommended to be within the range [EDNS0LOCALSTART, EDNS0LOCALEND] -// (RFC6891), although any unassigned code can actually be used. The content of -// the option is made available in Data, unaltered. -// Basic use pattern for creating a local option: -// -// o := new(dns.OPT) -// o.Hdr.Name = "." -// o.Hdr.Rrtype = dns.TypeOPT -// e := new(dns.EDNS0_LOCAL) -// e.Code = dns.EDNS0LOCALSTART -// e.Data = []byte{72, 82, 74} -// o.Option = append(o.Option, e) -type EDNS0_LOCAL struct { - Code uint16 - Data []byte -} - -func (e *EDNS0_LOCAL) Option() uint16 { return e.Code } -func (e *EDNS0_LOCAL) String() string { - return strconv.FormatInt(int64(e.Code), 10) + ":0x" + hex.EncodeToString(e.Data) -} - -func (e *EDNS0_LOCAL) pack() ([]byte, error) { - b := make([]byte, len(e.Data)) - copied := copy(b, e.Data) - if copied != len(e.Data) { - return nil, ErrBuf - } - return b, nil -} - -func (e *EDNS0_LOCAL) unpack(b []byte) error { - e.Data = make([]byte, len(b)) - copied := copy(e.Data, b) - if copied != len(b) { - return ErrBuf - } - return nil -} - -// EDNS0_TCP_KEEPALIVE is an EDNS0 option that instructs the server to keep -// the TCP connection alive. See RFC 7828. -type EDNS0_TCP_KEEPALIVE struct { - Code uint16 // Always EDNSTCPKEEPALIVE - Length uint16 // the value 0 if the TIMEOUT is omitted, the value 2 if it is present; - Timeout uint16 // an idle timeout value for the TCP connection, specified in units of 100 milliseconds, encoded in network byte order. -} - -func (e *EDNS0_TCP_KEEPALIVE) Option() uint16 { return EDNS0TCPKEEPALIVE } - -func (e *EDNS0_TCP_KEEPALIVE) pack() ([]byte, error) { - if e.Timeout != 0 && e.Length != 2 { - return nil, errors.New("dns: timeout specified but length is not 2") - } - if e.Timeout == 0 && e.Length != 0 { - return nil, errors.New("dns: timeout not specified but length is not 0") - } - b := make([]byte, 4+e.Length) - binary.BigEndian.PutUint16(b[0:], e.Code) - binary.BigEndian.PutUint16(b[2:], e.Length) - if e.Length == 2 { - binary.BigEndian.PutUint16(b[4:], e.Timeout) - } - return b, nil -} - -func (e *EDNS0_TCP_KEEPALIVE) unpack(b []byte) error { - if len(b) < 4 { - return ErrBuf - } - e.Length = binary.BigEndian.Uint16(b[2:4]) - if e.Length != 0 && e.Length != 2 { - return errors.New("dns: length mismatch, want 0/2 but got " + strconv.FormatUint(uint64(e.Length), 10)) - } - if e.Length == 2 { - if len(b) < 6 { - return ErrBuf - } - e.Timeout = binary.BigEndian.Uint16(b[4:6]) - } - return nil -} - -func (e *EDNS0_TCP_KEEPALIVE) String() (s string) { - s = "use tcp keep-alive" - if e.Length == 0 { - s += ", timeout omitted" - } else { - s += fmt.Sprintf(", timeout %dms", e.Timeout*100) - } - return -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/edns_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/edns_test.go deleted file mode 100644 index c290b0c8a..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/edns_test.go +++ /dev/null @@ -1,68 +0,0 @@ -package dns - -import "testing" - -func TestOPTTtl(t *testing.T) { - e := &OPT{} - e.Hdr.Name = "." - e.Hdr.Rrtype = TypeOPT - - // verify the default setting of DO=0 - if e.Do() { - t.Errorf("DO bit should be zero") - } - - // There are 6 possible invocations of SetDo(): - // - // 1. Starting with DO=0, using SetDo() - // 2. Starting with DO=0, using SetDo(true) - // 3. Starting with DO=0, using SetDo(false) - // 4. Starting with DO=1, using SetDo() - // 5. Starting with DO=1, using SetDo(true) - // 6. Starting with DO=1, using SetDo(false) - - // verify that invoking SetDo() sets DO=1 (TEST #1) - e.SetDo() - if !e.Do() { - t.Errorf("DO bit should be non-zero") - } - // verify that using SetDo(true) works when DO=1 (TEST #5) - e.SetDo(true) - if !e.Do() { - t.Errorf("DO bit should still be non-zero") - } - // verify that we can use SetDo(false) to set DO=0 (TEST #6) - e.SetDo(false) - if e.Do() { - t.Errorf("DO bit should be zero") - } - // verify that if we call SetDo(false) when DO=0 that it is unchanged (TEST #3) - e.SetDo(false) - if e.Do() { - t.Errorf("DO bit should still be zero") - } - // verify that using SetDo(true) works for DO=0 (TEST #2) - e.SetDo(true) - if !e.Do() { - t.Errorf("DO bit should be non-zero") - } - // verify that using SetDo() works for DO=1 (TEST #4) - e.SetDo() - if !e.Do() { - t.Errorf("DO bit should be non-zero") - } - - if e.Version() != 0 { - t.Errorf("version should be non-zero") - } - - e.SetVersion(42) - if e.Version() != 42 { - t.Errorf("set 42, expected %d, got %d", 42, e.Version()) - } - - e.SetExtendedRcode(42) - if e.ExtendedRcode() != 42 { - t.Errorf("set 42, expected %d, got %d", 42-15, e.ExtendedRcode()) - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/example_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/example_test.go deleted file mode 100644 index 64c14962c..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/example_test.go +++ /dev/null @@ -1,146 +0,0 @@ -package dns_test - -import ( - "errors" - "fmt" - "log" - "net" - - "github.com/miekg/dns" -) - -// Retrieve the MX records for miek.nl. -func ExampleMX() { - config, _ := dns.ClientConfigFromFile("/etc/resolv.conf") - c := new(dns.Client) - m := new(dns.Msg) - m.SetQuestion("miek.nl.", dns.TypeMX) - m.RecursionDesired = true - r, _, err := c.Exchange(m, config.Servers[0]+":"+config.Port) - if err != nil { - return - } - if r.Rcode != dns.RcodeSuccess { - return - } - for _, a := range r.Answer { - if mx, ok := a.(*dns.MX); ok { - fmt.Printf("%s\n", mx.String()) - } - } -} - -// Retrieve the DNSKEY records of a zone and convert them -// to DS records for SHA1, SHA256 and SHA384. -func ExampleDS() { - config, _ := dns.ClientConfigFromFile("/etc/resolv.conf") - c := new(dns.Client) - m := new(dns.Msg) - zone := "miek.nl" - m.SetQuestion(dns.Fqdn(zone), dns.TypeDNSKEY) - m.SetEdns0(4096, true) - r, _, err := c.Exchange(m, config.Servers[0]+":"+config.Port) - if err != nil { - return - } - if r.Rcode != dns.RcodeSuccess { - return - } - for _, k := range r.Answer { - if key, ok := k.(*dns.DNSKEY); ok { - for _, alg := range []uint8{dns.SHA1, dns.SHA256, dns.SHA384} { - fmt.Printf("%s; %d\n", key.ToDS(alg).String(), key.Flags) - } - } - } -} - -const TypeAPAIR = 0x0F99 - -type APAIR struct { - addr [2]net.IP -} - -func NewAPAIR() dns.PrivateRdata { return new(APAIR) } - -func (rd *APAIR) String() string { return rd.addr[0].String() + " " + rd.addr[1].String() } -func (rd *APAIR) Parse(txt []string) error { - if len(txt) != 2 { - return errors.New("two addresses required for APAIR") - } - for i, s := range txt { - ip := net.ParseIP(s) - if ip == nil { - return errors.New("invalid IP in APAIR text representation") - } - rd.addr[i] = ip - } - return nil -} - -func (rd *APAIR) Pack(buf []byte) (int, error) { - b := append([]byte(rd.addr[0]), []byte(rd.addr[1])...) - n := copy(buf, b) - if n != len(b) { - return n, dns.ErrBuf - } - return n, nil -} - -func (rd *APAIR) Unpack(buf []byte) (int, error) { - ln := net.IPv4len * 2 - if len(buf) != ln { - return 0, errors.New("invalid length of APAIR rdata") - } - cp := make([]byte, ln) - copy(cp, buf) // clone bytes to use them in IPs - - rd.addr[0] = net.IP(cp[:3]) - rd.addr[1] = net.IP(cp[4:]) - - return len(buf), nil -} - -func (rd *APAIR) Copy(dest dns.PrivateRdata) error { - cp := make([]byte, rd.Len()) - _, err := rd.Pack(cp) - if err != nil { - return err - } - - d := dest.(*APAIR) - d.addr[0] = net.IP(cp[:3]) - d.addr[1] = net.IP(cp[4:]) - return nil -} - -func (rd *APAIR) Len() int { - return net.IPv4len * 2 -} - -func ExamplePrivateHandle() { - dns.PrivateHandle("APAIR", TypeAPAIR, NewAPAIR) - defer dns.PrivateHandleRemove(TypeAPAIR) - - rr, err := dns.NewRR("miek.nl. APAIR (1.2.3.4 1.2.3.5)") - if err != nil { - log.Fatal("could not parse APAIR record: ", err) - } - fmt.Println(rr) - // Output: miek.nl. 3600 IN APAIR 1.2.3.4 1.2.3.5 - - m := new(dns.Msg) - m.Id = 12345 - m.SetQuestion("miek.nl.", TypeAPAIR) - m.Answer = append(m.Answer, rr) - - fmt.Println(m) - // ;; opcode: QUERY, status: NOERROR, id: 12345 - // ;; flags: rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 - // - // ;; QUESTION SECTION: - // ;miek.nl. IN APAIR - // - // ;; ANSWER SECTION: - // miek.nl. 3600 IN APAIR 1.2.3.4 1.2.3.5 -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/format.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/format.go deleted file mode 100644 index 3f5303c20..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/format.go +++ /dev/null @@ -1,87 +0,0 @@ -package dns - -import ( - "net" - "reflect" - "strconv" -) - -// NumField returns the number of rdata fields r has. -func NumField(r RR) int { - return reflect.ValueOf(r).Elem().NumField() - 1 // Remove RR_Header -} - -// Field returns the rdata field i as a string. Fields are indexed starting from 1. -// RR types that holds slice data, for instance the NSEC type bitmap will return a single -// string where the types are concatenated using a space. -// Accessing non existing fields will cause a panic. -func Field(r RR, i int) string { - if i == 0 { - return "" - } - d := reflect.ValueOf(r).Elem().Field(i) - switch k := d.Kind(); k { - case reflect.String: - return d.String() - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return strconv.FormatInt(d.Int(), 10) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - return strconv.FormatUint(d.Uint(), 10) - case reflect.Slice: - switch reflect.ValueOf(r).Elem().Type().Field(i).Tag { - case `dns:"a"`: - // TODO(miek): Hmm store this as 16 bytes - if d.Len() < net.IPv6len { - return net.IPv4(byte(d.Index(0).Uint()), - byte(d.Index(1).Uint()), - byte(d.Index(2).Uint()), - byte(d.Index(3).Uint())).String() - } - return net.IPv4(byte(d.Index(12).Uint()), - byte(d.Index(13).Uint()), - byte(d.Index(14).Uint()), - byte(d.Index(15).Uint())).String() - case `dns:"aaaa"`: - return net.IP{ - byte(d.Index(0).Uint()), - byte(d.Index(1).Uint()), - byte(d.Index(2).Uint()), - byte(d.Index(3).Uint()), - byte(d.Index(4).Uint()), - byte(d.Index(5).Uint()), - byte(d.Index(6).Uint()), - byte(d.Index(7).Uint()), - byte(d.Index(8).Uint()), - byte(d.Index(9).Uint()), - byte(d.Index(10).Uint()), - byte(d.Index(11).Uint()), - byte(d.Index(12).Uint()), - byte(d.Index(13).Uint()), - byte(d.Index(14).Uint()), - byte(d.Index(15).Uint()), - }.String() - case `dns:"nsec"`: - if d.Len() == 0 { - return "" - } - s := Type(d.Index(0).Uint()).String() - for i := 1; i < d.Len(); i++ { - s += " " + Type(d.Index(i).Uint()).String() - } - return s - default: - // if it does not have a tag its a string slice - fallthrough - case `dns:"txt"`: - if d.Len() == 0 { - return "" - } - s := d.Index(0).String() - for i := 1; i < d.Len(); i++ { - s += " " + d.Index(i).String() - } - return s - } - } - return "" -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/fuzz_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/fuzz_test.go deleted file mode 100644 index 255869730..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/fuzz_test.go +++ /dev/null @@ -1,25 +0,0 @@ -package dns - -import "testing" - -func TestFuzzString(t *testing.T) { - testcases := []string{"", " MINFO ", " RP ", " NSEC 0 0", " \" NSEC 0 0\"", " \" MINFO \"", - ";a ", ";a����������", - " NSAP O ", " NSAP N ", - " TYPE4 TYPE6a789a3bc0045c8a5fb42c7d1bd998f5444 IN 9579b47d46817afbd17273e6", - " TYPE45 3 3 4147994 TYPE\\(\\)\\)\\(\\)\\(\\(\\)\\(\\)\\)\\)\\(\\)\\(\\)\\(\\(\\R 948\"\")\\(\\)\\)\\)\\(\\ ", - "$GENERATE 0-3 ${441189,5039418474430,o}", - "$INCLUDE 00 TYPE00000000000n ", - "$INCLUDE PE4 TYPE061463623/727071511 \\(\\)\\$GENERATE 6-462/0", - } - for i, tc := range testcases { - rr, err := NewRR(tc) - if err == nil { - // rr can be nil because we can (for instance) just parse a comment - if rr == nil { - continue - } - t.Fatalf("parsed mailformed RR %d: %s", i, rr.String()) - } - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/generate.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/generate.go deleted file mode 100644 index e4481a4b0..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/generate.go +++ /dev/null @@ -1,159 +0,0 @@ -package dns - -import ( - "bytes" - "errors" - "fmt" - "strconv" - "strings" -) - -// Parse the $GENERATE statement as used in BIND9 zones. -// See http://www.zytrax.com/books/dns/ch8/generate.html for instance. -// We are called after '$GENERATE '. After which we expect: -// * the range (12-24/2) -// * lhs (ownername) -// * [[ttl][class]] -// * type -// * rhs (rdata) -// But we are lazy here, only the range is parsed *all* occurrences -// of $ after that are interpreted. -// Any error are returned as a string value, the empty string signals -// "no error". -func generate(l lex, c chan lex, t chan *Token, o string) string { - step := 1 - if i := strings.IndexAny(l.token, "/"); i != -1 { - if i+1 == len(l.token) { - return "bad step in $GENERATE range" - } - if s, err := strconv.Atoi(l.token[i+1:]); err == nil { - if s < 0 { - return "bad step in $GENERATE range" - } - step = s - } else { - return "bad step in $GENERATE range" - } - l.token = l.token[:i] - } - sx := strings.SplitN(l.token, "-", 2) - if len(sx) != 2 { - return "bad start-stop in $GENERATE range" - } - start, err := strconv.Atoi(sx[0]) - if err != nil { - return "bad start in $GENERATE range" - } - end, err := strconv.Atoi(sx[1]) - if err != nil { - return "bad stop in $GENERATE range" - } - if end < 0 || start < 0 || end < start { - return "bad range in $GENERATE range" - } - - <-c // _BLANK - // Create a complete new string, which we then parse again. - s := "" -BuildRR: - l = <-c - if l.value != zNewline && l.value != zEOF { - s += l.token - goto BuildRR - } - for i := start; i <= end; i += step { - var ( - escape bool - dom bytes.Buffer - mod string - err error - offset int - ) - - for j := 0; j < len(s); j++ { // No 'range' because we need to jump around - switch s[j] { - case '\\': - if escape { - dom.WriteByte('\\') - escape = false - continue - } - escape = true - case '$': - mod = "%d" - offset = 0 - if escape { - dom.WriteByte('$') - escape = false - continue - } - escape = false - if j+1 >= len(s) { // End of the string - dom.WriteString(fmt.Sprintf(mod, i+offset)) - continue - } else { - if s[j+1] == '$' { - dom.WriteByte('$') - j++ - continue - } - } - // Search for { and } - if s[j+1] == '{' { // Modifier block - sep := strings.Index(s[j+2:], "}") - if sep == -1 { - return "bad modifier in $GENERATE" - } - mod, offset, err = modToPrintf(s[j+2 : j+2+sep]) - if err != nil { - return err.Error() - } - j += 2 + sep // Jump to it - } - dom.WriteString(fmt.Sprintf(mod, i+offset)) - default: - if escape { // Pretty useless here - escape = false - continue - } - dom.WriteByte(s[j]) - } - } - // Re-parse the RR and send it on the current channel t - rx, err := NewRR("$ORIGIN " + o + "\n" + dom.String()) - if err != nil { - return err.Error() - } - t <- &Token{RR: rx} - // Its more efficient to first built the rrlist and then parse it in - // one go! But is this a problem? - } - return "" -} - -// Convert a $GENERATE modifier 0,0,d to something Printf can deal with. -func modToPrintf(s string) (string, int, error) { - xs := strings.SplitN(s, ",", 3) - if len(xs) != 3 { - return "", 0, errors.New("bad modifier in $GENERATE") - } - // xs[0] is offset, xs[1] is width, xs[2] is base - if xs[2] != "o" && xs[2] != "d" && xs[2] != "x" && xs[2] != "X" { - return "", 0, errors.New("bad base in $GENERATE") - } - offset, err := strconv.Atoi(xs[0]) - if err != nil || offset > 255 { - return "", 0, errors.New("bad offset in $GENERATE") - } - width, err := strconv.Atoi(xs[1]) - if err != nil || width > 255 { - return "", offset, errors.New("bad width in $GENERATE") - } - switch { - case width < 0: - return "", offset, errors.New("bad width in $GENERATE") - case width == 0: - return "%" + xs[1] + xs[2], offset, nil - } - return "%0" + xs[1] + xs[2], offset, nil -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/issue_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/issue_test.go deleted file mode 100644 index 265ad56c0..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/issue_test.go +++ /dev/null @@ -1,68 +0,0 @@ -package dns - -// Tests that solve that an specific issue. - -import ( - "strings" - "testing" -) - -func TestTCPRtt(t *testing.T) { - m := new(Msg) - m.RecursionDesired = true - m.SetQuestion("example.org.", TypeA) - - c := &Client{} - for _, proto := range []string{"udp", "tcp"} { - c.Net = proto - _, rtt, err := c.Exchange(m, "8.8.4.4:53") - if err != nil { - t.Fatal(err) - } - if rtt == 0 { - t.Fatalf("expecting non zero rtt %s, got zero", c.Net) - } - } -} - -func TestNSEC3MissingSalt(t *testing.T) { - rr, err := NewRR("ji6neoaepv8b5o6k4ev33abha8ht9fgc.example. NSEC3 1 1 12 aabbccdd K8UDEMVP1J2F7EG6JEBPS17VP3N8I58H") - if err != nil { - t.Fatalf("failed to parse example rr: %s", err) - } - m := new(Msg) - m.Answer = []RR{rr} - mb, err := m.Pack() - if err != nil { - t.Fatalf("expected to pack message. err: %s", err) - } - if err := m.Unpack(mb); err != nil { - t.Fatalf("expected to unpack message. missing salt? err: %s", err) - } - in := rr.(*NSEC3).Salt - out := m.Answer[0].(*NSEC3).Salt - if in != out { - t.Fatalf("expected salts to match. packed: `%s`. returned: `%s`", in, out) - } -} - -func TestNSEC3MixedNextDomain(t *testing.T) { - rr, err := NewRR("ji6neoaepv8b5o6k4ev33abha8ht9fgc.example. NSEC3 1 1 12 - k8udemvp1j2f7eg6jebps17vp3n8i58h") - if err != nil { - t.Fatalf("failed to parse example rr: %s", err) - } - m := new(Msg) - m.Answer = []RR{rr} - mb, err := m.Pack() - if err != nil { - t.Fatalf("expected to pack message. err: %s", err) - } - if err := m.Unpack(mb); err != nil { - t.Fatalf("expected to unpack message. err: %s", err) - } - in := strings.ToUpper(rr.(*NSEC3).NextDomain) - out := m.Answer[0].(*NSEC3).NextDomain - if in != out { - t.Fatalf("expected round trip to produce NextDomain `%s`, instead `%s`", in, out) - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/labels.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/labels.go deleted file mode 100644 index 9538d9c3a..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/labels.go +++ /dev/null @@ -1,171 +0,0 @@ -package dns - -import "strings" - -// Holds a bunch of helper functions for dealing with labels. - -// SplitDomainName splits a name string into it's labels. -// www.miek.nl. returns []string{"www", "miek", "nl"} -// .www.miek.nl. returns []string{"", "www", "miek", "nl"}, -// The root label (.) returns nil. Note that using -// strings.Split(s) will work in most cases, but does not handle -// escaped dots (\.) for instance. -// s must be a syntactically valid domain name, see IsDomainName. -func SplitDomainName(s string) (labels []string) { - if len(s) == 0 { - return nil - } - fqdnEnd := 0 // offset of the final '.' or the length of the name - idx := Split(s) - begin := 0 - if s[len(s)-1] == '.' { - fqdnEnd = len(s) - 1 - } else { - fqdnEnd = len(s) - } - - switch len(idx) { - case 0: - return nil - case 1: - // no-op - default: - end := 0 - for i := 1; i < len(idx); i++ { - end = idx[i] - labels = append(labels, s[begin:end-1]) - begin = end - } - } - - labels = append(labels, s[begin:fqdnEnd]) - return labels -} - -// CompareDomainName compares the names s1 and s2 and -// returns how many labels they have in common starting from the *right*. -// The comparison stops at the first inequality. The names are not downcased -// before the comparison. -// -// www.miek.nl. and miek.nl. have two labels in common: miek and nl -// www.miek.nl. and www.bla.nl. have one label in common: nl -// -// s1 and s2 must be syntactically valid domain names. -func CompareDomainName(s1, s2 string) (n int) { - s1, s2 = strings.ToLower(s1), strings.ToLower(s2) - s1 = Fqdn(s1) - s2 = Fqdn(s2) - l1 := Split(s1) - l2 := Split(s2) - - // the first check: root label - if l1 == nil || l2 == nil { - return - } - - j1 := len(l1) - 1 // end - i1 := len(l1) - 2 // start - j2 := len(l2) - 1 - i2 := len(l2) - 2 - // the second check can be done here: last/only label - // before we fall through into the for-loop below - if s1[l1[j1]:] == s2[l2[j2]:] { - n++ - } else { - return - } - for { - if i1 < 0 || i2 < 0 { - break - } - if s1[l1[i1]:l1[j1]] == s2[l2[i2]:l2[j2]] { - n++ - } else { - break - } - j1-- - i1-- - j2-- - i2-- - } - return -} - -// CountLabel counts the the number of labels in the string s. -// s must be a syntactically valid domain name. -func CountLabel(s string) (labels int) { - if s == "." { - return - } - off := 0 - end := false - for { - off, end = NextLabel(s, off) - labels++ - if end { - return - } - } -} - -// Split splits a name s into its label indexes. -// www.miek.nl. returns []int{0, 4, 9}, www.miek.nl also returns []int{0, 4, 9}. -// The root name (.) returns nil. Also see SplitDomainName. -// s must be a syntactically valid domain name. -func Split(s string) []int { - if s == "." { - return nil - } - idx := make([]int, 1, 3) - off := 0 - end := false - - for { - off, end = NextLabel(s, off) - if end { - return idx - } - idx = append(idx, off) - } -} - -// NextLabel returns the index of the start of the next label in the -// string s starting at offset. -// The bool end is true when the end of the string has been reached. -// Also see PrevLabel. -func NextLabel(s string, offset int) (i int, end bool) { - quote := false - for i = offset; i < len(s)-1; i++ { - switch s[i] { - case '\\': - quote = !quote - default: - quote = false - case '.': - if quote { - quote = !quote - continue - } - return i + 1, false - } - } - return i + 1, true -} - -// PrevLabel returns the index of the label when starting from the right and -// jumping n labels to the left. -// The bool start is true when the start of the string has been overshot. -// Also see NextLabel. -func PrevLabel(s string, n int) (i int, start bool) { - if n == 0 { - return len(s), false - } - lab := Split(s) - if lab == nil { - return 0, true - } - if n > len(lab) { - return 0, true - } - return lab[len(lab)-n], false -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/labels_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/labels_test.go deleted file mode 100644 index 9875d6cd9..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/labels_test.go +++ /dev/null @@ -1,203 +0,0 @@ -package dns - -import "testing" - -func TestCompareDomainName(t *testing.T) { - s1 := "www.miek.nl." - s2 := "miek.nl." - s3 := "www.bla.nl." - s4 := "nl.www.bla." - s5 := "nl" - s6 := "miek.nl" - - if CompareDomainName(s1, s2) != 2 { - t.Errorf("%s with %s should be %d", s1, s2, 2) - } - if CompareDomainName(s1, s3) != 1 { - t.Errorf("%s with %s should be %d", s1, s3, 1) - } - if CompareDomainName(s3, s4) != 0 { - t.Errorf("%s with %s should be %d", s3, s4, 0) - } - // Non qualified tests - if CompareDomainName(s1, s5) != 1 { - t.Errorf("%s with %s should be %d", s1, s5, 1) - } - if CompareDomainName(s1, s6) != 2 { - t.Errorf("%s with %s should be %d", s1, s5, 2) - } - - if CompareDomainName(s1, ".") != 0 { - t.Errorf("%s with %s should be %d", s1, s5, 0) - } - if CompareDomainName(".", ".") != 0 { - t.Errorf("%s with %s should be %d", ".", ".", 0) - } - if CompareDomainName("test.com.", "TEST.COM.") != 2 { - t.Errorf("test.com. and TEST.COM. should be an exact match") - } -} - -func TestSplit(t *testing.T) { - splitter := map[string]int{ - "www.miek.nl.": 3, - "www.miek.nl": 3, - "www..miek.nl": 4, - `www\.miek.nl.`: 2, - `www\\.miek.nl.`: 3, - ".": 0, - "nl.": 1, - "nl": 1, - "com.": 1, - ".com.": 2, - } - for s, i := range splitter { - if x := len(Split(s)); x != i { - t.Errorf("labels should be %d, got %d: %s %v", i, x, s, Split(s)) - } else { - t.Logf("%s %v", s, Split(s)) - } - } -} - -func TestSplit2(t *testing.T) { - splitter := map[string][]int{ - "www.miek.nl.": {0, 4, 9}, - "www.miek.nl": {0, 4, 9}, - "nl": {0}, - } - for s, i := range splitter { - x := Split(s) - switch len(i) { - case 1: - if x[0] != i[0] { - t.Errorf("labels should be %v, got %v: %s", i, x, s) - } - default: - if x[0] != i[0] || x[1] != i[1] || x[2] != i[2] { - t.Errorf("labels should be %v, got %v: %s", i, x, s) - } - } - } -} - -func TestPrevLabel(t *testing.T) { - type prev struct { - string - int - } - prever := map[prev]int{ - prev{"www.miek.nl.", 0}: 12, - prev{"www.miek.nl.", 1}: 9, - prev{"www.miek.nl.", 2}: 4, - - prev{"www.miek.nl", 0}: 11, - prev{"www.miek.nl", 1}: 9, - prev{"www.miek.nl", 2}: 4, - - prev{"www.miek.nl.", 5}: 0, - prev{"www.miek.nl", 5}: 0, - - prev{"www.miek.nl.", 3}: 0, - prev{"www.miek.nl", 3}: 0, - } - for s, i := range prever { - x, ok := PrevLabel(s.string, s.int) - if i != x { - t.Errorf("label should be %d, got %d, %t: preving %d, %s", i, x, ok, s.int, s.string) - } - } -} - -func TestCountLabel(t *testing.T) { - splitter := map[string]int{ - "www.miek.nl.": 3, - "www.miek.nl": 3, - "nl": 1, - ".": 0, - } - for s, i := range splitter { - x := CountLabel(s) - if x != i { - t.Errorf("CountLabel should have %d, got %d", i, x) - } - } -} - -func TestSplitDomainName(t *testing.T) { - labels := map[string][]string{ - "miek.nl": {"miek", "nl"}, - ".": nil, - "www.miek.nl.": {"www", "miek", "nl"}, - "www.miek.nl": {"www", "miek", "nl"}, - "www..miek.nl": {"www", "", "miek", "nl"}, - `www\.miek.nl`: {`www\.miek`, "nl"}, - `www\\.miek.nl`: {`www\\`, "miek", "nl"}, - ".www.miek.nl.": {"", "www", "miek", "nl"}, - } -domainLoop: - for domain, splits := range labels { - parts := SplitDomainName(domain) - if len(parts) != len(splits) { - t.Errorf("SplitDomainName returned %v for %s, expected %v", parts, domain, splits) - continue domainLoop - } - for i := range parts { - if parts[i] != splits[i] { - t.Errorf("SplitDomainName returned %v for %s, expected %v", parts, domain, splits) - continue domainLoop - } - } - } -} - -func TestIsDomainName(t *testing.T) { - type ret struct { - ok bool - lab int - } - names := map[string]*ret{ - "..": {false, 1}, - "@.": {true, 1}, - "www.example.com": {true, 3}, - "www.e%ample.com": {true, 3}, - "www.example.com.": {true, 3}, - "mi\\k.nl.": {true, 2}, - "mi\\k.nl": {true, 2}, - } - for d, ok := range names { - l, k := IsDomainName(d) - if ok.ok != k || ok.lab != l { - t.Errorf(" got %v %d for %s ", k, l, d) - t.Errorf("have %v %d for %s ", ok.ok, ok.lab, d) - } - } -} - -func BenchmarkSplitLabels(b *testing.B) { - for i := 0; i < b.N; i++ { - Split("www.example.com") - } -} - -func BenchmarkLenLabels(b *testing.B) { - for i := 0; i < b.N; i++ { - CountLabel("www.example.com") - } -} - -func BenchmarkCompareLabels(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - CompareDomainName("www.example.com", "aa.example.com") - } -} - -func BenchmarkIsSubDomain(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - IsSubDomain("www.example.com", "aa.example.com") - IsSubDomain("example.com", "aa.example.com") - IsSubDomain("miek.nl", "aa.example.com") - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/msg.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/msg.go deleted file mode 100644 index 605fe6c5c..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/msg.go +++ /dev/null @@ -1,1159 +0,0 @@ -// DNS packet assembly, see RFC 1035. Converting from - Unpack() - -// and to - Pack() - wire format. -// All the packers and unpackers take a (msg []byte, off int) -// and return (off1 int, ok bool). If they return ok==false, they -// also return off1==len(msg), so that the next unpacker will -// also fail. This lets us avoid checks of ok until the end of a -// packing sequence. - -package dns - -//go:generate go run msg_generate.go -//go:generate go run compress_generate.go - -import ( - crand "crypto/rand" - "encoding/binary" - "fmt" - "math/big" - "math/rand" - "strconv" - "sync" -) - -const ( - maxCompressionOffset = 2 << 13 // We have 14 bits for the compression pointer - maxDomainNameWireOctets = 255 // See RFC 1035 section 2.3.4 -) - -var ( - ErrAlg error = &Error{err: "bad algorithm"} // ErrAlg indicates an error with the (DNSSEC) algorithm. - ErrAuth error = &Error{err: "bad authentication"} // ErrAuth indicates an error in the TSIG authentication. - ErrBuf error = &Error{err: "buffer size too small"} // ErrBuf indicates that the buffer used is too small for the message. - ErrConnEmpty error = &Error{err: "conn has no connection"} // ErrConnEmpty indicates a connection is being used before it is initialized. - ErrExtendedRcode error = &Error{err: "bad extended rcode"} // ErrExtendedRcode ... - ErrFqdn error = &Error{err: "domain must be fully qualified"} // ErrFqdn indicates that a domain name does not have a closing dot. - ErrId error = &Error{err: "id mismatch"} // ErrId indicates there is a mismatch with the message's ID. - ErrKeyAlg error = &Error{err: "bad key algorithm"} // ErrKeyAlg indicates that the algorithm in the key is not valid. - ErrKey error = &Error{err: "bad key"} - ErrKeySize error = &Error{err: "bad key size"} - ErrLongDomain error = &Error{err: fmt.Sprintf("domain name exceeded %d wire-format octets", maxDomainNameWireOctets)} - ErrNoSig error = &Error{err: "no signature found"} - ErrPrivKey error = &Error{err: "bad private key"} - ErrRcode error = &Error{err: "bad rcode"} - ErrRdata error = &Error{err: "bad rdata"} - ErrRRset error = &Error{err: "bad rrset"} - ErrSecret error = &Error{err: "no secrets defined"} - ErrShortRead error = &Error{err: "short read"} - ErrSig error = &Error{err: "bad signature"} // ErrSig indicates that a signature can not be cryptographically validated. - ErrSoa error = &Error{err: "no SOA"} // ErrSOA indicates that no SOA RR was seen when doing zone transfers. - ErrTime error = &Error{err: "bad time"} // ErrTime indicates a timing error in TSIG authentication. - ErrTruncated error = &Error{err: "failed to unpack truncated message"} // ErrTruncated indicates that we failed to unpack a truncated message. We unpacked as much as we had so Msg can still be used, if desired. -) - -// Id by default, returns a 16 bits random number to be used as a -// message id. The random provided should be good enough. This being a -// variable the function can be reassigned to a custom function. -// For instance, to make it return a static value: -// -// dns.Id = func() uint16 { return 3 } -var Id func() uint16 = id - -var ( - idLock sync.Mutex - idRand *rand.Rand -) - -// id returns a 16 bits random number to be used as a -// message id. The random provided should be good enough. -func id() uint16 { - idLock.Lock() - - if idRand == nil { - // This (partially) works around - // https://github.com/golang/go/issues/11833 by only - // seeding idRand upon the first call to id. - - var seed int64 - var buf [8]byte - - if _, err := crand.Read(buf[:]); err == nil { - seed = int64(binary.LittleEndian.Uint64(buf[:])) - } else { - seed = rand.Int63() - } - - idRand = rand.New(rand.NewSource(seed)) - } - - // The call to idRand.Uint32 must be within the - // mutex lock because *rand.Rand is not safe for - // concurrent use. - // - // There is no added performance overhead to calling - // idRand.Uint32 inside a mutex lock over just - // calling rand.Uint32 as the global math/rand rng - // is internally protected by a sync.Mutex. - id := uint16(idRand.Uint32()) - - idLock.Unlock() - return id -} - -// MsgHdr is a a manually-unpacked version of (id, bits). -type MsgHdr struct { - Id uint16 - Response bool - Opcode int - Authoritative bool - Truncated bool - RecursionDesired bool - RecursionAvailable bool - Zero bool - AuthenticatedData bool - CheckingDisabled bool - Rcode int -} - -// Msg contains the layout of a DNS message. -type Msg struct { - MsgHdr - Compress bool `json:"-"` // If true, the message will be compressed when converted to wire format. - Question []Question // Holds the RR(s) of the question section. - Answer []RR // Holds the RR(s) of the answer section. - Ns []RR // Holds the RR(s) of the authority section. - Extra []RR // Holds the RR(s) of the additional section. -} - -// ClassToString is a maps Classes to strings for each CLASS wire type. -var ClassToString = map[uint16]string{ - ClassINET: "IN", - ClassCSNET: "CS", - ClassCHAOS: "CH", - ClassHESIOD: "HS", - ClassNONE: "NONE", - ClassANY: "ANY", -} - -// OpcodeToString maps Opcodes to strings. -var OpcodeToString = map[int]string{ - OpcodeQuery: "QUERY", - OpcodeIQuery: "IQUERY", - OpcodeStatus: "STATUS", - OpcodeNotify: "NOTIFY", - OpcodeUpdate: "UPDATE", -} - -// RcodeToString maps Rcodes to strings. -var RcodeToString = map[int]string{ - RcodeSuccess: "NOERROR", - RcodeFormatError: "FORMERR", - RcodeServerFailure: "SERVFAIL", - RcodeNameError: "NXDOMAIN", - RcodeNotImplemented: "NOTIMPL", - RcodeRefused: "REFUSED", - RcodeYXDomain: "YXDOMAIN", // See RFC 2136 - RcodeYXRrset: "YXRRSET", - RcodeNXRrset: "NXRRSET", - RcodeNotAuth: "NOTAUTH", - RcodeNotZone: "NOTZONE", - RcodeBadSig: "BADSIG", // Also known as RcodeBadVers, see RFC 6891 - // RcodeBadVers: "BADVERS", - RcodeBadKey: "BADKEY", - RcodeBadTime: "BADTIME", - RcodeBadMode: "BADMODE", - RcodeBadName: "BADNAME", - RcodeBadAlg: "BADALG", - RcodeBadTrunc: "BADTRUNC", - RcodeBadCookie: "BADCOOKIE", -} - -// Domain names are a sequence of counted strings -// split at the dots. They end with a zero-length string. - -// PackDomainName packs a domain name s into msg[off:]. -// If compression is wanted compress must be true and the compression -// map needs to hold a mapping between domain names and offsets -// pointing into msg. -func PackDomainName(s string, msg []byte, off int, compression map[string]int, compress bool) (off1 int, err error) { - off1, _, err = packDomainName(s, msg, off, compression, compress) - return -} - -func packDomainName(s string, msg []byte, off int, compression map[string]int, compress bool) (off1 int, labels int, err error) { - // special case if msg == nil - lenmsg := 256 - if msg != nil { - lenmsg = len(msg) - } - ls := len(s) - if ls == 0 { // Ok, for instance when dealing with update RR without any rdata. - return off, 0, nil - } - // If not fully qualified, error out, but only if msg == nil #ugly - switch { - case msg == nil: - if s[ls-1] != '.' { - s += "." - ls++ - } - case msg != nil: - if s[ls-1] != '.' { - return lenmsg, 0, ErrFqdn - } - } - // Each dot ends a segment of the name. - // We trade each dot byte for a length byte. - // Except for escaped dots (\.), which are normal dots. - // There is also a trailing zero. - - // Compression - nameoffset := -1 - pointer := -1 - // Emit sequence of counted strings, chopping at dots. - begin := 0 - bs := []byte(s) - roBs, bsFresh, escapedDot := s, true, false - for i := 0; i < ls; i++ { - if bs[i] == '\\' { - for j := i; j < ls-1; j++ { - bs[j] = bs[j+1] - } - ls-- - if off+1 > lenmsg { - return lenmsg, labels, ErrBuf - } - // check for \DDD - if i+2 < ls && isDigit(bs[i]) && isDigit(bs[i+1]) && isDigit(bs[i+2]) { - bs[i] = dddToByte(bs[i:]) - for j := i + 1; j < ls-2; j++ { - bs[j] = bs[j+2] - } - ls -= 2 - } - escapedDot = bs[i] == '.' - bsFresh = false - continue - } - - if bs[i] == '.' { - if i > 0 && bs[i-1] == '.' && !escapedDot { - // two dots back to back is not legal - return lenmsg, labels, ErrRdata - } - if i-begin >= 1<<6 { // top two bits of length must be clear - return lenmsg, labels, ErrRdata - } - // off can already (we're in a loop) be bigger than len(msg) - // this happens when a name isn't fully qualified - if off+1 > lenmsg { - return lenmsg, labels, ErrBuf - } - if msg != nil { - msg[off] = byte(i - begin) - } - offset := off - off++ - for j := begin; j < i; j++ { - if off+1 > lenmsg { - return lenmsg, labels, ErrBuf - } - if msg != nil { - msg[off] = bs[j] - } - off++ - } - if compress && !bsFresh { - roBs = string(bs) - bsFresh = true - } - // Don't try to compress '.' - // We should only compress when compress it true, but we should also still pick - // up names that can be used for *future* compression(s). - if compression != nil && roBs[begin:] != "." { - if p, ok := compression[roBs[begin:]]; !ok { - // Only offsets smaller than this can be used. - if offset < maxCompressionOffset { - compression[roBs[begin:]] = offset - } - } else { - // The first hit is the longest matching dname - // keep the pointer offset we get back and store - // the offset of the current name, because that's - // where we need to insert the pointer later - - // If compress is true, we're allowed to compress this dname - if pointer == -1 && compress { - pointer = p // Where to point to - nameoffset = offset // Where to point from - break - } - } - } - labels++ - begin = i + 1 - } - escapedDot = false - } - // Root label is special - if len(bs) == 1 && bs[0] == '.' { - return off, labels, nil - } - // If we did compression and we find something add the pointer here - if pointer != -1 { - // We have two bytes (14 bits) to put the pointer in - // if msg == nil, we will never do compression - binary.BigEndian.PutUint16(msg[nameoffset:], uint16(pointer^0xC000)) - off = nameoffset + 1 - goto End - } - if msg != nil && off < len(msg) { - msg[off] = 0 - } -End: - off++ - return off, labels, nil -} - -// Unpack a domain name. -// In addition to the simple sequences of counted strings above, -// domain names are allowed to refer to strings elsewhere in the -// packet, to avoid repeating common suffixes when returning -// many entries in a single domain. The pointers are marked -// by a length byte with the top two bits set. Ignoring those -// two bits, that byte and the next give a 14 bit offset from msg[0] -// where we should pick up the trail. -// Note that if we jump elsewhere in the packet, -// we return off1 == the offset after the first pointer we found, -// which is where the next record will start. -// In theory, the pointers are only allowed to jump backward. -// We let them jump anywhere and stop jumping after a while. - -// UnpackDomainName unpacks a domain name into a string. -func UnpackDomainName(msg []byte, off int) (string, int, error) { - s := make([]byte, 0, 64) - off1 := 0 - lenmsg := len(msg) - maxLen := maxDomainNameWireOctets - ptr := 0 // number of pointers followed -Loop: - for { - if off >= lenmsg { - return "", lenmsg, ErrBuf - } - c := int(msg[off]) - off++ - switch c & 0xC0 { - case 0x00: - if c == 0x00 { - // end of name - break Loop - } - // literal string - if off+c > lenmsg { - return "", lenmsg, ErrBuf - } - for j := off; j < off+c; j++ { - switch b := msg[j]; b { - case '.', '(', ')', ';', ' ', '@': - fallthrough - case '"', '\\': - s = append(s, '\\', b) - // presentation-format \X escapes add an extra byte - maxLen += 1 - default: - if b < 32 || b >= 127 { // unprintable, use \DDD - var buf [3]byte - bufs := strconv.AppendInt(buf[:0], int64(b), 10) - s = append(s, '\\') - for i := 0; i < 3-len(bufs); i++ { - s = append(s, '0') - } - for _, r := range bufs { - s = append(s, r) - } - // presentation-format \DDD escapes add 3 extra bytes - maxLen += 3 - } else { - s = append(s, b) - } - } - } - s = append(s, '.') - off += c - case 0xC0: - // pointer to somewhere else in msg. - // remember location after first ptr, - // since that's how many bytes we consumed. - // also, don't follow too many pointers -- - // maybe there's a loop. - if off >= lenmsg { - return "", lenmsg, ErrBuf - } - c1 := msg[off] - off++ - if ptr == 0 { - off1 = off - } - if ptr++; ptr > 10 { - return "", lenmsg, &Error{err: "too many compression pointers"} - } - // pointer should guarantee that it advances and points forwards at least - // but the condition on previous three lines guarantees that it's - // at least loop-free - off = (c^0xC0)<<8 | int(c1) - default: - // 0x80 and 0x40 are reserved - return "", lenmsg, ErrRdata - } - } - if ptr == 0 { - off1 = off - } - if len(s) == 0 { - s = []byte(".") - } else if len(s) >= maxLen { - // error if the name is too long, but don't throw it away - return string(s), lenmsg, ErrLongDomain - } - return string(s), off1, nil -} - -func packTxt(txt []string, msg []byte, offset int, tmp []byte) (int, error) { - if len(txt) == 0 { - if offset >= len(msg) { - return offset, ErrBuf - } - msg[offset] = 0 - return offset, nil - } - var err error - for i := range txt { - if len(txt[i]) > len(tmp) { - return offset, ErrBuf - } - offset, err = packTxtString(txt[i], msg, offset, tmp) - if err != nil { - return offset, err - } - } - return offset, nil -} - -func packTxtString(s string, msg []byte, offset int, tmp []byte) (int, error) { - lenByteOffset := offset - if offset >= len(msg) || len(s) > len(tmp) { - return offset, ErrBuf - } - offset++ - bs := tmp[:len(s)] - copy(bs, s) - for i := 0; i < len(bs); i++ { - if len(msg) <= offset { - return offset, ErrBuf - } - if bs[i] == '\\' { - i++ - if i == len(bs) { - break - } - // check for \DDD - if i+2 < len(bs) && isDigit(bs[i]) && isDigit(bs[i+1]) && isDigit(bs[i+2]) { - msg[offset] = dddToByte(bs[i:]) - i += 2 - } else { - msg[offset] = bs[i] - } - } else { - msg[offset] = bs[i] - } - offset++ - } - l := offset - lenByteOffset - 1 - if l > 255 { - return offset, &Error{err: "string exceeded 255 bytes in txt"} - } - msg[lenByteOffset] = byte(l) - return offset, nil -} - -func packOctetString(s string, msg []byte, offset int, tmp []byte) (int, error) { - if offset >= len(msg) || len(s) > len(tmp) { - return offset, ErrBuf - } - bs := tmp[:len(s)] - copy(bs, s) - for i := 0; i < len(bs); i++ { - if len(msg) <= offset { - return offset, ErrBuf - } - if bs[i] == '\\' { - i++ - if i == len(bs) { - break - } - // check for \DDD - if i+2 < len(bs) && isDigit(bs[i]) && isDigit(bs[i+1]) && isDigit(bs[i+2]) { - msg[offset] = dddToByte(bs[i:]) - i += 2 - } else { - msg[offset] = bs[i] - } - } else { - msg[offset] = bs[i] - } - offset++ - } - return offset, nil -} - -func unpackTxt(msg []byte, off0 int) (ss []string, off int, err error) { - off = off0 - var s string - for off < len(msg) && err == nil { - s, off, err = unpackTxtString(msg, off) - if err == nil { - ss = append(ss, s) - } - } - return -} - -func unpackTxtString(msg []byte, offset int) (string, int, error) { - if offset+1 > len(msg) { - return "", offset, &Error{err: "overflow unpacking txt"} - } - l := int(msg[offset]) - if offset+l+1 > len(msg) { - return "", offset, &Error{err: "overflow unpacking txt"} - } - s := make([]byte, 0, l) - for _, b := range msg[offset+1 : offset+1+l] { - switch b { - case '"', '\\': - s = append(s, '\\', b) - default: - if b < 32 || b > 127 { // unprintable - var buf [3]byte - bufs := strconv.AppendInt(buf[:0], int64(b), 10) - s = append(s, '\\') - for i := 0; i < 3-len(bufs); i++ { - s = append(s, '0') - } - for _, r := range bufs { - s = append(s, r) - } - } else { - s = append(s, b) - } - } - } - offset += 1 + l - return string(s), offset, nil -} - -// Helpers for dealing with escaped bytes -func isDigit(b byte) bool { return b >= '0' && b <= '9' } - -func dddToByte(s []byte) byte { - return byte((s[0]-'0')*100 + (s[1]-'0')*10 + (s[2] - '0')) -} - -// Helper function for packing and unpacking -func intToBytes(i *big.Int, length int) []byte { - buf := i.Bytes() - if len(buf) < length { - b := make([]byte, length) - copy(b[length-len(buf):], buf) - return b - } - return buf -} - -// PackRR packs a resource record rr into msg[off:]. -// See PackDomainName for documentation about the compression. -func PackRR(rr RR, msg []byte, off int, compression map[string]int, compress bool) (off1 int, err error) { - if rr == nil { - return len(msg), &Error{err: "nil rr"} - } - - off1, err = rr.pack(msg, off, compression, compress) - if err != nil { - return len(msg), err - } - // TODO(miek): Not sure if this is needed? If removed we can remove rawmsg.go as well. - if rawSetRdlength(msg, off, off1) { - return off1, nil - } - return off, ErrRdata -} - -// UnpackRR unpacks msg[off:] into an RR. -func UnpackRR(msg []byte, off int) (rr RR, off1 int, err error) { - h, off, msg, err := unpackHeader(msg, off) - if err != nil { - return nil, len(msg), err - } - end := off + int(h.Rdlength) - - if fn, known := typeToUnpack[h.Rrtype]; !known { - rr, off, err = unpackRFC3597(h, msg, off) - } else { - rr, off, err = fn(h, msg, off) - } - if off != end { - return &h, end, &Error{err: "bad rdlength"} - } - return rr, off, err -} - -// unpackRRslice unpacks msg[off:] into an []RR. -// If we cannot unpack the whole array, then it will return nil -func unpackRRslice(l int, msg []byte, off int) (dst1 []RR, off1 int, err error) { - var r RR - // Optimistically make dst be the length that was sent - dst := make([]RR, 0, l) - for i := 0; i < l; i++ { - off1 := off - r, off, err = UnpackRR(msg, off) - if err != nil { - off = len(msg) - break - } - // If offset does not increase anymore, l is a lie - if off1 == off { - l = i - break - } - dst = append(dst, r) - } - if err != nil && off == len(msg) { - dst = nil - } - return dst, off, err -} - -// Convert a MsgHdr to a string, with dig-like headers: -// -//;; opcode: QUERY, status: NOERROR, id: 48404 -// -//;; flags: qr aa rd ra; -func (h *MsgHdr) String() string { - if h == nil { - return "<nil> MsgHdr" - } - - s := ";; opcode: " + OpcodeToString[h.Opcode] - s += ", status: " + RcodeToString[h.Rcode] - s += ", id: " + strconv.Itoa(int(h.Id)) + "\n" - - s += ";; flags:" - if h.Response { - s += " qr" - } - if h.Authoritative { - s += " aa" - } - if h.Truncated { - s += " tc" - } - if h.RecursionDesired { - s += " rd" - } - if h.RecursionAvailable { - s += " ra" - } - if h.Zero { // Hmm - s += " z" - } - if h.AuthenticatedData { - s += " ad" - } - if h.CheckingDisabled { - s += " cd" - } - - s += ";" - return s -} - -// Pack packs a Msg: it is converted to to wire format. -// If the dns.Compress is true the message will be in compressed wire format. -func (dns *Msg) Pack() (msg []byte, err error) { - return dns.PackBuffer(nil) -} - -// PackBuffer packs a Msg, using the given buffer buf. If buf is too small -// a new buffer is allocated. -func (dns *Msg) PackBuffer(buf []byte) (msg []byte, err error) { - // We use a similar function in tsig.go's stripTsig. - var ( - dh Header - compression map[string]int - ) - - if dns.Compress { - compression = make(map[string]int) // Compression pointer mappings - } - - if dns.Rcode < 0 || dns.Rcode > 0xFFF { - return nil, ErrRcode - } - if dns.Rcode > 0xF { - // Regular RCODE field is 4 bits - opt := dns.IsEdns0() - if opt == nil { - return nil, ErrExtendedRcode - } - opt.SetExtendedRcode(uint8(dns.Rcode >> 4)) - dns.Rcode &= 0xF - } - - // Convert convenient Msg into wire-like Header. - dh.Id = dns.Id - dh.Bits = uint16(dns.Opcode)<<11 | uint16(dns.Rcode) - if dns.Response { - dh.Bits |= _QR - } - if dns.Authoritative { - dh.Bits |= _AA - } - if dns.Truncated { - dh.Bits |= _TC - } - if dns.RecursionDesired { - dh.Bits |= _RD - } - if dns.RecursionAvailable { - dh.Bits |= _RA - } - if dns.Zero { - dh.Bits |= _Z - } - if dns.AuthenticatedData { - dh.Bits |= _AD - } - if dns.CheckingDisabled { - dh.Bits |= _CD - } - - // Prepare variable sized arrays. - question := dns.Question - answer := dns.Answer - ns := dns.Ns - extra := dns.Extra - - dh.Qdcount = uint16(len(question)) - dh.Ancount = uint16(len(answer)) - dh.Nscount = uint16(len(ns)) - dh.Arcount = uint16(len(extra)) - - // We need the uncompressed length here, because we first pack it and then compress it. - msg = buf - uncompressedLen := compressedLen(dns, false) - if packLen := uncompressedLen + 1; len(msg) < packLen { - msg = make([]byte, packLen) - } - - // Pack it in: header and then the pieces. - off := 0 - off, err = dh.pack(msg, off, compression, dns.Compress) - if err != nil { - return nil, err - } - for i := 0; i < len(question); i++ { - off, err = question[i].pack(msg, off, compression, dns.Compress) - if err != nil { - return nil, err - } - } - for i := 0; i < len(answer); i++ { - off, err = PackRR(answer[i], msg, off, compression, dns.Compress) - if err != nil { - return nil, err - } - } - for i := 0; i < len(ns); i++ { - off, err = PackRR(ns[i], msg, off, compression, dns.Compress) - if err != nil { - return nil, err - } - } - for i := 0; i < len(extra); i++ { - off, err = PackRR(extra[i], msg, off, compression, dns.Compress) - if err != nil { - return nil, err - } - } - return msg[:off], nil -} - -// Unpack unpacks a binary message to a Msg structure. -func (dns *Msg) Unpack(msg []byte) (err error) { - var ( - dh Header - off int - ) - if dh, off, err = unpackMsgHdr(msg, off); err != nil { - return err - } - - dns.Id = dh.Id - dns.Response = (dh.Bits & _QR) != 0 - dns.Opcode = int(dh.Bits>>11) & 0xF - dns.Authoritative = (dh.Bits & _AA) != 0 - dns.Truncated = (dh.Bits & _TC) != 0 - dns.RecursionDesired = (dh.Bits & _RD) != 0 - dns.RecursionAvailable = (dh.Bits & _RA) != 0 - dns.Zero = (dh.Bits & _Z) != 0 - dns.AuthenticatedData = (dh.Bits & _AD) != 0 - dns.CheckingDisabled = (dh.Bits & _CD) != 0 - dns.Rcode = int(dh.Bits & 0xF) - - if off == len(msg) { - return ErrTruncated - } - - // Optimistically use the count given to us in the header - dns.Question = make([]Question, 0, int(dh.Qdcount)) - - for i := 0; i < int(dh.Qdcount); i++ { - off1 := off - var q Question - q, off, err = unpackQuestion(msg, off) - if err != nil { - // Even if Truncated is set, we only will set ErrTruncated if we - // actually got the questions - return err - } - if off1 == off { // Offset does not increase anymore, dh.Qdcount is a lie! - dh.Qdcount = uint16(i) - break - } - dns.Question = append(dns.Question, q) - } - - dns.Answer, off, err = unpackRRslice(int(dh.Ancount), msg, off) - // The header counts might have been wrong so we need to update it - dh.Ancount = uint16(len(dns.Answer)) - if err == nil { - dns.Ns, off, err = unpackRRslice(int(dh.Nscount), msg, off) - } - // The header counts might have been wrong so we need to update it - dh.Nscount = uint16(len(dns.Ns)) - if err == nil { - dns.Extra, off, err = unpackRRslice(int(dh.Arcount), msg, off) - } - // The header counts might have been wrong so we need to update it - dh.Arcount = uint16(len(dns.Extra)) - - if off != len(msg) { - // TODO(miek) make this an error? - // use PackOpt to let people tell how detailed the error reporting should be? - // println("dns: extra bytes in dns packet", off, "<", len(msg)) - } else if dns.Truncated { - // Whether we ran into a an error or not, we want to return that it - // was truncated - err = ErrTruncated - } - return err -} - -// Convert a complete message to a string with dig-like output. -func (dns *Msg) String() string { - if dns == nil { - return "<nil> MsgHdr" - } - s := dns.MsgHdr.String() + " " - s += "QUERY: " + strconv.Itoa(len(dns.Question)) + ", " - s += "ANSWER: " + strconv.Itoa(len(dns.Answer)) + ", " - s += "AUTHORITY: " + strconv.Itoa(len(dns.Ns)) + ", " - s += "ADDITIONAL: " + strconv.Itoa(len(dns.Extra)) + "\n" - if len(dns.Question) > 0 { - s += "\n;; QUESTION SECTION:\n" - for i := 0; i < len(dns.Question); i++ { - s += dns.Question[i].String() + "\n" - } - } - if len(dns.Answer) > 0 { - s += "\n;; ANSWER SECTION:\n" - for i := 0; i < len(dns.Answer); i++ { - if dns.Answer[i] != nil { - s += dns.Answer[i].String() + "\n" - } - } - } - if len(dns.Ns) > 0 { - s += "\n;; AUTHORITY SECTION:\n" - for i := 0; i < len(dns.Ns); i++ { - if dns.Ns[i] != nil { - s += dns.Ns[i].String() + "\n" - } - } - } - if len(dns.Extra) > 0 { - s += "\n;; ADDITIONAL SECTION:\n" - for i := 0; i < len(dns.Extra); i++ { - if dns.Extra[i] != nil { - s += dns.Extra[i].String() + "\n" - } - } - } - return s -} - -// Len returns the message length when in (un)compressed wire format. -// If dns.Compress is true compression it is taken into account. Len() -// is provided to be a faster way to get the size of the resulting packet, -// than packing it, measuring the size and discarding the buffer. -func (dns *Msg) Len() int { return compressedLen(dns, dns.Compress) } - -// compressedLen returns the message length when in compressed wire format -// when compress is true, otherwise the uncompressed length is returned. -func compressedLen(dns *Msg, compress bool) int { - // We always return one more than needed. - l := 12 // Message header is always 12 bytes - compression := map[string]int{} - - for i := 0; i < len(dns.Question); i++ { - l += dns.Question[i].len() - if compress { - compressionLenHelper(compression, dns.Question[i].Name) - } - } - for i := 0; i < len(dns.Answer); i++ { - if dns.Answer[i] == nil { - continue - } - l += dns.Answer[i].len() - if compress { - k, ok := compressionLenSearch(compression, dns.Answer[i].Header().Name) - if ok { - l += 1 - k - } - compressionLenHelper(compression, dns.Answer[i].Header().Name) - k, ok = compressionLenSearchType(compression, dns.Answer[i]) - if ok { - l += 1 - k - } - compressionLenHelperType(compression, dns.Answer[i]) - } - } - for i := 0; i < len(dns.Ns); i++ { - if dns.Ns[i] == nil { - continue - } - l += dns.Ns[i].len() - if compress { - k, ok := compressionLenSearch(compression, dns.Ns[i].Header().Name) - if ok { - l += 1 - k - } - compressionLenHelper(compression, dns.Ns[i].Header().Name) - k, ok = compressionLenSearchType(compression, dns.Ns[i]) - if ok { - l += 1 - k - } - compressionLenHelperType(compression, dns.Ns[i]) - } - } - for i := 0; i < len(dns.Extra); i++ { - if dns.Extra[i] == nil { - continue - } - l += dns.Extra[i].len() - if compress { - k, ok := compressionLenSearch(compression, dns.Extra[i].Header().Name) - if ok { - l += 1 - k - } - compressionLenHelper(compression, dns.Extra[i].Header().Name) - k, ok = compressionLenSearchType(compression, dns.Extra[i]) - if ok { - l += 1 - k - } - compressionLenHelperType(compression, dns.Extra[i]) - } - } - return l -} - -// Put the parts of the name in the compression map. -func compressionLenHelper(c map[string]int, s string) { - pref := "" - lbs := Split(s) - for j := len(lbs) - 1; j >= 0; j-- { - pref = s[lbs[j]:] - if _, ok := c[pref]; !ok { - c[pref] = len(pref) - } - } -} - -// Look for each part in the compression map and returns its length, -// keep on searching so we get the longest match. -func compressionLenSearch(c map[string]int, s string) (int, bool) { - off := 0 - end := false - if s == "" { // don't bork on bogus data - return 0, false - } - for { - if _, ok := c[s[off:]]; ok { - return len(s[off:]), true - } - if end { - break - } - off, end = NextLabel(s, off) - } - return 0, false -} - -// Copy returns a new RR which is a deep-copy of r. -func Copy(r RR) RR { r1 := r.copy(); return r1 } - -// Len returns the length (in octets) of the uncompressed RR in wire format. -func Len(r RR) int { return r.len() } - -// Copy returns a new *Msg which is a deep-copy of dns. -func (dns *Msg) Copy() *Msg { return dns.CopyTo(new(Msg)) } - -// CopyTo copies the contents to the provided message using a deep-copy and returns the copy. -func (dns *Msg) CopyTo(r1 *Msg) *Msg { - r1.MsgHdr = dns.MsgHdr - r1.Compress = dns.Compress - - if len(dns.Question) > 0 { - r1.Question = make([]Question, len(dns.Question)) - copy(r1.Question, dns.Question) // TODO(miek): Question is an immutable value, ok to do a shallow-copy - } - - rrArr := make([]RR, len(dns.Answer)+len(dns.Ns)+len(dns.Extra)) - var rri int - - if len(dns.Answer) > 0 { - rrbegin := rri - for i := 0; i < len(dns.Answer); i++ { - rrArr[rri] = dns.Answer[i].copy() - rri++ - } - r1.Answer = rrArr[rrbegin:rri:rri] - } - - if len(dns.Ns) > 0 { - rrbegin := rri - for i := 0; i < len(dns.Ns); i++ { - rrArr[rri] = dns.Ns[i].copy() - rri++ - } - r1.Ns = rrArr[rrbegin:rri:rri] - } - - if len(dns.Extra) > 0 { - rrbegin := rri - for i := 0; i < len(dns.Extra); i++ { - rrArr[rri] = dns.Extra[i].copy() - rri++ - } - r1.Extra = rrArr[rrbegin:rri:rri] - } - - return r1 -} - -func (q *Question) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := PackDomainName(q.Name, msg, off, compression, compress) - if err != nil { - return off, err - } - off, err = packUint16(q.Qtype, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(q.Qclass, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func unpackQuestion(msg []byte, off int) (Question, int, error) { - var ( - q Question - err error - ) - q.Name, off, err = UnpackDomainName(msg, off) - if err != nil { - return q, off, err - } - if off == len(msg) { - return q, off, nil - } - q.Qtype, off, err = unpackUint16(msg, off) - if err != nil { - return q, off, err - } - if off == len(msg) { - return q, off, nil - } - q.Qclass, off, err = unpackUint16(msg, off) - if off == len(msg) { - return q, off, nil - } - return q, off, err -} - -func (dh *Header) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := packUint16(dh.Id, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(dh.Bits, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(dh.Qdcount, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(dh.Ancount, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(dh.Nscount, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(dh.Arcount, msg, off) - return off, err -} - -func unpackMsgHdr(msg []byte, off int) (Header, int, error) { - var ( - dh Header - err error - ) - dh.Id, off, err = unpackUint16(msg, off) - if err != nil { - return dh, off, err - } - dh.Bits, off, err = unpackUint16(msg, off) - if err != nil { - return dh, off, err - } - dh.Qdcount, off, err = unpackUint16(msg, off) - if err != nil { - return dh, off, err - } - dh.Ancount, off, err = unpackUint16(msg, off) - if err != nil { - return dh, off, err - } - dh.Nscount, off, err = unpackUint16(msg, off) - if err != nil { - return dh, off, err - } - dh.Arcount, off, err = unpackUint16(msg, off) - return dh, off, err -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/msg_generate.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/msg_generate.go deleted file mode 100644 index 4d9f81d43..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/msg_generate.go +++ /dev/null @@ -1,349 +0,0 @@ -//+build ignore - -// msg_generate.go is meant to run with go generate. It will use -// go/{importer,types} to track down all the RR struct types. Then for each type -// it will generate pack/unpack methods based on the struct tags. The generated source is -// written to zmsg.go, and is meant to be checked into git. -package main - -import ( - "bytes" - "fmt" - "go/format" - "go/importer" - "go/types" - "log" - "os" - "strings" -) - -var packageHdr = ` -// *** DO NOT MODIFY *** -// AUTOGENERATED BY go generate from msg_generate.go - -package dns - -` - -// getTypeStruct will take a type and the package scope, and return the -// (innermost) struct if the type is considered a RR type (currently defined as -// those structs beginning with a RR_Header, could be redefined as implementing -// the RR interface). The bool return value indicates if embedded structs were -// resolved. -func getTypeStruct(t types.Type, scope *types.Scope) (*types.Struct, bool) { - st, ok := t.Underlying().(*types.Struct) - if !ok { - return nil, false - } - if st.Field(0).Type() == scope.Lookup("RR_Header").Type() { - return st, false - } - if st.Field(0).Anonymous() { - st, _ := getTypeStruct(st.Field(0).Type(), scope) - return st, true - } - return nil, false -} - -func main() { - // Import and type-check the package - pkg, err := importer.Default().Import("github.com/miekg/dns") - fatalIfErr(err) - scope := pkg.Scope() - - // Collect actual types (*X) - var namedTypes []string - for _, name := range scope.Names() { - o := scope.Lookup(name) - if o == nil || !o.Exported() { - continue - } - if st, _ := getTypeStruct(o.Type(), scope); st == nil { - continue - } - if name == "PrivateRR" { - continue - } - - // Check if corresponding TypeX exists - if scope.Lookup("Type"+o.Name()) == nil && o.Name() != "RFC3597" { - log.Fatalf("Constant Type%s does not exist.", o.Name()) - } - - namedTypes = append(namedTypes, o.Name()) - } - - b := &bytes.Buffer{} - b.WriteString(packageHdr) - - fmt.Fprint(b, "// pack*() functions\n\n") - for _, name := range namedTypes { - o := scope.Lookup(name) - st, _ := getTypeStruct(o.Type(), scope) - - fmt.Fprintf(b, "func (rr *%s) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {\n", name) - fmt.Fprint(b, `off, err := rr.Hdr.pack(msg, off, compression, compress) -if err != nil { - return off, err -} -headerEnd := off -`) - for i := 1; i < st.NumFields(); i++ { - o := func(s string) { - fmt.Fprintf(b, s, st.Field(i).Name()) - fmt.Fprint(b, `if err != nil { -return off, err -} -`) - } - - if _, ok := st.Field(i).Type().(*types.Slice); ok { - switch st.Tag(i) { - case `dns:"-"`: // ignored - case `dns:"txt"`: - o("off, err = packStringTxt(rr.%s, msg, off)\n") - case `dns:"opt"`: - o("off, err = packDataOpt(rr.%s, msg, off)\n") - case `dns:"nsec"`: - o("off, err = packDataNsec(rr.%s, msg, off)\n") - case `dns:"domain-name"`: - o("off, err = packDataDomainNames(rr.%s, msg, off, compression, compress)\n") - default: - log.Fatalln(name, st.Field(i).Name(), st.Tag(i)) - } - continue - } - - switch { - case st.Tag(i) == `dns:"-"`: // ignored - case st.Tag(i) == `dns:"cdomain-name"`: - o("off, err = PackDomainName(rr.%s, msg, off, compression, compress)\n") - case st.Tag(i) == `dns:"domain-name"`: - o("off, err = PackDomainName(rr.%s, msg, off, compression, false)\n") - case st.Tag(i) == `dns:"a"`: - o("off, err = packDataA(rr.%s, msg, off)\n") - case st.Tag(i) == `dns:"aaaa"`: - o("off, err = packDataAAAA(rr.%s, msg, off)\n") - case st.Tag(i) == `dns:"uint48"`: - o("off, err = packUint48(rr.%s, msg, off)\n") - case st.Tag(i) == `dns:"txt"`: - o("off, err = packString(rr.%s, msg, off)\n") - - case strings.HasPrefix(st.Tag(i), `dns:"size-base32`): // size-base32 can be packed just like base32 - fallthrough - case st.Tag(i) == `dns:"base32"`: - o("off, err = packStringBase32(rr.%s, msg, off)\n") - - case strings.HasPrefix(st.Tag(i), `dns:"size-base64`): // size-base64 can be packed just like base64 - fallthrough - case st.Tag(i) == `dns:"base64"`: - o("off, err = packStringBase64(rr.%s, msg, off)\n") - - case strings.HasPrefix(st.Tag(i), `dns:"size-hex:SaltLength`): - // directly write instead of using o() so we get the error check in the correct place - field := st.Field(i).Name() - fmt.Fprintf(b, `// Only pack salt if value is not "-", i.e. empty -if rr.%s != "-" { - off, err = packStringHex(rr.%s, msg, off) - if err != nil { - return off, err - } -} -`, field, field) - continue - case strings.HasPrefix(st.Tag(i), `dns:"size-hex`): // size-hex can be packed just like hex - fallthrough - case st.Tag(i) == `dns:"hex"`: - o("off, err = packStringHex(rr.%s, msg, off)\n") - - case st.Tag(i) == `dns:"octet"`: - o("off, err = packStringOctet(rr.%s, msg, off)\n") - case st.Tag(i) == "": - switch st.Field(i).Type().(*types.Basic).Kind() { - case types.Uint8: - o("off, err = packUint8(rr.%s, msg, off)\n") - case types.Uint16: - o("off, err = packUint16(rr.%s, msg, off)\n") - case types.Uint32: - o("off, err = packUint32(rr.%s, msg, off)\n") - case types.Uint64: - o("off, err = packUint64(rr.%s, msg, off)\n") - case types.String: - o("off, err = packString(rr.%s, msg, off)\n") - default: - log.Fatalln(name, st.Field(i).Name()) - } - default: - log.Fatalln(name, st.Field(i).Name(), st.Tag(i)) - } - } - // We have packed everything, only now we know the rdlength of this RR - fmt.Fprintln(b, "rr.Header().Rdlength = uint16(off-headerEnd)") - fmt.Fprintln(b, "return off, nil }\n") - } - - fmt.Fprint(b, "// unpack*() functions\n\n") - for _, name := range namedTypes { - o := scope.Lookup(name) - st, _ := getTypeStruct(o.Type(), scope) - - fmt.Fprintf(b, "func unpack%s(h RR_Header, msg []byte, off int) (RR, int, error) {\n", name) - fmt.Fprintf(b, "rr := new(%s)\n", name) - fmt.Fprint(b, "rr.Hdr = h\n") - fmt.Fprint(b, `if noRdata(h) { -return rr, off, nil - } -var err error -rdStart := off -_ = rdStart - -`) - for i := 1; i < st.NumFields(); i++ { - o := func(s string) { - fmt.Fprintf(b, s, st.Field(i).Name()) - fmt.Fprint(b, `if err != nil { -return rr, off, err -} -`) - } - - // size-* are special, because they reference a struct member we should use for the length. - if strings.HasPrefix(st.Tag(i), `dns:"size-`) { - structMember := structMember(st.Tag(i)) - structTag := structTag(st.Tag(i)) - switch structTag { - case "hex": - fmt.Fprintf(b, "rr.%s, off, err = unpackStringHex(msg, off, off + int(rr.%s))\n", st.Field(i).Name(), structMember) - case "base32": - fmt.Fprintf(b, "rr.%s, off, err = unpackStringBase32(msg, off, off + int(rr.%s))\n", st.Field(i).Name(), structMember) - case "base64": - fmt.Fprintf(b, "rr.%s, off, err = unpackStringBase64(msg, off, off + int(rr.%s))\n", st.Field(i).Name(), structMember) - default: - log.Fatalln(name, st.Field(i).Name(), st.Tag(i)) - } - fmt.Fprint(b, `if err != nil { -return rr, off, err -} -`) - continue - } - - if _, ok := st.Field(i).Type().(*types.Slice); ok { - switch st.Tag(i) { - case `dns:"-"`: // ignored - case `dns:"txt"`: - o("rr.%s, off, err = unpackStringTxt(msg, off)\n") - case `dns:"opt"`: - o("rr.%s, off, err = unpackDataOpt(msg, off)\n") - case `dns:"nsec"`: - o("rr.%s, off, err = unpackDataNsec(msg, off)\n") - case `dns:"domain-name"`: - o("rr.%s, off, err = unpackDataDomainNames(msg, off, rdStart + int(rr.Hdr.Rdlength))\n") - default: - log.Fatalln(name, st.Field(i).Name(), st.Tag(i)) - } - continue - } - - switch st.Tag(i) { - case `dns:"-"`: // ignored - case `dns:"cdomain-name"`: - fallthrough - case `dns:"domain-name"`: - o("rr.%s, off, err = UnpackDomainName(msg, off)\n") - case `dns:"a"`: - o("rr.%s, off, err = unpackDataA(msg, off)\n") - case `dns:"aaaa"`: - o("rr.%s, off, err = unpackDataAAAA(msg, off)\n") - case `dns:"uint48"`: - o("rr.%s, off, err = unpackUint48(msg, off)\n") - case `dns:"txt"`: - o("rr.%s, off, err = unpackString(msg, off)\n") - case `dns:"base32"`: - o("rr.%s, off, err = unpackStringBase32(msg, off, rdStart + int(rr.Hdr.Rdlength))\n") - case `dns:"base64"`: - o("rr.%s, off, err = unpackStringBase64(msg, off, rdStart + int(rr.Hdr.Rdlength))\n") - case `dns:"hex"`: - o("rr.%s, off, err = unpackStringHex(msg, off, rdStart + int(rr.Hdr.Rdlength))\n") - case `dns:"octet"`: - o("rr.%s, off, err = unpackStringOctet(msg, off)\n") - case "": - switch st.Field(i).Type().(*types.Basic).Kind() { - case types.Uint8: - o("rr.%s, off, err = unpackUint8(msg, off)\n") - case types.Uint16: - o("rr.%s, off, err = unpackUint16(msg, off)\n") - case types.Uint32: - o("rr.%s, off, err = unpackUint32(msg, off)\n") - case types.Uint64: - o("rr.%s, off, err = unpackUint64(msg, off)\n") - case types.String: - o("rr.%s, off, err = unpackString(msg, off)\n") - default: - log.Fatalln(name, st.Field(i).Name()) - } - default: - log.Fatalln(name, st.Field(i).Name(), st.Tag(i)) - } - // If we've hit len(msg) we return without error. - if i < st.NumFields()-1 { - fmt.Fprintf(b, `if off == len(msg) { -return rr, off, nil - } -`) - } - } - fmt.Fprintf(b, "return rr, off, err }\n\n") - } - // Generate typeToUnpack map - fmt.Fprintln(b, "var typeToUnpack = map[uint16]func(RR_Header, []byte, int) (RR, int, error){") - for _, name := range namedTypes { - if name == "RFC3597" { - continue - } - fmt.Fprintf(b, "Type%s: unpack%s,\n", name, name) - } - fmt.Fprintln(b, "}\n") - - // gofmt - res, err := format.Source(b.Bytes()) - if err != nil { - b.WriteTo(os.Stderr) - log.Fatal(err) - } - - // write result - f, err := os.Create("zmsg.go") - fatalIfErr(err) - defer f.Close() - f.Write(res) -} - -// structMember will take a tag like dns:"size-base32:SaltLength" and return the last part of this string. -func structMember(s string) string { - fields := strings.Split(s, ":") - if len(fields) == 0 { - return "" - } - f := fields[len(fields)-1] - // f should have a closing " - if len(f) > 1 { - return f[:len(f)-1] - } - return f -} - -// structTag will take a tag like dns:"size-base32:SaltLength" and return base32. -func structTag(s string) string { - fields := strings.Split(s, ":") - if len(fields) < 2 { - return "" - } - return fields[1][len("\"size-"):] -} - -func fatalIfErr(err error) { - if err != nil { - log.Fatal(err) - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/msg_helpers.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/msg_helpers.go deleted file mode 100644 index 615274ab0..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/msg_helpers.go +++ /dev/null @@ -1,633 +0,0 @@ -package dns - -import ( - "encoding/base32" - "encoding/base64" - "encoding/binary" - "encoding/hex" - "net" - "strconv" -) - -// helper functions called from the generated zmsg.go - -// These function are named after the tag to help pack/unpack, if there is no tag it is the name -// of the type they pack/unpack (string, int, etc). We prefix all with unpackData or packData, so packDataA or -// packDataDomainName. - -func unpackDataA(msg []byte, off int) (net.IP, int, error) { - if off+net.IPv4len > len(msg) { - return nil, len(msg), &Error{err: "overflow unpacking a"} - } - a := append(make(net.IP, 0, net.IPv4len), msg[off:off+net.IPv4len]...) - off += net.IPv4len - return a, off, nil -} - -func packDataA(a net.IP, msg []byte, off int) (int, error) { - // It must be a slice of 4, even if it is 16, we encode only the first 4 - if off+net.IPv4len > len(msg) { - return len(msg), &Error{err: "overflow packing a"} - } - switch len(a) { - case net.IPv4len, net.IPv6len: - copy(msg[off:], a.To4()) - off += net.IPv4len - case 0: - // Allowed, for dynamic updates. - default: - return len(msg), &Error{err: "overflow packing a"} - } - return off, nil -} - -func unpackDataAAAA(msg []byte, off int) (net.IP, int, error) { - if off+net.IPv6len > len(msg) { - return nil, len(msg), &Error{err: "overflow unpacking aaaa"} - } - aaaa := append(make(net.IP, 0, net.IPv6len), msg[off:off+net.IPv6len]...) - off += net.IPv6len - return aaaa, off, nil -} - -func packDataAAAA(aaaa net.IP, msg []byte, off int) (int, error) { - if off+net.IPv6len > len(msg) { - return len(msg), &Error{err: "overflow packing aaaa"} - } - - switch len(aaaa) { - case net.IPv6len: - copy(msg[off:], aaaa) - off += net.IPv6len - case 0: - // Allowed, dynamic updates. - default: - return len(msg), &Error{err: "overflow packing aaaa"} - } - return off, nil -} - -// unpackHeader unpacks an RR header, returning the offset to the end of the header and a -// re-sliced msg according to the expected length of the RR. -func unpackHeader(msg []byte, off int) (rr RR_Header, off1 int, truncmsg []byte, err error) { - hdr := RR_Header{} - if off == len(msg) { - return hdr, off, msg, nil - } - - hdr.Name, off, err = UnpackDomainName(msg, off) - if err != nil { - return hdr, len(msg), msg, err - } - hdr.Rrtype, off, err = unpackUint16(msg, off) - if err != nil { - return hdr, len(msg), msg, err - } - hdr.Class, off, err = unpackUint16(msg, off) - if err != nil { - return hdr, len(msg), msg, err - } - hdr.Ttl, off, err = unpackUint32(msg, off) - if err != nil { - return hdr, len(msg), msg, err - } - hdr.Rdlength, off, err = unpackUint16(msg, off) - if err != nil { - return hdr, len(msg), msg, err - } - msg, err = truncateMsgFromRdlength(msg, off, hdr.Rdlength) - return hdr, off, msg, nil -} - -// pack packs an RR header, returning the offset to the end of the header. -// See PackDomainName for documentation about the compression. -func (hdr RR_Header) pack(msg []byte, off int, compression map[string]int, compress bool) (off1 int, err error) { - if off == len(msg) { - return off, nil - } - - off, err = PackDomainName(hdr.Name, msg, off, compression, compress) - if err != nil { - return len(msg), err - } - off, err = packUint16(hdr.Rrtype, msg, off) - if err != nil { - return len(msg), err - } - off, err = packUint16(hdr.Class, msg, off) - if err != nil { - return len(msg), err - } - off, err = packUint32(hdr.Ttl, msg, off) - if err != nil { - return len(msg), err - } - off, err = packUint16(hdr.Rdlength, msg, off) - if err != nil { - return len(msg), err - } - return off, nil -} - -// helper helper functions. - -// truncateMsgFromRdLength truncates msg to match the expected length of the RR. -// Returns an error if msg is smaller than the expected size. -func truncateMsgFromRdlength(msg []byte, off int, rdlength uint16) (truncmsg []byte, err error) { - lenrd := off + int(rdlength) - if lenrd > len(msg) { - return msg, &Error{err: "overflowing header size"} - } - return msg[:lenrd], nil -} - -func fromBase32(s []byte) (buf []byte, err error) { - for i, b := range s { - if b >= 'a' && b <= 'z' { - s[i] = b - 32 - } - } - buflen := base32.HexEncoding.DecodedLen(len(s)) - buf = make([]byte, buflen) - n, err := base32.HexEncoding.Decode(buf, s) - buf = buf[:n] - return -} - -func toBase32(b []byte) string { return base32.HexEncoding.EncodeToString(b) } - -func fromBase64(s []byte) (buf []byte, err error) { - buflen := base64.StdEncoding.DecodedLen(len(s)) - buf = make([]byte, buflen) - n, err := base64.StdEncoding.Decode(buf, s) - buf = buf[:n] - return -} - -func toBase64(b []byte) string { return base64.StdEncoding.EncodeToString(b) } - -// dynamicUpdate returns true if the Rdlength is zero. -func noRdata(h RR_Header) bool { return h.Rdlength == 0 } - -func unpackUint8(msg []byte, off int) (i uint8, off1 int, err error) { - if off+1 > len(msg) { - return 0, len(msg), &Error{err: "overflow unpacking uint8"} - } - return uint8(msg[off]), off + 1, nil -} - -func packUint8(i uint8, msg []byte, off int) (off1 int, err error) { - if off+1 > len(msg) { - return len(msg), &Error{err: "overflow packing uint8"} - } - msg[off] = byte(i) - return off + 1, nil -} - -func unpackUint16(msg []byte, off int) (i uint16, off1 int, err error) { - if off+2 > len(msg) { - return 0, len(msg), &Error{err: "overflow unpacking uint16"} - } - return binary.BigEndian.Uint16(msg[off:]), off + 2, nil -} - -func packUint16(i uint16, msg []byte, off int) (off1 int, err error) { - if off+2 > len(msg) { - return len(msg), &Error{err: "overflow packing uint16"} - } - binary.BigEndian.PutUint16(msg[off:], i) - return off + 2, nil -} - -func unpackUint32(msg []byte, off int) (i uint32, off1 int, err error) { - if off+4 > len(msg) { - return 0, len(msg), &Error{err: "overflow unpacking uint32"} - } - return binary.BigEndian.Uint32(msg[off:]), off + 4, nil -} - -func packUint32(i uint32, msg []byte, off int) (off1 int, err error) { - if off+4 > len(msg) { - return len(msg), &Error{err: "overflow packing uint32"} - } - binary.BigEndian.PutUint32(msg[off:], i) - return off + 4, nil -} - -func unpackUint48(msg []byte, off int) (i uint64, off1 int, err error) { - if off+6 > len(msg) { - return 0, len(msg), &Error{err: "overflow unpacking uint64 as uint48"} - } - // Used in TSIG where the last 48 bits are occupied, so for now, assume a uint48 (6 bytes) - i = (uint64(uint64(msg[off])<<40 | uint64(msg[off+1])<<32 | uint64(msg[off+2])<<24 | uint64(msg[off+3])<<16 | - uint64(msg[off+4])<<8 | uint64(msg[off+5]))) - off += 6 - return i, off, nil -} - -func packUint48(i uint64, msg []byte, off int) (off1 int, err error) { - if off+6 > len(msg) { - return len(msg), &Error{err: "overflow packing uint64 as uint48"} - } - msg[off] = byte(i >> 40) - msg[off+1] = byte(i >> 32) - msg[off+2] = byte(i >> 24) - msg[off+3] = byte(i >> 16) - msg[off+4] = byte(i >> 8) - msg[off+5] = byte(i) - off += 6 - return off, nil -} - -func unpackUint64(msg []byte, off int) (i uint64, off1 int, err error) { - if off+8 > len(msg) { - return 0, len(msg), &Error{err: "overflow unpacking uint64"} - } - return binary.BigEndian.Uint64(msg[off:]), off + 8, nil -} - -func packUint64(i uint64, msg []byte, off int) (off1 int, err error) { - if off+8 > len(msg) { - return len(msg), &Error{err: "overflow packing uint64"} - } - binary.BigEndian.PutUint64(msg[off:], i) - off += 8 - return off, nil -} - -func unpackString(msg []byte, off int) (string, int, error) { - if off+1 > len(msg) { - return "", off, &Error{err: "overflow unpacking txt"} - } - l := int(msg[off]) - if off+l+1 > len(msg) { - return "", off, &Error{err: "overflow unpacking txt"} - } - s := make([]byte, 0, l) - for _, b := range msg[off+1 : off+1+l] { - switch b { - case '"', '\\': - s = append(s, '\\', b) - default: - if b < 32 || b > 127 { // unprintable - var buf [3]byte - bufs := strconv.AppendInt(buf[:0], int64(b), 10) - s = append(s, '\\') - for i := 0; i < 3-len(bufs); i++ { - s = append(s, '0') - } - for _, r := range bufs { - s = append(s, r) - } - } else { - s = append(s, b) - } - } - } - off += 1 + l - return string(s), off, nil -} - -func packString(s string, msg []byte, off int) (int, error) { - txtTmp := make([]byte, 256*4+1) - off, err := packTxtString(s, msg, off, txtTmp) - if err != nil { - return len(msg), err - } - return off, nil -} - -func unpackStringBase32(msg []byte, off, end int) (string, int, error) { - if end > len(msg) { - return "", len(msg), &Error{err: "overflow unpacking base32"} - } - s := toBase32(msg[off:end]) - return s, end, nil -} - -func packStringBase32(s string, msg []byte, off int) (int, error) { - b32, err := fromBase32([]byte(s)) - if err != nil { - return len(msg), err - } - if off+len(b32) > len(msg) { - return len(msg), &Error{err: "overflow packing base32"} - } - copy(msg[off:off+len(b32)], b32) - off += len(b32) - return off, nil -} - -func unpackStringBase64(msg []byte, off, end int) (string, int, error) { - // Rest of the RR is base64 encoded value, so we don't need an explicit length - // to be set. Thus far all RR's that have base64 encoded fields have those as their - // last one. What we do need is the end of the RR! - if end > len(msg) { - return "", len(msg), &Error{err: "overflow unpacking base64"} - } - s := toBase64(msg[off:end]) - return s, end, nil -} - -func packStringBase64(s string, msg []byte, off int) (int, error) { - b64, err := fromBase64([]byte(s)) - if err != nil { - return len(msg), err - } - if off+len(b64) > len(msg) { - return len(msg), &Error{err: "overflow packing base64"} - } - copy(msg[off:off+len(b64)], b64) - off += len(b64) - return off, nil -} - -func unpackStringHex(msg []byte, off, end int) (string, int, error) { - // Rest of the RR is hex encoded value, so we don't need an explicit length - // to be set. NSEC and TSIG have hex fields with a length field. - // What we do need is the end of the RR! - if end > len(msg) { - return "", len(msg), &Error{err: "overflow unpacking hex"} - } - - s := hex.EncodeToString(msg[off:end]) - return s, end, nil -} - -func packStringHex(s string, msg []byte, off int) (int, error) { - h, err := hex.DecodeString(s) - if err != nil { - return len(msg), err - } - if off+(len(h)) > len(msg) { - return len(msg), &Error{err: "overflow packing hex"} - } - copy(msg[off:off+len(h)], h) - off += len(h) - return off, nil -} - -func unpackStringTxt(msg []byte, off int) ([]string, int, error) { - txt, off, err := unpackTxt(msg, off) - if err != nil { - return nil, len(msg), err - } - return txt, off, nil -} - -func packStringTxt(s []string, msg []byte, off int) (int, error) { - txtTmp := make([]byte, 256*4+1) // If the whole string consists out of \DDD we need this many. - off, err := packTxt(s, msg, off, txtTmp) - if err != nil { - return len(msg), err - } - return off, nil -} - -func unpackDataOpt(msg []byte, off int) ([]EDNS0, int, error) { - var edns []EDNS0 -Option: - code := uint16(0) - if off+4 > len(msg) { - return nil, len(msg), &Error{err: "overflow unpacking opt"} - } - code = binary.BigEndian.Uint16(msg[off:]) - off += 2 - optlen := binary.BigEndian.Uint16(msg[off:]) - off += 2 - if off+int(optlen) > len(msg) { - return nil, len(msg), &Error{err: "overflow unpacking opt"} - } - switch code { - case EDNS0NSID: - e := new(EDNS0_NSID) - if err := e.unpack(msg[off : off+int(optlen)]); err != nil { - return nil, len(msg), err - } - edns = append(edns, e) - off += int(optlen) - case EDNS0SUBNET, EDNS0SUBNETDRAFT: - e := new(EDNS0_SUBNET) - if err := e.unpack(msg[off : off+int(optlen)]); err != nil { - return nil, len(msg), err - } - edns = append(edns, e) - off += int(optlen) - if code == EDNS0SUBNETDRAFT { - e.DraftOption = true - } - case EDNS0COOKIE: - e := new(EDNS0_COOKIE) - if err := e.unpack(msg[off : off+int(optlen)]); err != nil { - return nil, len(msg), err - } - edns = append(edns, e) - off += int(optlen) - case EDNS0UL: - e := new(EDNS0_UL) - if err := e.unpack(msg[off : off+int(optlen)]); err != nil { - return nil, len(msg), err - } - edns = append(edns, e) - off += int(optlen) - case EDNS0LLQ: - e := new(EDNS0_LLQ) - if err := e.unpack(msg[off : off+int(optlen)]); err != nil { - return nil, len(msg), err - } - edns = append(edns, e) - off += int(optlen) - case EDNS0DAU: - e := new(EDNS0_DAU) - if err := e.unpack(msg[off : off+int(optlen)]); err != nil { - return nil, len(msg), err - } - edns = append(edns, e) - off += int(optlen) - case EDNS0DHU: - e := new(EDNS0_DHU) - if err := e.unpack(msg[off : off+int(optlen)]); err != nil { - return nil, len(msg), err - } - edns = append(edns, e) - off += int(optlen) - case EDNS0N3U: - e := new(EDNS0_N3U) - if err := e.unpack(msg[off : off+int(optlen)]); err != nil { - return nil, len(msg), err - } - edns = append(edns, e) - off += int(optlen) - default: - e := new(EDNS0_LOCAL) - e.Code = code - if err := e.unpack(msg[off : off+int(optlen)]); err != nil { - return nil, len(msg), err - } - edns = append(edns, e) - off += int(optlen) - } - - if off < len(msg) { - goto Option - } - - return edns, off, nil -} - -func packDataOpt(options []EDNS0, msg []byte, off int) (int, error) { - for _, el := range options { - b, err := el.pack() - if err != nil || off+3 > len(msg) { - return len(msg), &Error{err: "overflow packing opt"} - } - binary.BigEndian.PutUint16(msg[off:], el.Option()) // Option code - binary.BigEndian.PutUint16(msg[off+2:], uint16(len(b))) // Length - off += 4 - if off+len(b) > len(msg) { - copy(msg[off:], b) - off = len(msg) - continue - } - // Actual data - copy(msg[off:off+len(b)], b) - off += len(b) - } - return off, nil -} - -func unpackStringOctet(msg []byte, off int) (string, int, error) { - s := string(msg[off:]) - return s, len(msg), nil -} - -func packStringOctet(s string, msg []byte, off int) (int, error) { - txtTmp := make([]byte, 256*4+1) - off, err := packOctetString(s, msg, off, txtTmp) - if err != nil { - return len(msg), err - } - return off, nil -} - -func unpackDataNsec(msg []byte, off int) ([]uint16, int, error) { - var nsec []uint16 - length, window, lastwindow := 0, 0, -1 - for off < len(msg) { - if off+2 > len(msg) { - return nsec, len(msg), &Error{err: "overflow unpacking nsecx"} - } - window = int(msg[off]) - length = int(msg[off+1]) - off += 2 - if window <= lastwindow { - // RFC 4034: Blocks are present in the NSEC RR RDATA in - // increasing numerical order. - return nsec, len(msg), &Error{err: "out of order NSEC block"} - } - if length == 0 { - // RFC 4034: Blocks with no types present MUST NOT be included. - return nsec, len(msg), &Error{err: "empty NSEC block"} - } - if length > 32 { - return nsec, len(msg), &Error{err: "NSEC block too long"} - } - if off+length > len(msg) { - return nsec, len(msg), &Error{err: "overflowing NSEC block"} - } - - // Walk the bytes in the window and extract the type bits - for j := 0; j < length; j++ { - b := msg[off+j] - // Check the bits one by one, and set the type - if b&0x80 == 0x80 { - nsec = append(nsec, uint16(window*256+j*8+0)) - } - if b&0x40 == 0x40 { - nsec = append(nsec, uint16(window*256+j*8+1)) - } - if b&0x20 == 0x20 { - nsec = append(nsec, uint16(window*256+j*8+2)) - } - if b&0x10 == 0x10 { - nsec = append(nsec, uint16(window*256+j*8+3)) - } - if b&0x8 == 0x8 { - nsec = append(nsec, uint16(window*256+j*8+4)) - } - if b&0x4 == 0x4 { - nsec = append(nsec, uint16(window*256+j*8+5)) - } - if b&0x2 == 0x2 { - nsec = append(nsec, uint16(window*256+j*8+6)) - } - if b&0x1 == 0x1 { - nsec = append(nsec, uint16(window*256+j*8+7)) - } - } - off += length - lastwindow = window - } - return nsec, off, nil -} - -func packDataNsec(bitmap []uint16, msg []byte, off int) (int, error) { - if len(bitmap) == 0 { - return off, nil - } - var lastwindow, lastlength uint16 - for j := 0; j < len(bitmap); j++ { - t := bitmap[j] - window := t / 256 - length := (t-window*256)/8 + 1 - if window > lastwindow && lastlength != 0 { // New window, jump to the new offset - off += int(lastlength) + 2 - lastlength = 0 - } - if window < lastwindow || length < lastlength { - return len(msg), &Error{err: "nsec bits out of order"} - } - if off+2+int(length) > len(msg) { - return len(msg), &Error{err: "overflow packing nsec"} - } - // Setting the window # - msg[off] = byte(window) - // Setting the octets length - msg[off+1] = byte(length) - // Setting the bit value for the type in the right octet - msg[off+1+int(length)] |= byte(1 << (7 - (t % 8))) - lastwindow, lastlength = window, length - } - off += int(lastlength) + 2 - return off, nil -} - -func unpackDataDomainNames(msg []byte, off, end int) ([]string, int, error) { - var ( - servers []string - s string - err error - ) - if end > len(msg) { - return nil, len(msg), &Error{err: "overflow unpacking domain names"} - } - for off < end { - s, off, err = UnpackDomainName(msg, off) - if err != nil { - return servers, len(msg), err - } - servers = append(servers, s) - } - return servers, off, nil -} - -func packDataDomainNames(names []string, msg []byte, off int, compression map[string]int, compress bool) (int, error) { - var err error - for j := 0; j < len(names); j++ { - off, err = PackDomainName(names[j], msg, off, compression, false && compress) - if err != nil { - return len(msg), err - } - } - return off, nil -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/msg_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/msg_test.go deleted file mode 100644 index 2dbef6260..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/msg_test.go +++ /dev/null @@ -1,124 +0,0 @@ -package dns - -import ( - "fmt" - "regexp" - "strconv" - "strings" - "testing" -) - -const ( - maxPrintableLabel = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789x" - tooLongLabel = maxPrintableLabel + "x" -) - -var ( - longDomain = maxPrintableLabel[:53] + strings.TrimSuffix( - strings.Join([]string{".", ".", ".", ".", "."}, maxPrintableLabel[:49]), ".") - reChar = regexp.MustCompile(`.`) - i = -1 - maxUnprintableLabel = reChar.ReplaceAllStringFunc(maxPrintableLabel, func(ch string) string { - if i++; i >= 32 { - i = 0 - } - return fmt.Sprintf("\\%03d", i) - }) -) - -func TestUnpackDomainName(t *testing.T) { - var cases = []struct { - label string - input string - expectedOutput string - expectedError string - }{ - {"empty domain", - "\x00", - ".", - ""}, - {"long label", - string(63) + maxPrintableLabel + "\x00", - maxPrintableLabel + ".", - ""}, - {"unprintable label", - string(63) + regexp.MustCompile(`\\[0-9]+`).ReplaceAllStringFunc(maxUnprintableLabel, - func(escape string) string { - n, _ := strconv.ParseInt(escape[1:], 10, 8) - return string(n) - }) + "\x00", - maxUnprintableLabel + ".", - ""}, - {"long domain", - string(53) + strings.Replace(longDomain, ".", string(49), -1) + "\x00", - longDomain + ".", - ""}, - {"compression pointer", - // an unrealistic but functional test referencing an offset _inside_ a label - "\x03foo" + "\x05\x03com\x00" + "\x07example" + "\xC0\x05", - "foo.\\003com\\000.example.com.", - ""}, - - {"too long domain", - string(54) + "x" + strings.Replace(longDomain, ".", string(49), -1) + "\x00", - "x" + longDomain + ".", - ErrLongDomain.Error()}, - {"too long by pointer", - // a matryoshka doll name to get over 255 octets after expansion via internal pointers - string([]byte{ - // 11 length values, first to last - 40, 37, 34, 31, 28, 25, 22, 19, 16, 13, 0, - // 12 filler values - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - // 10 pointers, last to first - 192, 10, 192, 9, 192, 8, 192, 7, 192, 6, 192, 5, 192, 4, 192, 3, 192, 2, 192, 1, - }), - "", - ErrLongDomain.Error()}, - {"long by pointer", - // a matryoshka doll name _not_ exceeding 255 octets after expansion - string([]byte{ - // 11 length values, first to last - 37, 34, 31, 28, 25, 22, 19, 16, 13, 10, 0, - // 9 filler values - 120, 120, 120, 120, 120, 120, 120, 120, 120, - // 10 pointers, last to first - 192, 10, 192, 9, 192, 8, 192, 7, 192, 6, 192, 5, 192, 4, 192, 3, 192, 2, 192, 1, - }), - "" + - (`\"\031\028\025\022\019\016\013\010\000xxxxxxxxx` + - `\192\010\192\009\192\008\192\007\192\006\192\005\192\004\192\003\192\002.`) + - (`\031\028\025\022\019\016\013\010\000xxxxxxxxx` + - `\192\010\192\009\192\008\192\007\192\006\192\005\192\004\192\003.`) + - (`\028\025\022\019\016\013\010\000xxxxxxxxx` + - `\192\010\192\009\192\008\192\007\192\006\192\005\192\004.`) + - (`\025\022\019\016\013\010\000xxxxxxxxx` + - `\192\010\192\009\192\008\192\007\192\006\192\005.`) + - `\022\019\016\013\010\000xxxxxxxxx\192\010\192\009\192\008\192\007\192\006.` + - `\019\016\013\010\000xxxxxxxxx\192\010\192\009\192\008\192\007.` + - `\016\013\010\000xxxxxxxxx\192\010\192\009\192\008.` + - `\013\010\000xxxxxxxxx\192\010\192\009.` + - `\010\000xxxxxxxxx\192\010.` + - `\000xxxxxxxxx.`, - ""}, - {"truncated name", "\x07example\x03", "", "dns: buffer size too small"}, - {"non-absolute name", "\x07example\x03com", "", "dns: buffer size too small"}, - {"compression pointer cycle", - "\x03foo" + "\x03bar" + "\x07example" + "\xC0\x04", - "", - "dns: too many compression pointers"}, - {"reserved compression pointer 0b10", "\x07example\x80", "", "dns: bad rdata"}, - {"reserved compression pointer 0b01", "\x07example\x40", "", "dns: bad rdata"}, - } - for _, test := range cases { - output, idx, err := UnpackDomainName([]byte(test.input), 0) - if test.expectedOutput != "" && output != test.expectedOutput { - t.Errorf("%s: expected %s, got %s", test.label, test.expectedOutput, output) - } - if test.expectedError == "" && err != nil { - t.Errorf("%s: expected no error, got %d %v", test.label, idx, err) - } else if test.expectedError != "" && (err == nil || err.Error() != test.expectedError) { - t.Errorf("%s: expected error %s, got %d %v", test.label, test.expectedError, idx, err) - } - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/nsecx.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/nsecx.go deleted file mode 100644 index 9b908c447..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/nsecx.go +++ /dev/null @@ -1,106 +0,0 @@ -package dns - -import ( - "crypto/sha1" - "hash" - "strings" -) - -type saltWireFmt struct { - Salt string `dns:"size-hex"` -} - -// HashName hashes a string (label) according to RFC 5155. It returns the hashed string in uppercase. -func HashName(label string, ha uint8, iter uint16, salt string) string { - saltwire := new(saltWireFmt) - saltwire.Salt = salt - wire := make([]byte, DefaultMsgSize) - n, err := packSaltWire(saltwire, wire) - if err != nil { - return "" - } - wire = wire[:n] - name := make([]byte, 255) - off, err := PackDomainName(strings.ToLower(label), name, 0, nil, false) - if err != nil { - return "" - } - name = name[:off] - var s hash.Hash - switch ha { - case SHA1: - s = sha1.New() - default: - return "" - } - - // k = 0 - s.Write(name) - s.Write(wire) - nsec3 := s.Sum(nil) - // k > 0 - for k := uint16(0); k < iter; k++ { - s.Reset() - s.Write(nsec3) - s.Write(wire) - nsec3 = s.Sum(nsec3[:0]) - } - return toBase32(nsec3) -} - -// Cover returns true if a name is covered by the NSEC3 record -func (rr *NSEC3) Cover(name string) bool { - nameHash := HashName(name, rr.Hash, rr.Iterations, rr.Salt) - owner := strings.ToUpper(rr.Hdr.Name) - labelIndices := Split(owner) - if len(labelIndices) < 2 { - return false - } - ownerHash := owner[:labelIndices[1]-1] - ownerZone := owner[labelIndices[1]:] - if !IsSubDomain(ownerZone, strings.ToUpper(name)) { // name is outside owner zone - return false - } - - nextHash := rr.NextDomain - if ownerHash == nextHash { // empty interval - return false - } - if ownerHash > nextHash { // end of zone - if nameHash > ownerHash { // covered since there is nothing after ownerHash - return true - } - return nameHash < nextHash // if nameHash is before beginning of zone it is covered - } - if nameHash < ownerHash { // nameHash is before ownerHash, not covered - return false - } - return nameHash < nextHash // if nameHash is before nextHash is it covered (between ownerHash and nextHash) -} - -// Match returns true if a name matches the NSEC3 record -func (rr *NSEC3) Match(name string) bool { - nameHash := HashName(name, rr.Hash, rr.Iterations, rr.Salt) - owner := strings.ToUpper(rr.Hdr.Name) - labelIndices := Split(owner) - if len(labelIndices) < 2 { - return false - } - ownerHash := owner[:labelIndices[1]-1] - ownerZone := owner[labelIndices[1]:] - if !IsSubDomain(ownerZone, strings.ToUpper(name)) { // name is outside owner zone - return false - } - if ownerHash == nameHash { - return true - } - return false -} - -func packSaltWire(sw *saltWireFmt, msg []byte) (int, error) { - off, err := packStringHex(sw.Salt, msg, 0) - if err != nil { - return off, err - } - return off, nil -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/nsecx_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/nsecx_test.go deleted file mode 100644 index 8d5f71797..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/nsecx_test.go +++ /dev/null @@ -1,133 +0,0 @@ -package dns - -import "testing" - -func TestPackNsec3(t *testing.T) { - nsec3 := HashName("dnsex.nl.", SHA1, 0, "DEAD") - if nsec3 != "ROCCJAE8BJJU7HN6T7NG3TNM8ACRS87J" { - t.Error(nsec3) - } - - nsec3 = HashName("a.b.c.example.org.", SHA1, 2, "DEAD") - if nsec3 != "6LQ07OAHBTOOEU2R9ANI2AT70K5O0RCG" { - t.Error(nsec3) - } -} - -func TestNsec3(t *testing.T) { - nsec3, _ := NewRR("sk4e8fj94u78smusb40o1n0oltbblu2r.nl. IN NSEC3 1 1 5 F10E9F7EA83FC8F3 SK4F38CQ0ATIEI8MH3RGD0P5I4II6QAN NS SOA TXT RRSIG DNSKEY NSEC3PARAM") - if !nsec3.(*NSEC3).Match("nl.") { // name hash = sk4e8fj94u78smusb40o1n0oltbblu2r - t.Fatal("sk4e8fj94u78smusb40o1n0oltbblu2r.nl. should match sk4e8fj94u78smusb40o1n0oltbblu2r.nl.") - } - if !nsec3.(*NSEC3).Match("NL.") { // name hash = sk4e8fj94u78smusb40o1n0oltbblu2r - t.Fatal("sk4e8fj94u78smusb40o1n0oltbblu2r.NL. should match sk4e8fj94u78smusb40o1n0oltbblu2r.nl.") - } - if nsec3.(*NSEC3).Match("com.") { // - t.Fatal("com. is not in the zone nl.") - } - if nsec3.(*NSEC3).Match("test.nl.") { // name hash = gd0ptr5bnfpimpu2d3v6gd4n0bai7s0q - t.Fatal("gd0ptr5bnfpimpu2d3v6gd4n0bai7s0q.nl. should not match sk4e8fj94u78smusb40o1n0oltbblu2r.nl.") - } - nsec3, _ = NewRR("nl. IN NSEC3 1 1 5 F10E9F7EA83FC8F3 SK4F38CQ0ATIEI8MH3RGD0P5I4II6QAN NS SOA TXT RRSIG DNSKEY NSEC3PARAM") - if nsec3.(*NSEC3).Match("nl.") { - t.Fatal("sk4e8fj94u78smusb40o1n0oltbblu2r.nl. should not match a record without a owner hash") - } - - for _, tc := range []struct { - rr *NSEC3 - name string - covers bool - }{ - // positive tests - { // name hash between owner hash and next hash - rr: &NSEC3{ - Hdr: RR_Header{Name: "2N1TB3VAIRUOBL6RKDVII42N9TFMIALP.com."}, - Hash: 1, - Flags: 1, - Iterations: 5, - Salt: "F10E9F7EA83FC8F3", - NextDomain: "PT3RON8N7PM3A0OE989IB84OOSADP7O8", - }, - name: "bsd.com.", - covers: true, - }, - { // end of zone, name hash is after owner hash - rr: &NSEC3{ - Hdr: RR_Header{Name: "3v62ulr0nre83v0rja2vjgtlif9v6rab.com."}, - Hash: 1, - Flags: 1, - Iterations: 5, - Salt: "F10E9F7EA83FC8F3", - NextDomain: "2N1TB3VAIRUOBL6RKDVII42N9TFMIALP", - }, - name: "csd.com.", - covers: true, - }, - { // end of zone, name hash is before beginning of zone - rr: &NSEC3{ - Hdr: RR_Header{Name: "PT3RON8N7PM3A0OE989IB84OOSADP7O8.com."}, - Hash: 1, - Flags: 1, - Iterations: 5, - Salt: "F10E9F7EA83FC8F3", - NextDomain: "3V62ULR0NRE83V0RJA2VJGTLIF9V6RAB", - }, - name: "asd.com.", - covers: true, - }, - // negative tests - { // too short owner name - rr: &NSEC3{ - Hdr: RR_Header{Name: "nl."}, - Hash: 1, - Flags: 1, - Iterations: 5, - Salt: "F10E9F7EA83FC8F3", - NextDomain: "39P99DCGG0MDLARTCRMCF6OFLLUL7PR6", - }, - name: "asd.com.", - covers: false, - }, - { // outside of zone - rr: &NSEC3{ - Hdr: RR_Header{Name: "39p91242oslggest5e6a7cci4iaeqvnk.nl."}, - Hash: 1, - Flags: 1, - Iterations: 5, - Salt: "F10E9F7EA83FC8F3", - NextDomain: "39P99DCGG0MDLARTCRMCF6OFLLUL7PR6", - }, - name: "asd.com.", - covers: false, - }, - { // empty interval - rr: &NSEC3{ - Hdr: RR_Header{Name: "2n1tb3vairuobl6rkdvii42n9tfmialp.com."}, - Hash: 1, - Flags: 1, - Iterations: 5, - Salt: "F10E9F7EA83FC8F3", - NextDomain: "2N1TB3VAIRUOBL6RKDVII42N9TFMIALP", - }, - name: "asd.com.", - covers: false, - }, - { // name hash is before owner hash, not covered - rr: &NSEC3{ - Hdr: RR_Header{Name: "3V62ULR0NRE83V0RJA2VJGTLIF9V6RAB.com."}, - Hash: 1, - Flags: 1, - Iterations: 5, - Salt: "F10E9F7EA83FC8F3", - NextDomain: "PT3RON8N7PM3A0OE989IB84OOSADP7O8", - }, - name: "asd.com.", - covers: false, - }, - } { - covers := tc.rr.Cover(tc.name) - if tc.covers != covers { - t.Fatalf("Cover failed for %s: expected %t, got %t [record: %s]", tc.name, tc.covers, covers, tc.rr) - } - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/parse_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/parse_test.go deleted file mode 100644 index fc5bdaf5d..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/parse_test.go +++ /dev/null @@ -1,1540 +0,0 @@ -package dns - -import ( - "bytes" - "crypto/rsa" - "encoding/hex" - "fmt" - "math/rand" - "net" - "reflect" - "strconv" - "strings" - "testing" - "testing/quick" - "time" -) - -func TestDotInName(t *testing.T) { - buf := make([]byte, 20) - PackDomainName("aa\\.bb.nl.", buf, 0, nil, false) - // index 3 must be a real dot - if buf[3] != '.' { - t.Error("dot should be a real dot") - } - - if buf[6] != 2 { - t.Error("this must have the value 2") - } - dom, _, _ := UnpackDomainName(buf, 0) - // printing it should yield the backspace again - if dom != "aa\\.bb.nl." { - t.Error("dot should have been escaped: ", dom) - } -} - -func TestDotLastInLabel(t *testing.T) { - sample := "aa\\..au." - buf := make([]byte, 20) - _, err := PackDomainName(sample, buf, 0, nil, false) - if err != nil { - t.Fatalf("unexpected error packing domain: %v", err) - } - dom, _, _ := UnpackDomainName(buf, 0) - if dom != sample { - t.Fatalf("unpacked domain `%s' doesn't match packed domain", dom) - } -} - -func TestTooLongDomainName(t *testing.T) { - l := "aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrsssttt." - dom := l + l + l + l + l + l + l - _, err := NewRR(dom + " IN A 127.0.0.1") - if err == nil { - t.Error("should be too long") - } else { - t.Logf("error is %v", err) - } - _, err = NewRR("..com. IN A 127.0.0.1") - if err == nil { - t.Error("should fail") - } else { - t.Logf("error is %v", err) - } -} - -func TestDomainName(t *testing.T) { - tests := []string{"r\\.gieben.miek.nl.", "www\\.www.miek.nl.", - "www.*.miek.nl.", "www.*.miek.nl.", - } - dbuff := make([]byte, 40) - - for _, ts := range tests { - if _, err := PackDomainName(ts, dbuff, 0, nil, false); err != nil { - t.Error("not a valid domain name") - continue - } - n, _, err := UnpackDomainName(dbuff, 0) - if err != nil { - t.Error("failed to unpack packed domain name") - continue - } - if ts != n { - t.Errorf("must be equal: in: %s, out: %s", ts, n) - } - } -} - -func TestDomainNameAndTXTEscapes(t *testing.T) { - tests := []byte{'.', '(', ')', ';', ' ', '@', '"', '\\', 9, 13, 10, 0, 255} - for _, b := range tests { - rrbytes := []byte{ - 1, b, 0, // owner - byte(TypeTXT >> 8), byte(TypeTXT), - byte(ClassINET >> 8), byte(ClassINET), - 0, 0, 0, 1, // TTL - 0, 2, 1, b, // Data - } - rr1, _, err := UnpackRR(rrbytes, 0) - if err != nil { - panic(err) - } - s := rr1.String() - rr2, err := NewRR(s) - if err != nil { - t.Errorf("Error parsing unpacked RR's string: %v", err) - t.Errorf(" Bytes: %v", rrbytes) - t.Errorf("String: %v", s) - } - repacked := make([]byte, len(rrbytes)) - if _, err := PackRR(rr2, repacked, 0, nil, false); err != nil { - t.Errorf("error packing parsed RR: %v", err) - t.Errorf(" original Bytes: %v", rrbytes) - t.Errorf("unpacked Struct: %v", rr1) - t.Errorf(" parsed Struct: %v", rr2) - } - if !bytes.Equal(repacked, rrbytes) { - t.Error("packed bytes don't match original bytes") - t.Errorf(" original bytes: %v", rrbytes) - t.Errorf(" packed bytes: %v", repacked) - t.Errorf("unpacked struct: %v", rr1) - t.Errorf(" parsed struct: %v", rr2) - } - } -} - -func TestTXTEscapeParsing(t *testing.T) { - test := [][]string{ - {`";"`, `";"`}, - {`\;`, `";"`}, - {`"\t"`, `"t"`}, - {`"\r"`, `"r"`}, - {`"\ "`, `" "`}, - {`"\;"`, `";"`}, - {`"\;\""`, `";\""`}, - {`"\(a\)"`, `"(a)"`}, - {`"\(a)"`, `"(a)"`}, - {`"(a\)"`, `"(a)"`}, - {`"(a)"`, `"(a)"`}, - {`"\048"`, `"0"`}, - {`"\` + "\t" + `"`, `"\009"`}, - {`"\` + "\n" + `"`, `"\010"`}, - {`"\` + "\r" + `"`, `"\013"`}, - {`"\` + "\x11" + `"`, `"\017"`}, - {`"\'"`, `"'"`}, - } - for _, s := range test { - rr, err := NewRR(fmt.Sprintf("example.com. IN TXT %v", s[0])) - if err != nil { - t.Errorf("could not parse %v TXT: %s", s[0], err) - continue - } - - txt := sprintTxt(rr.(*TXT).Txt) - if txt != s[1] { - t.Errorf("mismatch after parsing `%v` TXT record: `%v` != `%v`", s[0], txt, s[1]) - } - } -} - -func GenerateDomain(r *rand.Rand, size int) []byte { - dnLen := size % 70 // artificially limit size so there's less to intrepret if a failure occurs - var dn []byte - done := false - for i := 0; i < dnLen && !done; { - max := dnLen - i - if max > 63 { - max = 63 - } - lLen := max - if lLen != 0 { - lLen = int(r.Int31()) % max - } - done = lLen == 0 - if done { - continue - } - l := make([]byte, lLen+1) - l[0] = byte(lLen) - for j := 0; j < lLen; j++ { - l[j+1] = byte(rand.Int31()) - } - dn = append(dn, l...) - i += 1 + lLen - } - return append(dn, 0) -} - -func TestDomainQuick(t *testing.T) { - r := rand.New(rand.NewSource(0)) - f := func(l int) bool { - db := GenerateDomain(r, l) - ds, _, err := UnpackDomainName(db, 0) - if err != nil { - panic(err) - } - buf := make([]byte, 255) - off, err := PackDomainName(ds, buf, 0, nil, false) - if err != nil { - t.Errorf("error packing domain: %v", err) - t.Errorf(" bytes: %v", db) - t.Errorf("string: %v", ds) - return false - } - if !bytes.Equal(db, buf[:off]) { - t.Errorf("repacked domain doesn't match original:") - t.Errorf("src bytes: %v", db) - t.Errorf(" string: %v", ds) - t.Errorf("out bytes: %v", buf[:off]) - return false - } - return true - } - if err := quick.Check(f, nil); err != nil { - t.Error(err) - } -} - -func GenerateTXT(r *rand.Rand, size int) []byte { - rdLen := size % 300 // artificially limit size so there's less to intrepret if a failure occurs - var rd []byte - for i := 0; i < rdLen; { - max := rdLen - 1 - if max > 255 { - max = 255 - } - sLen := max - if max != 0 { - sLen = int(r.Int31()) % max - } - s := make([]byte, sLen+1) - s[0] = byte(sLen) - for j := 0; j < sLen; j++ { - s[j+1] = byte(rand.Int31()) - } - rd = append(rd, s...) - i += 1 + sLen - } - return rd -} - -// Ok, 2 things. 1) this test breaks with the new functionality of splitting up larger txt -// chunks into 255 byte pieces. 2) I don't like the random nature of this thing, because I can't -// place the quotes where they need to be. -// So either add some code the places the quotes in just the right spots, make this non random -// or do something else. -// Disabled for now. (miek) -func testTXTRRQuick(t *testing.T) { - s := rand.NewSource(0) - r := rand.New(s) - typeAndClass := []byte{ - byte(TypeTXT >> 8), byte(TypeTXT), - byte(ClassINET >> 8), byte(ClassINET), - 0, 0, 0, 1, // TTL - } - f := func(l int) bool { - owner := GenerateDomain(r, l) - rdata := GenerateTXT(r, l) - rrbytes := make([]byte, 0, len(owner)+2+2+4+2+len(rdata)) - rrbytes = append(rrbytes, owner...) - rrbytes = append(rrbytes, typeAndClass...) - rrbytes = append(rrbytes, byte(len(rdata)>>8)) - rrbytes = append(rrbytes, byte(len(rdata))) - rrbytes = append(rrbytes, rdata...) - rr, _, err := UnpackRR(rrbytes, 0) - if err != nil { - panic(err) - } - buf := make([]byte, len(rrbytes)*3) - off, err := PackRR(rr, buf, 0, nil, false) - if err != nil { - t.Errorf("pack Error: %v\nRR: %v", err, rr) - return false - } - buf = buf[:off] - if !bytes.Equal(buf, rrbytes) { - t.Errorf("packed bytes don't match original bytes") - t.Errorf("src bytes: %v", rrbytes) - t.Errorf(" struct: %v", rr) - t.Errorf("out bytes: %v", buf) - return false - } - if len(rdata) == 0 { - // string'ing won't produce any data to parse - return true - } - rrString := rr.String() - rr2, err := NewRR(rrString) - if err != nil { - t.Errorf("error parsing own output: %v", err) - t.Errorf("struct: %v", rr) - t.Errorf("string: %v", rrString) - return false - } - if rr2.String() != rrString { - t.Errorf("parsed rr.String() doesn't match original string") - t.Errorf("original: %v", rrString) - t.Errorf(" parsed: %v", rr2.String()) - return false - } - - buf = make([]byte, len(rrbytes)*3) - off, err = PackRR(rr2, buf, 0, nil, false) - if err != nil { - t.Errorf("error packing parsed rr: %v", err) - t.Errorf("unpacked Struct: %v", rr) - t.Errorf(" string: %v", rrString) - t.Errorf(" parsed Struct: %v", rr2) - return false - } - buf = buf[:off] - if !bytes.Equal(buf, rrbytes) { - t.Errorf("parsed packed bytes don't match original bytes") - t.Errorf(" source bytes: %v", rrbytes) - t.Errorf("unpacked struct: %v", rr) - t.Errorf(" string: %v", rrString) - t.Errorf(" parsed struct: %v", rr2) - t.Errorf(" repacked bytes: %v", buf) - return false - } - return true - } - c := &quick.Config{MaxCountScale: 10} - if err := quick.Check(f, c); err != nil { - t.Error(err) - } -} - -func TestParseDirectiveMisc(t *testing.T) { - tests := map[string]string{ - "$ORIGIN miek.nl.\na IN NS b": "a.miek.nl.\t3600\tIN\tNS\tb.miek.nl.", - "$TTL 2H\nmiek.nl. IN NS b.": "miek.nl.\t7200\tIN\tNS\tb.", - "miek.nl. 1D IN NS b.": "miek.nl.\t86400\tIN\tNS\tb.", - `name. IN SOA a6.nstld.com. hostmaster.nic.name. ( - 203362132 ; serial - 5m ; refresh (5 minutes) - 5m ; retry (5 minutes) - 2w ; expire (2 weeks) - 300 ; minimum (5 minutes) -)`: "name.\t3600\tIN\tSOA\ta6.nstld.com. hostmaster.nic.name. 203362132 300 300 1209600 300", - ". 3600000 IN NS ONE.MY-ROOTS.NET.": ".\t3600000\tIN\tNS\tONE.MY-ROOTS.NET.", - "ONE.MY-ROOTS.NET. 3600000 IN A 192.168.1.1": "ONE.MY-ROOTS.NET.\t3600000\tIN\tA\t192.168.1.1", - } - for i, o := range tests { - rr, err := NewRR(i) - if err != nil { - t.Error("failed to parse RR: ", err) - continue - } - if rr.String() != o { - t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String()) - } else { - t.Logf("RR is OK: `%s'", rr.String()) - } - } -} - -func TestNSEC(t *testing.T) { - nsectests := map[string]string{ - "nl. IN NSEC3PARAM 1 0 5 30923C44C6CBBB8F": "nl.\t3600\tIN\tNSEC3PARAM\t1 0 5 30923C44C6CBBB8F", - "p2209hipbpnm681knjnu0m1febshlv4e.nl. IN NSEC3 1 1 5 30923C44C6CBBB8F P90DG1KE8QEAN0B01613LHQDG0SOJ0TA NS SOA TXT RRSIG DNSKEY NSEC3PARAM": "p2209hipbpnm681knjnu0m1febshlv4e.nl.\t3600\tIN\tNSEC3\t1 1 5 30923C44C6CBBB8F P90DG1KE8QEAN0B01613LHQDG0SOJ0TA NS SOA TXT RRSIG DNSKEY NSEC3PARAM", - "localhost.dnssex.nl. IN NSEC www.dnssex.nl. A RRSIG NSEC": "localhost.dnssex.nl.\t3600\tIN\tNSEC\twww.dnssex.nl. A RRSIG NSEC", - "localhost.dnssex.nl. IN NSEC www.dnssex.nl. A RRSIG NSEC TYPE65534": "localhost.dnssex.nl.\t3600\tIN\tNSEC\twww.dnssex.nl. A RRSIG NSEC TYPE65534", - "localhost.dnssex.nl. IN NSEC www.dnssex.nl. A RRSIG NSec Type65534": "localhost.dnssex.nl.\t3600\tIN\tNSEC\twww.dnssex.nl. A RRSIG NSEC TYPE65534", - "44ohaq2njb0idnvolt9ggthvsk1e1uv8.skydns.test. NSEC3 1 0 0 - 44OHAQ2NJB0IDNVOLT9GGTHVSK1E1UVA": "44ohaq2njb0idnvolt9ggthvsk1e1uv8.skydns.test.\t3600\tIN\tNSEC3\t1 0 0 - 44OHAQ2NJB0IDNVOLT9GGTHVSK1E1UVA", - } - for i, o := range nsectests { - rr, err := NewRR(i) - if err != nil { - t.Error("failed to parse RR: ", err) - continue - } - if rr.String() != o { - t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String()) - } else { - t.Logf("RR is OK: `%s'", rr.String()) - } - } -} - -func TestParseLOC(t *testing.T) { - lt := map[string]string{ - "SW1A2AA.find.me.uk. LOC 51 30 12.748 N 00 07 39.611 W 0.00m 0.00m 0.00m 0.00m": "SW1A2AA.find.me.uk.\t3600\tIN\tLOC\t51 30 12.748 N 00 07 39.611 W 0m 0.00m 0.00m 0.00m", - "SW1A2AA.find.me.uk. LOC 51 0 0.0 N 00 07 39.611 W 0.00m 0.00m 0.00m 0.00m": "SW1A2AA.find.me.uk.\t3600\tIN\tLOC\t51 00 0.000 N 00 07 39.611 W 0m 0.00m 0.00m 0.00m", - } - for i, o := range lt { - rr, err := NewRR(i) - if err != nil { - t.Error("failed to parse RR: ", err) - continue - } - if rr.String() != o { - t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String()) - } else { - t.Logf("RR is OK: `%s'", rr.String()) - } - } -} - -func TestParseDS(t *testing.T) { - dt := map[string]string{ - "example.net. 3600 IN DS 40692 12 3 22261A8B0E0D799183E35E24E2AD6BB58533CBA7E3B14D659E9CA09B 2071398F": "example.net.\t3600\tIN\tDS\t40692 12 3 22261A8B0E0D799183E35E24E2AD6BB58533CBA7E3B14D659E9CA09B2071398F", - } - for i, o := range dt { - rr, err := NewRR(i) - if err != nil { - t.Error("failed to parse RR: ", err) - continue - } - if rr.String() != o { - t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String()) - } else { - t.Logf("RR is OK: `%s'", rr.String()) - } - } -} - -func TestQuotes(t *testing.T) { - tests := map[string]string{ - `t.example.com. IN TXT "a bc"`: "t.example.com.\t3600\tIN\tTXT\t\"a bc\"", - `t.example.com. IN TXT "a - bc"`: "t.example.com.\t3600\tIN\tTXT\t\"a\\010 bc\"", - `t.example.com. IN TXT ""`: "t.example.com.\t3600\tIN\tTXT\t\"\"", - `t.example.com. IN TXT "a"`: "t.example.com.\t3600\tIN\tTXT\t\"a\"", - `t.example.com. IN TXT "aa"`: "t.example.com.\t3600\tIN\tTXT\t\"aa\"", - `t.example.com. IN TXT "aaa" ;`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\"", - `t.example.com. IN TXT "abc" "DEF"`: "t.example.com.\t3600\tIN\tTXT\t\"abc\" \"DEF\"", - `t.example.com. IN TXT "abc" ( "DEF" )`: "t.example.com.\t3600\tIN\tTXT\t\"abc\" \"DEF\"", - `t.example.com. IN TXT aaa ;`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\"", - `t.example.com. IN TXT aaa aaa;`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\" \"aaa\"", - `t.example.com. IN TXT aaa aaa`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\" \"aaa\"", - `t.example.com. IN TXT aaa`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\"", - "cid.urn.arpa. NAPTR 100 50 \"s\" \"z3950+I2L+I2C\" \"\" _z3950._tcp.gatech.edu.": "cid.urn.arpa.\t3600\tIN\tNAPTR\t100 50 \"s\" \"z3950+I2L+I2C\" \"\" _z3950._tcp.gatech.edu.", - "cid.urn.arpa. NAPTR 100 50 \"s\" \"rcds+I2C\" \"\" _rcds._udp.gatech.edu.": "cid.urn.arpa.\t3600\tIN\tNAPTR\t100 50 \"s\" \"rcds+I2C\" \"\" _rcds._udp.gatech.edu.", - "cid.urn.arpa. NAPTR 100 50 \"s\" \"http+I2L+I2C+I2R\" \"\" _http._tcp.gatech.edu.": "cid.urn.arpa.\t3600\tIN\tNAPTR\t100 50 \"s\" \"http+I2L+I2C+I2R\" \"\" _http._tcp.gatech.edu.", - "cid.urn.arpa. NAPTR 100 10 \"\" \"\" \"/urn:cid:.+@([^\\.]+\\.)(.*)$/\\2/i\" .": "cid.urn.arpa.\t3600\tIN\tNAPTR\t100 10 \"\" \"\" \"/urn:cid:.+@([^\\.]+\\.)(.*)$/\\2/i\" .", - } - for i, o := range tests { - rr, err := NewRR(i) - if err != nil { - t.Error("failed to parse RR: ", err) - continue - } - if rr.String() != o { - t.Errorf("`%s' should be equal to\n`%s', but is\n`%s'", i, o, rr.String()) - } else { - t.Logf("RR is OK: `%s'", rr.String()) - } - } -} - -func TestParseClass(t *testing.T) { - tests := map[string]string{ - "t.example.com. IN A 127.0.0.1": "t.example.com. 3600 IN A 127.0.0.1", - "t.example.com. CS A 127.0.0.1": "t.example.com. 3600 CS A 127.0.0.1", - "t.example.com. CH A 127.0.0.1": "t.example.com. 3600 CH A 127.0.0.1", - // ClassANY can not occur in zone files - // "t.example.com. ANY A 127.0.0.1": "t.example.com. 3600 ANY A 127.0.0.1", - "t.example.com. NONE A 127.0.0.1": "t.example.com. 3600 NONE A 127.0.0.1", - } - for i, o := range tests { - rr, err := NewRR(i) - if err != nil { - t.Error("failed to parse RR: ", err) - continue - } - if rr.String() != o { - t.Errorf("`%s' should be equal to\n`%s', but is\n`%s'", i, o, rr.String()) - } else { - t.Logf("RR is OK: `%s'", rr.String()) - } - } -} - -func TestBrace(t *testing.T) { - tests := map[string]string{ - "(miek.nl.) 3600 IN A 127.0.1.1": "miek.nl.\t3600\tIN\tA\t127.0.1.1", - "miek.nl. (3600) IN MX (10) elektron.atoom.net.": "miek.nl.\t3600\tIN\tMX\t10 elektron.atoom.net.", - `miek.nl. IN ( - 3600 A 127.0.0.1)`: "miek.nl.\t3600\tIN\tA\t127.0.0.1", - "(miek.nl.) (A) (127.0.2.1)": "miek.nl.\t3600\tIN\tA\t127.0.2.1", - "miek.nl A 127.0.3.1": "miek.nl.\t3600\tIN\tA\t127.0.3.1", - "_ssh._tcp.local. 60 IN (PTR) stora._ssh._tcp.local.": "_ssh._tcp.local.\t60\tIN\tPTR\tstora._ssh._tcp.local.", - "miek.nl. NS ns.miek.nl": "miek.nl.\t3600\tIN\tNS\tns.miek.nl.", - `(miek.nl.) ( - (IN) - (AAAA) - (::1) )`: "miek.nl.\t3600\tIN\tAAAA\t::1", - `(miek.nl.) ( - (IN) - (AAAA) - (::1))`: "miek.nl.\t3600\tIN\tAAAA\t::1", - "miek.nl. IN AAAA ::2": "miek.nl.\t3600\tIN\tAAAA\t::2", - `((m)(i)ek.(n)l.) (SOA) (soa.) (soa.) ( - 2009032802 ; serial - 21600 ; refresh (6 hours) - 7(2)00 ; retry (2 hours) - 604()800 ; expire (1 week) - 3600 ; minimum (1 hour) - )`: "miek.nl.\t3600\tIN\tSOA\tsoa. soa. 2009032802 21600 7200 604800 3600", - "miek\\.nl. IN A 127.0.0.10": "miek\\.nl.\t3600\tIN\tA\t127.0.0.10", - "miek.nl. IN A 127.0.0.11": "miek.nl.\t3600\tIN\tA\t127.0.0.11", - "miek.nl. A 127.0.0.12": "miek.nl.\t3600\tIN\tA\t127.0.0.12", - `miek.nl. 86400 IN SOA elektron.atoom.net. miekg.atoom.net. ( - 2009032802 ; serial - 21600 ; refresh (6 hours) - 7200 ; retry (2 hours) - 604800 ; expire (1 week) - 3600 ; minimum (1 hour) - )`: "miek.nl.\t86400\tIN\tSOA\telektron.atoom.net. miekg.atoom.net. 2009032802 21600 7200 604800 3600", - } - for i, o := range tests { - rr, err := NewRR(i) - if err != nil { - t.Errorf("failed to parse RR: %v\n\t%s", err, i) - continue - } - if rr.String() != o { - t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String()) - } else { - t.Logf("RR is OK: `%s'", rr.String()) - } - } -} - -func TestParseFailure(t *testing.T) { - tests := []string{"miek.nl. IN A 327.0.0.1", - "miek.nl. IN AAAA ::x", - "miek.nl. IN MX a0 miek.nl.", - "miek.nl aap IN MX mx.miek.nl.", - "miek.nl 200 IN mxx 10 mx.miek.nl.", - "miek.nl. inn MX 10 mx.miek.nl.", - // "miek.nl. IN CNAME ", // actually valid nowadays, zero size rdata - "miek.nl. IN CNAME ..", - "miek.nl. PA MX 10 miek.nl.", - "miek.nl. ) IN MX 10 miek.nl.", - } - - for _, s := range tests { - _, err := NewRR(s) - if err == nil { - t.Errorf("should have triggered an error: \"%s\"", s) - } - } -} - -func TestZoneParsing(t *testing.T) { - // parse_test.db - db := ` -a.example.com. IN A 127.0.0.1 -8db7._openpgpkey.example.com. IN OPENPGPKEY mQCNAzIG -$ORIGIN a.example.com. -test IN A 127.0.0.1 - IN SSHFP 1 2 ( - BC6533CDC95A79078A39A56EA7635984ED655318ADA9 - B6159E30723665DA95BB ) -$ORIGIN b.example.com. -test IN CNAME test.a.example.com. -` - start := time.Now().UnixNano() - to := ParseZone(strings.NewReader(db), "", "parse_test.db") - var i int - for x := range to { - i++ - if x.Error != nil { - t.Error(x.Error) - continue - } - t.Log(x.RR) - } - delta := time.Now().UnixNano() - start - t.Logf("%d RRs parsed in %.2f s (%.2f RR/s)", i, float32(delta)/1e9, float32(i)/(float32(delta)/1e9)) -} - -func ExampleParseZone() { - zone := `$ORIGIN . -$TTL 3600 ; 1 hour -name IN SOA a6.nstld.com. hostmaster.nic.name. ( - 203362132 ; serial - 300 ; refresh (5 minutes) - 300 ; retry (5 minutes) - 1209600 ; expire (2 weeks) - 300 ; minimum (5 minutes) - ) -$TTL 10800 ; 3 hours -name. 10800 IN NS name. - IN NS g6.nstld.com. - 7200 NS h6.nstld.com. - 3600 IN NS j6.nstld.com. - IN 3600 NS k6.nstld.com. - NS l6.nstld.com. - NS a6.nstld.com. - NS c6.nstld.com. - NS d6.nstld.com. - NS f6.nstld.com. - NS m6.nstld.com. -( - NS m7.nstld.com. -) -$ORIGIN name. -0-0onlus NS ns7.ehiweb.it. - NS ns8.ehiweb.it. -0-g MX 10 mx01.nic - MX 10 mx02.nic - MX 10 mx03.nic - MX 10 mx04.nic -$ORIGIN 0-g.name -moutamassey NS ns01.yahoodomains.jp. - NS ns02.yahoodomains.jp. -` - to := ParseZone(strings.NewReader(zone), "", "testzone") - for x := range to { - fmt.Println(x.RR) - } - // Output: - // name. 3600 IN SOA a6.nstld.com. hostmaster.nic.name. 203362132 300 300 1209600 300 - // name. 10800 IN NS name. - // name. 10800 IN NS g6.nstld.com. - // name. 7200 IN NS h6.nstld.com. - // name. 3600 IN NS j6.nstld.com. - // name. 3600 IN NS k6.nstld.com. - // name. 10800 IN NS l6.nstld.com. - // name. 10800 IN NS a6.nstld.com. - // name. 10800 IN NS c6.nstld.com. - // name. 10800 IN NS d6.nstld.com. - // name. 10800 IN NS f6.nstld.com. - // name. 10800 IN NS m6.nstld.com. - // name. 10800 IN NS m7.nstld.com. - // 0-0onlus.name. 10800 IN NS ns7.ehiweb.it. - // 0-0onlus.name. 10800 IN NS ns8.ehiweb.it. - // 0-g.name. 10800 IN MX 10 mx01.nic.name. - // 0-g.name. 10800 IN MX 10 mx02.nic.name. - // 0-g.name. 10800 IN MX 10 mx03.nic.name. - // 0-g.name. 10800 IN MX 10 mx04.nic.name. - // moutamassey.0-g.name.name. 10800 IN NS ns01.yahoodomains.jp. - // moutamassey.0-g.name.name. 10800 IN NS ns02.yahoodomains.jp. -} - -func ExampleHIP() { - h := `www.example.com IN HIP ( 2 200100107B1A74DF365639CC39F1D578 - AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p -9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQ -b1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D - rvs.example.com. )` - if hip, err := NewRR(h); err == nil { - fmt.Println(hip.String()) - } - // Output: - // www.example.com. 3600 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs.example.com. -} - -func TestHIP(t *testing.T) { - h := `www.example.com. IN HIP ( 2 200100107B1A74DF365639CC39F1D578 - AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p -9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQ -b1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D - rvs1.example.com. - rvs2.example.com. )` - rr, err := NewRR(h) - if err != nil { - t.Fatalf("failed to parse RR: %v", err) - } - t.Logf("RR: %s", rr) - msg := new(Msg) - msg.Answer = []RR{rr, rr} - bytes, err := msg.Pack() - if err != nil { - t.Fatalf("failed to pack msg: %v", err) - } - if err := msg.Unpack(bytes); err != nil { - t.Fatalf("failed to unpack msg: %v", err) - } - if len(msg.Answer) != 2 { - t.Fatalf("2 answers expected: %v", msg) - } - for i, rr := range msg.Answer { - rr := rr.(*HIP) - t.Logf("RR: %s", rr) - if l := len(rr.RendezvousServers); l != 2 { - t.Fatalf("2 servers expected, only %d in record %d:\n%v", l, i, msg) - } - for j, s := range []string{"rvs1.example.com.", "rvs2.example.com."} { - if rr.RendezvousServers[j] != s { - t.Fatalf("expected server %d of record %d to be %s:\n%v", j, i, s, msg) - } - } - } -} - -func ExampleSOA() { - s := "example.com. 1000 SOA master.example.com. admin.example.com. 1 4294967294 4294967293 4294967295 100" - if soa, err := NewRR(s); err == nil { - fmt.Println(soa.String()) - } - // Output: - // example.com. 1000 IN SOA master.example.com. admin.example.com. 1 4294967294 4294967293 4294967295 100 -} - -func TestLineNumberError(t *testing.T) { - s := "example.com. 1000 SOA master.example.com. admin.example.com. monkey 4294967294 4294967293 4294967295 100" - if _, err := NewRR(s); err != nil { - if err.Error() != "dns: bad SOA zone parameter: \"monkey\" at line: 1:68" { - t.Error("not expecting this error: ", err) - } - } -} - -// Test with no known RR on the line -func TestLineNumberError2(t *testing.T) { - tests := map[string]string{ - "example.com. 1000 SO master.example.com. admin.example.com. 1 4294967294 4294967293 4294967295 100": "dns: expecting RR type or class, not this...: \"SO\" at line: 1:21", - "example.com 1000 IN TALINK a.example.com. b..example.com.": "dns: bad TALINK NextName: \"b..example.com.\" at line: 1:57", - "example.com 1000 IN TALINK ( a.example.com. b..example.com. )": "dns: bad TALINK NextName: \"b..example.com.\" at line: 1:60", - `example.com 1000 IN TALINK ( a.example.com. - bb..example.com. )`: "dns: bad TALINK NextName: \"bb..example.com.\" at line: 2:18", - // This is a bug, it should report an error on line 1, but the new is already processed. - `example.com 1000 IN TALINK ( a.example.com. b...example.com. - )`: "dns: bad TALINK NextName: \"b...example.com.\" at line: 2:1"} - - for in, errStr := range tests { - _, err := NewRR(in) - if err == nil { - t.Error("err is nil") - } else { - if err.Error() != errStr { - t.Errorf("%s: error should be %s is %v", in, errStr, err) - } - } - } -} - -// Test if the calculations are correct -func TestRfc1982(t *testing.T) { - // If the current time and the timestamp are more than 68 years apart - // it means the date has wrapped. 0 is 1970 - - // fall in the current 68 year span - strtests := []string{"20120525134203", "19700101000000", "20380119031408"} - for _, v := range strtests { - if x, _ := StringToTime(v); v != TimeToString(x) { - t.Errorf("1982 arithmetic string failure %s (%s:%d)", v, TimeToString(x), x) - } - } - - inttests := map[uint32]string{0: "19700101000000", - 1 << 31: "20380119031408", - 1<<32 - 1: "21060207062815", - } - for i, v := range inttests { - if TimeToString(i) != v { - t.Errorf("1982 arithmetic int failure %d:%s (%s)", i, v, TimeToString(i)) - } - } - - // Future tests, these dates get parsed to a date within the current 136 year span - future := map[string]string{"22680119031408": "20631123173144", - "19010101121212": "20370206184028", - "19210101121212": "20570206184028", - "19500101121212": "20860206184028", - "19700101000000": "19700101000000", - "19690101000000": "21050207062816", - "29210101121212": "21040522212236", - } - for from, to := range future { - x, _ := StringToTime(from) - y := TimeToString(x) - if y != to { - t.Errorf("1982 arithmetic future failure %s:%s (%s)", from, to, y) - } - } -} - -func TestEmpty(t *testing.T) { - for range ParseZone(strings.NewReader(""), "", "") { - t.Errorf("should be empty") - } -} - -func TestLowercaseTokens(t *testing.T) { - var testrecords = []string{ - "example.org. 300 IN a 1.2.3.4", - "example.org. 300 in A 1.2.3.4", - "example.org. 300 in a 1.2.3.4", - "example.org. 300 a 1.2.3.4", - "example.org. 300 A 1.2.3.4", - "example.org. IN a 1.2.3.4", - "example.org. in A 1.2.3.4", - "example.org. in a 1.2.3.4", - "example.org. a 1.2.3.4", - "example.org. A 1.2.3.4", - "example.org. a 1.2.3.4", - "$ORIGIN example.org.\n a 1.2.3.4", - "$Origin example.org.\n a 1.2.3.4", - "$origin example.org.\n a 1.2.3.4", - "example.org. Class1 Type1 1.2.3.4", - } - for _, testrr := range testrecords { - _, err := NewRR(testrr) - if err != nil { - t.Errorf("failed to parse %#v, got %v", testrr, err) - } - } -} - -func ExampleParseZone_generate() { - // From the manual: http://www.bind9.net/manual/bind/9.3.2/Bv9ARM.ch06.html#id2566761 - zone := "$GENERATE 1-2 0 NS SERVER$.EXAMPLE.\n$GENERATE 1-8 $ CNAME $.0" - to := ParseZone(strings.NewReader(zone), "0.0.192.IN-ADDR.ARPA.", "") - for x := range to { - if x.Error == nil { - fmt.Println(x.RR.String()) - } - } - // Output: - // 0.0.0.192.IN-ADDR.ARPA. 3600 IN NS SERVER1.EXAMPLE. - // 0.0.0.192.IN-ADDR.ARPA. 3600 IN NS SERVER2.EXAMPLE. - // 1.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 1.0.0.0.192.IN-ADDR.ARPA. - // 2.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 2.0.0.0.192.IN-ADDR.ARPA. - // 3.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 3.0.0.0.192.IN-ADDR.ARPA. - // 4.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 4.0.0.0.192.IN-ADDR.ARPA. - // 5.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 5.0.0.0.192.IN-ADDR.ARPA. - // 6.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 6.0.0.0.192.IN-ADDR.ARPA. - // 7.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 7.0.0.0.192.IN-ADDR.ARPA. - // 8.0.0.192.IN-ADDR.ARPA. 3600 IN CNAME 8.0.0.0.192.IN-ADDR.ARPA. -} - -func TestSRVPacking(t *testing.T) { - msg := Msg{} - - things := []string{"1.2.3.4:8484", - "45.45.45.45:8484", - "84.84.84.84:8484", - } - - for i, n := range things { - h, p, err := net.SplitHostPort(n) - if err != nil { - continue - } - port, _ := strconv.ParseUint(p, 10, 16) - - rr := &SRV{ - Hdr: RR_Header{Name: "somename.", - Rrtype: TypeSRV, - Class: ClassINET, - Ttl: 5}, - Priority: uint16(i), - Weight: 5, - Port: uint16(port), - Target: h + ".", - } - - msg.Answer = append(msg.Answer, rr) - } - - _, err := msg.Pack() - if err != nil { - t.Fatalf("couldn't pack %v: %v", msg, err) - } -} - -func TestParseBackslash(t *testing.T) { - if r, err := NewRR("nul\\000gap.test.globnix.net. 600 IN A 192.0.2.10"); err != nil { - t.Errorf("could not create RR with \\000 in it") - } else { - t.Logf("parsed %s", r.String()) - } - if r, err := NewRR(`nul\000gap.test.globnix.net. 600 IN TXT "Hello\123"`); err != nil { - t.Errorf("could not create RR with \\000 in it") - } else { - t.Logf("parsed %s", r.String()) - } - if r, err := NewRR(`m\ @\ iek.nl. IN 3600 A 127.0.0.1`); err != nil { - t.Errorf("could not create RR with \\ and \\@ in it") - } else { - t.Logf("parsed %s", r.String()) - } -} - -func TestILNP(t *testing.T) { - tests := []string{ - "host1.example.com.\t3600\tIN\tNID\t10 0014:4fff:ff20:ee64", - "host1.example.com.\t3600\tIN\tNID\t20 0015:5fff:ff21:ee65", - "host2.example.com.\t3600\tIN\tNID\t10 0016:6fff:ff22:ee66", - "host1.example.com.\t3600\tIN\tL32\t10 10.1.2.0", - "host1.example.com.\t3600\tIN\tL32\t20 10.1.4.0", - "host2.example.com.\t3600\tIN\tL32\t10 10.1.8.0", - "host1.example.com.\t3600\tIN\tL64\t10 2001:0DB8:1140:1000", - "host1.example.com.\t3600\tIN\tL64\t20 2001:0DB8:2140:2000", - "host2.example.com.\t3600\tIN\tL64\t10 2001:0DB8:4140:4000", - "host1.example.com.\t3600\tIN\tLP\t10 l64-subnet1.example.com.", - "host1.example.com.\t3600\tIN\tLP\t10 l64-subnet2.example.com.", - "host1.example.com.\t3600\tIN\tLP\t20 l32-subnet1.example.com.", - } - for _, t1 := range tests { - r, err := NewRR(t1) - if err != nil { - t.Fatalf("an error occurred: %v", err) - } else { - if t1 != r.String() { - t.Fatalf("strings should be equal %s %s", t1, r.String()) - } - } - } -} - -func TestGposEidNimloc(t *testing.T) { - dt := map[string]string{ - "444433332222111199990123000000ff. NSAP-PTR foo.bar.com.": "444433332222111199990123000000ff.\t3600\tIN\tNSAP-PTR\tfoo.bar.com.", - "lillee. IN GPOS -32.6882 116.8652 10.0": "lillee.\t3600\tIN\tGPOS\t-32.6882 116.8652 10.0", - "hinault. IN GPOS -22.6882 116.8652 250.0": "hinault.\t3600\tIN\tGPOS\t-22.6882 116.8652 250.0", - "VENERA. IN NIMLOC 75234159EAC457800920": "VENERA.\t3600\tIN\tNIMLOC\t75234159EAC457800920", - "VAXA. IN EID 3141592653589793": "VAXA.\t3600\tIN\tEID\t3141592653589793", - } - for i, o := range dt { - rr, err := NewRR(i) - if err != nil { - t.Error("failed to parse RR: ", err) - continue - } - if rr.String() != o { - t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String()) - } else { - t.Logf("RR is OK: `%s'", rr.String()) - } - } -} - -func TestPX(t *testing.T) { - dt := map[string]string{ - "*.net2.it. IN PX 10 net2.it. PRMD-net2.ADMD-p400.C-it.": "*.net2.it.\t3600\tIN\tPX\t10 net2.it. PRMD-net2.ADMD-p400.C-it.", - "ab.net2.it. IN PX 10 ab.net2.it. O-ab.PRMD-net2.ADMDb.C-it.": "ab.net2.it.\t3600\tIN\tPX\t10 ab.net2.it. O-ab.PRMD-net2.ADMDb.C-it.", - } - for i, o := range dt { - rr, err := NewRR(i) - if err != nil { - t.Error("failed to parse RR: ", err) - continue - } - if rr.String() != o { - t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String()) - } else { - t.Logf("RR is OK: `%s'", rr.String()) - } - } -} - -func TestComment(t *testing.T) { - // Comments we must see - comments := map[string]bool{"; this is comment 1": true, - "; this is comment 4": true, "; this is comment 6": true, - "; this is comment 7": true, "; this is comment 8": true} - zone := ` -foo. IN A 10.0.0.1 ; this is comment 1 -foo. IN A ( - 10.0.0.2 ; this is comment2 -) -; this is comment3 -foo. IN A 10.0.0.3 -foo. IN A ( 10.0.0.4 ); this is comment 4 - -foo. IN A 10.0.0.5 -; this is comment5 - -foo. IN A 10.0.0.6 - -foo. IN DNSKEY 256 3 5 AwEAAb+8l ; this is comment 6 -foo. IN NSEC miek.nl. TXT RRSIG NSEC; this is comment 7 -foo. IN TXT "THIS IS TEXT MAN"; this is comment 8 -` - for x := range ParseZone(strings.NewReader(zone), ".", "") { - if x.Error == nil { - if x.Comment != "" { - if _, ok := comments[x.Comment]; !ok { - t.Errorf("wrong comment %s", x.Comment) - } - } - } - } -} - -func TestEUIxx(t *testing.T) { - tests := map[string]string{ - "host.example. IN EUI48 00-00-5e-90-01-2a": "host.example.\t3600\tIN\tEUI48\t00-00-5e-90-01-2a", - "host.example. IN EUI64 00-00-5e-ef-00-00-00-2a": "host.example.\t3600\tIN\tEUI64\t00-00-5e-ef-00-00-00-2a", - } - for i, o := range tests { - r, err := NewRR(i) - if err != nil { - t.Errorf("failed to parse %s: %v", i, err) - } - if r.String() != o { - t.Errorf("want %s, got %s", o, r.String()) - } - } -} - -func TestUserRR(t *testing.T) { - tests := map[string]string{ - "host.example. IN UID 1234": "host.example.\t3600\tIN\tUID\t1234", - "host.example. IN GID 1234556": "host.example.\t3600\tIN\tGID\t1234556", - "host.example. IN UINFO \"Miek Gieben\"": "host.example.\t3600\tIN\tUINFO\t\"Miek Gieben\"", - } - for i, o := range tests { - r, err := NewRR(i) - if err != nil { - t.Errorf("failed to parse %s: %v", i, err) - } - if r.String() != o { - t.Errorf("want %s, got %s", o, r.String()) - } - } -} - -func TestTXT(t *testing.T) { - // Test single entry TXT record - rr, err := NewRR(`_raop._tcp.local. 60 IN TXT "single value"`) - if err != nil { - t.Error("failed to parse single value TXT record", err) - } else if rr, ok := rr.(*TXT); !ok { - t.Error("wrong type, record should be of type TXT") - } else { - if len(rr.Txt) != 1 { - t.Error("bad size of TXT value:", len(rr.Txt)) - } else if rr.Txt[0] != "single value" { - t.Error("bad single value") - } - if rr.String() != `_raop._tcp.local. 60 IN TXT "single value"` { - t.Error("bad representation of TXT record:", rr.String()) - } - if rr.len() != 28+1+12 { - t.Error("bad size of serialized record:", rr.len()) - } - } - - // Test multi entries TXT record - rr, err = NewRR(`_raop._tcp.local. 60 IN TXT "a=1" "b=2" "c=3" "d=4"`) - if err != nil { - t.Error("failed to parse multi-values TXT record", err) - } else if rr, ok := rr.(*TXT); !ok { - t.Error("wrong type, record should be of type TXT") - } else { - if len(rr.Txt) != 4 { - t.Error("bad size of TXT multi-value:", len(rr.Txt)) - } else if rr.Txt[0] != "a=1" || rr.Txt[1] != "b=2" || rr.Txt[2] != "c=3" || rr.Txt[3] != "d=4" { - t.Error("bad values in TXT records") - } - if rr.String() != `_raop._tcp.local. 60 IN TXT "a=1" "b=2" "c=3" "d=4"` { - t.Error("bad representation of TXT multi value record:", rr.String()) - } - if rr.len() != 28+1+3+1+3+1+3+1+3 { - t.Error("bad size of serialized multi value record:", rr.len()) - } - } - - // Test empty-string in TXT record - rr, err = NewRR(`_raop._tcp.local. 60 IN TXT ""`) - if err != nil { - t.Error("failed to parse empty-string TXT record", err) - } else if rr, ok := rr.(*TXT); !ok { - t.Error("wrong type, record should be of type TXT") - } else { - if len(rr.Txt) != 1 { - t.Error("bad size of TXT empty-string value:", len(rr.Txt)) - } else if rr.Txt[0] != "" { - t.Error("bad value for empty-string TXT record") - } - if rr.String() != `_raop._tcp.local. 60 IN TXT ""` { - t.Error("bad representation of empty-string TXT record:", rr.String()) - } - if rr.len() != 28+1 { - t.Error("bad size of serialized record:", rr.len()) - } - } - - // Test TXT record with chunk larger than 255 bytes, they should be split up, by the parser - s := "" - for i := 0; i < 255; i++ { - s += "a" - } - s += "b" - rr, err = NewRR(`test.local. 60 IN TXT "` + s + `"`) - if err != nil { - t.Error("failed to parse empty-string TXT record", err) - } - if rr.(*TXT).Txt[1] != "b" { - t.Errorf("Txt should have two chunk, last one my be 'b', but is %s", rr.(*TXT).Txt[1]) - } - t.Log(rr.String()) -} - -func TestTypeXXXX(t *testing.T) { - _, err := NewRR("example.com IN TYPE1234 \\# 4 aabbccdd") - if err != nil { - t.Errorf("failed to parse TYPE1234 RR: %v", err) - } - _, err = NewRR("example.com IN TYPE655341 \\# 8 aabbccddaabbccdd") - if err == nil { - t.Errorf("this should not work, for TYPE655341") - } - _, err = NewRR("example.com IN TYPE1 \\# 4 0a000001") - if err == nil { - t.Errorf("this should not work") - } -} - -func TestPTR(t *testing.T) { - _, err := NewRR("144.2.0.192.in-addr.arpa. 900 IN PTR ilouse03146p0\\(.example.com.") - if err != nil { - t.Error("failed to parse ", err) - } -} - -func TestDigit(t *testing.T) { - tests := map[string]byte{ - "miek\\000.nl. 100 IN TXT \"A\"": 0, - "miek\\001.nl. 100 IN TXT \"A\"": 1, - "miek\\254.nl. 100 IN TXT \"A\"": 254, - "miek\\255.nl. 100 IN TXT \"A\"": 255, - "miek\\256.nl. 100 IN TXT \"A\"": 0, - "miek\\257.nl. 100 IN TXT \"A\"": 1, - "miek\\004.nl. 100 IN TXT \"A\"": 4, - } - for s, i := range tests { - r, err := NewRR(s) - buf := make([]byte, 40) - if err != nil { - t.Fatalf("failed to parse %v", err) - } - PackRR(r, buf, 0, nil, false) - t.Log(buf) - if buf[5] != i { - t.Fatalf("5 pos must be %d, is %d", i, buf[5]) - } - r1, _, _ := UnpackRR(buf, 0) - if r1.Header().Ttl != 100 { - t.Fatalf("TTL should %d, is %d", 100, r1.Header().Ttl) - } - } -} - -func TestParseRRSIGTimestamp(t *testing.T) { - tests := map[string]bool{ - `miek.nl. IN RRSIG SOA 8 2 43200 20140210031301 20140111031301 12051 miek.nl. MVZUyrYwq0iZhMFDDnVXD2BvuNiUJjSYlJAgzyAE6CF875BMvvZa+Sb0 RlSCL7WODQSQHhCx/fegHhVVF+Iz8N8kOLrmXD1+jO3Bm6Prl5UhcsPx WTBsg/kmxbp8sR1kvH4oZJtVfakG3iDerrxNaf0sQwhZzyfJQAqpC7pcBoc=`: true, - `miek.nl. IN RRSIG SOA 8 2 43200 315565800 4102477800 12051 miek.nl. MVZUyrYwq0iZhMFDDnVXD2BvuNiUJjSYlJAgzyAE6CF875BMvvZa+Sb0 RlSCL7WODQSQHhCx/fegHhVVF+Iz8N8kOLrmXD1+jO3Bm6Prl5UhcsPx WTBsg/kmxbp8sR1kvH4oZJtVfakG3iDerrxNaf0sQwhZzyfJQAqpC7pcBoc=`: true, - } - for r := range tests { - _, err := NewRR(r) - if err != nil { - t.Error(err) - } - } -} - -func TestTxtEqual(t *testing.T) { - rr1 := new(TXT) - rr1.Hdr = RR_Header{Name: ".", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0} - rr1.Txt = []string{"a\"a", "\"", "b"} - rr2, _ := NewRR(rr1.String()) - if rr1.String() != rr2.String() { - // This is not an error, but keep this test. - t.Errorf("these two TXT records should match:\n%s\n%s", rr1.String(), rr2.String()) - } - t.Logf("%s\n%s", rr1.String(), rr2.String()) -} - -func TestTxtLong(t *testing.T) { - rr1 := new(TXT) - rr1.Hdr = RR_Header{Name: ".", Rrtype: TypeTXT, Class: ClassINET, Ttl: 0} - // Make a long txt record, this breaks when sending the packet, - // but not earlier. - rr1.Txt = []string{"start-"} - for i := 0; i < 200; i++ { - rr1.Txt[0] += "start-" - } - str := rr1.String() - if len(str) < len(rr1.Txt[0]) { - t.Error("string conversion should work") - } -} - -// Basically, don't crash. -func TestMalformedPackets(t *testing.T) { - var packets = []string{ - "0021641c0000000100000000000078787878787878787878787303636f6d0000100001", - } - - // com = 63 6f 6d - for _, packet := range packets { - data, _ := hex.DecodeString(packet) - // for _, v := range data { - // t.Log(v) - // } - var msg Msg - msg.Unpack(data) - // println(msg.String()) - } -} - -type algorithm struct { - name uint8 - bits int -} - -func TestNewPrivateKey(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - algorithms := []algorithm{ - {ECDSAP256SHA256, 256}, - {ECDSAP384SHA384, 384}, - {RSASHA1, 1024}, - {RSASHA256, 2048}, - {DSA, 1024}, - } - - for _, algo := range algorithms { - key := new(DNSKEY) - key.Hdr.Rrtype = TypeDNSKEY - key.Hdr.Name = "miek.nl." - key.Hdr.Class = ClassINET - key.Hdr.Ttl = 14400 - key.Flags = 256 - key.Protocol = 3 - key.Algorithm = algo.name - privkey, err := key.Generate(algo.bits) - if err != nil { - t.Fatal(err) - } - - newPrivKey, err := key.NewPrivateKey(key.PrivateKeyString(privkey)) - if err != nil { - t.Error(key.String()) - t.Error(key.PrivateKeyString(privkey)) - t.Fatal(err) - } - - switch newPrivKey := newPrivKey.(type) { - case *rsa.PrivateKey: - newPrivKey.Precompute() - } - - if !reflect.DeepEqual(privkey, newPrivKey) { - t.Errorf("[%v] Private keys differ:\n%#v\n%#v", AlgorithmToString[algo.name], privkey, newPrivKey) - } - } -} - -// special input test -func TestNewRRSpecial(t *testing.T) { - var ( - rr RR - err error - expect string - ) - - rr, err = NewRR("; comment") - expect = "" - if err != nil { - t.Errorf("unexpected err: %v", err) - } - if rr != nil { - t.Errorf("unexpected result: [%s] != [%s]", rr, expect) - } - - rr, err = NewRR("") - expect = "" - if err != nil { - t.Errorf("unexpected err: %v", err) - } - if rr != nil { - t.Errorf("unexpected result: [%s] != [%s]", rr, expect) - } - - rr, err = NewRR("$ORIGIN foo.") - expect = "" - if err != nil { - t.Errorf("unexpected err: %v", err) - } - if rr != nil { - t.Errorf("unexpected result: [%s] != [%s]", rr, expect) - } - - rr, err = NewRR(" ") - expect = "" - if err != nil { - t.Errorf("unexpected err: %v", err) - } - if rr != nil { - t.Errorf("unexpected result: [%s] != [%s]", rr, expect) - } - - rr, err = NewRR("\n") - expect = "" - if err != nil { - t.Errorf("unexpected err: %v", err) - } - if rr != nil { - t.Errorf("unexpected result: [%s] != [%s]", rr, expect) - } - - rr, err = NewRR("foo. A 1.1.1.1\nbar. A 2.2.2.2") - expect = "foo.\t3600\tIN\tA\t1.1.1.1" - if err != nil { - t.Errorf("unexpected err: %v", err) - } - if rr == nil || rr.String() != expect { - t.Errorf("unexpected result: [%s] != [%s]", rr, expect) - } -} - -func TestPrintfVerbsRdata(t *testing.T) { - x, _ := NewRR("www.miek.nl. IN MX 20 mx.miek.nl.") - if Field(x, 1) != "20" { - t.Errorf("should be 20") - } - if Field(x, 2) != "mx.miek.nl." { - t.Errorf("should be mx.miek.nl.") - } - - x, _ = NewRR("www.miek.nl. IN A 127.0.0.1") - if Field(x, 1) != "127.0.0.1" { - t.Errorf("should be 127.0.0.1") - } - - x, _ = NewRR("www.miek.nl. IN AAAA ::1") - if Field(x, 1) != "::1" { - t.Errorf("should be ::1") - } - - x, _ = NewRR("www.miek.nl. IN NSEC a.miek.nl. A NS SOA MX AAAA") - if Field(x, 1) != "a.miek.nl." { - t.Errorf("should be a.miek.nl.") - } - if Field(x, 2) != "A NS SOA MX AAAA" { - t.Errorf("should be A NS SOA MX AAAA") - } - - x, _ = NewRR("www.miek.nl. IN TXT \"first\" \"second\"") - if Field(x, 1) != "first second" { - t.Errorf("should be first second") - } - if Field(x, 0) != "" { - t.Errorf("should be empty") - } -} - -func TestParseTokenOverflow(t *testing.T) { - _, err := NewRR("_443._tcp.example.org. IN TLSA 0 0 0 308205e8308204d0a00302010202100411de8f53b462f6a5a861b712ec6b59300d06092a864886f70d01010b05003070310b300906035504061302555331153013060355040a130c446967694365727420496e6331193017060355040b13107777772e64696769636572742e636f6d312f302d06035504031326446967694365727420534841322048696768204173737572616e636520536572766572204341301e170d3134313130363030303030305a170d3135313131333132303030305a3081a5310b3009060355040613025553311330110603550408130a43616c69666f726e6961311430120603550407130b4c6f7320416e67656c6573313c303a060355040a1333496e7465726e657420436f72706f726174696f6e20666f722041737369676e6564204e616d657320616e64204e756d6265727331133011060355040b130a546563686e6f6c6f6779311830160603550403130f7777772e6578616d706c652e6f726730820122300d06092a864886f70d01010105000382010f003082010a02820101009e663f52a3d18cb67cdfed547408a4e47e4036538988da2798da3b6655f7240d693ed1cb3fe6d6ad3a9e657ff6efa86b83b0cad24e5d31ff2bf70ec3b78b213f1b4bf61bdc669cbbc07d67154128ca92a9b3cbb4213a836fb823ddd4d7cc04918314d25f06086fa9970ba17e357cca9b458c27eb71760ab95e3f9bc898ae89050ae4d09ba2f7e4259d9ff1e072a6971b18355a8b9e53670c3d5dbdbd283f93a764e71b3a4140ca0746090c08510e2e21078d7d07844bf9c03865b531a0bf2ee766bc401f6451c5a1e6f6fb5d5c1d6a97a0abe91ae8b02e89241e07353909ccd5b41c46de207c06801e08f20713603827f2ae3e68cf15ef881d7e0608f70742e30203010001a382024630820242301f0603551d230418301680145168ff90af0207753cccd9656462a212b859723b301d0603551d0e04160414b000a7f422e9b1ce216117c4c46e7164c8e60c553081810603551d11047a3078820f7777772e6578616d706c652e6f7267820b6578616d706c652e636f6d820b6578616d706c652e656475820b6578616d706c652e6e6574820b6578616d706c652e6f7267820f7777772e6578616d706c652e636f6d820f7777772e6578616d706c652e656475820f7777772e6578616d706c652e6e6574300e0603551d0f0101ff0404030205a0301d0603551d250416301406082b0601050507030106082b0601050507030230750603551d1f046e306c3034a032a030862e687474703a2f2f63726c332e64696769636572742e636f6d2f736861322d68612d7365727665722d67332e63726c3034a032a030862e687474703a2f2f63726c342e64696769636572742e636f6d2f736861322d68612d7365727665722d67332e63726c30420603551d20043b3039303706096086480186fd6c0101302a302806082b06010505070201161c68747470733a2f2f7777772e64696769636572742e636f6d2f43505330818306082b0601050507010104773075302406082b060105050730018618687474703a2f2f6f6373702e64696769636572742e636f6d304d06082b060105050730028641687474703a2f2f636163657274732e64696769636572742e636f6d2f446967694365727453484132486967684173737572616e636553657276657243412e637274300c0603551d130101ff04023000300d06092a864886f70d01010b050003820101005eac2124dedb3978a86ff3608406acb542d3cb54cb83facd63aec88144d6a1bf15dbf1f215c4a73e241e582365cba9ea50dd306541653b3513af1a0756c1b2720e8d112b34fb67181efad9c4609bdc670fb025fa6e6d42188161b026cf3089a08369c2f3609fc84bcc3479140c1922ede430ca8dbac2b2a3cdacb305ba15dc7361c4c3a5e6daa99cb446cb221b28078a7a944efba70d96f31ac143d959bccd2fd50e30c325ea2624fb6b6dbe9344dbcf133bfbd5b4e892d635dbf31596451672c6b65ba5ac9b3cddea92b35dab1065cae3c8cb6bb450a62ea2f72ea7c6bdc7b65fa09b012392543734083c7687d243f8d0375304d99ccd2e148966a8637a6797") - if err == nil { - t.Fatalf("token overflow should return an error") - } - t.Logf("err: %s\n", err) -} - -func TestParseTLSA(t *testing.T) { - lt := []string{ - "_443._tcp.example.org.\t3600\tIN\tTLSA\t1 1 1 c22be239f483c08957bc106219cc2d3ac1a308dfbbdd0a365f17b9351234cf00", - "_443._tcp.example.org.\t3600\tIN\tTLSA\t2 1 2 4e85f45179e9cd6e0e68e2eb5be2e85ec9b92d91c609caf3ef0315213e3f92ece92c38397a607214de95c7fadc0ad0f1c604a469a0387959745032c0d51492f3", - "_443._tcp.example.org.\t3600\tIN\tTLSA\t3 0 2 69ec8d2277360b215d0cd956b0e2747108dff34b27d461a41c800629e38ee6c2d1230cc9e8e36711330adc6766e6ff7c5fbb37f106f248337c1a20ad682888d2", - } - for _, o := range lt { - rr, err := NewRR(o) - if err != nil { - t.Error("failed to parse RR: ", err) - continue - } - if rr.String() != o { - t.Errorf("`%s' should be equal to\n`%s', but is `%s'", o, o, rr.String()) - } else { - t.Logf("RR is OK: `%s'", rr.String()) - } - } -} - -func TestParseSMIMEA(t *testing.T) { - lt := map[string]string{ - "2e85e1db3e62be6ea._smimecert.example.com.\t3600\tIN\tSMIMEA\t1 1 2 bd80f334566928fc18f58df7e4928c1886f48f71ca3fd41cd9b1854aca7c2180aaacad2819612ed68e7bd3701cc39be7f2529b017c0bc6a53e8fb3f0c7d48070": "2e85e1db3e62be6ea._smimecert.example.com.\t3600\tIN\tSMIMEA\t1 1 2 bd80f334566928fc18f58df7e4928c1886f48f71ca3fd41cd9b1854aca7c2180aaacad2819612ed68e7bd3701cc39be7f2529b017c0bc6a53e8fb3f0c7d48070", - "2e85e1db3e62be6ea._smimecert.example.com.\t3600\tIN\tSMIMEA\t0 0 1 cdcf0fc66b182928c5217ddd42c826983f5a4b94160ee6c1c9be62d38199f710": "2e85e1db3e62be6ea._smimecert.example.com.\t3600\tIN\tSMIMEA\t0 0 1 cdcf0fc66b182928c5217ddd42c826983f5a4b94160ee6c1c9be62d38199f710", - "2e85e1db3e62be6ea._smimecert.example.com.\t3600\tIN\tSMIMEA\t3 0 2 499a1eda2af8828b552cdb9d80c3744a25872fddd73f3898d8e4afa3549595d2dd4340126e759566fe8c26b251fa0c887ba4869f011a65f7e79967c2eb729f5b": "2e85e1db3e62be6ea._smimecert.example.com.\t3600\tIN\tSMIMEA\t3 0 2 499a1eda2af8828b552cdb9d80c3744a25872fddd73f3898d8e4afa3549595d2dd4340126e759566fe8c26b251fa0c887ba4869f011a65f7e79967c2eb729f5b", - "2e85e1db3e62be6eb._smimecert.example.com.\t3600\tIN\tSMIMEA\t3 0 2 499a1eda2af8828b552cdb9d80c3744a25872fddd73f3898d8e4afa3549595d2dd4340126e759566fe8 c26b251fa0c887ba4869f01 1a65f7e79967c2eb729f5b": "2e85e1db3e62be6eb._smimecert.example.com.\t3600\tIN\tSMIMEA\t3 0 2 499a1eda2af8828b552cdb9d80c3744a25872fddd73f3898d8e4afa3549595d2dd4340126e759566fe8c26b251fa0c887ba4869f011a65f7e79967c2eb729f5b", - } - for i, o := range lt { - rr, err := NewRR(i) - if err != nil { - t.Error("failed to parse RR: ", err) - continue - } - if rr.String() != o { - t.Errorf("`%s' should be equal to\n`%s', but is `%s'", o, o, rr.String()) - } else { - t.Logf("RR is OK: `%s'", rr.String()) - } - } -} - -func TestParseSSHFP(t *testing.T) { - lt := []string{ - "test.example.org.\t300\tSSHFP\t1 2 (\n" + - "\t\t\t\t\tBC6533CDC95A79078A39A56EA7635984ED655318ADA9\n" + - "\t\t\t\t\tB6159E30723665DA95BB )", - "test.example.org.\t300\tSSHFP\t1 2 ( BC6533CDC 95A79078A39A56EA7635984ED655318AD A9B6159E3072366 5DA95BB )", - } - result := "test.example.org.\t300\tIN\tSSHFP\t1 2 BC6533CDC95A79078A39A56EA7635984ED655318ADA9B6159E30723665DA95BB" - for _, o := range lt { - rr, err := NewRR(o) - if err != nil { - t.Error("failed to parse RR: ", err) - continue - } - if rr.String() != result { - t.Errorf("`%s' should be equal to\n\n`%s', but is \n`%s'", o, result, rr.String()) - } else { - t.Logf("RR is OK: `%s'", rr.String()) - } - } -} - -func TestParseHINFO(t *testing.T) { - dt := map[string]string{ - "example.net. HINFO A B": "example.net. 3600 IN HINFO \"A\" \"B\"", - "example.net. HINFO \"A\" \"B\"": "example.net. 3600 IN HINFO \"A\" \"B\"", - "example.net. HINFO A B C D E F": "example.net. 3600 IN HINFO \"A\" \"B C D E F\"", - "example.net. HINFO AB": "example.net. 3600 IN HINFO \"AB\" \"\"", - // "example.net. HINFO PC-Intel-700mhz \"Redhat Linux 7.1\"": "example.net. 3600 IN HINFO \"PC-Intel-700mhz\" \"Redhat Linux 7.1\"", - // This one is recommended in Pro Bind book http://www.zytrax.com/books/dns/ch8/hinfo.html - // but effectively, even Bind would replace it to correctly formed text when you AXFR - // TODO: remove this set of comments or figure support for quoted/unquoted combinations in endingToTxtSlice function - } - for i, o := range dt { - rr, err := NewRR(i) - if err != nil { - t.Error("failed to parse RR: ", err) - continue - } - if rr.String() != o { - t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String()) - } else { - t.Logf("RR is OK: `%s'", rr.String()) - } - } -} - -func TestParseCAA(t *testing.T) { - lt := map[string]string{ - "example.net. CAA 0 issue \"symantec.com\"": "example.net.\t3600\tIN\tCAA\t0 issue \"symantec.com\"", - "example.net. CAA 0 issuewild \"symantec.com; stuff\"": "example.net.\t3600\tIN\tCAA\t0 issuewild \"symantec.com; stuff\"", - "example.net. CAA 128 tbs \"critical\"": "example.net.\t3600\tIN\tCAA\t128 tbs \"critical\"", - "example.net. CAA 2 auth \"0>09\\006\\010+\\006\\001\\004\\001\\214y\\002\\003\\001\\006\\009`\\134H\\001e\\003\\004\\002\\001\\004 y\\209\\012\\221r\\220\\156Q\\218\\150\\150{\\166\\245:\\231\\182%\\157:\\133\\179}\\1923r\\238\\151\\255\\128q\\145\\002\\001\\000\"": "example.net.\t3600\tIN\tCAA\t2 auth \"0>09\\006\\010+\\006\\001\\004\\001\\214y\\002\\003\\001\\006\\009`\\134H\\001e\\003\\004\\002\\001\\004 y\\209\\012\\221r\\220\\156Q\\218\\150\\150{\\166\\245:\\231\\182%\\157:\\133\\179}\\1923r\\238\\151\\255\\128q\\145\\002\\001\\000\"", - "example.net. TYPE257 0 issue \"symantec.com\"": "example.net.\t3600\tIN\tCAA\t0 issue \"symantec.com\"", - } - for i, o := range lt { - rr, err := NewRR(i) - if err != nil { - t.Error("failed to parse RR: ", err) - continue - } - if rr.String() != o { - t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String()) - } else { - t.Logf("RR is OK: `%s'", rr.String()) - } - } -} - -func TestPackCAA(t *testing.T) { - m := new(Msg) - record := new(CAA) - record.Hdr = RR_Header{Name: "example.com.", Rrtype: TypeCAA, Class: ClassINET, Ttl: 0} - record.Tag = "issue" - record.Value = "symantec.com" - record.Flag = 1 - - m.Answer = append(m.Answer, record) - bytes, err := m.Pack() - if err != nil { - t.Fatalf("failed to pack msg: %v", err) - } - if err := m.Unpack(bytes); err != nil { - t.Fatalf("failed to unpack msg: %v", err) - } - if len(m.Answer) != 1 { - t.Fatalf("incorrect number of answers unpacked") - } - rr := m.Answer[0].(*CAA) - if rr.Tag != "issue" { - t.Fatalf("invalid tag for unpacked answer") - } else if rr.Value != "symantec.com" { - t.Fatalf("invalid value for unpacked answer") - } else if rr.Flag != 1 { - t.Fatalf("invalid flag for unpacked answer") - } -} - -func TestParseURI(t *testing.T) { - lt := map[string]string{ - "_http._tcp. IN URI 10 1 \"http://www.example.com/path\"": "_http._tcp.\t3600\tIN\tURI\t10 1 \"http://www.example.com/path\"", - "_http._tcp. IN URI 10 1 \"\"": "_http._tcp.\t3600\tIN\tURI\t10 1 \"\"", - } - for i, o := range lt { - rr, err := NewRR(i) - if err != nil { - t.Error("failed to parse RR: ", err) - continue - } - if rr.String() != o { - t.Errorf("`%s' should be equal to\n`%s', but is `%s'", i, o, rr.String()) - } else { - t.Logf("RR is OK: `%s'", rr.String()) - } - } -} - -func TestParseAVC(t *testing.T) { - avcs := map[string]string{ - `example.org. IN AVC "app-name:WOLFGANG|app-class:OAM|business=yes"`: `example.org. 3600 IN AVC "app-name:WOLFGANG|app-class:OAM|business=yes"`, - } - for avc, o := range avcs { - rr, err := NewRR(avc) - if err != nil { - t.Error("failed to parse RR: ", err) - continue - } - if rr.String() != o { - t.Errorf("`%s' should be equal to\n`%s', but is `%s'", avc, o, rr.String()) - } else { - t.Logf("RR is OK: `%s'", rr.String()) - } - } -} - -func TestUnbalancedParens(t *testing.T) { - sig := `example.com. 3600 IN RRSIG MX 15 2 3600 ( - 1440021600 1438207200 3613 example.com. ( - oL9krJun7xfBOIWcGHi7mag5/hdZrKWw15jPGrHpjQeRAvTdszaPD+QLs3f - x8A4M3e23mRZ9VrbpMngwcrqNAg== )` - _, err := NewRR(sig) - if err == nil { - t.Fatalf("Failed to detect extra opening brace") - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/privaterr.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/privaterr.go deleted file mode 100644 index 6b08e6e95..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/privaterr.go +++ /dev/null @@ -1,149 +0,0 @@ -package dns - -import ( - "fmt" - "strings" -) - -// PrivateRdata is an interface used for implementing "Private Use" RR types, see -// RFC 6895. This allows one to experiment with new RR types, without requesting an -// official type code. Also see dns.PrivateHandle and dns.PrivateHandleRemove. -type PrivateRdata interface { - // String returns the text presentaton of the Rdata of the Private RR. - String() string - // Parse parses the Rdata of the private RR. - Parse([]string) error - // Pack is used when packing a private RR into a buffer. - Pack([]byte) (int, error) - // Unpack is used when unpacking a private RR from a buffer. - // TODO(miek): diff. signature than Pack, see edns0.go for instance. - Unpack([]byte) (int, error) - // Copy copies the Rdata. - Copy(PrivateRdata) error - // Len returns the length in octets of the Rdata. - Len() int -} - -// PrivateRR represents an RR that uses a PrivateRdata user-defined type. -// It mocks normal RRs and implements dns.RR interface. -type PrivateRR struct { - Hdr RR_Header - Data PrivateRdata -} - -func mkPrivateRR(rrtype uint16) *PrivateRR { - // Panics if RR is not an instance of PrivateRR. - rrfunc, ok := TypeToRR[rrtype] - if !ok { - panic(fmt.Sprintf("dns: invalid operation with Private RR type %d", rrtype)) - } - - anyrr := rrfunc() - switch rr := anyrr.(type) { - case *PrivateRR: - return rr - } - panic(fmt.Sprintf("dns: RR is not a PrivateRR, TypeToRR[%d] generator returned %T", rrtype, anyrr)) -} - -// Header return the RR header of r. -func (r *PrivateRR) Header() *RR_Header { return &r.Hdr } - -func (r *PrivateRR) String() string { return r.Hdr.String() + r.Data.String() } - -// Private len and copy parts to satisfy RR interface. -func (r *PrivateRR) len() int { return r.Hdr.len() + r.Data.Len() } -func (r *PrivateRR) copy() RR { - // make new RR like this: - rr := mkPrivateRR(r.Hdr.Rrtype) - newh := r.Hdr.copyHeader() - rr.Hdr = *newh - - err := r.Data.Copy(rr.Data) - if err != nil { - panic("dns: got value that could not be used to copy Private rdata") - } - return rr -} -func (r *PrivateRR) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := r.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - n, err := r.Data.Pack(msg[off:]) - if err != nil { - return len(msg), err - } - off += n - r.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -// PrivateHandle registers a private resource record type. It requires -// string and numeric representation of private RR type and generator function as argument. -func PrivateHandle(rtypestr string, rtype uint16, generator func() PrivateRdata) { - rtypestr = strings.ToUpper(rtypestr) - - TypeToRR[rtype] = func() RR { return &PrivateRR{RR_Header{}, generator()} } - TypeToString[rtype] = rtypestr - StringToType[rtypestr] = rtype - - typeToUnpack[rtype] = func(h RR_Header, msg []byte, off int) (RR, int, error) { - if noRdata(h) { - return &h, off, nil - } - var err error - - rr := mkPrivateRR(h.Rrtype) - rr.Hdr = h - - off1, err := rr.Data.Unpack(msg[off:]) - off += off1 - if err != nil { - return rr, off, err - } - return rr, off, err - } - - setPrivateRR := func(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := mkPrivateRR(h.Rrtype) - rr.Hdr = h - - var l lex - text := make([]string, 0, 2) // could be 0..N elements, median is probably 1 - Fetch: - for { - // TODO(miek): we could also be returning _QUOTE, this might or might not - // be an issue (basically parsing TXT becomes hard) - switch l = <-c; l.value { - case zNewline, zEOF: - break Fetch - case zString: - text = append(text, l.token) - } - } - - err := rr.Data.Parse(text) - if err != nil { - return nil, &ParseError{f, err.Error(), l}, "" - } - - return rr, nil, "" - } - - typeToparserFunc[rtype] = parserFunc{setPrivateRR, true} -} - -// PrivateHandleRemove removes defenitions required to support private RR type. -func PrivateHandleRemove(rtype uint16) { - rtypestr, ok := TypeToString[rtype] - if ok { - delete(TypeToRR, rtype) - delete(TypeToString, rtype) - delete(typeToparserFunc, rtype) - delete(StringToType, rtypestr) - delete(typeToUnpack, rtype) - } - return -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/privaterr_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/privaterr_test.go deleted file mode 100644 index 72ec8f5c0..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/privaterr_test.go +++ /dev/null @@ -1,171 +0,0 @@ -package dns_test - -import ( - "strings" - "testing" - - "github.com/miekg/dns" -) - -const TypeISBN uint16 = 0xFF00 - -// A crazy new RR type :) -type ISBN struct { - x string // rdata with 10 or 13 numbers, dashes or spaces allowed -} - -func NewISBN() dns.PrivateRdata { return &ISBN{""} } - -func (rd *ISBN) Len() int { return len([]byte(rd.x)) } -func (rd *ISBN) String() string { return rd.x } - -func (rd *ISBN) Parse(txt []string) error { - rd.x = strings.TrimSpace(strings.Join(txt, " ")) - return nil -} - -func (rd *ISBN) Pack(buf []byte) (int, error) { - b := []byte(rd.x) - n := copy(buf, b) - if n != len(b) { - return n, dns.ErrBuf - } - return n, nil -} - -func (rd *ISBN) Unpack(buf []byte) (int, error) { - rd.x = string(buf) - return len(buf), nil -} - -func (rd *ISBN) Copy(dest dns.PrivateRdata) error { - isbn, ok := dest.(*ISBN) - if !ok { - return dns.ErrRdata - } - isbn.x = rd.x - return nil -} - -var testrecord = strings.Join([]string{"example.org.", "3600", "IN", "ISBN", "12-3 456789-0-123"}, "\t") - -func TestPrivateText(t *testing.T) { - dns.PrivateHandle("ISBN", TypeISBN, NewISBN) - defer dns.PrivateHandleRemove(TypeISBN) - - rr, err := dns.NewRR(testrecord) - if err != nil { - t.Fatal(err) - } - if rr.String() != testrecord { - t.Errorf("record string representation did not match original %#v != %#v", rr.String(), testrecord) - } else { - t.Log(rr.String()) - } -} - -func TestPrivateByteSlice(t *testing.T) { - dns.PrivateHandle("ISBN", TypeISBN, NewISBN) - defer dns.PrivateHandleRemove(TypeISBN) - - rr, err := dns.NewRR(testrecord) - if err != nil { - t.Fatal(err) - } - - buf := make([]byte, 100) - off, err := dns.PackRR(rr, buf, 0, nil, false) - if err != nil { - t.Errorf("got error packing ISBN: %v", err) - } - - custrr := rr.(*dns.PrivateRR) - if ln := custrr.Data.Len() + len(custrr.Header().Name) + 11; ln != off { - t.Errorf("offset is not matching to length of Private RR: %d!=%d", off, ln) - } - - rr1, off1, err := dns.UnpackRR(buf[:off], 0) - if err != nil { - t.Errorf("got error unpacking ISBN: %v", err) - return - } - - if off1 != off { - t.Errorf("offset after unpacking differs: %d != %d", off1, off) - } - - if rr1.String() != testrecord { - t.Errorf("record string representation did not match original %#v != %#v", rr1.String(), testrecord) - } else { - t.Log(rr1.String()) - } -} - -const TypeVERSION uint16 = 0xFF01 - -type VERSION struct { - x string -} - -func NewVersion() dns.PrivateRdata { return &VERSION{""} } - -func (rd *VERSION) String() string { return rd.x } -func (rd *VERSION) Parse(txt []string) error { - rd.x = strings.TrimSpace(strings.Join(txt, " ")) - return nil -} - -func (rd *VERSION) Pack(buf []byte) (int, error) { - b := []byte(rd.x) - n := copy(buf, b) - if n != len(b) { - return n, dns.ErrBuf - } - return n, nil -} - -func (rd *VERSION) Unpack(buf []byte) (int, error) { - rd.x = string(buf) - return len(buf), nil -} - -func (rd *VERSION) Copy(dest dns.PrivateRdata) error { - isbn, ok := dest.(*VERSION) - if !ok { - return dns.ErrRdata - } - isbn.x = rd.x - return nil -} - -func (rd *VERSION) Len() int { - return len([]byte(rd.x)) -} - -var smallzone = `$ORIGIN example.org. -@ SOA sns.dns.icann.org. noc.dns.icann.org. ( - 2014091518 7200 3600 1209600 3600 -) - A 1.2.3.4 -ok ISBN 1231-92110-12 -go VERSION ( - 1.3.1 ; comment -) -www ISBN 1231-92110-16 -* CNAME @ -` - -func TestPrivateZoneParser(t *testing.T) { - dns.PrivateHandle("ISBN", TypeISBN, NewISBN) - dns.PrivateHandle("VERSION", TypeVERSION, NewVersion) - defer dns.PrivateHandleRemove(TypeISBN) - defer dns.PrivateHandleRemove(TypeVERSION) - - r := strings.NewReader(smallzone) - for x := range dns.ParseZone(r, ".", "") { - if err := x.Error; err != nil { - t.Fatal(err) - } - t.Log(x.RR) - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/rawmsg.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/rawmsg.go deleted file mode 100644 index 6e21fba7e..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/rawmsg.go +++ /dev/null @@ -1,49 +0,0 @@ -package dns - -import "encoding/binary" - -// rawSetRdlength sets the rdlength in the header of -// the RR. The offset 'off' must be positioned at the -// start of the header of the RR, 'end' must be the -// end of the RR. -func rawSetRdlength(msg []byte, off, end int) bool { - l := len(msg) -Loop: - for { - if off+1 > l { - return false - } - c := int(msg[off]) - off++ - switch c & 0xC0 { - case 0x00: - if c == 0x00 { - // End of the domainname - break Loop - } - if off+c > l { - return false - } - off += c - - case 0xC0: - // pointer, next byte included, ends domainname - off++ - break Loop - } - } - // The domainname has been seen, we at the start of the fixed part in the header. - // Type is 2 bytes, class is 2 bytes, ttl 4 and then 2 bytes for the length. - off += 2 + 2 + 4 - if off+2 > l { - return false - } - //off+1 is the end of the header, 'end' is the end of the rr - //so 'end' - 'off+2' is the length of the rdata - rdatalen := end - (off + 2) - if rdatalen > 0xFFFF { - return false - } - binary.BigEndian.PutUint16(msg[off:], uint16(rdatalen)) - return true -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/remote_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/remote_test.go deleted file mode 100644 index 4cf701fe4..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/remote_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package dns - -import "testing" - -const LinodeAddr = "176.58.119.54:53" - -func TestClientRemote(t *testing.T) { - m := new(Msg) - m.SetQuestion("go.dns.miek.nl.", TypeTXT) - - c := new(Client) - r, _, err := c.Exchange(m, LinodeAddr) - if err != nil { - t.Errorf("failed to exchange: %v", err) - } - if r != nil && r.Rcode != RcodeSuccess { - t.Errorf("failed to get an valid answer\n%v", r) - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/reverse.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/reverse.go deleted file mode 100644 index f6e7a47a6..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/reverse.go +++ /dev/null @@ -1,38 +0,0 @@ -package dns - -// StringToType is the reverse of TypeToString, needed for string parsing. -var StringToType = reverseInt16(TypeToString) - -// StringToClass is the reverse of ClassToString, needed for string parsing. -var StringToClass = reverseInt16(ClassToString) - -// StringToOpcode is a map of opcodes to strings. -var StringToOpcode = reverseInt(OpcodeToString) - -// StringToRcode is a map of rcodes to strings. -var StringToRcode = reverseInt(RcodeToString) - -// Reverse a map -func reverseInt8(m map[uint8]string) map[string]uint8 { - n := make(map[string]uint8, len(m)) - for u, s := range m { - n[s] = u - } - return n -} - -func reverseInt16(m map[uint16]string) map[string]uint16 { - n := make(map[string]uint16, len(m)) - for u, s := range m { - n[s] = u - } - return n -} - -func reverseInt(m map[int]string) map[string]int { - n := make(map[string]int, len(m)) - for u, s := range m { - n[s] = u - } - return n -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/sanitize.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/sanitize.go deleted file mode 100644 index b489f3f05..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/sanitize.go +++ /dev/null @@ -1,84 +0,0 @@ -package dns - -// Dedup removes identical RRs from rrs. It preserves the original ordering. -// The lowest TTL of any duplicates is used in the remaining one. Dedup modifies -// rrs. -// m is used to store the RRs temporay. If it is nil a new map will be allocated. -func Dedup(rrs []RR, m map[string]RR) []RR { - if m == nil { - m = make(map[string]RR) - } - // Save the keys, so we don't have to call normalizedString twice. - keys := make([]*string, 0, len(rrs)) - - for _, r := range rrs { - key := normalizedString(r) - keys = append(keys, &key) - if _, ok := m[key]; ok { - // Shortest TTL wins. - if m[key].Header().Ttl > r.Header().Ttl { - m[key].Header().Ttl = r.Header().Ttl - } - continue - } - - m[key] = r - } - // If the length of the result map equals the amount of RRs we got, - // it means they were all different. We can then just return the original rrset. - if len(m) == len(rrs) { - return rrs - } - - j := 0 - for i, r := range rrs { - // If keys[i] lives in the map, we should copy and remove it. - if _, ok := m[*keys[i]]; ok { - delete(m, *keys[i]) - rrs[j] = r - j++ - } - - if len(m) == 0 { - break - } - } - - return rrs[:j] -} - -// normalizedString returns a normalized string from r. The TTL -// is removed and the domain name is lowercased. We go from this: -// DomainName<TAB>TTL<TAB>CLASS<TAB>TYPE<TAB>RDATA to: -// lowercasename<TAB>CLASS<TAB>TYPE... -func normalizedString(r RR) string { - // A string Go DNS makes has: domainname<TAB>TTL<TAB>... - b := []byte(r.String()) - - // find the first non-escaped tab, then another, so we capture where the TTL lives. - esc := false - ttlStart, ttlEnd := 0, 0 - for i := 0; i < len(b) && ttlEnd == 0; i++ { - switch { - case b[i] == '\\': - esc = !esc - case b[i] == '\t' && !esc: - if ttlStart == 0 { - ttlStart = i - continue - } - if ttlEnd == 0 { - ttlEnd = i - } - case b[i] >= 'A' && b[i] <= 'Z' && !esc: - b[i] += 32 - default: - esc = false - } - } - - // remove TTL. - copy(b[ttlStart:], b[ttlEnd:]) - cut := ttlEnd - ttlStart - return string(b[:len(b)-cut]) -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/sanitize_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/sanitize_test.go deleted file mode 100644 index 2ba3fe9a3..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/sanitize_test.go +++ /dev/null @@ -1,84 +0,0 @@ -package dns - -import "testing" - -func TestDedup(t *testing.T) { - // make it []string - testcases := map[[3]RR][]string{ - [...]RR{ - newRR(t, "mIek.nl. IN A 127.0.0.1"), - newRR(t, "mieK.nl. IN A 127.0.0.1"), - newRR(t, "miek.Nl. IN A 127.0.0.1"), - }: {"mIek.nl.\t3600\tIN\tA\t127.0.0.1"}, - [...]RR{ - newRR(t, "miEk.nl. 2000 IN A 127.0.0.1"), - newRR(t, "mieK.Nl. 1000 IN A 127.0.0.1"), - newRR(t, "Miek.nL. 500 IN A 127.0.0.1"), - }: {"miEk.nl.\t500\tIN\tA\t127.0.0.1"}, - [...]RR{ - newRR(t, "miek.nl. IN A 127.0.0.1"), - newRR(t, "miek.nl. CH A 127.0.0.1"), - newRR(t, "miek.nl. IN A 127.0.0.1"), - }: {"miek.nl.\t3600\tIN\tA\t127.0.0.1", - "miek.nl.\t3600\tCH\tA\t127.0.0.1", - }, - [...]RR{ - newRR(t, "miek.nl. CH A 127.0.0.1"), - newRR(t, "miek.nl. IN A 127.0.0.1"), - newRR(t, "miek.de. IN A 127.0.0.1"), - }: {"miek.nl.\t3600\tCH\tA\t127.0.0.1", - "miek.nl.\t3600\tIN\tA\t127.0.0.1", - "miek.de.\t3600\tIN\tA\t127.0.0.1", - }, - [...]RR{ - newRR(t, "miek.de. IN A 127.0.0.1"), - newRR(t, "miek.nl. 200 IN A 127.0.0.1"), - newRR(t, "miek.nl. 300 IN A 127.0.0.1"), - }: {"miek.de.\t3600\tIN\tA\t127.0.0.1", - "miek.nl.\t200\tIN\tA\t127.0.0.1", - }, - } - - for rr, expected := range testcases { - out := Dedup([]RR{rr[0], rr[1], rr[2]}, nil) - for i, o := range out { - if o.String() != expected[i] { - t.Fatalf("expected %v, got %v", expected[i], o.String()) - } - } - } -} - -func BenchmarkDedup(b *testing.B) { - rrs := []RR{ - newRR(nil, "miEk.nl. 2000 IN A 127.0.0.1"), - newRR(nil, "mieK.Nl. 1000 IN A 127.0.0.1"), - newRR(nil, "Miek.nL. 500 IN A 127.0.0.1"), - } - m := make(map[string]RR) - for i := 0; i < b.N; i++ { - Dedup(rrs, m) - } -} - -func TestNormalizedString(t *testing.T) { - tests := map[RR]string{ - newRR(t, "mIEk.Nl. 3600 IN A 127.0.0.1"): "miek.nl.\tIN\tA\t127.0.0.1", - newRR(t, "m\\ iek.nL. 3600 IN A 127.0.0.1"): "m\\ iek.nl.\tIN\tA\t127.0.0.1", - newRR(t, "m\\\tIeK.nl. 3600 in A 127.0.0.1"): "m\\009iek.nl.\tIN\tA\t127.0.0.1", - } - for tc, expected := range tests { - n := normalizedString(tc) - if n != expected { - t.Errorf("expected %s, got %s", expected, n) - } - } -} - -func newRR(t *testing.T, s string) RR { - r, err := NewRR(s) - if err != nil { - t.Logf("newRR: %v", err) - } - return r -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/scan.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/scan.go deleted file mode 100644 index 8d4773c3e..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/scan.go +++ /dev/null @@ -1,987 +0,0 @@ -package dns - -import ( - "io" - "log" - "os" - "strconv" - "strings" -) - -type debugging bool - -const debug debugging = false - -func (d debugging) Printf(format string, args ...interface{}) { - if d { - log.Printf(format, args...) - } -} - -const maxTok = 2048 // Largest token we can return. -const maxUint16 = 1<<16 - 1 - -// Tokinize a RFC 1035 zone file. The tokenizer will normalize it: -// * Add ownernames if they are left blank; -// * Suppress sequences of spaces; -// * Make each RR fit on one line (_NEWLINE is send as last) -// * Handle comments: ; -// * Handle braces - anywhere. -const ( - // Zonefile - zEOF = iota - zString - zBlank - zQuote - zNewline - zRrtpe - zOwner - zClass - zDirOrigin // $ORIGIN - zDirTtl // $TTL - zDirInclude // $INCLUDE - zDirGenerate // $GENERATE - - // Privatekey file - zValue - zKey - - zExpectOwnerDir // Ownername - zExpectOwnerBl // Whitespace after the ownername - zExpectAny // Expect rrtype, ttl or class - zExpectAnyNoClass // Expect rrtype or ttl - zExpectAnyNoClassBl // The whitespace after _EXPECT_ANY_NOCLASS - zExpectAnyNoTtl // Expect rrtype or class - zExpectAnyNoTtlBl // Whitespace after _EXPECT_ANY_NOTTL - zExpectRrtype // Expect rrtype - zExpectRrtypeBl // Whitespace BEFORE rrtype - zExpectRdata // The first element of the rdata - zExpectDirTtlBl // Space after directive $TTL - zExpectDirTtl // Directive $TTL - zExpectDirOriginBl // Space after directive $ORIGIN - zExpectDirOrigin // Directive $ORIGIN - zExpectDirIncludeBl // Space after directive $INCLUDE - zExpectDirInclude // Directive $INCLUDE - zExpectDirGenerate // Directive $GENERATE - zExpectDirGenerateBl // Space after directive $GENERATE -) - -// ParseError is a parsing error. It contains the parse error and the location in the io.Reader -// where the error occurred. -type ParseError struct { - file string - err string - lex lex -} - -func (e *ParseError) Error() (s string) { - if e.file != "" { - s = e.file + ": " - } - s += "dns: " + e.err + ": " + strconv.QuoteToASCII(e.lex.token) + " at line: " + - strconv.Itoa(e.lex.line) + ":" + strconv.Itoa(e.lex.column) - return -} - -type lex struct { - token string // text of the token - tokenUpper string // uppercase text of the token - length int // length of the token - err bool // when true, token text has lexer error - value uint8 // value: zString, _BLANK, etc. - line int // line in the file - column int // column in the file - torc uint16 // type or class as parsed in the lexer, we only need to look this up in the grammar - comment string // any comment text seen -} - -// Token holds the token that are returned when a zone file is parsed. -type Token struct { - // The scanned resource record when error is not nil. - RR - // When an error occurred, this has the error specifics. - Error *ParseError - // A potential comment positioned after the RR and on the same line. - Comment string -} - -// NewRR reads the RR contained in the string s. Only the first RR is -// returned. If s contains no RR, return nil with no error. The class -// defaults to IN and TTL defaults to 3600. The full zone file syntax -// like $TTL, $ORIGIN, etc. is supported. All fields of the returned -// RR are set, except RR.Header().Rdlength which is set to 0. -func NewRR(s string) (RR, error) { - if len(s) > 0 && s[len(s)-1] != '\n' { // We need a closing newline - return ReadRR(strings.NewReader(s+"\n"), "") - } - return ReadRR(strings.NewReader(s), "") -} - -// ReadRR reads the RR contained in q. -// See NewRR for more documentation. -func ReadRR(q io.Reader, filename string) (RR, error) { - r := <-parseZoneHelper(q, ".", filename, 1) - if r == nil { - return nil, nil - } - - if r.Error != nil { - return nil, r.Error - } - return r.RR, nil -} - -// ParseZone reads a RFC 1035 style zonefile from r. It returns *Tokens on the -// returned channel, which consist out the parsed RR, a potential comment or an error. -// If there is an error the RR is nil. The string file is only used -// in error reporting. The string origin is used as the initial origin, as -// if the file would start with: $ORIGIN origin . -// The directives $INCLUDE, $ORIGIN, $TTL and $GENERATE are supported. -// The channel t is closed by ParseZone when the end of r is reached. -// -// Basic usage pattern when reading from a string (z) containing the -// zone data: -// -// for x := range dns.ParseZone(strings.NewReader(z), "", "") { -// if x.Error != nil { -// // log.Println(x.Error) -// } else { -// // Do something with x.RR -// } -// } -// -// Comments specified after an RR (and on the same line!) are returned too: -// -// foo. IN A 10.0.0.1 ; this is a comment -// -// The text "; this is comment" is returned in Token.Comment. Comments inside the -// RR are discarded. Comments on a line by themselves are discarded too. -func ParseZone(r io.Reader, origin, file string) chan *Token { - return parseZoneHelper(r, origin, file, 10000) -} - -func parseZoneHelper(r io.Reader, origin, file string, chansize int) chan *Token { - t := make(chan *Token, chansize) - go parseZone(r, origin, file, t, 0) - return t -} - -func parseZone(r io.Reader, origin, f string, t chan *Token, include int) { - defer func() { - if include == 0 { - close(t) - } - }() - s := scanInit(r) - c := make(chan lex) - // Start the lexer - go zlexer(s, c) - // 6 possible beginnings of a line, _ is a space - // 0. zRRTYPE -> all omitted until the rrtype - // 1. zOwner _ zRrtype -> class/ttl omitted - // 2. zOwner _ zString _ zRrtype -> class omitted - // 3. zOwner _ zString _ zClass _ zRrtype -> ttl/class - // 4. zOwner _ zClass _ zRrtype -> ttl omitted - // 5. zOwner _ zClass _ zString _ zRrtype -> class/ttl (reversed) - // After detecting these, we know the zRrtype so we can jump to functions - // handling the rdata for each of these types. - - if origin == "" { - origin = "." - } - origin = Fqdn(origin) - if _, ok := IsDomainName(origin); !ok { - t <- &Token{Error: &ParseError{f, "bad initial origin name", lex{}}} - return - } - - st := zExpectOwnerDir // initial state - var h RR_Header - var defttl uint32 = defaultTtl - var prevName string - for l := range c { - // Lexer spotted an error already - if l.err == true { - t <- &Token{Error: &ParseError{f, l.token, l}} - return - - } - switch st { - case zExpectOwnerDir: - // We can also expect a directive, like $TTL or $ORIGIN - h.Ttl = defttl - h.Class = ClassINET - switch l.value { - case zNewline: - st = zExpectOwnerDir - case zOwner: - h.Name = l.token - if l.token[0] == '@' { - h.Name = origin - prevName = h.Name - st = zExpectOwnerBl - break - } - if h.Name[l.length-1] != '.' { - h.Name = appendOrigin(h.Name, origin) - } - _, ok := IsDomainName(l.token) - if !ok { - t <- &Token{Error: &ParseError{f, "bad owner name", l}} - return - } - prevName = h.Name - st = zExpectOwnerBl - case zDirTtl: - st = zExpectDirTtlBl - case zDirOrigin: - st = zExpectDirOriginBl - case zDirInclude: - st = zExpectDirIncludeBl - case zDirGenerate: - st = zExpectDirGenerateBl - case zRrtpe: - h.Name = prevName - h.Rrtype = l.torc - st = zExpectRdata - case zClass: - h.Name = prevName - h.Class = l.torc - st = zExpectAnyNoClassBl - case zBlank: - // Discard, can happen when there is nothing on the - // line except the RR type - case zString: - ttl, ok := stringToTtl(l.token) - if !ok { - t <- &Token{Error: &ParseError{f, "not a TTL", l}} - return - } - h.Ttl = ttl - // Don't about the defttl, we should take the $TTL value - // defttl = ttl - st = zExpectAnyNoTtlBl - - default: - t <- &Token{Error: &ParseError{f, "syntax error at beginning", l}} - return - } - case zExpectDirIncludeBl: - if l.value != zBlank { - t <- &Token{Error: &ParseError{f, "no blank after $INCLUDE-directive", l}} - return - } - st = zExpectDirInclude - case zExpectDirInclude: - if l.value != zString { - t <- &Token{Error: &ParseError{f, "expecting $INCLUDE value, not this...", l}} - return - } - neworigin := origin // There may be optionally a new origin set after the filename, if not use current one - l := <-c - switch l.value { - case zBlank: - l := <-c - if l.value == zString { - if _, ok := IsDomainName(l.token); !ok || l.length == 0 || l.err { - t <- &Token{Error: &ParseError{f, "bad origin name", l}} - return - } - // a new origin is specified. - if l.token[l.length-1] != '.' { - if origin != "." { // Prevent .. endings - neworigin = l.token + "." + origin - } else { - neworigin = l.token + origin - } - } else { - neworigin = l.token - } - } - case zNewline, zEOF: - // Ok - default: - t <- &Token{Error: &ParseError{f, "garbage after $INCLUDE", l}} - return - } - // Start with the new file - r1, e1 := os.Open(l.token) - if e1 != nil { - t <- &Token{Error: &ParseError{f, "failed to open `" + l.token + "'", l}} - return - } - if include+1 > 7 { - t <- &Token{Error: &ParseError{f, "too deeply nested $INCLUDE", l}} - return - } - parseZone(r1, l.token, neworigin, t, include+1) - st = zExpectOwnerDir - case zExpectDirTtlBl: - if l.value != zBlank { - t <- &Token{Error: &ParseError{f, "no blank after $TTL-directive", l}} - return - } - st = zExpectDirTtl - case zExpectDirTtl: - if l.value != zString { - t <- &Token{Error: &ParseError{f, "expecting $TTL value, not this...", l}} - return - } - if e, _ := slurpRemainder(c, f); e != nil { - t <- &Token{Error: e} - return - } - ttl, ok := stringToTtl(l.token) - if !ok { - t <- &Token{Error: &ParseError{f, "expecting $TTL value, not this...", l}} - return - } - defttl = ttl - st = zExpectOwnerDir - case zExpectDirOriginBl: - if l.value != zBlank { - t <- &Token{Error: &ParseError{f, "no blank after $ORIGIN-directive", l}} - return - } - st = zExpectDirOrigin - case zExpectDirOrigin: - if l.value != zString { - t <- &Token{Error: &ParseError{f, "expecting $ORIGIN value, not this...", l}} - return - } - if e, _ := slurpRemainder(c, f); e != nil { - t <- &Token{Error: e} - } - if _, ok := IsDomainName(l.token); !ok { - t <- &Token{Error: &ParseError{f, "bad origin name", l}} - return - } - if l.token[l.length-1] != '.' { - if origin != "." { // Prevent .. endings - origin = l.token + "." + origin - } else { - origin = l.token + origin - } - } else { - origin = l.token - } - st = zExpectOwnerDir - case zExpectDirGenerateBl: - if l.value != zBlank { - t <- &Token{Error: &ParseError{f, "no blank after $GENERATE-directive", l}} - return - } - st = zExpectDirGenerate - case zExpectDirGenerate: - if l.value != zString { - t <- &Token{Error: &ParseError{f, "expecting $GENERATE value, not this...", l}} - return - } - if errMsg := generate(l, c, t, origin); errMsg != "" { - t <- &Token{Error: &ParseError{f, errMsg, l}} - return - } - st = zExpectOwnerDir - case zExpectOwnerBl: - if l.value != zBlank { - t <- &Token{Error: &ParseError{f, "no blank after owner", l}} - return - } - st = zExpectAny - case zExpectAny: - switch l.value { - case zRrtpe: - h.Rrtype = l.torc - st = zExpectRdata - case zClass: - h.Class = l.torc - st = zExpectAnyNoClassBl - case zString: - ttl, ok := stringToTtl(l.token) - if !ok { - t <- &Token{Error: &ParseError{f, "not a TTL", l}} - return - } - h.Ttl = ttl - // defttl = ttl // don't set the defttl here - st = zExpectAnyNoTtlBl - default: - t <- &Token{Error: &ParseError{f, "expecting RR type, TTL or class, not this...", l}} - return - } - case zExpectAnyNoClassBl: - if l.value != zBlank { - t <- &Token{Error: &ParseError{f, "no blank before class", l}} - return - } - st = zExpectAnyNoClass - case zExpectAnyNoTtlBl: - if l.value != zBlank { - t <- &Token{Error: &ParseError{f, "no blank before TTL", l}} - return - } - st = zExpectAnyNoTtl - case zExpectAnyNoTtl: - switch l.value { - case zClass: - h.Class = l.torc - st = zExpectRrtypeBl - case zRrtpe: - h.Rrtype = l.torc - st = zExpectRdata - default: - t <- &Token{Error: &ParseError{f, "expecting RR type or class, not this...", l}} - return - } - case zExpectAnyNoClass: - switch l.value { - case zString: - ttl, ok := stringToTtl(l.token) - if !ok { - t <- &Token{Error: &ParseError{f, "not a TTL", l}} - return - } - h.Ttl = ttl - // defttl = ttl // don't set the def ttl anymore - st = zExpectRrtypeBl - case zRrtpe: - h.Rrtype = l.torc - st = zExpectRdata - default: - t <- &Token{Error: &ParseError{f, "expecting RR type or TTL, not this...", l}} - return - } - case zExpectRrtypeBl: - if l.value != zBlank { - t <- &Token{Error: &ParseError{f, "no blank before RR type", l}} - return - } - st = zExpectRrtype - case zExpectRrtype: - if l.value != zRrtpe { - t <- &Token{Error: &ParseError{f, "unknown RR type", l}} - return - } - h.Rrtype = l.torc - st = zExpectRdata - case zExpectRdata: - r, e, c1 := setRR(h, c, origin, f) - if e != nil { - // If e.lex is nil than we have encounter a unknown RR type - // in that case we substitute our current lex token - if e.lex.token == "" && e.lex.value == 0 { - e.lex = l // Uh, dirty - } - t <- &Token{Error: e} - return - } - t <- &Token{RR: r, Comment: c1} - st = zExpectOwnerDir - } - } - // If we get here, we and the h.Rrtype is still zero, we haven't parsed anything, this - // is not an error, because an empty zone file is still a zone file. -} - -// zlexer scans the sourcefile and returns tokens on the channel c. -func zlexer(s *scan, c chan lex) { - var l lex - str := make([]byte, maxTok) // Should be enough for any token - stri := 0 // Offset in str (0 means empty) - com := make([]byte, maxTok) // Hold comment text - comi := 0 - quote := false - escape := false - space := false - commt := false - rrtype := false - owner := true - brace := 0 - x, err := s.tokenText() - defer close(c) - for err == nil { - l.column = s.position.Column - l.line = s.position.Line - if stri >= maxTok { - l.token = "token length insufficient for parsing" - l.err = true - debug.Printf("[%+v]", l.token) - c <- l - return - } - if comi >= maxTok { - l.token = "comment length insufficient for parsing" - l.err = true - debug.Printf("[%+v]", l.token) - c <- l - return - } - - switch x { - case ' ', '\t': - if escape { - escape = false - str[stri] = x - stri++ - break - } - if quote { - // Inside quotes this is legal - str[stri] = x - stri++ - break - } - if commt { - com[comi] = x - comi++ - break - } - if stri == 0 { - // Space directly in the beginning, handled in the grammar - } else if owner { - // If we have a string and its the first, make it an owner - l.value = zOwner - l.token = string(str[:stri]) - l.tokenUpper = strings.ToUpper(l.token) - l.length = stri - // escape $... start with a \ not a $, so this will work - switch l.tokenUpper { - case "$TTL": - l.value = zDirTtl - case "$ORIGIN": - l.value = zDirOrigin - case "$INCLUDE": - l.value = zDirInclude - case "$GENERATE": - l.value = zDirGenerate - } - debug.Printf("[7 %+v]", l.token) - c <- l - } else { - l.value = zString - l.token = string(str[:stri]) - l.tokenUpper = strings.ToUpper(l.token) - l.length = stri - if !rrtype { - if t, ok := StringToType[l.tokenUpper]; ok { - l.value = zRrtpe - l.torc = t - rrtype = true - } else { - if strings.HasPrefix(l.tokenUpper, "TYPE") { - t, ok := typeToInt(l.token) - if !ok { - l.token = "unknown RR type" - l.err = true - c <- l - return - } - l.value = zRrtpe - l.torc = t - } - } - if t, ok := StringToClass[l.tokenUpper]; ok { - l.value = zClass - l.torc = t - } else { - if strings.HasPrefix(l.tokenUpper, "CLASS") { - t, ok := classToInt(l.token) - if !ok { - l.token = "unknown class" - l.err = true - c <- l - return - } - l.value = zClass - l.torc = t - } - } - } - debug.Printf("[6 %+v]", l.token) - c <- l - } - stri = 0 - // I reverse space stuff here - if !space && !commt { - l.value = zBlank - l.token = " " - l.length = 1 - debug.Printf("[5 %+v]", l.token) - c <- l - } - owner = false - space = true - case ';': - if escape { - escape = false - str[stri] = x - stri++ - break - } - if quote { - // Inside quotes this is legal - str[stri] = x - stri++ - break - } - if stri > 0 { - l.value = zString - l.token = string(str[:stri]) - l.tokenUpper = strings.ToUpper(l.token) - l.length = stri - debug.Printf("[4 %+v]", l.token) - c <- l - stri = 0 - } - commt = true - com[comi] = ';' - comi++ - case '\r': - escape = false - if quote { - str[stri] = x - stri++ - break - } - // discard if outside of quotes - case '\n': - escape = false - // Escaped newline - if quote { - str[stri] = x - stri++ - break - } - // inside quotes this is legal - if commt { - // Reset a comment - commt = false - rrtype = false - stri = 0 - // If not in a brace this ends the comment AND the RR - if brace == 0 { - owner = true - owner = true - l.value = zNewline - l.token = "\n" - l.tokenUpper = l.token - l.length = 1 - l.comment = string(com[:comi]) - debug.Printf("[3 %+v %+v]", l.token, l.comment) - c <- l - l.comment = "" - comi = 0 - break - } - com[comi] = ' ' // convert newline to space - comi++ - break - } - - if brace == 0 { - // If there is previous text, we should output it here - if stri != 0 { - l.value = zString - l.token = string(str[:stri]) - l.tokenUpper = strings.ToUpper(l.token) - - l.length = stri - if !rrtype { - if t, ok := StringToType[l.tokenUpper]; ok { - l.value = zRrtpe - l.torc = t - rrtype = true - } - } - debug.Printf("[2 %+v]", l.token) - c <- l - } - l.value = zNewline - l.token = "\n" - l.tokenUpper = l.token - l.length = 1 - debug.Printf("[1 %+v]", l.token) - c <- l - stri = 0 - commt = false - rrtype = false - owner = true - comi = 0 - } - case '\\': - // comments do not get escaped chars, everything is copied - if commt { - com[comi] = x - comi++ - break - } - // something already escaped must be in string - if escape { - str[stri] = x - stri++ - escape = false - break - } - // something escaped outside of string gets added to string - str[stri] = x - stri++ - escape = true - case '"': - if commt { - com[comi] = x - comi++ - break - } - if escape { - str[stri] = x - stri++ - escape = false - break - } - space = false - // send previous gathered text and the quote - if stri != 0 { - l.value = zString - l.token = string(str[:stri]) - l.tokenUpper = strings.ToUpper(l.token) - l.length = stri - - debug.Printf("[%+v]", l.token) - c <- l - stri = 0 - } - - // send quote itself as separate token - l.value = zQuote - l.token = "\"" - l.tokenUpper = l.token - l.length = 1 - c <- l - quote = !quote - case '(', ')': - if commt { - com[comi] = x - comi++ - break - } - if escape { - str[stri] = x - stri++ - escape = false - break - } - if quote { - str[stri] = x - stri++ - break - } - switch x { - case ')': - brace-- - if brace < 0 { - l.token = "extra closing brace" - l.tokenUpper = l.token - l.err = true - debug.Printf("[%+v]", l.token) - c <- l - return - } - case '(': - brace++ - } - default: - escape = false - if commt { - com[comi] = x - comi++ - break - } - str[stri] = x - stri++ - space = false - } - x, err = s.tokenText() - } - if stri > 0 { - // Send remainder - l.token = string(str[:stri]) - l.tokenUpper = strings.ToUpper(l.token) - l.length = stri - l.value = zString - debug.Printf("[%+v]", l.token) - c <- l - } - if brace != 0 { - l.token = "unbalanced brace" - l.tokenUpper = l.token - l.err = true - c <- l - } -} - -// Extract the class number from CLASSxx -func classToInt(token string) (uint16, bool) { - offset := 5 - if len(token) < offset+1 { - return 0, false - } - class, err := strconv.ParseUint(token[offset:], 10, 16) - if err != nil { - return 0, false - } - return uint16(class), true -} - -// Extract the rr number from TYPExxx -func typeToInt(token string) (uint16, bool) { - offset := 4 - if len(token) < offset+1 { - return 0, false - } - typ, err := strconv.ParseUint(token[offset:], 10, 16) - if err != nil { - return 0, false - } - return uint16(typ), true -} - -// Parse things like 2w, 2m, etc, Return the time in seconds. -func stringToTtl(token string) (uint32, bool) { - s := uint32(0) - i := uint32(0) - for _, c := range token { - switch c { - case 's', 'S': - s += i - i = 0 - case 'm', 'M': - s += i * 60 - i = 0 - case 'h', 'H': - s += i * 60 * 60 - i = 0 - case 'd', 'D': - s += i * 60 * 60 * 24 - i = 0 - case 'w', 'W': - s += i * 60 * 60 * 24 * 7 - i = 0 - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - i *= 10 - i += uint32(c) - '0' - default: - return 0, false - } - } - return s + i, true -} - -// Parse LOC records' <digits>[.<digits>][mM] into a -// mantissa exponent format. Token should contain the entire -// string (i.e. no spaces allowed) -func stringToCm(token string) (e, m uint8, ok bool) { - if token[len(token)-1] == 'M' || token[len(token)-1] == 'm' { - token = token[0 : len(token)-1] - } - s := strings.SplitN(token, ".", 2) - var meters, cmeters, val int - var err error - switch len(s) { - case 2: - if cmeters, err = strconv.Atoi(s[1]); err != nil { - return - } - fallthrough - case 1: - if meters, err = strconv.Atoi(s[0]); err != nil { - return - } - case 0: - // huh? - return 0, 0, false - } - ok = true - if meters > 0 { - e = 2 - val = meters - } else { - e = 0 - val = cmeters - } - for val > 10 { - e++ - val /= 10 - } - if e > 9 { - ok = false - } - m = uint8(val) - return -} - -func appendOrigin(name, origin string) string { - if origin == "." { - return name + origin - } - return name + "." + origin -} - -// LOC record helper function -func locCheckNorth(token string, latitude uint32) (uint32, bool) { - switch token { - case "n", "N": - return LOC_EQUATOR + latitude, true - case "s", "S": - return LOC_EQUATOR - latitude, true - } - return latitude, false -} - -// LOC record helper function -func locCheckEast(token string, longitude uint32) (uint32, bool) { - switch token { - case "e", "E": - return LOC_EQUATOR + longitude, true - case "w", "W": - return LOC_EQUATOR - longitude, true - } - return longitude, false -} - -// "Eat" the rest of the "line". Return potential comments -func slurpRemainder(c chan lex, f string) (*ParseError, string) { - l := <-c - com := "" - switch l.value { - case zBlank: - l = <-c - com = l.comment - if l.value != zNewline && l.value != zEOF { - return &ParseError{f, "garbage after rdata", l}, "" - } - case zNewline: - com = l.comment - case zEOF: - default: - return &ParseError{f, "garbage after rdata", l}, "" - } - return nil, com -} - -// Parse a 64 bit-like ipv6 address: "0014:4fff:ff20:ee64" -// Used for NID and L64 record. -func stringToNodeID(l lex) (uint64, *ParseError) { - if len(l.token) < 19 { - return 0, &ParseError{l.token, "bad NID/L64 NodeID/Locator64", l} - } - // There must be three colons at fixes postitions, if not its a parse error - if l.token[4] != ':' && l.token[9] != ':' && l.token[14] != ':' { - return 0, &ParseError{l.token, "bad NID/L64 NodeID/Locator64", l} - } - s := l.token[0:4] + l.token[5:9] + l.token[10:14] + l.token[15:19] - u, err := strconv.ParseUint(s, 16, 64) - if err != nil { - return 0, &ParseError{l.token, "bad NID/L64 NodeID/Locator64", l} - } - return u, nil -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/scan_rr.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/scan_rr.go deleted file mode 100644 index b8b18fd77..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/scan_rr.go +++ /dev/null @@ -1,2184 +0,0 @@ -package dns - -import ( - "encoding/base64" - "net" - "strconv" - "strings" -) - -type parserFunc struct { - // Func defines the function that parses the tokens and returns the RR - // or an error. The last string contains any comments in the line as - // they returned by the lexer as well. - Func func(h RR_Header, c chan lex, origin string, file string) (RR, *ParseError, string) - // Signals if the RR ending is of variable length, like TXT or records - // that have Hexadecimal or Base64 as their last element in the Rdata. Records - // that have a fixed ending or for instance A, AAAA, SOA and etc. - Variable bool -} - -// Parse the rdata of each rrtype. -// All data from the channel c is either zString or zBlank. -// After the rdata there may come a zBlank and then a zNewline -// or immediately a zNewline. If this is not the case we flag -// an *ParseError: garbage after rdata. -func setRR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - parserfunc, ok := typeToparserFunc[h.Rrtype] - if ok { - r, e, cm := parserfunc.Func(h, c, o, f) - if parserfunc.Variable { - return r, e, cm - } - if e != nil { - return nil, e, "" - } - e, cm = slurpRemainder(c, f) - if e != nil { - return nil, e, "" - } - return r, nil, cm - } - // RFC3957 RR (Unknown RR handling) - return setRFC3597(h, c, o, f) -} - -// A remainder of the rdata with embedded spaces, return the parsed string (sans the spaces) -// or an error -func endingToString(c chan lex, errstr, f string) (string, *ParseError, string) { - s := "" - l := <-c // zString - for l.value != zNewline && l.value != zEOF { - if l.err { - return s, &ParseError{f, errstr, l}, "" - } - switch l.value { - case zString: - s += l.token - case zBlank: // Ok - default: - return "", &ParseError{f, errstr, l}, "" - } - l = <-c - } - return s, nil, l.comment -} - -// A remainder of the rdata with embedded spaces, split on unquoted whitespace -// and return the parsed string slice or an error -func endingToTxtSlice(c chan lex, errstr, f string) ([]string, *ParseError, string) { - // Get the remaining data until we see a zNewline - l := <-c - if l.err { - return nil, &ParseError{f, errstr, l}, "" - } - - // Build the slice - s := make([]string, 0) - quote := false - empty := false - for l.value != zNewline && l.value != zEOF { - if l.err { - return nil, &ParseError{f, errstr, l}, "" - } - switch l.value { - case zString: - empty = false - if len(l.token) > 255 { - // split up tokens that are larger than 255 into 255-chunks - sx := []string{} - p, i := 0, 255 - for { - if i <= len(l.token) { - sx = append(sx, l.token[p:i]) - } else { - sx = append(sx, l.token[p:]) - break - - } - p, i = p+255, i+255 - } - s = append(s, sx...) - break - } - - s = append(s, l.token) - case zBlank: - if quote { - // zBlank can only be seen in between txt parts. - return nil, &ParseError{f, errstr, l}, "" - } - case zQuote: - if empty && quote { - s = append(s, "") - } - quote = !quote - empty = true - default: - return nil, &ParseError{f, errstr, l}, "" - } - l = <-c - } - if quote { - return nil, &ParseError{f, errstr, l}, "" - } - return s, nil, l.comment -} - -func setA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(A) - rr.Hdr = h - - l := <-c - if l.length == 0 { // Dynamic updates. - return rr, nil, "" - } - rr.A = net.ParseIP(l.token) - if rr.A == nil || l.err { - return nil, &ParseError{f, "bad A A", l}, "" - } - return rr, nil, "" -} - -func setAAAA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(AAAA) - rr.Hdr = h - - l := <-c - if l.length == 0 { - return rr, nil, "" - } - rr.AAAA = net.ParseIP(l.token) - if rr.AAAA == nil || l.err { - return nil, &ParseError{f, "bad AAAA AAAA", l}, "" - } - return rr, nil, "" -} - -func setNS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(NS) - rr.Hdr = h - - l := <-c - rr.Ns = l.token - if l.length == 0 { - return rr, nil, "" - } - if l.token == "@" { - rr.Ns = o - return rr, nil, "" - } - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad NS Ns", l}, "" - } - if rr.Ns[l.length-1] != '.' { - rr.Ns = appendOrigin(rr.Ns, o) - } - return rr, nil, "" -} - -func setPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(PTR) - rr.Hdr = h - - l := <-c - rr.Ptr = l.token - if l.length == 0 { // dynamic update rr. - return rr, nil, "" - } - if l.token == "@" { - rr.Ptr = o - return rr, nil, "" - } - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad PTR Ptr", l}, "" - } - if rr.Ptr[l.length-1] != '.' { - rr.Ptr = appendOrigin(rr.Ptr, o) - } - return rr, nil, "" -} - -func setNSAPPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(NSAPPTR) - rr.Hdr = h - - l := <-c - rr.Ptr = l.token - if l.length == 0 { - return rr, nil, "" - } - if l.token == "@" { - rr.Ptr = o - return rr, nil, "" - } - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad NSAP-PTR Ptr", l}, "" - } - if rr.Ptr[l.length-1] != '.' { - rr.Ptr = appendOrigin(rr.Ptr, o) - } - return rr, nil, "" -} - -func setRP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(RP) - rr.Hdr = h - - l := <-c - rr.Mbox = l.token - if l.length == 0 { - return rr, nil, "" - } - if l.token == "@" { - rr.Mbox = o - } else { - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad RP Mbox", l}, "" - } - if rr.Mbox[l.length-1] != '.' { - rr.Mbox = appendOrigin(rr.Mbox, o) - } - } - <-c // zBlank - l = <-c - rr.Txt = l.token - if l.token == "@" { - rr.Txt = o - return rr, nil, "" - } - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad RP Txt", l}, "" - } - if rr.Txt[l.length-1] != '.' { - rr.Txt = appendOrigin(rr.Txt, o) - } - return rr, nil, "" -} - -func setMR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(MR) - rr.Hdr = h - - l := <-c - rr.Mr = l.token - if l.length == 0 { - return rr, nil, "" - } - if l.token == "@" { - rr.Mr = o - return rr, nil, "" - } - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad MR Mr", l}, "" - } - if rr.Mr[l.length-1] != '.' { - rr.Mr = appendOrigin(rr.Mr, o) - } - return rr, nil, "" -} - -func setMB(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(MB) - rr.Hdr = h - - l := <-c - rr.Mb = l.token - if l.length == 0 { - return rr, nil, "" - } - if l.token == "@" { - rr.Mb = o - return rr, nil, "" - } - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad MB Mb", l}, "" - } - if rr.Mb[l.length-1] != '.' { - rr.Mb = appendOrigin(rr.Mb, o) - } - return rr, nil, "" -} - -func setMG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(MG) - rr.Hdr = h - - l := <-c - rr.Mg = l.token - if l.length == 0 { - return rr, nil, "" - } - if l.token == "@" { - rr.Mg = o - return rr, nil, "" - } - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad MG Mg", l}, "" - } - if rr.Mg[l.length-1] != '.' { - rr.Mg = appendOrigin(rr.Mg, o) - } - return rr, nil, "" -} - -func setHINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(HINFO) - rr.Hdr = h - - chunks, e, c1 := endingToTxtSlice(c, "bad HINFO Fields", f) - if e != nil { - return nil, e, c1 - } - - if ln := len(chunks); ln == 0 { - return rr, nil, "" - } else if ln == 1 { - // Can we split it? - if out := strings.Fields(chunks[0]); len(out) > 1 { - chunks = out - } else { - chunks = append(chunks, "") - } - } - - rr.Cpu = chunks[0] - rr.Os = strings.Join(chunks[1:], " ") - - return rr, nil, "" -} - -func setMINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(MINFO) - rr.Hdr = h - - l := <-c - rr.Rmail = l.token - if l.length == 0 { - return rr, nil, "" - } - if l.token == "@" { - rr.Rmail = o - } else { - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad MINFO Rmail", l}, "" - } - if rr.Rmail[l.length-1] != '.' { - rr.Rmail = appendOrigin(rr.Rmail, o) - } - } - <-c // zBlank - l = <-c - rr.Email = l.token - if l.token == "@" { - rr.Email = o - return rr, nil, "" - } - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad MINFO Email", l}, "" - } - if rr.Email[l.length-1] != '.' { - rr.Email = appendOrigin(rr.Email, o) - } - return rr, nil, "" -} - -func setMF(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(MF) - rr.Hdr = h - - l := <-c - rr.Mf = l.token - if l.length == 0 { - return rr, nil, "" - } - if l.token == "@" { - rr.Mf = o - return rr, nil, "" - } - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad MF Mf", l}, "" - } - if rr.Mf[l.length-1] != '.' { - rr.Mf = appendOrigin(rr.Mf, o) - } - return rr, nil, "" -} - -func setMD(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(MD) - rr.Hdr = h - - l := <-c - rr.Md = l.token - if l.length == 0 { - return rr, nil, "" - } - if l.token == "@" { - rr.Md = o - return rr, nil, "" - } - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad MD Md", l}, "" - } - if rr.Md[l.length-1] != '.' { - rr.Md = appendOrigin(rr.Md, o) - } - return rr, nil, "" -} - -func setMX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(MX) - rr.Hdr = h - - l := <-c - if l.length == 0 { - return rr, nil, "" - } - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return nil, &ParseError{f, "bad MX Pref", l}, "" - } - rr.Preference = uint16(i) - <-c // zBlank - l = <-c // zString - rr.Mx = l.token - if l.token == "@" { - rr.Mx = o - return rr, nil, "" - } - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad MX Mx", l}, "" - } - if rr.Mx[l.length-1] != '.' { - rr.Mx = appendOrigin(rr.Mx, o) - } - return rr, nil, "" -} - -func setRT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(RT) - rr.Hdr = h - l := <-c - if l.length == 0 { - return rr, nil, "" - } - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil { - return nil, &ParseError{f, "bad RT Preference", l}, "" - } - rr.Preference = uint16(i) - <-c // zBlank - l = <-c // zString - rr.Host = l.token - if l.token == "@" { - rr.Host = o - return rr, nil, "" - } - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad RT Host", l}, "" - } - if rr.Host[l.length-1] != '.' { - rr.Host = appendOrigin(rr.Host, o) - } - return rr, nil, "" -} - -func setAFSDB(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(AFSDB) - rr.Hdr = h - - l := <-c - if l.length == 0 { - return rr, nil, "" - } - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return nil, &ParseError{f, "bad AFSDB Subtype", l}, "" - } - rr.Subtype = uint16(i) - <-c // zBlank - l = <-c // zString - rr.Hostname = l.token - if l.token == "@" { - rr.Hostname = o - return rr, nil, "" - } - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad AFSDB Hostname", l}, "" - } - if rr.Hostname[l.length-1] != '.' { - rr.Hostname = appendOrigin(rr.Hostname, o) - } - return rr, nil, "" -} - -func setX25(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(X25) - rr.Hdr = h - - l := <-c - if l.length == 0 { - return rr, nil, "" - } - if l.err { - return nil, &ParseError{f, "bad X25 PSDNAddress", l}, "" - } - rr.PSDNAddress = l.token - return rr, nil, "" -} - -func setKX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(KX) - rr.Hdr = h - - l := <-c - if l.length == 0 { - return rr, nil, "" - } - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return nil, &ParseError{f, "bad KX Pref", l}, "" - } - rr.Preference = uint16(i) - <-c // zBlank - l = <-c // zString - rr.Exchanger = l.token - if l.token == "@" { - rr.Exchanger = o - return rr, nil, "" - } - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad KX Exchanger", l}, "" - } - if rr.Exchanger[l.length-1] != '.' { - rr.Exchanger = appendOrigin(rr.Exchanger, o) - } - return rr, nil, "" -} - -func setCNAME(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(CNAME) - rr.Hdr = h - - l := <-c - rr.Target = l.token - if l.length == 0 { - return rr, nil, "" - } - if l.token == "@" { - rr.Target = o - return rr, nil, "" - } - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad CNAME Target", l}, "" - } - if rr.Target[l.length-1] != '.' { - rr.Target = appendOrigin(rr.Target, o) - } - return rr, nil, "" -} - -func setDNAME(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(DNAME) - rr.Hdr = h - - l := <-c - rr.Target = l.token - if l.length == 0 { - return rr, nil, "" - } - if l.token == "@" { - rr.Target = o - return rr, nil, "" - } - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad CNAME Target", l}, "" - } - if rr.Target[l.length-1] != '.' { - rr.Target = appendOrigin(rr.Target, o) - } - return rr, nil, "" -} - -func setSOA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(SOA) - rr.Hdr = h - - l := <-c - rr.Ns = l.token - if l.length == 0 { - return rr, nil, "" - } - <-c // zBlank - if l.token == "@" { - rr.Ns = o - } else { - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad SOA Ns", l}, "" - } - if rr.Ns[l.length-1] != '.' { - rr.Ns = appendOrigin(rr.Ns, o) - } - } - - l = <-c - rr.Mbox = l.token - if l.token == "@" { - rr.Mbox = o - } else { - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad SOA Mbox", l}, "" - } - if rr.Mbox[l.length-1] != '.' { - rr.Mbox = appendOrigin(rr.Mbox, o) - } - } - <-c // zBlank - - var ( - v uint32 - ok bool - ) - for i := 0; i < 5; i++ { - l = <-c - if l.err { - return nil, &ParseError{f, "bad SOA zone parameter", l}, "" - } - if j, e := strconv.ParseUint(l.token, 10, 32); e != nil { - if i == 0 { - // Serial should be a number - return nil, &ParseError{f, "bad SOA zone parameter", l}, "" - } - if v, ok = stringToTtl(l.token); !ok { - return nil, &ParseError{f, "bad SOA zone parameter", l}, "" - - } - } else { - v = uint32(j) - } - switch i { - case 0: - rr.Serial = v - <-c // zBlank - case 1: - rr.Refresh = v - <-c // zBlank - case 2: - rr.Retry = v - <-c // zBlank - case 3: - rr.Expire = v - <-c // zBlank - case 4: - rr.Minttl = v - } - } - return rr, nil, "" -} - -func setSRV(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(SRV) - rr.Hdr = h - - l := <-c - if l.length == 0 { - return rr, nil, "" - } - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return nil, &ParseError{f, "bad SRV Priority", l}, "" - } - rr.Priority = uint16(i) - <-c // zBlank - l = <-c // zString - i, e = strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return nil, &ParseError{f, "bad SRV Weight", l}, "" - } - rr.Weight = uint16(i) - <-c // zBlank - l = <-c // zString - i, e = strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return nil, &ParseError{f, "bad SRV Port", l}, "" - } - rr.Port = uint16(i) - <-c // zBlank - l = <-c // zString - rr.Target = l.token - if l.token == "@" { - rr.Target = o - return rr, nil, "" - } - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad SRV Target", l}, "" - } - if rr.Target[l.length-1] != '.' { - rr.Target = appendOrigin(rr.Target, o) - } - return rr, nil, "" -} - -func setNAPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(NAPTR) - rr.Hdr = h - - l := <-c - if l.length == 0 { - return rr, nil, "" - } - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return nil, &ParseError{f, "bad NAPTR Order", l}, "" - } - rr.Order = uint16(i) - <-c // zBlank - l = <-c // zString - i, e = strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return nil, &ParseError{f, "bad NAPTR Preference", l}, "" - } - rr.Preference = uint16(i) - // Flags - <-c // zBlank - l = <-c // _QUOTE - if l.value != zQuote { - return nil, &ParseError{f, "bad NAPTR Flags", l}, "" - } - l = <-c // Either String or Quote - if l.value == zString { - rr.Flags = l.token - l = <-c // _QUOTE - if l.value != zQuote { - return nil, &ParseError{f, "bad NAPTR Flags", l}, "" - } - } else if l.value == zQuote { - rr.Flags = "" - } else { - return nil, &ParseError{f, "bad NAPTR Flags", l}, "" - } - - // Service - <-c // zBlank - l = <-c // _QUOTE - if l.value != zQuote { - return nil, &ParseError{f, "bad NAPTR Service", l}, "" - } - l = <-c // Either String or Quote - if l.value == zString { - rr.Service = l.token - l = <-c // _QUOTE - if l.value != zQuote { - return nil, &ParseError{f, "bad NAPTR Service", l}, "" - } - } else if l.value == zQuote { - rr.Service = "" - } else { - return nil, &ParseError{f, "bad NAPTR Service", l}, "" - } - - // Regexp - <-c // zBlank - l = <-c // _QUOTE - if l.value != zQuote { - return nil, &ParseError{f, "bad NAPTR Regexp", l}, "" - } - l = <-c // Either String or Quote - if l.value == zString { - rr.Regexp = l.token - l = <-c // _QUOTE - if l.value != zQuote { - return nil, &ParseError{f, "bad NAPTR Regexp", l}, "" - } - } else if l.value == zQuote { - rr.Regexp = "" - } else { - return nil, &ParseError{f, "bad NAPTR Regexp", l}, "" - } - // After quote no space?? - <-c // zBlank - l = <-c // zString - rr.Replacement = l.token - if l.token == "@" { - rr.Replacement = o - return rr, nil, "" - } - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad NAPTR Replacement", l}, "" - } - if rr.Replacement[l.length-1] != '.' { - rr.Replacement = appendOrigin(rr.Replacement, o) - } - return rr, nil, "" -} - -func setTALINK(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(TALINK) - rr.Hdr = h - - l := <-c - rr.PreviousName = l.token - if l.length == 0 { - return rr, nil, "" - } - if l.token == "@" { - rr.PreviousName = o - } else { - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad TALINK PreviousName", l}, "" - } - if rr.PreviousName[l.length-1] != '.' { - rr.PreviousName = appendOrigin(rr.PreviousName, o) - } - } - <-c // zBlank - l = <-c - rr.NextName = l.token - if l.token == "@" { - rr.NextName = o - return rr, nil, "" - } - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad TALINK NextName", l}, "" - } - if rr.NextName[l.length-1] != '.' { - rr.NextName = appendOrigin(rr.NextName, o) - } - return rr, nil, "" -} - -func setLOC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(LOC) - rr.Hdr = h - // Non zero defaults for LOC record, see RFC 1876, Section 3. - rr.HorizPre = 165 // 10000 - rr.VertPre = 162 // 10 - rr.Size = 18 // 1 - ok := false - // North - l := <-c - if l.length == 0 { - return rr, nil, "" - } - i, e := strconv.ParseUint(l.token, 10, 32) - if e != nil || l.err { - return nil, &ParseError{f, "bad LOC Latitude", l}, "" - } - rr.Latitude = 1000 * 60 * 60 * uint32(i) - - <-c // zBlank - // Either number, 'N' or 'S' - l = <-c - if rr.Latitude, ok = locCheckNorth(l.token, rr.Latitude); ok { - goto East - } - i, e = strconv.ParseUint(l.token, 10, 32) - if e != nil || l.err { - return nil, &ParseError{f, "bad LOC Latitude minutes", l}, "" - } - rr.Latitude += 1000 * 60 * uint32(i) - - <-c // zBlank - l = <-c - if i, e := strconv.ParseFloat(l.token, 32); e != nil || l.err { - return nil, &ParseError{f, "bad LOC Latitude seconds", l}, "" - } else { - rr.Latitude += uint32(1000 * i) - } - <-c // zBlank - // Either number, 'N' or 'S' - l = <-c - if rr.Latitude, ok = locCheckNorth(l.token, rr.Latitude); ok { - goto East - } - // If still alive, flag an error - return nil, &ParseError{f, "bad LOC Latitude North/South", l}, "" - -East: - // East - <-c // zBlank - l = <-c - if i, e := strconv.ParseUint(l.token, 10, 32); e != nil || l.err { - return nil, &ParseError{f, "bad LOC Longitude", l}, "" - } else { - rr.Longitude = 1000 * 60 * 60 * uint32(i) - } - <-c // zBlank - // Either number, 'E' or 'W' - l = <-c - if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok { - goto Altitude - } - if i, e := strconv.ParseUint(l.token, 10, 32); e != nil || l.err { - return nil, &ParseError{f, "bad LOC Longitude minutes", l}, "" - } else { - rr.Longitude += 1000 * 60 * uint32(i) - } - <-c // zBlank - l = <-c - if i, e := strconv.ParseFloat(l.token, 32); e != nil || l.err { - return nil, &ParseError{f, "bad LOC Longitude seconds", l}, "" - } else { - rr.Longitude += uint32(1000 * i) - } - <-c // zBlank - // Either number, 'E' or 'W' - l = <-c - if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok { - goto Altitude - } - // If still alive, flag an error - return nil, &ParseError{f, "bad LOC Longitude East/West", l}, "" - -Altitude: - <-c // zBlank - l = <-c - if l.length == 0 || l.err { - return nil, &ParseError{f, "bad LOC Altitude", l}, "" - } - if l.token[len(l.token)-1] == 'M' || l.token[len(l.token)-1] == 'm' { - l.token = l.token[0 : len(l.token)-1] - } - if i, e := strconv.ParseFloat(l.token, 32); e != nil { - return nil, &ParseError{f, "bad LOC Altitude", l}, "" - } else { - rr.Altitude = uint32(i*100.0 + 10000000.0 + 0.5) - } - - // And now optionally the other values - l = <-c - count := 0 - for l.value != zNewline && l.value != zEOF { - switch l.value { - case zString: - switch count { - case 0: // Size - e, m, ok := stringToCm(l.token) - if !ok { - return nil, &ParseError{f, "bad LOC Size", l}, "" - } - rr.Size = (e & 0x0f) | (m << 4 & 0xf0) - case 1: // HorizPre - e, m, ok := stringToCm(l.token) - if !ok { - return nil, &ParseError{f, "bad LOC HorizPre", l}, "" - } - rr.HorizPre = (e & 0x0f) | (m << 4 & 0xf0) - case 2: // VertPre - e, m, ok := stringToCm(l.token) - if !ok { - return nil, &ParseError{f, "bad LOC VertPre", l}, "" - } - rr.VertPre = (e & 0x0f) | (m << 4 & 0xf0) - } - count++ - case zBlank: - // Ok - default: - return nil, &ParseError{f, "bad LOC Size, HorizPre or VertPre", l}, "" - } - l = <-c - } - return rr, nil, "" -} - -func setHIP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(HIP) - rr.Hdr = h - - // HitLength is not represented - l := <-c - if l.length == 0 { - return rr, nil, l.comment - } - i, e := strconv.ParseUint(l.token, 10, 8) - if e != nil || l.err { - return nil, &ParseError{f, "bad HIP PublicKeyAlgorithm", l}, "" - } - rr.PublicKeyAlgorithm = uint8(i) - <-c // zBlank - l = <-c // zString - if l.length == 0 || l.err { - return nil, &ParseError{f, "bad HIP Hit", l}, "" - } - rr.Hit = l.token // This can not contain spaces, see RFC 5205 Section 6. - rr.HitLength = uint8(len(rr.Hit)) / 2 - - <-c // zBlank - l = <-c // zString - if l.length == 0 || l.err { - return nil, &ParseError{f, "bad HIP PublicKey", l}, "" - } - rr.PublicKey = l.token // This cannot contain spaces - rr.PublicKeyLength = uint16(base64.StdEncoding.DecodedLen(len(rr.PublicKey))) - - // RendezvousServers (if any) - l = <-c - var xs []string - for l.value != zNewline && l.value != zEOF { - switch l.value { - case zString: - if l.token == "@" { - xs = append(xs, o) - l = <-c - continue - } - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad HIP RendezvousServers", l}, "" - } - if l.token[l.length-1] != '.' { - l.token = appendOrigin(l.token, o) - } - xs = append(xs, l.token) - case zBlank: - // Ok - default: - return nil, &ParseError{f, "bad HIP RendezvousServers", l}, "" - } - l = <-c - } - rr.RendezvousServers = xs - return rr, nil, l.comment -} - -func setCERT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(CERT) - rr.Hdr = h - - l := <-c - if l.length == 0 { - return rr, nil, l.comment - } - if v, ok := StringToCertType[l.token]; ok { - rr.Type = v - } else if i, e := strconv.ParseUint(l.token, 10, 16); e != nil { - return nil, &ParseError{f, "bad CERT Type", l}, "" - } else { - rr.Type = uint16(i) - } - <-c // zBlank - l = <-c // zString - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return nil, &ParseError{f, "bad CERT KeyTag", l}, "" - } - rr.KeyTag = uint16(i) - <-c // zBlank - l = <-c // zString - if v, ok := StringToAlgorithm[l.token]; ok { - rr.Algorithm = v - } else if i, e := strconv.ParseUint(l.token, 10, 8); e != nil { - return nil, &ParseError{f, "bad CERT Algorithm", l}, "" - } else { - rr.Algorithm = uint8(i) - } - s, e1, c1 := endingToString(c, "bad CERT Certificate", f) - if e1 != nil { - return nil, e1, c1 - } - rr.Certificate = s - return rr, nil, c1 -} - -func setOPENPGPKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(OPENPGPKEY) - rr.Hdr = h - - s, e, c1 := endingToString(c, "bad OPENPGPKEY PublicKey", f) - if e != nil { - return nil, e, c1 - } - rr.PublicKey = s - return rr, nil, c1 -} - -func setSIG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - r, e, s := setRRSIG(h, c, o, f) - if r != nil { - return &SIG{*r.(*RRSIG)}, e, s - } - return nil, e, s -} - -func setRRSIG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(RRSIG) - rr.Hdr = h - l := <-c - if l.length == 0 { - return rr, nil, l.comment - } - if t, ok := StringToType[l.tokenUpper]; !ok { - if strings.HasPrefix(l.tokenUpper, "TYPE") { - t, ok = typeToInt(l.tokenUpper) - if !ok { - return nil, &ParseError{f, "bad RRSIG Typecovered", l}, "" - } - rr.TypeCovered = t - } else { - return nil, &ParseError{f, "bad RRSIG Typecovered", l}, "" - } - } else { - rr.TypeCovered = t - } - <-c // zBlank - l = <-c - i, err := strconv.ParseUint(l.token, 10, 8) - if err != nil || l.err { - return nil, &ParseError{f, "bad RRSIG Algorithm", l}, "" - } - rr.Algorithm = uint8(i) - <-c // zBlank - l = <-c - i, err = strconv.ParseUint(l.token, 10, 8) - if err != nil || l.err { - return nil, &ParseError{f, "bad RRSIG Labels", l}, "" - } - rr.Labels = uint8(i) - <-c // zBlank - l = <-c - i, err = strconv.ParseUint(l.token, 10, 32) - if err != nil || l.err { - return nil, &ParseError{f, "bad RRSIG OrigTtl", l}, "" - } - rr.OrigTtl = uint32(i) - <-c // zBlank - l = <-c - if i, err := StringToTime(l.token); err != nil { - // Try to see if all numeric and use it as epoch - if i, err := strconv.ParseInt(l.token, 10, 64); err == nil { - // TODO(miek): error out on > MAX_UINT32, same below - rr.Expiration = uint32(i) - } else { - return nil, &ParseError{f, "bad RRSIG Expiration", l}, "" - } - } else { - rr.Expiration = i - } - <-c // zBlank - l = <-c - if i, err := StringToTime(l.token); err != nil { - if i, err := strconv.ParseInt(l.token, 10, 64); err == nil { - rr.Inception = uint32(i) - } else { - return nil, &ParseError{f, "bad RRSIG Inception", l}, "" - } - } else { - rr.Inception = i - } - <-c // zBlank - l = <-c - i, err = strconv.ParseUint(l.token, 10, 16) - if err != nil || l.err { - return nil, &ParseError{f, "bad RRSIG KeyTag", l}, "" - } - rr.KeyTag = uint16(i) - <-c // zBlank - l = <-c - rr.SignerName = l.token - if l.token == "@" { - rr.SignerName = o - } else { - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad RRSIG SignerName", l}, "" - } - if rr.SignerName[l.length-1] != '.' { - rr.SignerName = appendOrigin(rr.SignerName, o) - } - } - s, e, c1 := endingToString(c, "bad RRSIG Signature", f) - if e != nil { - return nil, e, c1 - } - rr.Signature = s - return rr, nil, c1 -} - -func setNSEC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(NSEC) - rr.Hdr = h - - l := <-c - rr.NextDomain = l.token - if l.length == 0 { - return rr, nil, l.comment - } - if l.token == "@" { - rr.NextDomain = o - } else { - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad NSEC NextDomain", l}, "" - } - if rr.NextDomain[l.length-1] != '.' { - rr.NextDomain = appendOrigin(rr.NextDomain, o) - } - } - - rr.TypeBitMap = make([]uint16, 0) - var ( - k uint16 - ok bool - ) - l = <-c - for l.value != zNewline && l.value != zEOF { - switch l.value { - case zBlank: - // Ok - case zString: - if k, ok = StringToType[l.tokenUpper]; !ok { - if k, ok = typeToInt(l.tokenUpper); !ok { - return nil, &ParseError{f, "bad NSEC TypeBitMap", l}, "" - } - } - rr.TypeBitMap = append(rr.TypeBitMap, k) - default: - return nil, &ParseError{f, "bad NSEC TypeBitMap", l}, "" - } - l = <-c - } - return rr, nil, l.comment -} - -func setNSEC3(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(NSEC3) - rr.Hdr = h - - l := <-c - if l.length == 0 { - return rr, nil, l.comment - } - i, e := strconv.ParseUint(l.token, 10, 8) - if e != nil || l.err { - return nil, &ParseError{f, "bad NSEC3 Hash", l}, "" - } - rr.Hash = uint8(i) - <-c // zBlank - l = <-c - i, e = strconv.ParseUint(l.token, 10, 8) - if e != nil || l.err { - return nil, &ParseError{f, "bad NSEC3 Flags", l}, "" - } - rr.Flags = uint8(i) - <-c // zBlank - l = <-c - i, e = strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return nil, &ParseError{f, "bad NSEC3 Iterations", l}, "" - } - rr.Iterations = uint16(i) - <-c - l = <-c - if len(l.token) == 0 || l.err { - return nil, &ParseError{f, "bad NSEC3 Salt", l}, "" - } - rr.SaltLength = uint8(len(l.token)) / 2 - rr.Salt = l.token - - <-c - l = <-c - if len(l.token) == 0 || l.err { - return nil, &ParseError{f, "bad NSEC3 NextDomain", l}, "" - } - rr.HashLength = 20 // Fix for NSEC3 (sha1 160 bits) - rr.NextDomain = l.token - - rr.TypeBitMap = make([]uint16, 0) - var ( - k uint16 - ok bool - ) - l = <-c - for l.value != zNewline && l.value != zEOF { - switch l.value { - case zBlank: - // Ok - case zString: - if k, ok = StringToType[l.tokenUpper]; !ok { - if k, ok = typeToInt(l.tokenUpper); !ok { - return nil, &ParseError{f, "bad NSEC3 TypeBitMap", l}, "" - } - } - rr.TypeBitMap = append(rr.TypeBitMap, k) - default: - return nil, &ParseError{f, "bad NSEC3 TypeBitMap", l}, "" - } - l = <-c - } - return rr, nil, l.comment -} - -func setNSEC3PARAM(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(NSEC3PARAM) - rr.Hdr = h - - l := <-c - if l.length == 0 { - return rr, nil, "" - } - i, e := strconv.ParseUint(l.token, 10, 8) - if e != nil || l.err { - return nil, &ParseError{f, "bad NSEC3PARAM Hash", l}, "" - } - rr.Hash = uint8(i) - <-c // zBlank - l = <-c - i, e = strconv.ParseUint(l.token, 10, 8) - if e != nil || l.err { - return nil, &ParseError{f, "bad NSEC3PARAM Flags", l}, "" - } - rr.Flags = uint8(i) - <-c // zBlank - l = <-c - i, e = strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return nil, &ParseError{f, "bad NSEC3PARAM Iterations", l}, "" - } - rr.Iterations = uint16(i) - <-c - l = <-c - rr.SaltLength = uint8(len(l.token)) - rr.Salt = l.token - return rr, nil, "" -} - -func setEUI48(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(EUI48) - rr.Hdr = h - - l := <-c - if l.length == 0 { - return rr, nil, "" - } - if l.length != 17 || l.err { - return nil, &ParseError{f, "bad EUI48 Address", l}, "" - } - addr := make([]byte, 12) - dash := 0 - for i := 0; i < 10; i += 2 { - addr[i] = l.token[i+dash] - addr[i+1] = l.token[i+1+dash] - dash++ - if l.token[i+1+dash] != '-' { - return nil, &ParseError{f, "bad EUI48 Address", l}, "" - } - } - addr[10] = l.token[15] - addr[11] = l.token[16] - - i, e := strconv.ParseUint(string(addr), 16, 48) - if e != nil { - return nil, &ParseError{f, "bad EUI48 Address", l}, "" - } - rr.Address = i - return rr, nil, "" -} - -func setEUI64(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(EUI64) - rr.Hdr = h - - l := <-c - if l.length == 0 { - return rr, nil, "" - } - if l.length != 23 || l.err { - return nil, &ParseError{f, "bad EUI64 Address", l}, "" - } - addr := make([]byte, 16) - dash := 0 - for i := 0; i < 14; i += 2 { - addr[i] = l.token[i+dash] - addr[i+1] = l.token[i+1+dash] - dash++ - if l.token[i+1+dash] != '-' { - return nil, &ParseError{f, "bad EUI64 Address", l}, "" - } - } - addr[14] = l.token[21] - addr[15] = l.token[22] - - i, e := strconv.ParseUint(string(addr), 16, 64) - if e != nil { - return nil, &ParseError{f, "bad EUI68 Address", l}, "" - } - rr.Address = uint64(i) - return rr, nil, "" -} - -func setSSHFP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(SSHFP) - rr.Hdr = h - - l := <-c - if l.length == 0 { - return rr, nil, "" - } - i, e := strconv.ParseUint(l.token, 10, 8) - if e != nil || l.err { - return nil, &ParseError{f, "bad SSHFP Algorithm", l}, "" - } - rr.Algorithm = uint8(i) - <-c // zBlank - l = <-c - i, e = strconv.ParseUint(l.token, 10, 8) - if e != nil || l.err { - return nil, &ParseError{f, "bad SSHFP Type", l}, "" - } - rr.Type = uint8(i) - <-c // zBlank - s, e1, c1 := endingToString(c, "bad SSHFP Fingerprint", f) - if e1 != nil { - return nil, e1, c1 - } - rr.FingerPrint = s - return rr, nil, "" -} - -func setDNSKEYs(h RR_Header, c chan lex, o, f, typ string) (RR, *ParseError, string) { - rr := new(DNSKEY) - rr.Hdr = h - - l := <-c - if l.length == 0 { - return rr, nil, l.comment - } - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return nil, &ParseError{f, "bad " + typ + " Flags", l}, "" - } - rr.Flags = uint16(i) - <-c // zBlank - l = <-c // zString - i, e = strconv.ParseUint(l.token, 10, 8) - if e != nil || l.err { - return nil, &ParseError{f, "bad " + typ + " Protocol", l}, "" - } - rr.Protocol = uint8(i) - <-c // zBlank - l = <-c // zString - i, e = strconv.ParseUint(l.token, 10, 8) - if e != nil || l.err { - return nil, &ParseError{f, "bad " + typ + " Algorithm", l}, "" - } - rr.Algorithm = uint8(i) - s, e1, c1 := endingToString(c, "bad "+typ+" PublicKey", f) - if e1 != nil { - return nil, e1, c1 - } - rr.PublicKey = s - return rr, nil, c1 -} - -func setKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - r, e, s := setDNSKEYs(h, c, o, f, "KEY") - if r != nil { - return &KEY{*r.(*DNSKEY)}, e, s - } - return nil, e, s -} - -func setDNSKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - r, e, s := setDNSKEYs(h, c, o, f, "DNSKEY") - return r, e, s -} - -func setCDNSKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - r, e, s := setDNSKEYs(h, c, o, f, "CDNSKEY") - if r != nil { - return &CDNSKEY{*r.(*DNSKEY)}, e, s - } - return nil, e, s -} - -func setRKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(RKEY) - rr.Hdr = h - - l := <-c - if l.length == 0 { - return rr, nil, l.comment - } - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return nil, &ParseError{f, "bad RKEY Flags", l}, "" - } - rr.Flags = uint16(i) - <-c // zBlank - l = <-c // zString - i, e = strconv.ParseUint(l.token, 10, 8) - if e != nil || l.err { - return nil, &ParseError{f, "bad RKEY Protocol", l}, "" - } - rr.Protocol = uint8(i) - <-c // zBlank - l = <-c // zString - i, e = strconv.ParseUint(l.token, 10, 8) - if e != nil || l.err { - return nil, &ParseError{f, "bad RKEY Algorithm", l}, "" - } - rr.Algorithm = uint8(i) - s, e1, c1 := endingToString(c, "bad RKEY PublicKey", f) - if e1 != nil { - return nil, e1, c1 - } - rr.PublicKey = s - return rr, nil, c1 -} - -func setEID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(EID) - rr.Hdr = h - s, e, c1 := endingToString(c, "bad EID Endpoint", f) - if e != nil { - return nil, e, c1 - } - rr.Endpoint = s - return rr, nil, c1 -} - -func setNIMLOC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(NIMLOC) - rr.Hdr = h - s, e, c1 := endingToString(c, "bad NIMLOC Locator", f) - if e != nil { - return nil, e, c1 - } - rr.Locator = s - return rr, nil, c1 -} - -func setGPOS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(GPOS) - rr.Hdr = h - l := <-c - if l.length == 0 { - return rr, nil, "" - } - _, e := strconv.ParseFloat(l.token, 64) - if e != nil || l.err { - return nil, &ParseError{f, "bad GPOS Longitude", l}, "" - } - rr.Longitude = l.token - <-c // zBlank - l = <-c - _, e = strconv.ParseFloat(l.token, 64) - if e != nil || l.err { - return nil, &ParseError{f, "bad GPOS Latitude", l}, "" - } - rr.Latitude = l.token - <-c // zBlank - l = <-c - _, e = strconv.ParseFloat(l.token, 64) - if e != nil || l.err { - return nil, &ParseError{f, "bad GPOS Altitude", l}, "" - } - rr.Altitude = l.token - return rr, nil, "" -} - -func setDSs(h RR_Header, c chan lex, o, f, typ string) (RR, *ParseError, string) { - rr := new(DS) - rr.Hdr = h - l := <-c - if l.length == 0 { - return rr, nil, l.comment - } - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return nil, &ParseError{f, "bad " + typ + " KeyTag", l}, "" - } - rr.KeyTag = uint16(i) - <-c // zBlank - l = <-c - if i, e = strconv.ParseUint(l.token, 10, 8); e != nil { - i, ok := StringToAlgorithm[l.tokenUpper] - if !ok || l.err { - return nil, &ParseError{f, "bad " + typ + " Algorithm", l}, "" - } - rr.Algorithm = i - } else { - rr.Algorithm = uint8(i) - } - <-c // zBlank - l = <-c - i, e = strconv.ParseUint(l.token, 10, 8) - if e != nil || l.err { - return nil, &ParseError{f, "bad " + typ + " DigestType", l}, "" - } - rr.DigestType = uint8(i) - s, e1, c1 := endingToString(c, "bad "+typ+" Digest", f) - if e1 != nil { - return nil, e1, c1 - } - rr.Digest = s - return rr, nil, c1 -} - -func setDS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - r, e, s := setDSs(h, c, o, f, "DS") - return r, e, s -} - -func setDLV(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - r, e, s := setDSs(h, c, o, f, "DLV") - if r != nil { - return &DLV{*r.(*DS)}, e, s - } - return nil, e, s -} - -func setCDS(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - r, e, s := setDSs(h, c, o, f, "CDS") - if r != nil { - return &CDS{*r.(*DS)}, e, s - } - return nil, e, s -} - -func setTA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(TA) - rr.Hdr = h - l := <-c - if l.length == 0 { - return rr, nil, l.comment - } - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return nil, &ParseError{f, "bad TA KeyTag", l}, "" - } - rr.KeyTag = uint16(i) - <-c // zBlank - l = <-c - if i, e := strconv.ParseUint(l.token, 10, 8); e != nil { - i, ok := StringToAlgorithm[l.tokenUpper] - if !ok || l.err { - return nil, &ParseError{f, "bad TA Algorithm", l}, "" - } - rr.Algorithm = i - } else { - rr.Algorithm = uint8(i) - } - <-c // zBlank - l = <-c - i, e = strconv.ParseUint(l.token, 10, 8) - if e != nil || l.err { - return nil, &ParseError{f, "bad TA DigestType", l}, "" - } - rr.DigestType = uint8(i) - s, e, c1 := endingToString(c, "bad TA Digest", f) - if e != nil { - return nil, e.(*ParseError), c1 - } - rr.Digest = s - return rr, nil, c1 -} - -func setTLSA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(TLSA) - rr.Hdr = h - l := <-c - if l.length == 0 { - return rr, nil, l.comment - } - i, e := strconv.ParseUint(l.token, 10, 8) - if e != nil || l.err { - return nil, &ParseError{f, "bad TLSA Usage", l}, "" - } - rr.Usage = uint8(i) - <-c // zBlank - l = <-c - i, e = strconv.ParseUint(l.token, 10, 8) - if e != nil || l.err { - return nil, &ParseError{f, "bad TLSA Selector", l}, "" - } - rr.Selector = uint8(i) - <-c // zBlank - l = <-c - i, e = strconv.ParseUint(l.token, 10, 8) - if e != nil || l.err { - return nil, &ParseError{f, "bad TLSA MatchingType", l}, "" - } - rr.MatchingType = uint8(i) - // So this needs be e2 (i.e. different than e), because...??t - s, e2, c1 := endingToString(c, "bad TLSA Certificate", f) - if e2 != nil { - return nil, e2, c1 - } - rr.Certificate = s - return rr, nil, c1 -} - -func setSMIMEA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(SMIMEA) - rr.Hdr = h - l := <-c - if l.length == 0 { - return rr, nil, l.comment - } - i, e := strconv.ParseUint(l.token, 10, 8) - if e != nil || l.err { - return nil, &ParseError{f, "bad SMIMEA Usage", l}, "" - } - rr.Usage = uint8(i) - <-c // zBlank - l = <-c - i, e = strconv.ParseUint(l.token, 10, 8) - if e != nil || l.err { - return nil, &ParseError{f, "bad SMIMEA Selector", l}, "" - } - rr.Selector = uint8(i) - <-c // zBlank - l = <-c - i, e = strconv.ParseUint(l.token, 10, 8) - if e != nil || l.err { - return nil, &ParseError{f, "bad SMIMEA MatchingType", l}, "" - } - rr.MatchingType = uint8(i) - // So this needs be e2 (i.e. different than e), because...??t - s, e2, c1 := endingToString(c, "bad SMIMEA Certificate", f) - if e2 != nil { - return nil, e2, c1 - } - rr.Certificate = s - return rr, nil, c1 -} - -func setRFC3597(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(RFC3597) - rr.Hdr = h - l := <-c - if l.token != "\\#" { - return nil, &ParseError{f, "bad RFC3597 Rdata", l}, "" - } - <-c // zBlank - l = <-c - rdlength, e := strconv.Atoi(l.token) - if e != nil || l.err { - return nil, &ParseError{f, "bad RFC3597 Rdata ", l}, "" - } - - s, e1, c1 := endingToString(c, "bad RFC3597 Rdata", f) - if e1 != nil { - return nil, e1, c1 - } - if rdlength*2 != len(s) { - return nil, &ParseError{f, "bad RFC3597 Rdata", l}, "" - } - rr.Rdata = s - return rr, nil, c1 -} - -func setSPF(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(SPF) - rr.Hdr = h - - s, e, c1 := endingToTxtSlice(c, "bad SPF Txt", f) - if e != nil { - return nil, e, "" - } - rr.Txt = s - return rr, nil, c1 -} - -func setAVC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(AVC) - rr.Hdr = h - - s, e, c1 := endingToTxtSlice(c, "bad AVC Txt", f) - if e != nil { - return nil, e, "" - } - rr.Txt = s - return rr, nil, c1 -} - -func setTXT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(TXT) - rr.Hdr = h - - // no zBlank reading here, because all this rdata is TXT - s, e, c1 := endingToTxtSlice(c, "bad TXT Txt", f) - if e != nil { - return nil, e, "" - } - rr.Txt = s - return rr, nil, c1 -} - -// identical to setTXT -func setNINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(NINFO) - rr.Hdr = h - - s, e, c1 := endingToTxtSlice(c, "bad NINFO ZSData", f) - if e != nil { - return nil, e, "" - } - rr.ZSData = s - return rr, nil, c1 -} - -func setURI(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(URI) - rr.Hdr = h - - l := <-c - if l.length == 0 { // Dynamic updates. - return rr, nil, "" - } - - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return nil, &ParseError{f, "bad URI Priority", l}, "" - } - rr.Priority = uint16(i) - <-c // zBlank - l = <-c - i, e = strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return nil, &ParseError{f, "bad URI Weight", l}, "" - } - rr.Weight = uint16(i) - - <-c // zBlank - s, err, c1 := endingToTxtSlice(c, "bad URI Target", f) - if err != nil { - return nil, err, "" - } - if len(s) > 1 { - return nil, &ParseError{f, "bad URI Target", l}, "" - } - rr.Target = s[0] - return rr, nil, c1 -} - -func setDHCID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - // awesome record to parse! - rr := new(DHCID) - rr.Hdr = h - - s, e, c1 := endingToString(c, "bad DHCID Digest", f) - if e != nil { - return nil, e, c1 - } - rr.Digest = s - return rr, nil, c1 -} - -func setNID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(NID) - rr.Hdr = h - - l := <-c - if l.length == 0 { - return rr, nil, "" - } - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return nil, &ParseError{f, "bad NID Preference", l}, "" - } - rr.Preference = uint16(i) - <-c // zBlank - l = <-c // zString - u, err := stringToNodeID(l) - if err != nil || l.err { - return nil, err, "" - } - rr.NodeID = u - return rr, nil, "" -} - -func setL32(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(L32) - rr.Hdr = h - - l := <-c - if l.length == 0 { - return rr, nil, "" - } - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return nil, &ParseError{f, "bad L32 Preference", l}, "" - } - rr.Preference = uint16(i) - <-c // zBlank - l = <-c // zString - rr.Locator32 = net.ParseIP(l.token) - if rr.Locator32 == nil || l.err { - return nil, &ParseError{f, "bad L32 Locator", l}, "" - } - return rr, nil, "" -} - -func setLP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(LP) - rr.Hdr = h - - l := <-c - if l.length == 0 { - return rr, nil, "" - } - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return nil, &ParseError{f, "bad LP Preference", l}, "" - } - rr.Preference = uint16(i) - <-c // zBlank - l = <-c // zString - rr.Fqdn = l.token - if l.length == 0 { - return rr, nil, "" - } - if l.token == "@" { - rr.Fqdn = o - return rr, nil, "" - } - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad LP Fqdn", l}, "" - } - if rr.Fqdn[l.length-1] != '.' { - rr.Fqdn = appendOrigin(rr.Fqdn, o) - } - return rr, nil, "" -} - -func setL64(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(L64) - rr.Hdr = h - - l := <-c - if l.length == 0 { - return rr, nil, "" - } - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return nil, &ParseError{f, "bad L64 Preference", l}, "" - } - rr.Preference = uint16(i) - <-c // zBlank - l = <-c // zString - u, err := stringToNodeID(l) - if err != nil || l.err { - return nil, err, "" - } - rr.Locator64 = u - return rr, nil, "" -} - -func setUID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(UID) - rr.Hdr = h - l := <-c - if l.length == 0 { - return rr, nil, "" - } - i, e := strconv.ParseUint(l.token, 10, 32) - if e != nil || l.err { - return nil, &ParseError{f, "bad UID Uid", l}, "" - } - rr.Uid = uint32(i) - return rr, nil, "" -} - -func setGID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(GID) - rr.Hdr = h - l := <-c - if l.length == 0 { - return rr, nil, "" - } - i, e := strconv.ParseUint(l.token, 10, 32) - if e != nil || l.err { - return nil, &ParseError{f, "bad GID Gid", l}, "" - } - rr.Gid = uint32(i) - return rr, nil, "" -} - -func setUINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(UINFO) - rr.Hdr = h - s, e, c1 := endingToTxtSlice(c, "bad UINFO Uinfo", f) - if e != nil { - return nil, e, c1 - } - if ln := len(s); ln == 0 { - return rr, nil, c1 - } - rr.Uinfo = s[0] // silently discard anything after the first character-string - return rr, nil, c1 -} - -func setPX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(PX) - rr.Hdr = h - - l := <-c - if l.length == 0 { - return rr, nil, "" - } - i, e := strconv.ParseUint(l.token, 10, 16) - if e != nil || l.err { - return nil, &ParseError{f, "bad PX Preference", l}, "" - } - rr.Preference = uint16(i) - <-c // zBlank - l = <-c // zString - rr.Map822 = l.token - if l.length == 0 { - return rr, nil, "" - } - if l.token == "@" { - rr.Map822 = o - return rr, nil, "" - } - _, ok := IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad PX Map822", l}, "" - } - if rr.Map822[l.length-1] != '.' { - rr.Map822 = appendOrigin(rr.Map822, o) - } - <-c // zBlank - l = <-c // zString - rr.Mapx400 = l.token - if l.token == "@" { - rr.Mapx400 = o - return rr, nil, "" - } - _, ok = IsDomainName(l.token) - if !ok || l.length == 0 || l.err { - return nil, &ParseError{f, "bad PX Mapx400", l}, "" - } - if rr.Mapx400[l.length-1] != '.' { - rr.Mapx400 = appendOrigin(rr.Mapx400, o) - } - return rr, nil, "" -} - -func setCAA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { - rr := new(CAA) - rr.Hdr = h - l := <-c - if l.length == 0 { - return rr, nil, l.comment - } - i, err := strconv.ParseUint(l.token, 10, 8) - if err != nil || l.err { - return nil, &ParseError{f, "bad CAA Flag", l}, "" - } - rr.Flag = uint8(i) - - <-c // zBlank - l = <-c // zString - if l.value != zString { - return nil, &ParseError{f, "bad CAA Tag", l}, "" - } - rr.Tag = l.token - - <-c // zBlank - s, e, c1 := endingToTxtSlice(c, "bad CAA Value", f) - if e != nil { - return nil, e, "" - } - if len(s) > 1 { - return nil, &ParseError{f, "bad CAA Value", l}, "" - } - rr.Value = s[0] - return rr, nil, c1 -} - -var typeToparserFunc = map[uint16]parserFunc{ - TypeAAAA: {setAAAA, false}, - TypeAFSDB: {setAFSDB, false}, - TypeA: {setA, false}, - TypeCAA: {setCAA, true}, - TypeCDS: {setCDS, true}, - TypeCDNSKEY: {setCDNSKEY, true}, - TypeCERT: {setCERT, true}, - TypeCNAME: {setCNAME, false}, - TypeDHCID: {setDHCID, true}, - TypeDLV: {setDLV, true}, - TypeDNAME: {setDNAME, false}, - TypeKEY: {setKEY, true}, - TypeDNSKEY: {setDNSKEY, true}, - TypeDS: {setDS, true}, - TypeEID: {setEID, true}, - TypeEUI48: {setEUI48, false}, - TypeEUI64: {setEUI64, false}, - TypeGID: {setGID, false}, - TypeGPOS: {setGPOS, false}, - TypeHINFO: {setHINFO, true}, - TypeHIP: {setHIP, true}, - TypeKX: {setKX, false}, - TypeL32: {setL32, false}, - TypeL64: {setL64, false}, - TypeLOC: {setLOC, true}, - TypeLP: {setLP, false}, - TypeMB: {setMB, false}, - TypeMD: {setMD, false}, - TypeMF: {setMF, false}, - TypeMG: {setMG, false}, - TypeMINFO: {setMINFO, false}, - TypeMR: {setMR, false}, - TypeMX: {setMX, false}, - TypeNAPTR: {setNAPTR, false}, - TypeNID: {setNID, false}, - TypeNIMLOC: {setNIMLOC, true}, - TypeNINFO: {setNINFO, true}, - TypeNSAPPTR: {setNSAPPTR, false}, - TypeNSEC3PARAM: {setNSEC3PARAM, false}, - TypeNSEC3: {setNSEC3, true}, - TypeNSEC: {setNSEC, true}, - TypeNS: {setNS, false}, - TypeOPENPGPKEY: {setOPENPGPKEY, true}, - TypePTR: {setPTR, false}, - TypePX: {setPX, false}, - TypeSIG: {setSIG, true}, - TypeRKEY: {setRKEY, true}, - TypeRP: {setRP, false}, - TypeRRSIG: {setRRSIG, true}, - TypeRT: {setRT, false}, - TypeSMIMEA: {setSMIMEA, true}, - TypeSOA: {setSOA, false}, - TypeSPF: {setSPF, true}, - TypeAVC: {setAVC, true}, - TypeSRV: {setSRV, false}, - TypeSSHFP: {setSSHFP, true}, - TypeTALINK: {setTALINK, false}, - TypeTA: {setTA, true}, - TypeTLSA: {setTLSA, true}, - TypeTXT: {setTXT, true}, - TypeUID: {setUID, false}, - TypeUINFO: {setUINFO, true}, - TypeURI: {setURI, true}, - TypeX25: {setX25, false}, -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/scanner.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/scanner.go deleted file mode 100644 index c29bc2f38..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/scanner.go +++ /dev/null @@ -1,43 +0,0 @@ -package dns - -// Implement a simple scanner, return a byte stream from an io reader. - -import ( - "bufio" - "io" - "text/scanner" -) - -type scan struct { - src *bufio.Reader - position scanner.Position - eof bool // Have we just seen a eof -} - -func scanInit(r io.Reader) *scan { - s := new(scan) - s.src = bufio.NewReader(r) - s.position.Line = 1 - return s -} - -// tokenText returns the next byte from the input -func (s *scan) tokenText() (byte, error) { - c, err := s.src.ReadByte() - if err != nil { - return c, err - } - // delay the newline handling until the next token is delivered, - // fixes off-by-one errors when reporting a parse error. - if s.eof == true { - s.position.Line++ - s.position.Column = 0 - s.eof = false - } - if c == '\n' { - s.eof = true - return c, nil - } - s.position.Column++ - return c, nil -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/server.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/server.go deleted file mode 100644 index 0ca6e008c..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/server.go +++ /dev/null @@ -1,734 +0,0 @@ -// DNS server implementation. - -package dns - -import ( - "bytes" - "crypto/tls" - "encoding/binary" - "io" - "net" - "sync" - "time" -) - -// Maximum number of TCP queries before we close the socket. -const maxTCPQueries = 128 - -// Handler is implemented by any value that implements ServeDNS. -type Handler interface { - ServeDNS(w ResponseWriter, r *Msg) -} - -// A ResponseWriter interface is used by an DNS handler to -// construct an DNS response. -type ResponseWriter interface { - // LocalAddr returns the net.Addr of the server - LocalAddr() net.Addr - // RemoteAddr returns the net.Addr of the client that sent the current request. - RemoteAddr() net.Addr - // WriteMsg writes a reply back to the client. - WriteMsg(*Msg) error - // Write writes a raw buffer back to the client. - Write([]byte) (int, error) - // Close closes the connection. - Close() error - // TsigStatus returns the status of the Tsig. - TsigStatus() error - // TsigTimersOnly sets the tsig timers only boolean. - TsigTimersOnly(bool) - // Hijack lets the caller take over the connection. - // After a call to Hijack(), the DNS package will not do anything with the connection. - Hijack() -} - -type response struct { - hijacked bool // connection has been hijacked by handler - tsigStatus error - tsigTimersOnly bool - tsigRequestMAC string - tsigSecret map[string]string // the tsig secrets - udp *net.UDPConn // i/o connection if UDP was used - tcp net.Conn // i/o connection if TCP was used - udpSession *SessionUDP // oob data to get egress interface right - remoteAddr net.Addr // address of the client - writer Writer // writer to output the raw DNS bits -} - -// ServeMux is an DNS request multiplexer. It matches the -// zone name of each incoming request against a list of -// registered patterns add calls the handler for the pattern -// that most closely matches the zone name. ServeMux is DNSSEC aware, meaning -// that queries for the DS record are redirected to the parent zone (if that -// is also registered), otherwise the child gets the query. -// ServeMux is also safe for concurrent access from multiple goroutines. -type ServeMux struct { - z map[string]Handler - m *sync.RWMutex -} - -// NewServeMux allocates and returns a new ServeMux. -func NewServeMux() *ServeMux { return &ServeMux{z: make(map[string]Handler), m: new(sync.RWMutex)} } - -// DefaultServeMux is the default ServeMux used by Serve. -var DefaultServeMux = NewServeMux() - -// The HandlerFunc type is an adapter to allow the use of -// ordinary functions as DNS handlers. If f is a function -// with the appropriate signature, HandlerFunc(f) is a -// Handler object that calls f. -type HandlerFunc func(ResponseWriter, *Msg) - -// ServeDNS calls f(w, r). -func (f HandlerFunc) ServeDNS(w ResponseWriter, r *Msg) { - f(w, r) -} - -// HandleFailed returns a HandlerFunc that returns SERVFAIL for every request it gets. -func HandleFailed(w ResponseWriter, r *Msg) { - m := new(Msg) - m.SetRcode(r, RcodeServerFailure) - // does not matter if this write fails - w.WriteMsg(m) -} - -func failedHandler() Handler { return HandlerFunc(HandleFailed) } - -// ListenAndServe Starts a server on address and network specified Invoke handler -// for incoming queries. -func ListenAndServe(addr string, network string, handler Handler) error { - server := &Server{Addr: addr, Net: network, Handler: handler} - return server.ListenAndServe() -} - -// ListenAndServeTLS acts like http.ListenAndServeTLS, more information in -// http://golang.org/pkg/net/http/#ListenAndServeTLS -func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error { - cert, err := tls.LoadX509KeyPair(certFile, keyFile) - if err != nil { - return err - } - - config := tls.Config{ - Certificates: []tls.Certificate{cert}, - } - - server := &Server{ - Addr: addr, - Net: "tcp-tls", - TLSConfig: &config, - Handler: handler, - } - - return server.ListenAndServe() -} - -// ActivateAndServe activates a server with a listener from systemd, -// l and p should not both be non-nil. -// If both l and p are not nil only p will be used. -// Invoke handler for incoming queries. -func ActivateAndServe(l net.Listener, p net.PacketConn, handler Handler) error { - server := &Server{Listener: l, PacketConn: p, Handler: handler} - return server.ActivateAndServe() -} - -func (mux *ServeMux) match(q string, t uint16) Handler { - mux.m.RLock() - defer mux.m.RUnlock() - var handler Handler - b := make([]byte, len(q)) // worst case, one label of length q - off := 0 - end := false - for { - l := len(q[off:]) - for i := 0; i < l; i++ { - b[i] = q[off+i] - if b[i] >= 'A' && b[i] <= 'Z' { - b[i] |= ('a' - 'A') - } - } - if h, ok := mux.z[string(b[:l])]; ok { // causes garbage, might want to change the map key - if t != TypeDS { - return h - } - // Continue for DS to see if we have a parent too, if so delegeate to the parent - handler = h - } - off, end = NextLabel(q, off) - if end { - break - } - } - // Wildcard match, if we have found nothing try the root zone as a last resort. - if h, ok := mux.z["."]; ok { - return h - } - return handler -} - -// Handle adds a handler to the ServeMux for pattern. -func (mux *ServeMux) Handle(pattern string, handler Handler) { - if pattern == "" { - panic("dns: invalid pattern " + pattern) - } - mux.m.Lock() - mux.z[Fqdn(pattern)] = handler - mux.m.Unlock() -} - -// HandleFunc adds a handler function to the ServeMux for pattern. -func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Msg)) { - mux.Handle(pattern, HandlerFunc(handler)) -} - -// HandleRemove deregistrars the handler specific for pattern from the ServeMux. -func (mux *ServeMux) HandleRemove(pattern string) { - if pattern == "" { - panic("dns: invalid pattern " + pattern) - } - mux.m.Lock() - delete(mux.z, Fqdn(pattern)) - mux.m.Unlock() -} - -// ServeDNS dispatches the request to the handler whose -// pattern most closely matches the request message. If DefaultServeMux -// is used the correct thing for DS queries is done: a possible parent -// is sought. -// If no handler is found a standard SERVFAIL message is returned -// If the request message does not have exactly one question in the -// question section a SERVFAIL is returned, unlesss Unsafe is true. -func (mux *ServeMux) ServeDNS(w ResponseWriter, request *Msg) { - var h Handler - if len(request.Question) < 1 { // allow more than one question - h = failedHandler() - } else { - if h = mux.match(request.Question[0].Name, request.Question[0].Qtype); h == nil { - h = failedHandler() - } - } - h.ServeDNS(w, request) -} - -// Handle registers the handler with the given pattern -// in the DefaultServeMux. The documentation for -// ServeMux explains how patterns are matched. -func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) } - -// HandleRemove deregisters the handle with the given pattern -// in the DefaultServeMux. -func HandleRemove(pattern string) { DefaultServeMux.HandleRemove(pattern) } - -// HandleFunc registers the handler function with the given pattern -// in the DefaultServeMux. -func HandleFunc(pattern string, handler func(ResponseWriter, *Msg)) { - DefaultServeMux.HandleFunc(pattern, handler) -} - -// Writer writes raw DNS messages; each call to Write should send an entire message. -type Writer interface { - io.Writer -} - -// Reader reads raw DNS messages; each call to ReadTCP or ReadUDP should return an entire message. -type Reader interface { - // ReadTCP reads a raw message from a TCP connection. Implementations may alter - // connection properties, for example the read-deadline. - ReadTCP(conn net.Conn, timeout time.Duration) ([]byte, error) - // ReadUDP reads a raw message from a UDP connection. Implementations may alter - // connection properties, for example the read-deadline. - ReadUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error) -} - -// defaultReader is an adapter for the Server struct that implements the Reader interface -// using the readTCP and readUDP func of the embedded Server. -type defaultReader struct { - *Server -} - -func (dr *defaultReader) ReadTCP(conn net.Conn, timeout time.Duration) ([]byte, error) { - return dr.readTCP(conn, timeout) -} - -func (dr *defaultReader) ReadUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error) { - return dr.readUDP(conn, timeout) -} - -// DecorateReader is a decorator hook for extending or supplanting the functionality of a Reader. -// Implementations should never return a nil Reader. -type DecorateReader func(Reader) Reader - -// DecorateWriter is a decorator hook for extending or supplanting the functionality of a Writer. -// Implementations should never return a nil Writer. -type DecorateWriter func(Writer) Writer - -// A Server defines parameters for running an DNS server. -type Server struct { - // Address to listen on, ":dns" if empty. - Addr string - // if "tcp" or "tcp-tls" (DNS over TLS) it will invoke a TCP listener, otherwise an UDP one - Net string - // TCP Listener to use, this is to aid in systemd's socket activation. - Listener net.Listener - // TLS connection configuration - TLSConfig *tls.Config - // UDP "Listener" to use, this is to aid in systemd's socket activation. - PacketConn net.PacketConn - // Handler to invoke, dns.DefaultServeMux if nil. - Handler Handler - // Default buffer size to use to read incoming UDP messages. If not set - // it defaults to MinMsgSize (512 B). - UDPSize int - // The net.Conn.SetReadTimeout value for new connections, defaults to 2 * time.Second. - ReadTimeout time.Duration - // The net.Conn.SetWriteTimeout value for new connections, defaults to 2 * time.Second. - WriteTimeout time.Duration - // TCP idle timeout for multiple queries, if nil, defaults to 8 * time.Second (RFC 5966). - IdleTimeout func() time.Duration - // Secret(s) for Tsig map[<zonename>]<base64 secret>. - TsigSecret map[string]string - // Unsafe instructs the server to disregard any sanity checks and directly hand the message to - // the handler. It will specifically not check if the query has the QR bit not set. - Unsafe bool - // If NotifyStartedFunc is set it is called once the server has started listening. - NotifyStartedFunc func() - // DecorateReader is optional, allows customization of the process that reads raw DNS messages. - DecorateReader DecorateReader - // DecorateWriter is optional, allows customization of the process that writes raw DNS messages. - DecorateWriter DecorateWriter - - // Graceful shutdown handling - - inFlight sync.WaitGroup - - lock sync.RWMutex - started bool -} - -// ListenAndServe starts a nameserver on the configured address in *Server. -func (srv *Server) ListenAndServe() error { - srv.lock.Lock() - defer srv.lock.Unlock() - if srv.started { - return &Error{err: "server already started"} - } - addr := srv.Addr - if addr == "" { - addr = ":domain" - } - if srv.UDPSize == 0 { - srv.UDPSize = MinMsgSize - } - switch srv.Net { - case "tcp", "tcp4", "tcp6": - a, err := net.ResolveTCPAddr(srv.Net, addr) - if err != nil { - return err - } - l, err := net.ListenTCP(srv.Net, a) - if err != nil { - return err - } - srv.Listener = l - srv.started = true - srv.lock.Unlock() - err = srv.serveTCP(l) - srv.lock.Lock() // to satisfy the defer at the top - return err - case "tcp-tls", "tcp4-tls", "tcp6-tls": - network := "tcp" - if srv.Net == "tcp4-tls" { - network = "tcp4" - } else if srv.Net == "tcp6-tls" { - network = "tcp6" - } - - l, err := tls.Listen(network, addr, srv.TLSConfig) - if err != nil { - return err - } - srv.Listener = l - srv.started = true - srv.lock.Unlock() - err = srv.serveTCP(l) - srv.lock.Lock() // to satisfy the defer at the top - return err - case "udp", "udp4", "udp6": - a, err := net.ResolveUDPAddr(srv.Net, addr) - if err != nil { - return err - } - l, err := net.ListenUDP(srv.Net, a) - if err != nil { - return err - } - if e := setUDPSocketOptions(l); e != nil { - return e - } - srv.PacketConn = l - srv.started = true - srv.lock.Unlock() - err = srv.serveUDP(l) - srv.lock.Lock() // to satisfy the defer at the top - return err - } - return &Error{err: "bad network"} -} - -// ActivateAndServe starts a nameserver with the PacketConn or Listener -// configured in *Server. Its main use is to start a server from systemd. -func (srv *Server) ActivateAndServe() error { - srv.lock.Lock() - defer srv.lock.Unlock() - if srv.started { - return &Error{err: "server already started"} - } - pConn := srv.PacketConn - l := srv.Listener - if pConn != nil { - if srv.UDPSize == 0 { - srv.UDPSize = MinMsgSize - } - // Check PacketConn interface's type is valid and value - // is not nil - if t, ok := pConn.(*net.UDPConn); ok && t != nil { - if e := setUDPSocketOptions(t); e != nil { - return e - } - srv.started = true - srv.lock.Unlock() - e := srv.serveUDP(t) - srv.lock.Lock() // to satisfy the defer at the top - return e - } - } - if l != nil { - srv.started = true - srv.lock.Unlock() - e := srv.serveTCP(l) - srv.lock.Lock() // to satisfy the defer at the top - return e - } - return &Error{err: "bad listeners"} -} - -// Shutdown gracefully shuts down a server. After a call to Shutdown, ListenAndServe and -// ActivateAndServe will return. All in progress queries are completed before the server -// is taken down. If the Shutdown is taking longer than the reading timeout an error -// is returned. -func (srv *Server) Shutdown() error { - srv.lock.Lock() - if !srv.started { - srv.lock.Unlock() - return &Error{err: "server not started"} - } - srv.started = false - srv.lock.Unlock() - - if srv.PacketConn != nil { - srv.PacketConn.Close() - } - if srv.Listener != nil { - srv.Listener.Close() - } - - fin := make(chan bool) - go func() { - srv.inFlight.Wait() - fin <- true - }() - - select { - case <-time.After(srv.getReadTimeout()): - return &Error{err: "server shutdown is pending"} - case <-fin: - return nil - } -} - -// getReadTimeout is a helper func to use system timeout if server did not intend to change it. -func (srv *Server) getReadTimeout() time.Duration { - rtimeout := dnsTimeout - if srv.ReadTimeout != 0 { - rtimeout = srv.ReadTimeout - } - return rtimeout -} - -// serveTCP starts a TCP listener for the server. -// Each request is handled in a separate goroutine. -func (srv *Server) serveTCP(l net.Listener) error { - defer l.Close() - - if srv.NotifyStartedFunc != nil { - srv.NotifyStartedFunc() - } - - reader := Reader(&defaultReader{srv}) - if srv.DecorateReader != nil { - reader = srv.DecorateReader(reader) - } - - handler := srv.Handler - if handler == nil { - handler = DefaultServeMux - } - rtimeout := srv.getReadTimeout() - // deadline is not used here - for { - rw, err := l.Accept() - if err != nil { - if neterr, ok := err.(net.Error); ok && neterr.Temporary() { - continue - } - return err - } - m, err := reader.ReadTCP(rw, rtimeout) - srv.lock.RLock() - if !srv.started { - srv.lock.RUnlock() - return nil - } - srv.lock.RUnlock() - if err != nil { - continue - } - srv.inFlight.Add(1) - go srv.serve(rw.RemoteAddr(), handler, m, nil, nil, rw) - } -} - -// serveUDP starts a UDP listener for the server. -// Each request is handled in a separate goroutine. -func (srv *Server) serveUDP(l *net.UDPConn) error { - defer l.Close() - - if srv.NotifyStartedFunc != nil { - srv.NotifyStartedFunc() - } - - reader := Reader(&defaultReader{srv}) - if srv.DecorateReader != nil { - reader = srv.DecorateReader(reader) - } - - handler := srv.Handler - if handler == nil { - handler = DefaultServeMux - } - rtimeout := srv.getReadTimeout() - // deadline is not used here - for { - m, s, err := reader.ReadUDP(l, rtimeout) - srv.lock.RLock() - if !srv.started { - srv.lock.RUnlock() - return nil - } - srv.lock.RUnlock() - if err != nil { - continue - } - srv.inFlight.Add(1) - go srv.serve(s.RemoteAddr(), handler, m, l, s, nil) - } -} - -// Serve a new connection. -func (srv *Server) serve(a net.Addr, h Handler, m []byte, u *net.UDPConn, s *SessionUDP, t net.Conn) { - defer srv.inFlight.Done() - - w := &response{tsigSecret: srv.TsigSecret, udp: u, tcp: t, remoteAddr: a, udpSession: s} - if srv.DecorateWriter != nil { - w.writer = srv.DecorateWriter(w) - } else { - w.writer = w - } - - q := 0 // counter for the amount of TCP queries we get - - reader := Reader(&defaultReader{srv}) - if srv.DecorateReader != nil { - reader = srv.DecorateReader(reader) - } -Redo: - req := new(Msg) - err := req.Unpack(m) - if err != nil { // Send a FormatError back - x := new(Msg) - x.SetRcodeFormatError(req) - w.WriteMsg(x) - goto Exit - } - if !srv.Unsafe && req.Response { - goto Exit - } - - w.tsigStatus = nil - if w.tsigSecret != nil { - if t := req.IsTsig(); t != nil { - secret := t.Hdr.Name - if _, ok := w.tsigSecret[secret]; !ok { - w.tsigStatus = ErrKeyAlg - } - w.tsigStatus = TsigVerify(m, w.tsigSecret[secret], "", false) - w.tsigTimersOnly = false - w.tsigRequestMAC = req.Extra[len(req.Extra)-1].(*TSIG).MAC - } - } - h.ServeDNS(w, req) // Writes back to the client - -Exit: - if w.tcp == nil { - return - } - // TODO(miek): make this number configurable? - if q > maxTCPQueries { // close socket after this many queries - w.Close() - return - } - - if w.hijacked { - return // client calls Close() - } - if u != nil { // UDP, "close" and return - w.Close() - return - } - idleTimeout := tcpIdleTimeout - if srv.IdleTimeout != nil { - idleTimeout = srv.IdleTimeout() - } - m, err = reader.ReadTCP(w.tcp, idleTimeout) - if err == nil { - q++ - goto Redo - } - w.Close() - return -} - -func (srv *Server) readTCP(conn net.Conn, timeout time.Duration) ([]byte, error) { - conn.SetReadDeadline(time.Now().Add(timeout)) - l := make([]byte, 2) - n, err := conn.Read(l) - if err != nil || n != 2 { - if err != nil { - return nil, err - } - return nil, ErrShortRead - } - length := binary.BigEndian.Uint16(l) - if length == 0 { - return nil, ErrShortRead - } - m := make([]byte, int(length)) - n, err = conn.Read(m[:int(length)]) - if err != nil || n == 0 { - if err != nil { - return nil, err - } - return nil, ErrShortRead - } - i := n - for i < int(length) { - j, err := conn.Read(m[i:int(length)]) - if err != nil { - return nil, err - } - i += j - } - n = i - m = m[:n] - return m, nil -} - -func (srv *Server) readUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error) { - conn.SetReadDeadline(time.Now().Add(timeout)) - m := make([]byte, srv.UDPSize) - n, s, err := ReadFromSessionUDP(conn, m) - if err != nil || n == 0 { - if err != nil { - return nil, nil, err - } - return nil, nil, ErrShortRead - } - m = m[:n] - return m, s, nil -} - -// WriteMsg implements the ResponseWriter.WriteMsg method. -func (w *response) WriteMsg(m *Msg) (err error) { - var data []byte - if w.tsigSecret != nil { // if no secrets, dont check for the tsig (which is a longer check) - if t := m.IsTsig(); t != nil { - data, w.tsigRequestMAC, err = TsigGenerate(m, w.tsigSecret[t.Hdr.Name], w.tsigRequestMAC, w.tsigTimersOnly) - if err != nil { - return err - } - _, err = w.writer.Write(data) - return err - } - } - data, err = m.Pack() - if err != nil { - return err - } - _, err = w.writer.Write(data) - return err -} - -// Write implements the ResponseWriter.Write method. -func (w *response) Write(m []byte) (int, error) { - switch { - case w.udp != nil: - n, err := WriteToSessionUDP(w.udp, m, w.udpSession) - return n, err - case w.tcp != nil: - lm := len(m) - if lm < 2 { - return 0, io.ErrShortBuffer - } - if lm > MaxMsgSize { - return 0, &Error{err: "message too large"} - } - l := make([]byte, 2, 2+lm) - binary.BigEndian.PutUint16(l, uint16(lm)) - m = append(l, m...) - - n, err := io.Copy(w.tcp, bytes.NewReader(m)) - return int(n), err - } - panic("not reached") -} - -// LocalAddr implements the ResponseWriter.LocalAddr method. -func (w *response) LocalAddr() net.Addr { - if w.tcp != nil { - return w.tcp.LocalAddr() - } - return w.udp.LocalAddr() -} - -// RemoteAddr implements the ResponseWriter.RemoteAddr method. -func (w *response) RemoteAddr() net.Addr { return w.remoteAddr } - -// TsigStatus implements the ResponseWriter.TsigStatus method. -func (w *response) TsigStatus() error { return w.tsigStatus } - -// TsigTimersOnly implements the ResponseWriter.TsigTimersOnly method. -func (w *response) TsigTimersOnly(b bool) { w.tsigTimersOnly = b } - -// Hijack implements the ResponseWriter.Hijack method. -func (w *response) Hijack() { w.hijacked = true } - -// Close implements the ResponseWriter.Close method -func (w *response) Close() error { - // Can't close the udp conn, as that is actually the listener. - if w.tcp != nil { - e := w.tcp.Close() - w.tcp = nil - return e - } - return nil -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/server_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/server_test.go deleted file mode 100644 index f17a2f90f..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/server_test.go +++ /dev/null @@ -1,719 +0,0 @@ -package dns - -import ( - "crypto/tls" - "fmt" - "io" - "net" - "runtime" - "sync" - "testing" - "time" -) - -func HelloServer(w ResponseWriter, req *Msg) { - m := new(Msg) - m.SetReply(req) - - m.Extra = make([]RR, 1) - m.Extra[0] = &TXT{Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}} - w.WriteMsg(m) -} - -func HelloServerBadID(w ResponseWriter, req *Msg) { - m := new(Msg) - m.SetReply(req) - m.Id++ - - m.Extra = make([]RR, 1) - m.Extra[0] = &TXT{Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}} - w.WriteMsg(m) -} - -func AnotherHelloServer(w ResponseWriter, req *Msg) { - m := new(Msg) - m.SetReply(req) - - m.Extra = make([]RR, 1) - m.Extra[0] = &TXT{Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello example"}} - w.WriteMsg(m) -} - -func RunLocalUDPServer(laddr string) (*Server, string, error) { - server, l, _, err := RunLocalUDPServerWithFinChan(laddr) - - return server, l, err -} - -func RunLocalUDPServerWithFinChan(laddr string) (*Server, string, chan struct{}, error) { - pc, err := net.ListenPacket("udp", laddr) - if err != nil { - return nil, "", nil, err - } - server := &Server{PacketConn: pc, ReadTimeout: time.Hour, WriteTimeout: time.Hour} - - waitLock := sync.Mutex{} - waitLock.Lock() - server.NotifyStartedFunc = waitLock.Unlock - - fin := make(chan struct{}, 0) - - go func() { - server.ActivateAndServe() - close(fin) - pc.Close() - }() - - waitLock.Lock() - return server, pc.LocalAddr().String(), fin, nil -} - -func RunLocalUDPServerUnsafe(laddr string) (*Server, string, error) { - pc, err := net.ListenPacket("udp", laddr) - if err != nil { - return nil, "", err - } - server := &Server{PacketConn: pc, Unsafe: true, - ReadTimeout: time.Hour, WriteTimeout: time.Hour} - - waitLock := sync.Mutex{} - waitLock.Lock() - server.NotifyStartedFunc = waitLock.Unlock - - go func() { - server.ActivateAndServe() - pc.Close() - }() - - waitLock.Lock() - return server, pc.LocalAddr().String(), nil -} - -func RunLocalTCPServer(laddr string) (*Server, string, error) { - l, err := net.Listen("tcp", laddr) - if err != nil { - return nil, "", err - } - - server := &Server{Listener: l, ReadTimeout: time.Hour, WriteTimeout: time.Hour} - - waitLock := sync.Mutex{} - waitLock.Lock() - server.NotifyStartedFunc = waitLock.Unlock - - go func() { - server.ActivateAndServe() - l.Close() - }() - - waitLock.Lock() - return server, l.Addr().String(), nil -} - -func RunLocalTLSServer(laddr string, config *tls.Config) (*Server, string, error) { - l, err := tls.Listen("tcp", laddr, config) - if err != nil { - return nil, "", err - } - - server := &Server{Listener: l, ReadTimeout: time.Hour, WriteTimeout: time.Hour} - - waitLock := sync.Mutex{} - waitLock.Lock() - server.NotifyStartedFunc = waitLock.Unlock - - go func() { - server.ActivateAndServe() - l.Close() - }() - - waitLock.Lock() - return server, l.Addr().String(), nil -} - -func TestServing(t *testing.T) { - HandleFunc("miek.nl.", HelloServer) - HandleFunc("example.com.", AnotherHelloServer) - defer HandleRemove("miek.nl.") - defer HandleRemove("example.com.") - - s, addrstr, err := RunLocalUDPServer("127.0.0.1:0") - if err != nil { - t.Fatalf("unable to run test server: %v", err) - } - defer s.Shutdown() - - c := new(Client) - m := new(Msg) - m.SetQuestion("miek.nl.", TypeTXT) - r, _, err := c.Exchange(m, addrstr) - if err != nil || len(r.Extra) == 0 { - t.Fatal("failed to exchange miek.nl", err) - } - txt := r.Extra[0].(*TXT).Txt[0] - if txt != "Hello world" { - t.Error("unexpected result for miek.nl", txt, "!= Hello world") - } - - m.SetQuestion("example.com.", TypeTXT) - r, _, err = c.Exchange(m, addrstr) - if err != nil { - t.Fatal("failed to exchange example.com", err) - } - txt = r.Extra[0].(*TXT).Txt[0] - if txt != "Hello example" { - t.Error("unexpected result for example.com", txt, "!= Hello example") - } - - // Test Mixes cased as noticed by Ask. - m.SetQuestion("eXaMplE.cOm.", TypeTXT) - r, _, err = c.Exchange(m, addrstr) - if err != nil { - t.Error("failed to exchange eXaMplE.cOm", err) - } - txt = r.Extra[0].(*TXT).Txt[0] - if txt != "Hello example" { - t.Error("unexpected result for example.com", txt, "!= Hello example") - } -} - -func TestServingTLS(t *testing.T) { - HandleFunc("miek.nl.", HelloServer) - HandleFunc("example.com.", AnotherHelloServer) - defer HandleRemove("miek.nl.") - defer HandleRemove("example.com.") - - cert, err := tls.X509KeyPair(CertPEMBlock, KeyPEMBlock) - if err != nil { - t.Fatalf("unable to build certificate: %v", err) - } - - config := tls.Config{ - Certificates: []tls.Certificate{cert}, - } - - s, addrstr, err := RunLocalTLSServer("127.0.0.1:0", &config) - if err != nil { - t.Fatalf("unable to run test server: %v", err) - } - defer s.Shutdown() - - c := new(Client) - c.Net = "tcp-tls" - c.TLSConfig = &tls.Config{ - InsecureSkipVerify: true, - } - - m := new(Msg) - m.SetQuestion("miek.nl.", TypeTXT) - r, _, err := c.Exchange(m, addrstr) - if err != nil || len(r.Extra) == 0 { - t.Fatal("failed to exchange miek.nl", err) - } - txt := r.Extra[0].(*TXT).Txt[0] - if txt != "Hello world" { - t.Error("unexpected result for miek.nl", txt, "!= Hello world") - } - - m.SetQuestion("example.com.", TypeTXT) - r, _, err = c.Exchange(m, addrstr) - if err != nil { - t.Fatal("failed to exchange example.com", err) - } - txt = r.Extra[0].(*TXT).Txt[0] - if txt != "Hello example" { - t.Error("unexpected result for example.com", txt, "!= Hello example") - } - - // Test Mixes cased as noticed by Ask. - m.SetQuestion("eXaMplE.cOm.", TypeTXT) - r, _, err = c.Exchange(m, addrstr) - if err != nil { - t.Error("failed to exchange eXaMplE.cOm", err) - } - txt = r.Extra[0].(*TXT).Txt[0] - if txt != "Hello example" { - t.Error("unexpected result for example.com", txt, "!= Hello example") - } -} - -func BenchmarkServe(b *testing.B) { - b.StopTimer() - HandleFunc("miek.nl.", HelloServer) - defer HandleRemove("miek.nl.") - a := runtime.GOMAXPROCS(4) - - s, addrstr, err := RunLocalUDPServer("127.0.0.1:0") - if err != nil { - b.Fatalf("unable to run test server: %v", err) - } - defer s.Shutdown() - - c := new(Client) - m := new(Msg) - m.SetQuestion("miek.nl", TypeSOA) - - b.StartTimer() - for i := 0; i < b.N; i++ { - c.Exchange(m, addrstr) - } - runtime.GOMAXPROCS(a) -} - -func benchmarkServe6(b *testing.B) { - b.StopTimer() - HandleFunc("miek.nl.", HelloServer) - defer HandleRemove("miek.nl.") - a := runtime.GOMAXPROCS(4) - s, addrstr, err := RunLocalUDPServer("[::1]:0") - if err != nil { - b.Fatalf("unable to run test server: %v", err) - } - defer s.Shutdown() - - c := new(Client) - m := new(Msg) - m.SetQuestion("miek.nl", TypeSOA) - - b.StartTimer() - for i := 0; i < b.N; i++ { - c.Exchange(m, addrstr) - } - runtime.GOMAXPROCS(a) -} - -func HelloServerCompress(w ResponseWriter, req *Msg) { - m := new(Msg) - m.SetReply(req) - m.Extra = make([]RR, 1) - m.Extra[0] = &TXT{Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}} - m.Compress = true - w.WriteMsg(m) -} - -func BenchmarkServeCompress(b *testing.B) { - b.StopTimer() - HandleFunc("miek.nl.", HelloServerCompress) - defer HandleRemove("miek.nl.") - a := runtime.GOMAXPROCS(4) - s, addrstr, err := RunLocalUDPServer("127.0.0.1:0") - if err != nil { - b.Fatalf("unable to run test server: %v", err) - } - defer s.Shutdown() - - c := new(Client) - m := new(Msg) - m.SetQuestion("miek.nl", TypeSOA) - b.StartTimer() - for i := 0; i < b.N; i++ { - c.Exchange(m, addrstr) - } - runtime.GOMAXPROCS(a) -} - -func TestDotAsCatchAllWildcard(t *testing.T) { - mux := NewServeMux() - mux.Handle(".", HandlerFunc(HelloServer)) - mux.Handle("example.com.", HandlerFunc(AnotherHelloServer)) - - handler := mux.match("www.miek.nl.", TypeTXT) - if handler == nil { - t.Error("wildcard match failed") - } - - handler = mux.match("www.example.com.", TypeTXT) - if handler == nil { - t.Error("example.com match failed") - } - - handler = mux.match("a.www.example.com.", TypeTXT) - if handler == nil { - t.Error("a.www.example.com match failed") - } - - handler = mux.match("boe.", TypeTXT) - if handler == nil { - t.Error("boe. match failed") - } -} - -func TestCaseFolding(t *testing.T) { - mux := NewServeMux() - mux.Handle("_udp.example.com.", HandlerFunc(HelloServer)) - - handler := mux.match("_dns._udp.example.com.", TypeSRV) - if handler == nil { - t.Error("case sensitive characters folded") - } - - handler = mux.match("_DNS._UDP.EXAMPLE.COM.", TypeSRV) - if handler == nil { - t.Error("case insensitive characters not folded") - } -} - -func TestRootServer(t *testing.T) { - mux := NewServeMux() - mux.Handle(".", HandlerFunc(HelloServer)) - - handler := mux.match(".", TypeNS) - if handler == nil { - t.Error("root match failed") - } -} - -type maxRec struct { - max int - sync.RWMutex -} - -var M = new(maxRec) - -func HelloServerLargeResponse(resp ResponseWriter, req *Msg) { - m := new(Msg) - m.SetReply(req) - m.Authoritative = true - m1 := 0 - M.RLock() - m1 = M.max - M.RUnlock() - for i := 0; i < m1; i++ { - aRec := &A{ - Hdr: RR_Header{ - Name: req.Question[0].Name, - Rrtype: TypeA, - Class: ClassINET, - Ttl: 0, - }, - A: net.ParseIP(fmt.Sprintf("127.0.0.%d", i+1)).To4(), - } - m.Answer = append(m.Answer, aRec) - } - resp.WriteMsg(m) -} - -func TestServingLargeResponses(t *testing.T) { - HandleFunc("example.", HelloServerLargeResponse) - defer HandleRemove("example.") - - s, addrstr, err := RunLocalUDPServer("127.0.0.1:0") - if err != nil { - t.Fatalf("unable to run test server: %v", err) - } - defer s.Shutdown() - - // Create request - m := new(Msg) - m.SetQuestion("web.service.example.", TypeANY) - - c := new(Client) - c.Net = "udp" - M.Lock() - M.max = 2 - M.Unlock() - _, _, err = c.Exchange(m, addrstr) - if err != nil { - t.Errorf("failed to exchange: %v", err) - } - // This must fail - M.Lock() - M.max = 20 - M.Unlock() - _, _, err = c.Exchange(m, addrstr) - if err == nil { - t.Error("failed to fail exchange, this should generate packet error") - } - // But this must work again - c.UDPSize = 7000 - _, _, err = c.Exchange(m, addrstr) - if err != nil { - t.Errorf("failed to exchange: %v", err) - } -} - -func TestServingResponse(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - HandleFunc("miek.nl.", HelloServer) - s, addrstr, err := RunLocalUDPServer("127.0.0.1:0") - if err != nil { - t.Fatalf("unable to run test server: %v", err) - } - - c := new(Client) - m := new(Msg) - m.SetQuestion("miek.nl.", TypeTXT) - m.Response = false - _, _, err = c.Exchange(m, addrstr) - if err != nil { - t.Fatal("failed to exchange", err) - } - m.Response = true - _, _, err = c.Exchange(m, addrstr) - if err == nil { - t.Fatal("exchanged response message") - } - - s.Shutdown() - s, addrstr, err = RunLocalUDPServerUnsafe("127.0.0.1:0") - if err != nil { - t.Fatalf("unable to run test server: %v", err) - } - defer s.Shutdown() - - m.Response = true - _, _, err = c.Exchange(m, addrstr) - if err != nil { - t.Fatal("could exchanged response message in Unsafe mode") - } -} - -func TestShutdownTCP(t *testing.T) { - s, _, err := RunLocalTCPServer("127.0.0.1:0") - if err != nil { - t.Fatalf("unable to run test server: %v", err) - } - err = s.Shutdown() - if err != nil { - t.Errorf("could not shutdown test TCP server, %v", err) - } -} - -func TestShutdownTLS(t *testing.T) { - cert, err := tls.X509KeyPair(CertPEMBlock, KeyPEMBlock) - if err != nil { - t.Fatalf("unable to build certificate: %v", err) - } - - config := tls.Config{ - Certificates: []tls.Certificate{cert}, - } - - s, _, err := RunLocalTLSServer("127.0.0.1:0", &config) - if err != nil { - t.Fatalf("unable to run test server: %v", err) - } - err = s.Shutdown() - if err != nil { - t.Errorf("could not shutdown test TLS server, %v", err) - } -} - -type trigger struct { - done bool - sync.RWMutex -} - -func (t *trigger) Set() { - t.Lock() - defer t.Unlock() - t.done = true -} -func (t *trigger) Get() bool { - t.RLock() - defer t.RUnlock() - return t.done -} - -func TestHandlerCloseTCP(t *testing.T) { - - ln, err := net.Listen("tcp", "127.0.0.1:0") - if err != nil { - panic(err) - } - addr := ln.Addr().String() - - server := &Server{Addr: addr, Net: "tcp", Listener: ln} - - hname := "testhandlerclosetcp." - triggered := &trigger{} - HandleFunc(hname, func(w ResponseWriter, r *Msg) { - triggered.Set() - w.Close() - }) - defer HandleRemove(hname) - - go func() { - defer server.Shutdown() - c := &Client{Net: "tcp"} - m := new(Msg).SetQuestion(hname, 1) - tries := 0 - exchange: - _, _, err := c.Exchange(m, addr) - if err != nil && err != io.EOF { - t.Logf("exchange failed: %s\n", err) - if tries == 3 { - return - } - time.Sleep(time.Second / 10) - tries++ - goto exchange - } - }() - server.ActivateAndServe() - if !triggered.Get() { - t.Fatalf("handler never called") - } -} - -func TestShutdownUDP(t *testing.T) { - s, _, fin, err := RunLocalUDPServerWithFinChan("127.0.0.1:0") - if err != nil { - t.Fatalf("unable to run test server: %v", err) - } - err = s.Shutdown() - if err != nil { - t.Errorf("could not shutdown test UDP server, %v", err) - } - select { - case <-fin: - case <-time.After(2 * time.Second): - t.Error("Could not shutdown test UDP server. Gave up waiting") - } -} - -type ExampleFrameLengthWriter struct { - Writer -} - -func (e *ExampleFrameLengthWriter) Write(m []byte) (int, error) { - fmt.Println("writing raw DNS message of length", len(m)) - return e.Writer.Write(m) -} - -func ExampleDecorateWriter() { - // instrument raw DNS message writing - wf := DecorateWriter(func(w Writer) Writer { - return &ExampleFrameLengthWriter{w} - }) - - // simple UDP server - pc, err := net.ListenPacket("udp", "127.0.0.1:0") - if err != nil { - fmt.Println(err.Error()) - return - } - server := &Server{ - PacketConn: pc, - DecorateWriter: wf, - ReadTimeout: time.Hour, WriteTimeout: time.Hour, - } - - waitLock := sync.Mutex{} - waitLock.Lock() - server.NotifyStartedFunc = waitLock.Unlock - defer server.Shutdown() - - go func() { - server.ActivateAndServe() - pc.Close() - }() - - waitLock.Lock() - - HandleFunc("miek.nl.", HelloServer) - - c := new(Client) - m := new(Msg) - m.SetQuestion("miek.nl.", TypeTXT) - _, _, err = c.Exchange(m, pc.LocalAddr().String()) - if err != nil { - fmt.Println("failed to exchange", err.Error()) - return - } - // Output: writing raw DNS message of length 56 -} - -var ( - // CertPEMBlock is a X509 data used to test TLS servers (used with tls.X509KeyPair) - CertPEMBlock = []byte(`-----BEGIN CERTIFICATE----- -MIIDAzCCAeugAwIBAgIRAJFYMkcn+b8dpU15wjf++GgwDQYJKoZIhvcNAQELBQAw -EjEQMA4GA1UEChMHQWNtZSBDbzAeFw0xNjAxMDgxMjAzNTNaFw0xNzAxMDcxMjAz -NTNaMBIxEDAOBgNVBAoTB0FjbWUgQ28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -ggEKAoIBAQDXjqO6skvP03k58CNjQggd9G/mt+Wa+xRU+WXiKCCHttawM8x+slq5 -yfsHCwxlwsGn79HmJqecNqgHb2GWBXAvVVokFDTcC1hUP4+gp2gu9Ny27UHTjlLm -O0l/xZ5MN8tfKyYlFw18tXu3fkaPyHj8v/D1RDkuo4ARdFvGSe8TqisbhLk2+9ow -xfIGbEM9Fdiw8qByC2+d+FfvzIKz3GfQVwn0VoRom8L6NBIANq1IGrB5JefZB6nv -DnfuxkBmY7F1513HKuEJ8KsLWWZWV9OPU4j4I4Rt+WJNlKjbD2srHxyrS2RDsr91 -8nCkNoWVNO3sZq0XkWKecdc921vL4ginAgMBAAGjVDBSMA4GA1UdDwEB/wQEAwIC -pDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MBoGA1UdEQQT -MBGCCWxvY2FsaG9zdIcEfwAAATANBgkqhkiG9w0BAQsFAAOCAQEAGcU3iyLBIVZj -aDzSvEDHUd1bnLBl1C58Xu/CyKlPqVU7mLfK0JcgEaYQTSX6fCJVNLbbCrcGLsPJ -fbjlBbyeLjTV413fxPVuona62pBFjqdtbli2Qe8FRH2KBdm41JUJGdo+SdsFu7nc -BFOcubdw6LLIXvsTvwndKcHWx1rMX709QU1Vn1GAIsbJV/DWI231Jyyb+lxAUx/C -8vce5uVxiKcGS+g6OjsN3D3TtiEQGSXLh013W6Wsih8td8yMCMZ3w8LQ38br1GUe -ahLIgUJ9l6HDguM17R7kGqxNvbElsMUHfTtXXP7UDQUiYXDakg8xDP6n9DCDhJ8Y -bSt7OLB7NQ== ------END CERTIFICATE-----`) - - // KeyPEMBlock is a X509 data used to test TLS servers (used with tls.X509KeyPair) - KeyPEMBlock = []byte(`-----BEGIN RSA PRIVATE KEY----- -MIIEpQIBAAKCAQEA146jurJLz9N5OfAjY0IIHfRv5rflmvsUVPll4iggh7bWsDPM -frJaucn7BwsMZcLBp+/R5iannDaoB29hlgVwL1VaJBQ03AtYVD+PoKdoLvTctu1B -045S5jtJf8WeTDfLXysmJRcNfLV7t35Gj8h4/L/w9UQ5LqOAEXRbxknvE6orG4S5 -NvvaMMXyBmxDPRXYsPKgcgtvnfhX78yCs9xn0FcJ9FaEaJvC+jQSADatSBqweSXn -2Qep7w537sZAZmOxdeddxyrhCfCrC1lmVlfTj1OI+COEbfliTZSo2w9rKx8cq0tk -Q7K/dfJwpDaFlTTt7GatF5FinnHXPdtby+IIpwIDAQABAoIBAAJK4RDmPooqTJrC -JA41MJLo+5uvjwCT9QZmVKAQHzByUFw1YNJkITTiognUI0CdzqNzmH7jIFs39ZeG -proKusO2G6xQjrNcZ4cV2fgyb5g4QHStl0qhs94A+WojduiGm2IaumAgm6Mc5wDv -ld6HmknN3Mku/ZCyanVFEIjOVn2WB7ZQLTBs6ZYaebTJG2Xv6p9t2YJW7pPQ9Xce -s9ohAWohyM4X/OvfnfnLtQp2YLw/BxwehBsCR5SXM3ibTKpFNtxJC8hIfTuWtxZu -2ywrmXShYBRB1WgtZt5k04bY/HFncvvcHK3YfI1+w4URKtwdaQgPUQRbVwDwuyBn -flfkCJECgYEA/eWt01iEyE/lXkGn6V9lCocUU7lCU6yk5UT8VXVUc5If4KZKPfCk -p4zJDOqwn2eM673aWz/mG9mtvAvmnugaGjcaVCyXOp/D/GDmKSoYcvW5B/yjfkLy -dK6Yaa5LDRVYlYgyzcdCT5/9Qc626NzFwKCZNI4ncIU8g7ViATRxWJ8CgYEA2Ver -vZ0M606sfgC0H3NtwNBxmuJ+lIF5LNp/wDi07lDfxRR1rnZMX5dnxjcpDr/zvm8J -WtJJX3xMgqjtHuWKL3yKKony9J5ZPjichSbSbhrzfovgYIRZLxLLDy4MP9L3+CX/ -yBXnqMWuSnFX+M5fVGxdDWiYF3V+wmeOv9JvavkCgYEAiXAPDFzaY+R78O3xiu7M -r0o3wqqCMPE/wav6O/hrYrQy9VSO08C0IM6g9pEEUwWmzuXSkZqhYWoQFb8Lc/GI -T7CMXAxXQLDDUpbRgG79FR3Wr3AewHZU8LyiXHKwxcBMV4WGmsXGK3wbh8fyU1NO -6NsGk+BvkQVOoK1LBAPzZ1kCgYEAsBSmD8U33T9s4dxiEYTrqyV0lH3g/SFz8ZHH -pAyNEPI2iC1ONhyjPWKlcWHpAokiyOqeUpVBWnmSZtzC1qAydsxYB6ShT+sl9BHb -RMix/QAauzBJhQhUVJ3OIys0Q1UBDmqCsjCE8SfOT4NKOUnA093C+YT+iyrmmktZ -zDCJkckCgYEAndqM5KXGk5xYo+MAA1paZcbTUXwaWwjLU+XSRSSoyBEi5xMtfvUb -7+a1OMhLwWbuz+pl64wFKrbSUyimMOYQpjVE/1vk/kb99pxbgol27hdKyTH1d+ov -kFsxKCqxAnBVGEWAvVZAiiTOxleQFjz5RnL0BQp9Lg2cQe+dvuUmIAA= ------END RSA PRIVATE KEY-----`) -) - -func testShutdownBindPort(t *testing.T, protocol string, port string) { - handler := NewServeMux() - handler.HandleFunc(".", func(w ResponseWriter, r *Msg) {}) - startedCh := make(chan struct{}) - s := &Server{ - Addr: net.JoinHostPort("127.0.0.1", port), - Net: protocol, - Handler: handler, - NotifyStartedFunc: func() { - startedCh <- struct{}{} - }, - } - go func() { - if err := s.ListenAndServe(); err != nil { - t.Log(err) - } - }() - <-startedCh - t.Logf("DNS server is started on: %s", s.Addr) - if err := s.Shutdown(); err != nil { - t.Fatal(err) - } - time.Sleep(100 * time.Millisecond) - go func() { - if err := s.ListenAndServe(); err != nil { - t.Fatal(err) - } - }() - <-startedCh - t.Logf("DNS server is started on: %s", s.Addr) -} - -func TestShutdownBindPortUDP(t *testing.T) { - testShutdownBindPort(t, "udp", "1153") -} - -func TestShutdownBindPortTCP(t *testing.T) { - testShutdownBindPort(t, "tcp", "1154") -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/sig0.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/sig0.go deleted file mode 100644 index f31e9e684..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/sig0.go +++ /dev/null @@ -1,218 +0,0 @@ -package dns - -import ( - "crypto" - "crypto/dsa" - "crypto/ecdsa" - "crypto/rsa" - "encoding/binary" - "math/big" - "strings" - "time" -) - -// Sign signs a dns.Msg. It fills the signature with the appropriate data. -// The SIG record should have the SignerName, KeyTag, Algorithm, Inception -// and Expiration set. -func (rr *SIG) Sign(k crypto.Signer, m *Msg) ([]byte, error) { - if k == nil { - return nil, ErrPrivKey - } - if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 { - return nil, ErrKey - } - rr.Header().Rrtype = TypeSIG - rr.Header().Class = ClassANY - rr.Header().Ttl = 0 - rr.Header().Name = "." - rr.OrigTtl = 0 - rr.TypeCovered = 0 - rr.Labels = 0 - - buf := make([]byte, m.Len()+rr.len()) - mbuf, err := m.PackBuffer(buf) - if err != nil { - return nil, err - } - if &buf[0] != &mbuf[0] { - return nil, ErrBuf - } - off, err := PackRR(rr, buf, len(mbuf), nil, false) - if err != nil { - return nil, err - } - buf = buf[:off:cap(buf)] - - hash, ok := AlgorithmToHash[rr.Algorithm] - if !ok { - return nil, ErrAlg - } - - hasher := hash.New() - // Write SIG rdata - hasher.Write(buf[len(mbuf)+1+2+2+4+2:]) - // Write message - hasher.Write(buf[:len(mbuf)]) - - signature, err := sign(k, hasher.Sum(nil), hash, rr.Algorithm) - if err != nil { - return nil, err - } - - rr.Signature = toBase64(signature) - - buf = append(buf, signature...) - if len(buf) > int(^uint16(0)) { - return nil, ErrBuf - } - // Adjust sig data length - rdoff := len(mbuf) + 1 + 2 + 2 + 4 - rdlen := binary.BigEndian.Uint16(buf[rdoff:]) - rdlen += uint16(len(signature)) - binary.BigEndian.PutUint16(buf[rdoff:], rdlen) - // Adjust additional count - adc := binary.BigEndian.Uint16(buf[10:]) - adc++ - binary.BigEndian.PutUint16(buf[10:], adc) - return buf, nil -} - -// Verify validates the message buf using the key k. -// It's assumed that buf is a valid message from which rr was unpacked. -func (rr *SIG) Verify(k *KEY, buf []byte) error { - if k == nil { - return ErrKey - } - if rr.KeyTag == 0 || len(rr.SignerName) == 0 || rr.Algorithm == 0 { - return ErrKey - } - - var hash crypto.Hash - switch rr.Algorithm { - case DSA, RSASHA1: - hash = crypto.SHA1 - case RSASHA256, ECDSAP256SHA256: - hash = crypto.SHA256 - case ECDSAP384SHA384: - hash = crypto.SHA384 - case RSASHA512: - hash = crypto.SHA512 - default: - return ErrAlg - } - hasher := hash.New() - - buflen := len(buf) - qdc := binary.BigEndian.Uint16(buf[4:]) - anc := binary.BigEndian.Uint16(buf[6:]) - auc := binary.BigEndian.Uint16(buf[8:]) - adc := binary.BigEndian.Uint16(buf[10:]) - offset := 12 - var err error - for i := uint16(0); i < qdc && offset < buflen; i++ { - _, offset, err = UnpackDomainName(buf, offset) - if err != nil { - return err - } - // Skip past Type and Class - offset += 2 + 2 - } - for i := uint16(1); i < anc+auc+adc && offset < buflen; i++ { - _, offset, err = UnpackDomainName(buf, offset) - if err != nil { - return err - } - // Skip past Type, Class and TTL - offset += 2 + 2 + 4 - if offset+1 >= buflen { - continue - } - var rdlen uint16 - rdlen = binary.BigEndian.Uint16(buf[offset:]) - offset += 2 - offset += int(rdlen) - } - if offset >= buflen { - return &Error{err: "overflowing unpacking signed message"} - } - - // offset should be just prior to SIG - bodyend := offset - // owner name SHOULD be root - _, offset, err = UnpackDomainName(buf, offset) - if err != nil { - return err - } - // Skip Type, Class, TTL, RDLen - offset += 2 + 2 + 4 + 2 - sigstart := offset - // Skip Type Covered, Algorithm, Labels, Original TTL - offset += 2 + 1 + 1 + 4 - if offset+4+4 >= buflen { - return &Error{err: "overflow unpacking signed message"} - } - expire := binary.BigEndian.Uint32(buf[offset:]) - offset += 4 - incept := binary.BigEndian.Uint32(buf[offset:]) - offset += 4 - now := uint32(time.Now().Unix()) - if now < incept || now > expire { - return ErrTime - } - // Skip key tag - offset += 2 - var signername string - signername, offset, err = UnpackDomainName(buf, offset) - if err != nil { - return err - } - // If key has come from the DNS name compression might - // have mangled the case of the name - if strings.ToLower(signername) != strings.ToLower(k.Header().Name) { - return &Error{err: "signer name doesn't match key name"} - } - sigend := offset - hasher.Write(buf[sigstart:sigend]) - hasher.Write(buf[:10]) - hasher.Write([]byte{ - byte((adc - 1) << 8), - byte(adc - 1), - }) - hasher.Write(buf[12:bodyend]) - - hashed := hasher.Sum(nil) - sig := buf[sigend:] - switch k.Algorithm { - case DSA: - pk := k.publicKeyDSA() - sig = sig[1:] - r := big.NewInt(0) - r.SetBytes(sig[:len(sig)/2]) - s := big.NewInt(0) - s.SetBytes(sig[len(sig)/2:]) - if pk != nil { - if dsa.Verify(pk, hashed, r, s) { - return nil - } - return ErrSig - } - case RSASHA1, RSASHA256, RSASHA512: - pk := k.publicKeyRSA() - if pk != nil { - return rsa.VerifyPKCS1v15(pk, hash, hashed, sig) - } - case ECDSAP256SHA256, ECDSAP384SHA384: - pk := k.publicKeyECDSA() - r := big.NewInt(0) - r.SetBytes(sig[:len(sig)/2]) - s := big.NewInt(0) - s.SetBytes(sig[len(sig)/2:]) - if pk != nil { - if ecdsa.Verify(pk, hashed, r, s) { - return nil - } - return ErrSig - } - } - return ErrKeyAlg -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/sig0_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/sig0_test.go deleted file mode 100644 index 122de6a8e..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/sig0_test.go +++ /dev/null @@ -1,89 +0,0 @@ -package dns - -import ( - "crypto" - "testing" - "time" -) - -func TestSIG0(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - m := new(Msg) - m.SetQuestion("example.org.", TypeSOA) - for _, alg := range []uint8{ECDSAP256SHA256, ECDSAP384SHA384, RSASHA1, RSASHA256, RSASHA512} { - algstr := AlgorithmToString[alg] - keyrr := new(KEY) - keyrr.Hdr.Name = algstr + "." - keyrr.Hdr.Rrtype = TypeKEY - keyrr.Hdr.Class = ClassINET - keyrr.Algorithm = alg - keysize := 1024 - switch alg { - case ECDSAP256SHA256: - keysize = 256 - case ECDSAP384SHA384: - keysize = 384 - } - pk, err := keyrr.Generate(keysize) - if err != nil { - t.Errorf("failed to generate key for “%s”: %v", algstr, err) - continue - } - now := uint32(time.Now().Unix()) - sigrr := new(SIG) - sigrr.Hdr.Name = "." - sigrr.Hdr.Rrtype = TypeSIG - sigrr.Hdr.Class = ClassANY - sigrr.Algorithm = alg - sigrr.Expiration = now + 300 - sigrr.Inception = now - 300 - sigrr.KeyTag = keyrr.KeyTag() - sigrr.SignerName = keyrr.Hdr.Name - mb, err := sigrr.Sign(pk.(crypto.Signer), m) - if err != nil { - t.Errorf("failed to sign message using “%s”: %v", algstr, err) - continue - } - m := new(Msg) - if err := m.Unpack(mb); err != nil { - t.Errorf("failed to unpack message signed using “%s”: %v", algstr, err) - continue - } - if len(m.Extra) != 1 { - t.Errorf("missing SIG for message signed using “%s”", algstr) - continue - } - var sigrrwire *SIG - switch rr := m.Extra[0].(type) { - case *SIG: - sigrrwire = rr - default: - t.Errorf("expected SIG RR, instead: %v", rr) - continue - } - for _, rr := range []*SIG{sigrr, sigrrwire} { - id := "sigrr" - if rr == sigrrwire { - id = "sigrrwire" - } - if err := rr.Verify(keyrr, mb); err != nil { - t.Errorf("failed to verify “%s” signed SIG(%s): %v", algstr, id, err) - continue - } - } - mb[13]++ - if err := sigrr.Verify(keyrr, mb); err == nil { - t.Errorf("verify succeeded on an altered message using “%s”", algstr) - continue - } - sigrr.Expiration = 2 - sigrr.Inception = 1 - mb, _ = sigrr.Sign(pk.(crypto.Signer), m) - if err := sigrr.Verify(keyrr, mb); err == nil { - t.Errorf("verify succeeded on an expired message using “%s”", algstr) - continue - } - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/singleinflight.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/singleinflight.go deleted file mode 100644 index 9573c7d0b..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/singleinflight.go +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Adapted for dns package usage by Miek Gieben. - -package dns - -import "sync" -import "time" - -// call is an in-flight or completed singleflight.Do call -type call struct { - wg sync.WaitGroup - val *Msg - rtt time.Duration - err error - dups int -} - -// singleflight represents a class of work and forms a namespace in -// which units of work can be executed with duplicate suppression. -type singleflight struct { - sync.Mutex // protects m - m map[string]*call // lazily initialized -} - -// Do executes and returns the results of the given function, making -// sure that only one execution is in-flight for a given key at a -// time. If a duplicate comes in, the duplicate caller waits for the -// original to complete and receives the same results. -// The return value shared indicates whether v was given to multiple callers. -func (g *singleflight) Do(key string, fn func() (*Msg, time.Duration, error)) (v *Msg, rtt time.Duration, err error, shared bool) { - g.Lock() - if g.m == nil { - g.m = make(map[string]*call) - } - if c, ok := g.m[key]; ok { - c.dups++ - g.Unlock() - c.wg.Wait() - return c.val, c.rtt, c.err, true - } - c := new(call) - c.wg.Add(1) - g.m[key] = c - g.Unlock() - - c.val, c.rtt, c.err = fn() - c.wg.Done() - - g.Lock() - delete(g.m, key) - g.Unlock() - - return c.val, c.rtt, c.err, c.dups > 0 -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/smimea.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/smimea.go deleted file mode 100644 index 4e7ded4b3..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/smimea.go +++ /dev/null @@ -1,47 +0,0 @@ -package dns - -import ( - "crypto/sha256" - "crypto/x509" - "encoding/hex" -) - -// Sign creates a SMIMEA record from an SSL certificate. -func (r *SMIMEA) Sign(usage, selector, matchingType int, cert *x509.Certificate) (err error) { - r.Hdr.Rrtype = TypeSMIMEA - r.Usage = uint8(usage) - r.Selector = uint8(selector) - r.MatchingType = uint8(matchingType) - - r.Certificate, err = CertificateToDANE(r.Selector, r.MatchingType, cert) - if err != nil { - return err - } - return nil -} - -// Verify verifies a SMIMEA record against an SSL certificate. If it is OK -// a nil error is returned. -func (r *SMIMEA) Verify(cert *x509.Certificate) error { - c, err := CertificateToDANE(r.Selector, r.MatchingType, cert) - if err != nil { - return err // Not also ErrSig? - } - if r.Certificate == c { - return nil - } - return ErrSig // ErrSig, really? -} - -// SMIMEAName returns the ownername of a SMIMEA resource record as per the -// format specified in RFC 'draft-ietf-dane-smime-12' Section 2 and 3 -func SMIMEAName(email, domain string) (string, error) { - hasher := sha256.New() - hasher.Write([]byte(email)) - - // RFC Section 3: "The local-part is hashed using the SHA2-256 - // algorithm with the hash truncated to 28 octets and - // represented in its hexadecimal representation to become the - // left-most label in the prepared domain name" - return hex.EncodeToString(hasher.Sum(nil)[:28]) + "." + "_smimecert." + domain, nil -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/tlsa.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/tlsa.go deleted file mode 100644 index 431e2fb5a..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/tlsa.go +++ /dev/null @@ -1,47 +0,0 @@ -package dns - -import ( - "crypto/x509" - "net" - "strconv" -) - -// Sign creates a TLSA record from an SSL certificate. -func (r *TLSA) Sign(usage, selector, matchingType int, cert *x509.Certificate) (err error) { - r.Hdr.Rrtype = TypeTLSA - r.Usage = uint8(usage) - r.Selector = uint8(selector) - r.MatchingType = uint8(matchingType) - - r.Certificate, err = CertificateToDANE(r.Selector, r.MatchingType, cert) - if err != nil { - return err - } - return nil -} - -// Verify verifies a TLSA record against an SSL certificate. If it is OK -// a nil error is returned. -func (r *TLSA) Verify(cert *x509.Certificate) error { - c, err := CertificateToDANE(r.Selector, r.MatchingType, cert) - if err != nil { - return err // Not also ErrSig? - } - if r.Certificate == c { - return nil - } - return ErrSig // ErrSig, really? -} - -// TLSAName returns the ownername of a TLSA resource record as per the -// rules specified in RFC 6698, Section 3. -func TLSAName(name, service, network string) (string, error) { - if !IsFqdn(name) { - return "", ErrFqdn - } - p, err := net.LookupPort(network, service) - if err != nil { - return "", err - } - return "_" + strconv.Itoa(p) + "._" + network + "." + name, nil -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/tsig.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/tsig.go deleted file mode 100644 index 24013096b..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/tsig.go +++ /dev/null @@ -1,383 +0,0 @@ -package dns - -import ( - "crypto/hmac" - "crypto/md5" - "crypto/sha1" - "crypto/sha256" - "crypto/sha512" - "encoding/binary" - "encoding/hex" - "hash" - "strconv" - "strings" - "time" -) - -// HMAC hashing codes. These are transmitted as domain names. -const ( - HmacMD5 = "hmac-md5.sig-alg.reg.int." - HmacSHA1 = "hmac-sha1." - HmacSHA256 = "hmac-sha256." - HmacSHA512 = "hmac-sha512." -) - -// TSIG is the RR the holds the transaction signature of a message. -// See RFC 2845 and RFC 4635. -type TSIG struct { - Hdr RR_Header - Algorithm string `dns:"domain-name"` - TimeSigned uint64 `dns:"uint48"` - Fudge uint16 - MACSize uint16 - MAC string `dns:"size-hex:MACSize"` - OrigId uint16 - Error uint16 - OtherLen uint16 - OtherData string `dns:"size-hex:OtherLen"` -} - -// TSIG has no official presentation format, but this will suffice. - -func (rr *TSIG) String() string { - s := "\n;; TSIG PSEUDOSECTION:\n" - s += rr.Hdr.String() + - " " + rr.Algorithm + - " " + tsigTimeToString(rr.TimeSigned) + - " " + strconv.Itoa(int(rr.Fudge)) + - " " + strconv.Itoa(int(rr.MACSize)) + - " " + strings.ToUpper(rr.MAC) + - " " + strconv.Itoa(int(rr.OrigId)) + - " " + strconv.Itoa(int(rr.Error)) + // BIND prints NOERROR - " " + strconv.Itoa(int(rr.OtherLen)) + - " " + rr.OtherData - return s -} - -// The following values must be put in wireformat, so that the MAC can be calculated. -// RFC 2845, section 3.4.2. TSIG Variables. -type tsigWireFmt struct { - // From RR_Header - Name string `dns:"domain-name"` - Class uint16 - Ttl uint32 - // Rdata of the TSIG - Algorithm string `dns:"domain-name"` - TimeSigned uint64 `dns:"uint48"` - Fudge uint16 - // MACSize, MAC and OrigId excluded - Error uint16 - OtherLen uint16 - OtherData string `dns:"size-hex:OtherLen"` -} - -// If we have the MAC use this type to convert it to wiredata. Section 3.4.3. Request MAC -type macWireFmt struct { - MACSize uint16 - MAC string `dns:"size-hex:MACSize"` -} - -// 3.3. Time values used in TSIG calculations -type timerWireFmt struct { - TimeSigned uint64 `dns:"uint48"` - Fudge uint16 -} - -// TsigGenerate fills out the TSIG record attached to the message. -// The message should contain -// a "stub" TSIG RR with the algorithm, key name (owner name of the RR), -// time fudge (defaults to 300 seconds) and the current time -// The TSIG MAC is saved in that Tsig RR. -// When TsigGenerate is called for the first time requestMAC is set to the empty string and -// timersOnly is false. -// If something goes wrong an error is returned, otherwise it is nil. -func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, string, error) { - if m.IsTsig() == nil { - panic("dns: TSIG not last RR in additional") - } - // If we barf here, the caller is to blame - rawsecret, err := fromBase64([]byte(secret)) - if err != nil { - return nil, "", err - } - - rr := m.Extra[len(m.Extra)-1].(*TSIG) - m.Extra = m.Extra[0 : len(m.Extra)-1] // kill the TSIG from the msg - mbuf, err := m.Pack() - if err != nil { - return nil, "", err - } - buf := tsigBuffer(mbuf, rr, requestMAC, timersOnly) - - t := new(TSIG) - var h hash.Hash - switch strings.ToLower(rr.Algorithm) { - case HmacMD5: - h = hmac.New(md5.New, []byte(rawsecret)) - case HmacSHA1: - h = hmac.New(sha1.New, []byte(rawsecret)) - case HmacSHA256: - h = hmac.New(sha256.New, []byte(rawsecret)) - case HmacSHA512: - h = hmac.New(sha512.New, []byte(rawsecret)) - default: - return nil, "", ErrKeyAlg - } - h.Write(buf) - t.MAC = hex.EncodeToString(h.Sum(nil)) - t.MACSize = uint16(len(t.MAC) / 2) // Size is half! - - t.Hdr = RR_Header{Name: rr.Hdr.Name, Rrtype: TypeTSIG, Class: ClassANY, Ttl: 0} - t.Fudge = rr.Fudge - t.TimeSigned = rr.TimeSigned - t.Algorithm = rr.Algorithm - t.OrigId = m.Id - - tbuf := make([]byte, t.len()) - if off, err := PackRR(t, tbuf, 0, nil, false); err == nil { - tbuf = tbuf[:off] // reset to actual size used - } else { - return nil, "", err - } - mbuf = append(mbuf, tbuf...) - // Update the ArCount directly in the buffer. - binary.BigEndian.PutUint16(mbuf[10:], uint16(len(m.Extra)+1)) - - return mbuf, t.MAC, nil -} - -// TsigVerify verifies the TSIG on a message. -// If the signature does not validate err contains the -// error, otherwise it is nil. -func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) error { - rawsecret, err := fromBase64([]byte(secret)) - if err != nil { - return err - } - // Strip the TSIG from the incoming msg - stripped, tsig, err := stripTsig(msg) - if err != nil { - return err - } - - msgMAC, err := hex.DecodeString(tsig.MAC) - if err != nil { - return err - } - - buf := tsigBuffer(stripped, tsig, requestMAC, timersOnly) - - // Fudge factor works both ways. A message can arrive before it was signed because - // of clock skew. - now := uint64(time.Now().Unix()) - ti := now - tsig.TimeSigned - if now < tsig.TimeSigned { - ti = tsig.TimeSigned - now - } - if uint64(tsig.Fudge) < ti { - return ErrTime - } - - var h hash.Hash - switch strings.ToLower(tsig.Algorithm) { - case HmacMD5: - h = hmac.New(md5.New, rawsecret) - case HmacSHA1: - h = hmac.New(sha1.New, rawsecret) - case HmacSHA256: - h = hmac.New(sha256.New, rawsecret) - case HmacSHA512: - h = hmac.New(sha512.New, rawsecret) - default: - return ErrKeyAlg - } - h.Write(buf) - if !hmac.Equal(h.Sum(nil), msgMAC) { - return ErrSig - } - return nil -} - -// Create a wiredata buffer for the MAC calculation. -func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []byte { - var buf []byte - if rr.TimeSigned == 0 { - rr.TimeSigned = uint64(time.Now().Unix()) - } - if rr.Fudge == 0 { - rr.Fudge = 300 // Standard (RFC) default. - } - - if requestMAC != "" { - m := new(macWireFmt) - m.MACSize = uint16(len(requestMAC) / 2) - m.MAC = requestMAC - buf = make([]byte, len(requestMAC)) // long enough - n, _ := packMacWire(m, buf) - buf = buf[:n] - } - - tsigvar := make([]byte, DefaultMsgSize) - if timersOnly { - tsig := new(timerWireFmt) - tsig.TimeSigned = rr.TimeSigned - tsig.Fudge = rr.Fudge - n, _ := packTimerWire(tsig, tsigvar) - tsigvar = tsigvar[:n] - } else { - tsig := new(tsigWireFmt) - tsig.Name = strings.ToLower(rr.Hdr.Name) - tsig.Class = ClassANY - tsig.Ttl = rr.Hdr.Ttl - tsig.Algorithm = strings.ToLower(rr.Algorithm) - tsig.TimeSigned = rr.TimeSigned - tsig.Fudge = rr.Fudge - tsig.Error = rr.Error - tsig.OtherLen = rr.OtherLen - tsig.OtherData = rr.OtherData - n, _ := packTsigWire(tsig, tsigvar) - tsigvar = tsigvar[:n] - } - - if requestMAC != "" { - x := append(buf, msgbuf...) - buf = append(x, tsigvar...) - } else { - buf = append(msgbuf, tsigvar...) - } - return buf -} - -// Strip the TSIG from the raw message. -func stripTsig(msg []byte) ([]byte, *TSIG, error) { - // Copied from msg.go's Unpack() Header, but modified. - var ( - dh Header - err error - ) - off, tsigoff := 0, 0 - - if dh, off, err = unpackMsgHdr(msg, off); err != nil { - return nil, nil, err - } - if dh.Arcount == 0 { - return nil, nil, ErrNoSig - } - - // Rcode, see msg.go Unpack() - if int(dh.Bits&0xF) == RcodeNotAuth { - return nil, nil, ErrAuth - } - - for i := 0; i < int(dh.Qdcount); i++ { - _, off, err = unpackQuestion(msg, off) - if err != nil { - return nil, nil, err - } - } - - _, off, err = unpackRRslice(int(dh.Ancount), msg, off) - if err != nil { - return nil, nil, err - } - _, off, err = unpackRRslice(int(dh.Nscount), msg, off) - if err != nil { - return nil, nil, err - } - - rr := new(TSIG) - var extra RR - for i := 0; i < int(dh.Arcount); i++ { - tsigoff = off - extra, off, err = UnpackRR(msg, off) - if err != nil { - return nil, nil, err - } - if extra.Header().Rrtype == TypeTSIG { - rr = extra.(*TSIG) - // Adjust Arcount. - arcount := binary.BigEndian.Uint16(msg[10:]) - binary.BigEndian.PutUint16(msg[10:], arcount-1) - break - } - } - if rr == nil { - return nil, nil, ErrNoSig - } - return msg[:tsigoff], rr, nil -} - -// Translate the TSIG time signed into a date. There is no -// need for RFC1982 calculations as this date is 48 bits. -func tsigTimeToString(t uint64) string { - ti := time.Unix(int64(t), 0).UTC() - return ti.Format("20060102150405") -} - -func packTsigWire(tw *tsigWireFmt, msg []byte) (int, error) { - // copied from zmsg.go TSIG packing - // RR_Header - off, err := PackDomainName(tw.Name, msg, 0, nil, false) - if err != nil { - return off, err - } - off, err = packUint16(tw.Class, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(tw.Ttl, msg, off) - if err != nil { - return off, err - } - - off, err = PackDomainName(tw.Algorithm, msg, off, nil, false) - if err != nil { - return off, err - } - off, err = packUint48(tw.TimeSigned, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(tw.Fudge, msg, off) - if err != nil { - return off, err - } - - off, err = packUint16(tw.Error, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(tw.OtherLen, msg, off) - if err != nil { - return off, err - } - off, err = packStringHex(tw.OtherData, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func packMacWire(mw *macWireFmt, msg []byte) (int, error) { - off, err := packUint16(mw.MACSize, msg, 0) - if err != nil { - return off, err - } - off, err = packStringHex(mw.MAC, msg, off) - if err != nil { - return off, err - } - return off, nil -} - -func packTimerWire(tw *timerWireFmt, msg []byte) (int, error) { - off, err := packUint48(tw.TimeSigned, msg, 0) - if err != nil { - return off, err - } - off, err = packUint16(tw.Fudge, msg, off) - if err != nil { - return off, err - } - return off, nil -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/tsig_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/tsig_test.go deleted file mode 100644 index 48b9988b6..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/tsig_test.go +++ /dev/null @@ -1,37 +0,0 @@ -package dns - -import ( - "testing" - "time" -) - -func newTsig(algo string) *Msg { - m := new(Msg) - m.SetQuestion("example.org.", TypeA) - m.SetTsig("example.", algo, 300, time.Now().Unix()) - return m -} - -func TestTsig(t *testing.T) { - m := newTsig(HmacMD5) - buf, _, err := TsigGenerate(m, "pRZgBrBvI4NAHZYhxmhs/Q==", "", false) - if err != nil { - t.Fatal(err) - } - err = TsigVerify(buf, "pRZgBrBvI4NAHZYhxmhs/Q==", "", false) - if err != nil { - t.Fatal(err) - } -} - -func TestTsigCase(t *testing.T) { - m := newTsig("HmAc-mD5.sig-ALg.rEg.int.") // HmacMD5 - buf, _, err := TsigGenerate(m, "pRZgBrBvI4NAHZYhxmhs/Q==", "", false) - if err != nil { - t.Fatal(err) - } - err = TsigVerify(buf, "pRZgBrBvI4NAHZYhxmhs/Q==", "", false) - if err != nil { - t.Fatal(err) - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/types.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/types.go deleted file mode 100644 index 53da4755c..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/types.go +++ /dev/null @@ -1,1287 +0,0 @@ -package dns - -import ( - "fmt" - "net" - "strconv" - "strings" - "time" -) - -type ( - // Type is a DNS type. - Type uint16 - // Class is a DNS class. - Class uint16 - // Name is a DNS domain name. - Name string -) - -// Packet formats - -// Wire constants and supported types. -const ( - // valid RR_Header.Rrtype and Question.qtype - - TypeNone uint16 = 0 - TypeA uint16 = 1 - TypeNS uint16 = 2 - TypeMD uint16 = 3 - TypeMF uint16 = 4 - TypeCNAME uint16 = 5 - TypeSOA uint16 = 6 - TypeMB uint16 = 7 - TypeMG uint16 = 8 - TypeMR uint16 = 9 - TypeNULL uint16 = 10 - TypePTR uint16 = 12 - TypeHINFO uint16 = 13 - TypeMINFO uint16 = 14 - TypeMX uint16 = 15 - TypeTXT uint16 = 16 - TypeRP uint16 = 17 - TypeAFSDB uint16 = 18 - TypeX25 uint16 = 19 - TypeISDN uint16 = 20 - TypeRT uint16 = 21 - TypeNSAPPTR uint16 = 23 - TypeSIG uint16 = 24 - TypeKEY uint16 = 25 - TypePX uint16 = 26 - TypeGPOS uint16 = 27 - TypeAAAA uint16 = 28 - TypeLOC uint16 = 29 - TypeNXT uint16 = 30 - TypeEID uint16 = 31 - TypeNIMLOC uint16 = 32 - TypeSRV uint16 = 33 - TypeATMA uint16 = 34 - TypeNAPTR uint16 = 35 - TypeKX uint16 = 36 - TypeCERT uint16 = 37 - TypeDNAME uint16 = 39 - TypeOPT uint16 = 41 // EDNS - TypeDS uint16 = 43 - TypeSSHFP uint16 = 44 - TypeRRSIG uint16 = 46 - TypeNSEC uint16 = 47 - TypeDNSKEY uint16 = 48 - TypeDHCID uint16 = 49 - TypeNSEC3 uint16 = 50 - TypeNSEC3PARAM uint16 = 51 - TypeTLSA uint16 = 52 - TypeSMIMEA uint16 = 53 - TypeHIP uint16 = 55 - TypeNINFO uint16 = 56 - TypeRKEY uint16 = 57 - TypeTALINK uint16 = 58 - TypeCDS uint16 = 59 - TypeCDNSKEY uint16 = 60 - TypeOPENPGPKEY uint16 = 61 - TypeSPF uint16 = 99 - TypeUINFO uint16 = 100 - TypeUID uint16 = 101 - TypeGID uint16 = 102 - TypeUNSPEC uint16 = 103 - TypeNID uint16 = 104 - TypeL32 uint16 = 105 - TypeL64 uint16 = 106 - TypeLP uint16 = 107 - TypeEUI48 uint16 = 108 - TypeEUI64 uint16 = 109 - TypeURI uint16 = 256 - TypeCAA uint16 = 257 - TypeAVC uint16 = 258 - - TypeTKEY uint16 = 249 - TypeTSIG uint16 = 250 - - // valid Question.Qtype only - TypeIXFR uint16 = 251 - TypeAXFR uint16 = 252 - TypeMAILB uint16 = 253 - TypeMAILA uint16 = 254 - TypeANY uint16 = 255 - - TypeTA uint16 = 32768 - TypeDLV uint16 = 32769 - TypeReserved uint16 = 65535 - - // valid Question.Qclass - ClassINET = 1 - ClassCSNET = 2 - ClassCHAOS = 3 - ClassHESIOD = 4 - ClassNONE = 254 - ClassANY = 255 - - // Message Response Codes. - RcodeSuccess = 0 - RcodeFormatError = 1 - RcodeServerFailure = 2 - RcodeNameError = 3 - RcodeNotImplemented = 4 - RcodeRefused = 5 - RcodeYXDomain = 6 - RcodeYXRrset = 7 - RcodeNXRrset = 8 - RcodeNotAuth = 9 - RcodeNotZone = 10 - RcodeBadSig = 16 // TSIG - RcodeBadVers = 16 // EDNS0 - RcodeBadKey = 17 - RcodeBadTime = 18 - RcodeBadMode = 19 // TKEY - RcodeBadName = 20 - RcodeBadAlg = 21 - RcodeBadTrunc = 22 // TSIG - RcodeBadCookie = 23 // DNS Cookies - - // Message Opcodes. There is no 3. - OpcodeQuery = 0 - OpcodeIQuery = 1 - OpcodeStatus = 2 - OpcodeNotify = 4 - OpcodeUpdate = 5 -) - -// Header is the wire format for the DNS packet header. -type Header struct { - Id uint16 - Bits uint16 - Qdcount, Ancount, Nscount, Arcount uint16 -} - -const ( - headerSize = 12 - - // Header.Bits - _QR = 1 << 15 // query/response (response=1) - _AA = 1 << 10 // authoritative - _TC = 1 << 9 // truncated - _RD = 1 << 8 // recursion desired - _RA = 1 << 7 // recursion available - _Z = 1 << 6 // Z - _AD = 1 << 5 // authticated data - _CD = 1 << 4 // checking disabled - - LOC_EQUATOR = 1 << 31 // RFC 1876, Section 2. - LOC_PRIMEMERIDIAN = 1 << 31 // RFC 1876, Section 2. - - LOC_HOURS = 60 * 1000 - LOC_DEGREES = 60 * LOC_HOURS - - LOC_ALTITUDEBASE = 100000 -) - -// Different Certificate Types, see RFC 4398, Section 2.1 -const ( - CertPKIX = 1 + iota - CertSPKI - CertPGP - CertIPIX - CertISPKI - CertIPGP - CertACPKIX - CertIACPKIX - CertURI = 253 - CertOID = 254 -) - -// CertTypeToString converts the Cert Type to its string representation. -// See RFC 4398 and RFC 6944. -var CertTypeToString = map[uint16]string{ - CertPKIX: "PKIX", - CertSPKI: "SPKI", - CertPGP: "PGP", - CertIPIX: "IPIX", - CertISPKI: "ISPKI", - CertIPGP: "IPGP", - CertACPKIX: "ACPKIX", - CertIACPKIX: "IACPKIX", - CertURI: "URI", - CertOID: "OID", -} - -// StringToCertType is the reverseof CertTypeToString. -var StringToCertType = reverseInt16(CertTypeToString) - -//go:generate go run types_generate.go - -// Question holds a DNS question. There can be multiple questions in the -// question section of a message. Usually there is just one. -type Question struct { - Name string `dns:"cdomain-name"` // "cdomain-name" specifies encoding (and may be compressed) - Qtype uint16 - Qclass uint16 -} - -func (q *Question) len() int { - return len(q.Name) + 1 + 2 + 2 -} - -func (q *Question) String() (s string) { - // prefix with ; (as in dig) - s = ";" + sprintName(q.Name) + "\t" - s += Class(q.Qclass).String() + "\t" - s += " " + Type(q.Qtype).String() - return s -} - -// ANY is a wildcard record. See RFC 1035, Section 3.2.3. ANY -// is named "*" there. -type ANY struct { - Hdr RR_Header - // Does not have any rdata -} - -func (rr *ANY) String() string { return rr.Hdr.String() } - -type CNAME struct { - Hdr RR_Header - Target string `dns:"cdomain-name"` -} - -func (rr *CNAME) String() string { return rr.Hdr.String() + sprintName(rr.Target) } - -type HINFO struct { - Hdr RR_Header - Cpu string - Os string -} - -func (rr *HINFO) String() string { - return rr.Hdr.String() + sprintTxt([]string{rr.Cpu, rr.Os}) -} - -type MB struct { - Hdr RR_Header - Mb string `dns:"cdomain-name"` -} - -func (rr *MB) String() string { return rr.Hdr.String() + sprintName(rr.Mb) } - -type MG struct { - Hdr RR_Header - Mg string `dns:"cdomain-name"` -} - -func (rr *MG) String() string { return rr.Hdr.String() + sprintName(rr.Mg) } - -type MINFO struct { - Hdr RR_Header - Rmail string `dns:"cdomain-name"` - Email string `dns:"cdomain-name"` -} - -func (rr *MINFO) String() string { - return rr.Hdr.String() + sprintName(rr.Rmail) + " " + sprintName(rr.Email) -} - -type MR struct { - Hdr RR_Header - Mr string `dns:"cdomain-name"` -} - -func (rr *MR) String() string { - return rr.Hdr.String() + sprintName(rr.Mr) -} - -type MF struct { - Hdr RR_Header - Mf string `dns:"cdomain-name"` -} - -func (rr *MF) String() string { - return rr.Hdr.String() + sprintName(rr.Mf) -} - -type MD struct { - Hdr RR_Header - Md string `dns:"cdomain-name"` -} - -func (rr *MD) String() string { - return rr.Hdr.String() + sprintName(rr.Md) -} - -type MX struct { - Hdr RR_Header - Preference uint16 - Mx string `dns:"cdomain-name"` -} - -func (rr *MX) String() string { - return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Mx) -} - -type AFSDB struct { - Hdr RR_Header - Subtype uint16 - Hostname string `dns:"cdomain-name"` -} - -func (rr *AFSDB) String() string { - return rr.Hdr.String() + strconv.Itoa(int(rr.Subtype)) + " " + sprintName(rr.Hostname) -} - -type X25 struct { - Hdr RR_Header - PSDNAddress string -} - -func (rr *X25) String() string { - return rr.Hdr.String() + rr.PSDNAddress -} - -type RT struct { - Hdr RR_Header - Preference uint16 - Host string `dns:"cdomain-name"` -} - -func (rr *RT) String() string { - return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Host) -} - -type NS struct { - Hdr RR_Header - Ns string `dns:"cdomain-name"` -} - -func (rr *NS) String() string { - return rr.Hdr.String() + sprintName(rr.Ns) -} - -type PTR struct { - Hdr RR_Header - Ptr string `dns:"cdomain-name"` -} - -func (rr *PTR) String() string { - return rr.Hdr.String() + sprintName(rr.Ptr) -} - -type RP struct { - Hdr RR_Header - Mbox string `dns:"domain-name"` - Txt string `dns:"domain-name"` -} - -func (rr *RP) String() string { - return rr.Hdr.String() + rr.Mbox + " " + sprintTxt([]string{rr.Txt}) -} - -type SOA struct { - Hdr RR_Header - Ns string `dns:"cdomain-name"` - Mbox string `dns:"cdomain-name"` - Serial uint32 - Refresh uint32 - Retry uint32 - Expire uint32 - Minttl uint32 -} - -func (rr *SOA) String() string { - return rr.Hdr.String() + sprintName(rr.Ns) + " " + sprintName(rr.Mbox) + - " " + strconv.FormatInt(int64(rr.Serial), 10) + - " " + strconv.FormatInt(int64(rr.Refresh), 10) + - " " + strconv.FormatInt(int64(rr.Retry), 10) + - " " + strconv.FormatInt(int64(rr.Expire), 10) + - " " + strconv.FormatInt(int64(rr.Minttl), 10) -} - -type TXT struct { - Hdr RR_Header - Txt []string `dns:"txt"` -} - -func (rr *TXT) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) } - -func sprintName(s string) string { - src := []byte(s) - dst := make([]byte, 0, len(src)) - for i := 0; i < len(src); { - if i+1 < len(src) && src[i] == '\\' && src[i+1] == '.' { - dst = append(dst, src[i:i+2]...) - i += 2 - } else { - b, n := nextByte(src, i) - if n == 0 { - i++ // dangling back slash - } else if b == '.' { - dst = append(dst, b) - } else { - dst = appendDomainNameByte(dst, b) - } - i += n - } - } - return string(dst) -} - -func sprintTxtOctet(s string) string { - src := []byte(s) - dst := make([]byte, 0, len(src)) - dst = append(dst, '"') - for i := 0; i < len(src); { - if i+1 < len(src) && src[i] == '\\' && src[i+1] == '.' { - dst = append(dst, src[i:i+2]...) - i += 2 - } else { - b, n := nextByte(src, i) - if n == 0 { - i++ // dangling back slash - } else if b == '.' { - dst = append(dst, b) - } else { - if b < ' ' || b > '~' { - dst = appendByte(dst, b) - } else { - dst = append(dst, b) - } - } - i += n - } - } - dst = append(dst, '"') - return string(dst) -} - -func sprintTxt(txt []string) string { - var out []byte - for i, s := range txt { - if i > 0 { - out = append(out, ` "`...) - } else { - out = append(out, '"') - } - bs := []byte(s) - for j := 0; j < len(bs); { - b, n := nextByte(bs, j) - if n == 0 { - break - } - out = appendTXTStringByte(out, b) - j += n - } - out = append(out, '"') - } - return string(out) -} - -func appendDomainNameByte(s []byte, b byte) []byte { - switch b { - case '.', ' ', '\'', '@', ';', '(', ')': // additional chars to escape - return append(s, '\\', b) - } - return appendTXTStringByte(s, b) -} - -func appendTXTStringByte(s []byte, b byte) []byte { - switch b { - case '"', '\\': - return append(s, '\\', b) - } - if b < ' ' || b > '~' { - return appendByte(s, b) - } - return append(s, b) -} - -func appendByte(s []byte, b byte) []byte { - var buf [3]byte - bufs := strconv.AppendInt(buf[:0], int64(b), 10) - s = append(s, '\\') - for i := 0; i < 3-len(bufs); i++ { - s = append(s, '0') - } - for _, r := range bufs { - s = append(s, r) - } - return s -} - -func nextByte(b []byte, offset int) (byte, int) { - if offset >= len(b) { - return 0, 0 - } - if b[offset] != '\\' { - // not an escape sequence - return b[offset], 1 - } - switch len(b) - offset { - case 1: // dangling escape - return 0, 0 - case 2, 3: // too short to be \ddd - default: // maybe \ddd - if isDigit(b[offset+1]) && isDigit(b[offset+2]) && isDigit(b[offset+3]) { - return dddToByte(b[offset+1:]), 4 - } - } - // not \ddd, just an RFC 1035 "quoted" character - return b[offset+1], 2 -} - -type SPF struct { - Hdr RR_Header - Txt []string `dns:"txt"` -} - -func (rr *SPF) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) } - -type AVC struct { - Hdr RR_Header - Txt []string `dns:"txt"` -} - -func (rr *AVC) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) } - -type SRV struct { - Hdr RR_Header - Priority uint16 - Weight uint16 - Port uint16 - Target string `dns:"domain-name"` -} - -func (rr *SRV) String() string { - return rr.Hdr.String() + - strconv.Itoa(int(rr.Priority)) + " " + - strconv.Itoa(int(rr.Weight)) + " " + - strconv.Itoa(int(rr.Port)) + " " + sprintName(rr.Target) -} - -type NAPTR struct { - Hdr RR_Header - Order uint16 - Preference uint16 - Flags string - Service string - Regexp string - Replacement string `dns:"domain-name"` -} - -func (rr *NAPTR) String() string { - return rr.Hdr.String() + - strconv.Itoa(int(rr.Order)) + " " + - strconv.Itoa(int(rr.Preference)) + " " + - "\"" + rr.Flags + "\" " + - "\"" + rr.Service + "\" " + - "\"" + rr.Regexp + "\" " + - rr.Replacement -} - -// The CERT resource record, see RFC 4398. -type CERT struct { - Hdr RR_Header - Type uint16 - KeyTag uint16 - Algorithm uint8 - Certificate string `dns:"base64"` -} - -func (rr *CERT) String() string { - var ( - ok bool - certtype, algorithm string - ) - if certtype, ok = CertTypeToString[rr.Type]; !ok { - certtype = strconv.Itoa(int(rr.Type)) - } - if algorithm, ok = AlgorithmToString[rr.Algorithm]; !ok { - algorithm = strconv.Itoa(int(rr.Algorithm)) - } - return rr.Hdr.String() + certtype + - " " + strconv.Itoa(int(rr.KeyTag)) + - " " + algorithm + - " " + rr.Certificate -} - -// The DNAME resource record, see RFC 2672. -type DNAME struct { - Hdr RR_Header - Target string `dns:"domain-name"` -} - -func (rr *DNAME) String() string { - return rr.Hdr.String() + sprintName(rr.Target) -} - -type A struct { - Hdr RR_Header - A net.IP `dns:"a"` -} - -func (rr *A) String() string { - if rr.A == nil { - return rr.Hdr.String() - } - return rr.Hdr.String() + rr.A.String() -} - -type AAAA struct { - Hdr RR_Header - AAAA net.IP `dns:"aaaa"` -} - -func (rr *AAAA) String() string { - if rr.AAAA == nil { - return rr.Hdr.String() - } - return rr.Hdr.String() + rr.AAAA.String() -} - -type PX struct { - Hdr RR_Header - Preference uint16 - Map822 string `dns:"domain-name"` - Mapx400 string `dns:"domain-name"` -} - -func (rr *PX) String() string { - return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Map822) + " " + sprintName(rr.Mapx400) -} - -type GPOS struct { - Hdr RR_Header - Longitude string - Latitude string - Altitude string -} - -func (rr *GPOS) String() string { - return rr.Hdr.String() + rr.Longitude + " " + rr.Latitude + " " + rr.Altitude -} - -type LOC struct { - Hdr RR_Header - Version uint8 - Size uint8 - HorizPre uint8 - VertPre uint8 - Latitude uint32 - Longitude uint32 - Altitude uint32 -} - -// cmToM takes a cm value expressed in RFC1876 SIZE mantissa/exponent -// format and returns a string in m (two decimals for the cm) -func cmToM(m, e uint8) string { - if e < 2 { - if e == 1 { - m *= 10 - } - - return fmt.Sprintf("0.%02d", m) - } - - s := fmt.Sprintf("%d", m) - for e > 2 { - s += "0" - e-- - } - return s -} - -func (rr *LOC) String() string { - s := rr.Hdr.String() - - lat := rr.Latitude - ns := "N" - if lat > LOC_EQUATOR { - lat = lat - LOC_EQUATOR - } else { - ns = "S" - lat = LOC_EQUATOR - lat - } - h := lat / LOC_DEGREES - lat = lat % LOC_DEGREES - m := lat / LOC_HOURS - lat = lat % LOC_HOURS - s += fmt.Sprintf("%02d %02d %0.3f %s ", h, m, (float64(lat) / 1000), ns) - - lon := rr.Longitude - ew := "E" - if lon > LOC_PRIMEMERIDIAN { - lon = lon - LOC_PRIMEMERIDIAN - } else { - ew = "W" - lon = LOC_PRIMEMERIDIAN - lon - } - h = lon / LOC_DEGREES - lon = lon % LOC_DEGREES - m = lon / LOC_HOURS - lon = lon % LOC_HOURS - s += fmt.Sprintf("%02d %02d %0.3f %s ", h, m, (float64(lon) / 1000), ew) - - var alt = float64(rr.Altitude) / 100 - alt -= LOC_ALTITUDEBASE - if rr.Altitude%100 != 0 { - s += fmt.Sprintf("%.2fm ", alt) - } else { - s += fmt.Sprintf("%.0fm ", alt) - } - - s += cmToM((rr.Size&0xf0)>>4, rr.Size&0x0f) + "m " - s += cmToM((rr.HorizPre&0xf0)>>4, rr.HorizPre&0x0f) + "m " - s += cmToM((rr.VertPre&0xf0)>>4, rr.VertPre&0x0f) + "m" - - return s -} - -// SIG is identical to RRSIG and nowadays only used for SIG(0), RFC2931. -type SIG struct { - RRSIG -} - -type RRSIG struct { - Hdr RR_Header - TypeCovered uint16 - Algorithm uint8 - Labels uint8 - OrigTtl uint32 - Expiration uint32 - Inception uint32 - KeyTag uint16 - SignerName string `dns:"domain-name"` - Signature string `dns:"base64"` -} - -func (rr *RRSIG) String() string { - s := rr.Hdr.String() - s += Type(rr.TypeCovered).String() - s += " " + strconv.Itoa(int(rr.Algorithm)) + - " " + strconv.Itoa(int(rr.Labels)) + - " " + strconv.FormatInt(int64(rr.OrigTtl), 10) + - " " + TimeToString(rr.Expiration) + - " " + TimeToString(rr.Inception) + - " " + strconv.Itoa(int(rr.KeyTag)) + - " " + sprintName(rr.SignerName) + - " " + rr.Signature - return s -} - -type NSEC struct { - Hdr RR_Header - NextDomain string `dns:"domain-name"` - TypeBitMap []uint16 `dns:"nsec"` -} - -func (rr *NSEC) String() string { - s := rr.Hdr.String() + sprintName(rr.NextDomain) - for i := 0; i < len(rr.TypeBitMap); i++ { - s += " " + Type(rr.TypeBitMap[i]).String() - } - return s -} - -func (rr *NSEC) len() int { - l := rr.Hdr.len() + len(rr.NextDomain) + 1 - lastwindow := uint32(2 ^ 32 + 1) - for _, t := range rr.TypeBitMap { - window := t / 256 - if uint32(window) != lastwindow { - l += 1 + 32 - } - lastwindow = uint32(window) - } - return l -} - -type DLV struct { - DS -} - -type CDS struct { - DS -} - -type DS struct { - Hdr RR_Header - KeyTag uint16 - Algorithm uint8 - DigestType uint8 - Digest string `dns:"hex"` -} - -func (rr *DS) String() string { - return rr.Hdr.String() + strconv.Itoa(int(rr.KeyTag)) + - " " + strconv.Itoa(int(rr.Algorithm)) + - " " + strconv.Itoa(int(rr.DigestType)) + - " " + strings.ToUpper(rr.Digest) -} - -type KX struct { - Hdr RR_Header - Preference uint16 - Exchanger string `dns:"domain-name"` -} - -func (rr *KX) String() string { - return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + - " " + sprintName(rr.Exchanger) -} - -type TA struct { - Hdr RR_Header - KeyTag uint16 - Algorithm uint8 - DigestType uint8 - Digest string `dns:"hex"` -} - -func (rr *TA) String() string { - return rr.Hdr.String() + strconv.Itoa(int(rr.KeyTag)) + - " " + strconv.Itoa(int(rr.Algorithm)) + - " " + strconv.Itoa(int(rr.DigestType)) + - " " + strings.ToUpper(rr.Digest) -} - -type TALINK struct { - Hdr RR_Header - PreviousName string `dns:"domain-name"` - NextName string `dns:"domain-name"` -} - -func (rr *TALINK) String() string { - return rr.Hdr.String() + - sprintName(rr.PreviousName) + " " + sprintName(rr.NextName) -} - -type SSHFP struct { - Hdr RR_Header - Algorithm uint8 - Type uint8 - FingerPrint string `dns:"hex"` -} - -func (rr *SSHFP) String() string { - return rr.Hdr.String() + strconv.Itoa(int(rr.Algorithm)) + - " " + strconv.Itoa(int(rr.Type)) + - " " + strings.ToUpper(rr.FingerPrint) -} - -type KEY struct { - DNSKEY -} - -type CDNSKEY struct { - DNSKEY -} - -type DNSKEY struct { - Hdr RR_Header - Flags uint16 - Protocol uint8 - Algorithm uint8 - PublicKey string `dns:"base64"` -} - -func (rr *DNSKEY) String() string { - return rr.Hdr.String() + strconv.Itoa(int(rr.Flags)) + - " " + strconv.Itoa(int(rr.Protocol)) + - " " + strconv.Itoa(int(rr.Algorithm)) + - " " + rr.PublicKey -} - -type RKEY struct { - Hdr RR_Header - Flags uint16 - Protocol uint8 - Algorithm uint8 - PublicKey string `dns:"base64"` -} - -func (rr *RKEY) String() string { - return rr.Hdr.String() + strconv.Itoa(int(rr.Flags)) + - " " + strconv.Itoa(int(rr.Protocol)) + - " " + strconv.Itoa(int(rr.Algorithm)) + - " " + rr.PublicKey -} - -type NSAPPTR struct { - Hdr RR_Header - Ptr string `dns:"domain-name"` -} - -func (rr *NSAPPTR) String() string { return rr.Hdr.String() + sprintName(rr.Ptr) } - -type NSEC3 struct { - Hdr RR_Header - Hash uint8 - Flags uint8 - Iterations uint16 - SaltLength uint8 - Salt string `dns:"size-hex:SaltLength"` - HashLength uint8 - NextDomain string `dns:"size-base32:HashLength"` - TypeBitMap []uint16 `dns:"nsec"` -} - -func (rr *NSEC3) String() string { - s := rr.Hdr.String() - s += strconv.Itoa(int(rr.Hash)) + - " " + strconv.Itoa(int(rr.Flags)) + - " " + strconv.Itoa(int(rr.Iterations)) + - " " + saltToString(rr.Salt) + - " " + rr.NextDomain - for i := 0; i < len(rr.TypeBitMap); i++ { - s += " " + Type(rr.TypeBitMap[i]).String() - } - return s -} - -func (rr *NSEC3) len() int { - l := rr.Hdr.len() + 6 + len(rr.Salt)/2 + 1 + len(rr.NextDomain) + 1 - lastwindow := uint32(2 ^ 32 + 1) - for _, t := range rr.TypeBitMap { - window := t / 256 - if uint32(window) != lastwindow { - l += 1 + 32 - } - lastwindow = uint32(window) - } - return l -} - -type NSEC3PARAM struct { - Hdr RR_Header - Hash uint8 - Flags uint8 - Iterations uint16 - SaltLength uint8 - Salt string `dns:"size-hex:SaltLength"` -} - -func (rr *NSEC3PARAM) String() string { - s := rr.Hdr.String() - s += strconv.Itoa(int(rr.Hash)) + - " " + strconv.Itoa(int(rr.Flags)) + - " " + strconv.Itoa(int(rr.Iterations)) + - " " + saltToString(rr.Salt) - return s -} - -type TKEY struct { - Hdr RR_Header - Algorithm string `dns:"domain-name"` - Inception uint32 - Expiration uint32 - Mode uint16 - Error uint16 - KeySize uint16 - Key string - OtherLen uint16 - OtherData string -} - -func (rr *TKEY) String() string { - // It has no presentation format - return "" -} - -// RFC3597 represents an unknown/generic RR. -type RFC3597 struct { - Hdr RR_Header - Rdata string `dns:"hex"` -} - -func (rr *RFC3597) String() string { - // Let's call it a hack - s := rfc3597Header(rr.Hdr) - - s += "\\# " + strconv.Itoa(len(rr.Rdata)/2) + " " + rr.Rdata - return s -} - -func rfc3597Header(h RR_Header) string { - var s string - - s += sprintName(h.Name) + "\t" - s += strconv.FormatInt(int64(h.Ttl), 10) + "\t" - s += "CLASS" + strconv.Itoa(int(h.Class)) + "\t" - s += "TYPE" + strconv.Itoa(int(h.Rrtype)) + "\t" - return s -} - -type URI struct { - Hdr RR_Header - Priority uint16 - Weight uint16 - Target string `dns:"octet"` -} - -func (rr *URI) String() string { - return rr.Hdr.String() + strconv.Itoa(int(rr.Priority)) + - " " + strconv.Itoa(int(rr.Weight)) + " " + sprintTxtOctet(rr.Target) -} - -type DHCID struct { - Hdr RR_Header - Digest string `dns:"base64"` -} - -func (rr *DHCID) String() string { return rr.Hdr.String() + rr.Digest } - -type TLSA struct { - Hdr RR_Header - Usage uint8 - Selector uint8 - MatchingType uint8 - Certificate string `dns:"hex"` -} - -func (rr *TLSA) String() string { - return rr.Hdr.String() + - strconv.Itoa(int(rr.Usage)) + - " " + strconv.Itoa(int(rr.Selector)) + - " " + strconv.Itoa(int(rr.MatchingType)) + - " " + rr.Certificate -} - -type SMIMEA struct { - Hdr RR_Header - Usage uint8 - Selector uint8 - MatchingType uint8 - Certificate string `dns:"hex"` -} - -func (rr *SMIMEA) String() string { - s := rr.Hdr.String() + - strconv.Itoa(int(rr.Usage)) + - " " + strconv.Itoa(int(rr.Selector)) + - " " + strconv.Itoa(int(rr.MatchingType)) - - // Every Nth char needs a space on this output. If we output - // this as one giant line, we can't read it can in because in some cases - // the cert length overflows scan.maxTok (2048). - sx := splitN(rr.Certificate, 1024) // conservative value here - s += " " + strings.Join(sx, " ") - return s -} - -type HIP struct { - Hdr RR_Header - HitLength uint8 - PublicKeyAlgorithm uint8 - PublicKeyLength uint16 - Hit string `dns:"size-hex:HitLength"` - PublicKey string `dns:"size-base64:PublicKeyLength"` - RendezvousServers []string `dns:"domain-name"` -} - -func (rr *HIP) String() string { - s := rr.Hdr.String() + - strconv.Itoa(int(rr.PublicKeyAlgorithm)) + - " " + rr.Hit + - " " + rr.PublicKey - for _, d := range rr.RendezvousServers { - s += " " + sprintName(d) - } - return s -} - -type NINFO struct { - Hdr RR_Header - ZSData []string `dns:"txt"` -} - -func (rr *NINFO) String() string { return rr.Hdr.String() + sprintTxt(rr.ZSData) } - -type NID struct { - Hdr RR_Header - Preference uint16 - NodeID uint64 -} - -func (rr *NID) String() string { - s := rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) - node := fmt.Sprintf("%0.16x", rr.NodeID) - s += " " + node[0:4] + ":" + node[4:8] + ":" + node[8:12] + ":" + node[12:16] - return s -} - -type L32 struct { - Hdr RR_Header - Preference uint16 - Locator32 net.IP `dns:"a"` -} - -func (rr *L32) String() string { - if rr.Locator32 == nil { - return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) - } - return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + - " " + rr.Locator32.String() -} - -type L64 struct { - Hdr RR_Header - Preference uint16 - Locator64 uint64 -} - -func (rr *L64) String() string { - s := rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) - node := fmt.Sprintf("%0.16X", rr.Locator64) - s += " " + node[0:4] + ":" + node[4:8] + ":" + node[8:12] + ":" + node[12:16] - return s -} - -type LP struct { - Hdr RR_Header - Preference uint16 - Fqdn string `dns:"domain-name"` -} - -func (rr *LP) String() string { - return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + sprintName(rr.Fqdn) -} - -type EUI48 struct { - Hdr RR_Header - Address uint64 `dns:"uint48"` -} - -func (rr *EUI48) String() string { return rr.Hdr.String() + euiToString(rr.Address, 48) } - -type EUI64 struct { - Hdr RR_Header - Address uint64 -} - -func (rr *EUI64) String() string { return rr.Hdr.String() + euiToString(rr.Address, 64) } - -type CAA struct { - Hdr RR_Header - Flag uint8 - Tag string - Value string `dns:"octet"` -} - -func (rr *CAA) String() string { - return rr.Hdr.String() + strconv.Itoa(int(rr.Flag)) + " " + rr.Tag + " " + sprintTxtOctet(rr.Value) -} - -type UID struct { - Hdr RR_Header - Uid uint32 -} - -func (rr *UID) String() string { return rr.Hdr.String() + strconv.FormatInt(int64(rr.Uid), 10) } - -type GID struct { - Hdr RR_Header - Gid uint32 -} - -func (rr *GID) String() string { return rr.Hdr.String() + strconv.FormatInt(int64(rr.Gid), 10) } - -type UINFO struct { - Hdr RR_Header - Uinfo string -} - -func (rr *UINFO) String() string { return rr.Hdr.String() + sprintTxt([]string{rr.Uinfo}) } - -type EID struct { - Hdr RR_Header - Endpoint string `dns:"hex"` -} - -func (rr *EID) String() string { return rr.Hdr.String() + strings.ToUpper(rr.Endpoint) } - -type NIMLOC struct { - Hdr RR_Header - Locator string `dns:"hex"` -} - -func (rr *NIMLOC) String() string { return rr.Hdr.String() + strings.ToUpper(rr.Locator) } - -type OPENPGPKEY struct { - Hdr RR_Header - PublicKey string `dns:"base64"` -} - -func (rr *OPENPGPKEY) String() string { return rr.Hdr.String() + rr.PublicKey } - -// TimeToString translates the RRSIG's incep. and expir. times to the -// string representation used when printing the record. -// It takes serial arithmetic (RFC 1982) into account. -func TimeToString(t uint32) string { - mod := ((int64(t) - time.Now().Unix()) / year68) - 1 - if mod < 0 { - mod = 0 - } - ti := time.Unix(int64(t)-(mod*year68), 0).UTC() - return ti.Format("20060102150405") -} - -// StringToTime translates the RRSIG's incep. and expir. times from -// string values like "20110403154150" to an 32 bit integer. -// It takes serial arithmetic (RFC 1982) into account. -func StringToTime(s string) (uint32, error) { - t, err := time.Parse("20060102150405", s) - if err != nil { - return 0, err - } - mod := (t.Unix() / year68) - 1 - if mod < 0 { - mod = 0 - } - return uint32(t.Unix() - (mod * year68)), nil -} - -// saltToString converts a NSECX salt to uppercase and returns "-" when it is empty. -func saltToString(s string) string { - if len(s) == 0 { - return "-" - } - return strings.ToUpper(s) -} - -func euiToString(eui uint64, bits int) (hex string) { - switch bits { - case 64: - hex = fmt.Sprintf("%16.16x", eui) - hex = hex[0:2] + "-" + hex[2:4] + "-" + hex[4:6] + "-" + hex[6:8] + - "-" + hex[8:10] + "-" + hex[10:12] + "-" + hex[12:14] + "-" + hex[14:16] - case 48: - hex = fmt.Sprintf("%12.12x", eui) - hex = hex[0:2] + "-" + hex[2:4] + "-" + hex[4:6] + "-" + hex[6:8] + - "-" + hex[8:10] + "-" + hex[10:12] - } - return -} - -// copyIP returns a copy of ip. -func copyIP(ip net.IP) net.IP { - p := make(net.IP, len(ip)) - copy(p, ip) - return p -} - -// SplitN splits a string into N sized string chunks. -// This might become an exported function once. -func splitN(s string, n int) []string { - if len(s) < n { - return []string{s} - } - sx := []string{} - p, i := 0, n - for { - if i <= len(s) { - sx = append(sx, s[p:i]) - } else { - sx = append(sx, s[p:]) - break - - } - p, i = p+n, i+n - } - - return sx -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/types_generate.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/types_generate.go deleted file mode 100644 index dd1310942..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/types_generate.go +++ /dev/null @@ -1,271 +0,0 @@ -//+build ignore - -// types_generate.go is meant to run with go generate. It will use -// go/{importer,types} to track down all the RR struct types. Then for each type -// it will generate conversion tables (TypeToRR and TypeToString) and banal -// methods (len, Header, copy) based on the struct tags. The generated source is -// written to ztypes.go, and is meant to be checked into git. -package main - -import ( - "bytes" - "fmt" - "go/format" - "go/importer" - "go/types" - "log" - "os" - "strings" - "text/template" -) - -var skipLen = map[string]struct{}{ - "NSEC": {}, - "NSEC3": {}, - "OPT": {}, -} - -var packageHdr = ` -// *** DO NOT MODIFY *** -// AUTOGENERATED BY go generate from type_generate.go - -package dns - -import ( - "encoding/base64" - "net" -) - -` - -var TypeToRR = template.Must(template.New("TypeToRR").Parse(` -// TypeToRR is a map of constructors for each RR type. -var TypeToRR = map[uint16]func() RR{ -{{range .}}{{if ne . "RFC3597"}} Type{{.}}: func() RR { return new({{.}}) }, -{{end}}{{end}} } - -`)) - -var typeToString = template.Must(template.New("typeToString").Parse(` -// TypeToString is a map of strings for each RR type. -var TypeToString = map[uint16]string{ -{{range .}}{{if ne . "NSAPPTR"}} Type{{.}}: "{{.}}", -{{end}}{{end}} TypeNSAPPTR: "NSAP-PTR", -} - -`)) - -var headerFunc = template.Must(template.New("headerFunc").Parse(` -// Header() functions -{{range .}} func (rr *{{.}}) Header() *RR_Header { return &rr.Hdr } -{{end}} - -`)) - -// getTypeStruct will take a type and the package scope, and return the -// (innermost) struct if the type is considered a RR type (currently defined as -// those structs beginning with a RR_Header, could be redefined as implementing -// the RR interface). The bool return value indicates if embedded structs were -// resolved. -func getTypeStruct(t types.Type, scope *types.Scope) (*types.Struct, bool) { - st, ok := t.Underlying().(*types.Struct) - if !ok { - return nil, false - } - if st.Field(0).Type() == scope.Lookup("RR_Header").Type() { - return st, false - } - if st.Field(0).Anonymous() { - st, _ := getTypeStruct(st.Field(0).Type(), scope) - return st, true - } - return nil, false -} - -func main() { - // Import and type-check the package - pkg, err := importer.Default().Import("github.com/miekg/dns") - fatalIfErr(err) - scope := pkg.Scope() - - // Collect constants like TypeX - var numberedTypes []string - for _, name := range scope.Names() { - o := scope.Lookup(name) - if o == nil || !o.Exported() { - continue - } - b, ok := o.Type().(*types.Basic) - if !ok || b.Kind() != types.Uint16 { - continue - } - if !strings.HasPrefix(o.Name(), "Type") { - continue - } - name := strings.TrimPrefix(o.Name(), "Type") - if name == "PrivateRR" { - continue - } - numberedTypes = append(numberedTypes, name) - } - - // Collect actual types (*X) - var namedTypes []string - for _, name := range scope.Names() { - o := scope.Lookup(name) - if o == nil || !o.Exported() { - continue - } - if st, _ := getTypeStruct(o.Type(), scope); st == nil { - continue - } - if name == "PrivateRR" { - continue - } - - // Check if corresponding TypeX exists - if scope.Lookup("Type"+o.Name()) == nil && o.Name() != "RFC3597" { - log.Fatalf("Constant Type%s does not exist.", o.Name()) - } - - namedTypes = append(namedTypes, o.Name()) - } - - b := &bytes.Buffer{} - b.WriteString(packageHdr) - - // Generate TypeToRR - fatalIfErr(TypeToRR.Execute(b, namedTypes)) - - // Generate typeToString - fatalIfErr(typeToString.Execute(b, numberedTypes)) - - // Generate headerFunc - fatalIfErr(headerFunc.Execute(b, namedTypes)) - - // Generate len() - fmt.Fprint(b, "// len() functions\n") - for _, name := range namedTypes { - if _, ok := skipLen[name]; ok { - continue - } - o := scope.Lookup(name) - st, isEmbedded := getTypeStruct(o.Type(), scope) - if isEmbedded { - continue - } - fmt.Fprintf(b, "func (rr *%s) len() int {\n", name) - fmt.Fprintf(b, "l := rr.Hdr.len()\n") - for i := 1; i < st.NumFields(); i++ { - o := func(s string) { fmt.Fprintf(b, s, st.Field(i).Name()) } - - if _, ok := st.Field(i).Type().(*types.Slice); ok { - switch st.Tag(i) { - case `dns:"-"`: - // ignored - case `dns:"cdomain-name"`, `dns:"domain-name"`, `dns:"txt"`: - o("for _, x := range rr.%s { l += len(x) + 1 }\n") - default: - log.Fatalln(name, st.Field(i).Name(), st.Tag(i)) - } - continue - } - - switch { - case st.Tag(i) == `dns:"-"`: - // ignored - case st.Tag(i) == `dns:"cdomain-name"`, st.Tag(i) == `dns:"domain-name"`: - o("l += len(rr.%s) + 1\n") - case st.Tag(i) == `dns:"octet"`: - o("l += len(rr.%s)\n") - case strings.HasPrefix(st.Tag(i), `dns:"size-base64`): - fallthrough - case st.Tag(i) == `dns:"base64"`: - o("l += base64.StdEncoding.DecodedLen(len(rr.%s))\n") - case strings.HasPrefix(st.Tag(i), `dns:"size-hex`): - fallthrough - case st.Tag(i) == `dns:"hex"`: - o("l += len(rr.%s)/2 + 1\n") - case st.Tag(i) == `dns:"a"`: - o("l += net.IPv4len // %s\n") - case st.Tag(i) == `dns:"aaaa"`: - o("l += net.IPv6len // %s\n") - case st.Tag(i) == `dns:"txt"`: - o("for _, t := range rr.%s { l += len(t) + 1 }\n") - case st.Tag(i) == `dns:"uint48"`: - o("l += 6 // %s\n") - case st.Tag(i) == "": - switch st.Field(i).Type().(*types.Basic).Kind() { - case types.Uint8: - o("l++ // %s\n") - case types.Uint16: - o("l += 2 // %s\n") - case types.Uint32: - o("l += 4 // %s\n") - case types.Uint64: - o("l += 8 // %s\n") - case types.String: - o("l += len(rr.%s) + 1\n") - default: - log.Fatalln(name, st.Field(i).Name()) - } - default: - log.Fatalln(name, st.Field(i).Name(), st.Tag(i)) - } - } - fmt.Fprintf(b, "return l }\n") - } - - // Generate copy() - fmt.Fprint(b, "// copy() functions\n") - for _, name := range namedTypes { - o := scope.Lookup(name) - st, isEmbedded := getTypeStruct(o.Type(), scope) - if isEmbedded { - continue - } - fmt.Fprintf(b, "func (rr *%s) copy() RR {\n", name) - fields := []string{"*rr.Hdr.copyHeader()"} - for i := 1; i < st.NumFields(); i++ { - f := st.Field(i).Name() - if sl, ok := st.Field(i).Type().(*types.Slice); ok { - t := sl.Underlying().String() - t = strings.TrimPrefix(t, "[]") - if strings.Contains(t, ".") { - splits := strings.Split(t, ".") - t = splits[len(splits)-1] - } - fmt.Fprintf(b, "%s := make([]%s, len(rr.%s)); copy(%s, rr.%s)\n", - f, t, f, f, f) - fields = append(fields, f) - continue - } - if st.Field(i).Type().String() == "net.IP" { - fields = append(fields, "copyIP(rr."+f+")") - continue - } - fields = append(fields, "rr."+f) - } - fmt.Fprintf(b, "return &%s{%s}\n", name, strings.Join(fields, ",")) - fmt.Fprintf(b, "}\n") - } - - // gofmt - res, err := format.Source(b.Bytes()) - if err != nil { - b.WriteTo(os.Stderr) - log.Fatal(err) - } - - // write result - f, err := os.Create("ztypes.go") - fatalIfErr(err) - defer f.Close() - f.Write(res) -} - -func fatalIfErr(err error) { - if err != nil { - log.Fatal(err) - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/types_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/types_test.go deleted file mode 100644 index c117cfbc7..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/types_test.go +++ /dev/null @@ -1,74 +0,0 @@ -package dns - -import ( - "testing" -) - -func TestCmToM(t *testing.T) { - s := cmToM(0, 0) - if s != "0.00" { - t.Error("0, 0") - } - - s = cmToM(1, 0) - if s != "0.01" { - t.Error("1, 0") - } - - s = cmToM(3, 1) - if s != "0.30" { - t.Error("3, 1") - } - - s = cmToM(4, 2) - if s != "4" { - t.Error("4, 2") - } - - s = cmToM(5, 3) - if s != "50" { - t.Error("5, 3") - } - - s = cmToM(7, 5) - if s != "7000" { - t.Error("7, 5") - } - - s = cmToM(9, 9) - if s != "90000000" { - t.Error("9, 9") - } -} - -func TestSplitN(t *testing.T) { - xs := splitN("abc", 5) - if len(xs) != 1 && xs[0] != "abc" { - t.Errorf("Failure to split abc") - } - - s := "" - for i := 0; i < 255; i++ { - s += "a" - } - - xs = splitN(s, 255) - if len(xs) != 1 && xs[0] != s { - t.Errorf("failure to split 255 char long string") - } - - s += "b" - xs = splitN(s, 255) - if len(xs) != 2 || xs[1] != "b" { - t.Errorf("failure to split 256 char long string: %d", len(xs)) - } - - // Make s longer - for i := 0; i < 255; i++ { - s += "a" - } - xs = splitN(s, 255) - if len(xs) != 3 || xs[2] != "a" { - t.Errorf("failure to split 510 char long string: %d", len(xs)) - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/udp.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/udp.go deleted file mode 100644 index af111b9a8..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/udp.go +++ /dev/null @@ -1,34 +0,0 @@ -// +build !windows - -package dns - -import ( - "net" -) - -// SessionUDP holds the remote address and the associated -// out-of-band data. -type SessionUDP struct { - raddr *net.UDPAddr - context []byte -} - -// RemoteAddr returns the remote network address. -func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr } - -// ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a -// net.UDPAddr. -func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) { - oob := make([]byte, 40) - n, oobn, _, raddr, err := conn.ReadMsgUDP(b, oob) - if err != nil { - return n, nil, err - } - return n, &SessionUDP{raddr, oob[:oobn]}, err -} - -// WriteToSessionUDP acts just like net.UDPConn.WritetTo(), but uses a *SessionUDP instead of a net.Addr. -func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) { - n, _, err := conn.WriteMsgUDP(b, session.context, session.raddr) - return n, err -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/udp_linux.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/udp_linux.go deleted file mode 100644 index 033df4239..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/udp_linux.go +++ /dev/null @@ -1,105 +0,0 @@ -// +build linux,!appengine - -package dns - -// See: -// * http://stackoverflow.com/questions/3062205/setting-the-source-ip-for-a-udp-socket and -// * http://blog.powerdns.com/2012/10/08/on-binding-datagram-udp-sockets-to-the-any-addresses/ -// -// Why do we need this: When listening on 0.0.0.0 with UDP so kernel decides what is the outgoing -// interface, this might not always be the correct one. This code will make sure the egress -// packet's interface matched the ingress' one. - -import ( - "net" - "syscall" -) - -// setUDPSocketOptions sets the UDP socket options. -// This function is implemented on a per platform basis. See udp_*.go for more details -func setUDPSocketOptions(conn *net.UDPConn) error { - sa, err := getUDPSocketName(conn) - if err != nil { - return err - } - switch sa.(type) { - case *syscall.SockaddrInet6: - v6only, err := getUDPSocketOptions6Only(conn) - if err != nil { - return err - } - setUDPSocketOptions6(conn) - if !v6only { - setUDPSocketOptions4(conn) - } - case *syscall.SockaddrInet4: - setUDPSocketOptions4(conn) - } - return nil -} - -// setUDPSocketOptions4 prepares the v4 socket for sessions. -func setUDPSocketOptions4(conn *net.UDPConn) error { - file, err := conn.File() - if err != nil { - return err - } - if err := syscall.SetsockoptInt(int(file.Fd()), syscall.IPPROTO_IP, syscall.IP_PKTINFO, 1); err != nil { - file.Close() - return err - } - // Calling File() above results in the connection becoming blocking, we must fix that. - // See https://github.com/miekg/dns/issues/279 - err = syscall.SetNonblock(int(file.Fd()), true) - if err != nil { - file.Close() - return err - } - file.Close() - return nil -} - -// setUDPSocketOptions6 prepares the v6 socket for sessions. -func setUDPSocketOptions6(conn *net.UDPConn) error { - file, err := conn.File() - if err != nil { - return err - } - if err := syscall.SetsockoptInt(int(file.Fd()), syscall.IPPROTO_IPV6, syscall.IPV6_RECVPKTINFO, 1); err != nil { - file.Close() - return err - } - err = syscall.SetNonblock(int(file.Fd()), true) - if err != nil { - file.Close() - return err - } - file.Close() - return nil -} - -// getUDPSocketOption6Only return true if the socket is v6 only and false when it is v4/v6 combined -// (dualstack). -func getUDPSocketOptions6Only(conn *net.UDPConn) (bool, error) { - file, err := conn.File() - if err != nil { - return false, err - } - // dual stack. See http://stackoverflow.com/questions/1618240/how-to-support-both-ipv4-and-ipv6-connections - v6only, err := syscall.GetsockoptInt(int(file.Fd()), syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY) - if err != nil { - file.Close() - return false, err - } - file.Close() - return v6only == 1, nil -} - -func getUDPSocketName(conn *net.UDPConn) (syscall.Sockaddr, error) { - file, err := conn.File() - if err != nil { - return nil, err - } - defer file.Close() - return syscall.Getsockname(int(file.Fd())) -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/udp_other.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/udp_other.go deleted file mode 100644 index 488a282b2..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/udp_other.go +++ /dev/null @@ -1,15 +0,0 @@ -// +build !linux appengine - -package dns - -import ( - "net" -) - -// These do nothing. See udp_linux.go for an example of how to implement this. - -// We tried to adhire to some kind of naming scheme. -func setUDPSocketOptions(conn *net.UDPConn) error { return nil } -func setUDPSocketOptions4(conn *net.UDPConn) error { return nil } -func setUDPSocketOptions6(conn *net.UDPConn) error { return nil } -func getUDPSocketOptions6Only(conn *net.UDPConn) (bool, error) { return false, nil } diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/udp_windows.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/udp_windows.go deleted file mode 100644 index 51e532ac2..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/udp_windows.go +++ /dev/null @@ -1,29 +0,0 @@ -// +build windows - -package dns - -import "net" - -type SessionUDP struct { - raddr *net.UDPAddr -} - -func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr } - -// ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a -// net.UDPAddr. -func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) { - n, raddr, err := conn.ReadFrom(b) - if err != nil { - return n, nil, err - } - session := &SessionUDP{raddr.(*net.UDPAddr)} - return n, session, err -} - -// WriteToSessionUDP acts just like net.UDPConn.WritetTo(), but uses a *SessionUDP instead of a net.Addr. -func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) { - n, err := conn.WriteTo(b, session.raddr) - return n, err -} - diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/update.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/update.go deleted file mode 100644 index e90c5c968..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/update.go +++ /dev/null @@ -1,106 +0,0 @@ -package dns - -// NameUsed sets the RRs in the prereq section to -// "Name is in use" RRs. RFC 2136 section 2.4.4. -func (u *Msg) NameUsed(rr []RR) { - if u.Answer == nil { - u.Answer = make([]RR, 0, len(rr)) - } - for _, r := range rr { - u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: TypeANY, Class: ClassANY}}) - } -} - -// NameNotUsed sets the RRs in the prereq section to -// "Name is in not use" RRs. RFC 2136 section 2.4.5. -func (u *Msg) NameNotUsed(rr []RR) { - if u.Answer == nil { - u.Answer = make([]RR, 0, len(rr)) - } - for _, r := range rr { - u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: TypeANY, Class: ClassNONE}}) - } -} - -// Used sets the RRs in the prereq section to -// "RRset exists (value dependent -- with rdata)" RRs. RFC 2136 section 2.4.2. -func (u *Msg) Used(rr []RR) { - if len(u.Question) == 0 { - panic("dns: empty question section") - } - if u.Answer == nil { - u.Answer = make([]RR, 0, len(rr)) - } - for _, r := range rr { - r.Header().Class = u.Question[0].Qclass - u.Answer = append(u.Answer, r) - } -} - -// RRsetUsed sets the RRs in the prereq section to -// "RRset exists (value independent -- no rdata)" RRs. RFC 2136 section 2.4.1. -func (u *Msg) RRsetUsed(rr []RR) { - if u.Answer == nil { - u.Answer = make([]RR, 0, len(rr)) - } - for _, r := range rr { - u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: r.Header().Rrtype, Class: ClassANY}}) - } -} - -// RRsetNotUsed sets the RRs in the prereq section to -// "RRset does not exist" RRs. RFC 2136 section 2.4.3. -func (u *Msg) RRsetNotUsed(rr []RR) { - if u.Answer == nil { - u.Answer = make([]RR, 0, len(rr)) - } - for _, r := range rr { - u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: r.Header().Rrtype, Class: ClassNONE}}) - } -} - -// Insert creates a dynamic update packet that adds an complete RRset, see RFC 2136 section 2.5.1. -func (u *Msg) Insert(rr []RR) { - if len(u.Question) == 0 { - panic("dns: empty question section") - } - if u.Ns == nil { - u.Ns = make([]RR, 0, len(rr)) - } - for _, r := range rr { - r.Header().Class = u.Question[0].Qclass - u.Ns = append(u.Ns, r) - } -} - -// RemoveRRset creates a dynamic update packet that deletes an RRset, see RFC 2136 section 2.5.2. -func (u *Msg) RemoveRRset(rr []RR) { - if u.Ns == nil { - u.Ns = make([]RR, 0, len(rr)) - } - for _, r := range rr { - u.Ns = append(u.Ns, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: r.Header().Rrtype, Class: ClassANY}}) - } -} - -// RemoveName creates a dynamic update packet that deletes all RRsets of a name, see RFC 2136 section 2.5.3 -func (u *Msg) RemoveName(rr []RR) { - if u.Ns == nil { - u.Ns = make([]RR, 0, len(rr)) - } - for _, r := range rr { - u.Ns = append(u.Ns, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: TypeANY, Class: ClassANY}}) - } -} - -// Remove creates a dynamic update packet deletes RR from a RRSset, see RFC 2136 section 2.5.4 -func (u *Msg) Remove(rr []RR) { - if u.Ns == nil { - u.Ns = make([]RR, 0, len(rr)) - } - for _, r := range rr { - r.Header().Class = ClassNONE - r.Header().Ttl = 0 - u.Ns = append(u.Ns, r) - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/update_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/update_test.go deleted file mode 100644 index 12760a1ee..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/update_test.go +++ /dev/null @@ -1,145 +0,0 @@ -package dns - -import ( - "bytes" - "testing" -) - -func TestDynamicUpdateParsing(t *testing.T) { - prefix := "example.com. IN " - for _, typ := range TypeToString { - if typ == "OPT" || typ == "AXFR" || typ == "IXFR" || typ == "ANY" || typ == "TKEY" || - typ == "TSIG" || typ == "ISDN" || typ == "UNSPEC" || typ == "NULL" || typ == "ATMA" || - typ == "Reserved" || typ == "None" || typ == "NXT" || typ == "MAILB" || typ == "MAILA" { - continue - } - r, err := NewRR(prefix + typ) - if err != nil { - t.Errorf("failure to parse: %s %s: %v", prefix, typ, err) - } else { - t.Logf("parsed: %s", r.String()) - } - } -} - -func TestDynamicUpdateUnpack(t *testing.T) { - // From https://github.com/miekg/dns/issues/150#issuecomment-62296803 - // It should be an update message for the zone "example.", - // deleting the A RRset "example." and then adding an A record at "example.". - // class ANY, TYPE A - buf := []byte{171, 68, 40, 0, 0, 1, 0, 0, 0, 2, 0, 0, 7, 101, 120, 97, 109, 112, 108, 101, 0, 0, 6, 0, 1, 192, 12, 0, 1, 0, 255, 0, 0, 0, 0, 0, 0, 192, 12, 0, 1, 0, 1, 0, 0, 0, 0, 0, 4, 127, 0, 0, 1} - msg := new(Msg) - err := msg.Unpack(buf) - if err != nil { - t.Errorf("failed to unpack: %v\n%s", err, msg.String()) - } -} - -func TestDynamicUpdateZeroRdataUnpack(t *testing.T) { - m := new(Msg) - rr := &RR_Header{Name: ".", Rrtype: 0, Class: 1, Ttl: ^uint32(0), Rdlength: 0} - m.Answer = []RR{rr, rr, rr, rr, rr} - m.Ns = m.Answer - for n, s := range TypeToString { - rr.Rrtype = n - bytes, err := m.Pack() - if err != nil { - t.Errorf("failed to pack %s: %v", s, err) - continue - } - if err := new(Msg).Unpack(bytes); err != nil { - t.Errorf("failed to unpack %s: %v", s, err) - } - } -} - -func TestRemoveRRset(t *testing.T) { - // Should add a zero data RR in Class ANY with a TTL of 0 - // for each set mentioned in the RRs provided to it. - rr, err := NewRR(". 100 IN A 127.0.0.1") - if err != nil { - t.Fatalf("error constructing RR: %v", err) - } - m := new(Msg) - m.Ns = []RR{&RR_Header{Name: ".", Rrtype: TypeA, Class: ClassANY, Ttl: 0, Rdlength: 0}} - expectstr := m.String() - expect, err := m.Pack() - if err != nil { - t.Fatalf("error packing expected msg: %v", err) - } - - m.Ns = nil - m.RemoveRRset([]RR{rr}) - actual, err := m.Pack() - if err != nil { - t.Fatalf("error packing actual msg: %v", err) - } - if !bytes.Equal(actual, expect) { - tmp := new(Msg) - if err := tmp.Unpack(actual); err != nil { - t.Fatalf("error unpacking actual msg: %v\nexpected: %v\ngot: %v\n", err, expect, actual) - } - t.Errorf("expected msg:\n%s", expectstr) - t.Errorf("actual msg:\n%v", tmp) - } -} - -func TestPreReqAndRemovals(t *testing.T) { - // Build a list of multiple prereqs and then somes removes followed by an insert. - // We should be able to add multiple prereqs and updates. - m := new(Msg) - m.SetUpdate("example.org.") - m.Id = 1234 - - // Use a full set of RRs each time, so we are sure the rdata is stripped. - rrName1, _ := NewRR("name_used. 3600 IN A 127.0.0.1") - rrName2, _ := NewRR("name_not_used. 3600 IN A 127.0.0.1") - rrRemove1, _ := NewRR("remove1. 3600 IN A 127.0.0.1") - rrRemove2, _ := NewRR("remove2. 3600 IN A 127.0.0.1") - rrRemove3, _ := NewRR("remove3. 3600 IN A 127.0.0.1") - rrInsert, _ := NewRR("insert. 3600 IN A 127.0.0.1") - rrRrset1, _ := NewRR("rrset_used1. 3600 IN A 127.0.0.1") - rrRrset2, _ := NewRR("rrset_used2. 3600 IN A 127.0.0.1") - rrRrset3, _ := NewRR("rrset_not_used. 3600 IN A 127.0.0.1") - - // Handle the prereqs. - m.NameUsed([]RR{rrName1}) - m.NameNotUsed([]RR{rrName2}) - m.RRsetUsed([]RR{rrRrset1}) - m.Used([]RR{rrRrset2}) - m.RRsetNotUsed([]RR{rrRrset3}) - - // and now the updates. - m.RemoveName([]RR{rrRemove1}) - m.RemoveRRset([]RR{rrRemove2}) - m.Remove([]RR{rrRemove3}) - m.Insert([]RR{rrInsert}) - - // This test function isn't a Example function because we print these RR with tabs at the - // end and the Example function trim these, thus they never match. - // TODO(miek): don't print these tabs and make this into an Example function. - expect := `;; opcode: UPDATE, status: NOERROR, id: 1234 -;; flags:; QUERY: 1, ANSWER: 5, AUTHORITY: 4, ADDITIONAL: 0 - -;; QUESTION SECTION: -;example.org. IN SOA - -;; ANSWER SECTION: -name_used. 0 ANY ANY -name_not_used. 0 NONE ANY -rrset_used1. 0 ANY A -rrset_used2. 3600 IN A 127.0.0.1 -rrset_not_used. 0 NONE A - -;; AUTHORITY SECTION: -remove1. 0 ANY ANY -remove2. 0 ANY A -remove3. 0 NONE A 127.0.0.1 -insert. 3600 IN A 127.0.0.1 -` - - if m.String() != expect { - t.Errorf("expected msg:\n%s", expect) - t.Errorf("actual msg:\n%v", m.String()) - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/xfr.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/xfr.go deleted file mode 100644 index 576c5590a..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/xfr.go +++ /dev/null @@ -1,255 +0,0 @@ -package dns - -import ( - "fmt" - "time" -) - -// Envelope is used when doing a zone transfer with a remote server. -type Envelope struct { - RR []RR // The set of RRs in the answer section of the xfr reply message. - Error error // If something went wrong, this contains the error. -} - -// A Transfer defines parameters that are used during a zone transfer. -type Transfer struct { - *Conn - DialTimeout time.Duration // net.DialTimeout, defaults to 2 seconds - ReadTimeout time.Duration // net.Conn.SetReadTimeout value for connections, defaults to 2 seconds - WriteTimeout time.Duration // net.Conn.SetWriteTimeout value for connections, defaults to 2 seconds - TsigSecret map[string]string // Secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be fully qualified - tsigTimersOnly bool -} - -// Think we need to away to stop the transfer - -// In performs an incoming transfer with the server in a. -// If you would like to set the source IP, or some other attribute -// of a Dialer for a Transfer, you can do so by specifying the attributes -// in the Transfer.Conn: -// -// d := net.Dialer{LocalAddr: transfer_source} -// con, err := d.Dial("tcp", master) -// dnscon := &dns.Conn{Conn:con} -// transfer = &dns.Transfer{Conn: dnscon} -// channel, err := transfer.In(message, master) -// -func (t *Transfer) In(q *Msg, a string) (env chan *Envelope, err error) { - timeout := dnsTimeout - if t.DialTimeout != 0 { - timeout = t.DialTimeout - } - if t.Conn == nil { - t.Conn, err = DialTimeout("tcp", a, timeout) - if err != nil { - return nil, err - } - } - if err := t.WriteMsg(q); err != nil { - return nil, err - } - env = make(chan *Envelope) - go func() { - if q.Question[0].Qtype == TypeAXFR { - go t.inAxfr(q.Id, env) - return - } - if q.Question[0].Qtype == TypeIXFR { - go t.inIxfr(q.Id, env) - return - } - }() - return env, nil -} - -func (t *Transfer) inAxfr(id uint16, c chan *Envelope) { - first := true - defer t.Close() - defer close(c) - timeout := dnsTimeout - if t.ReadTimeout != 0 { - timeout = t.ReadTimeout - } - for { - t.Conn.SetReadDeadline(time.Now().Add(timeout)) - in, err := t.ReadMsg() - if err != nil { - c <- &Envelope{nil, err} - return - } - if id != in.Id { - c <- &Envelope{in.Answer, ErrId} - return - } - if first { - if in.Rcode != RcodeSuccess { - c <- &Envelope{in.Answer, &Error{err: fmt.Sprintf(errXFR, in.Rcode)}} - return - } - if !isSOAFirst(in) { - c <- &Envelope{in.Answer, ErrSoa} - return - } - first = !first - // only one answer that is SOA, receive more - if len(in.Answer) == 1 { - t.tsigTimersOnly = true - c <- &Envelope{in.Answer, nil} - continue - } - } - - if !first { - t.tsigTimersOnly = true // Subsequent envelopes use this. - if isSOALast(in) { - c <- &Envelope{in.Answer, nil} - return - } - c <- &Envelope{in.Answer, nil} - } - } -} - -func (t *Transfer) inIxfr(id uint16, c chan *Envelope) { - serial := uint32(0) // The first serial seen is the current server serial - first := true - defer t.Close() - defer close(c) - timeout := dnsTimeout - if t.ReadTimeout != 0 { - timeout = t.ReadTimeout - } - for { - t.SetReadDeadline(time.Now().Add(timeout)) - in, err := t.ReadMsg() - if err != nil { - c <- &Envelope{nil, err} - return - } - if id != in.Id { - c <- &Envelope{in.Answer, ErrId} - return - } - if first { - if in.Rcode != RcodeSuccess { - c <- &Envelope{in.Answer, &Error{err: fmt.Sprintf(errXFR, in.Rcode)}} - return - } - // A single SOA RR signals "no changes" - if len(in.Answer) == 1 && isSOAFirst(in) { - c <- &Envelope{in.Answer, nil} - return - } - - // Check if the returned answer is ok - if !isSOAFirst(in) { - c <- &Envelope{in.Answer, ErrSoa} - return - } - // This serial is important - serial = in.Answer[0].(*SOA).Serial - first = !first - } - - // Now we need to check each message for SOA records, to see what we need to do - if !first { - t.tsigTimersOnly = true - // If the last record in the IXFR contains the servers' SOA, we should quit - if v, ok := in.Answer[len(in.Answer)-1].(*SOA); ok { - if v.Serial == serial { - c <- &Envelope{in.Answer, nil} - return - } - } - c <- &Envelope{in.Answer, nil} - } - } -} - -// Out performs an outgoing transfer with the client connecting in w. -// Basic use pattern: -// -// ch := make(chan *dns.Envelope) -// tr := new(dns.Transfer) -// go tr.Out(w, r, ch) -// ch <- &dns.Envelope{RR: []dns.RR{soa, rr1, rr2, rr3, soa}} -// close(ch) -// w.Hijack() -// // w.Close() // Client closes connection -// -// The server is responsible for sending the correct sequence of RRs through the -// channel ch. -func (t *Transfer) Out(w ResponseWriter, q *Msg, ch chan *Envelope) error { - for x := range ch { - r := new(Msg) - // Compress? - r.SetReply(q) - r.Authoritative = true - // assume it fits TODO(miek): fix - r.Answer = append(r.Answer, x.RR...) - if err := w.WriteMsg(r); err != nil { - return err - } - } - w.TsigTimersOnly(true) - return nil -} - -// ReadMsg reads a message from the transfer connection t. -func (t *Transfer) ReadMsg() (*Msg, error) { - m := new(Msg) - p := make([]byte, MaxMsgSize) - n, err := t.Read(p) - if err != nil && n == 0 { - return nil, err - } - p = p[:n] - if err := m.Unpack(p); err != nil { - return nil, err - } - if ts := m.IsTsig(); ts != nil && t.TsigSecret != nil { - if _, ok := t.TsigSecret[ts.Hdr.Name]; !ok { - return m, ErrSecret - } - // Need to work on the original message p, as that was used to calculate the tsig. - err = TsigVerify(p, t.TsigSecret[ts.Hdr.Name], t.tsigRequestMAC, t.tsigTimersOnly) - t.tsigRequestMAC = ts.MAC - } - return m, err -} - -// WriteMsg writes a message through the transfer connection t. -func (t *Transfer) WriteMsg(m *Msg) (err error) { - var out []byte - if ts := m.IsTsig(); ts != nil && t.TsigSecret != nil { - if _, ok := t.TsigSecret[ts.Hdr.Name]; !ok { - return ErrSecret - } - out, t.tsigRequestMAC, err = TsigGenerate(m, t.TsigSecret[ts.Hdr.Name], t.tsigRequestMAC, t.tsigTimersOnly) - } else { - out, err = m.Pack() - } - if err != nil { - return err - } - if _, err = t.Write(out); err != nil { - return err - } - return nil -} - -func isSOAFirst(in *Msg) bool { - if len(in.Answer) > 0 { - return in.Answer[0].Header().Rrtype == TypeSOA - } - return false -} - -func isSOALast(in *Msg) bool { - if len(in.Answer) > 0 { - return in.Answer[len(in.Answer)-1].Header().Rrtype == TypeSOA - } - return false -} - -const errXFR = "bad xfr rcode: %d" diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/xfr_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/xfr_test.go deleted file mode 100644 index a478963a3..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/xfr_test.go +++ /dev/null @@ -1,184 +0,0 @@ -// +build net - -package dns - -import ( - "net" - "strings" - "testing" - "time" -) - -func getIP(s string) string { - a, err := net.LookupAddr(s) - if err != nil { - return "" - } - return a[0] -} - -// flaky, need to setup local server and test from that. -func TestAXFR_Miek(t *testing.T) { - // This test runs against a server maintained by Miek - if testing.Short() { - return - } - m := new(Msg) - m.SetAxfr("miek.nl.") - - server := getIP("linode.atoom.net") - - tr := new(Transfer) - - if a, err := tr.In(m, net.JoinHostPort(server, "53")); err != nil { - t.Fatal("failed to setup axfr: ", err) - } else { - for ex := range a { - if ex.Error != nil { - t.Errorf("error %v", ex.Error) - break - } - for _, rr := range ex.RR { - t.Log(rr.String()) - } - } - } -} - -// fails. -func TestAXFR_NLNL_MultipleEnvelopes(t *testing.T) { - // This test runs against a server maintained by NLnet Labs - if testing.Short() { - return - } - m := new(Msg) - m.SetAxfr("nlnetlabs.nl.") - - server := getIP("open.nlnetlabs.nl.") - - tr := new(Transfer) - if a, err := tr.In(m, net.JoinHostPort(server, "53")); err != nil { - t.Fatalf("failed to setup axfr %v for server: %v", err, server) - } else { - for ex := range a { - if ex.Error != nil { - t.Errorf("error %v", ex.Error) - break - } - } - } -} - -func TestAXFR_Miek_Tsig(t *testing.T) { - // This test runs against a server maintained by Miek - if testing.Short() { - return - } - m := new(Msg) - m.SetAxfr("example.nl.") - m.SetTsig("axfr.", HmacMD5, 300, time.Now().Unix()) - - tr := new(Transfer) - tr.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="} - - if a, err := tr.In(m, "176.58.119.54:53"); err != nil { - t.Fatal("failed to setup axfr: ", err) - } else { - for ex := range a { - if ex.Error != nil { - t.Errorf("error %v", ex.Error) - break - } - for _, rr := range ex.RR { - t.Log(rr.String()) - } - } - } -} - -func TestAXFR_SIDN_NSD3_NONE(t *testing.T) { testAXFRSIDN(t, "nsd", "") } -func TestAXFR_SIDN_NSD3_MD5(t *testing.T) { testAXFRSIDN(t, "nsd", HmacMD5) } -func TestAXFR_SIDN_NSD3_SHA1(t *testing.T) { testAXFRSIDN(t, "nsd", HmacSHA1) } -func TestAXFR_SIDN_NSD3_SHA256(t *testing.T) { testAXFRSIDN(t, "nsd", HmacSHA256) } - -func TestAXFR_SIDN_NSD4_NONE(t *testing.T) { testAXFRSIDN(t, "nsd4", "") } -func TestAXFR_SIDN_NSD4_MD5(t *testing.T) { testAXFRSIDN(t, "nsd4", HmacMD5) } -func TestAXFR_SIDN_NSD4_SHA1(t *testing.T) { testAXFRSIDN(t, "nsd4", HmacSHA1) } -func TestAXFR_SIDN_NSD4_SHA256(t *testing.T) { testAXFRSIDN(t, "nsd4", HmacSHA256) } - -func TestAXFR_SIDN_BIND9_NONE(t *testing.T) { testAXFRSIDN(t, "bind9", "") } -func TestAXFR_SIDN_BIND9_MD5(t *testing.T) { testAXFRSIDN(t, "bind9", HmacMD5) } -func TestAXFR_SIDN_BIND9_SHA1(t *testing.T) { testAXFRSIDN(t, "bind9", HmacSHA1) } -func TestAXFR_SIDN_BIND9_SHA256(t *testing.T) { testAXFRSIDN(t, "bind9", HmacSHA256) } - -func TestAXFR_SIDN_KNOT_NONE(t *testing.T) { testAXFRSIDN(t, "knot", "") } -func TestAXFR_SIDN_KNOT_MD5(t *testing.T) { testAXFRSIDN(t, "knot", HmacMD5) } -func TestAXFR_SIDN_KNOT_SHA1(t *testing.T) { testAXFRSIDN(t, "knot", HmacSHA1) } -func TestAXFR_SIDN_KNOT_SHA256(t *testing.T) { testAXFRSIDN(t, "knot", HmacSHA256) } - -func TestAXFR_SIDN_POWERDNS_NONE(t *testing.T) { testAXFRSIDN(t, "powerdns", "") } -func TestAXFR_SIDN_POWERDNS_MD5(t *testing.T) { testAXFRSIDN(t, "powerdns", HmacMD5) } -func TestAXFR_SIDN_POWERDNS_SHA1(t *testing.T) { testAXFRSIDN(t, "powerdns", HmacSHA1) } -func TestAXFR_SIDN_POWERDNS_SHA256(t *testing.T) { testAXFRSIDN(t, "powerdns", HmacSHA256) } - -func TestAXFR_SIDN_YADIFA_NONE(t *testing.T) { testAXFRSIDN(t, "yadifa", "") } -func TestAXFR_SIDN_YADIFA_MD5(t *testing.T) { testAXFRSIDN(t, "yadifa", HmacMD5) } -func TestAXFR_SIDN_YADIFA_SHA1(t *testing.T) { testAXFRSIDN(t, "yadifa", HmacSHA1) } -func TestAXFR_SIDN_YADIFA_SHA256(t *testing.T) { testAXFRSIDN(t, "yadifa", HmacSHA256) } - -func testAXFRSIDN(t *testing.T, host, alg string) { - // This tests run against a server maintained by SIDN labs, see: - // https://workbench.sidnlabs.nl/ - if testing.Short() { - return - } - x := new(Transfer) - x.TsigSecret = map[string]string{ - "wb_md5.": "Wu/utSasZUkoeCNku152Zw==", - "wb_sha1_longkey.": "uhMpEhPq/RAD9Bt4mqhfmi+7ZdKmjLQb/lcrqYPXR4s/nnbsqw==", - "wb_sha256.": "npfrIJjt/MJOjGJoBNZtsjftKMhkSpIYMv2RzRZt1f8=", - } - keyname := map[string]string{ - HmacMD5: "wb_md5.", - HmacSHA1: "wb_sha1_longkey.", - HmacSHA256: "wb_sha256.", - }[alg] - - m := new(Msg) - m.SetAxfr("types.wb.sidnlabs.nl.") - if keyname != "" { - m.SetTsig(keyname, alg, 300, time.Now().Unix()) - } - c, err := x.In(m, host+".sidnlabs.nl:53") - if err != nil { - t.Fatal(err) - } - for e := range c { - if e.Error != nil { - t.Fatal(e.Error) - } - } -} - -func TestAXFRFailNotAuth(t *testing.T) { - // This tests run against a server maintained by SIDN labs, see: - // https://workbench.sidnlabs.nl/ - if testing.Short() { - return - } - x := new(Transfer) - - m := new(Msg) - m.SetAxfr("sidnlabs.nl.") - c, err := x.In(m, "yadifa.sidnlabs.nl:53") - if err != nil { - t.Fatal(err) - } - for e := range c { - if e.Error != nil { - if !strings.HasPrefix(e.Error.Error(), "dns: bad xfr rcode:") { - t.Fatal(e.Error) - } - } - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/zcompress.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/zcompress.go deleted file mode 100644 index b277978b9..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/zcompress.go +++ /dev/null @@ -1,119 +0,0 @@ -// *** DO NOT MODIFY *** -// AUTOGENERATED BY go generate from compress_generate.go - -package dns - -func compressionLenHelperType(c map[string]int, r RR) { - switch x := r.(type) { - case *PTR: - compressionLenHelper(c, x.Ptr) - case *SOA: - compressionLenHelper(c, x.Ns) - compressionLenHelper(c, x.Mbox) - case *AFSDB: - compressionLenHelper(c, x.Hostname) - case *HIP: - for i := range x.RendezvousServers { - compressionLenHelper(c, x.RendezvousServers[i]) - } - case *LP: - compressionLenHelper(c, x.Fqdn) - case *CNAME: - compressionLenHelper(c, x.Target) - case *MB: - compressionLenHelper(c, x.Mb) - case *RP: - compressionLenHelper(c, x.Mbox) - compressionLenHelper(c, x.Txt) - case *RRSIG: - compressionLenHelper(c, x.SignerName) - case *MF: - compressionLenHelper(c, x.Mf) - case *MINFO: - compressionLenHelper(c, x.Rmail) - compressionLenHelper(c, x.Email) - case *SIG: - compressionLenHelper(c, x.SignerName) - case *SRV: - compressionLenHelper(c, x.Target) - case *TSIG: - compressionLenHelper(c, x.Algorithm) - case *KX: - compressionLenHelper(c, x.Exchanger) - case *MG: - compressionLenHelper(c, x.Mg) - case *NSAPPTR: - compressionLenHelper(c, x.Ptr) - case *PX: - compressionLenHelper(c, x.Map822) - compressionLenHelper(c, x.Mapx400) - case *DNAME: - compressionLenHelper(c, x.Target) - case *MR: - compressionLenHelper(c, x.Mr) - case *MX: - compressionLenHelper(c, x.Mx) - case *TKEY: - compressionLenHelper(c, x.Algorithm) - case *NSEC: - compressionLenHelper(c, x.NextDomain) - case *TALINK: - compressionLenHelper(c, x.PreviousName) - compressionLenHelper(c, x.NextName) - case *MD: - compressionLenHelper(c, x.Md) - case *NAPTR: - compressionLenHelper(c, x.Replacement) - case *NS: - compressionLenHelper(c, x.Ns) - case *RT: - compressionLenHelper(c, x.Host) - } -} - -func compressionLenSearchType(c map[string]int, r RR) (int, bool) { - switch x := r.(type) { - case *MG: - k1, ok1 := compressionLenSearch(c, x.Mg) - return k1, ok1 - case *PTR: - k1, ok1 := compressionLenSearch(c, x.Ptr) - return k1, ok1 - case *AFSDB: - k1, ok1 := compressionLenSearch(c, x.Hostname) - return k1, ok1 - case *MB: - k1, ok1 := compressionLenSearch(c, x.Mb) - return k1, ok1 - case *MD: - k1, ok1 := compressionLenSearch(c, x.Md) - return k1, ok1 - case *MF: - k1, ok1 := compressionLenSearch(c, x.Mf) - return k1, ok1 - case *NS: - k1, ok1 := compressionLenSearch(c, x.Ns) - return k1, ok1 - case *RT: - k1, ok1 := compressionLenSearch(c, x.Host) - return k1, ok1 - case *SOA: - k1, ok1 := compressionLenSearch(c, x.Ns) - k2, ok2 := compressionLenSearch(c, x.Mbox) - return k1 + k2, ok1 && ok2 - case *CNAME: - k1, ok1 := compressionLenSearch(c, x.Target) - return k1, ok1 - case *MINFO: - k1, ok1 := compressionLenSearch(c, x.Rmail) - k2, ok2 := compressionLenSearch(c, x.Email) - return k1 + k2, ok1 && ok2 - case *MR: - k1, ok1 := compressionLenSearch(c, x.Mr) - return k1, ok1 - case *MX: - k1, ok1 := compressionLenSearch(c, x.Mx) - return k1, ok1 - } - return 0, false -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/zmsg.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/zmsg.go deleted file mode 100644 index 418fb1fe3..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/zmsg.go +++ /dev/null @@ -1,3565 +0,0 @@ -// *** DO NOT MODIFY *** -// AUTOGENERATED BY go generate from msg_generate.go - -package dns - -// pack*() functions - -func (rr *A) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packDataA(rr.A, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *AAAA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packDataAAAA(rr.AAAA, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *AFSDB) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint16(rr.Subtype, msg, off) - if err != nil { - return off, err - } - off, err = PackDomainName(rr.Hostname, msg, off, compression, compress) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *ANY) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *AVC) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packStringTxt(rr.Txt, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *CAA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint8(rr.Flag, msg, off) - if err != nil { - return off, err - } - off, err = packString(rr.Tag, msg, off) - if err != nil { - return off, err - } - off, err = packStringOctet(rr.Value, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *CDNSKEY) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint16(rr.Flags, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Protocol, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packStringBase64(rr.PublicKey, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *CDS) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint16(rr.KeyTag, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.DigestType, msg, off) - if err != nil { - return off, err - } - off, err = packStringHex(rr.Digest, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *CERT) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint16(rr.Type, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.KeyTag, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packStringBase64(rr.Certificate, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *CNAME) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = PackDomainName(rr.Target, msg, off, compression, compress) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *DHCID) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packStringBase64(rr.Digest, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *DLV) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint16(rr.KeyTag, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.DigestType, msg, off) - if err != nil { - return off, err - } - off, err = packStringHex(rr.Digest, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *DNAME) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = PackDomainName(rr.Target, msg, off, compression, false) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *DNSKEY) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint16(rr.Flags, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Protocol, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packStringBase64(rr.PublicKey, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *DS) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint16(rr.KeyTag, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.DigestType, msg, off) - if err != nil { - return off, err - } - off, err = packStringHex(rr.Digest, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *EID) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packStringHex(rr.Endpoint, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *EUI48) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint48(rr.Address, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *EUI64) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint64(rr.Address, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *GID) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint32(rr.Gid, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *GPOS) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packString(rr.Longitude, msg, off) - if err != nil { - return off, err - } - off, err = packString(rr.Latitude, msg, off) - if err != nil { - return off, err - } - off, err = packString(rr.Altitude, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *HINFO) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packString(rr.Cpu, msg, off) - if err != nil { - return off, err - } - off, err = packString(rr.Os, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *HIP) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint8(rr.HitLength, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.PublicKeyAlgorithm, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.PublicKeyLength, msg, off) - if err != nil { - return off, err - } - off, err = packStringHex(rr.Hit, msg, off) - if err != nil { - return off, err - } - off, err = packStringBase64(rr.PublicKey, msg, off) - if err != nil { - return off, err - } - off, err = packDataDomainNames(rr.RendezvousServers, msg, off, compression, compress) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *KEY) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint16(rr.Flags, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Protocol, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packStringBase64(rr.PublicKey, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *KX) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint16(rr.Preference, msg, off) - if err != nil { - return off, err - } - off, err = PackDomainName(rr.Exchanger, msg, off, compression, false) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *L32) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint16(rr.Preference, msg, off) - if err != nil { - return off, err - } - off, err = packDataA(rr.Locator32, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *L64) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint16(rr.Preference, msg, off) - if err != nil { - return off, err - } - off, err = packUint64(rr.Locator64, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *LOC) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint8(rr.Version, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Size, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.HorizPre, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.VertPre, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(rr.Latitude, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(rr.Longitude, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(rr.Altitude, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *LP) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint16(rr.Preference, msg, off) - if err != nil { - return off, err - } - off, err = PackDomainName(rr.Fqdn, msg, off, compression, false) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *MB) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = PackDomainName(rr.Mb, msg, off, compression, compress) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *MD) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = PackDomainName(rr.Md, msg, off, compression, compress) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *MF) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = PackDomainName(rr.Mf, msg, off, compression, compress) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *MG) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = PackDomainName(rr.Mg, msg, off, compression, compress) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *MINFO) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = PackDomainName(rr.Rmail, msg, off, compression, compress) - if err != nil { - return off, err - } - off, err = PackDomainName(rr.Email, msg, off, compression, compress) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *MR) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = PackDomainName(rr.Mr, msg, off, compression, compress) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *MX) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint16(rr.Preference, msg, off) - if err != nil { - return off, err - } - off, err = PackDomainName(rr.Mx, msg, off, compression, compress) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *NAPTR) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint16(rr.Order, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.Preference, msg, off) - if err != nil { - return off, err - } - off, err = packString(rr.Flags, msg, off) - if err != nil { - return off, err - } - off, err = packString(rr.Service, msg, off) - if err != nil { - return off, err - } - off, err = packString(rr.Regexp, msg, off) - if err != nil { - return off, err - } - off, err = PackDomainName(rr.Replacement, msg, off, compression, false) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *NID) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint16(rr.Preference, msg, off) - if err != nil { - return off, err - } - off, err = packUint64(rr.NodeID, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *NIMLOC) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packStringHex(rr.Locator, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *NINFO) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packStringTxt(rr.ZSData, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *NS) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = PackDomainName(rr.Ns, msg, off, compression, compress) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *NSAPPTR) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = PackDomainName(rr.Ptr, msg, off, compression, false) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *NSEC) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = PackDomainName(rr.NextDomain, msg, off, compression, false) - if err != nil { - return off, err - } - off, err = packDataNsec(rr.TypeBitMap, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *NSEC3) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint8(rr.Hash, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Flags, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.Iterations, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.SaltLength, msg, off) - if err != nil { - return off, err - } - // Only pack salt if value is not "-", i.e. empty - if rr.Salt != "-" { - off, err = packStringHex(rr.Salt, msg, off) - if err != nil { - return off, err - } - } - off, err = packUint8(rr.HashLength, msg, off) - if err != nil { - return off, err - } - off, err = packStringBase32(rr.NextDomain, msg, off) - if err != nil { - return off, err - } - off, err = packDataNsec(rr.TypeBitMap, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *NSEC3PARAM) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint8(rr.Hash, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Flags, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.Iterations, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.SaltLength, msg, off) - if err != nil { - return off, err - } - // Only pack salt if value is not "-", i.e. empty - if rr.Salt != "-" { - off, err = packStringHex(rr.Salt, msg, off) - if err != nil { - return off, err - } - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *OPENPGPKEY) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packStringBase64(rr.PublicKey, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *OPT) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packDataOpt(rr.Option, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *PTR) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = PackDomainName(rr.Ptr, msg, off, compression, compress) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *PX) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint16(rr.Preference, msg, off) - if err != nil { - return off, err - } - off, err = PackDomainName(rr.Map822, msg, off, compression, false) - if err != nil { - return off, err - } - off, err = PackDomainName(rr.Mapx400, msg, off, compression, false) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *RFC3597) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packStringHex(rr.Rdata, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *RKEY) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint16(rr.Flags, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Protocol, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packStringBase64(rr.PublicKey, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *RP) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = PackDomainName(rr.Mbox, msg, off, compression, false) - if err != nil { - return off, err - } - off, err = PackDomainName(rr.Txt, msg, off, compression, false) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *RRSIG) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint16(rr.TypeCovered, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Labels, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(rr.OrigTtl, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(rr.Expiration, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(rr.Inception, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.KeyTag, msg, off) - if err != nil { - return off, err - } - off, err = PackDomainName(rr.SignerName, msg, off, compression, false) - if err != nil { - return off, err - } - off, err = packStringBase64(rr.Signature, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *RT) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint16(rr.Preference, msg, off) - if err != nil { - return off, err - } - off, err = PackDomainName(rr.Host, msg, off, compression, compress) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *SIG) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint16(rr.TypeCovered, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Labels, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(rr.OrigTtl, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(rr.Expiration, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(rr.Inception, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.KeyTag, msg, off) - if err != nil { - return off, err - } - off, err = PackDomainName(rr.SignerName, msg, off, compression, false) - if err != nil { - return off, err - } - off, err = packStringBase64(rr.Signature, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *SMIMEA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint8(rr.Usage, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Selector, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.MatchingType, msg, off) - if err != nil { - return off, err - } - off, err = packStringHex(rr.Certificate, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *SOA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = PackDomainName(rr.Ns, msg, off, compression, compress) - if err != nil { - return off, err - } - off, err = PackDomainName(rr.Mbox, msg, off, compression, compress) - if err != nil { - return off, err - } - off, err = packUint32(rr.Serial, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(rr.Refresh, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(rr.Retry, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(rr.Expire, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(rr.Minttl, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *SPF) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packStringTxt(rr.Txt, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *SRV) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint16(rr.Priority, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.Weight, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.Port, msg, off) - if err != nil { - return off, err - } - off, err = PackDomainName(rr.Target, msg, off, compression, false) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *SSHFP) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint8(rr.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Type, msg, off) - if err != nil { - return off, err - } - off, err = packStringHex(rr.FingerPrint, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *TA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint16(rr.KeyTag, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Algorithm, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.DigestType, msg, off) - if err != nil { - return off, err - } - off, err = packStringHex(rr.Digest, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *TALINK) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = PackDomainName(rr.PreviousName, msg, off, compression, false) - if err != nil { - return off, err - } - off, err = PackDomainName(rr.NextName, msg, off, compression, false) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *TKEY) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = PackDomainName(rr.Algorithm, msg, off, compression, false) - if err != nil { - return off, err - } - off, err = packUint32(rr.Inception, msg, off) - if err != nil { - return off, err - } - off, err = packUint32(rr.Expiration, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.Mode, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.Error, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.KeySize, msg, off) - if err != nil { - return off, err - } - off, err = packString(rr.Key, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.OtherLen, msg, off) - if err != nil { - return off, err - } - off, err = packString(rr.OtherData, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *TLSA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint8(rr.Usage, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.Selector, msg, off) - if err != nil { - return off, err - } - off, err = packUint8(rr.MatchingType, msg, off) - if err != nil { - return off, err - } - off, err = packStringHex(rr.Certificate, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *TSIG) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = PackDomainName(rr.Algorithm, msg, off, compression, false) - if err != nil { - return off, err - } - off, err = packUint48(rr.TimeSigned, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.Fudge, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.MACSize, msg, off) - if err != nil { - return off, err - } - off, err = packStringHex(rr.MAC, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.OrigId, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.Error, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.OtherLen, msg, off) - if err != nil { - return off, err - } - off, err = packStringHex(rr.OtherData, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *TXT) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packStringTxt(rr.Txt, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *UID) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint32(rr.Uid, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *UINFO) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packString(rr.Uinfo, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *URI) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packUint16(rr.Priority, msg, off) - if err != nil { - return off, err - } - off, err = packUint16(rr.Weight, msg, off) - if err != nil { - return off, err - } - off, err = packStringOctet(rr.Target, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -func (rr *X25) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) - if err != nil { - return off, err - } - headerEnd := off - off, err = packString(rr.PSDNAddress, msg, off) - if err != nil { - return off, err - } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil -} - -// unpack*() functions - -func unpackA(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(A) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.A, off, err = unpackDataA(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackAAAA(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(AAAA) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.AAAA, off, err = unpackDataAAAA(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackAFSDB(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(AFSDB) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Subtype, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Hostname, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackANY(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(ANY) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - return rr, off, err -} - -func unpackAVC(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(AVC) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Txt, off, err = unpackStringTxt(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackCAA(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(CAA) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Flag, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Tag, off, err = unpackString(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Value, off, err = unpackStringOctet(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackCDNSKEY(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(CDNSKEY) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Flags, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Protocol, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Algorithm, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackCDS(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(CDS) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.KeyTag, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Algorithm, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.DigestType, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackCERT(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(CERT) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Type, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.KeyTag, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Algorithm, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Certificate, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackCNAME(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(CNAME) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Target, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackDHCID(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(DHCID) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Digest, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackDLV(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(DLV) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.KeyTag, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Algorithm, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.DigestType, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackDNAME(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(DNAME) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Target, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackDNSKEY(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(DNSKEY) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Flags, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Protocol, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Algorithm, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackDS(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(DS) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.KeyTag, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Algorithm, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.DigestType, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackEID(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(EID) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Endpoint, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackEUI48(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(EUI48) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Address, off, err = unpackUint48(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackEUI64(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(EUI64) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Address, off, err = unpackUint64(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackGID(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(GID) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Gid, off, err = unpackUint32(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackGPOS(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(GPOS) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Longitude, off, err = unpackString(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Latitude, off, err = unpackString(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Altitude, off, err = unpackString(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackHINFO(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(HINFO) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Cpu, off, err = unpackString(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Os, off, err = unpackString(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackHIP(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(HIP) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.HitLength, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.PublicKeyAlgorithm, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.PublicKeyLength, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Hit, off, err = unpackStringHex(msg, off, off+int(rr.HitLength)) - if err != nil { - return rr, off, err - } - rr.PublicKey, off, err = unpackStringBase64(msg, off, off+int(rr.PublicKeyLength)) - if err != nil { - return rr, off, err - } - rr.RendezvousServers, off, err = unpackDataDomainNames(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackKEY(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(KEY) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Flags, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Protocol, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Algorithm, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackKX(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(KX) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Preference, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Exchanger, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackL32(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(L32) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Preference, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Locator32, off, err = unpackDataA(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackL64(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(L64) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Preference, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Locator64, off, err = unpackUint64(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackLOC(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(LOC) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Version, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Size, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.HorizPre, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.VertPre, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Latitude, off, err = unpackUint32(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Longitude, off, err = unpackUint32(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Altitude, off, err = unpackUint32(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackLP(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(LP) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Preference, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Fqdn, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackMB(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(MB) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Mb, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackMD(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(MD) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Md, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackMF(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(MF) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Mf, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackMG(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(MG) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Mg, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackMINFO(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(MINFO) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Rmail, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Email, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackMR(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(MR) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Mr, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackMX(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(MX) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Preference, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Mx, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackNAPTR(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(NAPTR) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Order, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Preference, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Flags, off, err = unpackString(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Service, off, err = unpackString(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Regexp, off, err = unpackString(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Replacement, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackNID(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(NID) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Preference, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.NodeID, off, err = unpackUint64(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackNIMLOC(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(NIMLOC) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Locator, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackNINFO(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(NINFO) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.ZSData, off, err = unpackStringTxt(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackNS(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(NS) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Ns, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackNSAPPTR(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(NSAPPTR) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Ptr, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackNSEC(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(NSEC) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.NextDomain, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.TypeBitMap, off, err = unpackDataNsec(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackNSEC3(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(NSEC3) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Hash, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Flags, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Iterations, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.SaltLength, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Salt, off, err = unpackStringHex(msg, off, off+int(rr.SaltLength)) - if err != nil { - return rr, off, err - } - rr.HashLength, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.NextDomain, off, err = unpackStringBase32(msg, off, off+int(rr.HashLength)) - if err != nil { - return rr, off, err - } - rr.TypeBitMap, off, err = unpackDataNsec(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackNSEC3PARAM(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(NSEC3PARAM) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Hash, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Flags, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Iterations, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.SaltLength, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Salt, off, err = unpackStringHex(msg, off, off+int(rr.SaltLength)) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackOPENPGPKEY(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(OPENPGPKEY) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackOPT(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(OPT) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Option, off, err = unpackDataOpt(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackPTR(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(PTR) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Ptr, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackPX(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(PX) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Preference, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Map822, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Mapx400, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackRFC3597(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(RFC3597) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Rdata, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackRKEY(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(RKEY) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Flags, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Protocol, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Algorithm, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackRP(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(RP) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Mbox, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Txt, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackRRSIG(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(RRSIG) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.TypeCovered, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Algorithm, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Labels, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.OrigTtl, off, err = unpackUint32(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Expiration, off, err = unpackUint32(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Inception, off, err = unpackUint32(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.KeyTag, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.SignerName, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Signature, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackRT(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(RT) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Preference, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Host, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackSIG(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(SIG) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.TypeCovered, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Algorithm, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Labels, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.OrigTtl, off, err = unpackUint32(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Expiration, off, err = unpackUint32(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Inception, off, err = unpackUint32(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.KeyTag, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.SignerName, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Signature, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackSMIMEA(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(SMIMEA) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Usage, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Selector, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.MatchingType, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Certificate, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackSOA(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(SOA) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Ns, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Mbox, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Serial, off, err = unpackUint32(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Refresh, off, err = unpackUint32(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Retry, off, err = unpackUint32(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Expire, off, err = unpackUint32(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Minttl, off, err = unpackUint32(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackSPF(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(SPF) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Txt, off, err = unpackStringTxt(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackSRV(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(SRV) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Priority, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Weight, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Port, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Target, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackSSHFP(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(SSHFP) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Algorithm, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Type, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.FingerPrint, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackTA(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(TA) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.KeyTag, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Algorithm, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.DigestType, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackTALINK(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(TALINK) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.PreviousName, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.NextName, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackTKEY(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(TKEY) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Algorithm, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Inception, off, err = unpackUint32(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Expiration, off, err = unpackUint32(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Mode, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Error, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.KeySize, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Key, off, err = unpackString(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.OtherLen, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.OtherData, off, err = unpackString(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackTLSA(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(TLSA) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Usage, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Selector, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.MatchingType, off, err = unpackUint8(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Certificate, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackTSIG(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(TSIG) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Algorithm, off, err = UnpackDomainName(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.TimeSigned, off, err = unpackUint48(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Fudge, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.MACSize, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.MAC, off, err = unpackStringHex(msg, off, off+int(rr.MACSize)) - if err != nil { - return rr, off, err - } - rr.OrigId, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Error, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.OtherLen, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.OtherData, off, err = unpackStringHex(msg, off, off+int(rr.OtherLen)) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackTXT(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(TXT) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Txt, off, err = unpackStringTxt(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackUID(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(UID) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Uid, off, err = unpackUint32(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackUINFO(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(UINFO) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Uinfo, off, err = unpackString(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackURI(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(URI) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.Priority, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Weight, off, err = unpackUint16(msg, off) - if err != nil { - return rr, off, err - } - if off == len(msg) { - return rr, off, nil - } - rr.Target, off, err = unpackStringOctet(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -func unpackX25(h RR_Header, msg []byte, off int) (RR, int, error) { - rr := new(X25) - rr.Hdr = h - if noRdata(h) { - return rr, off, nil - } - var err error - rdStart := off - _ = rdStart - - rr.PSDNAddress, off, err = unpackString(msg, off) - if err != nil { - return rr, off, err - } - return rr, off, err -} - -var typeToUnpack = map[uint16]func(RR_Header, []byte, int) (RR, int, error){ - TypeA: unpackA, - TypeAAAA: unpackAAAA, - TypeAFSDB: unpackAFSDB, - TypeANY: unpackANY, - TypeAVC: unpackAVC, - TypeCAA: unpackCAA, - TypeCDNSKEY: unpackCDNSKEY, - TypeCDS: unpackCDS, - TypeCERT: unpackCERT, - TypeCNAME: unpackCNAME, - TypeDHCID: unpackDHCID, - TypeDLV: unpackDLV, - TypeDNAME: unpackDNAME, - TypeDNSKEY: unpackDNSKEY, - TypeDS: unpackDS, - TypeEID: unpackEID, - TypeEUI48: unpackEUI48, - TypeEUI64: unpackEUI64, - TypeGID: unpackGID, - TypeGPOS: unpackGPOS, - TypeHINFO: unpackHINFO, - TypeHIP: unpackHIP, - TypeKEY: unpackKEY, - TypeKX: unpackKX, - TypeL32: unpackL32, - TypeL64: unpackL64, - TypeLOC: unpackLOC, - TypeLP: unpackLP, - TypeMB: unpackMB, - TypeMD: unpackMD, - TypeMF: unpackMF, - TypeMG: unpackMG, - TypeMINFO: unpackMINFO, - TypeMR: unpackMR, - TypeMX: unpackMX, - TypeNAPTR: unpackNAPTR, - TypeNID: unpackNID, - TypeNIMLOC: unpackNIMLOC, - TypeNINFO: unpackNINFO, - TypeNS: unpackNS, - TypeNSAPPTR: unpackNSAPPTR, - TypeNSEC: unpackNSEC, - TypeNSEC3: unpackNSEC3, - TypeNSEC3PARAM: unpackNSEC3PARAM, - TypeOPENPGPKEY: unpackOPENPGPKEY, - TypeOPT: unpackOPT, - TypePTR: unpackPTR, - TypePX: unpackPX, - TypeRKEY: unpackRKEY, - TypeRP: unpackRP, - TypeRRSIG: unpackRRSIG, - TypeRT: unpackRT, - TypeSIG: unpackSIG, - TypeSMIMEA: unpackSMIMEA, - TypeSOA: unpackSOA, - TypeSPF: unpackSPF, - TypeSRV: unpackSRV, - TypeSSHFP: unpackSSHFP, - TypeTA: unpackTA, - TypeTALINK: unpackTALINK, - TypeTKEY: unpackTKEY, - TypeTLSA: unpackTLSA, - TypeTSIG: unpackTSIG, - TypeTXT: unpackTXT, - TypeUID: unpackUID, - TypeUINFO: unpackUINFO, - TypeURI: unpackURI, - TypeX25: unpackX25, -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/ztypes.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/ztypes.go deleted file mode 100644 index 3e534f12e..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/miekg/dns/ztypes.go +++ /dev/null @@ -1,857 +0,0 @@ -// *** DO NOT MODIFY *** -// AUTOGENERATED BY go generate from type_generate.go - -package dns - -import ( - "encoding/base64" - "net" -) - -// TypeToRR is a map of constructors for each RR type. -var TypeToRR = map[uint16]func() RR{ - TypeA: func() RR { return new(A) }, - TypeAAAA: func() RR { return new(AAAA) }, - TypeAFSDB: func() RR { return new(AFSDB) }, - TypeANY: func() RR { return new(ANY) }, - TypeAVC: func() RR { return new(AVC) }, - TypeCAA: func() RR { return new(CAA) }, - TypeCDNSKEY: func() RR { return new(CDNSKEY) }, - TypeCDS: func() RR { return new(CDS) }, - TypeCERT: func() RR { return new(CERT) }, - TypeCNAME: func() RR { return new(CNAME) }, - TypeDHCID: func() RR { return new(DHCID) }, - TypeDLV: func() RR { return new(DLV) }, - TypeDNAME: func() RR { return new(DNAME) }, - TypeDNSKEY: func() RR { return new(DNSKEY) }, - TypeDS: func() RR { return new(DS) }, - TypeEID: func() RR { return new(EID) }, - TypeEUI48: func() RR { return new(EUI48) }, - TypeEUI64: func() RR { return new(EUI64) }, - TypeGID: func() RR { return new(GID) }, - TypeGPOS: func() RR { return new(GPOS) }, - TypeHINFO: func() RR { return new(HINFO) }, - TypeHIP: func() RR { return new(HIP) }, - TypeKEY: func() RR { return new(KEY) }, - TypeKX: func() RR { return new(KX) }, - TypeL32: func() RR { return new(L32) }, - TypeL64: func() RR { return new(L64) }, - TypeLOC: func() RR { return new(LOC) }, - TypeLP: func() RR { return new(LP) }, - TypeMB: func() RR { return new(MB) }, - TypeMD: func() RR { return new(MD) }, - TypeMF: func() RR { return new(MF) }, - TypeMG: func() RR { return new(MG) }, - TypeMINFO: func() RR { return new(MINFO) }, - TypeMR: func() RR { return new(MR) }, - TypeMX: func() RR { return new(MX) }, - TypeNAPTR: func() RR { return new(NAPTR) }, - TypeNID: func() RR { return new(NID) }, - TypeNIMLOC: func() RR { return new(NIMLOC) }, - TypeNINFO: func() RR { return new(NINFO) }, - TypeNS: func() RR { return new(NS) }, - TypeNSAPPTR: func() RR { return new(NSAPPTR) }, - TypeNSEC: func() RR { return new(NSEC) }, - TypeNSEC3: func() RR { return new(NSEC3) }, - TypeNSEC3PARAM: func() RR { return new(NSEC3PARAM) }, - TypeOPENPGPKEY: func() RR { return new(OPENPGPKEY) }, - TypeOPT: func() RR { return new(OPT) }, - TypePTR: func() RR { return new(PTR) }, - TypePX: func() RR { return new(PX) }, - TypeRKEY: func() RR { return new(RKEY) }, - TypeRP: func() RR { return new(RP) }, - TypeRRSIG: func() RR { return new(RRSIG) }, - TypeRT: func() RR { return new(RT) }, - TypeSIG: func() RR { return new(SIG) }, - TypeSMIMEA: func() RR { return new(SMIMEA) }, - TypeSOA: func() RR { return new(SOA) }, - TypeSPF: func() RR { return new(SPF) }, - TypeSRV: func() RR { return new(SRV) }, - TypeSSHFP: func() RR { return new(SSHFP) }, - TypeTA: func() RR { return new(TA) }, - TypeTALINK: func() RR { return new(TALINK) }, - TypeTKEY: func() RR { return new(TKEY) }, - TypeTLSA: func() RR { return new(TLSA) }, - TypeTSIG: func() RR { return new(TSIG) }, - TypeTXT: func() RR { return new(TXT) }, - TypeUID: func() RR { return new(UID) }, - TypeUINFO: func() RR { return new(UINFO) }, - TypeURI: func() RR { return new(URI) }, - TypeX25: func() RR { return new(X25) }, -} - -// TypeToString is a map of strings for each RR type. -var TypeToString = map[uint16]string{ - TypeA: "A", - TypeAAAA: "AAAA", - TypeAFSDB: "AFSDB", - TypeANY: "ANY", - TypeATMA: "ATMA", - TypeAVC: "AVC", - TypeAXFR: "AXFR", - TypeCAA: "CAA", - TypeCDNSKEY: "CDNSKEY", - TypeCDS: "CDS", - TypeCERT: "CERT", - TypeCNAME: "CNAME", - TypeDHCID: "DHCID", - TypeDLV: "DLV", - TypeDNAME: "DNAME", - TypeDNSKEY: "DNSKEY", - TypeDS: "DS", - TypeEID: "EID", - TypeEUI48: "EUI48", - TypeEUI64: "EUI64", - TypeGID: "GID", - TypeGPOS: "GPOS", - TypeHINFO: "HINFO", - TypeHIP: "HIP", - TypeISDN: "ISDN", - TypeIXFR: "IXFR", - TypeKEY: "KEY", - TypeKX: "KX", - TypeL32: "L32", - TypeL64: "L64", - TypeLOC: "LOC", - TypeLP: "LP", - TypeMAILA: "MAILA", - TypeMAILB: "MAILB", - TypeMB: "MB", - TypeMD: "MD", - TypeMF: "MF", - TypeMG: "MG", - TypeMINFO: "MINFO", - TypeMR: "MR", - TypeMX: "MX", - TypeNAPTR: "NAPTR", - TypeNID: "NID", - TypeNIMLOC: "NIMLOC", - TypeNINFO: "NINFO", - TypeNS: "NS", - TypeNSEC: "NSEC", - TypeNSEC3: "NSEC3", - TypeNSEC3PARAM: "NSEC3PARAM", - TypeNULL: "NULL", - TypeNXT: "NXT", - TypeNone: "None", - TypeOPENPGPKEY: "OPENPGPKEY", - TypeOPT: "OPT", - TypePTR: "PTR", - TypePX: "PX", - TypeRKEY: "RKEY", - TypeRP: "RP", - TypeRRSIG: "RRSIG", - TypeRT: "RT", - TypeReserved: "Reserved", - TypeSIG: "SIG", - TypeSMIMEA: "SMIMEA", - TypeSOA: "SOA", - TypeSPF: "SPF", - TypeSRV: "SRV", - TypeSSHFP: "SSHFP", - TypeTA: "TA", - TypeTALINK: "TALINK", - TypeTKEY: "TKEY", - TypeTLSA: "TLSA", - TypeTSIG: "TSIG", - TypeTXT: "TXT", - TypeUID: "UID", - TypeUINFO: "UINFO", - TypeUNSPEC: "UNSPEC", - TypeURI: "URI", - TypeX25: "X25", - TypeNSAPPTR: "NSAP-PTR", -} - -// Header() functions -func (rr *A) Header() *RR_Header { return &rr.Hdr } -func (rr *AAAA) Header() *RR_Header { return &rr.Hdr } -func (rr *AFSDB) Header() *RR_Header { return &rr.Hdr } -func (rr *ANY) Header() *RR_Header { return &rr.Hdr } -func (rr *AVC) Header() *RR_Header { return &rr.Hdr } -func (rr *CAA) Header() *RR_Header { return &rr.Hdr } -func (rr *CDNSKEY) Header() *RR_Header { return &rr.Hdr } -func (rr *CDS) Header() *RR_Header { return &rr.Hdr } -func (rr *CERT) Header() *RR_Header { return &rr.Hdr } -func (rr *CNAME) Header() *RR_Header { return &rr.Hdr } -func (rr *DHCID) Header() *RR_Header { return &rr.Hdr } -func (rr *DLV) Header() *RR_Header { return &rr.Hdr } -func (rr *DNAME) Header() *RR_Header { return &rr.Hdr } -func (rr *DNSKEY) Header() *RR_Header { return &rr.Hdr } -func (rr *DS) Header() *RR_Header { return &rr.Hdr } -func (rr *EID) Header() *RR_Header { return &rr.Hdr } -func (rr *EUI48) Header() *RR_Header { return &rr.Hdr } -func (rr *EUI64) Header() *RR_Header { return &rr.Hdr } -func (rr *GID) Header() *RR_Header { return &rr.Hdr } -func (rr *GPOS) Header() *RR_Header { return &rr.Hdr } -func (rr *HINFO) Header() *RR_Header { return &rr.Hdr } -func (rr *HIP) Header() *RR_Header { return &rr.Hdr } -func (rr *KEY) Header() *RR_Header { return &rr.Hdr } -func (rr *KX) Header() *RR_Header { return &rr.Hdr } -func (rr *L32) Header() *RR_Header { return &rr.Hdr } -func (rr *L64) Header() *RR_Header { return &rr.Hdr } -func (rr *LOC) Header() *RR_Header { return &rr.Hdr } -func (rr *LP) Header() *RR_Header { return &rr.Hdr } -func (rr *MB) Header() *RR_Header { return &rr.Hdr } -func (rr *MD) Header() *RR_Header { return &rr.Hdr } -func (rr *MF) Header() *RR_Header { return &rr.Hdr } -func (rr *MG) Header() *RR_Header { return &rr.Hdr } -func (rr *MINFO) Header() *RR_Header { return &rr.Hdr } -func (rr *MR) Header() *RR_Header { return &rr.Hdr } -func (rr *MX) Header() *RR_Header { return &rr.Hdr } -func (rr *NAPTR) Header() *RR_Header { return &rr.Hdr } -func (rr *NID) Header() *RR_Header { return &rr.Hdr } -func (rr *NIMLOC) Header() *RR_Header { return &rr.Hdr } -func (rr *NINFO) Header() *RR_Header { return &rr.Hdr } -func (rr *NS) Header() *RR_Header { return &rr.Hdr } -func (rr *NSAPPTR) Header() *RR_Header { return &rr.Hdr } -func (rr *NSEC) Header() *RR_Header { return &rr.Hdr } -func (rr *NSEC3) Header() *RR_Header { return &rr.Hdr } -func (rr *NSEC3PARAM) Header() *RR_Header { return &rr.Hdr } -func (rr *OPENPGPKEY) Header() *RR_Header { return &rr.Hdr } -func (rr *OPT) Header() *RR_Header { return &rr.Hdr } -func (rr *PTR) Header() *RR_Header { return &rr.Hdr } -func (rr *PX) Header() *RR_Header { return &rr.Hdr } -func (rr *RFC3597) Header() *RR_Header { return &rr.Hdr } -func (rr *RKEY) Header() *RR_Header { return &rr.Hdr } -func (rr *RP) Header() *RR_Header { return &rr.Hdr } -func (rr *RRSIG) Header() *RR_Header { return &rr.Hdr } -func (rr *RT) Header() *RR_Header { return &rr.Hdr } -func (rr *SIG) Header() *RR_Header { return &rr.Hdr } -func (rr *SMIMEA) Header() *RR_Header { return &rr.Hdr } -func (rr *SOA) Header() *RR_Header { return &rr.Hdr } -func (rr *SPF) Header() *RR_Header { return &rr.Hdr } -func (rr *SRV) Header() *RR_Header { return &rr.Hdr } -func (rr *SSHFP) Header() *RR_Header { return &rr.Hdr } -func (rr *TA) Header() *RR_Header { return &rr.Hdr } -func (rr *TALINK) Header() *RR_Header { return &rr.Hdr } -func (rr *TKEY) Header() *RR_Header { return &rr.Hdr } -func (rr *TLSA) Header() *RR_Header { return &rr.Hdr } -func (rr *TSIG) Header() *RR_Header { return &rr.Hdr } -func (rr *TXT) Header() *RR_Header { return &rr.Hdr } -func (rr *UID) Header() *RR_Header { return &rr.Hdr } -func (rr *UINFO) Header() *RR_Header { return &rr.Hdr } -func (rr *URI) Header() *RR_Header { return &rr.Hdr } -func (rr *X25) Header() *RR_Header { return &rr.Hdr } - -// len() functions -func (rr *A) len() int { - l := rr.Hdr.len() - l += net.IPv4len // A - return l -} -func (rr *AAAA) len() int { - l := rr.Hdr.len() - l += net.IPv6len // AAAA - return l -} -func (rr *AFSDB) len() int { - l := rr.Hdr.len() - l += 2 // Subtype - l += len(rr.Hostname) + 1 - return l -} -func (rr *ANY) len() int { - l := rr.Hdr.len() - return l -} -func (rr *AVC) len() int { - l := rr.Hdr.len() - for _, x := range rr.Txt { - l += len(x) + 1 - } - return l -} -func (rr *CAA) len() int { - l := rr.Hdr.len() - l++ // Flag - l += len(rr.Tag) + 1 - l += len(rr.Value) - return l -} -func (rr *CERT) len() int { - l := rr.Hdr.len() - l += 2 // Type - l += 2 // KeyTag - l++ // Algorithm - l += base64.StdEncoding.DecodedLen(len(rr.Certificate)) - return l -} -func (rr *CNAME) len() int { - l := rr.Hdr.len() - l += len(rr.Target) + 1 - return l -} -func (rr *DHCID) len() int { - l := rr.Hdr.len() - l += base64.StdEncoding.DecodedLen(len(rr.Digest)) - return l -} -func (rr *DNAME) len() int { - l := rr.Hdr.len() - l += len(rr.Target) + 1 - return l -} -func (rr *DNSKEY) len() int { - l := rr.Hdr.len() - l += 2 // Flags - l++ // Protocol - l++ // Algorithm - l += base64.StdEncoding.DecodedLen(len(rr.PublicKey)) - return l -} -func (rr *DS) len() int { - l := rr.Hdr.len() - l += 2 // KeyTag - l++ // Algorithm - l++ // DigestType - l += len(rr.Digest)/2 + 1 - return l -} -func (rr *EID) len() int { - l := rr.Hdr.len() - l += len(rr.Endpoint)/2 + 1 - return l -} -func (rr *EUI48) len() int { - l := rr.Hdr.len() - l += 6 // Address - return l -} -func (rr *EUI64) len() int { - l := rr.Hdr.len() - l += 8 // Address - return l -} -func (rr *GID) len() int { - l := rr.Hdr.len() - l += 4 // Gid - return l -} -func (rr *GPOS) len() int { - l := rr.Hdr.len() - l += len(rr.Longitude) + 1 - l += len(rr.Latitude) + 1 - l += len(rr.Altitude) + 1 - return l -} -func (rr *HINFO) len() int { - l := rr.Hdr.len() - l += len(rr.Cpu) + 1 - l += len(rr.Os) + 1 - return l -} -func (rr *HIP) len() int { - l := rr.Hdr.len() - l++ // HitLength - l++ // PublicKeyAlgorithm - l += 2 // PublicKeyLength - l += len(rr.Hit)/2 + 1 - l += base64.StdEncoding.DecodedLen(len(rr.PublicKey)) - for _, x := range rr.RendezvousServers { - l += len(x) + 1 - } - return l -} -func (rr *KX) len() int { - l := rr.Hdr.len() - l += 2 // Preference - l += len(rr.Exchanger) + 1 - return l -} -func (rr *L32) len() int { - l := rr.Hdr.len() - l += 2 // Preference - l += net.IPv4len // Locator32 - return l -} -func (rr *L64) len() int { - l := rr.Hdr.len() - l += 2 // Preference - l += 8 // Locator64 - return l -} -func (rr *LOC) len() int { - l := rr.Hdr.len() - l++ // Version - l++ // Size - l++ // HorizPre - l++ // VertPre - l += 4 // Latitude - l += 4 // Longitude - l += 4 // Altitude - return l -} -func (rr *LP) len() int { - l := rr.Hdr.len() - l += 2 // Preference - l += len(rr.Fqdn) + 1 - return l -} -func (rr *MB) len() int { - l := rr.Hdr.len() - l += len(rr.Mb) + 1 - return l -} -func (rr *MD) len() int { - l := rr.Hdr.len() - l += len(rr.Md) + 1 - return l -} -func (rr *MF) len() int { - l := rr.Hdr.len() - l += len(rr.Mf) + 1 - return l -} -func (rr *MG) len() int { - l := rr.Hdr.len() - l += len(rr.Mg) + 1 - return l -} -func (rr *MINFO) len() int { - l := rr.Hdr.len() - l += len(rr.Rmail) + 1 - l += len(rr.Email) + 1 - return l -} -func (rr *MR) len() int { - l := rr.Hdr.len() - l += len(rr.Mr) + 1 - return l -} -func (rr *MX) len() int { - l := rr.Hdr.len() - l += 2 // Preference - l += len(rr.Mx) + 1 - return l -} -func (rr *NAPTR) len() int { - l := rr.Hdr.len() - l += 2 // Order - l += 2 // Preference - l += len(rr.Flags) + 1 - l += len(rr.Service) + 1 - l += len(rr.Regexp) + 1 - l += len(rr.Replacement) + 1 - return l -} -func (rr *NID) len() int { - l := rr.Hdr.len() - l += 2 // Preference - l += 8 // NodeID - return l -} -func (rr *NIMLOC) len() int { - l := rr.Hdr.len() - l += len(rr.Locator)/2 + 1 - return l -} -func (rr *NINFO) len() int { - l := rr.Hdr.len() - for _, x := range rr.ZSData { - l += len(x) + 1 - } - return l -} -func (rr *NS) len() int { - l := rr.Hdr.len() - l += len(rr.Ns) + 1 - return l -} -func (rr *NSAPPTR) len() int { - l := rr.Hdr.len() - l += len(rr.Ptr) + 1 - return l -} -func (rr *NSEC3PARAM) len() int { - l := rr.Hdr.len() - l++ // Hash - l++ // Flags - l += 2 // Iterations - l++ // SaltLength - l += len(rr.Salt)/2 + 1 - return l -} -func (rr *OPENPGPKEY) len() int { - l := rr.Hdr.len() - l += base64.StdEncoding.DecodedLen(len(rr.PublicKey)) - return l -} -func (rr *PTR) len() int { - l := rr.Hdr.len() - l += len(rr.Ptr) + 1 - return l -} -func (rr *PX) len() int { - l := rr.Hdr.len() - l += 2 // Preference - l += len(rr.Map822) + 1 - l += len(rr.Mapx400) + 1 - return l -} -func (rr *RFC3597) len() int { - l := rr.Hdr.len() - l += len(rr.Rdata)/2 + 1 - return l -} -func (rr *RKEY) len() int { - l := rr.Hdr.len() - l += 2 // Flags - l++ // Protocol - l++ // Algorithm - l += base64.StdEncoding.DecodedLen(len(rr.PublicKey)) - return l -} -func (rr *RP) len() int { - l := rr.Hdr.len() - l += len(rr.Mbox) + 1 - l += len(rr.Txt) + 1 - return l -} -func (rr *RRSIG) len() int { - l := rr.Hdr.len() - l += 2 // TypeCovered - l++ // Algorithm - l++ // Labels - l += 4 // OrigTtl - l += 4 // Expiration - l += 4 // Inception - l += 2 // KeyTag - l += len(rr.SignerName) + 1 - l += base64.StdEncoding.DecodedLen(len(rr.Signature)) - return l -} -func (rr *RT) len() int { - l := rr.Hdr.len() - l += 2 // Preference - l += len(rr.Host) + 1 - return l -} -func (rr *SMIMEA) len() int { - l := rr.Hdr.len() - l++ // Usage - l++ // Selector - l++ // MatchingType - l += len(rr.Certificate)/2 + 1 - return l -} -func (rr *SOA) len() int { - l := rr.Hdr.len() - l += len(rr.Ns) + 1 - l += len(rr.Mbox) + 1 - l += 4 // Serial - l += 4 // Refresh - l += 4 // Retry - l += 4 // Expire - l += 4 // Minttl - return l -} -func (rr *SPF) len() int { - l := rr.Hdr.len() - for _, x := range rr.Txt { - l += len(x) + 1 - } - return l -} -func (rr *SRV) len() int { - l := rr.Hdr.len() - l += 2 // Priority - l += 2 // Weight - l += 2 // Port - l += len(rr.Target) + 1 - return l -} -func (rr *SSHFP) len() int { - l := rr.Hdr.len() - l++ // Algorithm - l++ // Type - l += len(rr.FingerPrint)/2 + 1 - return l -} -func (rr *TA) len() int { - l := rr.Hdr.len() - l += 2 // KeyTag - l++ // Algorithm - l++ // DigestType - l += len(rr.Digest)/2 + 1 - return l -} -func (rr *TALINK) len() int { - l := rr.Hdr.len() - l += len(rr.PreviousName) + 1 - l += len(rr.NextName) + 1 - return l -} -func (rr *TKEY) len() int { - l := rr.Hdr.len() - l += len(rr.Algorithm) + 1 - l += 4 // Inception - l += 4 // Expiration - l += 2 // Mode - l += 2 // Error - l += 2 // KeySize - l += len(rr.Key) + 1 - l += 2 // OtherLen - l += len(rr.OtherData) + 1 - return l -} -func (rr *TLSA) len() int { - l := rr.Hdr.len() - l++ // Usage - l++ // Selector - l++ // MatchingType - l += len(rr.Certificate)/2 + 1 - return l -} -func (rr *TSIG) len() int { - l := rr.Hdr.len() - l += len(rr.Algorithm) + 1 - l += 6 // TimeSigned - l += 2 // Fudge - l += 2 // MACSize - l += len(rr.MAC)/2 + 1 - l += 2 // OrigId - l += 2 // Error - l += 2 // OtherLen - l += len(rr.OtherData)/2 + 1 - return l -} -func (rr *TXT) len() int { - l := rr.Hdr.len() - for _, x := range rr.Txt { - l += len(x) + 1 - } - return l -} -func (rr *UID) len() int { - l := rr.Hdr.len() - l += 4 // Uid - return l -} -func (rr *UINFO) len() int { - l := rr.Hdr.len() - l += len(rr.Uinfo) + 1 - return l -} -func (rr *URI) len() int { - l := rr.Hdr.len() - l += 2 // Priority - l += 2 // Weight - l += len(rr.Target) - return l -} -func (rr *X25) len() int { - l := rr.Hdr.len() - l += len(rr.PSDNAddress) + 1 - return l -} - -// copy() functions -func (rr *A) copy() RR { - return &A{*rr.Hdr.copyHeader(), copyIP(rr.A)} -} -func (rr *AAAA) copy() RR { - return &AAAA{*rr.Hdr.copyHeader(), copyIP(rr.AAAA)} -} -func (rr *AFSDB) copy() RR { - return &AFSDB{*rr.Hdr.copyHeader(), rr.Subtype, rr.Hostname} -} -func (rr *ANY) copy() RR { - return &ANY{*rr.Hdr.copyHeader()} -} -func (rr *AVC) copy() RR { - Txt := make([]string, len(rr.Txt)) - copy(Txt, rr.Txt) - return &AVC{*rr.Hdr.copyHeader(), Txt} -} -func (rr *CAA) copy() RR { - return &CAA{*rr.Hdr.copyHeader(), rr.Flag, rr.Tag, rr.Value} -} -func (rr *CERT) copy() RR { - return &CERT{*rr.Hdr.copyHeader(), rr.Type, rr.KeyTag, rr.Algorithm, rr.Certificate} -} -func (rr *CNAME) copy() RR { - return &CNAME{*rr.Hdr.copyHeader(), rr.Target} -} -func (rr *DHCID) copy() RR { - return &DHCID{*rr.Hdr.copyHeader(), rr.Digest} -} -func (rr *DNAME) copy() RR { - return &DNAME{*rr.Hdr.copyHeader(), rr.Target} -} -func (rr *DNSKEY) copy() RR { - return &DNSKEY{*rr.Hdr.copyHeader(), rr.Flags, rr.Protocol, rr.Algorithm, rr.PublicKey} -} -func (rr *DS) copy() RR { - return &DS{*rr.Hdr.copyHeader(), rr.KeyTag, rr.Algorithm, rr.DigestType, rr.Digest} -} -func (rr *EID) copy() RR { - return &EID{*rr.Hdr.copyHeader(), rr.Endpoint} -} -func (rr *EUI48) copy() RR { - return &EUI48{*rr.Hdr.copyHeader(), rr.Address} -} -func (rr *EUI64) copy() RR { - return &EUI64{*rr.Hdr.copyHeader(), rr.Address} -} -func (rr *GID) copy() RR { - return &GID{*rr.Hdr.copyHeader(), rr.Gid} -} -func (rr *GPOS) copy() RR { - return &GPOS{*rr.Hdr.copyHeader(), rr.Longitude, rr.Latitude, rr.Altitude} -} -func (rr *HINFO) copy() RR { - return &HINFO{*rr.Hdr.copyHeader(), rr.Cpu, rr.Os} -} -func (rr *HIP) copy() RR { - RendezvousServers := make([]string, len(rr.RendezvousServers)) - copy(RendezvousServers, rr.RendezvousServers) - return &HIP{*rr.Hdr.copyHeader(), rr.HitLength, rr.PublicKeyAlgorithm, rr.PublicKeyLength, rr.Hit, rr.PublicKey, RendezvousServers} -} -func (rr *KX) copy() RR { - return &KX{*rr.Hdr.copyHeader(), rr.Preference, rr.Exchanger} -} -func (rr *L32) copy() RR { - return &L32{*rr.Hdr.copyHeader(), rr.Preference, copyIP(rr.Locator32)} -} -func (rr *L64) copy() RR { - return &L64{*rr.Hdr.copyHeader(), rr.Preference, rr.Locator64} -} -func (rr *LOC) copy() RR { - return &LOC{*rr.Hdr.copyHeader(), rr.Version, rr.Size, rr.HorizPre, rr.VertPre, rr.Latitude, rr.Longitude, rr.Altitude} -} -func (rr *LP) copy() RR { - return &LP{*rr.Hdr.copyHeader(), rr.Preference, rr.Fqdn} -} -func (rr *MB) copy() RR { - return &MB{*rr.Hdr.copyHeader(), rr.Mb} -} -func (rr *MD) copy() RR { - return &MD{*rr.Hdr.copyHeader(), rr.Md} -} -func (rr *MF) copy() RR { - return &MF{*rr.Hdr.copyHeader(), rr.Mf} -} -func (rr *MG) copy() RR { - return &MG{*rr.Hdr.copyHeader(), rr.Mg} -} -func (rr *MINFO) copy() RR { - return &MINFO{*rr.Hdr.copyHeader(), rr.Rmail, rr.Email} -} -func (rr *MR) copy() RR { - return &MR{*rr.Hdr.copyHeader(), rr.Mr} -} -func (rr *MX) copy() RR { - return &MX{*rr.Hdr.copyHeader(), rr.Preference, rr.Mx} -} -func (rr *NAPTR) copy() RR { - return &NAPTR{*rr.Hdr.copyHeader(), rr.Order, rr.Preference, rr.Flags, rr.Service, rr.Regexp, rr.Replacement} -} -func (rr *NID) copy() RR { - return &NID{*rr.Hdr.copyHeader(), rr.Preference, rr.NodeID} -} -func (rr *NIMLOC) copy() RR { - return &NIMLOC{*rr.Hdr.copyHeader(), rr.Locator} -} -func (rr *NINFO) copy() RR { - ZSData := make([]string, len(rr.ZSData)) - copy(ZSData, rr.ZSData) - return &NINFO{*rr.Hdr.copyHeader(), ZSData} -} -func (rr *NS) copy() RR { - return &NS{*rr.Hdr.copyHeader(), rr.Ns} -} -func (rr *NSAPPTR) copy() RR { - return &NSAPPTR{*rr.Hdr.copyHeader(), rr.Ptr} -} -func (rr *NSEC) copy() RR { - TypeBitMap := make([]uint16, len(rr.TypeBitMap)) - copy(TypeBitMap, rr.TypeBitMap) - return &NSEC{*rr.Hdr.copyHeader(), rr.NextDomain, TypeBitMap} -} -func (rr *NSEC3) copy() RR { - TypeBitMap := make([]uint16, len(rr.TypeBitMap)) - copy(TypeBitMap, rr.TypeBitMap) - return &NSEC3{*rr.Hdr.copyHeader(), rr.Hash, rr.Flags, rr.Iterations, rr.SaltLength, rr.Salt, rr.HashLength, rr.NextDomain, TypeBitMap} -} -func (rr *NSEC3PARAM) copy() RR { - return &NSEC3PARAM{*rr.Hdr.copyHeader(), rr.Hash, rr.Flags, rr.Iterations, rr.SaltLength, rr.Salt} -} -func (rr *OPENPGPKEY) copy() RR { - return &OPENPGPKEY{*rr.Hdr.copyHeader(), rr.PublicKey} -} -func (rr *OPT) copy() RR { - Option := make([]EDNS0, len(rr.Option)) - copy(Option, rr.Option) - return &OPT{*rr.Hdr.copyHeader(), Option} -} -func (rr *PTR) copy() RR { - return &PTR{*rr.Hdr.copyHeader(), rr.Ptr} -} -func (rr *PX) copy() RR { - return &PX{*rr.Hdr.copyHeader(), rr.Preference, rr.Map822, rr.Mapx400} -} -func (rr *RFC3597) copy() RR { - return &RFC3597{*rr.Hdr.copyHeader(), rr.Rdata} -} -func (rr *RKEY) copy() RR { - return &RKEY{*rr.Hdr.copyHeader(), rr.Flags, rr.Protocol, rr.Algorithm, rr.PublicKey} -} -func (rr *RP) copy() RR { - return &RP{*rr.Hdr.copyHeader(), rr.Mbox, rr.Txt} -} -func (rr *RRSIG) copy() RR { - return &RRSIG{*rr.Hdr.copyHeader(), rr.TypeCovered, rr.Algorithm, rr.Labels, rr.OrigTtl, rr.Expiration, rr.Inception, rr.KeyTag, rr.SignerName, rr.Signature} -} -func (rr *RT) copy() RR { - return &RT{*rr.Hdr.copyHeader(), rr.Preference, rr.Host} -} -func (rr *SMIMEA) copy() RR { - return &SMIMEA{*rr.Hdr.copyHeader(), rr.Usage, rr.Selector, rr.MatchingType, rr.Certificate} -} -func (rr *SOA) copy() RR { - return &SOA{*rr.Hdr.copyHeader(), rr.Ns, rr.Mbox, rr.Serial, rr.Refresh, rr.Retry, rr.Expire, rr.Minttl} -} -func (rr *SPF) copy() RR { - Txt := make([]string, len(rr.Txt)) - copy(Txt, rr.Txt) - return &SPF{*rr.Hdr.copyHeader(), Txt} -} -func (rr *SRV) copy() RR { - return &SRV{*rr.Hdr.copyHeader(), rr.Priority, rr.Weight, rr.Port, rr.Target} -} -func (rr *SSHFP) copy() RR { - return &SSHFP{*rr.Hdr.copyHeader(), rr.Algorithm, rr.Type, rr.FingerPrint} -} -func (rr *TA) copy() RR { - return &TA{*rr.Hdr.copyHeader(), rr.KeyTag, rr.Algorithm, rr.DigestType, rr.Digest} -} -func (rr *TALINK) copy() RR { - return &TALINK{*rr.Hdr.copyHeader(), rr.PreviousName, rr.NextName} -} -func (rr *TKEY) copy() RR { - return &TKEY{*rr.Hdr.copyHeader(), rr.Algorithm, rr.Inception, rr.Expiration, rr.Mode, rr.Error, rr.KeySize, rr.Key, rr.OtherLen, rr.OtherData} -} -func (rr *TLSA) copy() RR { - return &TLSA{*rr.Hdr.copyHeader(), rr.Usage, rr.Selector, rr.MatchingType, rr.Certificate} -} -func (rr *TSIG) copy() RR { - return &TSIG{*rr.Hdr.copyHeader(), rr.Algorithm, rr.TimeSigned, rr.Fudge, rr.MACSize, rr.MAC, rr.OrigId, rr.Error, rr.OtherLen, rr.OtherData} -} -func (rr *TXT) copy() RR { - Txt := make([]string, len(rr.Txt)) - copy(Txt, rr.Txt) - return &TXT{*rr.Hdr.copyHeader(), Txt} -} -func (rr *UID) copy() RR { - return &UID{*rr.Hdr.copyHeader(), rr.Uid} -} -func (rr *UINFO) copy() RR { - return &UINFO{*rr.Hdr.copyHeader(), rr.Uinfo} -} -func (rr *URI) copy() RR { - return &URI{*rr.Hdr.copyHeader(), rr.Priority, rr.Weight, rr.Target} -} -func (rr *X25) copy() RR { - return &X25{*rr.Hdr.copyHeader(), rr.PSDNAddress} -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/.gitcookies.enc b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/.gitcookies.enc Binary files differdeleted file mode 100644 index 09c303c94..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/.gitcookies.enc +++ /dev/null diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/.gitignore b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/.gitignore deleted file mode 100644 index 74d32f0ab..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -lego.exe -lego -.lego -.idea diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/.travis.yml b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/.travis.yml deleted file mode 100644 index ff9ae963a..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/.travis.yml +++ /dev/null @@ -1,16 +0,0 @@ -language: go -go: -- 1.7 -- 1.8 -- tip -services: - - memcached -env: - - MEMCACHED_HOSTS=localhost:11211 -install: -- go get -t ./... -script: -- go vet ./... -- go test -v ./... -before_install: -- '[ "${TRAVIS_PULL_REQUEST}" = "false" ] && openssl aes-256-cbc -K $encrypted_26c593b079d9_key -iv $encrypted_26c593b079d9_iv -in .gitcookies.enc -out .gitcookies -d || true' diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/CHANGELOG.md b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/CHANGELOG.md deleted file mode 100644 index c43c4a936..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/CHANGELOG.md +++ /dev/null @@ -1,94 +0,0 @@ -# Changelog - -## [0.3.1] - 2016-04-19 - -### Added: -- lib: A new DNS provider for Vultr. - -### Fixed: -- lib: DNS Provider for DigitalOcean could not handle subdomains properly. -- lib: handleHTTPError should only try to JSON decode error messages with the right content type. -- lib: The propagation checker for the DNS challenge would not retry on send errors. - - -## [0.3.0] - 2016-03-19 - -### Added: -- CLI: The `--dns` switch. To include the DNS challenge for consideration. When using this switch, all other solvers are disabled. Supported are the following solvers: cloudflare, digitalocean, dnsimple, dyn, gandi, googlecloud, namecheap, route53, rfc2136 and manual. -- CLI: The `--accept-tos` switch. Indicates your acceptance of the Let's Encrypt terms of service without prompting you. -- CLI: The `--webroot` switch. The HTTP-01 challenge may now be completed by dropping a file into a webroot. When using this switch, all other solvers are disabled. -- CLI: The `--key-type` switch. This replaces the `--rsa-key-size` switch and supports the following key types: EC256, EC384, RSA2048, RSA4096 and RSA8192. -- CLI: The `--dnshelp` switch. This displays a more in-depth help topic for DNS solvers. -- CLI: The `--no-bundle` sub switch for the `run` and `renew` commands. When this switch is set, the CLI will not bundle the issuer certificate with your certificate. -- lib: A new type for challenge identifiers `Challenge` -- lib: A new interface for custom challenge providers `acme.ChallengeProvider` -- lib: A new interface for DNS-01 providers to allow for custom timeouts for the validation function `acme.ChallengeProviderTimeout` -- lib: SetChallengeProvider function. Pass a challenge identifier and a Provider to replace the default behaviour of a challenge. -- lib: The DNS-01 challenge has been implemented with modular solvers using the `ChallengeProvider` interface. Included solvers are: cloudflare, digitalocean, dnsimple, gandi, namecheap, route53, rfc2136 and manual. -- lib: The `acme.KeyType` type was added and is used for the configuration of crypto parameters for RSA and EC keys. Valid KeyTypes are: EC256, EC384, RSA2048, RSA4096 and RSA8192. - -### Changed -- lib: ExcludeChallenges now expects to be passed an array of `Challenge` types. -- lib: HTTP-01 now supports custom solvers using the `ChallengeProvider` interface. -- lib: TLS-SNI-01 now supports custom solvers using the `ChallengeProvider` interface. -- lib: The `GetPrivateKey` function in the `acme.User` interface is now expected to return a `crypto.PrivateKey` instead of an `rsa.PrivateKey` for EC compat. -- lib: The `acme.NewClient` function now expects an `acme.KeyType` instead of the keyBits parameter. - -### Removed -- CLI: The `rsa-key-size` switch was removed in favor of `key-type` to support EC keys. - -### Fixed -- lib: Fixed a race condition in HTTP-01 -- lib: Fixed an issue where status codes on ACME challenge responses could lead to no action being taken. -- lib: Fixed a regression when calling the Renew function with a SAN certificate. - -## [0.2.0] - 2016-01-09 - -### Added: -- CLI: The `--exclude` or `-x` switch. To exclude a challenge from being solved. -- CLI: The `--http` switch. To set the listen address and port of HTTP based challenges. Supports `host:port` and `:port` for any interface. -- CLI: The `--tls` switch. To set the listen address and port of TLS based challenges. Supports `host:port` and `:port` for any interface. -- CLI: The `--reuse-key` switch for the `renew` operation. This lets you reuse an existing private key for renewals. -- lib: ExcludeChallenges function. Pass an array of challenge identifiers to exclude them from solving. -- lib: SetHTTPAddress function. Pass a port to set the listen port for HTTP based challenges. -- lib: SetTLSAddress function. Pass a port to set the listen port of TLS based challenges. -- lib: acme.UserAgent variable. Use this to customize the user agent on all requests sent by lego. - -### Changed: -- lib: NewClient does no longer accept the optPort parameter -- lib: ObtainCertificate now returns a SAN certificate if you pass more then one domain. -- lib: GetOCSPForCert now returns the parsed OCSP response instead of just the status. -- lib: ObtainCertificate has a new parameter `privKey crypto.PrivateKey` which lets you reuse an existing private key for new certificates. -- lib: RenewCertificate now expects the PrivateKey property of the CertificateResource to be set only if you want to reuse the key. - -### Removed: -- CLI: The `--port` switch was removed. -- lib: RenewCertificate does no longer offer to also revoke your old certificate. - -### Fixed: -- CLI: Fix logic using the `--days` parameter for renew - -## [0.1.1] - 2015-12-18 - -### Added: -- CLI: Added a way to automate renewal through a cronjob using the --days parameter to renew - -### Changed: -- lib: Improved log output on challenge failures. - -### Fixed: -- CLI: The short parameter for domains would not get accepted -- CLI: The cli did not return proper exit codes on error library errors. -- lib: RenewCertificate did not properly renew SAN certificates. - -### Security -- lib: Fix possible DOS on GetOCSPForCert - -## [0.1.0] - 2015-12-03 -- Initial release - -[0.3.1]: https://github.com/xenolf/lego/compare/v0.3.0...v0.3.1 -[0.3.0]: https://github.com/xenolf/lego/compare/v0.2.0...v0.3.0 -[0.2.0]: https://github.com/xenolf/lego/compare/v0.1.1...v0.2.0 -[0.1.1]: https://github.com/xenolf/lego/compare/v0.1.0...v0.1.1 -[0.1.0]: https://github.com/xenolf/lego/tree/v0.1.0 diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/CONTRIBUTING.md b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/CONTRIBUTING.md deleted file mode 100644 index 9939a5ab3..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/CONTRIBUTING.md +++ /dev/null @@ -1,32 +0,0 @@ -# How to contribute to lego - -Contributions in the form of patches and proposals are essential to keep lego great and to make it even better. -To ensure a great and easy experience for everyone, please review the few guidelines in this document. - -## Bug reports - -- Use the issue search to see if the issue has already been reported. -- Also look for closed issues to see if your issue has already been fixed. -- If both of the above do not apply create a new issue and include as much information as possible. - -Bug reports should include all information a person could need to reproduce your problem without the need to -follow up for more information. If possible, provide detailed steps for us to reproduce it, the expected behaviour and the actual behaviour. - -## Feature proposals and requests - -Feature requests are welcome and should be discussed in an issue. -Please keep proposals focused on one thing at a time and be as detailed as possible. -It is up to you to make a strong point about your proposal and convince us of the merits and the added complexity of this feature. - -## Pull requests - -Patches, new features and improvements are a great way to help the project. -Please keep them focused on one thing and do not include unrelated commits. - -All pull requests which alter the behaviour of the program, add new behaviour or somehow alter code in a non-trivial way should **always** include tests. - -If you want to contribute a significant pull request (with a non-trivial workload for you) please **ask first**. We do not want you to spend -a lot of time on something the project's developers might not want to merge into the project. - -**IMPORTANT**: By submitting a patch, you agree to allow the project -owners to license your work under the terms of the [MIT License](LICENSE). diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/Dockerfile b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/Dockerfile deleted file mode 100644 index c03964076..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/Dockerfile +++ /dev/null @@ -1,14 +0,0 @@ -FROM alpine:3.4 - -ENV GOPATH /go - -RUN apk update && apk add ca-certificates go git && \ - rm -rf /var/cache/apk/* && \ - go get -u github.com/xenolf/lego && \ - cd /go/src/github.com/xenolf/lego && \ - go build -o /usr/bin/lego . && \ - apk del go git && \ - rm -rf /var/cache/apk/* && \ - rm -rf /go - -ENTRYPOINT [ "/usr/bin/lego" ] diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/LICENSE b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/LICENSE deleted file mode 100644 index 17460b716..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Sebastian Erhart - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/README.md b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/README.md deleted file mode 100644 index 5dc9d550d..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/README.md +++ /dev/null @@ -1,267 +0,0 @@ -# lego -Let's Encrypt client and ACME library written in Go - -[![GoDoc](https://godoc.org/github.com/xenolf/lego/acme?status.svg)](https://godoc.org/github.com/xenolf/lego/acme) -[![Build Status](https://travis-ci.org/xenolf/lego.svg?branch=master)](https://travis-ci.org/xenolf/lego) -[![Dev Chat](https://img.shields.io/badge/dev%20chat-gitter-blue.svg?label=dev+chat)](https://gitter.im/xenolf/lego) - -#### General -This is a work in progress. Please do *NOT* run this on a production server and please report any bugs you find! - -#### Installation -lego supports both binary installs and install from source. - -To get the binary just download the latest release for your OS/Arch from [the release page](https://github.com/xenolf/lego/releases) -and put the binary somewhere convenient. lego does not assume anything about the location you run it from. - -To install from source, just run -``` -go get -u github.com/xenolf/lego -``` - -To build lego inside a Docker container, just run -``` -docker build -t lego . -``` -##### From the package manager -- [ArchLinux (AUR)](https://aur.archlinux.org/packages/lego-git): -``` -yaourt -S lego-git -``` -#### Features - -- Register with CA -- Obtain certificates, both from scratch or with an existing CSR -- Renew certificates -- Revoke certificates -- Robust implementation of all ACME challenges - - HTTP (http-01) - - TLS with Server Name Indication (tls-sni-01) - - DNS (dns-01) -- SAN certificate support -- Comes with multiple optional [DNS providers](https://github.com/xenolf/lego/tree/master/providers/dns) -- [Custom challenge solvers](https://github.com/xenolf/lego/wiki/Writing-a-Challenge-Solver) -- Certificate bundling -- OCSP helper function - -Please keep in mind that CLI switches and APIs are still subject to change. - -When using the standard `--path` option, all certificates and account configurations are saved to a folder *.lego* in the current working directory. - -#### Sudo -The CLI does not require root permissions but needs to bind to port 80 and 443 for certain challenges. -To run the CLI without sudo, you have four options: - -- Use setcap 'cap_net_bind_service=+ep' /path/to/program -- Pass the `--http` or/and the `--tls` option and specify a custom port to bind to. In this case you have to forward port 80/443 to these custom ports (see [Port Usage](#port-usage)). -- Pass the `--webroot` option and specify the path to your webroot folder. In this case the challenge will be written in a file in `.well-known/acme-challenge/` inside your webroot. -- Pass the `--dns` option and specify a DNS provider. - -#### Port Usage -By default lego assumes it is able to bind to ports 80 and 443 to solve challenges. -If this is not possible in your environment, you can use the `--http` and `--tls` options to instruct -lego to listen on that interface:port for any incoming challenges. - -If you are using this option, make sure you proxy all of the following traffic to these ports. - -HTTP Port: -- All plaintext HTTP requests to port 80 which begin with a request path of `/.well-known/acme-challenge/` for the HTTP challenge. - -TLS Port: -- All TLS handshakes on port 443 for the TLS-SNI challenge. - -This traffic redirection is only needed as long as lego solves challenges. As soon as you have received your certificates you can deactivate the forwarding. - -#### Usage - -``` -NAME: - lego - Let's Encrypt client written in Go - -USAGE: - lego [global options] command [command options] [arguments...] - -VERSION: - 0.3.1 - -COMMANDS: - run Register an account, then create and install a certificate - revoke Revoke a certificate - renew Renew a certificate - dnshelp Shows additional help for the --dns global option - help, h Shows a list of commands or help for one command - -GLOBAL OPTIONS: - --domains, -d [--domains option --domains option] Add domains to the process - --csr, -c Certificate signing request filename, if an external CSR is to be used - --server, -s "https://acme-v01.api.letsencrypt.org/directory" CA hostname (and optionally :port). The server certificate must be trusted in order to avoid further modifications to the client. - --email, -m Email used for registration and recovery contact. - --accept-tos, -a By setting this flag to true you indicate that you accept the current Let's Encrypt terms of service. - --key-type, -k "rsa2048" Key type to use for private keys. Supported: rsa2048, rsa4096, rsa8192, ec256, ec384 - --path "${CWD}/.lego" Directory to use for storing the data - --exclude, -x [--exclude option --exclude option] Explicitly disallow solvers by name from being used. Solvers: "http-01", "tls-sni-01". - --webroot Set the webroot folder to use for HTTP based challenges to write directly in a file in .well-known/acme-challenge - --http Set the port and interface to use for HTTP based challenges to listen on. Supported: interface:port or :port - --tls Set the port and interface to use for TLS based challenges to listen on. Supported: interface:port or :port - --dns Solve a DNS challenge using the specified provider. Disables all other challenges. Run 'lego dnshelp' for help on usage. - --help, -h show help - --version, -v print the version -``` - -##### CLI Example - -Assumes the `lego` binary has permission to bind to ports 80 and 443. You can get a pre-built binary from the [releases](https://github.com/xenolf/lego/releases) page. -If your environment does not allow you to bind to these ports, please read [Port Usage](#port-usage). - -Obtain a certificate: - -```bash -$ lego --email="foo@bar.com" --domains="example.com" run -``` - -(Find your certificate in the `.lego` folder of current working directory.) - -To renew the certificate: - -```bash -$ lego --email="foo@bar.com" --domains="example.com" renew -``` - -To renew the certificate only if it's older than 30 days - -```bash -$ lego --email="foo@bar.com" --domains="example.com" renew --days 30 -``` - -Obtain a certificate using the DNS challenge and AWS Route 53: - -```bash -$ AWS_REGION=us-east-1 AWS_ACCESS_KEY_ID=my_id AWS_SECRET_ACCESS_KEY=my_key lego --email="foo@bar.com" --domains="example.com" --dns="route53" run -``` - -Note that `--dns=foo` implies `--exclude=http-01` and `--exclude=tls-sni-01`. lego will not attempt other challenges if you've told it to use DNS instead. - -Obtain a certificate given a certificate signing request (CSR) generated by something else: - -```bash -$ lego --email="foo@bar.com" --csr=/path/to/csr.pem run -``` - -(lego will infer the domains to be validated based on the contents of the CSR, so make sure the CSR's Common Name and optional SubjectAltNames are set correctly.) - -lego defaults to communicating with the production Let's Encrypt ACME server. If you'd like to test something without issuing real certificates, consider using the staging endpoint instead: - -```bash -$ lego --server=https://acme-staging.api.letsencrypt.org/directory … -``` - -#### DNS Challenge API Details - -##### AWS Route 53 - -The following AWS IAM policy document describes the permissions required for lego to complete the DNS challenge. -Replace `<INSERT_YOUR_HOSTED_ZONE_ID_HERE>` with the Route 53 zone ID of the domain you are authorizing. - -```json -{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "route53:GetChange", - "route53:ListHostedZonesByName" - ], - "Resource": [ - "*" - ] - }, - { - "Effect": "Allow", - "Action": [ - "route53:ChangeResourceRecordSets" - ], - "Resource": [ - "arn:aws:route53:::hostedzone/<INSERT_YOUR_HOSTED_ZONE_ID_HERE>" - ] - } - ] -} -``` - -#### ACME Library Usage - -A valid, but bare-bones example use of the acme package: - -```go -// You'll need a user or account type that implements acme.User -type MyUser struct { - Email string - Registration *acme.RegistrationResource - key crypto.PrivateKey -} -func (u MyUser) GetEmail() string { - return u.Email -} -func (u MyUser) GetRegistration() *acme.RegistrationResource { - return u.Registration -} -func (u MyUser) GetPrivateKey() crypto.PrivateKey { - return u.key -} - -// Create a user. New accounts need an email and private key to start. -const rsaKeySize = 2048 -privateKey, err := rsa.GenerateKey(rand.Reader, rsaKeySize) -if err != nil { - log.Fatal(err) -} -myUser := MyUser{ - Email: "you@yours.com", - key: privateKey, -} - -// A client facilitates communication with the CA server. This CA URL is -// configured for a local dev instance of Boulder running in Docker in a VM. -client, err := acme.NewClient("http://192.168.99.100:4000", &myUser, acme.RSA2048) -if err != nil { - log.Fatal(err) -} - -// We specify an http port of 5002 and an tls port of 5001 on all interfaces -// because we aren't running as root and can't bind a listener to port 80 and 443 -// (used later when we attempt to pass challenges). Keep in mind that we still -// need to proxy challenge traffic to port 5002 and 5001. -client.SetHTTPAddress(":5002") -client.SetTLSAddress(":5001") - -// New users will need to register -reg, err := client.Register() -if err != nil { - log.Fatal(err) -} -myUser.Registration = reg - -// SAVE THE USER. - -// The client has a URL to the current Let's Encrypt Subscriber -// Agreement. The user will need to agree to it. -err = client.AgreeToTOS() -if err != nil { - log.Fatal(err) -} - -// The acme library takes care of completing the challenges to obtain the certificate(s). -// The domains must resolve to this machine or you have to use the DNS challenge. -bundle := false -certificates, failures := client.ObtainCertificate([]string{"mydomain.com"}, bundle, nil, false) -if len(failures) > 0 { - log.Fatal(failures) -} - -// Each certificate comes back with the cert bytes, the bytes of the client's -// private key, and a certificate URL. SAVE THESE TO DISK. -fmt.Printf("%#v\n", certificates) - -// ... all done. -``` diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/challenges.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/challenges.go deleted file mode 100644 index 857900507..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/challenges.go +++ /dev/null @@ -1,16 +0,0 @@ -package acme - -// Challenge is a string that identifies a particular type and version of ACME challenge. -type Challenge string - -const ( - // HTTP01 is the "http-01" ACME challenge https://github.com/ietf-wg-acme/acme/blob/master/draft-ietf-acme-acme.md#http - // Note: HTTP01ChallengePath returns the URL path to fulfill this challenge - HTTP01 = Challenge("http-01") - // TLSSNI01 is the "tls-sni-01" ACME challenge https://github.com/ietf-wg-acme/acme/blob/master/draft-ietf-acme-acme.md#tls-with-server-name-indication-tls-sni - // Note: TLSSNI01ChallengeCert returns a certificate to fulfill this challenge - TLSSNI01 = Challenge("tls-sni-01") - // DNS01 is the "dns-01" ACME challenge https://github.com/ietf-wg-acme/acme/blob/master/draft-ietf-acme-acme.md#dns - // Note: DNS01Record returns a DNS record which will fulfill this challenge - DNS01 = Challenge("dns-01") -) diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/client.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/client.go deleted file mode 100644 index bcb844371..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/client.go +++ /dev/null @@ -1,825 +0,0 @@ -// Package acme implements the ACME protocol for Let's Encrypt and other conforming providers. -package acme - -import ( - "crypto" - "crypto/x509" - "encoding/base64" - "encoding/json" - "errors" - "fmt" - "io/ioutil" - "log" - "net" - "net/http" - "regexp" - "strconv" - "strings" - "time" -) - -var ( - // Logger is an optional custom logger. - Logger *log.Logger -) - -const ( - // maxBodySize is the maximum size of body that we will read. - maxBodySize = 1024 * 1024 - - // overallRequestLimit is the overall number of request per second limited on the - // “new-reg”, “new-authz” and “new-cert” endpoints. From the documentation the - // limitation is 20 requests per second, but using 20 as value doesn't work but 18 do - overallRequestLimit = 18 -) - -// logf writes a log entry. It uses Logger if not -// nil, otherwise it uses the default log.Logger. -func logf(format string, args ...interface{}) { - if Logger != nil { - Logger.Printf(format, args...) - } else { - log.Printf(format, args...) - } -} - -// User interface is to be implemented by users of this library. -// It is used by the client type to get user specific information. -type User interface { - GetEmail() string - GetRegistration() *RegistrationResource - GetPrivateKey() crypto.PrivateKey -} - -// Interface for all challenge solvers to implement. -type solver interface { - Solve(challenge challenge, domain string) error -} - -type validateFunc func(j *jws, domain, uri string, chlng challenge) error - -// Client is the user-friendy way to ACME -type Client struct { - directory directory - user User - jws *jws - keyType KeyType - solvers map[Challenge]solver -} - -// NewClient creates a new ACME client on behalf of the user. The client will depend on -// the ACME directory located at caDirURL for the rest of its actions. A private -// key of type keyType (see KeyType contants) will be generated when requesting a new -// certificate if one isn't provided. -func NewClient(caDirURL string, user User, keyType KeyType) (*Client, error) { - privKey := user.GetPrivateKey() - if privKey == nil { - return nil, errors.New("private key was nil") - } - - var dir directory - if _, err := getJSON(caDirURL, &dir); err != nil { - return nil, fmt.Errorf("get directory at '%s': %v", caDirURL, err) - } - - if dir.NewRegURL == "" { - return nil, errors.New("directory missing new registration URL") - } - if dir.NewAuthzURL == "" { - return nil, errors.New("directory missing new authz URL") - } - if dir.NewCertURL == "" { - return nil, errors.New("directory missing new certificate URL") - } - if dir.RevokeCertURL == "" { - return nil, errors.New("directory missing revoke certificate URL") - } - - jws := &jws{privKey: privKey, directoryURL: caDirURL} - - // REVIEW: best possibility? - // Add all available solvers with the right index as per ACME - // spec to this map. Otherwise they won`t be found. - solvers := make(map[Challenge]solver) - solvers[HTTP01] = &httpChallenge{jws: jws, validate: validate, provider: &HTTPProviderServer{}} - solvers[TLSSNI01] = &tlsSNIChallenge{jws: jws, validate: validate, provider: &TLSProviderServer{}} - - return &Client{directory: dir, user: user, jws: jws, keyType: keyType, solvers: solvers}, nil -} - -// SetChallengeProvider specifies a custom provider p that can solve the given challenge type. -func (c *Client) SetChallengeProvider(challenge Challenge, p ChallengeProvider) error { - switch challenge { - case HTTP01: - c.solvers[challenge] = &httpChallenge{jws: c.jws, validate: validate, provider: p} - case TLSSNI01: - c.solvers[challenge] = &tlsSNIChallenge{jws: c.jws, validate: validate, provider: p} - case DNS01: - c.solvers[challenge] = &dnsChallenge{jws: c.jws, validate: validate, provider: p} - default: - return fmt.Errorf("Unknown challenge %v", challenge) - } - return nil -} - -// SetHTTPAddress specifies a custom interface:port to be used for HTTP based challenges. -// If this option is not used, the default port 80 and all interfaces will be used. -// To only specify a port and no interface use the ":port" notation. -// -// NOTE: This REPLACES any custom HTTP provider previously set by calling -// c.SetChallengeProvider with the default HTTP challenge provider. -func (c *Client) SetHTTPAddress(iface string) error { - host, port, err := net.SplitHostPort(iface) - if err != nil { - return err - } - - if chlng, ok := c.solvers[HTTP01]; ok { - chlng.(*httpChallenge).provider = NewHTTPProviderServer(host, port) - } - - return nil -} - -// SetTLSAddress specifies a custom interface:port to be used for TLS based challenges. -// If this option is not used, the default port 443 and all interfaces will be used. -// To only specify a port and no interface use the ":port" notation. -// -// NOTE: This REPLACES any custom TLS-SNI provider previously set by calling -// c.SetChallengeProvider with the default TLS-SNI challenge provider. -func (c *Client) SetTLSAddress(iface string) error { - host, port, err := net.SplitHostPort(iface) - if err != nil { - return err - } - - if chlng, ok := c.solvers[TLSSNI01]; ok { - chlng.(*tlsSNIChallenge).provider = NewTLSProviderServer(host, port) - } - return nil -} - -// ExcludeChallenges explicitly removes challenges from the pool for solving. -func (c *Client) ExcludeChallenges(challenges []Challenge) { - // Loop through all challenges and delete the requested one if found. - for _, challenge := range challenges { - delete(c.solvers, challenge) - } -} - -// Register the current account to the ACME server. -func (c *Client) Register() (*RegistrationResource, error) { - if c == nil || c.user == nil { - return nil, errors.New("acme: cannot register a nil client or user") - } - logf("[INFO] acme: Registering account for %s", c.user.GetEmail()) - - regMsg := registrationMessage{ - Resource: "new-reg", - } - if c.user.GetEmail() != "" { - regMsg.Contact = []string{"mailto:" + c.user.GetEmail()} - } else { - regMsg.Contact = []string{} - } - - var serverReg Registration - var regURI string - hdr, err := postJSON(c.jws, c.directory.NewRegURL, regMsg, &serverReg) - if err != nil { - remoteErr, ok := err.(RemoteError) - if ok && remoteErr.StatusCode == 409 { - regURI = hdr.Get("Location") - regMsg = registrationMessage{ - Resource: "reg", - } - if hdr, err = postJSON(c.jws, regURI, regMsg, &serverReg); err != nil { - return nil, err - } - } else { - return nil, err - } - } - - reg := &RegistrationResource{Body: serverReg} - - links := parseLinks(hdr["Link"]) - - if regURI == "" { - regURI = hdr.Get("Location") - } - reg.URI = regURI - if links["terms-of-service"] != "" { - reg.TosURL = links["terms-of-service"] - } - - if links["next"] != "" { - reg.NewAuthzURL = links["next"] - } else { - return nil, errors.New("acme: The server did not return 'next' link to proceed") - } - - return reg, nil -} - -// DeleteRegistration deletes the client's user registration from the ACME -// server. -func (c *Client) DeleteRegistration() error { - if c == nil || c.user == nil { - return errors.New("acme: cannot unregister a nil client or user") - } - logf("[INFO] acme: Deleting account for %s", c.user.GetEmail()) - - regMsg := registrationMessage{ - Resource: "reg", - Delete: true, - } - - _, err := postJSON(c.jws, c.user.GetRegistration().URI, regMsg, nil) - if err != nil { - return err - } - - return nil -} - -// QueryRegistration runs a POST request on the client's registration and -// returns the result. -// -// This is similar to the Register function, but acting on an existing -// registration link and resource. -func (c *Client) QueryRegistration() (*RegistrationResource, error) { - if c == nil || c.user == nil { - return nil, errors.New("acme: cannot query the registration of a nil client or user") - } - // Log the URL here instead of the email as the email may not be set - logf("[INFO] acme: Querying account for %s", c.user.GetRegistration().URI) - - regMsg := registrationMessage{ - Resource: "reg", - } - - var serverReg Registration - hdr, err := postJSON(c.jws, c.user.GetRegistration().URI, regMsg, &serverReg) - if err != nil { - return nil, err - } - - reg := &RegistrationResource{Body: serverReg} - - links := parseLinks(hdr["Link"]) - // Location: header is not returned so this needs to be populated off of - // existing URI - reg.URI = c.user.GetRegistration().URI - if links["terms-of-service"] != "" { - reg.TosURL = links["terms-of-service"] - } - - if links["next"] != "" { - reg.NewAuthzURL = links["next"] - } else { - return nil, errors.New("acme: No new-authz link in response to registration query") - } - - return reg, nil -} - -// AgreeToTOS updates the Client registration and sends the agreement to -// the server. -func (c *Client) AgreeToTOS() error { - reg := c.user.GetRegistration() - - reg.Body.Agreement = c.user.GetRegistration().TosURL - reg.Body.Resource = "reg" - _, err := postJSON(c.jws, c.user.GetRegistration().URI, c.user.GetRegistration().Body, nil) - return err -} - -// ObtainCertificateForCSR tries to obtain a certificate matching the CSR passed into it. -// The domains are inferred from the CommonName and SubjectAltNames, if any. The private key -// for this CSR is not required. -// If bundle is true, the []byte contains both the issuer certificate and -// your issued certificate as a bundle. -// This function will never return a partial certificate. If one domain in the list fails, -// the whole certificate will fail. -func (c *Client) ObtainCertificateForCSR(csr x509.CertificateRequest, bundle bool) (CertificateResource, map[string]error) { - // figure out what domains it concerns - // start with the common name - domains := []string{csr.Subject.CommonName} - - // loop over the SubjectAltName DNS names -DNSNames: - for _, sanName := range csr.DNSNames { - for _, existingName := range domains { - if existingName == sanName { - // duplicate; skip this name - continue DNSNames - } - } - - // name is unique - domains = append(domains, sanName) - } - - if bundle { - logf("[INFO][%s] acme: Obtaining bundled SAN certificate given a CSR", strings.Join(domains, ", ")) - } else { - logf("[INFO][%s] acme: Obtaining SAN certificate given a CSR", strings.Join(domains, ", ")) - } - - challenges, failures := c.getChallenges(domains) - // If any challenge fails - return. Do not generate partial SAN certificates. - if len(failures) > 0 { - for _, auth := range challenges { - c.disableAuthz(auth) - } - - return CertificateResource{}, failures - } - - errs := c.solveChallenges(challenges) - // If any challenge fails - return. Do not generate partial SAN certificates. - if len(errs) > 0 { - return CertificateResource{}, errs - } - - logf("[INFO][%s] acme: Validations succeeded; requesting certificates", strings.Join(domains, ", ")) - - cert, err := c.requestCertificateForCsr(challenges, bundle, csr.Raw, nil) - if err != nil { - for _, chln := range challenges { - failures[chln.Domain] = err - } - } - - // Add the CSR to the certificate so that it can be used for renewals. - cert.CSR = pemEncode(&csr) - - return cert, failures -} - -// ObtainCertificate tries to obtain a single certificate using all domains passed into it. -// The first domain in domains is used for the CommonName field of the certificate, all other -// domains are added using the Subject Alternate Names extension. A new private key is generated -// for every invocation of this function. If you do not want that you can supply your own private key -// in the privKey parameter. If this parameter is non-nil it will be used instead of generating a new one. -// If bundle is true, the []byte contains both the issuer certificate and -// your issued certificate as a bundle. -// This function will never return a partial certificate. If one domain in the list fails, -// the whole certificate will fail. -func (c *Client) ObtainCertificate(domains []string, bundle bool, privKey crypto.PrivateKey, mustStaple bool) (CertificateResource, map[string]error) { - if bundle { - logf("[INFO][%s] acme: Obtaining bundled SAN certificate", strings.Join(domains, ", ")) - } else { - logf("[INFO][%s] acme: Obtaining SAN certificate", strings.Join(domains, ", ")) - } - - challenges, failures := c.getChallenges(domains) - // If any challenge fails - return. Do not generate partial SAN certificates. - if len(failures) > 0 { - for _, auth := range challenges { - c.disableAuthz(auth) - } - - return CertificateResource{}, failures - } - - errs := c.solveChallenges(challenges) - // If any challenge fails - return. Do not generate partial SAN certificates. - if len(errs) > 0 { - return CertificateResource{}, errs - } - - logf("[INFO][%s] acme: Validations succeeded; requesting certificates", strings.Join(domains, ", ")) - - cert, err := c.requestCertificate(challenges, bundle, privKey, mustStaple) - if err != nil { - for _, chln := range challenges { - failures[chln.Domain] = err - } - } - - return cert, failures -} - -// RevokeCertificate takes a PEM encoded certificate or bundle and tries to revoke it at the CA. -func (c *Client) RevokeCertificate(certificate []byte) error { - certificates, err := parsePEMBundle(certificate) - if err != nil { - return err - } - - x509Cert := certificates[0] - if x509Cert.IsCA { - return fmt.Errorf("Certificate bundle starts with a CA certificate") - } - - encodedCert := base64.URLEncoding.EncodeToString(x509Cert.Raw) - - _, err = postJSON(c.jws, c.directory.RevokeCertURL, revokeCertMessage{Resource: "revoke-cert", Certificate: encodedCert}, nil) - return err -} - -// RenewCertificate takes a CertificateResource and tries to renew the certificate. -// If the renewal process succeeds, the new certificate will ge returned in a new CertResource. -// Please be aware that this function will return a new certificate in ANY case that is not an error. -// If the server does not provide us with a new cert on a GET request to the CertURL -// this function will start a new-cert flow where a new certificate gets generated. -// If bundle is true, the []byte contains both the issuer certificate and -// your issued certificate as a bundle. -// For private key reuse the PrivateKey property of the passed in CertificateResource should be non-nil. -func (c *Client) RenewCertificate(cert CertificateResource, bundle, mustStaple bool) (CertificateResource, error) { - // Input certificate is PEM encoded. Decode it here as we may need the decoded - // cert later on in the renewal process. The input may be a bundle or a single certificate. - certificates, err := parsePEMBundle(cert.Certificate) - if err != nil { - return CertificateResource{}, err - } - - x509Cert := certificates[0] - if x509Cert.IsCA { - return CertificateResource{}, fmt.Errorf("[%s] Certificate bundle starts with a CA certificate", cert.Domain) - } - - // This is just meant to be informal for the user. - timeLeft := x509Cert.NotAfter.Sub(time.Now().UTC()) - logf("[INFO][%s] acme: Trying renewal with %d hours remaining", cert.Domain, int(timeLeft.Hours())) - - // We always need to request a new certificate to renew. - // Start by checking to see if the certificate was based off a CSR, and - // use that if it's defined. - if len(cert.CSR) > 0 { - csr, err := pemDecodeTox509CSR(cert.CSR) - if err != nil { - return CertificateResource{}, err - } - newCert, failures := c.ObtainCertificateForCSR(*csr, bundle) - return newCert, failures[cert.Domain] - } - - var privKey crypto.PrivateKey - if cert.PrivateKey != nil { - privKey, err = parsePEMPrivateKey(cert.PrivateKey) - if err != nil { - return CertificateResource{}, err - } - } - - var domains []string - var failures map[string]error - // check for SAN certificate - if len(x509Cert.DNSNames) > 1 { - domains = append(domains, x509Cert.Subject.CommonName) - for _, sanDomain := range x509Cert.DNSNames { - if sanDomain == x509Cert.Subject.CommonName { - continue - } - domains = append(domains, sanDomain) - } - } else { - domains = append(domains, x509Cert.Subject.CommonName) - } - - newCert, failures := c.ObtainCertificate(domains, bundle, privKey, mustStaple) - return newCert, failures[cert.Domain] -} - -// Looks through the challenge combinations to find a solvable match. -// Then solves the challenges in series and returns. -func (c *Client) solveChallenges(challenges []authorizationResource) map[string]error { - // loop through the resources, basically through the domains. - failures := make(map[string]error) - for _, authz := range challenges { - if authz.Body.Status == "valid" { - // Boulder might recycle recent validated authz (see issue #267) - logf("[INFO][%s] acme: Authorization already valid; skipping challenge", authz.Domain) - continue - } - // no solvers - no solving - if solvers := c.chooseSolvers(authz.Body, authz.Domain); solvers != nil { - for i, solver := range solvers { - // TODO: do not immediately fail if one domain fails to validate. - err := solver.Solve(authz.Body.Challenges[i], authz.Domain) - if err != nil { - c.disableAuthz(authz) - failures[authz.Domain] = err - } - } - } else { - c.disableAuthz(authz) - failures[authz.Domain] = fmt.Errorf("[%s] acme: Could not determine solvers", authz.Domain) - } - } - - return failures -} - -// Checks all combinations from the server and returns an array of -// solvers which should get executed in series. -func (c *Client) chooseSolvers(auth authorization, domain string) map[int]solver { - for _, combination := range auth.Combinations { - solvers := make(map[int]solver) - for _, idx := range combination { - if solver, ok := c.solvers[auth.Challenges[idx].Type]; ok { - solvers[idx] = solver - } else { - logf("[INFO][%s] acme: Could not find solver for: %s", domain, auth.Challenges[idx].Type) - } - } - - // If we can solve the whole combination, return the solvers - if len(solvers) == len(combination) { - return solvers - } - } - return nil -} - -// Get the challenges needed to proof our identifier to the ACME server. -func (c *Client) getChallenges(domains []string) ([]authorizationResource, map[string]error) { - resc, errc := make(chan authorizationResource), make(chan domainError) - - delay := time.Second / overallRequestLimit - - for _, domain := range domains { - time.Sleep(delay) - - go func(domain string) { - authMsg := authorization{Resource: "new-authz", Identifier: identifier{Type: "dns", Value: domain}} - var authz authorization - hdr, err := postJSON(c.jws, c.user.GetRegistration().NewAuthzURL, authMsg, &authz) - if err != nil { - errc <- domainError{Domain: domain, Error: err} - return - } - - links := parseLinks(hdr["Link"]) - if links["next"] == "" { - logf("[ERROR][%s] acme: Server did not provide next link to proceed", domain) - errc <- domainError{Domain: domain, Error: errors.New("Server did not provide next link to proceed")} - return - } - - resc <- authorizationResource{Body: authz, NewCertURL: links["next"], AuthURL: hdr.Get("Location"), Domain: domain} - }(domain) - } - - responses := make(map[string]authorizationResource) - failures := make(map[string]error) - for i := 0; i < len(domains); i++ { - select { - case res := <-resc: - responses[res.Domain] = res - case err := <-errc: - failures[err.Domain] = err.Error - } - } - - challenges := make([]authorizationResource, 0, len(responses)) - for _, domain := range domains { - if challenge, ok := responses[domain]; ok { - challenges = append(challenges, challenge) - } - } - - logAuthz(challenges) - - close(resc) - close(errc) - - return challenges, failures -} - -func logAuthz(authz []authorizationResource) { - for _, auth := range authz { - logf("[INFO][%s] AuthURL: %s", auth.Domain, auth.AuthURL) - } -} - -// cleanAuthz loops through the passed in slice and disables any auths which are not "valid" -func (c *Client) disableAuthz(auth authorizationResource) error { - var disabledAuth authorization - _, err := postJSON(c.jws, auth.AuthURL, deactivateAuthMessage{Resource: "authz", Status: "deactivated"}, &disabledAuth) - return err -} - -func (c *Client) requestCertificate(authz []authorizationResource, bundle bool, privKey crypto.PrivateKey, mustStaple bool) (CertificateResource, error) { - if len(authz) == 0 { - return CertificateResource{}, errors.New("Passed no authorizations to requestCertificate!") - } - - var err error - if privKey == nil { - privKey, err = generatePrivateKey(c.keyType) - if err != nil { - return CertificateResource{}, err - } - } - - // determine certificate name(s) based on the authorization resources - commonName := authz[0] - var san []string - for _, auth := range authz[1:] { - san = append(san, auth.Domain) - } - - // TODO: should the CSR be customizable? - csr, err := generateCsr(privKey, commonName.Domain, san, mustStaple) - if err != nil { - return CertificateResource{}, err - } - - return c.requestCertificateForCsr(authz, bundle, csr, pemEncode(privKey)) -} - -func (c *Client) requestCertificateForCsr(authz []authorizationResource, bundle bool, csr []byte, privateKeyPem []byte) (CertificateResource, error) { - commonName := authz[0] - - var authURLs []string - for _, auth := range authz[1:] { - authURLs = append(authURLs, auth.AuthURL) - } - - csrString := base64.URLEncoding.EncodeToString(csr) - jsonBytes, err := json.Marshal(csrMessage{Resource: "new-cert", Csr: csrString, Authorizations: authURLs}) - if err != nil { - return CertificateResource{}, err - } - - resp, err := c.jws.post(commonName.NewCertURL, jsonBytes) - if err != nil { - return CertificateResource{}, err - } - - certRes := CertificateResource{ - Domain: commonName.Domain, - CertURL: resp.Header.Get("Location"), - PrivateKey: privateKeyPem, - } - - maxChecks := 1000 - for i := 0; i < maxChecks; i++ { - done, err := c.checkCertResponse(resp, &certRes, bundle) - resp.Body.Close() - if err != nil { - return CertificateResource{}, err - } - if done { - break - } - if i == maxChecks-1 { - return CertificateResource{}, fmt.Errorf("polled for certificate %d times; giving up", i) - } - resp, err = httpGet(certRes.CertURL) - if err != nil { - return CertificateResource{}, err - } - } - - return certRes, nil -} - -// checkCertResponse checks resp to see if a certificate is contained in the -// response, and if so, loads it into certRes and returns true. If the cert -// is not yet ready, it returns false. This function honors the waiting period -// required by the Retry-After header of the response, if specified. This -// function may read from resp.Body but does NOT close it. The certRes input -// should already have the Domain (common name) field populated. If bundle is -// true, the certificate will be bundled with the issuer's cert. -func (c *Client) checkCertResponse(resp *http.Response, certRes *CertificateResource, bundle bool) (bool, error) { - switch resp.StatusCode { - case 201, 202: - cert, err := ioutil.ReadAll(limitReader(resp.Body, maxBodySize)) - if err != nil { - return false, err - } - - // The server returns a body with a length of zero if the - // certificate was not ready at the time this request completed. - // Otherwise the body is the certificate. - if len(cert) > 0 { - certRes.CertStableURL = resp.Header.Get("Content-Location") - certRes.AccountRef = c.user.GetRegistration().URI - - issuedCert := pemEncode(derCertificateBytes(cert)) - - // The issuer certificate link is always supplied via an "up" link - // in the response headers of a new certificate. - links := parseLinks(resp.Header["Link"]) - issuerCert, err := c.getIssuerCertificate(links["up"]) - if err != nil { - // If we fail to acquire the issuer cert, return the issued certificate - do not fail. - logf("[WARNING][%s] acme: Could not bundle issuer certificate: %v", certRes.Domain, err) - } else { - issuerCert = pemEncode(derCertificateBytes(issuerCert)) - - // If bundle is true, we want to return a certificate bundle. - // To do this, we append the issuer cert to the issued cert. - if bundle { - issuedCert = append(issuedCert, issuerCert...) - } - } - - certRes.Certificate = issuedCert - certRes.IssuerCertificate = issuerCert - logf("[INFO][%s] Server responded with a certificate.", certRes.Domain) - return true, nil - } - - // The certificate was granted but is not yet issued. - // Check retry-after and loop. - ra := resp.Header.Get("Retry-After") - retryAfter, err := strconv.Atoi(ra) - if err != nil { - return false, err - } - - logf("[INFO][%s] acme: Server responded with status 202; retrying after %ds", certRes.Domain, retryAfter) - time.Sleep(time.Duration(retryAfter) * time.Second) - - return false, nil - default: - return false, handleHTTPError(resp) - } -} - -// getIssuerCertificate requests the issuer certificate -func (c *Client) getIssuerCertificate(url string) ([]byte, error) { - logf("[INFO] acme: Requesting issuer cert from %s", url) - resp, err := httpGet(url) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - issuerBytes, err := ioutil.ReadAll(limitReader(resp.Body, maxBodySize)) - if err != nil { - return nil, err - } - - _, err = x509.ParseCertificate(issuerBytes) - if err != nil { - return nil, err - } - - return issuerBytes, err -} - -func parseLinks(links []string) map[string]string { - aBrkt := regexp.MustCompile("[<>]") - slver := regexp.MustCompile("(.+) *= *\"(.+)\"") - linkMap := make(map[string]string) - - for _, link := range links { - - link = aBrkt.ReplaceAllString(link, "") - parts := strings.Split(link, ";") - - matches := slver.FindStringSubmatch(parts[1]) - if len(matches) > 0 { - linkMap[matches[2]] = parts[0] - } - } - - return linkMap -} - -// validate makes the ACME server start validating a -// challenge response, only returning once it is done. -func validate(j *jws, domain, uri string, chlng challenge) error { - var challengeResponse challenge - - hdr, err := postJSON(j, uri, chlng, &challengeResponse) - if err != nil { - return err - } - - // After the path is sent, the ACME server will access our server. - // Repeatedly check the server for an updated status on our request. - for { - switch challengeResponse.Status { - case "valid": - logf("[INFO][%s] The server validated our request", domain) - return nil - case "pending": - break - case "invalid": - return handleChallengeError(challengeResponse) - default: - return errors.New("The server returned an unexpected state.") - } - - ra, err := strconv.Atoi(hdr.Get("Retry-After")) - if err != nil { - // The ACME server MUST return a Retry-After. - // If it doesn't, we'll just poll hard. - ra = 1 - } - time.Sleep(time.Duration(ra) * time.Second) - - hdr, err = getJSON(uri, &challengeResponse) - if err != nil { - return err - } - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/client_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/client_test.go deleted file mode 100644 index b18334c8a..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/client_test.go +++ /dev/null @@ -1,269 +0,0 @@ -package acme - -import ( - "crypto" - "crypto/rand" - "crypto/rsa" - "encoding/json" - "net" - "net/http" - "net/http/httptest" - "strings" - "testing" - "time" -) - -func TestNewClient(t *testing.T) { - keyBits := 32 // small value keeps test fast - keyType := RSA2048 - key, err := rsa.GenerateKey(rand.Reader, keyBits) - if err != nil { - t.Fatal("Could not generate test key:", err) - } - user := mockUser{ - email: "test@test.com", - regres: new(RegistrationResource), - privatekey: key, - } - - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - data, _ := json.Marshal(directory{NewAuthzURL: "http://test", NewCertURL: "http://test", NewRegURL: "http://test", RevokeCertURL: "http://test"}) - w.Write(data) - })) - - client, err := NewClient(ts.URL, user, keyType) - if err != nil { - t.Fatalf("Could not create client: %v", err) - } - - if client.jws == nil { - t.Fatalf("Expected client.jws to not be nil") - } - if expected, actual := key, client.jws.privKey; actual != expected { - t.Errorf("Expected jws.privKey to be %p but was %p", expected, actual) - } - - if client.keyType != keyType { - t.Errorf("Expected keyType to be %s but was %s", keyType, client.keyType) - } - - if expected, actual := 2, len(client.solvers); actual != expected { - t.Fatalf("Expected %d solver(s), got %d", expected, actual) - } -} - -func TestClientOptPort(t *testing.T) { - keyBits := 32 // small value keeps test fast - key, err := rsa.GenerateKey(rand.Reader, keyBits) - if err != nil { - t.Fatal("Could not generate test key:", err) - } - user := mockUser{ - email: "test@test.com", - regres: new(RegistrationResource), - privatekey: key, - } - - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - data, _ := json.Marshal(directory{NewAuthzURL: "http://test", NewCertURL: "http://test", NewRegURL: "http://test", RevokeCertURL: "http://test"}) - w.Write(data) - })) - - optPort := "1234" - optHost := "" - client, err := NewClient(ts.URL, user, RSA2048) - if err != nil { - t.Fatalf("Could not create client: %v", err) - } - client.SetHTTPAddress(net.JoinHostPort(optHost, optPort)) - client.SetTLSAddress(net.JoinHostPort(optHost, optPort)) - - httpSolver, ok := client.solvers[HTTP01].(*httpChallenge) - if !ok { - t.Fatal("Expected http-01 solver to be httpChallenge type") - } - if httpSolver.jws != client.jws { - t.Error("Expected http-01 to have same jws as client") - } - if got := httpSolver.provider.(*HTTPProviderServer).port; got != optPort { - t.Errorf("Expected http-01 to have port %s but was %s", optPort, got) - } - if got := httpSolver.provider.(*HTTPProviderServer).iface; got != optHost { - t.Errorf("Expected http-01 to have iface %s but was %s", optHost, got) - } - - httpsSolver, ok := client.solvers[TLSSNI01].(*tlsSNIChallenge) - if !ok { - t.Fatal("Expected tls-sni-01 solver to be httpChallenge type") - } - if httpsSolver.jws != client.jws { - t.Error("Expected tls-sni-01 to have same jws as client") - } - if got := httpsSolver.provider.(*TLSProviderServer).port; got != optPort { - t.Errorf("Expected tls-sni-01 to have port %s but was %s", optPort, got) - } - if got := httpsSolver.provider.(*TLSProviderServer).iface; got != optHost { - t.Errorf("Expected tls-sni-01 to have port %s but was %s", optHost, got) - } - - // test setting different host - optHost = "127.0.0.1" - client.SetHTTPAddress(net.JoinHostPort(optHost, optPort)) - client.SetTLSAddress(net.JoinHostPort(optHost, optPort)) - - if got := httpSolver.provider.(*HTTPProviderServer).iface; got != optHost { - t.Errorf("Expected http-01 to have iface %s but was %s", optHost, got) - } - if got := httpsSolver.provider.(*TLSProviderServer).port; got != optPort { - t.Errorf("Expected tls-sni-01 to have port %s but was %s", optPort, got) - } -} - -func TestNotHoldingLockWhileMakingHTTPRequests(t *testing.T) { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - time.Sleep(250 * time.Millisecond) - w.Header().Add("Replay-Nonce", "12345") - w.Header().Add("Retry-After", "0") - writeJSONResponse(w, &challenge{Type: "http-01", Status: "Valid", URI: "http://example.com/", Token: "token"}) - })) - defer ts.Close() - - privKey, _ := rsa.GenerateKey(rand.Reader, 512) - j := &jws{privKey: privKey, directoryURL: ts.URL} - ch := make(chan bool) - resultCh := make(chan bool) - go func() { - j.Nonce() - ch <- true - }() - go func() { - j.Nonce() - ch <- true - }() - go func() { - <-ch - <-ch - resultCh <- true - }() - select { - case <-resultCh: - case <-time.After(400 * time.Millisecond): - t.Fatal("JWS is probably holding a lock while making HTTP request") - } -} - -func TestValidate(t *testing.T) { - var statuses []string - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // Minimal stub ACME server for validation. - w.Header().Add("Replay-Nonce", "12345") - w.Header().Add("Retry-After", "0") - switch r.Method { - case "HEAD": - case "POST": - st := statuses[0] - statuses = statuses[1:] - writeJSONResponse(w, &challenge{Type: "http-01", Status: st, URI: "http://example.com/", Token: "token"}) - - case "GET": - st := statuses[0] - statuses = statuses[1:] - writeJSONResponse(w, &challenge{Type: "http-01", Status: st, URI: "http://example.com/", Token: "token"}) - - default: - http.Error(w, r.Method, http.StatusMethodNotAllowed) - } - })) - defer ts.Close() - - privKey, _ := rsa.GenerateKey(rand.Reader, 512) - j := &jws{privKey: privKey, directoryURL: ts.URL} - - tsts := []struct { - name string - statuses []string - want string - }{ - {"POST-unexpected", []string{"weird"}, "unexpected"}, - {"POST-valid", []string{"valid"}, ""}, - {"POST-invalid", []string{"invalid"}, "Error Detail"}, - {"GET-unexpected", []string{"pending", "weird"}, "unexpected"}, - {"GET-valid", []string{"pending", "valid"}, ""}, - {"GET-invalid", []string{"pending", "invalid"}, "Error Detail"}, - } - - for _, tst := range tsts { - statuses = tst.statuses - if err := validate(j, "example.com", ts.URL, challenge{Type: "http-01", Token: "token"}); err == nil && tst.want != "" { - t.Errorf("[%s] validate: got error %v, want something with %q", tst.name, err, tst.want) - } else if err != nil && !strings.Contains(err.Error(), tst.want) { - t.Errorf("[%s] validate: got error %v, want something with %q", tst.name, err, tst.want) - } - } -} - -func TestGetChallenges(t *testing.T) { - var ts *httptest.Server - ts = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - switch r.Method { - case "GET", "HEAD": - w.Header().Add("Replay-Nonce", "12345") - w.Header().Add("Retry-After", "0") - writeJSONResponse(w, directory{NewAuthzURL: ts.URL, NewCertURL: ts.URL, NewRegURL: ts.URL, RevokeCertURL: ts.URL}) - case "POST": - writeJSONResponse(w, authorization{}) - } - })) - defer ts.Close() - - keyBits := 512 // small value keeps test fast - keyType := RSA2048 - key, err := rsa.GenerateKey(rand.Reader, keyBits) - if err != nil { - t.Fatal("Could not generate test key:", err) - } - user := mockUser{ - email: "test@test.com", - regres: &RegistrationResource{NewAuthzURL: ts.URL}, - privatekey: key, - } - - client, err := NewClient(ts.URL, user, keyType) - if err != nil { - t.Fatalf("Could not create client: %v", err) - } - - _, failures := client.getChallenges([]string{"example.com"}) - if failures["example.com"] == nil { - t.Fatal("Expecting \"Server did not provide next link to proceed\" error, got nil") - } -} - -// writeJSONResponse marshals the body as JSON and writes it to the response. -func writeJSONResponse(w http.ResponseWriter, body interface{}) { - bs, err := json.Marshal(body) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - w.Header().Set("Content-Type", "application/json") - if _, err := w.Write(bs); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - } -} - -// stubValidate is like validate, except it does nothing. -func stubValidate(j *jws, domain, uri string, chlng challenge) error { - return nil -} - -type mockUser struct { - email string - regres *RegistrationResource - privatekey *rsa.PrivateKey -} - -func (u mockUser) GetEmail() string { return u.email } -func (u mockUser) GetRegistration() *RegistrationResource { return u.regres } -func (u mockUser) GetPrivateKey() crypto.PrivateKey { return u.privatekey } diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/crypto.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/crypto.go deleted file mode 100644 index fa868a90d..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/crypto.go +++ /dev/null @@ -1,347 +0,0 @@ -package acme - -import ( - "bytes" - "crypto" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "crypto/rsa" - "crypto/x509" - "crypto/x509/pkix" - "encoding/base64" - "encoding/pem" - "errors" - "fmt" - "io" - "io/ioutil" - "math/big" - "net/http" - "strings" - "time" - - "encoding/asn1" - - "golang.org/x/crypto/ocsp" -) - -// KeyType represents the key algo as well as the key size or curve to use. -type KeyType string -type derCertificateBytes []byte - -// Constants for all key types we support. -const ( - EC256 = KeyType("P256") - EC384 = KeyType("P384") - RSA2048 = KeyType("2048") - RSA4096 = KeyType("4096") - RSA8192 = KeyType("8192") -) - -const ( - // OCSPGood means that the certificate is valid. - OCSPGood = ocsp.Good - // OCSPRevoked means that the certificate has been deliberately revoked. - OCSPRevoked = ocsp.Revoked - // OCSPUnknown means that the OCSP responder doesn't know about the certificate. - OCSPUnknown = ocsp.Unknown - // OCSPServerFailed means that the OCSP responder failed to process the request. - OCSPServerFailed = ocsp.ServerFailed -) - -// Constants for OCSP must staple -var ( - tlsFeatureExtensionOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 24} - ocspMustStapleFeature = []byte{0x30, 0x03, 0x02, 0x01, 0x05} -) - -// GetOCSPForCert takes a PEM encoded cert or cert bundle returning the raw OCSP response, -// the parsed response, and an error, if any. The returned []byte can be passed directly -// into the OCSPStaple property of a tls.Certificate. If the bundle only contains the -// issued certificate, this function will try to get the issuer certificate from the -// IssuingCertificateURL in the certificate. If the []byte and/or ocsp.Response return -// values are nil, the OCSP status may be assumed OCSPUnknown. -func GetOCSPForCert(bundle []byte) ([]byte, *ocsp.Response, error) { - certificates, err := parsePEMBundle(bundle) - if err != nil { - return nil, nil, err - } - - // We expect the certificate slice to be ordered downwards the chain. - // SRV CRT -> CA. We need to pull the leaf and issuer certs out of it, - // which should always be the first two certificates. If there's no - // OCSP server listed in the leaf cert, there's nothing to do. And if - // we have only one certificate so far, we need to get the issuer cert. - issuedCert := certificates[0] - if len(issuedCert.OCSPServer) == 0 { - return nil, nil, errors.New("no OCSP server specified in cert") - } - if len(certificates) == 1 { - // TODO: build fallback. If this fails, check the remaining array entries. - if len(issuedCert.IssuingCertificateURL) == 0 { - return nil, nil, errors.New("no issuing certificate URL") - } - - resp, err := httpGet(issuedCert.IssuingCertificateURL[0]) - if err != nil { - return nil, nil, err - } - defer resp.Body.Close() - - issuerBytes, err := ioutil.ReadAll(limitReader(resp.Body, 1024*1024)) - if err != nil { - return nil, nil, err - } - - issuerCert, err := x509.ParseCertificate(issuerBytes) - if err != nil { - return nil, nil, err - } - - // Insert it into the slice on position 0 - // We want it ordered right SRV CRT -> CA - certificates = append(certificates, issuerCert) - } - issuerCert := certificates[1] - - // Finally kick off the OCSP request. - ocspReq, err := ocsp.CreateRequest(issuedCert, issuerCert, nil) - if err != nil { - return nil, nil, err - } - - reader := bytes.NewReader(ocspReq) - req, err := httpPost(issuedCert.OCSPServer[0], "application/ocsp-request", reader) - if err != nil { - return nil, nil, err - } - defer req.Body.Close() - - ocspResBytes, err := ioutil.ReadAll(limitReader(req.Body, 1024*1024)) - ocspRes, err := ocsp.ParseResponse(ocspResBytes, issuerCert) - if err != nil { - return nil, nil, err - } - - return ocspResBytes, ocspRes, nil -} - -func getKeyAuthorization(token string, key interface{}) (string, error) { - var publicKey crypto.PublicKey - switch k := key.(type) { - case *ecdsa.PrivateKey: - publicKey = k.Public() - case *rsa.PrivateKey: - publicKey = k.Public() - } - - // Generate the Key Authorization for the challenge - jwk := keyAsJWK(publicKey) - if jwk == nil { - return "", errors.New("Could not generate JWK from key.") - } - thumbBytes, err := jwk.Thumbprint(crypto.SHA256) - if err != nil { - return "", err - } - - // unpad the base64URL - keyThumb := base64.URLEncoding.EncodeToString(thumbBytes) - index := strings.Index(keyThumb, "=") - if index != -1 { - keyThumb = keyThumb[:index] - } - - return token + "." + keyThumb, nil -} - -// parsePEMBundle parses a certificate bundle from top to bottom and returns -// a slice of x509 certificates. This function will error if no certificates are found. -func parsePEMBundle(bundle []byte) ([]*x509.Certificate, error) { - var certificates []*x509.Certificate - var certDERBlock *pem.Block - - for { - certDERBlock, bundle = pem.Decode(bundle) - if certDERBlock == nil { - break - } - - if certDERBlock.Type == "CERTIFICATE" { - cert, err := x509.ParseCertificate(certDERBlock.Bytes) - if err != nil { - return nil, err - } - certificates = append(certificates, cert) - } - } - - if len(certificates) == 0 { - return nil, errors.New("No certificates were found while parsing the bundle.") - } - - return certificates, nil -} - -func parsePEMPrivateKey(key []byte) (crypto.PrivateKey, error) { - keyBlock, _ := pem.Decode(key) - - switch keyBlock.Type { - case "RSA PRIVATE KEY": - return x509.ParsePKCS1PrivateKey(keyBlock.Bytes) - case "EC PRIVATE KEY": - return x509.ParseECPrivateKey(keyBlock.Bytes) - default: - return nil, errors.New("Unknown PEM header value") - } -} - -func generatePrivateKey(keyType KeyType) (crypto.PrivateKey, error) { - - switch keyType { - case EC256: - return ecdsa.GenerateKey(elliptic.P256(), rand.Reader) - case EC384: - return ecdsa.GenerateKey(elliptic.P384(), rand.Reader) - case RSA2048: - return rsa.GenerateKey(rand.Reader, 2048) - case RSA4096: - return rsa.GenerateKey(rand.Reader, 4096) - case RSA8192: - return rsa.GenerateKey(rand.Reader, 8192) - } - - return nil, fmt.Errorf("Invalid KeyType: %s", keyType) -} - -func generateCsr(privateKey crypto.PrivateKey, domain string, san []string, mustStaple bool) ([]byte, error) { - template := x509.CertificateRequest{ - Subject: pkix.Name{ - CommonName: domain, - }, - } - - if len(san) > 0 { - template.DNSNames = san - } - - if mustStaple { - template.ExtraExtensions = append(template.ExtraExtensions, pkix.Extension{ - Id: tlsFeatureExtensionOID, - Value: ocspMustStapleFeature, - }) - } - - return x509.CreateCertificateRequest(rand.Reader, &template, privateKey) -} - -func pemEncode(data interface{}) []byte { - var pemBlock *pem.Block - switch key := data.(type) { - case *ecdsa.PrivateKey: - keyBytes, _ := x509.MarshalECPrivateKey(key) - pemBlock = &pem.Block{Type: "EC PRIVATE KEY", Bytes: keyBytes} - case *rsa.PrivateKey: - pemBlock = &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key)} - break - case *x509.CertificateRequest: - pemBlock = &pem.Block{Type: "CERTIFICATE REQUEST", Bytes: key.Raw} - break - case derCertificateBytes: - pemBlock = &pem.Block{Type: "CERTIFICATE", Bytes: []byte(data.(derCertificateBytes))} - } - - return pem.EncodeToMemory(pemBlock) -} - -func pemDecode(data []byte) (*pem.Block, error) { - pemBlock, _ := pem.Decode(data) - if pemBlock == nil { - return nil, fmt.Errorf("Pem decode did not yield a valid block. Is the certificate in the right format?") - } - - return pemBlock, nil -} - -func pemDecodeTox509(pem []byte) (*x509.Certificate, error) { - pemBlock, err := pemDecode(pem) - if pemBlock == nil { - return nil, err - } - - return x509.ParseCertificate(pemBlock.Bytes) -} - -func pemDecodeTox509CSR(pem []byte) (*x509.CertificateRequest, error) { - pemBlock, err := pemDecode(pem) - if pemBlock == nil { - return nil, err - } - - if pemBlock.Type != "CERTIFICATE REQUEST" { - return nil, fmt.Errorf("PEM block is not a certificate request") - } - - return x509.ParseCertificateRequest(pemBlock.Bytes) -} - -// GetPEMCertExpiration returns the "NotAfter" date of a PEM encoded certificate. -// The certificate has to be PEM encoded. Any other encodings like DER will fail. -func GetPEMCertExpiration(cert []byte) (time.Time, error) { - pemBlock, err := pemDecode(cert) - if pemBlock == nil { - return time.Time{}, err - } - - return getCertExpiration(pemBlock.Bytes) -} - -// getCertExpiration returns the "NotAfter" date of a DER encoded certificate. -func getCertExpiration(cert []byte) (time.Time, error) { - pCert, err := x509.ParseCertificate(cert) - if err != nil { - return time.Time{}, err - } - - return pCert.NotAfter, nil -} - -func generatePemCert(privKey *rsa.PrivateKey, domain string) ([]byte, error) { - derBytes, err := generateDerCert(privKey, time.Time{}, domain) - if err != nil { - return nil, err - } - - return pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes}), nil -} - -func generateDerCert(privKey *rsa.PrivateKey, expiration time.Time, domain string) ([]byte, error) { - serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) - serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) - if err != nil { - return nil, err - } - - if expiration.IsZero() { - expiration = time.Now().Add(365) - } - - template := x509.Certificate{ - SerialNumber: serialNumber, - Subject: pkix.Name{ - CommonName: "ACME Challenge TEMP", - }, - NotBefore: time.Now(), - NotAfter: expiration, - - KeyUsage: x509.KeyUsageKeyEncipherment, - BasicConstraintsValid: true, - DNSNames: []string{domain}, - } - - return x509.CreateCertificate(rand.Reader, &template, &template, &privKey.PublicKey, privKey) -} - -func limitReader(rd io.ReadCloser, numBytes int64) io.ReadCloser { - return http.MaxBytesReader(nil, rd, numBytes) -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/crypto_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/crypto_test.go deleted file mode 100644 index 6f43835fb..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/crypto_test.go +++ /dev/null @@ -1,93 +0,0 @@ -package acme - -import ( - "bytes" - "crypto/rand" - "crypto/rsa" - "testing" - "time" -) - -func TestGeneratePrivateKey(t *testing.T) { - key, err := generatePrivateKey(RSA2048) - if err != nil { - t.Error("Error generating private key:", err) - } - if key == nil { - t.Error("Expected key to not be nil, but it was") - } -} - -func TestGenerateCSR(t *testing.T) { - key, err := rsa.GenerateKey(rand.Reader, 512) - if err != nil { - t.Fatal("Error generating private key:", err) - } - - csr, err := generateCsr(key, "fizz.buzz", nil, true) - if err != nil { - t.Error("Error generating CSR:", err) - } - if csr == nil || len(csr) == 0 { - t.Error("Expected CSR with data, but it was nil or length 0") - } -} - -func TestPEMEncode(t *testing.T) { - buf := bytes.NewBufferString("TestingRSAIsSoMuchFun") - - reader := MockRandReader{b: buf} - key, err := rsa.GenerateKey(reader, 32) - if err != nil { - t.Fatal("Error generating private key:", err) - } - - data := pemEncode(key) - - if data == nil { - t.Fatal("Expected result to not be nil, but it was") - } - if len(data) != 127 { - t.Errorf("Expected PEM encoding to be length 127, but it was %d", len(data)) - } -} - -func TestPEMCertExpiration(t *testing.T) { - privKey, err := generatePrivateKey(RSA2048) - if err != nil { - t.Fatal("Error generating private key:", err) - } - - expiration := time.Now().Add(365) - expiration = expiration.Round(time.Second) - certBytes, err := generateDerCert(privKey.(*rsa.PrivateKey), expiration, "test.com") - if err != nil { - t.Fatal("Error generating cert:", err) - } - - buf := bytes.NewBufferString("TestingRSAIsSoMuchFun") - - // Some random string should return an error. - if ctime, err := GetPEMCertExpiration(buf.Bytes()); err == nil { - t.Errorf("Expected getCertExpiration to return an error for garbage string but returned %v", ctime) - } - - // A DER encoded certificate should return an error. - if _, err := GetPEMCertExpiration(certBytes); err == nil { - t.Errorf("Expected getCertExpiration to return an error for DER certificates but returned none.") - } - - // A PEM encoded certificate should work ok. - pemCert := pemEncode(derCertificateBytes(certBytes)) - if ctime, err := GetPEMCertExpiration(pemCert); err != nil || !ctime.Equal(expiration.UTC()) { - t.Errorf("Expected getCertExpiration to return %v but returned %v. Error: %v", expiration, ctime, err) - } -} - -type MockRandReader struct { - b *bytes.Buffer -} - -func (r MockRandReader) Read(p []byte) (int, error) { - return r.b.Read(p) -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/dns_challenge.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/dns_challenge.go deleted file mode 100644 index 30f2170ff..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/dns_challenge.go +++ /dev/null @@ -1,305 +0,0 @@ -package acme - -import ( - "crypto/sha256" - "encoding/base64" - "errors" - "fmt" - "log" - "net" - "strings" - "time" - - "github.com/miekg/dns" - "golang.org/x/net/publicsuffix" -) - -type preCheckDNSFunc func(fqdn, value string) (bool, error) - -var ( - // PreCheckDNS checks DNS propagation before notifying ACME that - // the DNS challenge is ready. - PreCheckDNS preCheckDNSFunc = checkDNSPropagation - fqdnToZone = map[string]string{} -) - -const defaultResolvConf = "/etc/resolv.conf" - -var defaultNameservers = []string{ - "google-public-dns-a.google.com:53", - "google-public-dns-b.google.com:53", -} - -var RecursiveNameservers = getNameservers(defaultResolvConf, defaultNameservers) - -// DNSTimeout is used to override the default DNS timeout of 10 seconds. -var DNSTimeout = 10 * time.Second - -// getNameservers attempts to get systems nameservers before falling back to the defaults -func getNameservers(path string, defaults []string) []string { - config, err := dns.ClientConfigFromFile(path) - if err != nil || len(config.Servers) == 0 { - return defaults - } - - systemNameservers := []string{} - for _, server := range config.Servers { - // ensure all servers have a port number - if _, _, err := net.SplitHostPort(server); err != nil { - systemNameservers = append(systemNameservers, net.JoinHostPort(server, "53")) - } else { - systemNameservers = append(systemNameservers, server) - } - } - return systemNameservers -} - -// DNS01Record returns a DNS record which will fulfill the `dns-01` challenge -func DNS01Record(domain, keyAuth string) (fqdn string, value string, ttl int) { - keyAuthShaBytes := sha256.Sum256([]byte(keyAuth)) - // base64URL encoding without padding - keyAuthSha := base64.URLEncoding.EncodeToString(keyAuthShaBytes[:sha256.Size]) - value = strings.TrimRight(keyAuthSha, "=") - ttl = 120 - fqdn = fmt.Sprintf("_acme-challenge.%s.", domain) - return -} - -// dnsChallenge implements the dns-01 challenge according to ACME 7.5 -type dnsChallenge struct { - jws *jws - validate validateFunc - provider ChallengeProvider -} - -func (s *dnsChallenge) Solve(chlng challenge, domain string) error { - logf("[INFO][%s] acme: Trying to solve DNS-01", domain) - - if s.provider == nil { - return errors.New("No DNS Provider configured") - } - - // Generate the Key Authorization for the challenge - keyAuth, err := getKeyAuthorization(chlng.Token, s.jws.privKey) - if err != nil { - return err - } - - err = s.provider.Present(domain, chlng.Token, keyAuth) - if err != nil { - return fmt.Errorf("Error presenting token: %s", err) - } - defer func() { - err := s.provider.CleanUp(domain, chlng.Token, keyAuth) - if err != nil { - log.Printf("Error cleaning up %s: %v ", domain, err) - } - }() - - fqdn, value, _ := DNS01Record(domain, keyAuth) - - logf("[INFO][%s] Checking DNS record propagation using %+v", domain, RecursiveNameservers) - - var timeout, interval time.Duration - switch provider := s.provider.(type) { - case ChallengeProviderTimeout: - timeout, interval = provider.Timeout() - default: - timeout, interval = 60*time.Second, 2*time.Second - } - - err = WaitFor(timeout, interval, func() (bool, error) { - return PreCheckDNS(fqdn, value) - }) - if err != nil { - return err - } - - return s.validate(s.jws, domain, chlng.URI, challenge{Resource: "challenge", Type: chlng.Type, Token: chlng.Token, KeyAuthorization: keyAuth}) -} - -// checkDNSPropagation checks if the expected TXT record has been propagated to all authoritative nameservers. -func checkDNSPropagation(fqdn, value string) (bool, error) { - // Initial attempt to resolve at the recursive NS - r, err := dnsQuery(fqdn, dns.TypeTXT, RecursiveNameservers, true) - if err != nil { - return false, err - } - if r.Rcode == dns.RcodeSuccess { - // If we see a CNAME here then use the alias - for _, rr := range r.Answer { - if cn, ok := rr.(*dns.CNAME); ok { - if cn.Hdr.Name == fqdn { - fqdn = cn.Target - break - } - } - } - } - - authoritativeNss, err := lookupNameservers(fqdn) - if err != nil { - return false, err - } - - return checkAuthoritativeNss(fqdn, value, authoritativeNss) -} - -// checkAuthoritativeNss queries each of the given nameservers for the expected TXT record. -func checkAuthoritativeNss(fqdn, value string, nameservers []string) (bool, error) { - for _, ns := range nameservers { - r, err := dnsQuery(fqdn, dns.TypeTXT, []string{net.JoinHostPort(ns, "53")}, false) - if err != nil { - return false, err - } - - if r.Rcode != dns.RcodeSuccess { - return false, fmt.Errorf("NS %s returned %s for %s", ns, dns.RcodeToString[r.Rcode], fqdn) - } - - var found bool - for _, rr := range r.Answer { - if txt, ok := rr.(*dns.TXT); ok { - if strings.Join(txt.Txt, "") == value { - found = true - break - } - } - } - - if !found { - return false, fmt.Errorf("NS %s did not return the expected TXT record", ns) - } - } - - return true, nil -} - -// dnsQuery will query a nameserver, iterating through the supplied servers as it retries -// The nameserver should include a port, to facilitate testing where we talk to a mock dns server. -func dnsQuery(fqdn string, rtype uint16, nameservers []string, recursive bool) (in *dns.Msg, err error) { - m := new(dns.Msg) - m.SetQuestion(fqdn, rtype) - m.SetEdns0(4096, false) - - if !recursive { - m.RecursionDesired = false - } - - // Will retry the request based on the number of servers (n+1) - for i := 1; i <= len(nameservers)+1; i++ { - ns := nameservers[i%len(nameservers)] - udp := &dns.Client{Net: "udp", Timeout: DNSTimeout} - in, _, err = udp.Exchange(m, ns) - - if err == dns.ErrTruncated { - tcp := &dns.Client{Net: "tcp", Timeout: DNSTimeout} - // If the TCP request suceeds, the err will reset to nil - in, _, err = tcp.Exchange(m, ns) - } - - if err == nil { - break - } - } - return -} - -// lookupNameservers returns the authoritative nameservers for the given fqdn. -func lookupNameservers(fqdn string) ([]string, error) { - var authoritativeNss []string - - zone, err := FindZoneByFqdn(fqdn, RecursiveNameservers) - if err != nil { - return nil, fmt.Errorf("Could not determine the zone: %v", err) - } - - r, err := dnsQuery(zone, dns.TypeNS, RecursiveNameservers, true) - if err != nil { - return nil, err - } - - for _, rr := range r.Answer { - if ns, ok := rr.(*dns.NS); ok { - authoritativeNss = append(authoritativeNss, strings.ToLower(ns.Ns)) - } - } - - if len(authoritativeNss) > 0 { - return authoritativeNss, nil - } - return nil, fmt.Errorf("Could not determine authoritative nameservers") -} - -// FindZoneByFqdn determines the zone apex for the given fqdn by recursing up the -// domain labels until the nameserver returns a SOA record in the answer section. -func FindZoneByFqdn(fqdn string, nameservers []string) (string, error) { - // Do we have it cached? - if zone, ok := fqdnToZone[fqdn]; ok { - return zone, nil - } - - labelIndexes := dns.Split(fqdn) - for _, index := range labelIndexes { - domain := fqdn[index:] - // Give up if we have reached the TLD - if isTLD(domain) { - break - } - - in, err := dnsQuery(domain, dns.TypeSOA, nameservers, true) - if err != nil { - return "", err - } - - // Any response code other than NOERROR and NXDOMAIN is treated as error - if in.Rcode != dns.RcodeNameError && in.Rcode != dns.RcodeSuccess { - return "", fmt.Errorf("Unexpected response code '%s' for %s", - dns.RcodeToString[in.Rcode], domain) - } - - // Check if we got a SOA RR in the answer section - if in.Rcode == dns.RcodeSuccess { - for _, ans := range in.Answer { - if soa, ok := ans.(*dns.SOA); ok { - zone := soa.Hdr.Name - fqdnToZone[fqdn] = zone - return zone, nil - } - } - } - } - - return "", fmt.Errorf("Could not find the start of authority") -} - -func isTLD(domain string) bool { - publicsuffix, _ := publicsuffix.PublicSuffix(UnFqdn(domain)) - if publicsuffix == UnFqdn(domain) { - return true - } - return false -} - -// ClearFqdnCache clears the cache of fqdn to zone mappings. Primarily used in testing. -func ClearFqdnCache() { - fqdnToZone = map[string]string{} -} - -// ToFqdn converts the name into a fqdn appending a trailing dot. -func ToFqdn(name string) string { - n := len(name) - if n == 0 || name[n-1] == '.' { - return name - } - return name + "." -} - -// UnFqdn converts the fqdn into a name removing the trailing dot. -func UnFqdn(name string) string { - n := len(name) - if n != 0 && name[n-1] == '.' { - return name[:n-1] - } - return name -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/dns_challenge_manual.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/dns_challenge_manual.go deleted file mode 100644 index 240384e60..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/dns_challenge_manual.go +++ /dev/null @@ -1,53 +0,0 @@ -package acme - -import ( - "bufio" - "fmt" - "os" -) - -const ( - dnsTemplate = "%s %d IN TXT \"%s\"" -) - -// DNSProviderManual is an implementation of the ChallengeProvider interface -type DNSProviderManual struct{} - -// NewDNSProviderManual returns a DNSProviderManual instance. -func NewDNSProviderManual() (*DNSProviderManual, error) { - return &DNSProviderManual{}, nil -} - -// Present prints instructions for manually creating the TXT record -func (*DNSProviderManual) Present(domain, token, keyAuth string) error { - fqdn, value, ttl := DNS01Record(domain, keyAuth) - dnsRecord := fmt.Sprintf(dnsTemplate, fqdn, ttl, value) - - authZone, err := FindZoneByFqdn(fqdn, RecursiveNameservers) - if err != nil { - return err - } - - logf("[INFO] acme: Please create the following TXT record in your %s zone:", authZone) - logf("[INFO] acme: %s", dnsRecord) - logf("[INFO] acme: Press 'Enter' when you are done") - - reader := bufio.NewReader(os.Stdin) - _, _ = reader.ReadString('\n') - return nil -} - -// CleanUp prints instructions for manually removing the TXT record -func (*DNSProviderManual) CleanUp(domain, token, keyAuth string) error { - fqdn, _, ttl := DNS01Record(domain, keyAuth) - dnsRecord := fmt.Sprintf(dnsTemplate, fqdn, ttl, "...") - - authZone, err := FindZoneByFqdn(fqdn, RecursiveNameservers) - if err != nil { - return err - } - - logf("[INFO] acme: You can now remove this TXT record from your %s zone:", authZone) - logf("[INFO] acme: %s", dnsRecord) - return nil -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/dns_challenge_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/dns_challenge_test.go deleted file mode 100644 index 597aaac17..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/dns_challenge_test.go +++ /dev/null @@ -1,206 +0,0 @@ -package acme - -import ( - "bufio" - "crypto/rand" - "crypto/rsa" - "net/http" - "net/http/httptest" - "os" - "reflect" - "sort" - "strings" - "testing" - "time" -) - -var lookupNameserversTestsOK = []struct { - fqdn string - nss []string -}{ - {"books.google.com.ng.", - []string{"ns1.google.com.", "ns2.google.com.", "ns3.google.com.", "ns4.google.com."}, - }, - {"www.google.com.", - []string{"ns1.google.com.", "ns2.google.com.", "ns3.google.com.", "ns4.google.com."}, - }, - {"physics.georgetown.edu.", - []string{"ns1.georgetown.edu.", "ns2.georgetown.edu.", "ns3.georgetown.edu."}, - }, -} - -var lookupNameserversTestsErr = []struct { - fqdn string - error string -}{ - // invalid tld - {"_null.n0n0.", - "Could not determine the zone", - }, - // invalid domain - {"_null.com.", - "Could not determine the zone", - }, - // invalid domain - {"in-valid.co.uk.", - "Could not determine the zone", - }, -} - -var findZoneByFqdnTests = []struct { - fqdn string - zone string -}{ - {"mail.google.com.", "google.com."}, // domain is a CNAME - {"foo.google.com.", "google.com."}, // domain is a non-existent subdomain -} - -var checkAuthoritativeNssTests = []struct { - fqdn, value string - ns []string - ok bool -}{ - // TXT RR w/ expected value - {"8.8.8.8.asn.routeviews.org.", "151698.8.8.024", []string{"asnums.routeviews.org."}, - true, - }, - // No TXT RR - {"ns1.google.com.", "", []string{"ns2.google.com."}, - false, - }, -} - -var checkAuthoritativeNssTestsErr = []struct { - fqdn, value string - ns []string - error string -}{ - // TXT RR /w unexpected value - {"8.8.8.8.asn.routeviews.org.", "fe01=", []string{"asnums.routeviews.org."}, - "did not return the expected TXT record", - }, - // No TXT RR - {"ns1.google.com.", "fe01=", []string{"ns2.google.com."}, - "did not return the expected TXT record", - }, -} - -var checkResolvConfServersTests = []struct { - fixture string - expected []string - defaults []string -}{ - {"testdata/resolv.conf.1", []string{"10.200.3.249:53", "10.200.3.250:5353", "[2001:4860:4860::8844]:53", "[10.0.0.1]:5353"}, []string{"127.0.0.1:53"}}, - {"testdata/resolv.conf.nonexistant", []string{"127.0.0.1:53"}, []string{"127.0.0.1:53"}}, -} - -func TestDNSValidServerResponse(t *testing.T) { - PreCheckDNS = func(fqdn, value string) (bool, error) { - return true, nil - } - privKey, _ := rsa.GenerateKey(rand.Reader, 512) - - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Add("Replay-Nonce", "12345") - w.Write([]byte("{\"type\":\"dns01\",\"status\":\"valid\",\"uri\":\"http://some.url\",\"token\":\"http8\"}")) - })) - - manualProvider, _ := NewDNSProviderManual() - jws := &jws{privKey: privKey, directoryURL: ts.URL} - solver := &dnsChallenge{jws: jws, validate: validate, provider: manualProvider} - clientChallenge := challenge{Type: "dns01", Status: "pending", URI: ts.URL, Token: "http8"} - - go func() { - time.Sleep(time.Second * 2) - f := bufio.NewWriter(os.Stdout) - defer f.Flush() - f.WriteString("\n") - }() - - if err := solver.Solve(clientChallenge, "example.com"); err != nil { - t.Errorf("VALID: Expected Solve to return no error but the error was -> %v", err) - } -} - -func TestPreCheckDNS(t *testing.T) { - ok, err := PreCheckDNS("acme-staging.api.letsencrypt.org", "fe01=") - if err != nil || !ok { - t.Errorf("preCheckDNS failed for acme-staging.api.letsencrypt.org") - } -} - -func TestLookupNameserversOK(t *testing.T) { - for _, tt := range lookupNameserversTestsOK { - nss, err := lookupNameservers(tt.fqdn) - if err != nil { - t.Fatalf("#%s: got %q; want nil", tt.fqdn, err) - } - - sort.Strings(nss) - sort.Strings(tt.nss) - - if !reflect.DeepEqual(nss, tt.nss) { - t.Errorf("#%s: got %v; want %v", tt.fqdn, nss, tt.nss) - } - } -} - -func TestLookupNameserversErr(t *testing.T) { - for _, tt := range lookupNameserversTestsErr { - _, err := lookupNameservers(tt.fqdn) - if err == nil { - t.Fatalf("#%s: expected %q (error); got <nil>", tt.fqdn, tt.error) - } - - if !strings.Contains(err.Error(), tt.error) { - t.Errorf("#%s: expected %q (error); got %q", tt.fqdn, tt.error, err) - continue - } - } -} - -func TestFindZoneByFqdn(t *testing.T) { - for _, tt := range findZoneByFqdnTests { - res, err := FindZoneByFqdn(tt.fqdn, RecursiveNameservers) - if err != nil { - t.Errorf("FindZoneByFqdn failed for %s: %v", tt.fqdn, err) - } - if res != tt.zone { - t.Errorf("%s: got %s; want %s", tt.fqdn, res, tt.zone) - } - } -} - -func TestCheckAuthoritativeNss(t *testing.T) { - for _, tt := range checkAuthoritativeNssTests { - ok, _ := checkAuthoritativeNss(tt.fqdn, tt.value, tt.ns) - if ok != tt.ok { - t.Errorf("%s: got %t; want %t", tt.fqdn, ok, tt.ok) - } - } -} - -func TestCheckAuthoritativeNssErr(t *testing.T) { - for _, tt := range checkAuthoritativeNssTestsErr { - _, err := checkAuthoritativeNss(tt.fqdn, tt.value, tt.ns) - if err == nil { - t.Fatalf("#%s: expected %q (error); got <nil>", tt.fqdn, tt.error) - } - if !strings.Contains(err.Error(), tt.error) { - t.Errorf("#%s: expected %q (error); got %q", tt.fqdn, tt.error, err) - continue - } - } -} - -func TestResolveConfServers(t *testing.T) { - for _, tt := range checkResolvConfServersTests { - result := getNameservers(tt.fixture, tt.defaults) - - sort.Strings(result) - sort.Strings(tt.expected) - if !reflect.DeepEqual(result, tt.expected) { - t.Errorf("#%s: expected %q; got %q", tt.fixture, tt.expected, result) - } - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/error.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/error.go deleted file mode 100644 index e4bc934c2..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/error.go +++ /dev/null @@ -1,94 +0,0 @@ -package acme - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - "strings" -) - -const ( - tosAgreementError = "Must agree to subscriber agreement before any further actions" - invalidNonceError = "JWS has invalid anti-replay nonce" -) - -// RemoteError is the base type for all errors specific to the ACME protocol. -type RemoteError struct { - StatusCode int `json:"status,omitempty"` - Type string `json:"type"` - Detail string `json:"detail"` -} - -func (e RemoteError) Error() string { - return fmt.Sprintf("acme: Error %d - %s - %s", e.StatusCode, e.Type, e.Detail) -} - -// TOSError represents the error which is returned if the user needs to -// accept the TOS. -// TODO: include the new TOS url if we can somehow obtain it. -type TOSError struct { - RemoteError -} - -// NonceError represents the error which is returned if the -// nonce sent by the client was not accepted by the server. -type NonceError struct { - RemoteError -} - -type domainError struct { - Domain string - Error error -} - -type challengeError struct { - RemoteError - records []validationRecord -} - -func (c challengeError) Error() string { - - var errStr string - for _, validation := range c.records { - errStr = errStr + fmt.Sprintf("\tValidation for %s:%s\n\tResolved to:\n\t\t%s\n\tUsed: %s\n\n", - validation.Hostname, validation.Port, strings.Join(validation.ResolvedAddresses, "\n\t\t"), validation.UsedAddress) - } - - return fmt.Sprintf("%s\nError Detail:\n%s", c.RemoteError.Error(), errStr) -} - -func handleHTTPError(resp *http.Response) error { - var errorDetail RemoteError - - contentType := resp.Header.Get("Content-Type") - if contentType == "application/json" || contentType == "application/problem+json" { - err := json.NewDecoder(resp.Body).Decode(&errorDetail) - if err != nil { - return err - } - } else { - detailBytes, err := ioutil.ReadAll(limitReader(resp.Body, maxBodySize)) - if err != nil { - return err - } - errorDetail.Detail = string(detailBytes) - } - - errorDetail.StatusCode = resp.StatusCode - - // Check for errors we handle specifically - if errorDetail.StatusCode == http.StatusForbidden && errorDetail.Detail == tosAgreementError { - return TOSError{errorDetail} - } - - if errorDetail.StatusCode == http.StatusBadRequest && strings.HasPrefix(errorDetail.Detail, invalidNonceError) { - return NonceError{errorDetail} - } - - return errorDetail -} - -func handleChallengeError(chlng challenge) error { - return challengeError{chlng.Error, chlng.ValidationRecords} -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/http.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/http.go deleted file mode 100644 index a858b5a75..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/http.go +++ /dev/null @@ -1,148 +0,0 @@ -package acme - -import ( - "encoding/json" - "errors" - "fmt" - "io" - "net/http" - "runtime" - "strings" - "time" -) - -// UserAgent (if non-empty) will be tacked onto the User-Agent string in requests. -var UserAgent string - -// HTTPClient is an HTTP client with a reasonable timeout value. -var HTTPClient = http.Client{Timeout: 10 * time.Second} - -const ( - // defaultGoUserAgent is the Go HTTP package user agent string. Too - // bad it isn't exported. If it changes, we should update it here, too. - defaultGoUserAgent = "Go-http-client/1.1" - - // ourUserAgent is the User-Agent of this underlying library package. - ourUserAgent = "xenolf-acme" -) - -// httpHead performs a HEAD request with a proper User-Agent string. -// The response body (resp.Body) is already closed when this function returns. -func httpHead(url string) (resp *http.Response, err error) { - req, err := http.NewRequest("HEAD", url, nil) - if err != nil { - return nil, fmt.Errorf("failed to head %q: %v", url, err) - } - - req.Header.Set("User-Agent", userAgent()) - - resp, err = HTTPClient.Do(req) - if err != nil { - return resp, fmt.Errorf("failed to do head %q: %v", url, err) - } - resp.Body.Close() - return resp, err -} - -// httpPost performs a POST request with a proper User-Agent string. -// Callers should close resp.Body when done reading from it. -func httpPost(url string, bodyType string, body io.Reader) (resp *http.Response, err error) { - req, err := http.NewRequest("POST", url, body) - if err != nil { - return nil, fmt.Errorf("failed to post %q: %v", url, err) - } - req.Header.Set("Content-Type", bodyType) - req.Header.Set("User-Agent", userAgent()) - - return HTTPClient.Do(req) -} - -// httpGet performs a GET request with a proper User-Agent string. -// Callers should close resp.Body when done reading from it. -func httpGet(url string) (resp *http.Response, err error) { - req, err := http.NewRequest("GET", url, nil) - if err != nil { - return nil, fmt.Errorf("failed to get %q: %v", url, err) - } - req.Header.Set("User-Agent", userAgent()) - - return HTTPClient.Do(req) -} - -// getJSON performs an HTTP GET request and parses the response body -// as JSON, into the provided respBody object. -func getJSON(uri string, respBody interface{}) (http.Header, error) { - resp, err := httpGet(uri) - if err != nil { - return nil, fmt.Errorf("failed to get json %q: %v", uri, err) - } - defer resp.Body.Close() - - if resp.StatusCode >= http.StatusBadRequest { - return resp.Header, handleHTTPError(resp) - } - - return resp.Header, json.NewDecoder(resp.Body).Decode(respBody) -} - -// postJSON performs an HTTP POST request and parses the response body -// as JSON, into the provided respBody object. -func postJSON(j *jws, uri string, reqBody, respBody interface{}) (http.Header, error) { - jsonBytes, err := json.Marshal(reqBody) - if err != nil { - return nil, errors.New("Failed to marshal network message...") - } - - resp, err := j.post(uri, jsonBytes) - if err != nil { - return nil, fmt.Errorf("Failed to post JWS message. -> %v", err) - } - - defer resp.Body.Close() - - if resp.StatusCode >= http.StatusBadRequest { - - err := handleHTTPError(resp) - - switch err.(type) { - - case NonceError: - - // Retry once if the nonce was invalidated - - retryResp, err := j.post(uri, jsonBytes) - if err != nil { - return nil, fmt.Errorf("Failed to post JWS message. -> %v", err) - } - - defer retryResp.Body.Close() - - if retryResp.StatusCode >= http.StatusBadRequest { - return retryResp.Header, handleHTTPError(retryResp) - } - - if respBody == nil { - return retryResp.Header, nil - } - - return retryResp.Header, json.NewDecoder(retryResp.Body).Decode(respBody) - - default: - return resp.Header, err - - } - - } - - if respBody == nil { - return resp.Header, nil - } - - return resp.Header, json.NewDecoder(resp.Body).Decode(respBody) -} - -// userAgent builds and returns the User-Agent string to use in requests. -func userAgent() string { - ua := fmt.Sprintf("%s (%s; %s) %s %s", defaultGoUserAgent, runtime.GOOS, runtime.GOARCH, ourUserAgent, UserAgent) - return strings.TrimSpace(ua) -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/http_challenge.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/http_challenge.go deleted file mode 100644 index 95cb1fd81..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/http_challenge.go +++ /dev/null @@ -1,41 +0,0 @@ -package acme - -import ( - "fmt" - "log" -) - -type httpChallenge struct { - jws *jws - validate validateFunc - provider ChallengeProvider -} - -// HTTP01ChallengePath returns the URL path for the `http-01` challenge -func HTTP01ChallengePath(token string) string { - return "/.well-known/acme-challenge/" + token -} - -func (s *httpChallenge) Solve(chlng challenge, domain string) error { - - logf("[INFO][%s] acme: Trying to solve HTTP-01", domain) - - // Generate the Key Authorization for the challenge - keyAuth, err := getKeyAuthorization(chlng.Token, s.jws.privKey) - if err != nil { - return err - } - - err = s.provider.Present(domain, chlng.Token, keyAuth) - if err != nil { - return fmt.Errorf("[%s] error presenting token: %v", domain, err) - } - defer func() { - err := s.provider.CleanUp(domain, chlng.Token, keyAuth) - if err != nil { - log.Printf("[%s] error cleaning up: %v", domain, err) - } - }() - - return s.validate(s.jws, domain, chlng.URI, challenge{Resource: "challenge", Type: chlng.Type, Token: chlng.Token, KeyAuthorization: keyAuth}) -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/http_challenge_server.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/http_challenge_server.go deleted file mode 100644 index 64c6a8280..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/http_challenge_server.go +++ /dev/null @@ -1,79 +0,0 @@ -package acme - -import ( - "fmt" - "net" - "net/http" - "strings" -) - -// HTTPProviderServer implements ChallengeProvider for `http-01` challenge -// It may be instantiated without using the NewHTTPProviderServer function if -// you want only to use the default values. -type HTTPProviderServer struct { - iface string - port string - done chan bool - listener net.Listener -} - -// NewHTTPProviderServer creates a new HTTPProviderServer on the selected interface and port. -// Setting iface and / or port to an empty string will make the server fall back to -// the "any" interface and port 80 respectively. -func NewHTTPProviderServer(iface, port string) *HTTPProviderServer { - return &HTTPProviderServer{iface: iface, port: port} -} - -// Present starts a web server and makes the token available at `HTTP01ChallengePath(token)` for web requests. -func (s *HTTPProviderServer) Present(domain, token, keyAuth string) error { - if s.port == "" { - s.port = "80" - } - - var err error - s.listener, err = net.Listen("tcp", net.JoinHostPort(s.iface, s.port)) - if err != nil { - return fmt.Errorf("Could not start HTTP server for challenge -> %v", err) - } - - s.done = make(chan bool) - go s.serve(domain, token, keyAuth) - return nil -} - -// CleanUp closes the HTTP server and removes the token from `HTTP01ChallengePath(token)` -func (s *HTTPProviderServer) CleanUp(domain, token, keyAuth string) error { - if s.listener == nil { - return nil - } - s.listener.Close() - <-s.done - return nil -} - -func (s *HTTPProviderServer) serve(domain, token, keyAuth string) { - path := HTTP01ChallengePath(token) - - // The handler validates the HOST header and request type. - // For validation it then writes the token the server returned with the challenge - mux := http.NewServeMux() - mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { - if strings.HasPrefix(r.Host, domain) && r.Method == "GET" { - w.Header().Add("Content-Type", "text/plain") - w.Write([]byte(keyAuth)) - logf("[INFO][%s] Served key authentication", domain) - } else { - logf("[WARN] Received request for domain %s with method %s but the domain did not match any challenge. Please ensure your are passing the HOST header properly.", r.Host, r.Method) - w.Write([]byte("TEST")) - } - }) - - httpServer := &http.Server{ - Handler: mux, - } - // Once httpServer is shut down we don't want any lingering - // connections, so disable KeepAlives. - httpServer.SetKeepAlivesEnabled(false) - httpServer.Serve(s.listener) - s.done <- true -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/http_challenge_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/http_challenge_test.go deleted file mode 100644 index 7400f56d4..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/http_challenge_test.go +++ /dev/null @@ -1,57 +0,0 @@ -package acme - -import ( - "crypto/rand" - "crypto/rsa" - "io/ioutil" - "strings" - "testing" -) - -func TestHTTPChallenge(t *testing.T) { - privKey, _ := rsa.GenerateKey(rand.Reader, 512) - j := &jws{privKey: privKey} - clientChallenge := challenge{Type: HTTP01, Token: "http1"} - mockValidate := func(_ *jws, _, _ string, chlng challenge) error { - uri := "http://localhost:23457/.well-known/acme-challenge/" + chlng.Token - resp, err := httpGet(uri) - if err != nil { - return err - } - defer resp.Body.Close() - - if want := "text/plain"; resp.Header.Get("Content-Type") != want { - t.Errorf("Get(%q) Content-Type: got %q, want %q", uri, resp.Header.Get("Content-Type"), want) - } - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return err - } - bodyStr := string(body) - - if bodyStr != chlng.KeyAuthorization { - t.Errorf("Get(%q) Body: got %q, want %q", uri, bodyStr, chlng.KeyAuthorization) - } - - return nil - } - solver := &httpChallenge{jws: j, validate: mockValidate, provider: &HTTPProviderServer{port: "23457"}} - - if err := solver.Solve(clientChallenge, "localhost:23457"); err != nil { - t.Errorf("Solve error: got %v, want nil", err) - } -} - -func TestHTTPChallengeInvalidPort(t *testing.T) { - privKey, _ := rsa.GenerateKey(rand.Reader, 128) - j := &jws{privKey: privKey} - clientChallenge := challenge{Type: HTTP01, Token: "http2"} - solver := &httpChallenge{jws: j, validate: stubValidate, provider: &HTTPProviderServer{port: "123456"}} - - if err := solver.Solve(clientChallenge, "localhost:123456"); err == nil { - t.Errorf("Solve error: got %v, want error", err) - } else if want, want18 := "invalid port 123456", "123456: invalid port"; !strings.HasSuffix(err.Error(), want) && !strings.HasSuffix(err.Error(), want18) { - t.Errorf("Solve error: got %q, want suffix %q", err.Error(), want) - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/http_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/http_test.go deleted file mode 100644 index 33a48a331..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/http_test.go +++ /dev/null @@ -1,100 +0,0 @@ -package acme - -import ( - "net/http" - "net/http/httptest" - "strings" - "testing" -) - -func TestHTTPHeadUserAgent(t *testing.T) { - var ua, method string - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - ua = r.Header.Get("User-Agent") - method = r.Method - })) - defer ts.Close() - - _, err := httpHead(ts.URL) - if err != nil { - t.Fatal(err) - } - - if method != "HEAD" { - t.Errorf("Expected method to be HEAD, got %s", method) - } - if !strings.Contains(ua, ourUserAgent) { - t.Errorf("Expected User-Agent to contain '%s', got: '%s'", ourUserAgent, ua) - } -} - -func TestHTTPGetUserAgent(t *testing.T) { - var ua, method string - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - ua = r.Header.Get("User-Agent") - method = r.Method - })) - defer ts.Close() - - res, err := httpGet(ts.URL) - if err != nil { - t.Fatal(err) - } - res.Body.Close() - - if method != "GET" { - t.Errorf("Expected method to be GET, got %s", method) - } - if !strings.Contains(ua, ourUserAgent) { - t.Errorf("Expected User-Agent to contain '%s', got: '%s'", ourUserAgent, ua) - } -} - -func TestHTTPPostUserAgent(t *testing.T) { - var ua, method string - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - ua = r.Header.Get("User-Agent") - method = r.Method - })) - defer ts.Close() - - res, err := httpPost(ts.URL, "text/plain", strings.NewReader("falalalala")) - if err != nil { - t.Fatal(err) - } - res.Body.Close() - - if method != "POST" { - t.Errorf("Expected method to be POST, got %s", method) - } - if !strings.Contains(ua, ourUserAgent) { - t.Errorf("Expected User-Agent to contain '%s', got: '%s'", ourUserAgent, ua) - } -} - -func TestUserAgent(t *testing.T) { - ua := userAgent() - - if !strings.Contains(ua, defaultGoUserAgent) { - t.Errorf("Expected UA to contain %s, got '%s'", defaultGoUserAgent, ua) - } - if !strings.Contains(ua, ourUserAgent) { - t.Errorf("Expected UA to contain %s, got '%s'", ourUserAgent, ua) - } - if strings.HasSuffix(ua, " ") { - t.Errorf("UA should not have trailing spaces; got '%s'", ua) - } - - // customize the UA by appending a value - UserAgent = "MyApp/1.2.3" - ua = userAgent() - if !strings.Contains(ua, defaultGoUserAgent) { - t.Errorf("Expected UA to contain %s, got '%s'", defaultGoUserAgent, ua) - } - if !strings.Contains(ua, ourUserAgent) { - t.Errorf("Expected UA to contain %s, got '%s'", ourUserAgent, ua) - } - if !strings.Contains(ua, UserAgent) { - t.Errorf("Expected custom UA to contain %s, got '%s'", UserAgent, ua) - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/jws.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/jws.go deleted file mode 100644 index a39434342..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/jws.go +++ /dev/null @@ -1,131 +0,0 @@ -package acme - -import ( - "bytes" - "crypto" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rsa" - "fmt" - "net/http" - "sync" - - "gopkg.in/square/go-jose.v1" -) - -type jws struct { - directoryURL string - privKey crypto.PrivateKey - nonces nonceManager -} - -func keyAsJWK(key interface{}) *jose.JsonWebKey { - switch k := key.(type) { - case *ecdsa.PublicKey: - return &jose.JsonWebKey{Key: k, Algorithm: "EC"} - case *rsa.PublicKey: - return &jose.JsonWebKey{Key: k, Algorithm: "RSA"} - - default: - return nil - } -} - -// Posts a JWS signed message to the specified URL. -// It does NOT close the response body, so the caller must -// do that if no error was returned. -func (j *jws) post(url string, content []byte) (*http.Response, error) { - signedContent, err := j.signContent(content) - if err != nil { - return nil, fmt.Errorf("Failed to sign content -> %s", err.Error()) - } - - resp, err := httpPost(url, "application/jose+json", bytes.NewBuffer([]byte(signedContent.FullSerialize()))) - if err != nil { - return nil, fmt.Errorf("Failed to HTTP POST to %s -> %s", url, err.Error()) - } - - nonce, nonceErr := getNonceFromResponse(resp) - if nonceErr == nil { - j.nonces.Push(nonce) - } - - return resp, nil -} - -func (j *jws) signContent(content []byte) (*jose.JsonWebSignature, error) { - - var alg jose.SignatureAlgorithm - switch k := j.privKey.(type) { - case *rsa.PrivateKey: - alg = jose.RS256 - case *ecdsa.PrivateKey: - if k.Curve == elliptic.P256() { - alg = jose.ES256 - } else if k.Curve == elliptic.P384() { - alg = jose.ES384 - } - } - - signer, err := jose.NewSigner(alg, j.privKey) - if err != nil { - return nil, fmt.Errorf("Failed to create jose signer -> %s", err.Error()) - } - signer.SetNonceSource(j) - - signed, err := signer.Sign(content) - if err != nil { - return nil, fmt.Errorf("Failed to sign content -> %s", err.Error()) - } - return signed, nil -} - -func (j *jws) Nonce() (string, error) { - if nonce, ok := j.nonces.Pop(); ok { - return nonce, nil - } - - return getNonce(j.directoryURL) -} - -type nonceManager struct { - nonces []string - sync.Mutex -} - -func (n *nonceManager) Pop() (string, bool) { - n.Lock() - defer n.Unlock() - - if len(n.nonces) == 0 { - return "", false - } - - nonce := n.nonces[len(n.nonces)-1] - n.nonces = n.nonces[:len(n.nonces)-1] - return nonce, true -} - -func (n *nonceManager) Push(nonce string) { - n.Lock() - defer n.Unlock() - n.nonces = append(n.nonces, nonce) -} - -func getNonce(url string) (string, error) { - resp, err := httpHead(url) - if err != nil { - return "", fmt.Errorf("Failed to get nonce from HTTP HEAD -> %s", err.Error()) - } - - return getNonceFromResponse(resp) -} - -func getNonceFromResponse(resp *http.Response) (string, error) { - nonce := resp.Header.Get("Replay-Nonce") - if nonce == "" { - return "", fmt.Errorf("Server did not respond with a proper nonce header.") - } - - return nonce, nil -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/messages.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/messages.go deleted file mode 100644 index 79ccf154e..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/messages.go +++ /dev/null @@ -1,115 +0,0 @@ -package acme - -import ( - "time" - - "gopkg.in/square/go-jose.v1" -) - -type directory struct { - NewAuthzURL string `json:"new-authz"` - NewCertURL string `json:"new-cert"` - NewRegURL string `json:"new-reg"` - RevokeCertURL string `json:"revoke-cert"` -} - -type registrationMessage struct { - Resource string `json:"resource"` - Contact []string `json:"contact"` - Delete bool `json:"delete,omitempty"` -} - -// Registration is returned by the ACME server after the registration -// The client implementation should save this registration somewhere. -type Registration struct { - Resource string `json:"resource,omitempty"` - ID int `json:"id"` - Key jose.JsonWebKey `json:"key"` - Contact []string `json:"contact"` - Agreement string `json:"agreement,omitempty"` - Authorizations string `json:"authorizations,omitempty"` - Certificates string `json:"certificates,omitempty"` -} - -// RegistrationResource represents all important informations about a registration -// of which the client needs to keep track itself. -type RegistrationResource struct { - Body Registration `json:"body,omitempty"` - URI string `json:"uri,omitempty"` - NewAuthzURL string `json:"new_authzr_uri,omitempty"` - TosURL string `json:"terms_of_service,omitempty"` -} - -type authorizationResource struct { - Body authorization - Domain string - NewCertURL string - AuthURL string -} - -type authorization struct { - Resource string `json:"resource,omitempty"` - Identifier identifier `json:"identifier"` - Status string `json:"status,omitempty"` - Expires time.Time `json:"expires,omitempty"` - Challenges []challenge `json:"challenges,omitempty"` - Combinations [][]int `json:"combinations,omitempty"` -} - -type identifier struct { - Type string `json:"type"` - Value string `json:"value"` -} - -type validationRecord struct { - URI string `json:"url,omitempty"` - Hostname string `json:"hostname,omitempty"` - Port string `json:"port,omitempty"` - ResolvedAddresses []string `json:"addressesResolved,omitempty"` - UsedAddress string `json:"addressUsed,omitempty"` -} - -type challenge struct { - Resource string `json:"resource,omitempty"` - Type Challenge `json:"type,omitempty"` - Status string `json:"status,omitempty"` - URI string `json:"uri,omitempty"` - Token string `json:"token,omitempty"` - KeyAuthorization string `json:"keyAuthorization,omitempty"` - TLS bool `json:"tls,omitempty"` - Iterations int `json:"n,omitempty"` - Error RemoteError `json:"error,omitempty"` - ValidationRecords []validationRecord `json:"validationRecord,omitempty"` -} - -type csrMessage struct { - Resource string `json:"resource,omitempty"` - Csr string `json:"csr"` - Authorizations []string `json:"authorizations"` -} - -type revokeCertMessage struct { - Resource string `json:"resource"` - Certificate string `json:"certificate"` -} - -type deactivateAuthMessage struct { - Resource string `json:"resource,omitempty"` - Status string `jsom:"status"` -} - -// CertificateResource represents a CA issued certificate. -// PrivateKey, Certificate and IssuerCertificate are all -// already PEM encoded and can be directly written to disk. -// Certificate may be a certificate bundle, depending on the -// options supplied to create it. -type CertificateResource struct { - Domain string `json:"domain"` - CertURL string `json:"certUrl"` - CertStableURL string `json:"certStableUrl"` - AccountRef string `json:"accountRef,omitempty"` - PrivateKey []byte `json:"-"` - Certificate []byte `json:"-"` - IssuerCertificate []byte `json:"-"` - CSR []byte `json:"-"` -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/pop_challenge.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/pop_challenge.go deleted file mode 100644 index 8d2a213b0..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/pop_challenge.go +++ /dev/null @@ -1 +0,0 @@ -package acme diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/provider.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/provider.go deleted file mode 100644 index d177ff07a..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/provider.go +++ /dev/null @@ -1,28 +0,0 @@ -package acme - -import "time" - -// ChallengeProvider enables implementing a custom challenge -// provider. Present presents the solution to a challenge available to -// be solved. CleanUp will be called by the challenge if Present ends -// in a non-error state. -type ChallengeProvider interface { - Present(domain, token, keyAuth string) error - CleanUp(domain, token, keyAuth string) error -} - -// ChallengeProviderTimeout allows for implementing a -// ChallengeProvider where an unusually long timeout is required when -// waiting for an ACME challenge to be satisfied, such as when -// checking for DNS record progagation. If an implementor of a -// ChallengeProvider provides a Timeout method, then the return values -// of the Timeout method will be used when appropriate by the acme -// package. The interval value is the time between checks. -// -// The default values used for timeout and interval are 60 seconds and -// 2 seconds respectively. These are used when no Timeout method is -// defined for the ChallengeProvider. -type ChallengeProviderTimeout interface { - ChallengeProvider - Timeout() (timeout, interval time.Duration) -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/testdata/resolv.conf.1 b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/testdata/resolv.conf.1 deleted file mode 100644 index 3098f99b5..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/testdata/resolv.conf.1 +++ /dev/null @@ -1,5 +0,0 @@ -domain company.com -nameserver 10.200.3.249 -nameserver 10.200.3.250:5353 -nameserver 2001:4860:4860::8844 -nameserver [10.0.0.1]:5353 diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/tls_sni_challenge.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/tls_sni_challenge.go deleted file mode 100644 index 34383cbfa..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/tls_sni_challenge.go +++ /dev/null @@ -1,67 +0,0 @@ -package acme - -import ( - "crypto/rsa" - "crypto/sha256" - "crypto/tls" - "encoding/hex" - "fmt" - "log" -) - -type tlsSNIChallenge struct { - jws *jws - validate validateFunc - provider ChallengeProvider -} - -func (t *tlsSNIChallenge) Solve(chlng challenge, domain string) error { - // FIXME: https://github.com/ietf-wg-acme/acme/pull/22 - // Currently we implement this challenge to track boulder, not the current spec! - - logf("[INFO][%s] acme: Trying to solve TLS-SNI-01", domain) - - // Generate the Key Authorization for the challenge - keyAuth, err := getKeyAuthorization(chlng.Token, t.jws.privKey) - if err != nil { - return err - } - - err = t.provider.Present(domain, chlng.Token, keyAuth) - if err != nil { - return fmt.Errorf("[%s] error presenting token: %v", domain, err) - } - defer func() { - err := t.provider.CleanUp(domain, chlng.Token, keyAuth) - if err != nil { - log.Printf("[%s] error cleaning up: %v", domain, err) - } - }() - return t.validate(t.jws, domain, chlng.URI, challenge{Resource: "challenge", Type: chlng.Type, Token: chlng.Token, KeyAuthorization: keyAuth}) -} - -// TLSSNI01ChallengeCert returns a certificate and target domain for the `tls-sni-01` challenge -func TLSSNI01ChallengeCert(keyAuth string) (tls.Certificate, string, error) { - // generate a new RSA key for the certificates - tempPrivKey, err := generatePrivateKey(RSA2048) - if err != nil { - return tls.Certificate{}, "", err - } - rsaPrivKey := tempPrivKey.(*rsa.PrivateKey) - rsaPrivPEM := pemEncode(rsaPrivKey) - - zBytes := sha256.Sum256([]byte(keyAuth)) - z := hex.EncodeToString(zBytes[:sha256.Size]) - domain := fmt.Sprintf("%s.%s.acme.invalid", z[:32], z[32:]) - tempCertPEM, err := generatePemCert(rsaPrivKey, domain) - if err != nil { - return tls.Certificate{}, "", err - } - - certificate, err := tls.X509KeyPair(tempCertPEM, rsaPrivPEM) - if err != nil { - return tls.Certificate{}, "", err - } - - return certificate, domain, nil -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/tls_sni_challenge_server.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/tls_sni_challenge_server.go deleted file mode 100644 index df00fbb5a..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/tls_sni_challenge_server.go +++ /dev/null @@ -1,62 +0,0 @@ -package acme - -import ( - "crypto/tls" - "fmt" - "net" - "net/http" -) - -// TLSProviderServer implements ChallengeProvider for `TLS-SNI-01` challenge -// It may be instantiated without using the NewTLSProviderServer function if -// you want only to use the default values. -type TLSProviderServer struct { - iface string - port string - done chan bool - listener net.Listener -} - -// NewTLSProviderServer creates a new TLSProviderServer on the selected interface and port. -// Setting iface and / or port to an empty string will make the server fall back to -// the "any" interface and port 443 respectively. -func NewTLSProviderServer(iface, port string) *TLSProviderServer { - return &TLSProviderServer{iface: iface, port: port} -} - -// Present makes the keyAuth available as a cert -func (s *TLSProviderServer) Present(domain, token, keyAuth string) error { - if s.port == "" { - s.port = "443" - } - - cert, _, err := TLSSNI01ChallengeCert(keyAuth) - if err != nil { - return err - } - - tlsConf := new(tls.Config) - tlsConf.Certificates = []tls.Certificate{cert} - - s.listener, err = tls.Listen("tcp", net.JoinHostPort(s.iface, s.port), tlsConf) - if err != nil { - return fmt.Errorf("Could not start HTTPS server for challenge -> %v", err) - } - - s.done = make(chan bool) - go func() { - http.Serve(s.listener, nil) - s.done <- true - }() - return nil -} - -// CleanUp closes the HTTP server. -func (s *TLSProviderServer) CleanUp(domain, token, keyAuth string) error { - if s.listener == nil { - return nil - } - s.listener.Close() - <-s.done - return nil -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/tls_sni_challenge_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/tls_sni_challenge_test.go deleted file mode 100644 index 83b2833a9..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/tls_sni_challenge_test.go +++ /dev/null @@ -1,65 +0,0 @@ -package acme - -import ( - "crypto/rand" - "crypto/rsa" - "crypto/sha256" - "crypto/tls" - "encoding/hex" - "fmt" - "strings" - "testing" -) - -func TestTLSSNIChallenge(t *testing.T) { - privKey, _ := rsa.GenerateKey(rand.Reader, 512) - j := &jws{privKey: privKey} - clientChallenge := challenge{Type: TLSSNI01, Token: "tlssni1"} - mockValidate := func(_ *jws, _, _ string, chlng challenge) error { - conn, err := tls.Dial("tcp", "localhost:23457", &tls.Config{ - InsecureSkipVerify: true, - }) - if err != nil { - t.Errorf("Expected to connect to challenge server without an error. %s", err.Error()) - } - - // Expect the server to only return one certificate - connState := conn.ConnectionState() - if count := len(connState.PeerCertificates); count != 1 { - t.Errorf("Expected the challenge server to return exactly one certificate but got %d", count) - } - - remoteCert := connState.PeerCertificates[0] - if count := len(remoteCert.DNSNames); count != 1 { - t.Errorf("Expected the challenge certificate to have exactly one DNSNames entry but had %d", count) - } - - zBytes := sha256.Sum256([]byte(chlng.KeyAuthorization)) - z := hex.EncodeToString(zBytes[:sha256.Size]) - domain := fmt.Sprintf("%s.%s.acme.invalid", z[:32], z[32:]) - - if remoteCert.DNSNames[0] != domain { - t.Errorf("Expected the challenge certificate DNSName to match %s but was %s", domain, remoteCert.DNSNames[0]) - } - - return nil - } - solver := &tlsSNIChallenge{jws: j, validate: mockValidate, provider: &TLSProviderServer{port: "23457"}} - - if err := solver.Solve(clientChallenge, "localhost:23457"); err != nil { - t.Errorf("Solve error: got %v, want nil", err) - } -} - -func TestTLSSNIChallengeInvalidPort(t *testing.T) { - privKey, _ := rsa.GenerateKey(rand.Reader, 128) - j := &jws{privKey: privKey} - clientChallenge := challenge{Type: TLSSNI01, Token: "tlssni2"} - solver := &tlsSNIChallenge{jws: j, validate: stubValidate, provider: &TLSProviderServer{port: "123456"}} - - if err := solver.Solve(clientChallenge, "localhost:123456"); err == nil { - t.Errorf("Solve error: got %v, want error", err) - } else if want, want18 := "invalid port 123456", "123456: invalid port"; !strings.HasSuffix(err.Error(), want) && !strings.HasSuffix(err.Error(), want18) { - t.Errorf("Solve error: got %q, want suffix %q", err.Error(), want) - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/utils.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/utils.go deleted file mode 100644 index 2fa0db304..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/utils.go +++ /dev/null @@ -1,29 +0,0 @@ -package acme - -import ( - "fmt" - "time" -) - -// WaitFor polls the given function 'f', once every 'interval', up to 'timeout'. -func WaitFor(timeout, interval time.Duration, f func() (bool, error)) error { - var lastErr string - timeup := time.After(timeout) - for { - select { - case <-timeup: - return fmt.Errorf("Time limit exceeded. Last error: %s", lastErr) - default: - } - - stop, err := f() - if stop { - return nil - } - if err != nil { - lastErr = err.Error() - } - - time.Sleep(interval) - } -} diff --git a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/utils_test.go b/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/utils_test.go deleted file mode 100644 index 158af4116..000000000 --- a/vendor/github.com/rsc/letsencrypt/vendor/github.com/xenolf/lego/acme/utils_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package acme - -import ( - "testing" - "time" -) - -func TestWaitForTimeout(t *testing.T) { - c := make(chan error) - go func() { - err := WaitFor(3*time.Second, 1*time.Second, func() (bool, error) { - return false, nil - }) - c <- err - }() - - timeout := time.After(4 * time.Second) - select { - case <-timeout: - t.Fatal("timeout exceeded") - case err := <-c: - if err == nil { - t.Errorf("expected timeout error; got %v", err) - } - } -} |