mirror of https://github.com/perkeep/perkeep.git
pkg/client: set ServerName before DialTLS handshake for android
Otherwise, the android app fails to connect with a server that uses Let's Encrypt (because it relies on SNI, which requires the ServerName to be set). Change-Id: I9f25486bea68e83c68584a83817c98bfc84f62b9
This commit is contained in:
parent
32fbc99a66
commit
8b2e541731
|
@ -333,6 +333,12 @@ func (o optionSameOrigin) modifyClient(c *Client) {
|
|||
c.sameOrigin = bool(o)
|
||||
}
|
||||
|
||||
type optionParamsOnly bool
|
||||
|
||||
func (o optionParamsOnly) modifyClient(c *Client) {
|
||||
c.paramsOnly = bool(o)
|
||||
}
|
||||
|
||||
// noop is for use with syncutil.Onces.
|
||||
func noop() error { return nil }
|
||||
|
||||
|
@ -1149,6 +1155,10 @@ func (c *Client) DialTLSFunc() func(network, addr string) (net.Conn, error) {
|
|||
} else {
|
||||
tlsConfig = &tls.Config{InsecureSkipVerify: true}
|
||||
}
|
||||
// Since we're doing the TLS handshake ourselves, we need to set the ServerName,
|
||||
// in case the server uses SNI (as is the case if it's relying on Let's Encrypt,
|
||||
// for example).
|
||||
tlsConfig.ServerName = c.serverNameOfAddr(addr)
|
||||
conn = tls.Client(ac, tlsConfig)
|
||||
if err := conn.Handshake(); err != nil {
|
||||
return nil, err
|
||||
|
@ -1176,6 +1186,21 @@ func (c *Client) DialTLSFunc() func(network, addr string) (net.Conn, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// serverNameOfAddr returns the host part of addr, or the empty string if addr
|
||||
// is not a valid address (see net.Dial). Additionally, if host is an IP literal,
|
||||
// serverNameOfAddr returns the empty string.
|
||||
func (c *Client) serverNameOfAddr(addr string) string {
|
||||
serverName, _, err := net.SplitHostPort(addr)
|
||||
if err != nil {
|
||||
c.printf("could not get server name from address %q: %v", addr, err)
|
||||
return ""
|
||||
}
|
||||
if ip := net.ParseIP(serverName); ip != nil {
|
||||
return ""
|
||||
}
|
||||
return serverName
|
||||
}
|
||||
|
||||
func (c *Client) Signer() (*schema.Signer, error) {
|
||||
c.signerOnce.Do(c.signerInit)
|
||||
return c.signer, c.signerErr
|
||||
|
@ -1299,8 +1324,11 @@ func (c *Client) Close() error {
|
|||
// and auth but does not use any on-disk config files or environment variables
|
||||
// for its configuration. It may still use the disk for caches.
|
||||
func NewFromParams(server string, mode auth.AuthMode, opts ...ClientOption) *Client {
|
||||
// paramsOnly = true needs to be passed as soon as an argument, because
|
||||
// there are code paths in newClient (c.transportForConfig) that can lead
|
||||
// to parsing the config file.
|
||||
opts = append(opts[:len(opts):len(opts)], optionParamsOnly(true))
|
||||
cl := newClient(server, mode, opts...)
|
||||
cl.paramsOnly = true
|
||||
return cl
|
||||
}
|
||||
|
||||
|
|
|
@ -61,3 +61,29 @@ func TestAliasFromConfig(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestServerOfName(t *testing.T) {
|
||||
addrs := []struct {
|
||||
input string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
input: "foo.com:80",
|
||||
want: "foo.com",
|
||||
},
|
||||
{
|
||||
input: "192.168.0.9:80",
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
input: "foo.com",
|
||||
want: "",
|
||||
},
|
||||
}
|
||||
c := NewFromParams("whatever", nil)
|
||||
for _, v := range addrs {
|
||||
if got := c.serverNameOfAddr(v.input); got != v.want {
|
||||
t.Errorf("wanted %v, got %q", v.want, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue