tripwire-open-source/src/tw/twutil.h

257 lines
13 KiB
C++

//
// The developer of the original code and/or files is Tripwire, Inc.
// Portions created by Tripwire, Inc. are copyright (C) 2000-2017 Tripwire,
// Inc. Tripwire is a registered trademark of Tripwire, Inc. All rights
// reserved.
//
// This program is free software. The contents of this file are subject
// to the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version. You may redistribute it and/or modify it
// only in compliance with the GNU General Public License.
//
// This program is distributed in the hope that it will be useful.
// However, this program is distributed AS-IS WITHOUT ANY
// WARRANTY; INCLUDING THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS
// FOR A PARTICULAR PURPOSE. Please see the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
//
// Nothing in the GNU General Public License or any other license to use
// the code or files shall permit you to use Tripwire's trademarks,
// service marks, or other intellectual property without Tripwire's
// prior written consent.
//
// If you have any questions, please contact Tripwire, Inc. at either
// info@tripwire.org or www.tripwire.org.
//
///////////////////////////////////////////////////////////////////////////////
// twutil.h
//
// cTWUtil -- top-level utility functions that can be shared between multiple
// executables
#ifndef __TWUTIL_H
#define __TWUTIL_H
#ifndef __TYPES_H
#include "core/types.h"
#endif
#ifndef __TCHAR_H
#include "core/tchar.h"
#endif
#ifndef __WCHAR16_H
#include "core/wchar16.h"
#endif
#ifndef __ERROR_H
#include "core/error.h"
#endif
#ifndef __FCOGENRE_H
#include "fco/fcogenre.h"
#endif
class cFCOReport;
class cElGamalSigPrivateKey;
class cElGamalSigPublicKey;
class cKeyFile;
class cPrivateKeyProxy;
class cFCOSpecList;
class cConfigFile;
class cCmdLineParser;
class cErrorBucket;
class cFileHeaderID;
class eError;
class cFCODbHeader;
class cFCOReportHeader;
class cFCOName;
class cFCODatabaseFile;
class cArchive;
class cMemoryArchive;
TSS_EXCEPTION( eTWUtil, eError )
TSS_EXCEPTION( eTWUtilNotFullPath, eTWUtil )
TSS_EXCEPTION( eTWUtilCfgKeyMismatch, eTWUtil )
TSS_EXCEPTION( eTWUtilCorruptedFile, eTWUtil )
TSS_EXCEPTION( eTWUtilBadPassLocal, eTWUtil )
TSS_EXCEPTION( eTWUtilBadPassSite, eTWUtil )
TSS_EXCEPTION( eTWUtilEchoModeSet, eTWUtil )
TSS_EXCEPTION( eTWUtilDbDoesntHaveGenre,eTWUtil )
TSS_EXCEPTION( eTWUtilPolUnencrypted, eTWUtil )
TSS_EXCEPTION( eTWUtilObjNotInDb, eTWUtil )
class cTWUtil
{
public:
//-------------------------------------------------------------------------
// Reading and Writing tripwire file objects (database, report, config
// and policy files).
//-------------------------------------------------------------------------
static void WriteDatabase(const TCHAR* filename, cFCODatabaseFile& db, bool bEncrypt, const cElGamalSigPrivateKey* pPrivateKey); // throw eError
// writes a database to disk. If an error occurs, a message is spit to stderr and an eError is thrown.
// if bEncrypt is false, then the key pointer may be false, otherwise, it must be non-null
static void ReadDatabase(const TCHAR* filename, cFCODatabaseFile& db, const cElGamalSigPublicKey* pPublicKey, bool& bEncrypted); // throw (eError);
// reads a database from disk. If the db is encrypted, then it will load the named key file into keyFile and
// set bEncrypted to true; otherwise keyFile is not modified and bEncrypted is set to false.
// if keyFile is already open, then the currently loaded keys are used and keyFileName is ignored.
// if an error occurs, this will print the error message to stderr and throw eError.
static void WriteReport (const TCHAR* filename, const cFCOReportHeader& reportHeader, const cFCOReport& r, bool bEncrypt, const cElGamalSigPrivateKey* pPrivateKey); // throw eError
static void ReadReport (const TCHAR* reportFileName, cFCOReportHeader& reportHeader, cFCOReport& r, const cElGamalSigPublicKey* pPublicKey, bool silent, bool& bEncrypted); // throw eError
// same as Read/WriteDatabase above, except it operates on reports
// if an error occurs, this will print the error message to stderr and throw eError.
static void WriteConfigText(const TCHAR* filename, const TSTRING configText, bool bEncrypt, const cElGamalSigPrivateKey* pPrivateKey); // throw (eArchive())
static void ReadConfigText(const TCHAR* filename, TSTRING& configText, cArchive* pBaggage = 0);
// read and write config file text to and from disk.
// if pBaggage is non-NULL, the contents of the baggage( ie -- the public key ) is copied to the archive.
// eArchive is thrown if filename can not be opened
// eSerializer is thrown if reading or writing fails
// eConfigFile is thrown if config file does not parse correctly during reading
static void WritePolicyText(const TCHAR* filename, const std::string& policyText, bool bEncrypt, const cElGamalSigPrivateKey* pPrivateKey);
static void ReadPolicyText(const TCHAR* filename, std::string& policyText, const cElGamalSigPublicKey* pPublicKey);
// read and write policy file to and from disk
// eError() will be thrown on error
//-------------------------------------------------------------------------
// Higher level manipulation of Tripwire file objects
//-------------------------------------------------------------------------
static TSTRING GetCfgFilePath(const cCmdLineParser& cmdLine, int cfgFileID);
// Get's the path of the config file, either from the commandline, or from
// the default location.
static void OpenConfigFile(cConfigFile& cf, cCmdLineParser& cmdLine, int cfgFileID, cErrorBucket& errorBucket, TSTRING& configFileOut );
// opens the config file, either from a known location or
// from the location specified on the command line. Returns false if it fails
// reads config info into cf
// cfgFileID is the ID of the config file that cCmdLineParser::ArgId() will know about
// if pBaggage is non-NULL, the contents of the baggage( ie -- the public key ) is copied to the archive.
// errors will be reported to errorBucket
// configFileOut returns actual config file used
// returns false on failure
static void UpdatePolicyFile(const TCHAR* destFileName, const TCHAR* srcFileName, bool bEncrypt, const cElGamalSigPrivateKey* pPrivateKey); // throw eError
// saves the plain text policy file pointed at by srcFileName encrypted with pPrivateKey in destFileName
// if an error occurs an exception suitable for printing with
//-------------------------------------------------------------------------
// key manipulation utilities
//-------------------------------------------------------------------------
static bool VerifyCfgSiteKey( const TSTRING& mstrConfigFile, const TSTRING& siteKeyPath ); //throw (eTWUtil)
// This method verifies that either the config file is unencrypted or the public key in the
// config file mstrConfigFile matches the public key contained in the file specified by siteKeyPath.
// Returns true if the keys match or false if the config file is unencrypted.
// Throws eTWUtil if the config file is encrypted but does not match the site key.
// Throws eError if the site keyfile can not be opened.
static void GetString(wc16_string& ret);
static void GetStringNoEcho(wc16_string& ret);
// This takes an input string from the user with or without displaying it on the screen.
// To use passphrazes compatible between Unicode and non-Unicode, we return the most portable
// type of string, the wide string.
// This simply calls GetString in the scope of a NoEcho object.
class NoEcho {
public:
NoEcho();
~NoEcho();
};
// For the lifetime of a cTWUtil::NoEcho object,
// tty echoing on standard input is disabled.
// At construction time, pending input is discarded.
// In order to be friendly to programs like expect,
// whose scripts typically supply input immediately after
// prompting, such prompting should happen after NoEcho
// construction to ensure that such input is not discarded.
static void OpenKeyFile(cKeyFile& keyFile, TSTRING fileName); // throw (eError)
// this opens the passed in keyfile and associates it with keyFile.
// If an error occurs an exception is thrown with appropriate information.
enum KeyType { KEY_SITE, KEY_LOCAL, KEY_PROVIDED };
enum SleepPeriodInSecs{ SLEEP_DEFAULT = 2 };
static const cElGamalSigPrivateKey* CreatePrivateKey(cKeyFile& keyFile, const WCHAR16* usePassphrase, KeyType keyType, int nSecs = SLEEP_DEFAULT );
static void CreatePrivateKey(cPrivateKeyProxy& proxy, cKeyFile& keyFile, const WCHAR16* usePassphrase, KeyType keyType, int nSecs = SLEEP_DEFAULT );
// This will attempt to create the private key from the given key file using the given password.
// If usePassphrase is NULL then the user will be promtped to enter the passphrase.
// If usePassphrase is non-NULL, then it will be used to attempt to opent the private
// key. If this is the wrong password, an error message will be printed and an exception thrown.
// The keyfile must already be open (using OpenKeyFile above).
// The key must be freed using cKeyFile::ReleasePrivateKey().
// keyType is just used so that an appropriate string can be displayed to the user
// nSecs is the number of to wait before showing user if password was correct. hinders brute
// force (dictionary, etc.) attacks. defaults to 2 seconds.
// NOTE: An eError() exception with an appropriate error message will be thrown on failure.
// TODO: Try to use the second version as we will want to upgrade to this some day - dmb
//-------------------------------------------------------------------------
// Command Line
//-------------------------------------------------------------------------
typedef std::vector<TSTRING> ObjList;
typedef std::pair<cGenre::Genre, ObjList> GenreObjs;
typedef std::vector<GenreObjs> GenreObjList;
static void ParseObjectList( GenreObjList& listOut, const ObjList& listIn ); // throw eError()
// takes a list of strings (listIn) and turns them into a collection of <genre, object list> pairs.
// This is used while integrity checking or printing a set of FCOs. This takes the form: [genre|objName]+
// where each object is associated with the most recently mentioned genre. If an object appears
// before any genre identifiers, it is assumed to be in FS on unix or NTFS on NT.
// eError will be thrown if an unknown genre is encountered
static cFCOName ParseObjectName( const TSTRING& fcoName ); // throw (eError)
// converts a string representation of an FCO name (that was passed in on the command line for integrity
// check or database printing) into a cFCOName. It is assumed that the name is for an object in the current
// genre. If the string cannot be converted (ie -- relative path or invalid formatting), eError is thrown.
//-------------------------------------------------------------------------
// Database and report header helpers
//-------------------------------------------------------------------------
// These are all used for filling out HeaderInfo structures
static TSTRING GetSystemName();
static TSTRING GetIPAddress();
static TSTRING GetCurrentUser();
static TSTRING GetHostID();
//-------------------------------------------------------------------------
// Micellaneous
//-------------------------------------------------------------------------
static bool IsObjectEncrypted( const TCHAR* objFileName, const cFileHeaderID& fhid, const TSTRING& errorMsg );
static bool IsObjectEncrypted( cArchive &arch, const cFileHeaderID& fhid, const TSTRING& errorMsg );
// Tests an object serialized to objFileName to see if it's encrypted. fhid ensures that the object in the
// file is of the correct type.
// If an error occurs while reading the file, this WILL PRINT an error message errorMsg,
// then it will throw eError(NULL).
static void PrintErrorMsg(const eError& e, const TSTRING& strExtra = _T(""));
// nicely displays the contents of the exception to stderr.
// currently, it has the format:
// ### Error e.GetErrorNum(): e.GetMsg() : cErrorTable::GetErrorString(e.GetErrorNum())
static bool ConfirmYN(const TCHAR* prompt);
// prompt the user with given string and wait for a 'Y' or 'N' response.
// returns true if 'Y' entered.
};
#endif //__TWUTIL_H