Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
a7f06905
Commit
a7f06905
authored
Feb 25, 2016
by
k8s-merge-robot
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #21185 from fabianofranz/fix_spdy_roundtripper_verify_hostname
Auto commit by PR queue bot
parents
995b7279
5cc943d3
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
156 additions
and
32 deletions
+156
-32
roundtripper.go
pkg/util/httpstream/spdy/roundtripper.go
+15
-2
roundtripper_test.go
pkg/util/httpstream/spdy/roundtripper_test.go
+141
-30
No files found.
pkg/util/httpstream/spdy/roundtripper.go
View file @
a7f06905
...
@@ -53,6 +53,10 @@ type SpdyRoundTripper struct {
...
@@ -53,6 +53,10 @@ type SpdyRoundTripper struct {
// Dialer is the dialer used to connect. Used if non-nil.
// Dialer is the dialer used to connect. Used if non-nil.
Dialer
*
net
.
Dialer
Dialer
*
net
.
Dialer
// proxier knows which proxy to use given a request, defaults to http.ProxyFromEnvironment
// Used primarily for mocking the proxy discovery in tests.
proxier
func
(
req
*
http
.
Request
)
(
*
url
.
URL
,
error
)
}
}
// NewRoundTripper creates a new SpdyRoundTripper that will use
// NewRoundTripper creates a new SpdyRoundTripper that will use
...
@@ -70,7 +74,11 @@ func NewSpdyRoundTripper(tlsConfig *tls.Config) *SpdyRoundTripper {
...
@@ -70,7 +74,11 @@ func NewSpdyRoundTripper(tlsConfig *tls.Config) *SpdyRoundTripper {
// dial dials the host specified by req, using TLS if appropriate, optionally
// dial dials the host specified by req, using TLS if appropriate, optionally
// using a proxy server if one is configured via environment variables.
// using a proxy server if one is configured via environment variables.
func
(
s
*
SpdyRoundTripper
)
dial
(
req
*
http
.
Request
)
(
net
.
Conn
,
error
)
{
func
(
s
*
SpdyRoundTripper
)
dial
(
req
*
http
.
Request
)
(
net
.
Conn
,
error
)
{
proxyURL
,
err
:=
http
.
ProxyFromEnvironment
(
req
)
proxier
:=
s
.
proxier
if
proxier
==
nil
{
proxier
=
http
.
ProxyFromEnvironment
}
proxyURL
,
err
:=
proxier
(
req
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
@@ -106,7 +114,7 @@ func (s *SpdyRoundTripper) dial(req *http.Request) (net.Conn, error) {
...
@@ -106,7 +114,7 @@ func (s *SpdyRoundTripper) dial(req *http.Request) (net.Conn, error) {
return
rwc
,
nil
return
rwc
,
nil
}
}
host
,
_
,
err
:=
net
.
SplitHostPort
(
req
.
URL
.
Host
)
host
,
_
,
err
:=
net
.
SplitHostPort
(
target
Host
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
@@ -122,6 +130,11 @@ func (s *SpdyRoundTripper) dial(req *http.Request) (net.Conn, error) {
...
@@ -122,6 +130,11 @@ func (s *SpdyRoundTripper) dial(req *http.Request) (net.Conn, error) {
return
nil
,
err
return
nil
,
err
}
}
// Return if we were configured to skip validation
if
s
.
tlsConfig
!=
nil
&&
s
.
tlsConfig
.
InsecureSkipVerify
{
return
tlsConn
,
nil
}
if
err
:=
tlsConn
.
VerifyHostname
(
host
);
err
!=
nil
{
if
err
:=
tlsConn
.
VerifyHostname
(
host
);
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
...
pkg/util/httpstream/spdy/roundtripper_test.go
View file @
a7f06905
...
@@ -22,20 +22,48 @@ import (
...
@@ -22,20 +22,48 @@ import (
"io"
"io"
"net/http"
"net/http"
"net/http/httptest"
"net/http/httptest"
"net/url"
"testing"
"testing"
"github.com/elazarl/goproxy"
"k8s.io/kubernetes/pkg/util/httpstream"
"k8s.io/kubernetes/pkg/util/httpstream"
)
)
func
TestRoundTripAndNewConnection
(
t
*
testing
.
T
)
{
func
TestRoundTripAndNewConnection
(
t
*
testing
.
T
)
{
localhostPool
:=
x509
.
NewCertPool
()
localhostPool
:=
x509
.
NewCertPool
()
if
!
localhostPool
.
AppendCertsFromPEM
(
localhostCert
)
{
if
!
localhostPool
.
AppendCertsFromPEM
(
localhostCert
)
{
t
.
Errorf
(
"error setting up localhostCert pool"
)
t
.
Errorf
(
"error setting up localhostCert pool"
)
}
}
httpsServerInvalidHostname
:=
func
(
h
http
.
Handler
)
*
httptest
.
Server
{
cert
,
err
:=
tls
.
X509KeyPair
(
exampleCert
,
exampleKey
)
if
err
!=
nil
{
t
.
Errorf
(
"https (invalid hostname): proxy_test: %v"
,
err
)
}
ts
:=
httptest
.
NewUnstartedServer
(
h
)
ts
.
TLS
=
&
tls
.
Config
{
Certificates
:
[]
tls
.
Certificate
{
cert
},
}
ts
.
StartTLS
()
return
ts
}
httpsServerValidHostname
:=
func
(
h
http
.
Handler
)
*
httptest
.
Server
{
cert
,
err
:=
tls
.
X509KeyPair
(
localhostCert
,
localhostKey
)
if
err
!=
nil
{
t
.
Errorf
(
"https (valid hostname): proxy_test: %v"
,
err
)
}
ts
:=
httptest
.
NewUnstartedServer
(
h
)
ts
.
TLS
=
&
tls
.
Config
{
Certificates
:
[]
tls
.
Certificate
{
cert
},
}
ts
.
StartTLS
()
return
ts
}
testCases
:=
map
[
string
]
struct
{
testCases
:=
map
[
string
]
struct
{
serverFunc
func
(
http
.
Handler
)
*
httptest
.
Server
serverFunc
func
(
http
.
Handler
)
*
httptest
.
Server
proxyServerFunc
func
(
http
.
Handler
)
*
httptest
.
Server
clientTLS
*
tls
.
Config
clientTLS
*
tls
.
Config
serverConnectionHeader
string
serverConnectionHeader
string
serverUpgradeHeader
string
serverUpgradeHeader
string
...
@@ -78,37 +106,85 @@ func TestRoundTripAndNewConnection(t *testing.T) {
...
@@ -78,37 +106,85 @@ func TestRoundTripAndNewConnection(t *testing.T) {
shouldError
:
false
,
shouldError
:
false
,
},
},
"https (invalid hostname + InsecureSkipVerify)"
:
{
"https (invalid hostname + InsecureSkipVerify)"
:
{
serverFunc
:
func
(
h
http
.
Handler
)
*
httptest
.
Server
{
serverFunc
:
httpsServerInvalidHostname
,
cert
,
err
:=
tls
.
X509KeyPair
(
exampleCert
,
exampleKey
)
if
err
!=
nil
{
t
.
Errorf
(
"https (invalid hostname): proxy_test: %v"
,
err
)
}
ts
:=
httptest
.
NewUnstartedServer
(
h
)
ts
.
TLS
=
&
tls
.
Config
{
Certificates
:
[]
tls
.
Certificate
{
cert
},
}
ts
.
StartTLS
()
return
ts
},
clientTLS
:
&
tls
.
Config
{
InsecureSkipVerify
:
true
},
clientTLS
:
&
tls
.
Config
{
InsecureSkipVerify
:
true
},
serverConnectionHeader
:
"Upgrade"
,
serverConnectionHeader
:
"Upgrade"
,
serverUpgradeHeader
:
"SPDY/3.1"
,
serverUpgradeHeader
:
"SPDY/3.1"
,
serverStatusCode
:
http
.
StatusSwitchingProtocols
,
serverStatusCode
:
http
.
StatusSwitchingProtocols
,
shouldError
:
false
,
shouldError
:
false
,
},
},
"https (invalid hostname + hostname verification)"
:
{
serverFunc
:
httpsServerInvalidHostname
,
clientTLS
:
&
tls
.
Config
{
InsecureSkipVerify
:
false
},
serverConnectionHeader
:
"Upgrade"
,
serverUpgradeHeader
:
"SPDY/3.1"
,
serverStatusCode
:
http
.
StatusSwitchingProtocols
,
shouldError
:
true
,
},
"https (valid hostname + RootCAs)"
:
{
"https (valid hostname + RootCAs)"
:
{
serverFunc
:
func
(
h
http
.
Handler
)
*
httptest
.
Server
{
serverFunc
:
httpsServerValidHostname
,
cert
,
err
:=
tls
.
X509KeyPair
(
localhostCert
,
localhostKey
)
clientTLS
:
&
tls
.
Config
{
RootCAs
:
localhostPool
},
if
err
!=
nil
{
serverConnectionHeader
:
"Upgrade"
,
t
.
Errorf
(
"https (valid hostname): proxy_test: %v"
,
err
)
serverUpgradeHeader
:
"SPDY/3.1"
,
}
serverStatusCode
:
http
.
StatusSwitchingProtocols
,
ts
:=
httptest
.
NewUnstartedServer
(
h
)
shouldError
:
false
,
ts
.
TLS
=
&
tls
.
Config
{
},
Certificates
:
[]
tls
.
Certificate
{
cert
},
"proxied http->http"
:
{
}
serverFunc
:
httptest
.
NewServer
,
ts
.
StartTLS
()
proxyServerFunc
:
httptest
.
NewServer
,
return
ts
serverConnectionHeader
:
"Upgrade"
,
},
serverUpgradeHeader
:
"SPDY/3.1"
,
serverStatusCode
:
http
.
StatusSwitchingProtocols
,
shouldError
:
false
,
},
"proxied https (invalid hostname + InsecureSkipVerify) -> http"
:
{
serverFunc
:
httptest
.
NewServer
,
proxyServerFunc
:
httpsServerInvalidHostname
,
clientTLS
:
&
tls
.
Config
{
InsecureSkipVerify
:
true
},
serverConnectionHeader
:
"Upgrade"
,
serverUpgradeHeader
:
"SPDY/3.1"
,
serverStatusCode
:
http
.
StatusSwitchingProtocols
,
shouldError
:
false
,
},
"proxied https (invalid hostname + hostname verification) -> http"
:
{
serverFunc
:
httptest
.
NewServer
,
proxyServerFunc
:
httpsServerInvalidHostname
,
clientTLS
:
&
tls
.
Config
{
InsecureSkipVerify
:
false
},
serverConnectionHeader
:
"Upgrade"
,
serverUpgradeHeader
:
"SPDY/3.1"
,
serverStatusCode
:
http
.
StatusSwitchingProtocols
,
shouldError
:
true
,
// fails because the client doesn't trust the proxy
},
"proxied https (valid hostname + RootCAs) -> http"
:
{
serverFunc
:
httptest
.
NewServer
,
proxyServerFunc
:
httpsServerValidHostname
,
clientTLS
:
&
tls
.
Config
{
RootCAs
:
localhostPool
},
serverConnectionHeader
:
"Upgrade"
,
serverUpgradeHeader
:
"SPDY/3.1"
,
serverStatusCode
:
http
.
StatusSwitchingProtocols
,
shouldError
:
false
,
},
"proxied https (invalid hostname + InsecureSkipVerify) -> https (invalid hostname)"
:
{
serverFunc
:
httpsServerInvalidHostname
,
proxyServerFunc
:
httpsServerInvalidHostname
,
clientTLS
:
&
tls
.
Config
{
InsecureSkipVerify
:
true
},
serverConnectionHeader
:
"Upgrade"
,
serverUpgradeHeader
:
"SPDY/3.1"
,
serverStatusCode
:
http
.
StatusSwitchingProtocols
,
shouldError
:
false
,
// works because the test proxy ignores TLS errors
},
"proxied https (invalid hostname + hostname verification) -> https (invalid hostname)"
:
{
serverFunc
:
httpsServerInvalidHostname
,
proxyServerFunc
:
httpsServerInvalidHostname
,
clientTLS
:
&
tls
.
Config
{
InsecureSkipVerify
:
false
},
serverConnectionHeader
:
"Upgrade"
,
serverUpgradeHeader
:
"SPDY/3.1"
,
serverStatusCode
:
http
.
StatusSwitchingProtocols
,
shouldError
:
true
,
// fails because the client doesn't trust the proxy
},
"proxied https (valid hostname + RootCAs) -> https (valid hostname + RootCAs)"
:
{
serverFunc
:
httpsServerValidHostname
,
proxyServerFunc
:
httpsServerValidHostname
,
clientTLS
:
&
tls
.
Config
{
RootCAs
:
localhostPool
},
clientTLS
:
&
tls
.
Config
{
RootCAs
:
localhostPool
},
serverConnectionHeader
:
"Upgrade"
,
serverConnectionHeader
:
"Upgrade"
,
serverUpgradeHeader
:
"SPDY/3.1"
,
serverUpgradeHeader
:
"SPDY/3.1"
,
...
@@ -149,20 +225,46 @@ func TestRoundTripAndNewConnection(t *testing.T) {
...
@@ -149,20 +225,46 @@ func TestRoundTripAndNewConnection(t *testing.T) {
// TODO: Uncomment when fix #19254
// TODO: Uncomment when fix #19254
// defer server.Close()
// defer server.Close()
serverURL
,
err
:=
url
.
Parse
(
server
.
URL
)
if
err
!=
nil
{
t
.
Fatalf
(
"%s: Error creating request: %s"
,
k
,
err
)
}
req
,
err
:=
http
.
NewRequest
(
"GET"
,
server
.
URL
,
nil
)
req
,
err
:=
http
.
NewRequest
(
"GET"
,
server
.
URL
,
nil
)
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatalf
(
"%s: Error creating request: %s"
,
k
,
err
)
t
.
Fatalf
(
"%s: Error creating request: %s"
,
k
,
err
)
}
}
spdyTransport
:=
NewRoundTripper
(
testCase
.
clientTLS
)
spdyTransport
:=
NewSpdyRoundTripper
(
testCase
.
clientTLS
)
var
proxierCalled
bool
var
proxyCalledWithHost
string
if
testCase
.
proxyServerFunc
!=
nil
{
proxyHandler
:=
goproxy
.
NewProxyHttpServer
()
proxyHandler
.
OnRequest
()
.
HandleConnectFunc
(
func
(
host
string
,
ctx
*
goproxy
.
ProxyCtx
)
(
*
goproxy
.
ConnectAction
,
string
)
{
proxyCalledWithHost
=
host
return
goproxy
.
OkConnect
,
host
})
proxy
:=
testCase
.
proxyServerFunc
(
proxyHandler
)
spdyTransport
.
proxier
=
func
(
proxierReq
*
http
.
Request
)
(
*
url
.
URL
,
error
)
{
proxyURL
,
err
:=
url
.
Parse
(
proxy
.
URL
)
if
err
!=
nil
{
return
nil
,
err
}
proxierCalled
=
true
return
proxyURL
,
nil
}
// TODO: Uncomment when fix #19254
// defer proxy.Close()
}
client
:=
&
http
.
Client
{
Transport
:
spdyTransport
}
client
:=
&
http
.
Client
{
Transport
:
spdyTransport
}
resp
,
err
:=
client
.
Do
(
req
)
resp
,
err
:=
client
.
Do
(
req
)
if
err
!=
nil
{
var
conn
httpstream
.
Connection
t
.
Fatalf
(
"%s: unexpected error from client.Do: %s"
,
k
,
err
)
if
err
==
nil
{
conn
,
err
=
spdyTransport
.
NewConnection
(
resp
)
}
}
conn
,
err
:=
spdyTransport
.
NewConnection
(
resp
)
haveErr
:=
err
!=
nil
haveErr
:=
err
!=
nil
if
e
,
a
:=
testCase
.
shouldError
,
haveErr
;
e
!=
a
{
if
e
,
a
:=
testCase
.
shouldError
,
haveErr
;
e
!=
a
{
t
.
Fatalf
(
"%s: shouldError=%t, got %t: %v"
,
k
,
e
,
a
,
err
)
t
.
Fatalf
(
"%s: shouldError=%t, got %t: %v"
,
k
,
e
,
a
,
err
)
...
@@ -200,6 +302,15 @@ func TestRoundTripAndNewConnection(t *testing.T) {
...
@@ -200,6 +302,15 @@ func TestRoundTripAndNewConnection(t *testing.T) {
if
e
,
a
:=
"hello"
,
string
(
b
[
0
:
n
]);
e
!=
a
{
if
e
,
a
:=
"hello"
,
string
(
b
[
0
:
n
]);
e
!=
a
{
t
.
Fatalf
(
"%s: expected '%s', got '%s'"
,
k
,
e
,
a
)
t
.
Fatalf
(
"%s: expected '%s', got '%s'"
,
k
,
e
,
a
)
}
}
if
testCase
.
proxyServerFunc
!=
nil
{
if
!
proxierCalled
{
t
.
Fatalf
(
"%s: Expected to use a proxy but proxier in SpdyRoundTripper wasn't called"
,
k
)
}
if
proxyCalledWithHost
!=
serverURL
.
Host
{
t
.
Fatalf
(
"%s: Expected to see a call to the proxy for backend %q, got %q"
,
k
,
serverURL
.
Host
,
proxyCalledWithHost
)
}
}
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment