Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RTSP DESCRIBE 401 when both BASIC and DIGEST auth is offered. #9800

Closed
DanijelBojcic opened this issue Dec 21, 2021 · 10 comments
Closed

RTSP DESCRIBE 401 when both BASIC and DIGEST auth is offered. #9800

DanijelBojcic opened this issue Dec 21, 2021 · 10 comments
Assignees

Comments

@DanijelBojcic
Copy link

When trying to play a HikVision IP Camera I get DESCRIBE 401 error.
The URL looks like this: rtsp://USER:[email protected]:554/Streaming/channels/102

Formats ( based on VLC's media information ) : H264 - MPEG-4 AVC (part 10) (h264)

Changing WWW_AUTHENTICATION_HEADER_BASIC_PATTERN to match WWW-Authenticate: Basic realm="IP Camera(C1214)" ( mentioned here ) didn't help, although I think it is also an issue because it currently doesn't recognize capital letters and numbers.

Auth

2021-12-21 12:05:35.895 10631-10956/com.dotlab.pierre.digitalhive D/RtspClient: RTSP/1.0 200 OK
    CSeq: 0
    Public: OPTIONS, DESCRIBE, PLAY, PAUSE, SETUP, TEARDOWN, SET_PARAMETER, GET_PARAMETER
    Date:  Tue, Dec 21 2021 12:08:36 GMT
2021-12-21 12:05:35.907 10631-10956/com.dotlab.pierre.digitalhive D/RtspClient: DESCRIBE rtsp://172.30.34.12:554/Streaming/channels/102 RTSP/1.0
    User-Agent: ExoPlayerLib/2.16.1
    CSeq: 1
2021-12-21 12:05:35.929 10631-10956/com.dotlab.pierre.digitalhive D/RtspClient: RTSP/1.0 401 Unauthorized
    CSeq: 1
    WWW-Authenticate: Digest realm="IP Camera(C1214)", nonce="0191a41d87c28cd52b3e9c8adc99291c", stale="FALSE"
    WWW-Authenticate: Basic realm="IP Camera(C1214)"
    Date:  Tue, Dec 21 2021 12:08:36 GMT
2021-12-21 12:05:35.937 10631-10956/com.dotlab.pierre.digitalhive D/RTSPClient: parseWwwAuthenticateHeader: BASIC
2021-12-21 12:05:35.942 10631-10956/com.dotlab.pierre.digitalhive D/RtspClient: DESCRIBE rtsp://172.30.34.12:554/Streaming/channels/102 RTSP/1.0
    User-Agent: ExoPlayerLib/2.16.1
    CSeq: 2
    Authorization: YWRtaW46ZGlnaXRhTGhpdkUh
2021-12-21 12:05:35.957 10631-10956/com.dotlab.pierre.digitalhive D/RtspClient: RTSP/1.0 401 Unauthorized
    CSeq: 2
    WWW-Authenticate: Digest realm="IP Camera(C1214)", nonce="22bb4bccbd3fdd372b71c3447fc5a714", stale="FALSE"
    WWW-Authenticate: Basic realm="IP Camera(C1214)"
    Date:  Tue, Dec 21 2021 12:08:36 GMT

Error

021-12-21 12:05:35.976 10631-10956/com.dotlab.pierre.digitalhive E/ExoPlayerImplInternal: Playback error
      com.google.android.exoplayer2.ExoPlaybackException: Source error
        at com.google.android.exoplayer2.ExoPlayerImplInternal.handleIoException(ExoPlayerImplInternal.java:628)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:604)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:246)
        at android.os.HandlerThread.run(HandlerThread.java:67)
     Caused by: java.io.IOException: DESCRIBE 401
        at com.google.android.exoplayer2.source.rtsp.RtspMediaPeriod$InternalListener.onSessionTimelineRequestFailed(RtspMediaPeriod.java:564)
        at com.google.android.exoplayer2.source.rtsp.RtspClient.dispatchRtspError(RtspClient.java:305)
        at com.google.android.exoplayer2.source.rtsp.RtspClient.access$600(RtspClient.java:73)
        at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener.handleRtspResponse(RtspClient.java:561)
        at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener.handleRtspMessage(RtspClient.java:494)
        at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener.lambda$onRtspMessageReceived$0$RtspClient$MessageListener(RtspClient.java:487)
        at com.google.android.exoplayer2.source.rtsp.-$$Lambda$RtspClient$MessageListener$dJPB0r-FyeWq7xUwLx0FyxTnUk0.run(Unknown Source:4)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:246) 
        at android.os.HandlerThread.run(HandlerThread.java:67) 
     Caused by: com.google.android.exoplayer2.source.rtsp.RtspMediaSource$RtspPlaybackException: DESCRIBE 401
        at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener.handleRtspResponse(RtspClient.java:563)
        at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener.handleRtspMessage(RtspClient.java:494) 
        at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener.lambda$onRtspMessageReceived$0$RtspClient$MessageListener(RtspClient.java:487) 
        at com.google.android.exoplayer2.source.rtsp.-$$Lambda$RtspClient$MessageListener$dJPB0r-FyeWq7xUwLx0FyxTnUk0.run(Unknown Source:4) 
        at android.os.Handler.handleCallback(Handler.java:938) 
        at android.os.Handler.dispatchMessage(Handler.java:99) 
        at android.os.Looper.loop(Looper.java:246) 
        at android.os.HandlerThread.run(HandlerThread.java:67) 

