Skip to content

Commit 3ac4b26

Browse files
committed
bundle-server: make server min TLS version configurable
Add a '--tls-version' option, which takes values matching those of the 'http.sslVersion' config in Git, to set the 'tls.Config.MinVersion' setting in the web server. Signed-off-by: Victoria Dye <[email protected]>
1 parent 4ba9ca2 commit 3ac4b26

File tree

4 files changed

+75
-5
lines changed

4 files changed

+75
-5
lines changed

cmd/git-bundle-web-server/bundle-server.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package main
22

33
import (
44
"context"
5+
"crypto/tls"
56
"fmt"
67
"net/http"
78
"os"
@@ -28,7 +29,9 @@ type bundleWebServer struct {
2829
}
2930

3031
func NewBundleWebServer(logger log.TraceLogger,
31-
port string, certFile string, keyFile string,
32+
port string,
33+
certFile string, keyFile string,
34+
tlsMinVersion uint16,
3235
) *bundleWebServer {
3336
bundleServer := &bundleWebServer{
3437
logger: logger,
@@ -43,11 +46,18 @@ func NewBundleWebServer(logger log.TraceLogger,
4346
Addr: ":" + port,
4447
}
4548

46-
if certFile != "" {
47-
bundleServer.listenAndServeFunc = func() error { return bundleServer.server.ListenAndServeTLS(certFile, keyFile) }
48-
} else {
49+
// No TLS configuration to be done, return
50+
if certFile == "" {
4951
bundleServer.listenAndServeFunc = func() error { return bundleServer.server.ListenAndServe() }
52+
return bundleServer
53+
}
54+
55+
// Configure for TLS
56+
tlsConfig := &tls.Config{
57+
MinVersion: tlsMinVersion,
5058
}
59+
bundleServer.server.TLSConfig = tlsConfig
60+
bundleServer.listenAndServeFunc = func() error { return bundleServer.server.ListenAndServeTLS(certFile, keyFile) }
5161

5262
return bundleServer
5363
}

cmd/git-bundle-web-server/main.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,14 @@ func main() {
2626
port := utils.GetFlagValue[string](parser, "port")
2727
cert := utils.GetFlagValue[string](parser, "cert")
2828
key := utils.GetFlagValue[string](parser, "key")
29+
tlsMinVersion := utils.GetFlagValue[uint16](parser, "tls-version")
2930

3031
// Configure the server
31-
bundleServer := NewBundleWebServer(logger, port, cert, key)
32+
bundleServer := NewBundleWebServer(logger,
33+
port,
34+
cert, key,
35+
tlsMinVersion,
36+
)
3237

3338
// Start the server asynchronously
3439
bundleServer.StartServerAsync(ctx)

cmd/utils/common-args.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ package utils
22

33
import (
44
"context"
5+
"crypto/tls"
56
"flag"
67
"fmt"
78
"strconv"
9+
"strings"
810
)
911

1012
// Helpers
@@ -39,11 +41,50 @@ func GetFlagValue[T any](parser argParser, name string) T {
3941

4042
// Sets of flags shared between multiple commands/programs
4143

44+
type tlsVersionValue uint16
45+
46+
var tlsVersions = map[tlsVersionValue]string{
47+
tls.VersionTLS11: "tlsv1.1",
48+
tls.VersionTLS12: "tlsv1.2",
49+
tls.VersionTLS13: "tlsv1.3",
50+
}
51+
52+
func (v *tlsVersionValue) String() string {
53+
if strVal, ok := tlsVersions[*v]; ok {
54+
return strVal
55+
} else {
56+
panic(fmt.Sprintf("invalid tlsVersionValue '%d'", *v))
57+
}
58+
}
59+
60+
func (v *tlsVersionValue) Set(strVal string) error {
61+
strLower := strings.ToLower(strVal)
62+
for val, str := range tlsVersions {
63+
if str == strLower {
64+
*v = val
65+
return nil
66+
}
67+
}
68+
69+
// add details to "invalid value for flag" message
70+
validTlsVersions := []string{}
71+
for _, str := range tlsVersions {
72+
validTlsVersions = append(validTlsVersions, "'"+str+"'")
73+
}
74+
return fmt.Errorf("valid TLS versions are: %s", strings.Join(validTlsVersions, ", "))
75+
}
76+
77+
func (v *tlsVersionValue) Get() any {
78+
return uint16(*v)
79+
}
80+
4281
func WebServerFlags(parser argParser) (*flag.FlagSet, func(context.Context)) {
4382
f := flag.NewFlagSet("", flag.ContinueOnError)
4483
port := f.String("port", "8080", "The port on which the server should be hosted")
4584
cert := f.String("cert", "", "The path to the X.509 SSL certificate file to use in securely hosting the server")
4685
key := f.String("key", "", "The path to the certificate's private key")
86+
tlsVersion := tlsVersionValue(tls.VersionTLS12)
87+
f.Var(&tlsVersion, "tls-version", "The minimum TLS version the server will accept")
4788

4889
// Function to call for additional arg validation (may exit with 'Usage()')
4990
validationFunc := func(ctx context.Context) {

docs/man/server-options.asc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,17 @@
1010
*--key* _path_:::
1111
Use the contents of the specified file as the private key of the X.509 SSL
1212
certificate specified with *--cert*.
13+
14+
*--tls-version* _version_:::
15+
If the web server is configured for TLS (i.e., *--cert* and *--key* are
16+
specified), reject requests using a version of TLS less than the given
17+
version. The _version_ must be one of the following non-case sensitive values:
18+
19+
- tlsv1.1
20+
- tlsv1.2
21+
- tlsv1.3
22+
23+
+
24+
These strings match those used in the *http.sslVersion* Git config setting
25+
(see man:git-config[1]). The default value is *tlsv1.2*. If the server is not
26+
configured for TLS, this option is a no-op.

0 commit comments

Comments
 (0)