Пример #1
0
inline void ParseAuthNameAndPassword(StrPtrLen *codedStrPtr, StrPtrLen* namePtr, StrPtrLen* passwordPtr)
 {
    
    if (!codedStrPtr || (codedStrPtr->Len >= kAuthNameAndPasswordBuffSize) ) 
    {   return; 
    }
    
    StrPtrLen   codedLineStr;
    StrPtrLen   nameAndPassword;
    memset(decodedLine,0,kAuthNameAndPasswordBuffSize);
    memset(codedLine,0,kAuthNameAndPasswordBuffSize);
    
    memcpy (codedLine,codedStrPtr->Ptr,codedStrPtr->Len);
    codedLineStr.Set((char*) codedLine, codedStrPtr->Len);  
    (void) Base64decode(decodedLine, codedLineStr.Ptr);
    
    nameAndPassword.Set((char*) decodedLine, strlen(decodedLine));
    StringParser parsedNameAndPassword(&nameAndPassword);
    
    parsedNameAndPassword.ConsumeUntil(namePtr,':');            
    parsedNameAndPassword.ConsumeLength(NULL, 1);

    // password can have whitespace, so read until the end of the line, not just until whitespace
    parsedNameAndPassword.ConsumeUntil(passwordPtr, StringParser::sEOLMask);
    
    namePtr->Ptr[namePtr->Len]= 0;
    passwordPtr->Ptr[passwordPtr->Len]= 0;
    
    //qtss_printf("decoded nameAndPassword="******"decoded name="); PRINT_STR(namePtr); 
    //qtss_printf("decoded password="); PRINT_STR(passwordPtr); 

    return;
};
Пример #2
0
QTSS_Error RTSPRequest::ParseBasicHeader(StringParser *inParsedAuthLinePtr)
{
    QTSS_Error  theErr = QTSS_NoErr;
    fAuthScheme = qtssAuthBasic;

    StrPtrLen authWord;
    
    inParsedAuthLinePtr->ConsumeWhitespace();
    inParsedAuthLinePtr->ConsumeUntilWhitespace(&authWord);
    if (0 == authWord.Len ) 
        return theErr;
        
    char* encodedStr = authWord.GetAsCString();
    OSCharArrayDeleter encodedStrDeleter(encodedStr);   
    
    char *decodedAuthWord = NEW char[Base64decode_len(encodedStr) + 1];
    OSCharArrayDeleter decodedAuthWordDeleter(decodedAuthWord);

    (void) Base64decode(decodedAuthWord, encodedStr);
    
    StrPtrLen   nameAndPassword;    
    nameAndPassword.Set(decodedAuthWord, ::strlen(decodedAuthWord));
    
    StrPtrLen   name("");
    StrPtrLen   password("");
    StringParser parsedNameAndPassword(&nameAndPassword);

    parsedNameAndPassword.ConsumeUntil(&name,':');          
    parsedNameAndPassword.ConsumeLength(NULL, 1);
    parsedNameAndPassword.GetThruEOL(&password);
        

    // Set the qtssRTSPReqUserName and qtssRTSPReqUserPassword attributes in the Request object
    (void) this->SetValue(qtssRTSPReqUserName, 0,  name.Ptr , name.Len, QTSSDictionary::kDontObeyReadOnly);
    (void) this->SetValue(qtssRTSPReqUserPassword, 0,  password.Ptr , password.Len, QTSSDictionary::kDontObeyReadOnly);

    // Also set the qtssUserName attribute in the qtssRTSPReqUserProfile object attribute of the Request Object
    (void) fUserProfile.SetValue(qtssUserName, 0, name.Ptr, name.Len, QTSSDictionary::kDontObeyReadOnly);
    
    return theErr;
}
Пример #3
0
QTSS_Error Initialize(QTSS_Initialize_Params* inParams)
{
    // Setup module utils
    QTSSModuleUtils::Initialize(inParams->inMessages, inParams->inServer, inParams->inErrorLogStream);

    sAccessLogPrefs = QTSSModuleUtils::GetModulePrefsObject(QTSSModuleUtils::GetModuleObjectByName("QTSSAccessLogModule"));
    sReflectorPrefs = QTSSModuleUtils::GetModulePrefsObject(QTSSModuleUtils::GetModuleObjectByName("QTSSReflectorModule"));
    sPrefs = QTSSModuleUtils::GetModulePrefsObject(inParams->inModule);

    // This module may not be present, so be careful...
    QTSS_ModuleObject theSvrControlModule = QTSSModuleUtils::GetModuleObjectByName("QTSSSvrControlModule");
    if (theSvrControlModule != NULL)
        sSvrControlPrefs = QTSSModuleUtils::GetModulePrefsObject(theSvrControlModule);
    sServer = inParams->inServer;
    sServerPrefs = inParams->inPrefs;
    
    sStartupTime = ::time(NULL);
    
	sDefaultURLStr.Delete();
    sDefaultURLStr.Set(QTSSModuleUtils::GetStringAttribute(sPrefs, sDefaultURLPrefName, sDefaultURL)); 

    return QTSS_NoErr;
}
Пример #4
0
SDPContainer* QTSS3GPPModuleUtils::Get3GPPSDPFeatureListCopy(ResizeableStringFormatter &buffer)
{
	SDPContainer* resultList = NEW SDPContainer;
	StrPtrLen theLinePtr;


	if (s3gppEnabled)
	{
		if (s3gppRateAdaptationEnabled)
		{
			buffer.Put(s3gppBitRateAdaptationSDPStr);
			buffer.Put((SInt32)s3gppRateAdaptationReportFrequency);
			buffer.PutEOL();
			theLinePtr.Set(buffer.GetBufPtr(), buffer.GetBytesWritten());
			resultList->AddHeaderLine(&theLinePtr);
			buffer.Reset();
		}

	}


	return resultList;
}
Пример #5
0
void AccessChecker::GetAccessFileInfo(const  char* inQTAccessDir)
{
	Assert( fAccessFile != NULL);

	const int kBufLen = 2048;
	char buf[kBufLen];
	StrPtrLen bufLine;
	::qtss_printf("QTSSDemoODAuthModule: File Info\n");
	while ( std::fgets(buf, kBufLen, fAccessFile) != NULL )
	{
		bufLine.Set(buf, strlen(buf));
		StringParser bufParser(&bufLine);

		//skip over leading whitespace
		bufParser.ConsumeUntil(NULL, StringParser::sWhitespaceMask);

		//skip over comments and blank lines...

		if ( (bufParser.GetDataRemaining() == 0) || (bufParser[0] == '#') || (bufParser[0] == '\0') )
			continue;

		StrPtrLen word;
		bufParser.ConsumeWord(&word);
		bufParser.ConsumeWhitespace();

		if ( word.Equal("AuthName") ) //realm name
		{
			bufParser.GetThruEOL(&word);
			fRealmHeader = word.Ptr;
		}
		else if ( word.Equal("AuthUserFile" ) ) //users name
		{
			char filePath[kBufLen];
			bufParser.GetThruEOL(&word); 
			if (word.Ptr[0] == '/') //absolute path
			{
				std::memcpy(filePath, word.Ptr, word.Len);
				filePath[word.Len] = '\0';
			}
			else
			{
				std::snprintf(filePath, sizeof(filePath), "%s/%s", inQTAccessDir, word.Ptr);
			}
			fUsersFile = std::fopen(filePath, "r");
		}
		else if ( word.Equal("AuthGroupFile") ) //groups name
		{
			char filePath[kBufLen];
			bufParser.GetThruEOL(&word); 
			if (word.Ptr[0] == '/') //absolute path
			{
				std::memcpy(filePath, word.Ptr, word.Len);
				filePath[word.Len] = '\0';
			}
			else
			{
				std::snprintf(filePath, sizeof(filePath), "%s/%s", inQTAccessDir, word.Ptr);
			}
			fGroupsFile = std::fopen(filePath, "r");
		}
	}

	if (fUsersFile == NULL)
	{
		fUsersFile = std::fopen(fUsersFilePath.c_str(), "r");
	}

	if (fGroupsFile == NULL)
	{
		fGroupsFile = std::fopen(fGroupsFilePath.c_str(), "r");
	}
}
Пример #6
0
bool AccessChecker::CheckUserAccess(const char* inUsername)
{
	::qtss_printf("In QTSSDemoODAuthModule: Check User Access - start\n");

	const int kBufLen = 2048;
	char buf[kBufLen];
	StrPtrLen bufLine;

	if ( fAccessFile == NULL )
		return false;

	std::rewind(fAccessFile);
	while ( std::fgets(buf, kBufLen, fAccessFile) != NULL )
	{
		bufLine.Set(buf, strlen(buf));
		StringParser bufParser(&bufLine);

		//skip over leading whitespace
		bufParser.ConsumeUntil(NULL, StringParser::sWhitespaceMask);

		//skip over comments and blank lines...
		if ((bufParser.GetDataRemaining() == 0) || (bufParser[0] == '#') || (bufParser[0] == '\0') )
			continue;

		StrPtrLen word;
		bufParser.ConsumeWord(&word);
		if ( word.Equal("require") )
		{
			bufParser.ConsumeWhitespace();
			bufParser.ConsumeWord(&word);

			if ( word.Equal("user") )
			{
				while (word.Len != 0)
				{
					bufParser.ConsumeWhitespace();
					bufParser.ConsumeWord(&word);

					if (word.Equal(inUsername)) 
					{
						 ::qtss_printf("QTSSDemoODAuthModule in CheckUserAccess() : user %s found\n", inUsername);
						return true;
					}
				}
			}
			else if (word.Equal("valid-user"))
			{   
				::qtss_printf("QTSSDemoODAuthModule in CheckUserAccess(): valid-user\n");
				return true;
			}
			else if ( word.Equal("group") )
			{
				while (word.Len != 0)
				{
					bufParser.ConsumeWhitespace();
					bufParser.ConsumeWord(&word);
					if ( this->CheckGroupMembership(inUsername, word.GetAsCString()) )
					{
						::qtss_printf("QTSSDemoODAuthModule in CheckUserAccess(): user is part of %s group\n", word.GetAsCString());
						return true;
					}
				}
			}
		}
	}

	return false;
}
Пример #7
0
QTSS_Error RelaySession::SetupRelaySession(SourceInfo* inInfo)
{
    QTSS_Error theErr = QTSS_NoErr;
    theErr = this->SetupReflectorSession(inInfo, NULL);
    
    if (theErr != QTSS_NoErr)
        return theErr;
        
    // create the reflector session object for this session
    UInt32 outIndex = 0;
    fRelaySessionObject = NULL;
        
        theErr = QTSS_LockObject(relayModuleAttributesObject);
        Assert(theErr == QTSS_NoErr);
        
    theErr = QTSS_CreateObjectValue (relayModuleAttributesObject , sRelaySessionObjectID, qtssRelaySessionObjectType, &outIndex, &fRelaySessionObject);
    Assert(theErr == QTSS_NoErr);
   
    if (fRelaySessionObject == NULL)
        return theErr;
        
        // set the values for all the static attributes in this session
    
    char* relayName = inInfo->Name();       // name of the relay
        if (relayName != NULL)
            theErr = QTSS_SetValue (fRelaySessionObject, sRelayName, 0, (void*)relayName, ::strlen(relayName));
        else
            theErr = QTSS_SetValue (fRelaySessionObject, sRelayName, 0, (void*)sEmptyStr.Ptr, sEmptyStr.Len);
        Assert(theErr == QTSS_NoErr);


    StrPtrLen sourceStr;            // type of source

    if (inInfo->IsRTSPSourceInfo())
    {       
        if (((RTSPSourceInfo*)inInfo)->IsAnnounce())
            sourceStr.Set(sAnnouncedSourceStr.Ptr, sAnnouncedSourceStr.Len);
        else
            sourceStr.Set(sRTSPSourceStr.Ptr, sRTSPSourceStr.Len);
    }
    else
        sourceStr.Set(sUDPSourceStr.Ptr, sUDPSourceStr.Len);
    
    theErr = QTSS_SetValue (fRelaySessionObject, sSourceType, 0, (void*)sourceStr.Ptr, sourceStr.Len);
    Assert(theErr == QTSS_NoErr);
    
    char theIPAddrBuf[20];          
    StrPtrLen theIPAddr(theIPAddrBuf, 20);
    
    struct in_addr theSrcAddr;      // source ip address
    theSrcAddr.s_addr = htonl(inInfo->GetStreamInfo(0)->fSrcIPAddr);
    SocketUtils::ConvertAddrToString(theSrcAddr, &theIPAddr);   
    
    theErr = QTSS_SetValue (fRelaySessionObject, sSourceIPAddr, 0, (void*)theIPAddr.Ptr, theIPAddr.Len);
    Assert(theErr == QTSS_NoErr);
    
    struct in_addr theDestAddr;     // dest (of source) ip address
    theDestAddr.s_addr = htonl(inInfo->GetStreamInfo(0)->fDestIPAddr);
    SocketUtils::ConvertAddrToString(theDestAddr, &theIPAddr);
    
    theErr = QTSS_SetValue (fRelaySessionObject, sSourceInIPAddr, 0, (void*)theIPAddr.Ptr, theIPAddr.Len);
    Assert(theErr == QTSS_NoErr);
    
    
    for (UInt32 index = 0; index < (inInfo->GetNumStreams()); index++)  // source udp ports
    {
        UInt16 udpPort = inInfo->GetStreamInfo(index)->fPort;
        theErr = QTSS_SetValue (fRelaySessionObject, sSourceUDPPorts, index, &udpPort, sizeof(udpPort));
                Assert(theErr == QTSS_NoErr);
    }
    
    if (inInfo->IsRTSPSourceInfo())     
    {
        RTSPSourceInfo* rtspInfo = (RTSPSourceInfo*)inInfo;
        if (!rtspInfo->IsAnnounce())
        {
            UInt16 rtspPort = (UInt16) rtspInfo->GetHostPort();
            char* username = rtspInfo->GetUsername();
            char* password = rtspInfo->GetPassword();
            theErr = QTSS_SetValue (fRelaySessionObject, sSourceRTSPPort, 0, &rtspPort, sizeof(rtspPort));  // source rtsp port
                        Assert(theErr == QTSS_NoErr);
                        
            theErr = QTSS_SetValue (fRelaySessionObject, sSourceUsername, 0, username, sizeof(username));   // source username
                        Assert(theErr == QTSS_NoErr);
                        
            theErr = QTSS_SetValue (fRelaySessionObject, sSourcePassword, 0, password, sizeof(password));   // source password  
                        Assert(theErr == QTSS_NoErr);
        }
        
        char* url = rtspInfo->GetSourceURL();
        theErr = QTSS_SetValue (fRelaySessionObject, sSourceURL, 0, url, ::strlen(url));
                Assert(theErr == QTSS_NoErr);                   // source url
    }

        UInt16 ttl = inInfo->GetStreamInfo(0)->fTimeToLive;
        theErr = QTSS_SetValue (fRelaySessionObject, sSourceTTL, 0, &ttl, sizeof(ttl)); // source ttl
        Assert(theErr == QTSS_NoErr);
        
        theErr = QTSS_UnlockObject(relayModuleAttributesObject);
        Assert(theErr == QTSS_NoErr);
        
        return QTSS_NoErr;
}
Пример #8
0
RelayOutput::RelayOutput(SourceInfo* inInfo, UInt32 inWhichOutput, RelaySession* inRelaySession, Bool16 isRTSPSourceInfo)
	: fRelaySession(inRelaySession),
	fOutputSocket(NULL, Socket::kNonBlockingSocketType),
	fNumStreams(inRelaySession->GetSourceInfo()->GetNumStreams()),  // use the reflector session's source info
	fOutputInfo(*inInfo->GetOutputInfo(inWhichOutput)),
	fQueueElem(),
	fFormatter(&fHTMLBuf[0], kMaxHTMLSize),
	fPacketsPerSecond(0),
	fBitsPerSecond(0),
	fLastUpdateTime(0),
	fTotalPacketsSent(0),
	fTotalBytesSent(0),
	fLastPackets(0),
	fLastBytes(0),
	fClientSocket(NULL),
	fClient(NULL),
	fDoingAnnounce(false),
	fValid(true),
	fOutgoingSDP(NULL),
	fAnnounceTask(NULL),
	fRTSPOutputInfo(NULL)
{
	Assert(fNumStreams > 0);

	fQueueElem.SetEnclosingObject(this);
	fStreamCookieArray = NEW void*[fNumStreams];
	fTrackIDArray = NEW UInt32[fNumStreams];
	fOutputInfo.fPortArray = NEW UInt16[fNumStreams];//copy constructor doesn't do this
	::memset(fOutputInfo.fPortArray, 0, fNumStreams * sizeof(UInt16));

	// create a bookmark for each stream we'll reflect
	this->InititializeBookmarks(inRelaySession->GetNumStreams());

	// Copy out all the track IDs for each stream
	for (UInt32 x = 0; x < fNumStreams; x++)
	{
		fTrackIDArray[x] = inRelaySession->GetSourceInfo()->GetStreamInfo(x)->fTrackID;
		fStreamCookieArray[x] = inRelaySession->GetStreamCookie(fTrackIDArray[x]);
	}

	// Copy the contents of the output port array

	if (inInfo->GetOutputInfo(inWhichOutput)->fPortArray != NULL)
	{
		UInt32 copySize = fNumStreams;
		if (fOutputInfo.fNumPorts < fNumStreams)
			copySize = fOutputInfo.fNumPorts;
		::memcpy(fOutputInfo.fPortArray, inInfo->GetOutputInfo(inWhichOutput)->fPortArray, copySize * sizeof(UInt16));
	}
	else if (fOutputInfo.fBasePort != 0)
	{
		for (UInt32 y = 0; y < fNumStreams; y++)
			fOutputInfo.fPortArray[y] = (UInt16)(fOutputInfo.fBasePort + (y * 2));
	}

	OS_Error err = BindSocket();
	if (err != OS_NoErr)
	{
		fValid = false;
		return;
	}

	RTSPOutputInfo* rtspInfo = NULL;
	if (isRTSPSourceInfo)
	{
		// in the case of the announce source info, the passed in source info will have the new
		// output information, but only the session's source info will have the sdp and url.
		RTSPSourceInfo* rtspSourceInfo = (RTSPSourceInfo *)(inInfo);
		Assert(rtspSourceInfo != NULL);
		RTSPSourceInfo* sessionSourceInfo = (RTSPSourceInfo *)(inRelaySession->GetSourceInfo());
		Assert(sessionSourceInfo != NULL);

		rtspInfo = rtspSourceInfo->GetRTSPOutputInfo(inWhichOutput);
		if (rtspInfo->fIsAnnounced)
		{
			fRTSPOutputInfo = NEW RTSPOutputInfo();
			fRTSPOutputInfo->Copy(*rtspInfo);

			fDoingAnnounce = true;
			// set up rtsp socket and client
			fClientSocket = new TCPClientSocket(Socket::kNonBlockingSocketType);
			fClient = new RTSPClient(fClientSocket, false, RelaySession::sRelayUserAgent);

			// set up the outgoing socket
			fClientSocket->Set(fOutputInfo.fDestAddr, rtspInfo->fAnnouncePort);
			int sndBufSize = 32 * 1024;
			int rcvBufSize = 1024;
			fClientSocket->SetOptions(sndBufSize, rcvBufSize);

			// set up the client object
			StrPtrLen url;
			if ((rtspInfo->fDestURl != NULL) && (strlen(rtspInfo->fDestURl) > 0))
				url.Set(rtspInfo->fDestURl);
			else
				url.Set(sessionSourceInfo->GetSourceURL());

			fClient->Set(url);

			fClient->SetTransportMode(RTSPClient::kPushMode);
			fClient->SetName(rtspInfo->fUserName);
			fClient->SetPassword(rtspInfo->fPassword);

			UInt32 len;
			fOutgoingSDP = sessionSourceInfo->GetAnnounceSDP(fOutputInfo.fDestAddr, &len);
			fAnnounceState = kSendingAnnounce;
			fCurrentSetup = 0;
			fAnnounceTask = new RelayAnnouncer(this);    // this will now go and run the async announce
			fAnnounceTask->Signal(Task::kStartEvent);
		}
	}

	// Write the Output HTML
	// Looks like: Relaying to: 229.49.52.102, Ports: 16898 16900 Time to live: 15
	static StrPtrLen sHTMLStart("Relaying to: ");
	static StrPtrLen sPorts(", Ports: ");
	static StrPtrLen sTimeToLive(" Time to live: ");
	static StrPtrLen sHTMLEnd("<BR>");

	// First, format the destination addr as a dotted decimal string
	char theIPAddrBuf[20];
	StrPtrLen theIPAddr(theIPAddrBuf, 20);
	struct in_addr theAddr;
	theAddr.s_addr = htonl(fOutputInfo.fDestAddr);
	SocketUtils::ConvertAddrToString(theAddr, &theIPAddr);

	// Begin writing the HTML
	fFormatter.Put(sHTMLStart);
	fFormatter.Put(theIPAddr);
	fFormatter.Put(sPorts);

	for (UInt32 y = 0; y < fNumStreams; y++)
	{
		// Write all the destination ports
		fFormatter.Put(fOutputInfo.fPortArray[y]);
		fFormatter.PutSpace();
	}

	if (SocketUtils::IsMulticastIPAddr(inInfo->GetOutputInfo(inWhichOutput)->fDestAddr))
	{
		// Put the time to live if this is a multicast destination
		fFormatter.Put(sTimeToLive);
		fFormatter.Put(fOutputInfo.fTimeToLive);
	}
	fFormatter.Put(sHTMLEnd);

	// Setup the StrPtrLen to point to the right stuff
	fOutputInfoHTML.Ptr = fFormatter.GetBufPtr();
	fOutputInfoHTML.Len = fFormatter.GetCurrentOffset();

	OSMutexLocker locker(&sQueueMutex);
	sRelayOutputQueue.EnQueue(&fQueueElem);

	SetupRelayOutputObject(rtspInfo);
}
Пример #9
0
QTSS_Error QTAccessFile::AuthorizeRequest(QTSS_StandardRTSP_Params* inParams, Bool16 allowNoAccessFiles, QTSS_ActionFlags noAction, QTSS_ActionFlags authorizeAction, Bool16 *outAuthorizedPtr, Bool16 *outAllowAnyUserPtr)
{
    if  ( (NULL == inParams) || (NULL == inParams->inRTSPRequest) || (NULL == outAllowAnyUserPtr) || (NULL == outAuthorizedPtr)  )
        return QTSS_RequestFailed;

    *outAllowAnyUserPtr = false;
    *outAuthorizedPtr = false;
    
    QTSS_RTSPRequestObject  theRTSPRequest = inParams->inRTSPRequest;
    
    // get the type of request
    // Don't touch write requests
    QTSS_ActionFlags action = QTSSModuleUtils::GetRequestActions(theRTSPRequest);
    if(action == qtssActionFlagsNoFlags)
        return QTSS_RequestFailed;
    
    if( (action & noAction) != 0)
        return QTSS_NoErr; // we don't handle
    
    //get the local file path
    char*   pathBuffStr = QTSSModuleUtils::GetLocalPath_Copy(theRTSPRequest);
    OSCharArrayDeleter pathBuffDeleter(pathBuffStr);
    if (NULL == pathBuffStr)
        return QTSS_RequestFailed;

    //get the root movie directory
    char*   movieRootDirStr = QTSSModuleUtils::GetMoviesRootDir_Copy(theRTSPRequest);
    OSCharArrayDeleter movieRootDeleter(movieRootDirStr);
    if (NULL == movieRootDirStr)
        return QTSS_RequestFailed;
    
    QTSS_UserProfileObject theUserProfile = QTSSModuleUtils::GetUserProfileObject(theRTSPRequest);
    if (NULL == theUserProfile)
        return QTSS_RequestFailed;

    char* accessFilePath = QTAccessFile::GetAccessFile_Copy(movieRootDirStr, pathBuffStr);
    OSCharArrayDeleter accessFilePathDeleter(accessFilePath);
        
    char* username = QTSSModuleUtils::GetUserName_Copy(theUserProfile);
    OSCharArrayDeleter usernameDeleter(username);

    UInt32 numGroups = 0;
    char** groupCharPtrArray =  QTSSModuleUtils::GetGroupsArray_Copy(theUserProfile, &numGroups);
    OSCharPointerArrayDeleter groupCharPtrArrayDeleter(groupCharPtrArray);
    
    StrPtrLen accessFileBuf;
    (void)QTSSModuleUtils::ReadEntireFile(accessFilePath, &accessFileBuf);
    OSCharArrayDeleter accessFileBufDeleter(accessFileBuf.Ptr);
        
    if (accessFileBuf.Len == 0 && !allowNoAccessFiles)
    {   accessFileBuf.Set(sAccessValidUser);
        if (DEBUG_QTACCESS) 
            qtss_printf("QTAccessFile::AuthorizeRequest SET Accessfile valid user for no accessfile %s\n", sAccessValidUser);
    }
      
    if (accessFileBuf.Len == 0 && allowNoAccessFiles)
    {   accessFileBuf.Set(sAccessAnyUser);
        if (DEBUG_QTACCESS) 
            qtss_printf("QTAccessFile::AuthorizeRequest SET Accessfile any user for no access file %s\n", sAccessAnyUser);
    }
      
    char realmName[kBuffLen] = { 0 };
    StrPtrLen   realmNameStr(realmName,kBuffLen -1);
    
    //check if this user is allowed to see this movie
    Bool16 allowRequest = this->AccessAllowed(username, groupCharPtrArray, numGroups,  &accessFileBuf, authorizeAction,&realmNameStr, outAllowAnyUserPtr );
    debug_printf("accessFile.AccessAllowed for user=%s returned %d\n", username, allowRequest);
    
    // Get the auth scheme
    QTSS_AuthScheme theAuthScheme = qtssAuthNone;
    UInt32 len = sizeof(theAuthScheme);
    QTSS_Error theErr = QTSS_GetValue(theRTSPRequest, qtssRTSPReqAuthScheme, 0, (void*)&theAuthScheme, &len);
    Assert(len == sizeof(theAuthScheme));
    if(theErr != QTSS_NoErr)
        return theErr;
    
    // If auth scheme is basic and the realm is present in the access file, use it
    if((theAuthScheme == qtssAuthBasic) && (realmNameStr.Ptr[0] != '\0'))   //set the realm if we have one
        (void) QTSS_SetValue(theRTSPRequest,qtssRTSPReqURLRealm, 0, realmNameStr.Ptr, ::strlen(realmNameStr.Ptr));
    else // if auth scheme is basic and no realm is present, or if the auth scheme is digest, use the realm from the users file
    {  
        char*   userRealm = NULL;   
        (void) QTSS_GetValueAsString(theUserProfile, qtssUserRealm, 0, &userRealm);
        if(userRealm != NULL)
        {
            OSCharArrayDeleter userRealmDeleter(userRealm);
            (void) QTSS_SetValue(theRTSPRequest,qtssRTSPReqURLRealm, 0, userRealm, ::strlen(userRealm));
        }
    }
    
    *outAuthorizedPtr = allowRequest;
    
    Bool16 founduser = this->HaveUser(username, NULL);
    Bool16 authContinue = true;
    char nameBuff[256];
    StrPtrLen reqNameStr(nameBuff, kBuffLen);
    StrPtrLen profileNameStr(username);
    theErr = QTSS_GetValue (theRTSPRequest,qtssRTSPReqUserName,0, (void *) reqNameStr.Ptr, &reqNameStr.Len);
 
    
if (DEBUG_QTACCESS)
{   qtss_printf("QTAccessFile::AuthorizeRequest qtaccess profile user =%s ", username);
    reqNameStr.PrintStr("request user="******"\n");
    qtss_printf("QTAccessFile::AuthorizeRequest allowRequest=%d founduser=%d authContinue=%d\n", allowRequest, founduser, authContinue);
}   
    if (allowRequest && founduser)
        theErr = QTSSModuleUtils::AuthorizeRequest(theRTSPRequest, &allowRequest, &founduser,&authContinue);
    if (!allowRequest && !founduser)
        theErr = QTSSModuleUtils::AuthorizeRequest(theRTSPRequest, &allowRequest, &founduser,&authContinue);

if (DEBUG_QTACCESS)
{   qtss_printf("QTAccessFile::AuthorizeRequest QTSSModuleUtils::AuthorizeRequest qtaccess profile user =%s ", username);
    reqNameStr.PrintStr("request user="******"\n");
    qtss_printf("QTAccessFile::AuthorizeRequest allowRequest=%d founduser=%d authContinue=%d\n", allowRequest, founduser, authContinue);
}   
 
    return theErr;
}
Пример #10
0
void UserAgentParser::Parse(StrPtrLen *inStream)
{
	StrPtrLen tempID;
	StrPtrLen tempData;
	StringParser parser(inStream);
	StrPtrLen startFields;


	memset(&fFieldData, 0, sizeof(fFieldData));

	parser.ConsumeUntil(&startFields, '('); // search for '(' if not found does nothing

	// parse through everything between the '(' and ')'.
	while (startFields.Len != 0)
	{
		//stop when we reach an empty line.
		tempID.Set(NULL, 0);
		tempData.Set(NULL, 0);

		parser.ConsumeLength(NULL, 1); // step past '(' or ';' if not found or at end of line does nothing
		parser.ConsumeWhitespace(); // search for non-white space if not found does nothing
		parser.ConsumeUntil(&tempID, sEOLWhitespaceEqualMask); // search for end of id (whitespace or =)if not found does nothing
		if (tempID.Len == 0) break;

		parser.ConsumeUntil(NULL, '='); // find the '='
		parser.ConsumeLength(NULL, 1); // step past if not found or at end of line does nothing
		parser.ConsumeUntil(&tempData, sEOLSemicolonCloseParenMask); // search for end of data if not found does nothing
		if (tempData.Len == 0) break;

		StrPtrLen   testID;
		UInt32      fieldID;
		for (short testField = 0; testField < UserAgentParser::eNumAttributes; testField++)
		{
			testID.Set(sFieldIDs[testField].fFieldName, sFieldIDs[testField].fLen);
			fieldID = sFieldIDs[testField].fID;
			if ((fFieldData[fieldID].fFound == false) && testID.Equal(tempID))
			{
				fFieldData[fieldID].fData = tempData;
				fFieldData[fieldID].fFound = true;
			}
		}

	}
	// If we parsed the OS field but not the OSVer field then check and see if
	// the OS field contains the OS version. If it does copy it from there.
	// (e.g. 'os=Mac%209.2.2' or 'os=Windows%20NT%204.0'.)
	if (fFieldData[eOs].fFound && !fFieldData[eOsver].fFound)
	{
		UInt16 len = (UInt16)fFieldData[eOs].fData.Len;
		char* cp = (char*)fFieldData[eOs].fData.Ptr;
		// skip up to the blank space if it exists.
		// (i.e. the blank is URL encoded as '%20')
		while (*cp != '%')
		{
			len--;
			if (*cp == '\0' || len == 0)
			{
				// no blank space...so we're all done.
				return;
			}
			cp++;
		}
		// skip over the blank space.
		cp += 3; len -= 3;
		// the remaining string is the OS version.
		fFieldData[eOsver].fData.Set(cp, len);
		fFieldData[eOsver].fFound = true;
		// and truncate the version from the OS field.
		fFieldData[eOs].fData.Len -= len + 3;
	}
}
Пример #11
0
QTSS_Error RTSPRequest::SendDigestChallenge(UInt32 qop, StrPtrLen *nonce, StrPtrLen* opaque)
{
    QTSS_Error theErr = QTSS_NoErr;

    char challengeBuf[kAuthChallengeHeaderBufSize];
    ResizeableStringFormatter challengeFormatter(challengeBuf, kAuthChallengeHeaderBufSize);
    
    StrPtrLen realm;
    char *prefRealmPtr = NULL;
    StrPtrLen *realmPtr = this->GetValue(qtssRTSPReqURLRealm);              // Get auth realm set by the module
    if(realmPtr->Len > 0) {
        realm = *realmPtr;
    }
    else {                                                                  // If module hasn't set the realm
        QTSServerInterface* theServer = QTSServerInterface::GetServer();    // get the realm from prefs
        prefRealmPtr = theServer->GetPrefs()->GetAuthorizationRealm();      // allocates memory
        Assert(prefRealmPtr != NULL);
        if (prefRealmPtr != NULL){  
            realm.Set(prefRealmPtr, strlen(prefRealmPtr));
        }
        else {
            realm = sDefaultRealm;  
        }
    }
    
    // Creating the Challenge header
    challengeFormatter.Put(sAuthDigestStr);             // [Digest]
    challengeFormatter.PutSpace();                      // [Digest ] 
    challengeFormatter.Put(sRealmStr);                  // [Digest realm]
    challengeFormatter.Put(sEqualQuote);                // [Digest realm="]
    challengeFormatter.Put(realm);                      // [Digest realm="somerealm]
    challengeFormatter.Put(sQuoteCommaSpace);           // [Digest realm="somerealm", ]
    if(this->GetStale()) {
        challengeFormatter.Put(sStaleTrue);             // [Digest realm="somerealm", stale="true", ]
    }
    challengeFormatter.Put(sNonceStr);                  // [Digest realm="somerealm", nonce]
    challengeFormatter.Put(sEqualQuote);                // [Digest realm="somerealm", nonce="]
    challengeFormatter.Put(*nonce);                     // [Digest realm="somerealm", nonce="19723343a9fd75e019723343a9fd75e0]
    challengeFormatter.PutChar('"');                    // [Digest realm="somerealm", nonce="19723343a9fd75e019723343a9fd75e0"]
    challengeFormatter.PutTerminator();                 // [Digest realm="somerealm", nonce="19723343a9fd75e019723343a9fd75e0"\0]

    StrPtrLen challengePtr(challengeFormatter.GetBufPtr(), challengeFormatter.GetBytesWritten() - 1);
    
    this->SetValue(qtssRTSPReqDigestChallenge, 0, challengePtr.Ptr, challengePtr.Len, QTSSDictionary::kDontObeyReadOnly);
    RTSPSessionInterface* thisRTSPSession = this->GetSession();
    if (thisRTSPSession)
    {   (void)thisRTSPSession->SetValue(qtssRTSPSesLastDigestChallenge, 0, challengePtr.Ptr, challengePtr.Len,QTSSDictionary::kDontObeyReadOnly);
    }

    fStatus = qtssClientUnAuthorized;
    this->SetResponseKeepAlive(true);
    this->AppendHeader(qtssWWWAuthenticateHeader, &challengePtr);
    this->SendHeader();
    
    // deleting the memory that was allocated in GetPrefs call above
    if (prefRealmPtr != NULL)
    {   
        delete[] prefRealmPtr;  
    }
        
    return theErr;
}
Пример #12
0
QTSS_Error RTSPRequest::SendBasicChallenge(void)
{   
    QTSS_Error theErr = QTSS_NoErr;
    char *prefRealmPtr = NULL;
    
    do 
    {   
        char realmBuff[kRealmBuffSize] = "Basic realm=\"";
        StrPtrLen challenge(realmBuff);
        StrPtrLen whichRealm;
        
        // Get the module's realm
        StrPtrLen moduleRealm;
        theErr = this->GetValuePtr(qtssRTSPReqURLRealm, 0,  (void **) &moduleRealm.Ptr, &moduleRealm.Len);
        if ( (QTSS_NoErr == theErr) && (moduleRealm.Len > 0) )
        {
            whichRealm = moduleRealm;   
        }
        else
        {
            theErr = QTSS_NoErr;
            // Get the default realm from the config file or use the static default if config realm is not found
            QTSServerInterface* theServer = QTSServerInterface::GetServer();
            prefRealmPtr = theServer->GetPrefs()->GetAuthorizationRealm(); // allocates memory
            Assert(prefRealmPtr != NULL);
            if (prefRealmPtr != NULL)
            {   whichRealm.Set(prefRealmPtr, strlen(prefRealmPtr));
            }   
            else
            {
                whichRealm = sDefaultRealm;
            }
        }
        
        int realmLen = whichRealm.Len + challenge.Len + 2; // add 2 based on double quote char + end of string 0x00
        if (realmLen > kRealmBuffSize) // The realm is too big so use the default realm
        {   Assert(0);
            whichRealm = sDefaultRealm;
        }
        memcpy(&challenge.Ptr[challenge.Len],whichRealm.Ptr,whichRealm.Len);
        int newLen = challenge.Len + whichRealm.Len;
        
        challenge.Ptr[newLen] = '"'; // add the terminating "" this was accounted for with the size check above
        challenge.Ptr[newLen + 1] = 0;// add the 0 terminator this was accounted for with the size check above
        challenge.Len = newLen +1; // set the real size of the string excluding the 0.
        
        #if (0)
        {  // test code
            char test[256];
            
            memcpy(test,sDefaultRealm.Ptr,sDefaultRealm.Len);
            test[sDefaultRealm.Len] = 0;
            qtss_printf("the static realm =%s \n",test);
            
            OSCharArrayDeleter prefDeleter(QTSServerInterface::GetServer()->GetPrefs()->GetAuthorizationRealm());
            memcpy(test,prefDeleter.GetObject(),strlen(prefDeleter.GetObject()));
            test[strlen(prefDeleter.GetObject())] = 0;
            qtss_printf("the Pref realm =%s \n",test);

            memcpy(test,moduleRealm.Ptr,moduleRealm.Len);
            test[moduleRealm.Len] = 0;
            qtss_printf("the moduleRealm  =%s \n",test);
        
            memcpy(test,whichRealm.Ptr,whichRealm.Len);
            test[whichRealm.Len] = 0;
            qtss_printf("the challenge realm  =%s \n",test);
            
            memcpy(test,challenge.Ptr,challenge.Len);
            test[challenge.Len] = 0;
            qtss_printf("the challenge string  =%s len = %"_S32BITARG_"\n",test, challenge.Len);
        }
        #endif

        fStatus = qtssClientUnAuthorized;
        this->SetResponseKeepAlive(true);
        this->AppendHeader(qtssWWWAuthenticateHeader, &challenge);
        this->SendHeader();

    
    } while (false);
    
    if (prefRealmPtr != NULL)
    {   
        delete[] prefRealmPtr;  
    }
    
    return theErr;
}
Пример #13
0
int RtspRequest::ParseRtspURI(StringParser &parser)//string& sRtspURI
{
    //read in the complete URL, set it to be the qtssAbsoluteURLParam
    StrPtrLen theAbsURL;
    //StringParser parser(StrPtrLen((char*)sRtspURI.c_str()));

    //  RTSPRequestInterface::sPathURLStopConditions stop on ? as well as sURLStopConditions
    parser.ConsumeUntil(&theAbsURL, sURLStopConditions );

    // set qtssRTSPReqAbsoluteURL to the URL throught the path component; will be : <protocol>://<host-addr>/<path>
    //this->SetVal(qtssRTSPReqAbsoluteURL, &theAbsURL);
    
    StringParser urlParser(&theAbsURL);
    
    //we always should have a slash before the uri.
    //If not, that indicates this is a full URI. Also, this could be a '*' OPTIONS request
    if ((*theAbsURL.Ptr != '/') && (*theAbsURL.Ptr != '*'))
    {
        //if it is a full URL, store the host name off in a separate parameter
        StrPtrLen theRTSPString;
        urlParser.ConsumeLength(&theRTSPString, 7); //consume "rtsp://"
        //assign the host field here to the proper QTSS param
        StrPtrLen theHost;
        urlParser.ConsumeUntil(&theHost, '/');
        //fHeaderDictionary.SetVal(qtssHostHeader, &theHost);
        ///save host
    }
    // don't allow non-aggregate operations indicated by a url/media track=id
// might need this for rate adapt   if (qtssSetupMethod != fMethod && qtssOptionsMethod != fMethod && qtssSetParameterMethod != fMethod) // any method not a setup, options, or setparameter is not allowed to have a "/trackID=" in the url.
    if (qtssSetupMethod != m_Method) // any method not a setup is not allowed to have a "/trackID=" in the url.
    {
        StrPtrLenDel tempCStr(theAbsURL.GetAsCString()); 
        StrPtrLen nonaggregate(tempCStr.FindString("/trackID="));
        if (nonaggregate.Len > 0) // check for non-aggregate method and return error
            return -1;//QTSSModuleUtils::SendErrorResponse(this, qtssClientAggregateOptionAllowed, qtssMsgBadRTSPMethod, &theAbsURL);
    }        
    // In case there is no URI at all... we have to fake it.
    static char* sSlashURI = "/";
        
    //whatever is in this position in the URL must be the URI. Store that
    //in the qtssURLParam. Confused?
    StrPtrLen theURLParam;
    UInt32 uriLen = urlParser.GetDataReceivedLen() - urlParser.GetDataParsedLen();
    if (uriLen > 0)
        ///this->SetVal(qtssRTSPReqURI, urlParser.GetCurrentPosition(), urlParser.GetDataReceivedLen() - urlParser.GetDataParsedLen());
        theURLParam.Set(urlParser.GetCurrentPosition(), urlParser.GetDataReceivedLen() - urlParser.GetDataParsedLen());
    else
        //
        // This might happen if there is nothing after the host at all, not even
        // a '/'. This is legal (RFC 2326, Sec 3.2). If so, just pretend that there
        // is a '/'
        ///this->SetVal(qtssRTSPReqURI, sSlashURI, 1);
        theURLParam.Set(sSlashURI, 1);

    // parse the query string from the url if present.
    // init qtssRTSPReqQueryString dictionary to an empty string
    StrPtrLen queryString;
    ///this->SetVal(qtssRTSPReqQueryString, queryString.Ptr, queryString.Len);
    
    if ( parser.GetDataRemaining() > 0 )
    {   
        if ( parser.PeekFast() == '?' )
        {       
            // we've got some CGI param
            parser.ConsumeLength(&queryString, 1); // toss '?'
            
            // consume the rest of the line..
            parser.ConsumeUntilWhitespace(&queryString);
            
            ///this->SetVal(qtssRTSPReqQueryString, queryString.Ptr, queryString.Len);
        }
    }
 
 
    //
    // If the is a '*', return right now because '*' is not a path
    // so the below functions don't make any sense.
    if ((*theAbsURL.Ptr == '*') && (theAbsURL.Len == 1))
    {
        //this->SetValue(qtssRTSPReqFilePath, 0, theAbsURL.Ptr, theAbsURL.Len, QTSSDictionary::kDontObeyReadOnly);
        strncpy(m_sFilePath, theAbsURL.Ptr, theAbsURL.Len);
        return 0;//QTSS_NoErr;
    }
    
    //path strings are statically allocated. Therefore, if they are longer than
    //this length we won't be able to handle the request.
    //StrPtrLen* theURLParam = this->GetValue(qtssRTSPReqURI);
    if (theURLParam.Len > RTSP_FILE_PATH_LEN_MAX)
        return -1; //QTSSModuleUtils::SendErrorResponse(this, qtssClientBadRequest, qtssMsgURLTooLong, theURLParam);

    //decode the URL, put the result in the separate buffer for the file path,
    //set the file path StrPtrLen to the proper value
    SInt32 theBytesWritten = StringTranslator::DecodeURL(theURLParam.Ptr, theURLParam.Len,
                                                m_sFilePath, RTSP_FILE_PATH_LEN_MAX);
    //if negative, an error occurred, reported as an QTSS_Error
    //we also need to leave room for a terminator.
    if ((theBytesWritten < 0) || (theBytesWritten == RTSP_FILE_PATH_LEN_MAX))
    {
        return -1;//QTSSModuleUtils::SendErrorResponse(this, qtssClientBadRequest, qtssMsgURLInBadFormat, theURLParam);
    }

    // Convert from a / delimited path to a local file system path
    ///StringTranslator::DecodePath(m_sFilePath, theBytesWritten);
    
    //setup the proper QTSS param
    m_sFilePath[theBytesWritten] = '\0';
    //this->SetVal(qtssRTSPReqFilePath, fFilePath, theBytesWritten);
    //this->SetValue(qtssRTSPReqFilePath, 0, fFilePath, theBytesWritten, QTSSDictionary::kDontObeyReadOnly);

    if (qtssSetupMethod == m_Method)
    {
        StrPtrLen thePathPtr(m_sFilePath);
        char *trackStr = thePathPtr.FindString("/trackID=");
        if (trackStr != NULL && *trackStr != 0)
        {
            *trackStr = 0; // terminate the string.
            //thePathPtr.Len = ::strlen(thePathPtr.Ptr);
        }
    }
    
    return 0;//QTSS_NoErr;
}