summaryrefslogtreecommitdiff
path: root/api/server/middleware
Commit message (Collapse)AuthorAgeFilesLines
* api/server: fix empty-lines (revive)Sebastiaan van Stijn2022-09-281-1/+0
| | | | | | | | api/server/router/build/build_routes.go:239:32: empty-lines: extra empty line at the start of a block (revive) api/server/middleware/version.go:45:241: empty-lines: extra empty line at the end of a block (revive) api/server/router/swarm/helpers_test.go:11:44: empty-lines: extra empty line at the end of a block (revive) Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
* api: add const for 'X-Registry-Auth'Sebastiaan van Stijn2022-07-291-1/+2
| | | | Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
* bump gotest.tools v3.0.1 for compatibility with Go 1.14Sebastiaan van Stijn2020-02-112-4/+4
| | | | | | full diff: https://github.com/gotestyourself/gotest.tools/compare/v2.3.0...v3.0.1 Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
* api/server: use constants for http methodsSebastiaan van Stijn2019-10-132-3/+3
| | | | Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
* DebugRequestMiddleware: Remove path handlingSebastiaan van Stijn2019-07-092-50/+8
| | | | | | | | Path-specific rules were removed, so this is no longer used. Signed-off-by: Sebastiaan van Stijn <github@gone.nl> (cherry picked from commit 530e63c1a61b105a6f7fc143c5acb9b5cd87f958) Signed-off-by: Tibor Vass <tibor@docker.com>
* DebugRequestMiddleware: unconditionally scrub data fieldSebastiaan van Stijn2019-07-092-10/+32
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Commit 77b8465d7e68ca102d7aae839c7b3fe0ecd28398 added a secret update endpoint to allow updating labels on existing secrets. However, when implementing the endpoint, the DebugRequestMiddleware was not updated to scrub the Data field (as is being done when creating a secret). When updating a secret (to set labels), the Data field should be either `nil` (not set), or contain the same value as the existing secret. In situations where the Data field is set, and the `dockerd` daemon is running with debugging enabled / log-level debug, the base64-encoded value of the secret is printed to the daemon logs. The docker cli does not have a `docker secret update` command, but when using `docker stack deploy`, the docker cli sends the secret data both when _creating_ a stack, and when _updating_ a stack, thus leaking the secret data if the daemon runs with debug enabled: 1. Start the daemon in debug-mode dockerd --debug 2. Initialize swarm docker swarm init 3. Create a file containing a secret echo secret > my_secret.txt 4. Create a docker-compose file using that secret cat > docker-compose.yml <<'EOF' version: "3.3" services: web: image: nginx:alpine secrets: - my_secret secrets: my_secret: file: ./my_secret.txt EOF 5. Deploy the stack docker stack deploy -c docker-compose.yml test 6. Verify that the secret is scrubbed in the daemon logs DEBU[2019-07-01T22:36:08.170617400Z] Calling POST /v1.30/secrets/create DEBU[2019-07-01T22:36:08.171364900Z] form data: {"Data":"*****","Labels":{"com.docker.stack.namespace":"test"},"Name":"test_my_secret"} 7. Re-deploy the stack to trigger an "update" docker stack deploy -c docker-compose.yml test 8. Notice that this time, the Data field is not scrubbed, and the base64-encoded secret is logged DEBU[2019-07-01T22:37:35.828819400Z] Calling POST /v1.30/secrets/w3hgvwpzl8yooq5ctnyp71v52/update?version=34 DEBU[2019-07-01T22:37:35.829993700Z] form data: {"Data":"c2VjcmV0Cg==","Labels":{"com.docker.stack.namespace":"test"},"Name":"test_my_secret"} This patch modifies `maskSecretKeys` to unconditionally scrub `Data` fields. Currently, only the `secrets` and `configs` endpoints use a field with this name, and no other POST API endpoints use a data field, so scrubbing this field unconditionally will only scrub requests for those endpoints. If a new endpoint is added in future where this field should not be scrubbed, we can re-introduce more fine-grained (path-specific) handling. This patch introduces some change in behavior: - In addition to secrets, requests to create or update _configs_ will now have their `Data` field scrubbed. Generally, the actual data should not be interesting for debugging, so likely will not be problematic. In addition, scrubbing this data for configs may actually be desirable, because (even though they are not explicitely designed for this purpose) configs may contain sensitive data (credentials inside a configuration file, e.g.). - Requests that send key/value pairs as a "map" and that contain a key named "data", will see the value of that field scrubbed. This means that (e.g.) setting a `label` named `data` on a config, will scrub/mask the value of that label. - Note that this is already the case for any label named `jointoken`, `password`, `secret`, `signingcakey`, or `unlockkey`. Signed-off-by: Sebastiaan van Stijn <github@gone.nl> (cherry picked from commit c7ce4be93ae8edd2da62a588e01c67313a4aba0c) Signed-off-by: Tibor Vass <tibor@docker.com>
* TestMaskSecretKeys: use subtestsSebastiaan van Stijn2019-07-091-2/+10
| | | | | | Signed-off-by: Sebastiaan van Stijn <github@gone.nl> (cherry picked from commit 32d70c7e21631224674cd60021d3ec908c2d888c) Signed-off-by: Tibor Vass <tibor@docker.com>
* TestMaskSecretKeys: add more test-casesSebastiaan van Stijn2019-07-091-3/+27
| | | | | | | | | | | Add tests for - case-insensitive matching of fields - recursive masking Signed-off-by: Sebastiaan van Stijn <github@gone.nl> (cherry picked from commit db5f811216e70bcb4a10e477c1558d6c68f618c5) Signed-off-by: Tibor Vass <tibor@docker.com>
* api/server, dockerversion: modify context keyKimMachineGun2018-08-221-1/+1
| | | | Signed-off-by: KimMachineGun <geon0250@gmail.com>
* Update tests to use gotest.tools 👼Vincent Demeester2018-06-132-4/+4
| | | | Signed-off-by: Vincent Demeester <vincent@sbr.pm>
* Switch from x/net/context -> contextKir Kolyshkin2018-04-236-8/+6
| | | | | | | | | | | Since Go 1.7, context is a standard package. Since Go 1.9, everything that is provided by "x/net/context" is a couple of type aliases to types in "context". Many vendored packages still use x/net/context, so vendor entry remains for now. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
* Automated migration usingDaniel Nephin2018-03-162-12/+14
| | | | | | gty-migrate-from-testify --ignore-build-tags Signed-off-by: Daniel Nephin <dnephin@docker.com>
* Add canonical import commentDaniel Nephin2018-02-057-7/+7
| | | | Signed-off-by: Daniel Nephin <dnephin@docker.com>
* Merge pull request #36013 from thaJeztah/improve-version-middleware-testVincent Demeester2018-01-221-56/+35
|\ | | | | Improve API version-middleware test
| * Improve API version-middleware testSebastiaan van Stijn2018-01-151-56/+35
| | | | | | | | | | | | | | | | | | | | Some improvements to the test; - Combine tests to reduce duplicated code - Add test-cases for empty version in request using the default version - Add test for valid versions in request actually setting the version Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
* | Golint: don't use basic untyped string for context keySebastiaan van Stijn2018-01-151-2/+2
|/ | | | Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
* Always return version and server headersSebastiaan van Stijn2017-10-112-5/+34
| | | | | | | | | | | | | | If a 400 error is returned due to an API version mismatch, no version and server-identification headers were returned by the API. All information in these headers is "static", so there is no reason to omit the information in case of an error being returned. This patch updates the version middleware to always return the headers. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
* Return 400 error if API client is too newSebastiaan van Stijn2017-10-102-5/+35
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Commit e98e4a71110fd33852bb755a9b8b4ebc9df904db implemented API version negotiation using the `/_ping` endpoint. In that change, URL validation for the maximum supported API version was removed from the API server (validation for the _minimum_ version was kept in place). With this feature, clients that support version negotiation would negotiate the maximum version supported by the daemon, and downgrade to an older API version if the client's default API version is not supported. However, clients that do _not_ support version negotiation can call API versions that are higher than the maximum supported version. Due to the missing version check, this is silently ignored, and the daemon's default API version is used. This is a problem, because the actual API version in use is non-deterministic; for example, calling `/v9999.9999/version` on a daemon that runs API v1.34 will use API v1.34, but calling the same URL on an older daemon may use API version v1.24. This patch reverts the removal of the API check for maximum supported versions. The documentation has been updated accordingly Before this patch is applied, the daemon returns a 200 (success): $ curl -v --unix-socket /var/run/docker.sock http://localhost/v9999.9999/version * Trying /var/run/docker.sock... * Connected to localhost (/Users/sebastiaan/Library/Containers/com.dock) port 80 (#0) > GET /v9999.9999/version HTTP/1.1 > Host: localhost > User-Agent: curl/7.54.0 > Accept: */* > < HTTP/1.1 200 OK < Api-Version: 1.32 < Content-Length: 240 < Content-Type: application/json < Date: Tue, 10 Oct 2017 09:11:29 GMT < Docker-Experimental: true < Ostype: linux < Server: Docker/17.09.0-ce (linux) < {"Version":"17.09.0-ce","ApiVersion":"1.32","MinAPIVersion":"1.12","GitCommit":"afdb6d4","GoVersion":"go1.8.3","Os":"linux","Arch":"amd64","KernelVersion":"4.9.49-moby","Experimental":true,"BuildTime":"2017-09-26T22:45:38.000000000+00:00"} * Connection #0 to host localhost left intact After this patch is applied, a 400 (Bad Request) is returned: $ curl -v --unix-socket /var/run/docker.sock http://localhost/v9999.9999/version * Trying /var/run/docker.sock... * Connected to localhost (/var/run/docker.sock) port 80 (#0) > GET /v9999.9999/info HTTP/1.1 > Host: localhost > User-Agent: curl/7.52.1 > Accept: */* > < HTTP/1.1 400 Bad Request < Content-Type: application/json < Date: Tue, 10 Oct 2017 08:08:34 GMT < Content-Length: 89 < {"message":"client version 9999.9999 is too new. Maximim supported API version is 1.34"} * Curl_http_done: called premature == 0 * Connection #0 to host localhost left intact Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
* Fix golint errors.Daniel Nephin2017-08-181-0/+1
| | | | Signed-off-by: Daniel Nephin <dnephin@docker.com>
* Remove string checking in API error handlingBrian Goff2017-08-151-2/+11
| | | | | | | | | | | | | | Use strongly typed errors to set HTTP status codes. Error interfaces are defined in the api/errors package and errors returned from controllers are checked against these interfaces. Errors can be wraeped in a pkg/errors.Causer, as long as somewhere in the line of causes one of the interfaces is implemented. The special error interfaces take precedence over Causer, meaning if both Causer and one of the new error interfaces are implemented, the Causer is not traversed. Signed-off-by: Brian Goff <cpuguy83@gmail.com>
* Update logrus to v1.0.1Derek McGowan2017-07-312-2/+2
| | | | | | Fixes case sensitivity issue Signed-off-by: Derek McGowan <derek@mcgstyle.net>
* middleware: Redact secret data on "secret create"Aaron Lehmann2017-06-292-4/+80
| | | | | | | | | | | With debug logging turned on, we currently log the base64-encoded secret payload. Change the middleware code to redact this. Since the field is called "Data", it requires some context-sensitivity. The URI path is examined to see which route is being invoked. Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
* Do not log the CA config CA signing key in debug mode.Ying Li2017-05-311-1/+1
| | | | Signed-off-by: Ying Li <ying.li@docker.com>
* Hide command options that are related to WindowsBoaz Shuster2017-03-121-0/+1
| | | | Signed-off-by: Boaz Shuster <ripcurld.github@gmail.com>
* use t.Fatal() to output the err message where the values used for formattingfate-grand-order2017-02-231-2/+2
| | | | | | text does not appear to contain a placeholder Signed-off-by: Helen Xie <chenjg@harmonycloud.cn>
* Revise swarm init/update flags, add unlocking capabilityAaron Lehmann2016-11-091-1/+1
| | | | | | | | | | - Neither swarm init or swarm update should take an unlock key - Add an autolock flag to turn on autolock - Make the necessary docker api changes - Add SwarmGetUnlockKey API call and use it when turning on autolock - Add swarm unlock-key subcommand Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
* Add support for swarm init lock and swarm unlockTonis Tiigi2016-11-091-1/+1
| | | | Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
* always add but hide experimental cmds and flagsVictor Vieux2016-11-083-56/+1
| | | | | | | | | | | | Signed-off-by: Victor Vieux <vieux@docker.com> update cobra and use Tags Signed-off-by: Victor Vieux <vieux@docker.com> allow client to talk to an older server Signed-off-by: Victor Vieux <vieux@docker.com>
* Make experimental a runtime flagKenfe-Mickael Laventure2016-10-241-0/+29
| | | | Signed-off-by: Kenfe-Mickael Laventure <mickael.laventure@gmail.com>
* Use apiError in server version middleware.Daniel Nephin2016-09-161-10/+3
| | | | Signed-off-by: Daniel Nephin <dnephin@docker.com>
* Add engine-api types to dockerMichael Crosby2016-09-072-2/+2
| | | | | | | This moves the types for the `engine-api` repo to the existing types package. Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
* Mask join tokens in daemon logsTonis Tiigi2016-08-021-1/+1
| | | Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
* Mask swarm secrets from daemon logsTonis Tiigi2016-06-301-3/+23
| | | Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
* Update code for latest engine-apiVincent Demeester2016-04-193-17/+16
| | | | | | | - Update CopyToContainer uses - Use engine-api/types/versions instead of pkg/version Signed-off-by: Vincent Demeester <vincent@sbr.pm>
* Move middleware to interfaces.David Calavera2016-04-117-123/+107
| | | | | | | | | | | This makes separating middlewares from the core api easier. As an example, the authorization middleware is moved to it's own package. Initialize all static middlewares when the server is created, reducing allocations every time a route is wrapper with the middlewares. Signed-off-by: David Calavera <david.calavera@gmail.com>
* Extend Docker authorization with TLS user informationLiron Levin2016-03-271-3/+11
| | | | | | | | | | | | | | Currently Docker authorization framework does not use any user information, which already available in the Docker context for TLS connection. The purpose of this CR is to complete the existing authz work by adding the basic client certificate details (SUBJECT_NAME) and authentication method (TLS) to the authz request. We think this should be the default behavior when no extended authorization module is specified (currently WIP under #20883). Signed-off-by: Liron Levin <liron@twistlock.com>
* Pass upstream client's user agent through to registry on image pullsMike Goelzer2016-03-201-0/+2
| | | | | | | | | | | | Changes how the Engine interacts with Registry servers on image pull. Previously, Engine sent a User-Agent string to the Registry server that included only the Engine's version information. This commit appends to that string the fields from the User-Agent sent by the client (e.g., Compose) of the Engine. This allows Registry server operators to understand what tools are actually generating pulls on their registries. Signed-off-by: Mike Goelzer <mgoelzer@docker.com>
* api: server: server: remove redunant debugfAntonio Murdaca2016-03-071-1/+1
| | | | Signed-off-by: Antonio Murdaca <runcom@redhat.com>
* fix typosallencloud2016-03-061-1/+1
| | | | Signed-off-by: allencloud <allen.sun@daocloud.io>
* Remove static errors from errors package.David Calavera2016-02-262-5/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Moving all strings to the errors package wasn't a good idea after all. Our custom implementation of Go errors predates everything that's nice and good about working with errors in Go. Take as an example what we have to do to get an error message: ```go func GetErrorMessage(err error) string { switch err.(type) { case errcode.Error: e, _ := err.(errcode.Error) return e.Message case errcode.ErrorCode: ec, _ := err.(errcode.ErrorCode) return ec.Message() default: return err.Error() } } ``` This goes against every good practice for Go development. The language already provides a simple, intuitive and standard way to get error messages, that is calling the `Error()` method from an error. Reinventing the error interface is a mistake. Our custom implementation also makes very hard to reason about errors, another nice thing about Go. I found several (>10) error declarations that we don't use anywhere. This is a clear sign about how little we know about the errors we return. I also found several error usages where the number of arguments was different than the parameters declared in the error, another clear example of how difficult is to reason about errors. Moreover, our custom implementation didn't really make easier for people to return custom HTTP status code depending on the errors. Again, it's hard to reason about when to set custom codes and how. Take an example what we have to do to extract the message and status code from an error before returning a response from the API: ```go switch err.(type) { case errcode.ErrorCode: daError, _ := err.(errcode.ErrorCode) statusCode = daError.Descriptor().HTTPStatusCode errMsg = daError.Message() case errcode.Error: // For reference, if you're looking for a particular error // then you can do something like : // import ( derr "github.com/docker/docker/errors" ) // if daError.ErrorCode() == derr.ErrorCodeNoSuchContainer { ... } daError, _ := err.(errcode.Error) statusCode = daError.ErrorCode().Descriptor().HTTPStatusCode errMsg = daError.Message default: // This part of will be removed once we've // converted everything over to use the errcode package // FIXME: this is brittle and should not be necessary. // If we need to differentiate between different possible error types, // we should create appropriate error types with clearly defined meaning errStr := strings.ToLower(err.Error()) for keyword, status := range map[string]int{ "not found": http.StatusNotFound, "no such": http.StatusNotFound, "bad parameter": http.StatusBadRequest, "conflict": http.StatusConflict, "impossible": http.StatusNotAcceptable, "wrong login/password": http.StatusUnauthorized, "hasn't been activated": http.StatusForbidden, } { if strings.Contains(errStr, keyword) { statusCode = status break } } } ``` You can notice two things in that code: 1. We have to explain how errors work, because our implementation goes against how easy to use Go errors are. 2. At no moment we arrived to remove that `switch` statement that was the original reason to use our custom implementation. This change removes all our status errors from the errors package and puts them back in their specific contexts. IT puts the messages back with their contexts. That way, we know right away when errors used and how to generate their messages. It uses custom interfaces to reason about errors. Errors that need to response with a custom status code MUST implementent this simple interface: ```go type errorWithStatus interface { HTTPErrorStatusCode() int } ``` This interface is very straightforward to implement. It also preserves Go errors real behavior, getting the message is as simple as using the `Error()` method. I included helper functions to generate errors that use custom status code in `errors/errors.go`. By doing this, we remove the hard dependency we have eeverywhere to our custom errors package. Yes, you can use it as a helper to generate error, but it's still very easy to generate errors without it. Please, read this fantastic blog post about errors in Go: http://dave.cheney.net/2014/12/24/inspecting-errors Signed-off-by: David Calavera <david.calavera@gmail.com>
* Make server middleware standalone functions.David Calavera2016-02-247-0/+275
Removing direct dependencies from the server configuration. Signed-off-by: David Calavera <david.calavera@gmail.com>