changeset 20527:b8f069b793c2

Realrtsp authentication
author rtogni
date Mon, 30 Oct 2006 21:55:58 +0000
parents d61a365dbe87
children df74d0a51102
files stream/librtsp/rtsp_session.c stream/librtsp/rtsp_session.h stream/realrtsp/real.c stream/realrtsp/real.h stream/stream_rtsp.c
diffstat 5 files changed, 58 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/stream/librtsp/rtsp_session.c	Mon Oct 30 21:31:11 2006 +0000
+++ b/stream/librtsp/rtsp_session.c	Mon Oct 30 21:55:58 2006 +0000
@@ -74,7 +74,8 @@
 };
 
 //rtsp_session_t *rtsp_session_start(char *mrl) {
-rtsp_session_t *rtsp_session_start(int fd, char **mrl, char *path, char *host, int port, int *redir, uint32_t bandwidth) {
+rtsp_session_t *rtsp_session_start(int fd, char **mrl, char *path, char *host,
+  int port, int *redir, uint32_t bandwidth, char *user, char *pass) {
 
   rtsp_session_t *rtsp_session = NULL;
   char *server;
@@ -111,7 +112,7 @@
   {
     /* we are talking to a real server ... */
 
-    h=real_setup_and_get_header(rtsp_session->s, bandwidth);
+    h=real_setup_and_get_header(rtsp_session->s, bandwidth, user, pass);
     if (!h) {
       /* got an redirect? */
       if (rtsp_search_answers(rtsp_session->s, RTSP_OPTIONS_LOCATION))
--- a/stream/librtsp/rtsp_session.h	Mon Oct 30 21:31:11 2006 +0000
+++ b/stream/librtsp/rtsp_session.h	Mon Oct 30 21:55:58 2006 +0000
@@ -33,7 +33,8 @@
 
 typedef struct rtsp_session_s rtsp_session_t;
 
-rtsp_session_t *rtsp_session_start(int fd, char **mrl, char *path, char *host, int port, int *redir, uint32_t bandwidth);
+rtsp_session_t *rtsp_session_start(int fd, char **mrl, char *path, char *host,
+  int port, int *redir, uint32_t bandwidth, char *user, char *pass);
 
 int rtsp_session_read(rtsp_session_t *session, char *data, int len);
 
--- a/stream/realrtsp/real.c	Mon Oct 30 21:31:11 2006 +0000
+++ b/stream/realrtsp/real.c	Mon Oct 30 21:55:58 2006 +0000
@@ -41,6 +41,8 @@
 #else
 #include "libavutil/md5.h"
 #endif
+#include "../http.h"
+#include "mp_msg.h"
 
 /*
 #define LOG
@@ -436,7 +438,8 @@
 
 //! maximum size of the rtsp description, must be < INT_MAX
 #define MAX_DESC_BUF (20 * 1024 * 1024)
-rmff_header_t  *real_setup_and_get_header(rtsp_t *rtsp_session, uint32_t bandwidth) {
+rmff_header_t *real_setup_and_get_header(rtsp_t *rtsp_session, uint32_t bandwidth,
+  char *username, char *password) {
 
   char *description=NULL;
   char *session_id=NULL;
@@ -450,6 +453,7 @@
   unsigned int size;
   int status;
   uint32_t maxbandwidth = bandwidth;
+  char* authfield = NULL;
   
   /* get challenge */
   challenge1=strdup(rtsp_search_answers(rtsp_session,"RealChallenge1"));
@@ -462,6 +466,7 @@
       bandwidth = 10485800;
   
   /* request stream description */
+rtsp_send_describe:
   rtsp_schedule_field(rtsp_session, "Accept: application/sdp");
   sprintf(buf, "Bandwidth: %u", bandwidth);
   rtsp_schedule_field(rtsp_session, buf);
@@ -471,8 +476,50 @@
   rtsp_schedule_field(rtsp_session, "SupportsMaximumASMBandwidth: 1");
   rtsp_schedule_field(rtsp_session, "Language: en-US");
   rtsp_schedule_field(rtsp_session, "Require: com.real.retain-entity-for-setup");
+  if(authfield)
+    rtsp_schedule_field(rtsp_session, authfield);
   status=rtsp_request_describe(rtsp_session,NULL);
 
+  if (status == 401) {
+    int authlen, b64_authlen;
+    char *authreq;
+    char* authstr = NULL;
+
+    if (authfield) {
+      mp_msg(MSGT_STREAM, MSGL_ERR, "realrtsp: authorization failed, check your credentials\n");
+      goto autherr;
+    }
+    if (!(authreq = rtsp_search_answers(rtsp_session,"WWW-Authenticate"))) {
+      mp_msg(MSGT_STREAM, MSGL_ERR, "realrtsp: 401 but no auth request, aborting\n");
+      goto autherr;
+    }
+    if (!username) {
+      mp_msg(MSGT_STREAM, MSGL_ERR, "realrtsp: auth required but no username supplied\n");
+      goto autherr;
+    }
+    if (!strstr(authreq, "Basic")) {
+      mp_msg(MSGT_STREAM, MSGL_ERR, "realrtsp: authenticator not supported (%s)\n", authreq);
+      goto autherr;
+    }
+    authlen = strlen(username) + (password ? strlen(password) : 0) + 2;
+    authstr = malloc(authlen);
+    sprintf(authstr, "%s:%s", username, password ? password : "");
+    authfield = malloc(authlen*2+22);
+    strcpy(authfield, "Authorization: Basic ");
+    b64_authlen = base64_encode(authstr, authlen, authfield+21, authlen*2);
+    free(authstr);
+    if (b64_authlen < 0) {
+      mp_msg(MSGT_STREAM, MSGL_ERR, "realrtsp: base64 output overflow, this should never happen\n");
+      goto autherr;
+    }
+    authfield[b64_authlen+21] = 0;
+    goto rtsp_send_describe;
+  }
+autherr:
+
+  if (authfield)
+     free(authfield);
+
   if ( status<200 || status>299 )
   {
     char *alert=rtsp_search_answers(rtsp_session,"Alert");
--- a/stream/realrtsp/real.h	Mon Oct 30 21:31:11 2006 +0000
+++ b/stream/realrtsp/real.h	Mon Oct 30 21:55:58 2006 +0000
@@ -48,7 +48,8 @@
 };
 
 int real_get_rdt_chunk(rtsp_t *rtsp_session, char **buffer);
-rmff_header_t *real_setup_and_get_header(rtsp_t *rtsp_session, uint32_t bandwidth);
+rmff_header_t *real_setup_and_get_header(rtsp_t *rtsp_session, uint32_t bandwidth,
+  char *username, char *password);
 struct real_rtsp_session_t *init_real_rtsp_session (void);
 void free_real_rtsp_session (struct real_rtsp_session_t* real_session);
 
--- a/stream/stream_rtsp.c	Mon Oct 30 21:31:11 2006 +0000
+++ b/stream/stream_rtsp.c	Mon Oct 30 21:55:58 2006 +0000
@@ -96,7 +96,9 @@
     rtsp = rtsp_session_start (fd, &mrl, file,
                                stream->streaming_ctrl->url->hostname,
                                port, &redirected,
-                               stream->streaming_ctrl->bandwidth);
+                               stream->streaming_ctrl->bandwidth,
+                               stream->streaming_ctrl->url->username,
+                               stream->streaming_ctrl->url->password);
 
     if (redirected == 1)
     {