Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vendor all dependencies #1651

Merged
merged 1 commit into from
May 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
8 changes: 5 additions & 3 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ Here are some of the expectations we have of contributors:

- **Write tests.** Tests are essential! Written properly, they ensure your change works, and that other changes in the future won't break your change. CI checks should pass.

- **Benchmarks should be included for optimizations.** Optimizations sometimes make code harder to read or have changes that are less than obvious. They should be proven to work better with benchmarks or profiling.
- **Benchmarks should be included for optimizations.** Optimizations sometimes make code harder to read or have changes that are less than obvious. They should be proven with benchmarks or profiling.

- **[Squash](http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html) insignificant commits.** Every commit should be significant. Commits which merely rewrite a comment or fix a typo can be combined into another commit that has more substance.
- **[Squash](http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html) insignificant commits.** Every commit should be significant. Commits which merely rewrite a comment or fix a typo can be combined into another commit that has more substance. Interactive rebase can do this, or a simpler way is `git reset --soft <diverging-commit>` then `git commit -s`.

- **Own your contributions.** Caddy is a growing project, and it's much better when individual contributors can help maintain their change after it is merged.

Expand Down Expand Up @@ -126,7 +126,9 @@ Collabators have push rights to the repository. We grant this permission after o

- **Do not merge pull requests until they have been approved by one or two other collaborators.** If a project owner approves the PR, it can be merged (as long as the conversation has finished too).

- **Prefer squashed commits over a messy merge.** If there are many little commits, please squash the commits so we don't clutter the commit history.
- **Prefer squashed commits over a messy merge.** If there are many little commits, please [squash the commits](https://stackoverflow.com/a/11732910/1048862) so we don't clutter the commit history.

- **Don't accept new dependencies lightly.** Dependencies can make the world crash and burn, but they are sometimes necessary. Choose carefully. Extremely small dependencies (a few lines of code) can be inlined. The rest may not be needed. For those that are, Caddy vendors all dependencies with the help of [gvt](https://github.com/FiloSottile/gvt). All external dependencies must be vendored, and _Caddy must not export any types defined by those dependencies_. Check this diligently!

- **Be extra careful in some areas of the code.** There are some critical areas in the Caddy code base that we review extra meticulously: the `caddy` and `caddytls` packages especially.

Expand Down
21 changes: 13 additions & 8 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
language: go

go:
- 1.8
- 1.8.3
- tip

matrix:
Expand All @@ -20,15 +20,20 @@ install:
- if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash dist/gitcookie.sh; fi
- go get -t ./...
- go get github.com/golang/lint/golint
- go get github.com/gordonklaus/ineffassign
- go get github.com/FiloSottile/vendorcheck
# Install gometalinter and certain linters
- go get github.com/alecthomas/gometalinter
- go get github.com/client9/misspell/cmd/misspell
- go get github.com/gordonklaus/ineffassign
- go get golang.org/x/tools/cmd/goimports
- go get github.com/tsenart/deadcode

script:
- diff <(echo -n) <(gofmt -s -d .)
- ineffassign .
- misspell -error .
- go vet ./...
- go test -race ./...
- gometalinter --disable-all -E vet -E gofmt -E misspell -E ineffassign -E goimports -E deadcode --tests --vendor ./...
- vendorcheck ./...
# TODO: When Go 1.9 is released, replace $(go list) subcommand with ./... because vendor folder should be ignored
- go test -race $(go list ./... | grep -v vendor)

after_script:
- golint ./...
# TODO: When Go 1.9 is released, replace $(go list) subcommand with ./... because vendor folder should be ignored
- golint $(go list ./... | grep -v vendor)
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ The Caddy project does not officially maintain any system-specific integrations

How you choose to run Caddy is up to you. Many users are satisfied with `nohup caddy &`. Others use `screen`. Users who need Caddy to come back up after reboots either do so in the script that caused the reboot, add a command to an init script, or configure a service with their OS.

If you have questions or concerns about Caddy' underlying crypto implementations, consult Go's [crypto packages](https://golang.org/pkg/crypto), starting with their documentation, then issues, then the code itself; as Caddy uses mainly those libraries.


## Contributing

Expand Down
22 changes: 15 additions & 7 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,31 @@ environment:

install:
- rmdir c:\go /s /q
- appveyor DownloadFile https://storage.googleapis.com/golang/go1.8.windows-amd64.zip
- 7z x go1.8.windows-amd64.zip -y -oC:\ > NUL
- appveyor DownloadFile https://storage.googleapis.com/golang/go1.8.3.windows-amd64.zip
- 7z x go1.8.3.windows-amd64.zip -y -oC:\ > NUL
- set PATH=%GOPATH%\bin;%PATH%
- go version
- go env
- go get -t ./...
- go get github.com/golang/lint/golint
- go get github.com/FiloSottile/vendorcheck
# Install gometalinter and certain linters
- go get github.com/alecthomas/gometalinter
- go get github.com/client9/misspell/cmd/misspell
- go get github.com/gordonklaus/ineffassign
- set PATH=%GOPATH%\bin;%PATH%
- go get golang.org/x/tools/cmd/goimports
- go get github.com/tsenart/deadcode

build: off

test_script:
- go vet ./...
- go test -race ./...
- ineffassign .
- gometalinter --disable-all -E vet -E gofmt -E misspell -E ineffassign -E goimports -E deadcode --tests --vendor ./...
- vendorcheck ./...
# TODO: When Go 1.9 comes out, replace this whole line with `go test -race ./...` b/c vendor folder should be ignored
- for /f "" %%G in ('go list ./... ^| find /i /v "/vendor/"') do (go test -race %%G & IF ERRORLEVEL == 1 EXIT 1)

after_test:
- golint ./...
# TODO: When Go 1.9 comes out, replace this whole line with `golint ./...` b/c vendor folder should be ignored
- for /f "" %%G in ('go list ./... ^| find /i /v "/vendor/"') do (golint %%G & IF ERRORLEVEL == 1 EXIT 1)

deploy: off
2 changes: 1 addition & 1 deletion caddyhttp/caddyhttp.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ import (
_ "github.com/mholt/caddy/caddyhttp/header"
_ "github.com/mholt/caddy/caddyhttp/index"
_ "github.com/mholt/caddy/caddyhttp/internalsrv"
_ "github.com/mholt/caddy/caddyhttp/limits"
_ "github.com/mholt/caddy/caddyhttp/log"
_ "github.com/mholt/caddy/caddyhttp/markdown"
_ "github.com/mholt/caddy/caddyhttp/maxrequestbody"
_ "github.com/mholt/caddy/caddyhttp/mime"
_ "github.com/mholt/caddy/caddyhttp/pprof"
_ "github.com/mholt/caddy/caddyhttp/proxy"
Expand Down
55 changes: 35 additions & 20 deletions caddyhttp/httpserver/condition.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,16 @@ func SetupIfMatcher(controller *caddy.Controller) (RequestMatcher, error) {

// operators
const (
isOp = "is"
notOp = "not"
hasOp = "has"
notHasOp = "not_has"
startsWithOp = "starts_with"
endsWithOp = "ends_with"
matchOp = "match"
notMatchOp = "not_match"
isOp = "is"
notOp = "not"
hasOp = "has"
notHasOp = "not_has"
startsWithOp = "starts_with"
notStartsWithOp = "not_starts_with"
endsWithOp = "ends_with"
notEndsWithOp = "not_ends_with"
matchOp = "match"
notMatchOp = "not_match"
)

func operatorError(operator string) error {
Expand All @@ -63,14 +65,16 @@ func operatorError(operator string) error {
type ifCondition func(string, string) bool

var ifConditions = map[string]ifCondition{
isOp: isFunc,
notOp: notFunc,
hasOp: hasFunc,
notHasOp: notHasFunc,
startsWithOp: startsWithFunc,
endsWithOp: endsWithFunc,
matchOp: matchFunc,
notMatchOp: notMatchFunc,
isOp: isFunc,
notOp: notFunc,
hasOp: hasFunc,
notHasOp: notHasFunc,
startsWithOp: startsWithFunc,
notStartsWithOp: notStartsWithFunc,
endsWithOp: endsWithFunc,
notEndsWithOp: notEndsWithFunc,
matchOp: matchFunc,
notMatchOp: notMatchFunc,
}

// isFunc is condition for Is operator.
Expand All @@ -82,7 +86,7 @@ func isFunc(a, b string) bool {
// notFunc is condition for Not operator.
// It checks for inequality.
func notFunc(a, b string) bool {
return a != b
return !isFunc(a, b)
}

// hasFunc is condition for Has operator.
Expand All @@ -94,7 +98,7 @@ func hasFunc(a, b string) bool {
// notHasFunc is condition for NotHas operator.
// It checks if b is not a substring of a.
func notHasFunc(a, b string) bool {
return !strings.Contains(a, b)
return !hasFunc(a, b)
}

// startsWithFunc is condition for StartsWith operator.
Expand All @@ -103,12 +107,24 @@ func startsWithFunc(a, b string) bool {
return strings.HasPrefix(a, b)
}

// notStartsWithFunc is condition for NotStartsWith operator.
// It checks if b is not a prefix of a.
func notStartsWithFunc(a, b string) bool {
return !startsWithFunc(a, b)
}

// endsWithFunc is condition for EndsWith operator.
// It checks if b is a suffix of a.
func endsWithFunc(a, b string) bool {
return strings.HasSuffix(a, b)
}

// notEndsWithFunc is condition for NotEndsWith operator.
// It checks if b is not a suffix of a.
func notEndsWithFunc(a, b string) bool {
return !endsWithFunc(a, b)
}

// matchFunc is condition for Match operator.
// It does regexp matching of a against pattern in b
// and returns if they match.
Expand All @@ -121,8 +137,7 @@ func matchFunc(a, b string) bool {
// It does regexp matching of a against pattern in b
// and returns if they do not match.
func notMatchFunc(a, b string) bool {
matched, _ := regexp.MatchString(b, a)
return !matched
return !matchFunc(a, b)
}

// ifCond is statement for a IfMatcher condition.
Expand Down
12 changes: 9 additions & 3 deletions caddyhttp/httpserver/condition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,15 @@ func TestConditions(t *testing.T) {
{"bab starts_with bb", false},
{"bab starts_with ba", true},
{"bab starts_with bab", true},
{"bab not_starts_with bb", true},
{"bab not_starts_with ba", false},
{"bab not_starts_with bab", false},
{"bab ends_with bb", false},
{"bab ends_with bab", true},
{"bab ends_with ab", true},
{"bab not_ends_with bb", true},
{"bab not_ends_with ab", false},
{"bab not_ends_with bab", false},
{"a match *", false},
{"a match a", true},
{"a match .*", true},
Expand Down Expand Up @@ -221,7 +227,7 @@ func TestSetupIfMatcher(t *testing.T) {
},
{`test {
if goal has go
if cook not_has go
if cook not_has go
}`, false, IfMatcher{
ifs: []ifCond{
{a: "goal", op: "has", b: "go"},
Expand All @@ -230,7 +236,7 @@ func TestSetupIfMatcher(t *testing.T) {
}},
{`test {
if goal has go
if cook not_has go
if cook not_has go
if_op and
}`, false, IfMatcher{
ifs: []ifCond{
Expand All @@ -240,7 +246,7 @@ func TestSetupIfMatcher(t *testing.T) {
}},
{`test {
if goal has go
if cook not_has go
if cook not_has go
if_op not
}`, true, IfMatcher{},
},
Expand Down
2 changes: 1 addition & 1 deletion caddyhttp/httpserver/logger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"sync"
"testing"

"gopkg.in/mcuadros/go-syslog.v2"
syslog "gopkg.in/mcuadros/go-syslog.v2"
"gopkg.in/mcuadros/go-syslog.v2/format"
)

Expand Down
55 changes: 37 additions & 18 deletions caddyhttp/httpserver/mitm.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,24 +326,34 @@ func (info rawHelloInfo) looksLikeFirefox() bool {
// EC point formats, and handshake compression methods."

// We check for the presence and order of the extensions.
// Note: Sometimes padding (21) is present, sometimes not.
// Note: Sometimes 0x15 (21, padding) is present, sometimes not.
// Note: Firefox 51+ does not advertise 0x3374 (13172, NPN).
// Note: Firefox doesn't advertise 0x0 (0, SNI) when connecting to IP addresses.
requiredExtensionsOrder := []uint16{23, 65281, 10, 11, 35, 16, 5, 65283, 13}
// Note: Firefox 55+ doesn't appear to advertise 0xFF03 (65283, short headers). It used to be between 5 and 13.
requiredExtensionsOrder := []uint16{23, 65281, 10, 11, 35, 16, 5, 13}
if !assertPresenceAndOrdering(requiredExtensionsOrder, info.extensions, true) {
return false
}

// We check for both presence of curves and their ordering.
expectedCurves := []tls.CurveID{29, 23, 24, 25}
if len(info.curves) != len(expectedCurves) {
requiredCurves := []tls.CurveID{29, 23, 24, 25}
if len(info.curves) < len(requiredCurves) {
return false
}
for i := range expectedCurves {
if info.curves[i] != expectedCurves[i] {
for i := range requiredCurves {
if info.curves[i] != requiredCurves[i] {
return false
}
}
if len(info.curves) > len(requiredCurves) {
// newer Firefox (55 Nightly?) may have additional curves at end of list
allowedCurves := []tls.CurveID{256, 257}
for i := range allowedCurves {
if info.curves[len(requiredCurves)+i] != allowedCurves[i] {
return false
}
}
}

if hasGreaseCiphers(info.cipherSuites) {
return false
Expand All @@ -353,6 +363,9 @@ func (info rawHelloInfo) looksLikeFirefox() bool {
// according to the paper, cipher suites may be not be added
// or reordered by the user, but they may be disabled.
expectedCipherSuiteOrder := []uint16{
TLS_AES_128_GCM_SHA256, // 0x1301
TLS_CHACHA20_POLY1305_SHA256, // 0x1303
TLS_AES_256_GCM_SHA384, // 0x1302
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, // 0xc02b
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, // 0xc02f
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, // 0xcca9
Expand Down Expand Up @@ -401,14 +414,14 @@ func (info rawHelloInfo) looksLikeChrome() bool {
// 0xc00a, 0xc014, 0xc009, 0x9c, 0x9d, 0x2f, 0x35, 0xa

chromeCipherExclusions := map[uint16]struct{}{
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: {}, // 0xc024
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: {}, // 0xc023
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: {}, // 0xc028
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: {}, // 0xc027
TLS_RSA_WITH_AES_256_CBC_SHA256: {}, // 0x3d
tls.TLS_RSA_WITH_AES_128_CBC_SHA256: {}, // 0x3c
TLS_DHE_RSA_WITH_AES_128_CBC_SHA: {}, // 0x33
TLS_DHE_RSA_WITH_AES_256_CBC_SHA: {}, // 0x39
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: {}, // 0xc024
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: {}, // 0xc023
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: {}, // 0xc028
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: {}, // 0xc027
TLS_RSA_WITH_AES_256_CBC_SHA256: {}, // 0x3d
tls.TLS_RSA_WITH_AES_128_CBC_SHA256: {}, // 0x3c
TLS_DHE_RSA_WITH_AES_128_CBC_SHA: {}, // 0x33
TLS_DHE_RSA_WITH_AES_256_CBC_SHA: {}, // 0x39
}
for _, ext := range info.cipherSuites {
if _, ok := chromeCipherExclusions[ext]; ok {
Expand Down Expand Up @@ -511,7 +524,7 @@ func (info rawHelloInfo) looksLikeSafari() bool {
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, // 0xc02c
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, // 0xc02b
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, // 0xc024
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, // 0xc023
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, // 0xc023
tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, // 0xc00a
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, // 0xc009
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, // 0xc030
Expand All @@ -523,7 +536,7 @@ func (info rawHelloInfo) looksLikeSafari() bool {
tls.TLS_RSA_WITH_AES_256_GCM_SHA384, // 0x9d
tls.TLS_RSA_WITH_AES_128_GCM_SHA256, // 0x9c
TLS_RSA_WITH_AES_256_CBC_SHA256, // 0x3d
TLS_RSA_WITH_AES_128_CBC_SHA256, // 0x3c
tls.TLS_RSA_WITH_AES_128_CBC_SHA256, // 0x3c
tls.TLS_RSA_WITH_AES_256_CBC_SHA, // 0x35
tls.TLS_RSA_WITH_AES_128_CBC_SHA, // 0x2f
}
Expand Down Expand Up @@ -610,11 +623,17 @@ const (
// cipher suites missing from the crypto/tls package,
// in no particular order here
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xc024
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xc023
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xc028
TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x3c
TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x3d
TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x33
TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x39
TLS_RSA_WITH_RC4_128_MD5 = 0x4

// new PSK ciphers introduced by TLS 1.3, not (yet) in crypto/tls
// https://tlswg.github.io/tls13-spec/#rfc.appendix.A.4)
TLS_AES_128_GCM_SHA256 = 0x1301
TLS_AES_256_GCM_SHA384 = 0x1302
TLS_CHACHA20_POLY1305_SHA256 = 0x1303
TLS_AES_128_CCM_SHA256 = 0x1304
TLS_AES_128_CCM_8_SHA256 = 0x1305
)