1
0
Fork 0
forked from External/mediamtx

allow disabling HTTPS validation by using sourceFingerprint (#665)

This commit is contained in:
aler9 2021-10-25 21:13:02 +02:00
parent d30822cb1b
commit 9155bffefb
5 changed files with 53 additions and 18 deletions

View file

@ -23,9 +23,10 @@ type hlsSourceParent interface {
}
type hlsSource struct {
ur string
wg *sync.WaitGroup
parent hlsSourceParent
ur string
fingerprint string
wg *sync.WaitGroup
parent hlsSourceParent
ctx context.Context
ctxCancel func()
@ -34,16 +35,18 @@ type hlsSource struct {
func newHLSSource(
parentCtx context.Context,
ur string,
fingerprint string,
wg *sync.WaitGroup,
parent hlsSourceParent) *hlsSource {
ctx, ctxCancel := context.WithCancel(parentCtx)
s := &hlsSource{
ur: ur,
wg: wg,
parent: parent,
ctx: ctx,
ctxCancel: ctxCancel,
ur: ur,
fingerprint: fingerprint,
wg: wg,
parent: parent,
ctx: ctx,
ctxCancel: ctxCancel,
}
s.Log(logger.Info, "started")
@ -141,6 +144,7 @@ func (s *hlsSource) runInner() bool {
c := hls.NewClient(
s.ur,
s.fingerprint,
onTracks,
onFrame,
s,

View file

@ -624,6 +624,7 @@ func (pa *path) staticSourceCreate() {
pa.source = newHLSSource(
pa.ctx,
pa.conf.Source,
pa.conf.SourceFingerprint,
&pa.sourceStaticWg,
pa)
}

View file

@ -3,6 +3,9 @@ package hls
import (
"bytes"
"context"
"crypto/sha256"
"crypto/tls"
"encoding/hex"
"fmt"
"io/ioutil"
"net/http"
@ -428,6 +431,7 @@ type Client struct {
ctx context.Context
ctxCancel func()
httpClient *http.Client
urlParsed *url.URL
lastDownloadTime time.Time
downloadedSegmentURIs []string
@ -455,19 +459,44 @@ type Client struct {
// NewClient allocates a Client.
func NewClient(
ur string,
fingerprint string,
onTracks func(*gortsplib.Track, *gortsplib.Track) error,
onFrame func(bool, []byte),
parent ClientParent,
) *Client {
ctx, ctxCancel := context.WithCancel(context.Background())
tlsConfig := &tls.Config{}
if fingerprint != "" {
tlsConfig.InsecureSkipVerify = true
tlsConfig.VerifyConnection = func(cs tls.ConnectionState) error {
h := sha256.New()
h.Write(cs.PeerCertificates[0].Raw)
hstr := hex.EncodeToString(h.Sum(nil))
fingerprintLower := strings.ToLower(fingerprint)
if hstr != fingerprintLower {
return fmt.Errorf("server fingerprint do not match: expected %s, got %s",
fingerprintLower, hstr)
}
return nil
}
}
c := &Client{
ur: ur,
onTracks: onTracks,
onFrame: onFrame,
parent: parent,
ctx: ctx,
ctxCancel: ctxCancel,
ur: ur,
onTracks: onTracks,
onFrame: onFrame,
parent: parent,
ctx: ctx,
ctxCancel: ctxCancel,
httpClient: &http.Client{
Transport: &http.Transport{
TLSClientConfig: tlsConfig,
},
},
segmentQueue: newClientSegmentQueue(),
allocateProcs: make(chan clientAllocateProcsReq),
outErr: make(chan error, 1),
@ -690,7 +719,7 @@ func (c *Client) downloadPlaylist(innerCtx context.Context) (m3u8.Playlist, erro
return nil, err
}
res, err := http.DefaultClient.Do(req)
res, err := c.httpClient.Do(req)
if err != nil {
return nil, err
}
@ -720,7 +749,7 @@ func (c *Client) downloadSegment(innerCtx context.Context, segmentURI string) ([
return nil, err
}
res, err := http.DefaultClient.Do(req)
res, err := c.httpClient.Do(req)
if err != nil {
return nil, err
}

View file

@ -116,6 +116,7 @@ func TestClient(t *testing.T) {
c := NewClient(
"http://localhost:5780/stream.m3u8",
"",
onTracks,
onFrame,
testClientParent{},

View file

@ -144,9 +144,9 @@ paths:
# when interacting with old cameras that require it.
sourceAnyPortEnable: no
# if the source is a RTSPS URL, and the source certificate is self-signed
# if the source is a RTSPS or HTTPS URL, and the source certificate is self-signed
# or invalid, you can provide the fingerprint of the certificate in order to
# validate it anyway, and at the same time prevent man-in-the-middle attacks.
# validate it anyway.
# the fingerprint can be obtained by running:
# openssl s_client -connect source_ip:source_port </dev/null 2>/dev/null | sed -n '/BEGIN/,/END/p' > server.crt
# openssl x509 -in server.crt -noout -fingerprint -sha256 | cut -d "=" -f2 | tr -d ':'