diff --git a/Gopkg.lock b/Gopkg.lock index e7f68c69..9e979e9e 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -100,6 +100,12 @@ packages = ["."] revision = "c35da9bed550558a4797c74e34957071214342e7" +[[projects]] + branch = "master" + name = "github.com/jedisct1/go-dnsstamps" + packages = ["."] + revision = "d8908ceb62ed5ff9fe230d14cdde7727b90737e6" + [[projects]] branch = "master" name = "github.com/jedisct1/go-minisign" @@ -155,6 +161,7 @@ name = "golang.org/x/net" packages = [ "bpf", + "http/httpguts", "http2", "http2/hpack", "idna", @@ -164,7 +171,7 @@ "ipv6", "lex/httplex" ] - revision = "500e7a4f953ddaf55d316b4d3adc516aa0379622" + revision = "d41e8174641f662c5a2d1c7a5f9e828788eb8706" [[projects]] branch = "master" @@ -176,7 +183,7 @@ "windows/svc/eventlog", "windows/svc/mgr" ] - revision = "2281fa97ef7b0c26324634d5a22f04babdac8713" + revision = "b126b21c05a91c856b027c16779c12e3bf236954" [[projects]] name = "golang.org/x/text" @@ -208,6 +215,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "5afc7ca4456d4f6f1a1da31e3ae1eb4eaf79ffe39c72a3dc98a2d78d4d865b79" + inputs-digest = "883af9e923fc950ed5ce4f7e72f24ff18aaed239807516582d38953d65273c22" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index aaee3b80..f00b4d12 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -42,6 +42,10 @@ branch = "master" name = "github.com/jedisct1/go-clocksmith" +[[constraint]] + branch = "master" + name = "github.com/jedisct1/go-dnsstamps" + [[constraint]] branch = "master" name = "github.com/jedisct1/go-minisign" @@ -66,6 +70,10 @@ branch = "master" name = "golang.org/x/crypto" +[[constraint]] + branch = "master" + name = "golang.org/x/net" + [[constraint]] name = "gopkg.in/natefinch/lumberjack.v2" version = "2.1.0" diff --git a/dnscrypt-proxy/config.go b/dnscrypt-proxy/config.go index e8df0703..716889cd 100644 --- a/dnscrypt-proxy/config.go +++ b/dnscrypt-proxy/config.go @@ -13,7 +13,7 @@ import ( "github.com/BurntSushi/toml" "github.com/jedisct1/dlog" - stamps "github.com/jedisct1/dnscrypt-proxy/dnsstamps" + stamps "github.com/jedisct1/go-dnsstamps" ) type Config struct { diff --git a/dnscrypt-proxy/proxy.go b/dnscrypt-proxy/proxy.go index 20007e2c..1735ba31 100644 --- a/dnscrypt-proxy/proxy.go +++ b/dnscrypt-proxy/proxy.go @@ -9,7 +9,7 @@ import ( "time" "github.com/jedisct1/dlog" - stamps "github.com/jedisct1/dnscrypt-proxy/dnsstamps" + stamps "github.com/jedisct1/go-dnsstamps" clocksmith "github.com/jedisct1/go-clocksmith" "golang.org/x/crypto/curve25519" ) diff --git a/dnscrypt-proxy/serversInfo.go b/dnscrypt-proxy/serversInfo.go index ffc8a93f..7d3770f1 100644 --- a/dnscrypt-proxy/serversInfo.go +++ b/dnscrypt-proxy/serversInfo.go @@ -17,7 +17,7 @@ import ( "github.com/VividCortex/ewma" "github.com/jedisct1/dlog" - stamps "github.com/jedisct1/dnscrypt-proxy/dnsstamps" + stamps "github.com/jedisct1/go-dnsstamps" "golang.org/x/crypto/ed25519" ) diff --git a/dnscrypt-proxy/sources.go b/dnscrypt-proxy/sources.go index aac01ed0..b8a8356c 100644 --- a/dnscrypt-proxy/sources.go +++ b/dnscrypt-proxy/sources.go @@ -17,7 +17,7 @@ import ( "github.com/dchest/safefile" "github.com/jedisct1/dlog" - stamps "github.com/jedisct1/dnscrypt-proxy/dnsstamps" + stamps "github.com/jedisct1/go-dnsstamps" "github.com/jedisct1/go-minisign" ) diff --git a/dnscrypt-proxy/xtransport.go b/dnscrypt-proxy/xtransport.go index 84cbe2af..eda95c59 100644 --- a/dnscrypt-proxy/xtransport.go +++ b/dnscrypt-proxy/xtransport.go @@ -18,7 +18,7 @@ import ( "time" "github.com/jedisct1/dlog" - stamps "github.com/jedisct1/dnscrypt-proxy/dnsstamps" + stamps "github.com/jedisct1/go-dnsstamps" "github.com/miekg/dns" "golang.org/x/net/http2" ) diff --git a/vendor/github.com/jedisct1/go-dnsstamps/.gitignore b/vendor/github.com/jedisct1/go-dnsstamps/.gitignore new file mode 100644 index 00000000..a1338d68 --- /dev/null +++ b/vendor/github.com/jedisct1/go-dnsstamps/.gitignore @@ -0,0 +1,14 @@ +# Binaries for programs and plugins +*.exe +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 +.glide/ diff --git a/vendor/github.com/jedisct1/go-dnsstamps/Gopkg.lock b/vendor/github.com/jedisct1/go-dnsstamps/Gopkg.lock new file mode 100644 index 00000000..d5b6c780 --- /dev/null +++ b/vendor/github.com/jedisct1/go-dnsstamps/Gopkg.lock @@ -0,0 +1,18 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + branch = "master" + name = "golang.org/x/crypto" + packages = [ + "ed25519", + "ed25519/internal/edwards25519" + ] + revision = "d6449816ce06963d9d136eee5a56fca5b0616e7e" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "5046e265393bd5e54f570ce29ae8bc6fa3f30ef5110e922996540400f287c64a" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/vendor/github.com/jedisct1/go-dnsstamps/Gopkg.toml b/vendor/github.com/jedisct1/go-dnsstamps/Gopkg.toml new file mode 100644 index 00000000..b35918c2 --- /dev/null +++ b/vendor/github.com/jedisct1/go-dnsstamps/Gopkg.toml @@ -0,0 +1,25 @@ +# Gopkg.toml example +# +# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md +# for detailed Gopkg.toml documentation. +# +# required = ["github.com/user/thing/cmd/thing"] +# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] +# +# [[constraint]] +# name = "github.com/user/project" +# version = "1.0.0" +# +# [[constraint]] +# name = "github.com/user/project2" +# branch = "dev" +# source = "github.com/myfork/project2" +# +# [[override]] +# name = "github.com/x/y" +# version = "2.4.0" + + +[[constraint]] + branch = "master" + name = "golang.org/x/crypto" diff --git a/vendor/github.com/jedisct1/go-dnsstamps/LICENSE b/vendor/github.com/jedisct1/go-dnsstamps/LICENSE new file mode 100644 index 00000000..74a9a9b2 --- /dev/null +++ b/vendor/github.com/jedisct1/go-dnsstamps/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Frank Denis + +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/jedisct1/go-dnsstamps/README.md b/vendor/github.com/jedisct1/go-dnsstamps/README.md new file mode 100644 index 00000000..27c479aa --- /dev/null +++ b/vendor/github.com/jedisct1/go-dnsstamps/README.md @@ -0,0 +1,2 @@ +# go-dnsstamps +DNS Stamps library for Go diff --git a/dnsstamps/dnsstamps.go b/vendor/github.com/jedisct1/go-dnsstamps/dnsstamps.go similarity index 100% rename from dnsstamps/dnsstamps.go rename to vendor/github.com/jedisct1/go-dnsstamps/dnsstamps.go diff --git a/vendor/golang.org/x/net/http/httpguts/guts.go b/vendor/golang.org/x/net/http/httpguts/guts.go new file mode 100644 index 00000000..e6cd0ced --- /dev/null +++ b/vendor/golang.org/x/net/http/httpguts/guts.go @@ -0,0 +1,50 @@ +// Copyright 2018 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. + +// Package httpguts provides functions implementing various details +// of the HTTP specification. +// +// This package is shared by the standard library (which vendors it) +// and x/net/http2. It comes with no API stability promise. +package httpguts + +import ( + "net/textproto" + "strings" +) + +// ValidTrailerHeader reports whether name is a valid header field name to appear +// in trailers. +// See RFC 7230, Section 4.1.2 +func ValidTrailerHeader(name string) bool { + name = textproto.CanonicalMIMEHeaderKey(name) + if strings.HasPrefix(name, "If-") || badTrailer[name] { + return false + } + return true +} + +var badTrailer = map[string]bool{ + "Authorization": true, + "Cache-Control": true, + "Connection": true, + "Content-Encoding": true, + "Content-Length": true, + "Content-Range": true, + "Content-Type": true, + "Expect": true, + "Host": true, + "Keep-Alive": true, + "Max-Forwards": true, + "Pragma": true, + "Proxy-Authenticate": true, + "Proxy-Authorization": true, + "Proxy-Connection": true, + "Range": true, + "Realm": true, + "Te": true, + "Trailer": true, + "Transfer-Encoding": true, + "Www-Authenticate": true, +} diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go index 39ed755a..72f65c8f 100644 --- a/vendor/golang.org/x/net/http2/server.go +++ b/vendor/golang.org/x/net/http2/server.go @@ -46,6 +46,7 @@ import ( "sync" "time" + "golang.org/x/net/http/httpguts" "golang.org/x/net/http2/hpack" ) @@ -1817,7 +1818,7 @@ func (st *stream) processTrailerHeaders(f *MetaHeadersFrame) error { if st.trailer != nil { for _, hf := range f.RegularFields() { key := sc.canonicalHeader(hf.Name) - if !ValidTrailerHeader(key) { + if !httpguts.ValidTrailerHeader(key) { // TODO: send more details to the peer somehow. But http2 has // no way to send debug data at a stream level. Discuss with // HTTP folk. @@ -2284,7 +2285,7 @@ func (rws *responseWriterState) hasTrailers() bool { return len(rws.trailers) != // written in the trailers at the end of the response. func (rws *responseWriterState) declareTrailer(k string) { k = http.CanonicalHeaderKey(k) - if !ValidTrailerHeader(k) { + if !httpguts.ValidTrailerHeader(k) { // Forbidden by RFC 7230, section 4.1.2. rws.conn.logf("ignoring invalid trailer %q", k) return @@ -2323,7 +2324,15 @@ func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) { } _, hasContentType := rws.snapHeader["Content-Type"] if !hasContentType && bodyAllowedForStatus(rws.status) && len(p) > 0 { - ctype = http.DetectContentType(p) + if cto := rws.snapHeader.Get("X-Content-Type-Options"); strings.EqualFold("nosniff", cto) { + // nosniff is an explicit directive not to guess a content-type. + // Content-sniffing is no less susceptible to polyglot attacks via + // hosted content when done on the server. + ctype = "application/octet-stream" + rws.conn.logf("http2: WriteHeader called with X-Content-Type-Options:nosniff but no Content-Type") + } else { + ctype = http.DetectContentType(p) + } } var date string if _, ok := rws.snapHeader["Date"]; !ok { @@ -2838,41 +2847,6 @@ func new400Handler(err error) http.HandlerFunc { } } -// ValidTrailerHeader reports whether name is a valid header field name to appear -// in trailers. -// See: http://tools.ietf.org/html/rfc7230#section-4.1.2 -func ValidTrailerHeader(name string) bool { - name = http.CanonicalHeaderKey(name) - if strings.HasPrefix(name, "If-") || badTrailer[name] { - return false - } - return true -} - -var badTrailer = map[string]bool{ - "Authorization": true, - "Cache-Control": true, - "Connection": true, - "Content-Encoding": true, - "Content-Length": true, - "Content-Range": true, - "Content-Type": true, - "Expect": true, - "Host": true, - "Keep-Alive": true, - "Max-Forwards": true, - "Pragma": true, - "Proxy-Authenticate": true, - "Proxy-Authorization": true, - "Proxy-Connection": true, - "Range": true, - "Realm": true, - "Te": true, - "Trailer": true, - "Transfer-Encoding": true, - "Www-Authenticate": true, -} - // h1ServerKeepAlivesDisabled reports whether hs has its keep-alives // disabled. See comments on h1ServerShutdownChan above for why // the code is written this way. diff --git a/vendor/golang.org/x/net/http2/server_test.go b/vendor/golang.org/x/net/http2/server_test.go index c5d8459c..4d66a4be 100644 --- a/vendor/golang.org/x/net/http2/server_test.go +++ b/vendor/golang.org/x/net/http2/server_test.go @@ -1760,6 +1760,42 @@ func TestServer_Response_Data_Sniff_DoesntOverride(t *testing.T) { }) } +func TestServer_Response_Nosniff_WithoutContentType(t *testing.T) { + const msg = "this is HTML." + testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { + w.Header().Set("X-Content-Type-Options", "nosniff") + w.WriteHeader(200) + io.WriteString(w, msg) + return nil + }, func(st *serverTester) { + getSlash(st) + hf := st.wantHeaders() + if hf.StreamEnded() { + t.Fatal("don't want END_STREAM, expecting data") + } + if !hf.HeadersEnded() { + t.Fatal("want END_HEADERS flag") + } + goth := st.decodeHeader(hf.HeaderBlockFragment()) + wanth := [][2]string{ + {":status", "200"}, + {"x-content-type-options", "nosniff"}, + {"content-type", "application/octet-stream"}, + {"content-length", strconv.Itoa(len(msg))}, + } + if !reflect.DeepEqual(goth, wanth) { + t.Errorf("Got headers %v; want %v", goth, wanth) + } + df := st.wantData() + if !df.StreamEnded() { + t.Error("expected DATA to have END_STREAM flag") + } + if got := string(df.Data()); got != msg { + t.Errorf("got DATA %q; want %q", got, msg) + } + }) +} + func TestServer_Response_TransferEncoding_chunked(t *testing.T) { const msg = "hi" testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error {