Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add Basic Authentication to the built in Html server.

 * Username defaults to "admin" (setting key: HTTP/Protected/UserName)
 * Password defaults to "mythtv"(setting key: HTTP/Protected/Password)
 * Protected URLs currently set to "/setup" and is a ';' delimited list
   Server does a case insensitive startsWith compare.
   (setting key: HTTP/Protected/Urls)

Things needed to be done still -

 * Password is sent in clear text (base64 encoded), we need to implement SSL
 * All authentication details stored in settings table... not very secure
   (Looking for suggestions to make this better).
  • Loading branch information...
commit 61ba720efe9b09d47a3a6d1e5b740c2493fa5447 1 parent b0d47e5
@dblain dblain authored
View
4 mythtv/libs/libmythupnp/htmlserver.cpp
@@ -69,7 +69,7 @@ bool HtmlServerExtension::ProcessRequest( HttpWorkerThread *, HTTPRequest *pRequ
{
if ( pRequest->m_sBaseUrl.startsWith("/") == false)
return( false );
-
+/*
// Temporary until we get authentication enabled
if ((pRequest->m_sResourceUrl.startsWith("/setup")) &&
(!getenv("MYTHHTMLSETUP")))
@@ -87,7 +87,7 @@ bool HtmlServerExtension::ProcessRequest( HttpWorkerThread *, HTTPRequest *pRequ
.arg(pRequest->m_sResourceUrl));
return true;
}
-
+*/
QFileInfo oInfo( m_sAbsoluteSharePath + pRequest->m_sResourceUrl );
if (oInfo.isDir())
View
83 mythtv/libs/libmythupnp/httprequest.cpp
@@ -103,6 +103,17 @@ static MIMETypes g_MIMETypes[] =
{ "m4a" , "audio/x-m4a" },
};
+static const char *Static401Error =
+ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\""
+ "\"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\">"
+ "<HTML>"
+ "<HEAD>"
+ "<TITLE>Error</TITLE>"
+ "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=ISO-8859-1\">"
+ "</HEAD>"
+ "<BODY><H1>401 Unauthorized.</H1></BODY>"
+ "</HTML>";
+
static const int g_nMIMELength = sizeof( g_MIMETypes) / sizeof( MIMETypes );
static const int g_on = 1;
static const int g_off = 0;
@@ -1013,6 +1024,23 @@ bool HTTPRequest::ParseRequest()
return false;
}
+ if (IsUrlProtected( m_sBaseUrl ))
+ {
+ if (!Authenticated())
+ {
+ m_eResponseType = ResponseTypeHTML;
+ m_nResponseStatus = 401;
+ m_mapRespHeaders[ "WWW-Authenticate" ] = "Basic realm=\"MythTv\"";
+
+ m_response.write( Static401Error );
+
+ SendResponse();
+
+ return true;
+ }
+ }
+
+
bSuccess = true;
SetContentType( m_mapHeaders[ "content-type" ] );
@@ -1411,6 +1439,61 @@ QString HTTPRequest::Encode(const QString &sIn)
}
/////////////////////////////////////////////////////////////////////////////
+//
+/////////////////////////////////////////////////////////////////////////////
+
+bool HTTPRequest::IsUrlProtected( const QString &sBaseUrl )
+{
+ QString sProtected = UPnp::g_pConfig->GetValue( "HTTP/Protected/Urls", "/setup" );
+
+ QStringList oList = sProtected.split( ';' );
+
+ for( int nIdx = 0; nIdx < oList.count(); nIdx++)
+ {
+ if (sBaseUrl.startsWith( oList[nIdx], Qt::CaseInsensitive ))
+ return true;
+ }
+
+ return false;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+//
+/////////////////////////////////////////////////////////////////////////////
+
+bool HTTPRequest::Authenticated()
+{
+ QStringList oList = m_mapHeaders[ "authorization" ].split( ' ' );
+
+ if (oList.count() < 2)
+ return false;
+
+ if (oList[0].compare( "basic", Qt::CaseInsensitive ) != 0)
+ return false;
+
+ QString sCredentials = QByteArray::fromBase64( oList[1].toUtf8() );
+
+ oList = sCredentials.split( ':' );
+
+ if (oList.count() < 2)
+ return false;
+
+ QString sUserName = UPnp::g_pConfig->GetValue( "HTTP/Protected/UserName", "admin" );
+
+
+ if (oList[0].compare( sUserName, Qt::CaseInsensitive ) != 0)
+ return false;
+
+ QString sPassword = UPnp::g_pConfig->GetValue( "HTTP/Protected/Password", "mythtv" );
+
+ if (oList[1] != sPassword )
+ return false;
+
+ return true;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
// BufferedSocketDeviceRequest Class Implementation
View
2  mythtv/libs/libmythupnp/httprequest.h
@@ -173,6 +173,8 @@ class UPNP_PUBLIC HTTPRequest
qint64 SendData ( QIODevice *pDevice, qint64 llStart, qint64 llBytes );
qint64 SendFile ( QFile &file, qint64 llStart, qint64 llBytes );
+ bool IsUrlProtected ( const QString &sBaseUrl );
+ bool Authenticated ();
public:
View
3  mythtv/programs/mythbackend/httpconfig.cpp
@@ -26,6 +26,7 @@ bool HttpConfig::ProcessRequest(HttpWorkerThread*, HTTPRequest *request)
return false;
}
+/*
// Temporary until we get authentication enabled
if (!getenv("MYTHHTMLSETUP"))
{
@@ -43,7 +44,7 @@ bool HttpConfig::ProcessRequest(HttpWorkerThread*, HTTPRequest *request)
return true;
}
-
+*/
bool handled = false;
if (request->m_sMethod == "Save")
{
Please sign in to comment.
Something went wrong with that request. Please try again.