/*
S->C:
RTSP/1.0 401 Unauthorized
CSeq: 302
Date: 23 Jan 1997 15:35:06 GMT
WWW-Authenticate: Digest
				realm="http-auth@example.org",
				qop="auth, auth-int",
				algorithm=SHA-256,
				nonce="7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v",
				opaque="FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS"
WWW-Authenticate: Digest
				realm="http-auth@example.org",
				qop="auth, auth-int",
				algorithm=MD5,
				nonce="7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v",
				opaque="FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS"

C->S:
DESCRIBE rtsp://server.example.com/fizzle/foo RTSP/1.0
CSeq: 312
Accept: application/sdp, application/rtsl, application/mheg
Authorization: Digest username="Mufasa",
			realm="http-auth@example.org",
			uri="/dir/index.html",
			algorithm=MD5,
			nonce="7ypf/xlj9XXwfDPEoM4URrv/xwf94BcCAzFZH4GiTo0v",
			nc=00000001,
			cnonce="f2/wE4q74E6zIJEtWaHKaf5wv/H5QzzpXusqGemxURZJ",
			qop=auth,
			response="8ca523f5e9506fed4657c9700eebdbec",
			opaque="FQhe/qaU925kfnzjCev0ciny7QMkPqMAFRtzCUYo5tdS"
*/

#include "rtsp-client-internal.h"

int rtsp_client_authenrization(struct rtsp_client_t* rtsp, const char* method, const char* uri, const char* content, int length, char* authenrization, int bytes)
{
	int n;
	if (0 != rtsp->auth.scheme)
	{
		rtsp->auth.nc += 1;
		snprintf(rtsp->auth.uri, sizeof(rtsp->auth.uri) - 1, "%s", uri);
		//snprintf(rtsp->auth.cnonce, sizeof(rtsp->auth.cnonce), "%p", rtsp); // TODO

		n = snprintf(authenrization, bytes, "Authorization: ");
		n += http_header_auth(&rtsp->auth, rtsp->pwd, method, content, length, authenrization + n, bytes - n);
		n += snprintf(authenrization + n, n < bytes ? bytes - n : 0, "\r\n");
		if (n > 0 && n < bytes)
			return n;
	}
	
	rtsp->authenrization[0] = 0;
	return 0;
}

int rtsp_client_www_authenticate(struct rtsp_client_t* rtsp, const char* filed)
{
	memset(&rtsp->auth, 0, sizeof(rtsp->auth));
	snprintf(rtsp->auth.username, sizeof(rtsp->auth.username) - 1, "%s", rtsp->usr);

	if (0 != http_header_www_authenticate(filed, &rtsp->auth))
	{
		assert(0);
		return -1;
	}

	if (HTTP_AUTHENTICATION_BASIC != rtsp->auth.scheme && HTTP_AUTHENTICATION_DIGEST != rtsp->auth.scheme)
	{
		// only Basic/Digest support
		assert(0);
		return -1;
	}

	if (HTTP_AUTHENTICATION_BASIC != rtsp->auth.scheme && 0 != strcasecmp(rtsp->auth.algorithm, "MD5") && 0 != rtsp->auth.algorithm[0])
	{
		// only MD5 Digest support
		assert(0);
		return -1;
	}

	// support auth/auth-int only 
	if (0 == memcmp(rtsp->auth.qop, "auth", 4))
	{
		rtsp->auth.qop[4] = 0;
	}
	else
	{
		// compatibility RFC2617
		rtsp->auth.qop[0] = 0;
	}

	return 0;
}

#if defined(_DEBUG) || defined(DEBUG)
void rtsp_client_auth_test()
{
	struct rtsp_client_t rtsp;
	memset(&rtsp, 0, sizeof(rtsp));
	strcpy(rtsp.pwd, "Circle Of Life");
	rtsp.auth.scheme = HTTP_AUTHENTICATION_DIGEST;
	strcpy(rtsp.auth.username, "Mufasa");
	strcpy(rtsp.auth.realm, "testrealm@host.com");
	strcpy(rtsp.auth.nonce, "dcd98b7102dd2f0e8b11d0f600bfb0c093");
	strcpy(rtsp.auth.opaque, "5ccc069c403ebaf9f0171e9517f40e41");
	strcpy(rtsp.auth.cnonce, "0a4f113b");
	strcpy(rtsp.auth.qop, "auth");
	rtsp_client_authenrization(&rtsp, "GET", "/dir/index.html", NULL, 0, rtsp.req, sizeof(rtsp.req));
	assert(strstr(rtsp.req, "response=\"6629fae49393a05397450978507c4ef1\""));
}
#endif
