8531c006d4
* enhancement: supporting http tunneled rtsp * refactor: simplify HTTP tunnel support per review feedback - Extract streamCandidate() for nmap port classification - Add isCommonHTTPPort() for masscan and nmap fallback - Move URL building to Stream.String() and Stream.URL() - Pass Stream directly to attack methods instead of individual args - Add TLS config for HTTPS tunnel support - Make auth detection non-fatal for tunneled streams - Rename HTTPTunnel to UseHTTPTunnel * - Testing the auth workflow for the tunneled streams is not blocking the rest of the pipeline since I changed the return values to Auth unknown and nil - added extra ports in the test according to suggestions * fixing some lint errors * removing the unused buildrtspurl * delayed the urlstream call for clarity removed error messages refactored the test that used the deprecated buildTRSPurl to use stream.URL and stream.String() methods * extracting iscommonHTTP port to pkg/ports (package ports) switching on u.scheme to create proper schemes for http and https * refactor: replace HTTP tunnel bool with scheme-based detection; enable TLS only for HTTPS-tunneled streams * chore: simnplify InferTunnelScheme and newRTSPClient * fix: remove rendundant check in streamCandidate * fix: typo in parseScheme * tests: coverage for new schemes * fix: use RTSP and not RTSPS for HTTPS URLs * fix: tunneled RTSP scheme handling and auth detection fallback * ui: render empty credentials as none in summary and TUI * chore: ignore duplicate-string warning for none literal * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * fix: rtsps probe headers --------- Co-authored-by: Brendan Le Glaunec <brendan@glaulabs.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
92 lines
2.0 KiB
Go
92 lines
2.0 KiB
Go
package cameradar
|
|
|
|
import (
|
|
"net"
|
|
"net/netip"
|
|
"net/url"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/bluenviron/gortsplib/v5/pkg/base"
|
|
)
|
|
|
|
// AuthType represents the RTSP authentication method.
|
|
type AuthType int
|
|
|
|
// Supported authentication methods.
|
|
const (
|
|
AuthUnknown AuthType = iota
|
|
AuthNone
|
|
AuthBasic
|
|
AuthDigest
|
|
)
|
|
|
|
// Stream represents a camera's stream, typically accessed over RTSP/RTSPS.
|
|
type Stream struct {
|
|
Device string `json:"device"`
|
|
Username string `json:"username"`
|
|
Password string `json:"password"`
|
|
Routes []string `json:"route"`
|
|
Address netip.Addr `json:"address" validate:"required"`
|
|
Port uint16 `json:"port" validate:"required"`
|
|
|
|
CredentialsFound bool `json:"credentials_found"`
|
|
RouteFound bool `json:"route_found"`
|
|
Available bool `json:"available"`
|
|
Scheme string `json:"scheme"`
|
|
|
|
AuthenticationType AuthType `json:"authentication_type"`
|
|
}
|
|
|
|
func (s Stream) resolvedScheme() string {
|
|
scheme := s.Scheme
|
|
if scheme == "" {
|
|
return "rtsp"
|
|
}
|
|
return scheme
|
|
}
|
|
|
|
func parseScheme(scheme string) string {
|
|
switch scheme {
|
|
case "http":
|
|
return "rtsp"
|
|
case "https":
|
|
return "rtsps"
|
|
default:
|
|
return scheme
|
|
}
|
|
}
|
|
|
|
// Route returns this stream's route if there is one.
|
|
func (s Stream) Route() string {
|
|
if len(s.Routes) > 0 {
|
|
return s.Routes[0]
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// String builds the stream URL using the configured scheme, defaulting to rtsp.
|
|
func (s Stream) String() string {
|
|
scheme := s.resolvedScheme()
|
|
|
|
host := net.JoinHostPort(s.Address.String(), strconv.Itoa(int(s.Port)))
|
|
path := "/" + strings.TrimLeft(strings.TrimSpace(s.Route()), "/")
|
|
|
|
u := &url.URL{
|
|
Scheme: scheme,
|
|
Host: host,
|
|
Path: path,
|
|
}
|
|
if s.Username != "" || s.Password != "" {
|
|
u.User = url.UserPassword(s.Username, s.Password)
|
|
}
|
|
|
|
return u.String()
|
|
}
|
|
|
|
// URL parses the stream URL into a *base.URL, normalizing http/https to rtsp/rtsps.
|
|
func (s Stream) URL() (*base.URL, error) {
|
|
s.Scheme = parseScheme(s.resolvedScheme())
|
|
return base.ParseURL(s.String())
|
|
}
|