Versions

  • ExoPlayer version number: 2.16.1
  • Android version: 11
  • Android device: Samsung Galaxy Tab A
@claincly
Copy link
Contributor

claincly commented Dec 21, 2021

The error happened because the server doesn't recognize the provided authentication info (YWRtaW46ZGlnaXRhTGhpdkUh). To isolate the issue, can you try
base64_encode("<username>:<password>")

and see if it matches YWRtaW46ZGlnaXRhTGhpdkUh?

As an aside, the current regex does match Basic realm="IP Camera(C1214)"

@claincly
Copy link
Contributor

My guess is, although your server provides BASIC auth scheme, it does not actually supports it. The server supports digest auth only.

@DanijelBojcic
Copy link
Author

DanijelBojcic commented Dec 21, 2021

I can confirm that it matches YWRtaW46ZGlnaXRhTGhpdkUh

If the problem is on the server how can VLC play it?

@claincly
Copy link
Contributor

claincly commented Dec 22, 2021

It would be helpful if you wireshark VLC and confirm if it uses digest instead. If it is, it's a sign for us to add "force using digest auth"

@DanijelBojcic
Copy link
Author

I was able to debug it. Here is the flow:

  1. VLC initiates the connection
  2. The server sends response 200
  3. VLC initiates the connection again
  4. The server sends 401 and asks for an auth
    Response: RTSP/1.0 401 Unauthorized
    CSeq: 3
    WWW-Authenticate: Digest realm="IP Camera(C1214)", nonce="375b7a9f858ed597c28a66316e6ab301", stale="FALSE"
    WWW-Authenticate: Basic realm="IP Camera(C1214)"
  1. VLC sends DIGEST by default, it doesn't even try it with basic auth.
    CSeq: 4
    Authorization: Digest username="X", realm="IP Camera(C1214)", nonce="375b7a9f858ed597c28a66316e6ab301", uri="rtsp://172.30.34.12:554/Streaming/channels/102", response="x"
    User-Agent: LibVLC/3.0.16 (LIVE555 Streaming Media v2016.11.28)
    Accept: application/sdp

My guess is, although your server provides BASIC auth scheme, it does not actually supports it. The server supports digest auth only.

It seems you've guessed rigth. How can I force exoplayer to use DIGEST auth instead until you fix it?

@claincly
Copy link
Contributor

You can patch RtspClient with the following code to prefer DIGEST:

@@ -548,14 +548,23 @@ import org.checkerframework.checker.null
           case 401:
             if (rtspAuthUserInfo != null && !receivedAuthorizationRequest) {
               // Unauthorized.
-              @Nullable
-              String wwwAuthenticateHeader = response.headers.get(RtspHeaders.WWW_AUTHENTICATE);
-              if (wwwAuthenticateHeader == null) {
+              ImmutableList<String> wwwAuthenticateHeaders =
+                  response.headers.values(RtspHeaders.WWW_AUTHENTICATE);
+              if (wwwAuthenticateHeaders.isEmpty()) {
                 throw ParserException.createForMalformedManifest(
                     "Missing WWW-Authenticate header in a 401 response.", /* cause= */ null);
               }
-              rtspAuthenticationInfo =
-                  RtspMessageUtil.parseWwwAuthenticateHeader(wwwAuthenticateHeader);
+
+              for (int i = 0; i < wwwAuthenticateHeaders.size(); i++) {
+                rtspAuthenticationInfo =
+                    RtspMessageUtil.parseWwwAuthenticateHeader(wwwAuthenticateHeaders.get(i));
+                if (rtspAuthenticationInfo.authenticationMechanism
+                    == RtspAuthenticationInfo.DIGEST) {
+                  // Prefers DIGEST when RTSP servers sends both BASIC and DIGEST auth info.
+                  break;
+                }
+              }
+
               messageSender.retryLastRequest();
               receivedAuthorizationRequest = true;
               return;

@DanijelBojcic
Copy link
Author

DanijelBojcic commented Dec 27, 2021

I have tried the patch, it forces the digest auth, but after the authentication I get the same error as before.

EDIT: I've just realized that it's not the same error, it's now SETUP 401. Should I open another issue for this?

These are the logs I get:

2021-12-27 08:35:23.603 4924-9223/com.dotlab.pierre.digitalhive D/RtspClient: OPTIONS rtsp://172.30.34.12:554/Streaming/channels/102 RTSP/1.0
    User-Agent: ExoPlayerLib/2.16.1
    CSeq: 0
2021-12-27 08:35:23.623 4924-9223/com.dotlab.pierre.digitalhive D/RtspClient: RTSP/1.0 200 OK
    CSeq: 0
    Public: OPTIONS, DESCRIBE, PLAY, PAUSE, SETUP, TEARDOWN, SET_PARAMETER, GET_PARAMETER
    Date:  Mon, Dec 27 2021 08:38:32 GMT
2021-12-27 08:35:23.630 4924-9223/com.dotlab.pierre.digitalhive D/RtspClient: DESCRIBE rtsp://172.30.34.12:554/Streaming/channels/102 RTSP/1.0
    User-Agent: ExoPlayerLib/2.16.1
    CSeq: 1
2021-12-27 08:35:23.677 4924-9223/com.dotlab.pierre.digitalhive D/RtspClient: RTSP/1.0 401 Unauthorized
    CSeq: 1
    WWW-Authenticate: Digest realm="IP Camera(C1214)", nonce="a0f8116631ca25c24d7ca559e253ad97", stale="FALSE"
    WWW-Authenticate: Basic realm="IP Camera(C1214)"
    Date:  Mon, Dec 27 2021 08:38:32 GMT
2021-12-27 08:35:23.685 4924-9223/com.dotlab.pierre.digitalhive D/RtspClient: DESCRIBE rtsp://172.30.34.12:554/Streaming/channels/102 RTSP/1.0
    User-Agent: ExoPlayerLib/2.16.1
    CSeq: 2
    Authorization: Digest username="X", realm="IP Camera(C1214)", nonce="a0f8116631ca25c24d7ca559e253ad97", uri="rtsp://172.30.34.12:554/Streaming/channels/102", response="c20f71721cdfddbfa780b92dc891ab18"
2021-12-27 08:35:23.714 4924-9223/com.dotlab.pierre.digitalhive D/RtspClient: RTSP/1.0 200 OK
    CSeq: 2
    Content-Type: application/sdp
    Content-Base: rtsp://172.30.34.12:554/Streaming/channels/102/
    Content-Length: 629
    
    v=0
    o=- 1640594312734789 1640594312734789 IN IP4 172.30.34.12
    s=Media Presentation
    e=NONE
    b=AS:5050
    t=0 0
    a=control:rtsp://172.30.34.12:554/Streaming/channels/102/
    m=video 0 RTP/AVP 96
    c=IN IP4 0.0.0.0
    b=AS:5000
    a=recvonly
    a=x-dimensions:640,480
    a=control:rtsp://172.30.34.12:554/Streaming/channels/102/trackID=1
    a=rtpmap:96 H264/90000
    a=fmtp:96 profile-level-id=420029; packetization-mode=1; sprop-parameter-sets=Z01AFo2NQFAe//+AAgABtwEBAUAAAPoAABdwOhgC3gAM6K7y40MAW8ABnRXeXCg=,aO44gA==
    a=Media_header:MEDIAINFO=494D4B48010200000400000100000000000000000000000000000000000000000000000000000000;
    a=appversion:1.0
2021-12-27 08:35:23.734 4924-9223/com.dotlab.pierre.digitalhive D/MediaCodecInfo: NoSupport [codec.profileLevel, avc1.420029, video/avc] [OMX.SEC.avc.sw.dec, video/avc] [gta3xlwifi, SM-T510, samsung, 30]
2021-12-27 08:35:23.736 4924-9223/com.dotlab.pierre.digitalhive D/MediaCodecInfo: NoSupport [codec.profileLevel, avc1.420029, video/avc] [OMX.SEC.avc.sw.dec, video/avc] [gta3xlwifi, SM-T510, samsung, 30]
2021-12-27 08:35:23.743 4924-9223/com.dotlab.pierre.digitalhive D/RtspClient: SETUP rtsp://172.30.34.12:554/Streaming/channels/102/trackID=1 RTSP/1.0
    User-Agent: ExoPlayerLib/2.16.1
    CSeq: 3
    Authorization: Digest username="X", realm="IP Camera(C1214)", nonce="a0f8116631ca25c24d7ca559e253ad97", uri="rtsp://172.30.34.12:554/Streaming/channels/102/trackID=1", response="9a0aff87dac3651bcd10c8db7bd7141f"
    Transport: RTP/AVP;unicast;client_port=34988-34989
2021-12-27 08:35:23.838 4924-9223/com.dotlab.pierre.digitalhive D/RtspClient: RTSP/1.0 200 OK
    CSeq: 3
    Session:       1926560283;timeout=60
    Transport: RTP/AVP;unicast;client_port=34988-34989;server_port=8310-8311;ssrc=406a7624;mode="play"
    Date:  Mon, Dec 27 2021 08:38:32 GMT
2021-12-27 08:35:23.847 4924-9223/com.dotlab.pierre.digitalhive D/RtspClient: PLAY rtsp://172.30.34.12:554/Streaming/channels/102 RTSP/1.0
    User-Agent: ExoPlayerLib/2.16.1
    CSeq: 4
    Session: 1926560283
    Authorization: Digest username="X", realm="IP Camera(C1214)", nonce="a0f8116631ca25c24d7ca559e253ad97", uri="rtsp://172.30.34.12:554/Streaming/channels/102", response="8b0d7210d2f682563e1ff8b40ba5dc5e"
    Range: npt=0.000-
2021-12-27 08:35:23.902 4924-9223/com.dotlab.pierre.digitalhive D/RtspClient: RTSP/1.0 200 OK
    CSeq: 4
    Session:       1926560283
    RTP-Info: url=rtsp://172.30.34.12:554/Streaming/channels/102/trackID=1;seq=56270;rtptime=3336819680
    Date:  Mon, Dec 27 2021 08:38:32 GMT
2021-12-27 08:35:31.743 4924-9223/com.dotlab.pierre.digitalhive D/RtspClient: TEARDOWN rtsp://172.30.34.12:554/Streaming/channels/102 RTSP/1.0
    User-Agent: ExoPlayerLib/2.16.1
    CSeq: 5
    Session: 1926560283
    Authorization: Digest username="X", realm="IP Camera(C1214)", nonce="a0f8116631ca25c24d7ca559e253ad97", uri="rtsp://172.30.34.12:554/Streaming/channels/102", response="004756f2bb16b27487717a334b861b2e"
2021-12-27 08:35:31.761 4924-9223/com.dotlab.pierre.digitalhive D/RtspClient: SETUP rtsp://172.30.34.12:554/Streaming/channels/102/trackID=1 RTSP/1.0
    User-Agent: ExoPlayerLib/2.16.1
    CSeq: 6
    Transport: RTP/AVP/TCP;unicast;interleaved=0-1
2021-12-27 08:35:31.772 4924-9223/com.dotlab.pierre.digitalhive D/RtspClient: RTSP/1.0 401 Unauthorized
    CSeq: 6
    WWW-Authenticate: Digest realm="IP Camera(C1214)", nonce="c1d5bc77650a1bdaba5d1813997f0fda", stale="FALSE"
    WWW-Authenticate: Basic realm="IP Camera(C1214)"
    Date:  Mon, Dec 27 2021 08:38:40 GMT
2021-12-27 08:35:31.779 4924-9223/com.dotlab.pierre.digitalhive D/RtspClient: SETUP rtsp://172.30.34.12:554/Streaming/channels/102/trackID=1 RTSP/1.0
    User-Agent: ExoPlayerLib/2.16.1
    CSeq: 7
    Authorization: Digest username="X", realm="IP Camera(C1214)", nonce="c1d5bc77650a1bdaba5d1813997f0fda", uri="rtsp://172.30.34.12:554/Streaming/channels/102/trackID=1", response="22a360658fce923f53d483e2a13cc037"
    Transport: RTP/AVP/TCP;unicast;interleaved=0-1
2021-12-27 08:35:31.788 4924-9223/com.dotlab.pierre.digitalhive D/RtspClient: RTSP/1.0 401 Unauthorized
    CSeq: 7
    WWW-Authenticate: Digest realm="IP Camera(C1214)", nonce="b77a5bc84c51b58a1d92fb495dff44e7", stale="FALSE"
    WWW-Authenticate: Basic realm="IP Camera(C1214)"
    Date:  Mon, Dec 27 2021 08:38:40 GMT
2021-12-27 08:35:31.795 4924-9223/com.dotlab.pierre.digitalhive E/ExoPlayerImplInternal: Playback error
      com.google.android.exoplayer2.ExoPlaybackException: Source error
        at com.google.android.exoplayer2.ExoPlayerImplInternal.handleIoException(ExoPlayerImplInternal.java:628)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:604)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:246)
        at android.os.HandlerThread.run(HandlerThread.java:67)
     Caused by: com.google.android.exoplayer2.source.rtsp.RtspMediaSource$RtspPlaybackException: SETUP 401
        at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener.handleRtspResponse(RtspClient.java:615)
        at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener.handleRtspMessage(RtspClient.java:535)
        at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener.lambda$onRtspMessageReceived$0$RtspClient$MessageListener(RtspClient.java:528)
        at com.google.android.exoplayer2.source.rtsp.-$$Lambda$RtspClient$MessageListener$dJPB0r-FyeWq7xUwLx0FyxTnUk0.run(Unknown Source:4)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:246) 
        at android.os.HandlerThread.run(HandlerThread.java:67) 

@claincly
Copy link
Contributor

Can you try building RtspMediaSource with forceUseRtpTcp set to true?

@DanijelBojcic
Copy link
Author

Thanks @claincly
It's working with the patch and the forceUseRtpTcp set to true.

@claincly claincly changed the title RTSP DESCRIBE 401 [HikVision] RTSP DESCRIBE 401 when both BASIC and DIGEST auth is offered. Jan 4, 2022
@claincly
Copy link
Contributor

claincly commented Jan 4, 2022

A note on why forceUseRtpTcp worked:

When ExoPlayer retries for using TCP, the flow is like

[C]linet: DESCRIBE
[S]erver: 401
C: DESCRIBE (w/ auth)
S: OK
C: SETUP (w/ auth)
S: OK
C: PLAY (w/ auth)
S: OK
<<---NO RTP packet, retry
C: TEARDOWN (w/ auth)
S:OK

<<--- RETRY

C: SETUP
S: 401
C: SETUP (w/ auth)
S:401

<<--- ExoPlayer fails

The server does not accept initiating authentication when performing SETUP, but ExoPlayer's TCP retrying logic starts with SETUP. forceUseRtpTcp though, eliminated the need to retry and thus will work.

In VLC's case, the retry logic starts the entire RTSP exchange (from OPTIONS, to DESCRIBE, SETUP, PLAY) again.

ojw28 pushed a commit that referenced this issue Jan 7, 2022
Issue: #9800

Added test for RTSP authentication.

PiperOrigin-RevId: 420048821
marcbaechinger pushed a commit to androidx/media that referenced this issue Jan 11, 2022
Issue: google/ExoPlayer#9800

Added test for RTSP authentication.

PiperOrigin-RevId: 420048821
@google google locked and limited conversation to collaborators Mar 5, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants