Skip to content

Commit

Permalink
Merge pull request #15 from istresearch/develop into main
Browse files Browse the repository at this point in the history
Add mTLS
  • Loading branch information
baracudda committed Jan 9, 2024
2 parents 1e74074 + 1536072 commit 5061b2e
Showing 1 changed file with 54 additions and 3 deletions.
57 changes: 54 additions & 3 deletions services/webhooks/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,25 @@ package webhooks

import (
"bytes"
"crypto/tls"
"crypto/x509"
"encoding/json"
"net/http"

"fmt"
"github.com/nyaruka/gocommon/httpx"
"github.com/nyaruka/goflow/flows"
"github.com/nyaruka/goflow/flows/engine"
"github.com/nyaruka/goflow/utils"
"io/ioutil"
"net/http"
"regexp"
)

const MAUTH_HEADER = "Mauth-Client-Ca"
const MAUTH_SERVER_CRT = "/etc/mauth/server/tls.crt"
const MAUTH_SERVER_KEY = "/etc/mauth/server/tls.key"

const MAUTH_CLIENT_BUNDLES_PATH = "/etc/mauth/clients/"

type service struct {
httpClient *http.Client
httpRetries *httpx.RetryConfig
Expand Down Expand Up @@ -38,6 +48,47 @@ func NewService(httpClient *http.Client, httpRetries *httpx.RetryConfig, httpAcc
}

func (s *service) Call(session flows.Session, request *http.Request) (*flows.WebhookCall, error) {
httpClient := s.httpClient

if mauthClientCa := request.Header.Get(MAUTH_HEADER); mauthClientCa != "" {
request.Header.Del(MAUTH_HEADER)

var re, err = regexp.MatchString(`[a-zA-Z0-9_-]+\.ca-bundle`, mauthClientCa)
if err != nil {
return nil, err
} else if re == false {
return nil, fmt.Errorf("invalid mauth header provided")
}

cert, err := tls.LoadX509KeyPair(MAUTH_SERVER_CRT, MAUTH_SERVER_KEY)
if err != nil {
return nil, err
}

caCert, err := ioutil.ReadFile(MAUTH_CLIENT_BUNDLES_PATH + mauthClientCa)
if err != nil {
return nil, err
}

caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)

// Because defaultclient can be used across routines and be reused multiple times, we need to
// explicitly create one just for mTLS.
// Todo: Do we want to cache the clients based on the keypair used on a given connection?
httpClient = &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: caCertPool,
Certificates: []tls.Certificate{cert},
},
},
CheckRedirect: s.httpClient.CheckRedirect,
Jar: s.httpClient.Jar,
Timeout: s.httpClient.Timeout,
}
}

// set any headers with defaults
for k, v := range s.defaultHeaders {
if request.Header.Get(k) == "" {
Expand All @@ -51,7 +102,7 @@ func (s *service) Call(session flows.Session, request *http.Request) (*flows.Web
request.Header.Del("Accept-Encoding")
}

trace, err := httpx.DoTrace(s.httpClient, request, s.httpRetries, s.httpAccess, s.maxBodyBytes)
trace, err := httpx.DoTrace(httpClient, request, s.httpRetries, s.httpAccess, s.maxBodyBytes)
if trace != nil {
call := &flows.WebhookCall{Trace: trace}

Expand Down

0 comments on commit 5061b2e

Please sign in to comment.