host/cxpslib/serveroptions.h (155 lines of code) (raw):
///
/// \file serveroptions.h
///
/// \brief managing server otpions set in the conf file
///
/// \example cxps.conf
#ifndef SERVEROPTIONS_H
#define SERVEROPTIONS_H
#include <string>
#include <set>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/logic/tribool.hpp>
#include "tagvalue.h"
#include "errorexception.h"
#include "writemode.h"
#include "pssettingsconfigurator.h"
#define DEFAULT_LOG_DIR "log/"
#define DEFAULT_FX_ALLOWED_DIRS_PATH "fxallowed/"
#define DEFAULT_NAME "cxps" ///< default file prefix name
#define DEFAULT_CONF_FILE DEFAULT_NAME ".conf" ///< default conf file name
/// \brief CxInlineCompressAll is an alternate name for boost::indeterminate
///
/// use to explicitly test for inline compress all diff files\n
/// \n
/// e.g.\n
/// \code
/// boost::tribool inlineCompress = m_serverOptions->inlineCompressions();
/// if (CxInlimeCompressAll(tb)) {
/// // inline compress all diff files
/// }
/// \endcode
/// \n
/// see boost.tribool documentation for more details about tribool
BOOST_TRIBOOL_THIRD_STATE(CxInlineCompressAll);
/// \brief manages server options in the conf file
class ServerOptions {
public:
typedef std::pair<std::string, std::string> remapPrefixFromTo_t;
typedef std::set<std::string> dirs_t;
typedef std::multimap<std::string, std::string> biosIdHostIdMap_t; ///< holds biosid to hostid map from PS Settings.
typedef std::map<std::string, std::string> hostIdDirMap_t; ///< holds hostid to logfolder/telemetryfolder map from PS Settings.
/// \brief constructor
ServerOptions(std::string const& fileName, ///< name of configuration file to use
std::string const& installDir ///< cxps install dir (OK if empty)
);
virtual ~ServerOptions();
/// \brief gets the list of allowed dirs
///
/// the allowed dirs that cxps can read/write/delete
/// if more then one, separate with semi-colon
/// e.g. /home/systems;/svsystems/cache
/// notes
/// 1: if remap_full_prefix option is used, as long as either the from or to are
/// on the allowed_dirs it will be fine. I.e. you do not need to add both
/// 2: on windows drive letters matter as you could have the same dirname on
/// different drives but only want to allow a given dirname on a specific drive
///
/// \return dirs_t filled with allowed dirs
dirs_t const& allowedDirs() const;
/// \brief gets the list of exclude dirs which restricts the allowed dirs (see cxps.conf for details
///
/// exclude dirs is for excluding dirs under the allowed dirs in case you want to limit
/// certain directories under the allowed dirs. In general these are subdirs of the allowed dirs.
/// if you enter a relative dir (i.e. is not a full path), then that subdir will be
/// excluded under all listed allowed_dris. If you have more then 1 allowed dir and want
/// to exlcude a subdir under a specific allowed dir but not others, then you have to use the full path
/// of the exclude dir. Basically if the base name of the full files path matches one of the exclude dir
/// then it is not allowed, but still have access to subdirs. If you want to exclude a dir and all its
/// subdirs (recursively) then use /* at the end of the dir (dir1/subdir1/*)
///
/// e.g. with the following settings
///
/// allowed_dirs = /dir1;/dir2
/// exclude_dirs = xdir1;xdir2/*;/dir2/bar
///
/// so the allow_dirs says you can access everything under /dir1 and /dir2 but the exclude_dirs
/// refines to such that
/// * no access to files in xdir1 under both /dir1 and /dir2 (/dir1/xdir1 and /dir2/xdir1)
/// but still allow access to subdirs under xdir1 /dir1/xdir1/subxdir1).
/// * no access to files in xdir2 nor any of it subdirs for both /dir1 and /dir2 (/dir1/xdir2 and /dir2/xdir2)
/// * no access to bar under /dir2 only (/dir2/bar). So /dir1/bar is allowed
///
/// \return dirs_t filled with excluded dirs
dirs_t const& excludeDirs() const;
/// \brief get FX jobs allowed dirs
///
/// reads the fx jobs allowed dirs files generated by fragent
/// when an fx job runs
///
/// \return bool true: success, false: failed
bool getFxAllowedDirs(dirs_t& dirs);
std::string id() const;
/// \brief get the non-ssl ip address to listen on
std::string ipAddress() const;
/// \brief get the non-ssl port to listen on
std::string port() const;
/// \brief get the ssl port to listen on
std::string sslPort() const;
/// \brief get the user name that is allowed to login
std::string login() const;
/// \brief get the users password to be used for login
std::string password() const;
/// \brief get if RCM PS has been first time configured
bool isRcmPSFirstTimeConfigured() const;
/// \brief get cs ip address
std::string csIpAddress() const;
std::string csPort() const;
std::string csSslPort() const;
std::string csUrl() const;
std::string cfsLocalName() const;
/// \brief get server cert passphrase
std::string keyFilePassphrase() const;
/// \brief get the certificate file for ssl connections
boost::filesystem::path certificateFile() const;
/// \brief get the key file for ssl connections
boost::filesystem::path keyFile() const;
/// \brief get the diffie-hillman file for ssl connections
boost::filesystem::path diffieHillmanFile() const;
/// \brief get the server fingerprint
std::string fingerprint() const;
/// \brief get the cs client file used for cs ssl connections
boost::filesystem::path csCertFile() const;
/// \brief get the install dir
boost::filesystem::path installDir() const;
/// \brief get the default dir that should be used for requests
boost::filesystem::path requestDefaultDir() const;
/// \brief get fx allowed dirs path
boost::filesystem::path fxAllowedDirsPath() const;
/// \brief get the error log file name
boost::filesystem::path errorLogFile() const;
/// \brief get the transfer log file name
boost::filesystem::path xferLogFile() const;
/// \brief get the monitor log file name
boost::filesystem::path monitorLogFile() const;
/// \brief get the error log file name
boost::filesystem::path cfsCacheFile() const;
/// \brief get remap prefix
remapPrefixFromTo_t remapFullPathPrefix() const;
/// \brief get the maximum threads to create per server for processing requests
int maxThreads() const;
/// \brief get the maximum buffer size to use for reading/writing data from/to the socket
int maxBufferSizeBytes() const;
/// \brief get the send window size to use
int sendWindowSizeBytes() const;
/// \brief get the receive window size to use
int receiveWindowSizeBytes() const;
/// \brief get the seesion time out to use
int sessionTimeoutSeconds() const;
/// \brief get the maximum size an error log should before rotating
int errorLogMaxSizeBytes() const;
/// \brief get the number of error rotate logs to create.
int errorLogRotateCount() const;
/// \brief get the number of bytes to retain in the error log after rotating
int errorLogRetainSizeBytes() const;
/// \brief get the maximum size a transferr log should before rotating
int xferLogMaxSizeBytes() const;
/// \brief get the number of transfer rotate logs to create.
int xferLogRotateCount() const;
/// \brief get the number of bytes to retain in the transfer log after rotating
int xferLogRetainSizeBytes() const;
/// \brief get the maximum size a montior log should before rotating
int monitorLogMaxSizeBytes() const;
/// \brief get the number of monitor rotate logs to create.
int monitorLogRotateCount() const;
/// \brief get the number of bytes to retain in the monitor log after rotating
int monitorLogRetainSizeBytes() const;
/// \brief get initial read size
///
/// \note
/// \li \c this is for debugging only and is hidden conf file option
int initialReadSize() const;
/// \brief get the monitor log level
int monitorLogLevel() const;
/// \brief get the write mode setting
int writeMode() const;
/// \brief get the time in seconds to delay deleting sessions
int delaySessionDeleteSeconds() const;
/// \brief gets the cfs monitor interval
int cfsMonitorIntervalSeconds() const;
/// \brief gets the cfs get connection info interval
int cfsGetConnectInfoIntervalSeconds() const;
/// \brief gets the cfs worker interval time to wait
/// for requests to show up before sending heartbeat
int cfsGetWorkerIntervalSeconds() const;
/// \brief gets the cfs local port to use on windows
int cfsLocalPort() const;
/// \brief gets the cfs login retry count
int cfsLoginRetry() const;
/// \brief gets the cononce duration in seconds this determines
/// how long a cnonce is valid
long cnonceDurationSeconds() const;
/// \brief get the error log warnings log enabled setting
bool errorLogWarningsEnabled() const;
/// \brief get the monitor log enabled setting
bool xferLogEnabled() const;
/// \brief get the monitor log enabled setting
bool monitorLogEnabled() const;
/// \brief get create paths setting
bool createPaths() const;
/// \brief get create paths setting
bool copyOnRenameLinkFailure() const;
/// \brief get if check for embedded http request is enabled
bool checkForEmbeddedRequest() const;
/// \brief get cfs mode
bool cfsMode() const;
/// \brief get cfs mode
bool cfsSecureLogin() const;
/// \brief returns true if non secure cfs request should be rejected otherwise false
bool cfsRejectNonSecureRequests() const;
/// \brief get cs secure
bool csUseSecure() const;
/// \brief debuging option to delay between sending cfs fwd connect requests
bool delayCfsFwdConnect() const;
/// \option to assign half of cxps threads to http
int httpEnabled() const;
/// \brief get inline compression
boost::tribool inlineCompression() const;
/// \brief get recycle handle count
unsigned long recycleHandleCount() const;
/// \brief get interval in seconds before accept loop should be retried on failure
uint64_t acceptRetryIntervalSecs() const;
/// \brief get the cumulative throttle timer timeout
int cumulativeThrottleTimeoutInSec() const;
/// \brief get the cumulative throttle free space threshold in fraction
float cumulativeThrottleUsedSpaceThreshold() const;
/// \brief get the cumulative throttle threshold in bytes
unsigned long long cumulativeThrottleThresholdInBytes() const;
/// \brief should dynamic cumulative throttle be enabled or not
bool enableSizeBasedCumulativeThrottle() const;
/// \brief should the cumulative throttle timer be started or not
bool enableCumulativeThrottle() const;
/// \brief should diff and resync throttle timer be started or not
bool enableDiffAndResyncThrottle() const;
/// \brief get diff-resync throttle timer timeout in seconds
int diffResyncThrottleTimeoutInSec() const;
/// \brief get the diff throttle threshold in bytes
unsigned long long diffThrottleThresholdInBytes() const;
/// \brief get resync throttle threshold in bytes
unsigned long long resyncThrottleThresholdInBytes() const;
/// \brief get default throttle threshold in bytes
unsigned long long defaultThrottleThresholdInBytes() const;
/// \brief get cache expiry time for diff and resync throttle, the time after which cache should be invalidated
int diffResyncThrottleCacheExpiryIntervalInSec() const;
/// \brief get pruning interval for unprotected pairs, the time after which unprotected pairs must be dropped from cache
int nonProtectedPairPruneTimeoutInSec() const;
/// \brief get interval in seconds to poll the cached PS settings
uint64_t psSettingsPollIntervalSecs() const;
/// \brief does cached settings file contain the header in the
/// first line or not?
bool psSettingsIncludesHeader() const;
/// \brief should enforce strict major version checking (should
/// be same as supported by code) in parsing the cached setting file?
bool psSettingsEnforceMajorVersionCheck() const;
/// \brief should enforce strict minor version checking (should
/// be same as supported by code) in parsing the cached setting file?
/// Valid, only if psSettingsEnforceMajorVersionCheck() is true.
bool psSettingsEnforceMinorVersionCheck() const;
/// \brief should verify the header against conent of the cached
/// setting file with Checksum validation, etc.
bool psSettingsVerifyHeader() const;
/// \brief get the CA cert thumbprint
std::string getCaCertThumbprint() const;
/// \brief check if the client auth is based on CA cert
bool useCertBasedClientAuth() const;
/// \brief get biosid to hostid map from pssettings
void getAllowedDirsMapFromPSSettings(bool& isAccessControlEnabled,
biosIdHostIdMap_t& biosIdHostIdMap,
hostIdDirMap_t& hostIdLogRootFolderMap,
hostIdDirMap_t& hostIdTelemetryFolderMap);
/// \brief get the agent repository path
std::string getAgentRepositoryPath() const;
protected:
/// \brief build the list of allowed dirs
void buildAllowedDirs(boost::filesystem::path const& requestDir);
/// \brief build the list of exclude dirsk
void buildExcludeDirs();
/// \brief add a conf file option to m_options
///
/// \param line holds a line from the configuration file
void addOption(std::string line);
/// \brief gets the requested int option
///
/// \return
/// \li \c int holding the option value
/// \exception ERROR_EXCEPTION on error or if option required but not found
template <typename T>
T getOption(char const* option, ///< option to get
bool required, ///< indicates if the option is required ture: yes false: no
T defaultValue ///< default value to use if option not found
) const;
/// \brief get the requested bool option
///
/// \return
/// \li \c bool holding the option value
/// \exception ERROR_EXCEPTION on error or if option required but not found
bool getOption(char const* option, ///< option to get
bool required, ///< indicates if the option is required ture: yes false: no
bool defaultValue ///< default value to use if option not found
) const;
/// \brief get the requested string option
///
/// \return
/// \li \c string value of the option
/// \exception ERROR_EXCEPTION on error or if option required but not found
std::string getOption(char const* option, ///< option to get
bool required, ///< indicates if the option is required ture: yes false: no
std::string const& defaultValue ///< default value to use if option not found
) const;
/// \brief get the requested path option
///
/// \return
/// \li \c path holding option value
/// \exception ERROR_EXCEPTION on error or if option required but not found
boost::filesystem::path getOption(char const* option, ///< option to get
bool required, ///< indicates if the option is required ture: yes false: no
boost::filesystem::path const& defaultValue ///< default value to use if option not found
) const;
/// \brief gets the passphrase
///
/// if the str begins with exec: then it is a program that should be executed
/// that will return the passphrase, otherwise str is the passphrase
///
/// \return strd::string that holds the passphrase
std::string getKeyFilePassphrase(std::string const& str) const; ///< holds either passphrase or program to execute that will return passphrase
private:
tagValue_t m_options; ///< options from conf file
boost::filesystem::path m_defaultDir; ///< default dir to prepend to relative paths
ServerOptions::dirs_t m_allowedDirs;
ServerOptions::dirs_t m_excludeDirs;
PSSettings::PSSettingsConfigurator::SubscriptionNum_t m_tunablesNotifSubscriptionNum;
PSSettings::StringMapPtr m_tunablesPtr;
std::string m_agentRepositoryPath;
void updateTunables(PSSettings::StringMapPtr latestTunables);
bool getOption(char const* option, std::string &value) const;
void setIdFromPsConfig();
};
typedef boost::shared_ptr<ServerOptions> serverOptionsPtr;
#endif // SERVEROPTIONS_H