forked from TrueCloudLab/rclone
Remove Authorization:
headers from --dump-headers
output
Add in `--dump-auth` flag to put it back.
This commit is contained in:
parent
11301a64fb
commit
318e335137
4 changed files with 81 additions and 6 deletions
|
@ -543,6 +543,13 @@ here which are used for testing. These start with remote name eg
|
||||||
|
|
||||||
Write CPU profile to file. This can be analysed with `go tool pprof`.
|
Write CPU profile to file. This can be analysed with `go tool pprof`.
|
||||||
|
|
||||||
|
### --dump-auth ###
|
||||||
|
|
||||||
|
Dump HTTP headers - will contain sensitive info such as
|
||||||
|
`Authorization:` headers - use `--dump-headers` to dump without
|
||||||
|
`Authorization:` headers. Can be very verbose. Useful for debugging
|
||||||
|
only.
|
||||||
|
|
||||||
### --dump-bodies ###
|
### --dump-bodies ###
|
||||||
|
|
||||||
Dump HTTP headers and bodies - may contain sensitive info. Can be
|
Dump HTTP headers and bodies - may contain sensitive info. Can be
|
||||||
|
@ -555,8 +562,11 @@ and exclude options are filtering on.
|
||||||
|
|
||||||
### --dump-headers ###
|
### --dump-headers ###
|
||||||
|
|
||||||
Dump HTTP headers - may contain sensitive info. Can be very verbose.
|
Dump HTTP headers with `Authorization:` lines removed. May still
|
||||||
Useful for debugging only.
|
contain sensitive info. Can be very verbose. Useful for debugging
|
||||||
|
only.
|
||||||
|
|
||||||
|
Use `--dump-auth` if you do want the `Authorization:` headers.
|
||||||
|
|
||||||
### --memprofile=FILE ###
|
### --memprofile=FILE ###
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,7 @@ var (
|
||||||
timeout = pflag.DurationP("timeout", "", 5*60*time.Second, "IO idle timeout")
|
timeout = pflag.DurationP("timeout", "", 5*60*time.Second, "IO idle timeout")
|
||||||
dumpHeaders = pflag.BoolP("dump-headers", "", false, "Dump HTTP headers - may contain sensitive info")
|
dumpHeaders = pflag.BoolP("dump-headers", "", false, "Dump HTTP headers - may contain sensitive info")
|
||||||
dumpBodies = pflag.BoolP("dump-bodies", "", false, "Dump HTTP headers and bodies - may contain sensitive info")
|
dumpBodies = pflag.BoolP("dump-bodies", "", false, "Dump HTTP headers and bodies - may contain sensitive info")
|
||||||
|
dumpAuth = pflag.BoolP("dump-auth", "", false, "Dump HTTP headers with auth info")
|
||||||
skipVerify = pflag.BoolP("no-check-certificate", "", false, "Do not verify the server SSL certificate. Insecure.")
|
skipVerify = pflag.BoolP("no-check-certificate", "", false, "Do not verify the server SSL certificate. Insecure.")
|
||||||
AskPassword = pflag.BoolP("ask-password", "", true, "Allow prompt for password for encrypted configuration.")
|
AskPassword = pflag.BoolP("ask-password", "", true, "Allow prompt for password for encrypted configuration.")
|
||||||
deleteBefore = pflag.BoolP("delete-before", "", false, "When synchronizing, delete files on destination before transfering")
|
deleteBefore = pflag.BoolP("delete-before", "", false, "When synchronizing, delete files on destination before transfering")
|
||||||
|
@ -287,6 +288,7 @@ type ConfigInfo struct {
|
||||||
Timeout time.Duration // Data channel timeout
|
Timeout time.Duration // Data channel timeout
|
||||||
DumpHeaders bool
|
DumpHeaders bool
|
||||||
DumpBodies bool
|
DumpBodies bool
|
||||||
|
DumpAuth bool
|
||||||
Filter *Filter
|
Filter *Filter
|
||||||
InsecureSkipVerify bool // Skip server certificate verification
|
InsecureSkipVerify bool // Skip server certificate verification
|
||||||
DeleteBefore bool // Delete before checking
|
DeleteBefore bool // Delete before checking
|
||||||
|
@ -341,6 +343,7 @@ func LoadConfig() {
|
||||||
Config.IgnoreExisting = *ignoreExisting
|
Config.IgnoreExisting = *ignoreExisting
|
||||||
Config.DumpHeaders = *dumpHeaders
|
Config.DumpHeaders = *dumpHeaders
|
||||||
Config.DumpBodies = *dumpBodies
|
Config.DumpBodies = *dumpBodies
|
||||||
|
Config.DumpAuth = *dumpAuth
|
||||||
Config.InsecureSkipVerify = *skipVerify
|
Config.InsecureSkipVerify = *skipVerify
|
||||||
Config.LowLevelRetries = *lowLevelRetries
|
Config.LowLevelRetries = *lowLevelRetries
|
||||||
Config.UpdateOlder = *updateOlder
|
Config.UpdateOlder = *updateOlder
|
||||||
|
|
46
fs/http.go
46
fs/http.go
|
@ -3,6 +3,7 @@
|
||||||
package fs
|
package fs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -112,7 +113,7 @@ func (ci *ConfigInfo) Transport() http.RoundTripper {
|
||||||
// t.ExpectContinueTimeout
|
// t.ExpectContinueTimeout
|
||||||
ci.initTransport(t)
|
ci.initTransport(t)
|
||||||
// Wrap that http.Transport in our own transport
|
// Wrap that http.Transport in our own transport
|
||||||
transport = NewTransport(t, ci.DumpHeaders, ci.DumpBodies)
|
transport = NewTransport(t, ci.DumpHeaders, ci.DumpBodies, ci.DumpAuth)
|
||||||
})
|
})
|
||||||
return transport
|
return transport
|
||||||
}
|
}
|
||||||
|
@ -131,15 +132,17 @@ type Transport struct {
|
||||||
*http.Transport
|
*http.Transport
|
||||||
logHeader bool
|
logHeader bool
|
||||||
logBody bool
|
logBody bool
|
||||||
|
logAuth bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTransport wraps the http.Transport passed in and logs all
|
// NewTransport wraps the http.Transport passed in and logs all
|
||||||
// roundtrips including the body if logBody is set.
|
// roundtrips including the body if logBody is set.
|
||||||
func NewTransport(transport *http.Transport, logHeader, logBody bool) *Transport {
|
func NewTransport(transport *http.Transport, logHeader, logBody, logAuth bool) *Transport {
|
||||||
return &Transport{
|
return &Transport{
|
||||||
Transport: transport,
|
Transport: transport,
|
||||||
logHeader: logHeader,
|
logHeader: logHeader,
|
||||||
logBody: logBody,
|
logBody: logBody,
|
||||||
|
logAuth: logAuth,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,13 +183,48 @@ func checkServerTime(req *http.Request, resp *http.Response) {
|
||||||
checkedHostMu.Unlock()
|
checkedHostMu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var authBuf = []byte("Authorization: ")
|
||||||
|
|
||||||
|
// cleanAuth gets rid of one Authorization: header within the first 4k
|
||||||
|
func cleanAuth(buf []byte) []byte {
|
||||||
|
// Find how much buffer to check
|
||||||
|
n := 4096
|
||||||
|
if len(buf) < n {
|
||||||
|
n = len(buf)
|
||||||
|
}
|
||||||
|
// See if there is an Authorization: header
|
||||||
|
i := bytes.Index(buf[:n], authBuf)
|
||||||
|
if i < 0 {
|
||||||
|
return buf
|
||||||
|
}
|
||||||
|
i += len(authBuf)
|
||||||
|
// Overwrite the next 4 chars with 'X'
|
||||||
|
for j := 0; i < len(buf) && j < 4; j++ {
|
||||||
|
if buf[i] == '\n' {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
buf[i] = 'X'
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
// Snip out to the next '\n'
|
||||||
|
j := bytes.IndexByte(buf[i:], '\n')
|
||||||
|
if j < 0 {
|
||||||
|
return buf[:i]
|
||||||
|
}
|
||||||
|
n = copy(buf[i:], buf[i+j:])
|
||||||
|
return buf[:i+n]
|
||||||
|
}
|
||||||
|
|
||||||
// RoundTrip implements the RoundTripper interface.
|
// RoundTrip implements the RoundTripper interface.
|
||||||
func (t *Transport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
|
func (t *Transport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
|
||||||
// Force user agent
|
// Force user agent
|
||||||
req.Header.Set("User-Agent", UserAgent)
|
req.Header.Set("User-Agent", UserAgent)
|
||||||
// Log request
|
// Log request
|
||||||
if t.logHeader || t.logBody {
|
if t.logHeader || t.logBody || t.logAuth {
|
||||||
buf, _ := httputil.DumpRequestOut(req, t.logBody)
|
buf, _ := httputil.DumpRequestOut(req, t.logBody)
|
||||||
|
if !t.logAuth {
|
||||||
|
buf = cleanAuth(buf)
|
||||||
|
}
|
||||||
Debug(nil, "%s", separatorReq)
|
Debug(nil, "%s", separatorReq)
|
||||||
Debug(nil, "%s (req %p)", "HTTP REQUEST", req)
|
Debug(nil, "%s (req %p)", "HTTP REQUEST", req)
|
||||||
Debug(nil, "%s", string(buf))
|
Debug(nil, "%s", string(buf))
|
||||||
|
@ -195,7 +233,7 @@ func (t *Transport) RoundTrip(req *http.Request) (resp *http.Response, err error
|
||||||
// Do round trip
|
// Do round trip
|
||||||
resp, err = t.Transport.RoundTrip(req)
|
resp, err = t.Transport.RoundTrip(req)
|
||||||
// Log response
|
// Log response
|
||||||
if t.logHeader || t.logBody {
|
if t.logHeader || t.logBody || t.logAuth {
|
||||||
Debug(nil, "%s", separatorResp)
|
Debug(nil, "%s", separatorResp)
|
||||||
Debug(nil, "%s (req %p)", "HTTP RESPONSE", req)
|
Debug(nil, "%s (req %p)", "HTTP RESPONSE", req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -38,3 +38,27 @@ func TestSetDefaults(t *testing.T) {
|
||||||
assert.Equal(t, old.TLSNextProto, new.TLSNextProto, "when checking .TLSNextProto")
|
assert.Equal(t, old.TLSNextProto, new.TLSNextProto, "when checking .TLSNextProto")
|
||||||
assert.Equal(t, old.MaxResponseHeaderBytes, new.MaxResponseHeaderBytes, "when checking .MaxResponseHeaderBytes")
|
assert.Equal(t, old.MaxResponseHeaderBytes, new.MaxResponseHeaderBytes, "when checking .MaxResponseHeaderBytes")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCleanAuth(t *testing.T) {
|
||||||
|
for _, test := range []struct {
|
||||||
|
in string
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{"", ""},
|
||||||
|
{"floo", "floo"},
|
||||||
|
{"Authorization: ", "Authorization: "},
|
||||||
|
{"Authorization: \n", "Authorization: \n"},
|
||||||
|
{"Authorization: A", "Authorization: X"},
|
||||||
|
{"Authorization: A\n", "Authorization: X\n"},
|
||||||
|
{"Authorization: AAAA", "Authorization: XXXX"},
|
||||||
|
{"Authorization: AAAA\n", "Authorization: XXXX\n"},
|
||||||
|
{"Authorization: AAAAA", "Authorization: XXXX"},
|
||||||
|
{"Authorization: AAAAA\n", "Authorization: XXXX\n"},
|
||||||
|
{"Authorization: AAAA\n", "Authorization: XXXX\n"},
|
||||||
|
{"Authorization: AAAAAAAAA\nPotato: Help\n", "Authorization: XXXX\nPotato: Help\n"},
|
||||||
|
{"Sausage: 1\nAuthorization: AAAAAAAAA\nPotato: Help\n", "Sausage: 1\nAuthorization: XXXX\nPotato: Help\n"},
|
||||||
|
} {
|
||||||
|
got := string(cleanAuth([]byte(test.in)))
|
||||||
|
assert.Equal(t, test.want, got, test.in)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue