Skip to content

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

Closed

Description

@DanijelBojcic

When trying to play a HikVision IP Camera I get DESCRIBE 401 error.
The URL looks like this: rtsp://USER:PASS@172.30.34.12: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

Activity

  1. claincly commented on Dec 21, 2021

    @claincly
    Contributor

    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)"

  2. claincly commented on Dec 21, 2021

    @claincly
    Contributor

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

  3. DanijelBojcic commented on Dec 21, 2021

    @DanijelBojcic
    Author

    I can confirm that it matches YWRtaW46ZGlnaXRhTGhpdkUh

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

  4. claincly commented on Dec 22, 2021

    @claincly
    Contributor

    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"

  5. DanijelBojcic commented on Dec 23, 2021

    @DanijelBojcic
    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?

  6. claincly commented on Dec 23, 2021

    @claincly
    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;
    
  7. DanijelBojcic commented on Dec 27, 2021

    @DanijelBojcic
    Author

    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) 
    
  8. claincly commented on Dec 29, 2021

    @claincly
    Contributor

    Can you try building RtspMediaSource with forceUseRtpTcp set to true?

  9. DanijelBojcic commented on Jan 3, 2022

    @DanijelBojcic
    Author

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

  10. changed the title [-]RTSP DESCRIBE 401 [HikVision][/-] [+]RTSP DESCRIBE 401 when both BASIC and DIGEST auth is offered.[/+] on Jan 4, 2022
  11. claincly commented on Jan 4, 2022

    @claincly
    Contributor

    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.

  12. locked and limited conversation to collaborators on Mar 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions