537 lines
22 KiB
C++
537 lines
22 KiB
C++
|
/*
|
||
|
*
|
||
|
* @APPLE_LICENSE_HEADER_START@
|
||
|
*
|
||
|
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||
|
*
|
||
|
* This file contains Original Code and/or Modifications of Original Code
|
||
|
* as defined in and that are subject to the Apple Public Source License
|
||
|
* Version 2.0 (the 'License'). You may not use this file except in
|
||
|
* compliance with the License. Please obtain a copy of the License at
|
||
|
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||
|
* file.
|
||
|
*
|
||
|
* The Original Code and all software distributed under the License are
|
||
|
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||
|
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||
|
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||
|
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||
|
* Please see the License for the specific language governing rights and
|
||
|
* limitations under the License.
|
||
|
*
|
||
|
* @APPLE_LICENSE_HEADER_END@
|
||
|
*
|
||
|
*/
|
||
|
/*
|
||
|
File: QTSSAccessModule.cpp
|
||
|
|
||
|
Contains: Implementation of QTSSAccessModule.
|
||
|
|
||
|
|
||
|
|
||
|
*/
|
||
|
|
||
|
#include "QTSSAccessModule.h"
|
||
|
|
||
|
#include "../defaultPaths.h"
|
||
|
|
||
|
|
||
|
#include "OSArrayObjectDeleter.h"
|
||
|
#include "QTSS_Private.h"
|
||
|
#include "StrPtrLen.h"
|
||
|
#include "OSMemory.h"
|
||
|
#include "MyAssert.h"
|
||
|
#include "StringFormatter.h"
|
||
|
#include "StrPtrLen.h"
|
||
|
#include "StringParser.h"
|
||
|
#include "base64.h"
|
||
|
#include "OS.h"
|
||
|
#include "AccessChecker.h"
|
||
|
#include "QTAccessFile.h"
|
||
|
#include "QTSSModuleUtils.h"
|
||
|
|
||
|
#ifndef __Win32__
|
||
|
#include <unistd.h>
|
||
|
#endif
|
||
|
|
||
|
#include <fcntl.h>
|
||
|
#include <errno.h>
|
||
|
|
||
|
|
||
|
|
||
|
// ATTRIBUTES
|
||
|
|
||
|
// STATIC DATA
|
||
|
|
||
|
|
||
|
#define MODPREFIX_ "modAccess_"
|
||
|
|
||
|
static StrPtrLen sSDPSuffix(".sdp");
|
||
|
static OSMutex* sUserMutex = NULL;
|
||
|
|
||
|
static Bool16 sDefaultAuthenticationEnabled = true;
|
||
|
static Bool16 sAuthenticationEnabled = true;
|
||
|
|
||
|
static char* sDefaultUsersFilePath = DEFAULTPATHS_ETC_DIR "qtusers";
|
||
|
static char* sUsersFilePath = NULL;
|
||
|
|
||
|
static char* sDefaultGroupsFilePath = DEFAULTPATHS_ETC_DIR "qtgroups";
|
||
|
static char* sGroupsFilePath = NULL;
|
||
|
|
||
|
static char* sDefaultAccessFileName = "qtaccess";
|
||
|
|
||
|
static QTSS_AttributeID sBadNameMessageAttrID = qtssIllegalAttrID;
|
||
|
static QTSS_AttributeID sUsersFileNotFoundMessageAttrID = qtssIllegalAttrID;
|
||
|
static QTSS_AttributeID sGroupsFileNotFoundMessageAttrID = qtssIllegalAttrID;
|
||
|
static QTSS_AttributeID sBadUsersFileMessageAttrID = qtssIllegalAttrID;
|
||
|
static QTSS_AttributeID sBadGroupsFileMessageAttrID = qtssIllegalAttrID;
|
||
|
|
||
|
static QTSS_StreamRef sErrorLogStream = NULL;
|
||
|
static QTSS_TextMessagesObject sMessages = NULL;
|
||
|
static QTSS_ModulePrefsObject sPrefs = NULL;
|
||
|
static QTSS_PrefsObject sServerPrefs = NULL;
|
||
|
|
||
|
static AccessChecker** sAccessCheckers;
|
||
|
static UInt32 sNumAccessCheckers = 0;
|
||
|
static UInt32 sAccessCheckerArraySize = 0;
|
||
|
|
||
|
static Bool16 sAllowGuestDefaultEnabled = true;
|
||
|
static Bool16 sDefaultGuestEnabled = true;
|
||
|
|
||
|
// FUNCTION PROTOTYPES
|
||
|
|
||
|
static QTSS_Error QTSSAccessModuleDispatch(QTSS_Role inRole, QTSS_RoleParamPtr inParams);
|
||
|
static QTSS_Error Register();
|
||
|
static QTSS_Error Initialize(QTSS_Initialize_Params* inParams);
|
||
|
static QTSS_Error Shutdown();
|
||
|
static QTSS_Error RereadPrefs();
|
||
|
static QTSS_Error AuthenticateRTSPRequest(QTSS_RTSPAuth_Params* inParams);
|
||
|
static QTSS_Error AccessAuthorizeRTSPRequest(QTSS_StandardRTSP_Params* inParams);
|
||
|
static char* GetCheckedFileName();
|
||
|
|
||
|
// FUNCTION IMPLEMENTATIONS
|
||
|
|
||
|
|
||
|
QTSS_Error QTSSAccessModule_Main(void* inPrivateArgs)
|
||
|
{
|
||
|
return _stublibrary_main(inPrivateArgs, QTSSAccessModuleDispatch);
|
||
|
}
|
||
|
|
||
|
|
||
|
QTSS_Error QTSSAccessModuleDispatch(QTSS_Role inRole, QTSS_RoleParamPtr inParams)
|
||
|
{
|
||
|
switch (inRole)
|
||
|
{
|
||
|
case QTSS_Register_Role:
|
||
|
return Register();
|
||
|
break;
|
||
|
|
||
|
case QTSS_Initialize_Role:
|
||
|
return Initialize(&inParams->initParams);
|
||
|
break;
|
||
|
|
||
|
case QTSS_RereadPrefs_Role:
|
||
|
return RereadPrefs();
|
||
|
break;
|
||
|
|
||
|
case QTSS_RTSPAuthenticate_Role:
|
||
|
if (sAuthenticationEnabled)
|
||
|
return AuthenticateRTSPRequest(&inParams->rtspAthnParams);
|
||
|
break;
|
||
|
|
||
|
case QTSS_RTSPAuthorize_Role:
|
||
|
if (sAuthenticationEnabled)
|
||
|
return AccessAuthorizeRTSPRequest(&inParams->rtspRequestParams);
|
||
|
break;
|
||
|
|
||
|
case QTSS_Shutdown_Role:
|
||
|
return Shutdown();
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return QTSS_NoErr;
|
||
|
}
|
||
|
|
||
|
QTSS_Error Register()
|
||
|
{
|
||
|
// Do role & attribute setup
|
||
|
(void)QTSS_AddRole(QTSS_Initialize_Role);
|
||
|
(void)QTSS_AddRole(QTSS_RereadPrefs_Role);
|
||
|
(void)QTSS_AddRole(QTSS_RTSPAuthenticate_Role);
|
||
|
(void)QTSS_AddRole(QTSS_RTSPAuthorize_Role);
|
||
|
|
||
|
// Add AuthenticateName and Password attributes
|
||
|
static char* sBadAccessFileName = "QTSSAccessModuleBadAccessFileName";
|
||
|
static char* sUsersFileNotFound = "QTSSAccessModuleUsersFileNotFound";
|
||
|
static char* sGroupsFileNotFound = "QTSSAccessModuleGroupsFileNotFound";
|
||
|
static char* sBadUsersFile = "QTSSAccessModuleBadUsersFile";
|
||
|
static char* sBadGroupsFile = "QTSSAccessModuleBadGroupsFile";
|
||
|
|
||
|
(void)QTSS_AddStaticAttribute(qtssTextMessagesObjectType, sBadAccessFileName, NULL, qtssAttrDataTypeCharArray);
|
||
|
(void)QTSS_IDForAttr(qtssTextMessagesObjectType, sBadAccessFileName, &sBadNameMessageAttrID);
|
||
|
|
||
|
(void)QTSS_AddStaticAttribute(qtssTextMessagesObjectType, sUsersFileNotFound, NULL, qtssAttrDataTypeCharArray);
|
||
|
(void)QTSS_IDForAttr(qtssTextMessagesObjectType, sUsersFileNotFound, &sUsersFileNotFoundMessageAttrID);
|
||
|
|
||
|
(void)QTSS_AddStaticAttribute(qtssTextMessagesObjectType, sGroupsFileNotFound, NULL, qtssAttrDataTypeCharArray);
|
||
|
(void)QTSS_IDForAttr(qtssTextMessagesObjectType, sGroupsFileNotFound, &sGroupsFileNotFoundMessageAttrID);
|
||
|
|
||
|
(void)QTSS_AddStaticAttribute(qtssTextMessagesObjectType, sBadUsersFile, NULL, qtssAttrDataTypeCharArray);
|
||
|
(void)QTSS_IDForAttr(qtssTextMessagesObjectType, sBadUsersFile, &sBadUsersFileMessageAttrID);
|
||
|
|
||
|
(void)QTSS_AddStaticAttribute(qtssTextMessagesObjectType, sBadGroupsFile, NULL, qtssAttrDataTypeCharArray);
|
||
|
(void)QTSS_IDForAttr(qtssTextMessagesObjectType, sBadGroupsFile, &sBadGroupsFileMessageAttrID);
|
||
|
|
||
|
return QTSS_NoErr;
|
||
|
}
|
||
|
|
||
|
|
||
|
QTSS_Error Initialize(QTSS_Initialize_Params* inParams)
|
||
|
{
|
||
|
// Create an array of AccessCheckers
|
||
|
sAccessCheckers = NEW AccessChecker*[2];
|
||
|
sAccessCheckers[0] = NEW AccessChecker();
|
||
|
sNumAccessCheckers = 1;
|
||
|
sAccessCheckerArraySize = 2;
|
||
|
|
||
|
// Setup module utils
|
||
|
QTSSModuleUtils::Initialize(inParams->inMessages, inParams->inServer, inParams->inErrorLogStream);
|
||
|
sErrorLogStream = inParams->inErrorLogStream;
|
||
|
sMessages = inParams->inMessages;
|
||
|
sPrefs = QTSSModuleUtils::GetModulePrefsObject(inParams->inModule);
|
||
|
sServerPrefs = inParams->inPrefs;
|
||
|
sUserMutex = NEW OSMutex();
|
||
|
RereadPrefs();
|
||
|
QTAccessFile::Initialize();
|
||
|
|
||
|
return QTSS_NoErr;
|
||
|
}
|
||
|
|
||
|
QTSS_Error Shutdown()
|
||
|
{
|
||
|
//cleanup
|
||
|
|
||
|
// delete all the AccessCheckers
|
||
|
UInt32 index;
|
||
|
for(index = 0; index < sNumAccessCheckers; index++)
|
||
|
delete sAccessCheckers[index];
|
||
|
delete[] sAccessCheckers;
|
||
|
sNumAccessCheckers = 0;
|
||
|
|
||
|
// delete the main users and groups path
|
||
|
|
||
|
//if(sUsersFilePath != sDefaultUsersFilePath)
|
||
|
// sUsersFilePath is assigned by a call to QTSSModuleUtils::GetStringAttribute which always
|
||
|
// allocates memory even if it just returns the default value
|
||
|
delete[] sUsersFilePath;
|
||
|
sUsersFilePath = NULL;
|
||
|
|
||
|
//if(sGroupsFilePath != sDefaultGroupsFilePath)
|
||
|
// sGroupsFilePath is assigned by a call to QTSSModuleUtils::GetStringAttribute which always
|
||
|
// allocates memory even if it just returns the default value
|
||
|
delete[] sGroupsFilePath;
|
||
|
sGroupsFilePath = NULL;
|
||
|
|
||
|
return QTSS_NoErr;
|
||
|
}
|
||
|
|
||
|
char* GetCheckedFileName()
|
||
|
{
|
||
|
char *result = NULL;
|
||
|
static char *badChars = "/'\"";
|
||
|
char theBadCharMessage[] = "' '";
|
||
|
char *theBadChar = NULL;
|
||
|
result = QTSSModuleUtils::GetStringAttribute(sPrefs, MODPREFIX_"qtaccessfilename", sDefaultAccessFileName);
|
||
|
StrPtrLen searchStr(result);
|
||
|
|
||
|
theBadChar = strpbrk(searchStr.Ptr, badChars);
|
||
|
if ( theBadChar!= NULL)
|
||
|
{
|
||
|
theBadCharMessage[1] = theBadChar[0];
|
||
|
QTSSModuleUtils::LogError(qtssWarningVerbosity,sBadNameMessageAttrID, 0, theBadCharMessage, result);
|
||
|
|
||
|
delete[] result;
|
||
|
result = NEW char[::strlen(sDefaultAccessFileName) + 2];
|
||
|
::strcpy(result, sDefaultAccessFileName);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
QTSS_Error RereadPrefs()
|
||
|
{
|
||
|
OSMutexLocker locker(sUserMutex);
|
||
|
|
||
|
//
|
||
|
// Use the standard GetAttribute routine to retrieve the correct values for our preferences
|
||
|
QTSSModuleUtils::GetAttribute(sPrefs, MODPREFIX_"enabled", qtssAttrDataTypeBool16,
|
||
|
&sAuthenticationEnabled, &sDefaultAuthenticationEnabled, sizeof(sAuthenticationEnabled));
|
||
|
|
||
|
//if(sUsersFilePath != sDefaultUsersFilePath)
|
||
|
// sUsersFilePath is assigned by a call to QTSSModuleUtils::GetStringAttribute which always
|
||
|
// allocates memory even if it just returns the default value
|
||
|
// delete this old memory before reassigning it to new memory
|
||
|
delete[] sUsersFilePath;
|
||
|
sUsersFilePath = NULL;
|
||
|
|
||
|
//if(sGroupsFilePath != sDefaultGroupsFilePath)
|
||
|
// sGroupsFilePath is assigned by a call to QTSSModuleUtils::GetStringAttribute which always
|
||
|
// allocates memory even if it just returns the default value
|
||
|
// delete this old memory before reassigning it to new memory
|
||
|
delete[] sGroupsFilePath;
|
||
|
sGroupsFilePath = NULL;
|
||
|
|
||
|
sUsersFilePath = QTSSModuleUtils::GetStringAttribute(sPrefs, MODPREFIX_"usersfilepath", sDefaultUsersFilePath);
|
||
|
sGroupsFilePath = QTSSModuleUtils::GetStringAttribute(sPrefs, MODPREFIX_"groupsfilepath", sDefaultGroupsFilePath);
|
||
|
// GetCheckedFileName always allocates memory
|
||
|
char* accessFile = GetCheckedFileName();
|
||
|
// QTAccessFile::SetAccessFileName makes its own copy,
|
||
|
// so delete the previous allocated memory after this call
|
||
|
QTAccessFile::SetAccessFileName(accessFile);
|
||
|
delete [] accessFile;
|
||
|
|
||
|
if(sAccessCheckers[0]->HaveFilePathsChanged(sUsersFilePath, sGroupsFilePath))
|
||
|
{
|
||
|
sAccessCheckers[0]->UpdateFilePaths(sUsersFilePath, sGroupsFilePath);
|
||
|
UInt32 err;
|
||
|
err = sAccessCheckers[0]->UpdateUserProfiles();
|
||
|
if(err & AccessChecker::kUsersFileNotFoundErr)
|
||
|
QTSSModuleUtils::LogError(qtssWarningVerbosity,sUsersFileNotFoundMessageAttrID, 0, sUsersFilePath, NULL);
|
||
|
else if(err & AccessChecker::kBadUsersFileErr)
|
||
|
QTSSModuleUtils::LogError(qtssWarningVerbosity,sBadUsersFileMessageAttrID, 0, sUsersFilePath, NULL);
|
||
|
if(err & AccessChecker::kGroupsFileNotFoundErr)
|
||
|
QTSSModuleUtils::LogError(qtssWarningVerbosity,sGroupsFileNotFoundMessageAttrID, 0, sGroupsFilePath, NULL);
|
||
|
else if(err & AccessChecker::kBadGroupsFileErr)
|
||
|
QTSSModuleUtils::LogError(qtssWarningVerbosity,sBadGroupsFileMessageAttrID, 0, sGroupsFilePath, NULL);
|
||
|
}
|
||
|
|
||
|
QTSSModuleUtils::GetAttribute(sServerPrefs,"enable_allow_guest_default", qtssAttrDataTypeBool16,
|
||
|
&sAllowGuestDefaultEnabled,(void *)&sDefaultGuestEnabled, sizeof(sAllowGuestDefaultEnabled));
|
||
|
|
||
|
|
||
|
return QTSS_NoErr;
|
||
|
}
|
||
|
|
||
|
QTSS_Error AuthenticateRTSPRequest(QTSS_RTSPAuth_Params* inParams)
|
||
|
{
|
||
|
QTSS_RTSPRequestObject theRTSPRequest = inParams->inRTSPRequest;
|
||
|
UInt32 fileErr;
|
||
|
|
||
|
OSMutexLocker locker(sUserMutex);
|
||
|
|
||
|
if ( (NULL == inParams) || (NULL == inParams->inRTSPRequest) )
|
||
|
return QTSS_RequestFailed;
|
||
|
|
||
|
// Get the user profile object from the request object
|
||
|
QTSS_UserProfileObject theUserProfile = NULL;
|
||
|
UInt32 len = sizeof(QTSS_UserProfileObject);
|
||
|
QTSS_Error theErr = QTSS_GetValue(theRTSPRequest, qtssRTSPReqUserProfile, 0, (void*)&theUserProfile, &len);
|
||
|
Assert(len == sizeof(QTSS_UserProfileObject));
|
||
|
if (theErr != QTSS_NoErr)
|
||
|
return theErr;
|
||
|
|
||
|
Bool16 defaultPaths = true;
|
||
|
// Check for a users and groups file in the access file
|
||
|
// For this, first get local file path and root movie directory
|
||
|
//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;
|
||
|
// Now get the access file path
|
||
|
char* accessFilePath = QTAccessFile::GetAccessFile_Copy(movieRootDirStr, pathBuffStr);
|
||
|
OSCharArrayDeleter accessFilePathDeleter(accessFilePath);
|
||
|
// Parse the access file for the AuthUserFile and AuthGroupFile keywords
|
||
|
char* usersFilePath = NULL;
|
||
|
char* groupsFilePath = NULL;
|
||
|
|
||
|
// Get the request action from the request object
|
||
|
QTSS_ActionFlags action = qtssActionFlagsNoFlags;
|
||
|
len = sizeof(action);
|
||
|
theErr = QTSS_GetValue(theRTSPRequest, qtssRTSPReqAction, 0, (void*)&action, &len);
|
||
|
Assert(len == sizeof(action));
|
||
|
if (theErr != QTSS_NoErr)
|
||
|
return theErr;
|
||
|
|
||
|
// Allocates memory for usersFilePath and groupsFilePath
|
||
|
QTSS_AuthScheme authScheme = QTAccessFile::FindUsersAndGroupsFilesAndAuthScheme(accessFilePath, action, &usersFilePath, &groupsFilePath);
|
||
|
|
||
|
if((usersFilePath != NULL) || (groupsFilePath != NULL))
|
||
|
defaultPaths = false;
|
||
|
|
||
|
if(usersFilePath == NULL)
|
||
|
usersFilePath = strdup(sUsersFilePath);
|
||
|
|
||
|
if(groupsFilePath == NULL)
|
||
|
groupsFilePath = strdup(sGroupsFilePath);
|
||
|
|
||
|
OSCharArrayDeleter userPathDeleter(usersFilePath);
|
||
|
OSCharArrayDeleter groupPathDeleter(groupsFilePath);
|
||
|
|
||
|
AccessChecker* currentChecker = NULL;
|
||
|
UInt32 index;
|
||
|
|
||
|
// If the default users and groups file are not the ones we need
|
||
|
if(!defaultPaths)
|
||
|
{
|
||
|
// check if there is one AccessChecker that matches the needed paths
|
||
|
// Don't have to check for the first one (or element zero) because it has the default paths
|
||
|
for(index = 1; index < sNumAccessCheckers; index++)
|
||
|
{
|
||
|
// If an access checker that matches the users and groups file paths is found
|
||
|
if(!sAccessCheckers[index]->HaveFilePathsChanged(usersFilePath, groupsFilePath))
|
||
|
{
|
||
|
currentChecker = sAccessCheckers[index];
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
// If an existing AccessChecker for the needed paths isn't found
|
||
|
if(currentChecker == NULL)
|
||
|
{
|
||
|
// Grow the AccessChecker array if needed
|
||
|
if(sNumAccessCheckers == sAccessCheckerArraySize)
|
||
|
{
|
||
|
AccessChecker** oldAccessCheckers = sAccessCheckers;
|
||
|
sAccessCheckers = NEW AccessChecker*[sAccessCheckerArraySize * 2];
|
||
|
for(index = 0; index < sNumAccessCheckers; index++)
|
||
|
{
|
||
|
sAccessCheckers[index] = oldAccessCheckers[index];
|
||
|
}
|
||
|
sAccessCheckerArraySize *= 2;
|
||
|
delete [] oldAccessCheckers;
|
||
|
}
|
||
|
|
||
|
// And create a new AccessChecker for the paths
|
||
|
sAccessCheckers[sNumAccessCheckers] = NEW AccessChecker();
|
||
|
sAccessCheckers[sNumAccessCheckers]->UpdateFilePaths(usersFilePath, groupsFilePath);
|
||
|
fileErr = sAccessCheckers[sNumAccessCheckers]->UpdateUserProfiles();
|
||
|
|
||
|
if(fileErr & AccessChecker::kUsersFileNotFoundErr)
|
||
|
QTSSModuleUtils::LogError(qtssWarningVerbosity,sUsersFileNotFoundMessageAttrID, 0, usersFilePath, NULL);
|
||
|
else if(fileErr & AccessChecker::kBadUsersFileErr)
|
||
|
QTSSModuleUtils::LogError(qtssWarningVerbosity,sBadUsersFileMessageAttrID, 0, usersFilePath, NULL);
|
||
|
if(fileErr & AccessChecker::kGroupsFileNotFoundErr)
|
||
|
QTSSModuleUtils::LogError(qtssWarningVerbosity,sGroupsFileNotFoundMessageAttrID, 0, groupsFilePath, NULL);
|
||
|
else if(fileErr & AccessChecker::kBadGroupsFileErr)
|
||
|
QTSSModuleUtils::LogError(qtssWarningVerbosity,sBadGroupsFileMessageAttrID, 0, groupsFilePath, NULL);
|
||
|
|
||
|
currentChecker = sAccessCheckers[sNumAccessCheckers];
|
||
|
sNumAccessCheckers++;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
currentChecker = sAccessCheckers[0];
|
||
|
}
|
||
|
|
||
|
// Before retrieving the user profile information
|
||
|
// check if the groups/users files have been modified and update them otherwise
|
||
|
fileErr = currentChecker->UpdateUserProfiles();
|
||
|
|
||
|
/*
|
||
|
// This is for logging the errors if users file and/or the groups file is not found or corrupted
|
||
|
char* usersFile = currentChecker->GetUsersFilePathPtr();
|
||
|
char* groupsFile = currentChecker->GetGroupsFilePathPtr();
|
||
|
|
||
|
if(fileErr & AccessChecker::kUsersFileNotFoundErr)
|
||
|
QTSSModuleUtils::LogError(qtssWarningVerbosity,sUsersFileNotFoundMessageAttrID, 0, usersFile, NULL);
|
||
|
else if(fileErr & AccessChecker::kBadUsersFileErr)
|
||
|
QTSSModuleUtils::LogError(qtssWarningVerbosity,sBadUsersFileMessageAttrID, 0, usersFile, NULL);
|
||
|
if(fileErr & AccessChecker::kGroupsFileNotFoundErr)
|
||
|
QTSSModuleUtils::LogError(qtssWarningVerbosity,sGroupsFileNotFoundMessageAttrID, 0, groupsFile, NULL);
|
||
|
else if(fileErr & AccessChecker::kBadGroupsFileErr)
|
||
|
QTSSModuleUtils::LogError(qtssWarningVerbosity,sBadGroupsFileMessageAttrID, 0, groupsFile, NULL);
|
||
|
*/
|
||
|
|
||
|
// Retrieve the password data and group information for the user and set them
|
||
|
// in the qtssRTSPReqUserProfile attr
|
||
|
// The password data is crypt of the real password for Basic authentication
|
||
|
// and it is MD5(username:realm:password) for Digest authentication
|
||
|
|
||
|
// It the access file didn't contain an auth scheme, then get the auth scheme out of the request object
|
||
|
// else, set the qtssRTSPReqAuthScheme to that found in the access file
|
||
|
|
||
|
if (authScheme == qtssAuthNone)
|
||
|
{
|
||
|
// Get the authentication scheme from the request object
|
||
|
len = sizeof(authScheme);
|
||
|
theErr = QTSS_GetValue(theRTSPRequest, qtssRTSPReqAuthScheme, 0, (void*)&authScheme, &len);
|
||
|
Assert(len == sizeof(authScheme));
|
||
|
if (theErr != QTSS_NoErr)
|
||
|
return theErr;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
theErr = QTSS_SetValue(theRTSPRequest, qtssRTSPReqAuthScheme, 0, (void*)&authScheme, sizeof(authScheme));
|
||
|
if (theErr != QTSS_NoErr)
|
||
|
return theErr;
|
||
|
}
|
||
|
|
||
|
// Set the qtssUserRealm to the realm value retrieved from the users file
|
||
|
// This should be used for digest auth scheme, and if no realm is found in the qtaccess file, then
|
||
|
// it should be used for basic auth scheme.
|
||
|
// No memory is allocated; just a pointer is returned
|
||
|
StrPtrLen* authRealm = currentChecker->GetAuthRealm();
|
||
|
(void)QTSS_SetValue(theUserProfile, qtssUserRealm, 0, (void*)(authRealm->Ptr), (authRealm->Len));
|
||
|
|
||
|
|
||
|
// Get the username from the user profile object
|
||
|
char* usernameBuf = NULL;
|
||
|
theErr = QTSS_GetValueAsString(theUserProfile, qtssUserName, 0, &usernameBuf);
|
||
|
OSCharArrayDeleter usernameBufDeleter(usernameBuf);
|
||
|
StrPtrLen username(usernameBuf);
|
||
|
if (theErr != QTSS_NoErr)
|
||
|
return theErr;
|
||
|
|
||
|
// No memory is allocated; just a pointer to the profile is returned
|
||
|
AccessChecker::UserProfile* profile = currentChecker->RetrieveUserProfile(&username);
|
||
|
|
||
|
if(profile == NULL)
|
||
|
return QTSS_NoErr;
|
||
|
|
||
|
// Set the qtssUserPassword attribute to either the crypted password or the digest password
|
||
|
// based on the authentication scheme
|
||
|
if (authScheme == qtssAuthBasic)
|
||
|
(void)QTSS_SetValue(theUserProfile, qtssUserPassword, 0, (void*)((profile->cryptPassword).Ptr), (profile->cryptPassword).Len);
|
||
|
else if (authScheme == qtssAuthDigest)
|
||
|
(void)QTSS_SetValue(theUserProfile, qtssUserPassword, 0, (void*)((profile->digestPassword).Ptr), (profile->digestPassword).Len);
|
||
|
|
||
|
|
||
|
// Set the multivalued qtssUserGroups attr to the groups the user belongs to, if any
|
||
|
UInt32 maxLen = profile->maxGroupNameLen;
|
||
|
for(index = 0; index < profile->numGroups; index++)
|
||
|
{
|
||
|
UInt32 curLen = ::strlen(profile->groups[index]);
|
||
|
if(curLen < maxLen)
|
||
|
{
|
||
|
char* groupWithPaddedZeros = NEW char[maxLen]; // memory allocated
|
||
|
::memcpy(groupWithPaddedZeros, profile->groups[index], curLen);
|
||
|
::memset(groupWithPaddedZeros+curLen, '\0', maxLen-curLen);
|
||
|
(void)QTSS_SetValue(theUserProfile, qtssUserGroups, index, (void*)groupWithPaddedZeros, maxLen);
|
||
|
delete [] groupWithPaddedZeros; // memory deleted
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
(void)QTSS_SetValue(theUserProfile, qtssUserGroups, index, (void*)(profile->groups[index]), maxLen);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return QTSS_NoErr;
|
||
|
}
|
||
|
|
||
|
QTSS_Error AccessAuthorizeRTSPRequest(QTSS_StandardRTSP_Params* inParams)
|
||
|
{
|
||
|
Bool16 allowNoAccessFiles = sAllowGuestDefaultEnabled; //no access files allowed means allowing guest access (unknown users)
|
||
|
QTSS_ActionFlags noAction = ~qtssActionFlagsRead; // allow any action
|
||
|
QTSS_ActionFlags authorizeAction = QTSSModuleUtils::GetRequestActions(inParams->inRTSPRequest);
|
||
|
Bool16 authorized =false;
|
||
|
Bool16 allowAnyUser = false;
|
||
|
QTAccessFile accessFile;
|
||
|
return accessFile.AuthorizeRequest(inParams,allowNoAccessFiles, noAction, authorizeAction, &authorized, &allowAnyUser);
|
||
|
}
|