Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
caddy
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
caddy
Commits
a7aeb979
Commit
a7aeb979
authored
Jan 21, 2019
by
Matthew Holt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
caddytls: Use IP address to find config; vendor: update certmagic
Closes #2356
parent
771dcf3d
Changes
7
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
165 additions
and
129 deletions
+165
-129
caddyhttp/httpserver/plugin.go
caddyhttp/httpserver/plugin.go
+10
-1
caddytls/config.go
caddytls/config.go
+4
-2
caddytls/handshake.go
caddytls/handshake.go
+5
-4
vendor/github.com/mholt/certmagic/config.go
vendor/github.com/mholt/certmagic/config.go
+3
-6
vendor/github.com/mholt/certmagic/handshake.go
vendor/github.com/mholt/certmagic/handshake.go
+88
-55
vendor/github.com/mholt/certmagic/user.go
vendor/github.com/mholt/certmagic/user.go
+54
-60
vendor/manifest
vendor/manifest
+1
-1
No files found.
caddyhttp/httpserver/plugin.go
View file @
a7aeb979
...
...
@@ -405,6 +405,8 @@ func groupSiteConfigsByListenAddr(configs []*SiteConfig) (map[string][]*SiteConf
// parts of an address. The component parts may be
// updated to the correct values as setup proceeds,
// but the original value should never be changed.
//
// The Host field must be in a normalized form.
type
Address
struct
{
Original
,
Scheme
,
Host
,
Port
,
Path
string
}
...
...
@@ -453,10 +455,17 @@ func (a Address) Normalize() Address {
if
!
CaseSensitivePath
{
path
=
strings
.
ToLower
(
path
)
}
// ensure host is normalized if it's an IP address
host
:=
a
.
Host
if
ip
:=
net
.
ParseIP
(
host
);
ip
!=
nil
{
host
=
ip
.
String
()
}
return
Address
{
Original
:
a
.
Original
,
Scheme
:
strings
.
ToLower
(
a
.
Scheme
),
Host
:
strings
.
ToLower
(
a
.
H
ost
),
Host
:
strings
.
ToLower
(
h
ost
),
Port
:
a
.
Port
,
Path
:
path
,
}
...
...
caddytls/config.go
View file @
a7aeb979
...
...
@@ -33,7 +33,9 @@ type Config struct {
// The hostname or class of hostnames this config is
// designated for; can contain wildcard characters
// according to RFC 6125 §6.4.3 - this field MUST
// be set in order for things to work as expected
// be set in order for things to work as expected,
// must be normalized, and if an IP address, must
// be normalized
Hostname
string
// Whether TLS is enabled
...
...
@@ -272,7 +274,7 @@ func MakeTLSConfig(configs []*Config) (*tls.Config, error) {
// A tls.Config must have Certificates or GetCertificate
// set, in order to be accepted by tls.Listen and quic.Listen.
// TODO: remove this once the standard library allows a tls.Config with
// only GetConfigForClient set.
// only GetConfigForClient set.
https://github.com/mholt/caddy/pull/2404
GetCertificate
:
func
(
*
tls
.
ClientHelloInfo
)
(
*
tls
.
Certificate
,
error
)
{
return
nil
,
fmt
.
Errorf
(
"all certificates configured via GetConfigForClient"
)
},
...
...
caddytls/handshake.go
View file @
a7aeb979
...
...
@@ -20,6 +20,7 @@ import (
"strings"
"github.com/mholt/caddy/telemetry"
"github.com/mholt/certmagic"
)
// configGroup is a type that keys configs by their hostname
...
...
@@ -27,7 +28,7 @@ import (
// method to get a config by matching its hostname).
type
configGroup
map
[
string
]
*
Config
// getConfig gets the config by the first key match for
name
.
// getConfig gets the config by the first key match for
hello
.
// In other words, "sub.foo.bar" will get the config for "*.foo.bar"
// if that is the closest match. If no match is found, the first
// (random) config will be loaded, which will defer any TLS alerts
...
...
@@ -36,8 +37,8 @@ type configGroup map[string]*Config
//
// This function follows nearly the same logic to lookup
// a hostname as the getCertificate function uses.
func
(
cg
configGroup
)
getConfig
(
name
string
)
*
Config
{
name
=
strings
.
ToLower
(
name
)
func
(
cg
configGroup
)
getConfig
(
hello
*
tls
.
ClientHelloInfo
)
*
Config
{
name
:=
certmagic
.
CertNameFromClientHello
(
hello
)
// exact match? great, let's use it
if
config
,
ok
:=
cg
[
name
];
ok
{
...
...
@@ -72,7 +73,7 @@ func (cg configGroup) getConfig(name string) *Config {
//
// This method is safe for use as a tls.Config.GetConfigForClient callback.
func
(
cg
configGroup
)
GetConfigForClient
(
clientHello
*
tls
.
ClientHelloInfo
)
(
*
tls
.
Config
,
error
)
{
config
:=
cg
.
getConfig
(
clientHello
.
ServerName
)
config
:=
cg
.
getConfig
(
clientHello
)
if
config
!=
nil
{
return
config
.
tlsConfig
,
nil
}
...
...
vendor/github.com/mholt/certmagic/config.go
View file @
a7aeb979
...
...
@@ -369,12 +369,9 @@ func (cfg *Config) preObtainOrRenewChecks(name string, allowPrompts bool) (bool,
return
true
,
nil
}
if
cfg
.
Email
==
""
{
var
err
error
cfg
.
Email
,
err
=
cfg
.
getEmail
(
allowPrompts
)
if
err
!=
nil
{
return
false
,
err
}
err
:=
cfg
.
getEmail
(
allowPrompts
)
if
err
!=
nil
{
return
false
,
err
}
return
false
,
nil
...
...
vendor/github.com/mholt/certmagic/handshake.go
View file @
a7aeb979
This diff is collapsed.
Click to expand it.
vendor/github.com/mholt/certmagic/user.go
View file @
a7aeb979
...
...
@@ -23,12 +23,13 @@ import (
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"path"
"sort"
"strings"
"github.com/xenolf/lego/
lego
"
"github.com/xenolf/lego/
acme
"
"github.com/xenolf/lego/registration"
)
...
...
@@ -71,81 +72,74 @@ func (cfg *Config) newUser(email string) (user, error) {
// getEmail does everything it can to obtain an email address
// from the user within the scope of memory and storage to use
// for ACME TLS. If it cannot get an email address, it
returns
//
empty string. (If user is present
, it will warn the user of
// for ACME TLS. If it cannot get an email address, it
does nothing
//
(If user is prompted
, it will warn the user of
// the consequences of an empty email.) This function MAY prompt
// the user for input. If
userPresent is false, the operato
r
// the user for input. If
allowPrompts is false, the use
r
// will NOT be prompted and an empty email may be returned.
// If the user is prompted, a new User will be created and
// stored in storage according to the email address they
// provided (which might be blank).
func
(
cfg
*
Config
)
getEmail
(
userPresent
bool
)
(
string
,
error
)
{
// First try memory
func
(
cfg
*
Config
)
getEmail
(
allowPrompts
bool
)
error
{
leEmail
:=
cfg
.
Email
// First try package default email
if
leEmail
==
""
{
leEmail
=
Email
}
// Then try to get most recent user email from storage
if
leEmail
==
""
{
leEmail
=
cfg
.
mostRecentUserEmail
()
cfg
.
Email
=
leEmail
// save for next time
}
// Looks like there is no email address readily available,
// so we will have to ask the user if we can.
if
leEmail
==
""
&&
userPresent
{
// evidently, no User data was present in storage;
// thus we must make a new User so that we can get
// the Terms of Service URL via our ACME client, phew!
user
,
err
:=
cfg
.
newUser
(
""
)
if
leEmail
==
""
&&
allowPrompts
{
// Looks like there is no email address readily available,
// so we will have to ask the user if we can.
var
err
error
leEmail
,
err
=
cfg
.
promptUserForEmail
()
if
err
!=
nil
{
return
""
,
err
}
// get the agreement URL
agreementURL
:=
agreementTestURL
if
agreementURL
==
""
{
// we call acme.NewClient directly because newACMEClient
// would require that we already know the user's email
caURL
:=
CA
if
cfg
.
CA
!=
""
{
caURL
=
cfg
.
CA
}
legoConfig
:=
lego
.
NewConfig
(
user
)
legoConfig
.
CADirURL
=
caURL
legoConfig
.
UserAgent
=
UserAgent
tempClient
,
err
:=
lego
.
NewClient
(
legoConfig
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"making ACME client to get ToS URL: %v"
,
err
)
}
agreementURL
=
tempClient
.
GetToSURL
()
}
// prompt the user for an email address and terms agreement
reader
:=
bufio
.
NewReader
(
stdin
)
cfg
.
promptUserAgreement
(
agreementURL
)
fmt
.
Println
(
"Please enter your email address to signify agreement and to be notified"
)
fmt
.
Println
(
"in case of issues. You can leave it blank, but we don't recommend it."
)
fmt
.
Print
(
" Email address: "
)
leEmail
,
err
=
reader
.
ReadString
(
'\n'
)
if
err
!=
nil
&&
err
!=
io
.
EOF
{
return
""
,
fmt
.
Errorf
(
"reading email address: %v"
,
err
)
return
err
}
leEmail
=
strings
.
TrimSpace
(
leEmail
)
cfg
.
Email
=
leEmail
cfg
.
Agreed
=
true
}
// lower-casing the email is important for consistency
cfg
.
Email
=
strings
.
ToLower
(
leEmail
)
return
nil
}
// save the new user to preserve this for next time
user
.
Email
=
leEmail
err
=
cfg
.
saveUser
(
user
)
if
err
!=
nil
{
return
""
,
err
}
func
(
cfg
*
Config
)
getAgreementURL
()
(
string
,
error
)
{
if
agreementTestURL
!=
""
{
return
agreementTestURL
,
nil
}
caURL
:=
CA
if
cfg
.
CA
!=
""
{
caURL
=
cfg
.
CA
}
response
,
err
:=
http
.
Get
(
caURL
)
if
err
!=
nil
{
return
""
,
err
}
defer
response
.
Body
.
Close
()
var
dir
acme
.
Directory
err
=
json
.
NewDecoder
(
response
.
Body
)
.
Decode
(
&
dir
)
if
err
!=
nil
{
return
""
,
err
}
return
dir
.
Meta
.
TermsOfService
,
nil
}
// lower-casing the email is important for consistency
return
strings
.
ToLower
(
leEmail
),
nil
func
(
cfg
*
Config
)
promptUserForEmail
()
(
string
,
error
)
{
agreementURL
,
err
:=
cfg
.
getAgreementURL
()
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"get Agreement URL: %v"
,
err
)
}
// prompt the user for an email address and terms agreement
reader
:=
bufio
.
NewReader
(
stdin
)
cfg
.
promptUserAgreement
(
agreementURL
)
fmt
.
Println
(
"Please enter your email address to signify agreement and to be notified"
)
fmt
.
Println
(
"in case of issues. You can leave it blank, but we don't recommend it."
)
fmt
.
Print
(
" Email address: "
)
leEmail
,
err
:=
reader
.
ReadString
(
'\n'
)
if
err
!=
nil
&&
err
!=
io
.
EOF
{
return
""
,
fmt
.
Errorf
(
"reading email address: %v"
,
err
)
}
leEmail
=
strings
.
TrimSpace
(
leEmail
)
return
leEmail
,
nil
}
// getUser loads the user with the given email from disk
...
...
vendor/manifest
View file @
a7aeb979
...
...
@@ -138,7 +138,7 @@
"importpath": "github.com/mholt/certmagic",
"repository": "https://github.com/mholt/certmagic",
"vcs": "git",
"revision": "
01ffe8b3c7d611483ef936e90845329709721127
",
"revision": "
c1d472b46046ee329c099086d689ada0c44d56b0
",
"branch": "master",
"notests": true
},
...
...
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