feat: support http tunneled rtsp (#419)
* 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>
This commit is contained in:
committed by
GitHub
parent
14dcb74e89
commit
8531c006d4
+11
-5
@@ -88,11 +88,9 @@ func formatStream(stream cameradar.Stream) string {
|
||||
builder.WriteString(" Routes: not found\n")
|
||||
}
|
||||
|
||||
if stream.CredentialsFound {
|
||||
if stream.CredentialsFound || stream.AuthenticationType == cameradar.AuthNone {
|
||||
builder.WriteString(" Credentials: ")
|
||||
builder.WriteString(stream.Username)
|
||||
builder.WriteString(":")
|
||||
builder.WriteString(stream.Password)
|
||||
builder.WriteString(formatCredentials(stream))
|
||||
builder.WriteString("\n")
|
||||
} else {
|
||||
builder.WriteString(" Credentials: not found\n")
|
||||
@@ -105,7 +103,7 @@ func formatStream(stream cameradar.Stream) string {
|
||||
builder.WriteString("no\n")
|
||||
}
|
||||
|
||||
if stream.RouteFound && stream.CredentialsFound {
|
||||
if stream.RouteFound && (stream.CredentialsFound || stream.AuthenticationType == cameradar.AuthNone) {
|
||||
builder.WriteString(" RTSP URL: ")
|
||||
builder.WriteString(formatRTSPURL(stream))
|
||||
builder.WriteString("\n")
|
||||
@@ -133,6 +131,14 @@ func formatAdminPanelURL(stream cameradar.Stream) string {
|
||||
return fmt.Sprintf("http://%s/", stream.Address.String())
|
||||
}
|
||||
|
||||
func formatCredentials(stream cameradar.Stream) string {
|
||||
if stream.Username == "" && stream.Password == "" {
|
||||
return "none"
|
||||
}
|
||||
|
||||
return stream.Username + ":" + stream.Password
|
||||
}
|
||||
|
||||
func authTypeLabel(auth cameradar.AuthType) string {
|
||||
switch auth {
|
||||
case cameradar.AuthNone:
|
||||
|
||||
@@ -73,18 +73,41 @@ func TestFormatSummary(t *testing.T) {
|
||||
"Authentication: digest",
|
||||
"Routes: stream1, stream2",
|
||||
"Credentials: user:pass",
|
||||
"Credentials: none",
|
||||
"RTSP URL: rtsp://user:pass@10.0.0.1:8554/stream1",
|
||||
"Admin panel: http://10.0.0.1/",
|
||||
"Admin panel: http://10.0.0.2/",
|
||||
},
|
||||
wantNotContains: []string{
|
||||
"RTSP URL: rtsp://10.0.0.2",
|
||||
"Error:",
|
||||
},
|
||||
orderedPairs: [][2]string{
|
||||
{"• 10.0.0.1:8554", "• 10.0.0.2:554"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "empty discovered credentials render as none",
|
||||
streams: []cameradar.Stream{
|
||||
{
|
||||
Address: netip.MustParseAddr("10.0.0.4"),
|
||||
Port: 554,
|
||||
Available: true,
|
||||
RouteFound: true,
|
||||
Routes: []string{"stream"},
|
||||
CredentialsFound: true,
|
||||
AuthenticationType: cameradar.AuthNone,
|
||||
},
|
||||
},
|
||||
wantContains: []string{
|
||||
"Accessible streams: 1",
|
||||
"Credentials: none",
|
||||
"RTSP URL: rtsp://10.0.0.4:554/stream",
|
||||
},
|
||||
wantNotContains: []string{
|
||||
"Credentials: :",
|
||||
"rtsp://:@10.0.0.4:554/stream",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
||||
+1
-1
@@ -542,7 +542,7 @@ func buildSummaryRows(streams []cameradar.Stream, visibility summaryVisibilitySt
|
||||
|
||||
credentials := emptyEntry
|
||||
if visibility.showCredentials && stream.CredentialsFound {
|
||||
credentials = fmt.Sprintf("%s:%s", stream.Username, stream.Password)
|
||||
credentials = formatCredentials(stream)
|
||||
}
|
||||
|
||||
available := emptyEntry
|
||||
|
||||
Reference in New Issue
Block a user