Commit ca34a3e1 authored by David Somers's avatar David Somers Committed by Matt Holt

httpserver: Placeholders for tls_protocol and tls_cipher (#2062)

Also add SSL_PROTOCOL and SSL_CIPHER env vars for fastcgi.

* Implement placeholders for ssl_protocol and ssl_cipher

* gofmt

* goimports

* Housekeeping and implement as {tls_protocol} and {tls_cipher}
parent 3ee6d306
......@@ -33,8 +33,11 @@ import (
"sync/atomic"
"time"
"crypto/tls"
"github.com/mholt/caddy"
"github.com/mholt/caddy/caddyhttp/httpserver"
"github.com/mholt/caddy/caddytls"
)
// Handler is a middleware type that can handle requests as a FastCGI client.
......@@ -323,6 +326,19 @@ func (h Handler) buildEnv(r *http.Request, rule Rule, fpath string) (map[string]
// Some web apps rely on knowing HTTPS or not
if r.TLS != nil {
env["HTTPS"] = "on"
// and pass the protocol details in a manner compatible with apache's mod_ssl
// (which is why they have a SSL_ prefix and not TLS_).
v, ok := tlsProtocolStringToMap[r.TLS.Version]
if ok {
env["SSL_PROTOCOL"] = v
}
// and pass the cipher suite in a manner compatible with apache's mod_ssl
for k, v := range caddytls.SupportedCiphersMap {
if v == r.TLS.CipherSuite {
env["SSL_CIPHER"] = k
break
}
}
}
// Add env variables from config (with support for placeholders in values)
......@@ -465,3 +481,11 @@ type LogError string
func (l LogError) Error() string {
return string(l)
}
// Map of supported protocols to Apache ssl_mod format
// Note that these are slightly different from SupportedProtocols in caddytls/config.go's
var tlsProtocolStringToMap = map[uint16]string{
tls.VersionTLS10: "TLSv1",
tls.VersionTLS11: "TLSv1.1",
tls.VersionTLS12: "TLSv1.2",
}
......@@ -29,6 +29,7 @@ import (
"time"
"github.com/mholt/caddy"
"github.com/mholt/caddy/caddytls"
)
// requestReplacer is a strings.Replacer which is used to
......@@ -375,6 +376,26 @@ func (r *replacer) getSubstitution(key string) string {
}
elapsedDuration := time.Since(r.responseRecorder.start)
return strconv.FormatInt(convertToMilliseconds(elapsedDuration), 10)
case "{tls_protocol}":
if r.request.TLS != nil {
for k, v := range caddytls.SupportedProtocols {
if v == r.request.TLS.Version {
return k
}
}
return "tls" // this should never happen, but guard in case
}
return r.emptyValue // because not using a secure channel
case "{tls_cipher}":
if r.request.TLS != nil {
for k, v := range caddytls.SupportedCiphersMap {
if v == r.request.TLS.CipherSuite {
return k
}
}
return "UNKNOWN" // this should never happen, but guard in case
}
return r.emptyValue
}
return r.emptyValue
......
......@@ -532,7 +532,8 @@ var supportedKeyTypes = map[string]acme.KeyType{
// Map of supported protocols.
// HTTP/2 only supports TLS 1.2 and higher.
var supportedProtocols = map[string]uint16{
// If updating this map, also update tlsProtocolStringToMap in caddyhttp/fastcgi/fastcgi.go
var SupportedProtocols = map[string]uint16{
"tls1.0": tls.VersionTLS10,
"tls1.1": tls.VersionTLS11,
"tls1.2": tls.VersionTLS12,
......@@ -548,7 +549,7 @@ var supportedProtocols = map[string]uint16{
// it is always added (even though it is not technically a cipher suite).
//
// This map, like any map, is NOT ORDERED. Do not range over this map.
var supportedCiphersMap = map[string]uint16{
var SupportedCiphersMap = map[string]uint16{
"ECDHE-ECDSA-AES256-GCM-SHA384": tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
"ECDHE-RSA-AES256-GCM-SHA384": tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
"ECDHE-ECDSA-AES128-GCM-SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
......
......@@ -106,19 +106,19 @@ func setupTLS(c *caddy.Controller) error {
case "protocols":
args := c.RemainingArgs()
if len(args) == 1 {
value, ok := supportedProtocols[strings.ToLower(args[0])]
value, ok := SupportedProtocols[strings.ToLower(args[0])]
if !ok {
return c.Errf("Wrong protocol name or protocol not supported: '%s'", args[0])
}
config.ProtocolMinVersion, config.ProtocolMaxVersion = value, value
} else {
value, ok := supportedProtocols[strings.ToLower(args[0])]
value, ok := SupportedProtocols[strings.ToLower(args[0])]
if !ok {
return c.Errf("Wrong protocol name or protocol not supported: '%s'", args[0])
}
config.ProtocolMinVersion = value
value, ok = supportedProtocols[strings.ToLower(args[1])]
value, ok = SupportedProtocols[strings.ToLower(args[1])]
if !ok {
return c.Errf("Wrong protocol name or protocol not supported: '%s'", args[1])
}
......@@ -129,7 +129,7 @@ func setupTLS(c *caddy.Controller) error {
}
case "ciphers":
for c.NextArg() {
value, ok := supportedCiphersMap[strings.ToUpper(c.Val())]
value, ok := SupportedCiphersMap[strings.ToUpper(c.Val())]
if !ok {
return c.Errf("Wrong cipher name or cipher not supported: '%s'", c.Val())
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment