From 13636fce07413d5b0e4356302753686dece3b595 Mon Sep 17 00:00:00 2001 From: rtogni Date: Mon, 30 Oct 2006 21:55:58 +0000 Subject: [PATCH] Realrtsp authentication git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@20543 b3059339-0415-0410-9bf9-f77b7e298cf2 --- stream/librtsp/rtsp_session.c | 5 ++-- stream/librtsp/rtsp_session.h | 3 ++- stream/realrtsp/real.c | 49 ++++++++++++++++++++++++++++++++++- stream/realrtsp/real.h | 3 ++- stream/stream_rtsp.c | 4 ++- 5 files changed, 58 insertions(+), 6 deletions(-) diff --git a/stream/librtsp/rtsp_session.c b/stream/librtsp/rtsp_session.c index b222543f57..6d440e06a4 100644 --- a/stream/librtsp/rtsp_session.c +++ b/stream/librtsp/rtsp_session.c @@ -74,7 +74,8 @@ struct rtsp_session_s { }; //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 @@ rtsp_session_t *rtsp_session_start(int fd, char **mrl, char *path, char *host, i { /* 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)) diff --git a/stream/librtsp/rtsp_session.h b/stream/librtsp/rtsp_session.h index e955e939b1..8503ae2cc7 100644 --- a/stream/librtsp/rtsp_session.h +++ b/stream/librtsp/rtsp_session.h @@ -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); diff --git a/stream/realrtsp/real.c b/stream/realrtsp/real.c index 00c0c124b3..4a84997b35 100644 --- a/stream/realrtsp/real.c +++ b/stream/realrtsp/real.c @@ -41,6 +41,8 @@ #else #include "libavutil/md5.h" #endif +#include "../http.h" +#include "mp_msg.h" /* #define LOG @@ -436,7 +438,8 @@ static int convert_timestamp(char *str, int *sec, int *msec) { //! 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 @@ rmff_header_t *real_setup_and_get_header(rtsp_t *rtsp_session, uint32_t bandwid 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 @@ rmff_header_t *real_setup_and_get_header(rtsp_t *rtsp_session, uint32_t bandwid 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 @@ rmff_header_t *real_setup_and_get_header(rtsp_t *rtsp_session, uint32_t bandwid 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"); diff --git a/stream/realrtsp/real.h b/stream/realrtsp/real.h index d0fe3fe306..447bb30de9 100644 --- a/stream/realrtsp/real.h +++ b/stream/realrtsp/real.h @@ -48,7 +48,8 @@ struct real_rtsp_session_t { }; 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); diff --git a/stream/stream_rtsp.c b/stream/stream_rtsp.c index 07e09e1afc..90a0ca311a 100644 --- a/stream/stream_rtsp.c +++ b/stream/stream_rtsp.c @@ -96,7 +96,9 @@ rtsp_streaming_start (stream_t *stream) 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) {