Re: [MPlayer-dev-eng] RN5 authentication for rtsp
- Date: Wed, 26 Mar 2008 14:40:38 -0400 (EDT)
- From: Paul <myj@xxxxxxxx>
- Subject: Re: [MPlayer-dev-eng] RN5 authentication for rtsp
Here's an updated patch with some bound checking on strings and proper
gargabe collection. There are no cosmetic changes to the code AFAIK. I had
to indent the original Basic auth code to allow for other possible
authentication methods blocks.
I've also attached another patch to use the username/passwd command line
arguments if none are supplied as part of the URL.
Paul
On Wed, 26 Mar 2008, Diego Biurrun wrote:
On Tue, Mar 25, 2008 at 11:58:53PM -0400, Paul wrote:
I've written an RN5 authentication code for realplayer streams, which is
used by Helix/Real servers.
Unfortunately, with the current structure of the code, it only works with
the username/password supplied in the url, not on command line.
Hopefully, someone can clean it up/commit it to the CVS ?
The patch contains a lot of cosmetic changes and is thus very hard to
review. Please resend without cosmetics.
Diego
_______________________________________________
MPlayer-dev-eng mailing list
MPlayer-dev-eng@xxxxxxxxxxxx
https://lists.mplayerhq.hu/mailman/listinfo/mplayer-dev-eng
--- MPlayer-1.0rc2/stream/realrtsp/real.c 2007-10-07 15:49:25.000000000 -0400
+++ MPlayer-1.0rc2.RN5/stream/realrtsp/real.c 2008-03-26 14:27:12.000000000 -0400
@@ -445,6 +445,7 @@
uint32_t maxbandwidth = bandwidth;
char* authfield = NULL;
int i;
+ static const char hex[]="0123456789abcdef";
/* get challenge */
challenge1=strdup(rtsp_search_answers(rtsp_session,"RealChallenge1"));
@@ -488,23 +489,85 @@
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;
+ if (strstr(authreq, "Basic")) {
+ 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;
}
- authfield[b64_authlen+21] = 0;
- goto rtsp_send_describe;
+ if (strstr(authreq, "RN5")) {
+ unsigned char mungedh[33];
+ unsigned char nonce[512];
+ unsigned char realm[512];
+ unsigned char zres[16];
+ char *p,*q,*b;
+
+ // find server supplied realm and save it
+ if ((p=strstr(authreq,"realm=\""))) {
+ p+=7;
+ q=realm;
+ b=q+sizeof(realm)-1;
+ while (*p && *p!='"' && q<b) {
+ *q++=*p++;
+ }
+ *q='\0';
+ }
+
+ // find server supplied nonce and save it
+ if ((p=strstr(authreq,"nonce=\""))) {
+ p+=+7;
+ q=nonce;
+ b=q+sizeof(nonce)-1;
+ while (*p && *p!='"' && q<b) {
+ *q++=*p++;
+ }
+ *q='\0';
+ }
+
+ p = malloc(1024);
+ // mimicking RealPlayer code here
+ sprintf(p,"%-.200s:%-.200s:%-.200s", username,realm,password);
+
+ // intermediate step to calculate credentials hash and store it in text format
+ av_md5_sum(zres, p, strlen(p));
+ for(i=0;i<16;i++) {
+ mungedh[i+i] = hex[zres[i] >> 4];
+ mungedh[i+i+1] = hex[zres[i] & 0x0f];
+ }
+ mungedh[i+i] = '\0';
+
+ // mimicking RealPlayer code here
+ sprintf(p,"%-.200s%-.200s%-.200sCopyright (C) 1995,1996,1997 RealNetworks, Inc.",
+ mungedh,nonce,"00000000-0000-0000-0000-000000000000");
+
+ // calculate the response to the server supplied nonce using our credentials
+ authfield = malloc(2048);
+ authstr = malloc(33);
+ av_md5_sum(zres, p, strlen(p));
+
+ for(i=0;i<16;i++) {
+ authstr[i+i] = hex[zres[i] >> 4];
+ authstr[i+i+1] = hex[zres[i] & 0x0f];
+ }
+ authstr[i+i] = '\0';
+
+ // mimicking RealPlayer code here
+ sprintf(authfield, "Authorization: RN5 username=\"%-.200s\", GUID=\"00000000-0000-0000-0000-000000000000\",realm=\"%-.200s\",nonce=\"%s\",response=\"%s\"",username,realm,nonce,authstr);
+
+ free(p);
+ free(authstr);
+ goto rtsp_send_describe;
+ }
+ mp_msg(MSGT_STREAM, MSGL_ERR, "realrtsp: authenticator not supported (%s)\n", authreq);
}
autherr:
--- MPlayer-1.0rc2/stream/url.c 2007-10-07 15:49:26.000000000 -0400
+++ MPlayer-1.0rc2.RN5/stream/url.c 2008-03-26 14:35:42.000000000 -0400
@@ -19,6 +19,9 @@
#define SIZE_MAX ((size_t)-1)
#endif
+extern char *network_username;
+extern char *network_password;
+
URL_t *url_redirect(URL_t **url, const char *redir) {
URL_t *u = *url;
URL_t *res;
@@ -141,6 +144,13 @@ url_new(const char* url) {
}
ptr1 = ptr2+1;
pos1 = ptr1-escfilename;
+ } else {
+ // No credentials supplied in URL. If username and passwd arguments were supplied,
+ // take them and attach them to the Curl struct
+ if (network_username)
+ Curl->username = strdup(network_username);
+ if (network_password)
+ Curl->password = strdup(network_password);
}
// before looking for a port number check if we have an IPv6 type numeric address
_______________________________________________
MPlayer-dev-eng mailing list
MPlayer-dev-eng@xxxxxxxxxxxx
https://lists.mplayerhq.hu/mailman/listinfo/mplayer-dev-eng