tripwire-open-source/src/twadmin/twadmincl.cpp

2697 lines
96 KiB
C++

//
// The developer of the original code and/or files is Tripwire, Inc.
// Portions created by Tripwire, Inc. are copyright (C) 2000 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.
//
///////////////////////////////////////////////////////////////////////////////
// twadmincl.cpp -- command line parsing for twadmin
//
#include "stdtwadmin.h"
#include <unistd.h>
#include "twadmincl.h"
#include "twadminstrings.h"
#include "keygeneration.h"
#include "core/errorgeneral.h"
#include "core/errorbucketimpl.h" // needed for the error table
#include "core/archive.h"
#include "core/usernotify.h"
#include "core/cmdlineparser.h"
#include "core/usernotify.h"
#include "fco/fconame.h"
#include "tw/configfile.h"
#include "tw/twutil.h"
#include "tw/filemanipulator.h"
#include "tw/fcodatabasefile.h"
#include "tw/fcoreport.h"
#include "tw/policyfile.h"
#include "tw/systeminfo.h"
#include "tw/twerrors.h"
#include "tw/twstrings.h"
#include "twparser/policyparser.h"
#include "twcrypto/keyfile.h"
#include "core/stringutil.h"
#include "util/fileutil.h"
#include "twcrypto/crypto.h"
#include "core/displayencoder.h"
//Provide a swab() impl. from glibc, for platforms that don't have one
#if defined(__SYLLABLE__) || defined(__ANDROID_API__)
void swab (const void *bfrom, void *bto, ssize_t n)
{
const char *from = (const char *) bfrom;
char *to = (char *) bto;
n &= ~((ssize_t) 1);
while (n > 1)
{
const char b0 = from[--n], b1 = from[--n];
to[n] = b0;
to[n + 1] = b1;
}
}
#endif
// forwards
static bool NotifyFileType(const cFileHeaderID& id, uint32 version, iUserNotify::VerboseLevel vl);
// Calls UserNotify(V_VERBOSE, ...) to print out type of file specified in cFileHeaderID.
// Returns false if cFileHeaderID not recognized.
// Used in changing and removing encryption algorithms
static bool NotifyEncryptionType(cFileHeader::Encoding encoding, iUserNotify::VerboseLevel vl);
// Calls UserNotify(V_VERBOSE, ...) to print out type of file specified in cFileHeaderID.
// Returns false if encoding not recognized.
// Used in changing and removing encryption algorithms
// error implementations
eTWACreateCfgMissingSitekey::eTWACreateCfgMissingSitekey( const TSTRING& msg, uint32 flags )
: eTWA( TSTRING(), flags )
{
mMsg = TSS_GetString(cTWAdmin, twadmin::STR_ERR2_CREATE_CFG_MISSING_KEYFILE) + msg;
}
eTWACreateCfgSitekeyMismatch::eTWACreateCfgSitekeyMismatch( const TSTRING& specifiedKeyfile, const TSTRING& configKeyfile, uint32 flags )
: eTWA( TSTRING(), flags )
{
mMsg = TSS_GetString(cTWAdmin, twadmin::STR_ERR2_CREATE_CFG_SITEKEY_MISMATCH1);
mMsg.append(specifiedKeyfile);
mMsg.append(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_CREATE_CFG_SITEKEY_MISMATCH2));
mMsg.append(configKeyfile);
mMsg.append(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_CREATE_CFG_SITEKEY_MISMATCH3));
}
///////////////////////////////////////////////////////////////////////////////
// cTWAModeCommon -- common modes that all iTWAMode implementations will
// derive from.
class cTWAModeCommon : public iTWAMode
{
protected:
int mVerbosity; // must be 0 <= n <= 2
TSTRING mPolFile;
TSTRING mSiteKeyFile;
bool mSiteKeyFileProvieded;
TSTRING mLocalKeyFile;
bool mLocalKeyFileProvieded;
bool mLatePassphrase;
cTWAModeCommon() : mVerbosity(1), mSiteKeyFileProvieded(false), mLocalKeyFileProvieded(false), mLatePassphrase(false) {}
void InitCmdLineCommon(cCmdLineParser& parser);
void FillOutConfigInfo(const cConfigFile* cf);
void FillOutCmdLineInfo(const cCmdLineParser& parser);
};
///////////////////////////////////////////////////////////////////////////////
// InitCmdLineCommon -- initializes the command line switches common to all
// modes
void cTWAModeCommon::InitCmdLineCommon(cCmdLineParser& parser)
{
parser.AddArg(cTWAdminCmdLine::HELP, TSTRING(_T("?")), TSTRING(_T("help")), cCmdLineParser::PARAM_NONE);
parser.AddArg(cTWAdminCmdLine::MODE, TSTRING(_T("m")), TSTRING(_T("")), cCmdLineParser::PARAM_ONE);
parser.AddArg(cTWAdminCmdLine::VERBOSE, TSTRING(_T("v")), TSTRING(_T("verbose")), cCmdLineParser::PARAM_NONE);
parser.AddArg(cTWAdminCmdLine::SILENT, TSTRING(_T("s")), TSTRING(_T("silent")), cCmdLineParser::PARAM_NONE);
parser.AddArg(cTWAdminCmdLine::SILENT, TSTRING(_T("")), TSTRING(_T("quiet")), cCmdLineParser::PARAM_NONE);
parser.AddArg(cTWAdminCmdLine::CFG_FILE, TSTRING(_T("c")), TSTRING(_T("cfgfile")), cCmdLineParser::PARAM_ONE);
parser.AddArg(cTWAdminCmdLine::POL_FILE, TSTRING(_T("p")), TSTRING(_T("polfile")), cCmdLineParser::PARAM_ONE);
parser.AddMutEx(cTWAdminCmdLine::VERBOSE, cTWAdminCmdLine::SILENT);
}
///////////////////////////////////////////////////////////////////////////////
// FillOutConfigInfo -- fills out all the common info with config file information
///////////////////////////////////////////////////////////////////////////////
void cTWAModeCommon::FillOutConfigInfo(const cConfigFile* cf)
{
if (cf == 0)
return;
TSTRING str;
if(cf->Lookup(TSTRING(_T("POLFILE")), str))
mPolFile = str;
if(cf->Lookup(TSTRING(_T("SITEKEYFILE")), str))
mSiteKeyFile = str;
if(cf->Lookup(TSTRING(_T("LOCALKEYFILE")), str))
mLocalKeyFile = str;
if(cf->Lookup(TSTRING(_T("LATEPROMPTING")), str))
{
if (_tcsicmp(str.c_str(), _T("true")) == 0)
mLatePassphrase = true;
}
//
// turn all of the file names into full paths (they're relative to the exe dir)
//
TSTRING fullPath;
if(!mPolFile.empty() && iFSServices::GetInstance()->FullPath( fullPath, mPolFile, cSystemInfo::GetExeDir() ))
mPolFile = fullPath;
if(!mSiteKeyFile.empty() && iFSServices::GetInstance()->FullPath( fullPath, mSiteKeyFile, cSystemInfo::GetExeDir() ))
mSiteKeyFile = fullPath;
if(!mLocalKeyFile.empty() && iFSServices::GetInstance()->FullPath( fullPath, mLocalKeyFile, cSystemInfo::GetExeDir() ))
mLocalKeyFile = fullPath;
}
///////////////////////////////////////////////////////////////////////////////
// FillOutCmdLineInfo -- fills out info common to all modes that appears on the
// command line.
///////////////////////////////////////////////////////////////////////////////
void cTWAModeCommon::FillOutCmdLineInfo(const cCmdLineParser& parser)
{
cCmdLineIter iter(parser);
for(iter.SeekBegin(); ! iter.Done(); iter.Next())
{
switch(iter.ArgId())
{
case cTWAdminCmdLine::VERBOSE:
mVerbosity = 2;
break;
case cTWAdminCmdLine::SILENT:
mVerbosity = 0;
break;
case cTWAdminCmdLine::POL_FILE:
ASSERT(iter.NumParams() > 0); // should be caught by cmd line parser
mPolFile = iter.ParamAt(0);
break;
case cTWAdminCmdLine::SITE_KEY_FILE:
ASSERT(iter.NumParams() > 0); // should be caught by cmd line parser
mSiteKeyFile = iter.ParamAt(0);
mSiteKeyFileProvieded = true;
break;
case cTWAdminCmdLine::LOCAL_KEY_FILE:
ASSERT(iter.NumParams() > 0); // should be caught by cmd line parser
mLocalKeyFile = iter.ParamAt(0);
mLocalKeyFileProvieded = true;
break;
}
}
// Turn all of the file names into full paths for nice presentation to the user.
// Note: We depend later on the if one of these files is not specified, the string
// is empty. Currently FullPath() expands "" to the CWD.
TSTRING fullPath;
if(!mPolFile.empty() && iFSServices::GetInstance()->FullPath(fullPath, mPolFile))
mPolFile = fullPath;
if(!mSiteKeyFile.empty() && iFSServices::GetInstance()->FullPath(fullPath, mSiteKeyFile))
mSiteKeyFile = fullPath;
if(!mLocalKeyFile.empty() && iFSServices::GetInstance()->FullPath(fullPath, mLocalKeyFile))
mLocalKeyFile = fullPath;
// use the verbosity information
ASSERT((mVerbosity >= 0) && (mVerbosity < 3));
iUserNotify::GetInstance()->SetVerboseLevel(mVerbosity);
}
///////////////////////////////////////////////////////////////////////////////
// TWAdmin modes
//
// No one else should need to see these classes, so we will keep them
// localized to this file.
//
///////////////////////////////////////////////////////////////////////////////
// cTWAModeCreateCfg
class cTWAModeCreateCfg : public cTWAModeCommon
{
public:
cTWAModeCreateCfg();
virtual ~cTWAModeCreateCfg();
virtual void InitCmdLineParser(cCmdLineParser& parser);
virtual bool Init (const cConfigFile* cf, const cCmdLineParser& parser);
virtual int Execute (cErrorQueue* pQueue);
virtual TSTRING GetModeUsage() { return TSS_GetString( cTWAdmin, twadmin::STR_TWADMIN_HELP_CREATE_CFGFILE ); }
virtual bool LoadConfigFile() { return true; }
virtual cTWAdminCmdLine::CmdLineArgs GetModeID() const { return cTWAdminCmdLine::MODE_CREATE_CONFIG; }
private:
TSTRING mPlaintextConfig;
TSTRING mEncryptedConfig;
wc16_string mPassPhrase; // pass phrase for private key
bool mPassPhraseProvided;
bool mNoEncryption;
};
cTWAModeCreateCfg::cTWAModeCreateCfg()
{
mNoEncryption = false;
mPassPhraseProvided = false;
}
cTWAModeCreateCfg::~cTWAModeCreateCfg()
{
}
void cTWAModeCreateCfg::InitCmdLineParser(cCmdLineParser& parser)
{
InitCmdLineCommon(parser);
parser.AddArg(cTWAdminCmdLine::MODE_CREATE_CONFIG, TSTRING(_T("")), TSTRING(_T("create-cfgfile")), cCmdLineParser::PARAM_NONE);
parser.AddArg(cTWAdminCmdLine::PASSPHRASE, TSTRING(_T("Q")), TSTRING(_T("site-passphrase")), cCmdLineParser::PARAM_ONE);
parser.AddArg(cTWAdminCmdLine::SITE_KEY_FILE, TSTRING(_T("S")), TSTRING(_T("site-keyfile")), cCmdLineParser::PARAM_ONE);
parser.AddArg(cTWAdminCmdLine::NO_ENCRYPTION, TSTRING(_T("e")), TSTRING(_T("no-encryption")), cCmdLineParser::PARAM_NONE);
parser.AddArg(cTWAdminCmdLine::PARAMS, TSTRING(_T("")), TSTRING(_T("")), cCmdLineParser::PARAM_ONE);
parser.AddMutEx(cTWAdminCmdLine::NO_ENCRYPTION, cTWAdminCmdLine::SITE_KEY_FILE);
parser.AddMutEx(cTWAdminCmdLine::NO_ENCRYPTION, cTWAdminCmdLine::PASSPHRASE);
}
bool cTWAModeCreateCfg::Init(const cConfigFile* cf, const cCmdLineParser& parser)
{
TSTRING str;
FillOutConfigInfo(cf);
FillOutCmdLineInfo(parser);
bool fConfigOnCmdLine = false;
cCmdLineIter iter(parser);
for(iter.SeekBegin(); ! iter.Done(); iter.Next())
{
switch(iter.ArgId())
{
case cTWAdminCmdLine::NO_ENCRYPTION:
mNoEncryption = true;
break;
case cTWAdminCmdLine::PASSPHRASE:
{
ASSERT(iter.NumParams() > 0); // should be caught by cmd line parser
mPassPhrase = cStringUtil::TstrToWstr(iter.ParamAt(0));
mPassPhraseProvided = true;
}
break;
case cTWAdminCmdLine::CFG_FILE:
if (iter.NumParams() < 1)
{
cTWUtil::PrintErrorMsg(eBadCmdLine(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_NO_CONFIG)));
return false;
}
mEncryptedConfig = iter.ParamAt(0);
fConfigOnCmdLine = true;
break;
case cTWAdminCmdLine::PARAMS:
ASSERT(iter.NumParams() == 1);
mPlaintextConfig = iter.ParamAt(0);
break;
}
}
// get full path to files
TSTRING strFullPath;
if( iFSServices::GetInstance()->FullPath( strFullPath, mPlaintextConfig ) )
mPlaintextConfig = strFullPath;
// OK, now we need to figure out where to put the new config file.
// If the location was specified on the command line, get the full path to it.
// otherwise, the location is the dir that this exe is in.
if( fConfigOnCmdLine )
{
TSTRING strFullPath;
if( iFSServices::GetInstance()->FullPath( strFullPath, mEncryptedConfig ) )
mEncryptedConfig = strFullPath;
}
else
{
iFSServices::GetInstance()->FullPath( mEncryptedConfig, TSS_GetString(cTW, tw::STR_DEF_CFG_FILENAME ),
cSystemInfo::GetExeDir() ) ;
}
return true;
}
int cTWAModeCreateCfg::Execute(cErrorQueue* pQueue)
{
if (mPlaintextConfig.empty())
{
cTWUtil::PrintErrorMsg(eBadCmdLine(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_NO_PT_CONFIG)));
return 1;
}
if (mEncryptedConfig.empty())
{
cTWUtil::PrintErrorMsg(eBadCmdLine(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_NO_CONFIG)));
return 1;
}
if (mSiteKeyFile.empty() && !mNoEncryption)
{
cTWUtil::PrintErrorMsg(eBadCmdLine(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_SITE_KEY_NOENCRYPT_NOT_SPECIFIED)));
return 1;
}
iUserNotify::GetInstance()->Notify(iUserNotify::V_VERBOSE,
TSS_GetString(cTWAdmin, twadmin::STR_UPCONFIG_VERBOSE_PT_CONFIG).c_str(),
cDisplayEncoder::EncodeInline( mPlaintextConfig ).c_str());
cFileArchive arch;
arch.OpenRead(mPlaintextConfig.c_str(), cFileArchive::FA_OPEN_TEXT); // Note: eArchive may be thrown
// read in config text
std::string narrowPlaintext;
narrowPlaintext.resize(arch.Length());
// NOTE: archive may write fewer than arch.Length() bytes since
// it is converting CR/LF to CR.
int cbRead = arch.ReadBlob((void*)narrowPlaintext.data(), arch.Length());
narrowPlaintext.resize( cbRead ); // may have garbage after plaintext[cbRead] due to text mode conversion
TSTRING plaintext = cStringUtil::StrToTstr(narrowPlaintext);
// Try reading it to see if there are any problems.
// Also open the keyfile so we can verify the keyfile specified in the plaintext
// matches the key we intend to encrypt the config file with.
cKeyFile plaintextKeyFile;
TSTRING plaintextKeyFileName;
bool plaintextKeyFileLoaded = false;
try
{
cConfigFile cf;
cf.ReadString(plaintext);
if ( (plaintextKeyFileLoaded = cf.Lookup(_T("SITEKEYFILE"), plaintextKeyFileName)) == true &&
(plaintextKeyFileLoaded = !plaintextKeyFileName.empty()) == true
)
{
TSTRING fullPath;
if (iFSServices::GetInstance()->FullPath( fullPath, plaintextKeyFileName, cSystemInfo::GetExeDir() ))
plaintextKeyFileName = fullPath;
cTWUtil::OpenKeyFile(plaintextKeyFile, plaintextKeyFileName);
plaintextKeyFileLoaded = true;
}
}
catch (eConfigFile& e)
{
pQueue->AddError( e );
return 1;
}
cKeyFile specifiedKeyFile;
const cElGamalSigPrivateKey* pPrivateKey;
if (!mNoEncryption)
{
cTWUtil::OpenKeyFile(specifiedKeyFile, mSiteKeyFile);
if (!plaintextKeyFileLoaded)
{
// User wishes to create a config file using a key, but has not specified the key in the config file.
// For safty and sanity reasons we do not let them do this.
pQueue->AddError( eTWACreateCfgMissingSitekey(TSTRING()) );
return false;
}
else if (!specifiedKeyFile.GetPublicKey()->IsEqual(*plaintextKeyFile.GetPublicKey()))
{
// The site key specified in this config file does not match the sitekey they are encrypting the
// config file with. This is likely to lead to problems so we try to catch it here.
pQueue->AddError( eTWACreateCfgSitekeyMismatch(mSiteKeyFile, plaintextKeyFileName) );
return false;
}
pPrivateKey = cTWUtil::CreatePrivateKey(specifiedKeyFile, mPassPhraseProvided ? mPassPhrase.c_str() : NULL, cTWUtil::KEY_SITE);
}
else
pPrivateKey = 0;
// Make sure we can create the file
cFileUtil::TestFileWritable(mEncryptedConfig);
// backup current file if it exists
cFileUtil::BackupFile(mEncryptedConfig);
if (!mNoEncryption)
{
cTWUtil::WriteConfigText(mEncryptedConfig.c_str(), plaintext, true, pPrivateKey);
specifiedKeyFile.ReleasePrivateKey();
}
else
cTWUtil::WriteConfigText(mEncryptedConfig.c_str(), plaintext, false, 0);
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// cTWAModeCreatePol
class cTWAModeCreatePol : public cTWAModeCommon
{
public:
cTWAModeCreatePol();
virtual ~cTWAModeCreatePol();
virtual void InitCmdLineParser(cCmdLineParser& parser);
virtual bool Init (const cConfigFile* cf, const cCmdLineParser& parser);
virtual int Execute (cErrorQueue* pQueue);
virtual TSTRING GetModeUsage() { return TSS_GetString( cTWAdmin, twadmin::STR_TWADMIN_HELP_CREATE_POLFILE ); }
virtual bool LoadConfigFile() { return true; }
virtual cTWAdminCmdLine::CmdLineArgs GetModeID() const { return cTWAdminCmdLine::MODE_CREATE_POLICY; }
private:
TSTRING mPlaintextPolicy;
wc16_string mPassPhrase; // pass phrase for private key
bool mPassPhraseProvided;
bool mNoEncryption;
};
cTWAModeCreatePol::cTWAModeCreatePol()
{
mNoEncryption = false;
mPassPhraseProvided = false;
}
cTWAModeCreatePol::~cTWAModeCreatePol()
{
}
void cTWAModeCreatePol::InitCmdLineParser(cCmdLineParser& parser)
{
InitCmdLineCommon(parser);
parser.AddArg(cTWAdminCmdLine::MODE_CREATE_POLICY, TSTRING(_T("")), TSTRING(_T("create-polfile")), cCmdLineParser::PARAM_NONE);
parser.AddArg(cTWAdminCmdLine::PASSPHRASE, TSTRING(_T("Q")), TSTRING(_T("site-passphrase")), cCmdLineParser::PARAM_ONE);
parser.AddArg(cTWAdminCmdLine::SITE_KEY_FILE, TSTRING(_T("S")), TSTRING(_T("site-keyfile")), cCmdLineParser::PARAM_ONE);
parser.AddArg(cTWAdminCmdLine::NO_ENCRYPTION, TSTRING(_T("e")), TSTRING(_T("no-encryption")), cCmdLineParser::PARAM_NONE);
parser.AddArg(cTWAdminCmdLine::PARAMS, TSTRING(_T("")), TSTRING(_T("")), cCmdLineParser::PARAM_ONE);
parser.AddMutEx(cTWAdminCmdLine::NO_ENCRYPTION, cTWAdminCmdLine::SITE_KEY_FILE);
parser.AddMutEx(cTWAdminCmdLine::NO_ENCRYPTION, cTWAdminCmdLine::PASSPHRASE);
}
bool cTWAModeCreatePol::Init(const cConfigFile* cf, const cCmdLineParser& parser)
{
TSTRING str;
FillOutConfigInfo(cf);
FillOutCmdLineInfo(parser);
cCmdLineIter iter(parser);
for(iter.SeekBegin(); ! iter.Done(); iter.Next())
{
switch(iter.ArgId())
{
case cTWAdminCmdLine::NO_ENCRYPTION:
mNoEncryption = true;
break;
case cTWAdminCmdLine::PASSPHRASE:
{
ASSERT(iter.NumParams() > 0); // should be caught by cmd line parser
mPassPhrase = cStringUtil::TstrToWstr(iter.ParamAt(0));
mPassPhraseProvided = true;
}
break;
case cTWAdminCmdLine::PARAMS:
ASSERT(iter.NumParams() == 1);
mPlaintextPolicy = iter.ParamAt(0);
break;
}
}
// get full path to files
TSTRING strFullPath;
if( iFSServices::GetInstance()->FullPath( strFullPath, mSiteKeyFile ) )
mSiteKeyFile = strFullPath;
if( iFSServices::GetInstance()->FullPath( strFullPath, mPlaintextPolicy ) )
mPlaintextPolicy = strFullPath;
if (mPlaintextPolicy.empty())
{
cTWUtil::PrintErrorMsg(eBadCmdLine(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_NO_PT_POLICY)));
return false;
}
// check that the config file and site key file are in sync...
//
if( ! mCfgFilePath.empty() )
try
{
if (cTWUtil::VerifyCfgSiteKey( mCfgFilePath, mSiteKeyFile ) == false)
cTWUtil::PrintErrorMsg(eTWCfgUnencrypted(_T(""), eError::NON_FATAL|eError::SUPRESS_THIRD_MSG));
}
catch (eTWUtilCfgKeyMismatch& e)
{
e.SetFatality(false);
cTWUtil::PrintErrorMsg(e);
}
return true;
}
int cTWAModeCreatePol::Execute(cErrorQueue* pQueue)
{
if (mPlaintextPolicy.empty())
{
cTWUtil::PrintErrorMsg(eBadCmdLine(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_NO_PT_POLICY)));
return 1;
}
if (mPolFile.empty())
{
cTWUtil::PrintErrorMsg(eBadCmdLine(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_NO_POLICY)));
return 1;
}
if (mSiteKeyFile.empty() && !mNoEncryption)
{
cTWUtil::PrintErrorMsg(eBadCmdLine(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_SITE_KEY_NOENCRYPT_NOT_SPECIFIED)));
return 1;
}
iUserNotify::GetInstance()->Notify(iUserNotify::V_VERBOSE,
TSS_GetString(cTWAdmin, twadmin::STR_UPCONFIG_VERBOSE_PT_POLICY).c_str(),
cDisplayEncoder::EncodeInline( mPlaintextPolicy ).c_str());
// open policy file as text
cFileArchive arch;
arch.OpenRead(mPlaintextPolicy.c_str(), cFileArchive::FA_OPEN_TEXT); // Note: eArchive may be thrown
// read in policy text
std::string plaintext;
plaintext.resize(arch.Length());
// NOTE: archive may write fewer than arch.Length() bytes since
// it is converting CR/LF to CR.
int cbRead = arch.ReadBlob((void*)plaintext.data(), arch.Length());
plaintext.resize( cbRead ); // may have garbage after plaintext[cbRead] due to text mode conversion
//
// make sure the policy file parses correctly before we update the old one
//
std::istringstream in( plaintext );
cPolicyParser parser( in );
try
{
parser.Check( pQueue );
}
catch(eError& e)
{
cTWUtil::PrintErrorMsg(e);
iUserNotify::GetInstance()->Notify( iUserNotify::V_NORMAL,
TSS_GetString(cTWAdmin, twadmin::STR_POL_NOT_UPDATED).c_str() );
return 1;
}
//
// open the key file...
//
cKeyFile keyfile;
const cElGamalSigPrivateKey* pPrivateKey;
if (!mNoEncryption)
{
cTWUtil::OpenKeyFile(keyfile, mSiteKeyFile);
pPrivateKey = cTWUtil::CreatePrivateKey(keyfile, mPassPhraseProvided ? mPassPhrase.c_str() : NULL, cTWUtil::KEY_SITE);
}
else
pPrivateKey = 0;
// Make sure we can create the file
cFileUtil::TestFileWritable(mPolFile);
// backup current file if it exists
cFileUtil::BackupFile(mPolFile);
if (!mNoEncryption)
{
cTWUtil::WritePolicyText(mPolFile.c_str(), plaintext, true, pPrivateKey);
keyfile.ReleasePrivateKey();
}
else
cTWUtil::WritePolicyText(mPolFile.c_str(), plaintext, false, 0);
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// cTWAModePrintCfg
class cTWAModePrintCfg : public cTWAModeCommon
{
public:
cTWAModePrintCfg();
virtual ~cTWAModePrintCfg();
virtual void InitCmdLineParser(cCmdLineParser& parser);
virtual bool Init (const cConfigFile* cf, const cCmdLineParser& parser);
virtual int Execute (cErrorQueue* pQueue);
virtual TSTRING GetModeUsage() { return TSS_GetString( cTWAdmin, twadmin::STR_TWADMIN_HELP_PRINT_CFGFILE ); }
virtual bool LoadConfigFile() { return true; }
virtual cTWAdminCmdLine::CmdLineArgs GetModeID() const { return cTWAdminCmdLine::MODE_PRINT_CONFIG; }
private:
TSTRING mEncryptedConfig;
};
cTWAModePrintCfg::cTWAModePrintCfg()
{
}
cTWAModePrintCfg::~cTWAModePrintCfg()
{
}
void cTWAModePrintCfg::InitCmdLineParser(cCmdLineParser& parser)
{
InitCmdLineCommon(parser);
parser.AddArg(cTWAdminCmdLine::MODE_PRINT_CONFIG, TSTRING(_T("")), TSTRING(_T("print-cfgfile")), cCmdLineParser::PARAM_NONE);
}
bool cTWAModePrintCfg::Init(const cConfigFile* cf, const cCmdLineParser& parser) //throw(eTWUTil)
{
FillOutConfigInfo(cf);
FillOutCmdLineInfo(parser);
mEncryptedConfig = cTWUtil::GetCfgFilePath(parser, cTWAdminCmdLine::CFG_FILE);
// check that the config file and site key file are in sync...
//
if( ! mCfgFilePath.empty() )
try
{
if (cTWUtil::VerifyCfgSiteKey( mCfgFilePath, mSiteKeyFile ) == false)
cTWUtil::PrintErrorMsg(eTWCfgUnencrypted(_T(""), eError::NON_FATAL|eError::SUPRESS_THIRD_MSG));
}
catch (eTWUtilCfgKeyMismatch& e)
{
e.SetFatality(false);
cTWUtil::PrintErrorMsg(e);
}
return true;
}
int cTWAModePrintCfg::Execute(cErrorQueue* pQueue)
{
try
{
TSTRING configText;
cTWUtil::ReadConfigText(mEncryptedConfig.c_str(), configText);
// Note: I believe print config and print policy are the only time we should
// print to standard out directly.
TCOUT << cDisplayEncoder::EncodeInlineAllowWS( configText );
TCOUT << std::endl;
}
catch (eError& e)
{
TSTRING extra;
extra += TSS_GetString(cTW, tw::STR_NEWLINE);
extra += TSS_GetString(cTW, tw::STR_ERR_TWCFG_CANT_READ);
cTWUtil::PrintErrorMsg(e, extra);
return 1;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// cTWAModePrintPol
class cTWAModePrintPol : public cTWAModeCommon
{
public:
cTWAModePrintPol();
virtual ~cTWAModePrintPol();
virtual void InitCmdLineParser(cCmdLineParser& parser);
virtual bool Init (const cConfigFile* cf, const cCmdLineParser& parser);
virtual int Execute (cErrorQueue* pQueue);
virtual TSTRING GetModeUsage() { return TSS_GetString( cTWAdmin, twadmin::STR_TWADMIN_HELP_PRINT_POLFILE ); }
virtual bool LoadConfigFile() { return true; }
virtual cTWAdminCmdLine::CmdLineArgs GetModeID() const { return cTWAdminCmdLine::MODE_PRINT_POLICY; }
private:
};
cTWAModePrintPol::cTWAModePrintPol()
{
}
cTWAModePrintPol::~cTWAModePrintPol()
{
}
void cTWAModePrintPol::InitCmdLineParser(cCmdLineParser& parser)
{
InitCmdLineCommon(parser);
parser.AddArg(cTWAdminCmdLine::MODE_PRINT_POLICY, TSTRING(_T("")), TSTRING(_T("print-polfile")), cCmdLineParser::PARAM_NONE);
parser.AddArg(cTWAdminCmdLine::SITE_KEY_FILE, TSTRING(_T("S")), TSTRING(_T("site-keyfile")), cCmdLineParser::PARAM_ONE);
}
bool cTWAModePrintPol::Init(const cConfigFile* cf, const cCmdLineParser& parser)
{
FillOutConfigInfo(cf);
FillOutCmdLineInfo(parser);
return true;
}
int cTWAModePrintPol::Execute(cErrorQueue* pQueue)
{
try
{
cKeyFile sitekey;
bool policyEncrypted = cTWUtil::IsObjectEncrypted(mPolFile.c_str(), cPolicyFile::GetFileHeaderID(), TSS_GetString( cTWAdmin, twadmin::STR_ERR2_UNABLE_TO_PRINT_POLICY ) );
if (policyEncrypted)
{
// check that the config file and site key file are in sync...
//
if( ! mCfgFilePath.empty() )
try
{
if (cTWUtil::VerifyCfgSiteKey( mCfgFilePath, mSiteKeyFile ) == false)
cTWUtil::PrintErrorMsg(eTWCfgUnencrypted(_T(""), eError::NON_FATAL|eError::SUPRESS_THIRD_MSG));
}
catch (eTWUtilCfgKeyMismatch& e)
{
e.SetFatality(false);
cTWUtil::PrintErrorMsg(e);
}
cTWUtil::OpenKeyFile(sitekey, mSiteKeyFile);
}
else
cTWUtil::PrintErrorMsg(eTWUtilPolUnencrypted(_T(""), eError::NON_FATAL|eError::SUPRESS_THIRD_MSG));
std::string policyText;
iUserNotify::GetInstance()->Notify( iUserNotify::V_VERBOSE, _T("%s%s\n"),
TSS_GetString(cTW, tw::STR_OPEN_POLICY_FILE).c_str(),
cDisplayEncoder::EncodeInline( mPolFile ).c_str());
cTWUtil::ReadPolicyText(mPolFile.c_str(), policyText, policyEncrypted ? sitekey.GetPublicKey() : 0);
// Note: I believe print config and print policy are the only time we should
// print to standard out directly.
TCOUT << cDisplayEncoder::EncodeInlineAllowWS( cStringUtil::StrToTstr( policyText ) );
TCOUT << std::endl;
}
catch (eError& e)
{
cTWUtil::PrintErrorMsg(e);
return 1;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// cTWAModeRemoveEncryption
class cTWAModeRemoveEncryption : public cTWAModeCommon
{
public:
cTWAModeRemoveEncryption();
virtual ~cTWAModeRemoveEncryption();
virtual void InitCmdLineParser(cCmdLineParser& parser);
virtual bool Init (const cConfigFile* cf, const cCmdLineParser& parser);
virtual int Execute (cErrorQueue* pQueue);
virtual TSTRING GetModeUsage () { return TSS_GetString( cTWAdmin, twadmin::STR_TWADMIN_HELP_REMOVE_ENCRYPTION ); }
virtual bool LoadConfigFile() { return true; }
virtual cTWAdminCmdLine::CmdLineArgs GetModeID() const { return cTWAdminCmdLine::MODE_REMOVE_ENCRYPTION; }
private:
std::list<TSTRING> mFileList;
wc16_string mSitePassphrase;
wc16_string mLocalPassphrase;
bool mSitePassphraseProvided;
bool mLocalPassphraseProvided;
};
cTWAModeRemoveEncryption::cTWAModeRemoveEncryption()
{
mSitePassphraseProvided = false;
mLocalPassphraseProvided = false;
}
cTWAModeRemoveEncryption::~cTWAModeRemoveEncryption()
{
}
void cTWAModeRemoveEncryption::InitCmdLineParser(cCmdLineParser& parser)
{
InitCmdLineCommon(parser);
parser.AddArg(cTWAdminCmdLine::MODE_REMOVE_ENCRYPTION, TSTRING(_T("")), TSTRING(_T("remove-encryption")), cCmdLineParser::PARAM_NONE);
parser.AddArg(cTWAdminCmdLine::SITE_KEY_FILE, TSTRING(_T("S")), TSTRING(_T("site-keyfile")), cCmdLineParser::PARAM_ONE);
parser.AddArg(cTWAdminCmdLine::LOCAL_KEY_FILE, TSTRING(_T("L")), TSTRING(_T("local-keyfile")), cCmdLineParser::PARAM_ONE);
parser.AddArg(cTWAdminCmdLine::SITEPASSPHRASE, TSTRING(_T("Q")), TSTRING(_T("site-passphrase")), cCmdLineParser::PARAM_ONE);
parser.AddArg(cTWAdminCmdLine::LOCALPASSPHRASE, TSTRING(_T("P")), TSTRING(_T("local-passphrase")), cCmdLineParser::PARAM_ONE);
parser.AddArg(cTWAdminCmdLine::PARAMS, TSTRING(_T("")), TSTRING(_T("")), cCmdLineParser::PARAM_MANY);
parser.AddMutEx(cTWAdminCmdLine::KEY_FILE, cTWAdminCmdLine::LOCAL_KEY_FILE);
parser.AddMutEx(cTWAdminCmdLine::KEY_FILE, cTWAdminCmdLine::LOCAL_KEY_FILE);
parser.AddMutEx(cTWAdminCmdLine::KEY_FILE, cTWAdminCmdLine::SITEPASSPHRASE);
}
bool cTWAModeRemoveEncryption::Init(const cConfigFile* cf, const cCmdLineParser& parser)
{
int i;
FillOutConfigInfo(cf);
FillOutCmdLineInfo(parser);
cCmdLineIter iter(parser);
for(iter.SeekBegin(); ! iter.Done(); iter.Next())
{
switch(iter.ArgId())
{
case cTWAdminCmdLine::LOCALPASSPHRASE:
ASSERT(iter.NumParams() == 1);
mLocalPassphraseProvided = true;
mLocalPassphrase = cStringUtil::TstrToWstr(iter.ParamAt(0));
break;
case cTWAdminCmdLine::SITEPASSPHRASE:
ASSERT(iter.NumParams() == 1);
mSitePassphraseProvided = true;
mSitePassphrase = cStringUtil::TstrToWstr(iter.ParamAt(0));
break;
case cTWAdminCmdLine::PARAMS:
for (i = 0; i < iter.NumParams(); ++i)
{
// get full path to files
TSTRING strFullPath;
if( iFSServices::GetInstance()->FullPath( strFullPath, iter.ParamAt(i) ) )
mFileList.push_back( strFullPath );
else
mFileList.push_back( iter.ParamAt(i) );
}
break;
}
}
// check that the config file and site key file are in sync...
//
if( ! mCfgFilePath.empty() )
try
{
if (cTWUtil::VerifyCfgSiteKey( mCfgFilePath, mSiteKeyFile ) == false)
cTWUtil::PrintErrorMsg(eTWCfgUnencrypted(_T(""), eError::NON_FATAL|eError::SUPRESS_THIRD_MSG));
}
catch (eTWUtilCfgKeyMismatch& e)
{
e.SetFatality(false);
cTWUtil::PrintErrorMsg(e);
}
return true;
}
int cTWAModeRemoveEncryption::Execute(cErrorQueue* pQueue)
{
TSTRING keyfile;
cTWUtil::KeyType keyType;
bool userKnowsLocalPassphrase = false;
bool userKnowsSitePassphrase = false;
bool bResult = true;
bool firstFile = true;
bool warningGiven = false;
bool lastMsgWasError = false; // used to send the separating newline to stderr instead of stdout
if (mFileList.empty())
{
cTWUtil::PrintErrorMsg(eBadCmdLine(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_NO_FILES_SPECIFIED)));
return 1;
}
std::list<TSTRING>::iterator i;
for (i = mFileList.begin(); i != mFileList.end(); ++i)
{
// These lines print out a blank line if necessary
if (!firstFile)
if (!lastMsgWasError)
iUserNotify::GetInstance()->Notify(iUserNotify::V_NORMAL, TSS_GetString(cTW, tw::STR_NEWLINE).c_str());
else
{
TCERR << std::endl;
lastMsgWasError = false;
}
else
firstFile = false;
if( cFileUtil::IsDir( i->c_str() ) )
{
// Ignore directories for this particular operation.
cTWUtil::PrintErrorMsg(eTWASkippingDirectory(*i, eError::NON_FATAL));
lastMsgWasError = true;
}
else
try
{
cFileManipulator manip(i->c_str());
manip.Init();
iUserNotify::GetInstance()->Notify(iUserNotify::V_NORMAL,
_T("%s %s\n"),
TSS_GetString(cTWAdmin, twadmin::STR_EXAMINING_FILE).c_str(),
cDisplayEncoder::EncodeInline( manip.GetFileName() ).c_str());
if (NotifyFileType(*manip.GetHeaderID(), manip.GetFileVersion(), iUserNotify::V_VERBOSE) == false)
{
throw eTWAFileTypeUnknown(manip.GetFileName());
}
// can't decrypt keyfiles
if (*manip.GetHeaderID() == cKeyFile::GetFileHeaderID())
{
cTWUtil::PrintErrorMsg(eTWAEncryptionChange(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_CAN_NOT_DECRYPT_KEYFILE), manip.GetFileName(), eError::NON_FATAL));
lastMsgWasError = true;
bResult = false;
continue;
}
// if this is a config file, make sure its embedded key is the
// same as the provided keyfile
if (*manip.GetHeaderID() == cConfigFile::GetFileHeaderID())
{
try
{
cTWUtil::VerifyCfgSiteKey( *i, mSiteKeyFile );
}
catch (eTWUtil& e)
{
e.SetSupressThird(true);
e.SetFatality(false);
cTWUtil::PrintErrorMsg(e);
if (e.GetID() == eError::CalcHash("eTWUtilCorruptedFile"))
cTWUtil::PrintErrorMsg( eTWADecryptCorrupt( manip.GetFileName(), eError::NON_FATAL ));
else
cTWUtil::PrintErrorMsg( eTWADecrypt( manip.GetFileName(), eError::NON_FATAL ));
//cTWUtil::PrintErrorMsg(eTWAEncryptionChange(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_REMOVE_ENCRYPTION_FAILED), manip.GetFileName(), eError::NON_FATAL));
lastMsgWasError = true;
bResult = false;
continue;
}
}
if (cFileManipulator::UseSiteKey(*manip.GetHeaderID()))
{
keyType = cTWUtil::KEY_SITE;
keyfile = mSiteKeyFile;
}
else
{
keyType = cTWUtil::KEY_LOCAL;
keyfile = mLocalKeyFile;
}
if (NotifyEncryptionType(manip.GetEncoding(), iUserNotify::V_VERBOSE) == false)
{
cTWUtil::PrintErrorMsg(eTWAEncryptionChange(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_ENCODING_TYPE_UNKNOWN), manip.GetFileName(), eError::NON_FATAL));
lastMsgWasError = true;
bResult = false;
continue;
}
else if (manip.GetEncoding() != cFileHeader::ASYM_ENCRYPTION)
{
cTWUtil::PrintErrorMsg(eTWAEncryptionChange(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_FILE_NOT_ENCRYPED), manip.GetFileName(), eError::NON_FATAL));
lastMsgWasError = true;
bResult = false;
continue;
}
else
{
// If we got here we have an Asymmetrically encrypted file
// warn user about removing encryption
if (!warningGiven)
{
iUserNotify::GetInstance()->Notify(iUserNotify::V_SILENT, TSS_GetString(cTWAdmin, twadmin::STR_REMOVE_ENCRYPTION_WARNING).c_str());
TCERR << std::endl;
warningGiven = true;
}
cKeyFile key;
key.ReadFile( keyfile.c_str() );
if (keyType == cTWUtil::KEY_LOCAL)
{
if (!userKnowsLocalPassphrase)
{
cTWUtil::CreatePrivateKey(key, mLocalPassphraseProvided ? mLocalPassphrase.c_str() : 0, keyType); // note: this throws an exception on failure
key.ReleasePrivateKey();
if (!mLatePassphrase) // force user to enter passphrase each time
userKnowsLocalPassphrase = true;
}
}
else if (keyType == cTWUtil::KEY_SITE)
{
if (!userKnowsSitePassphrase)
{
// Check to see if we can even use the site key to decrypt this file.
cTWUtil::CreatePrivateKey(key, mSitePassphraseProvided ? mSitePassphrase.c_str() : 0, keyType); // note: this throws an exception on failure
key.ReleasePrivateKey();
if (!mLatePassphrase) // force user to enter passphrase each time
userKnowsSitePassphrase = true;
}
}
else
ASSERT(false);
try
{
manip.ChangeEncryption(key.GetPublicKey(), NULL, false);
}
catch(eError& e)
{
// Let the user know the decryption failed
e.SetSupressThird( true );
e.SetFatality( false );
cTWUtil::PrintErrorMsg( e );
if (e.GetID() == eError::CalcHash("eArchiveCrypto"))
cTWUtil::PrintErrorMsg( eTWADecryptCorrupt( manip.GetFileName(), eError::NON_FATAL ));
else
cTWUtil::PrintErrorMsg( eTWADecrypt( manip.GetFileName(), eError::NON_FATAL ));
lastMsgWasError = true;
bResult = false;
continue;
}
iUserNotify::GetInstance()->Notify(iUserNotify::V_VERBOSE,
TSS_GetString(cTWAdmin, twadmin::STR_ENCRYPTION_REMOVED).c_str(),
cDisplayEncoder::EncodeInline( manip.GetFileName() ).c_str());
}
}
catch (eFileManip& e)
{
e.SetFatality(false);
cTWUtil::PrintErrorMsg(e);
lastMsgWasError = true;
bResult = false;
}
catch (eArchive& e)
{
e.SetFatality(false);
cTWUtil::PrintErrorMsg(e);
lastMsgWasError = true;
bResult = false;
}
}
return bResult == false;
}
///////////////////////////////////////////////////////////////////////////////
// cTWAModeEncrypt
class cTWAModeEncrypt : public cTWAModeCommon
{
public:
cTWAModeEncrypt();
virtual ~cTWAModeEncrypt();
virtual void InitCmdLineParser(cCmdLineParser& parser);
virtual bool Init (const cConfigFile* cf, const cCmdLineParser& parser);
virtual int Execute (cErrorQueue* pQueue);
virtual TSTRING GetModeUsage() { return TSS_GetString( cTWAdmin, twadmin::STR_TWADMIN_HELP_ENCRYPT ); }
virtual bool LoadConfigFile() { return true; }
virtual cTWAdminCmdLine::CmdLineArgs GetModeID() const { return cTWAdminCmdLine::MODE_REMOVE_ENCRYPTION; }
private:
std::list<TSTRING> mFileList;
wc16_string mSitePassphrase;
wc16_string mLocalPassphrase;
bool mSitePassphraseProvided;
bool mLocalPassphraseProvided;
bool mbLatePassphrase;
};
cTWAModeEncrypt::cTWAModeEncrypt()
{
mSitePassphraseProvided = false;
mLocalPassphraseProvided = false;
mbLatePassphrase = false;
}
cTWAModeEncrypt::~cTWAModeEncrypt()
{
}
void cTWAModeEncrypt::InitCmdLineParser(cCmdLineParser& parser)
{
InitCmdLineCommon(parser);
parser.AddArg(cTWAdminCmdLine::MODE_ENCRYPT, TSTRING(_T("")), TSTRING(_T("encrypt")), cCmdLineParser::PARAM_NONE);
parser.AddArg(cTWAdminCmdLine::SITE_KEY_FILE, TSTRING(_T("S")), TSTRING(_T("site-keyfile")), cCmdLineParser::PARAM_ONE);
parser.AddArg(cTWAdminCmdLine::LOCAL_KEY_FILE, TSTRING(_T("L")), TSTRING(_T("local-keyfile")), cCmdLineParser::PARAM_ONE);
parser.AddArg(cTWAdminCmdLine::LOCALPASSPHRASE, TSTRING(_T("P")), TSTRING(_T("local-passphrase")), cCmdLineParser::PARAM_ONE);
parser.AddArg(cTWAdminCmdLine::SITEPASSPHRASE, TSTRING(_T("Q")), TSTRING(_T("site-passphrase")), cCmdLineParser::PARAM_ONE);
parser.AddArg(cTWAdminCmdLine::PARAMS, TSTRING(_T("")), TSTRING(_T("")), cCmdLineParser::PARAM_MANY);
}
bool cTWAModeEncrypt::Init(const cConfigFile* cf, const cCmdLineParser& parser)
{
int i;
FillOutConfigInfo(cf);
TSTRING str;
if(cf->Lookup(TSTRING(_T("LATEPROMPTING")), str))
{
if (_tcsicmp(str.c_str(), _T("true")) == 0)
mbLatePassphrase = true;
}
FillOutCmdLineInfo(parser);
cCmdLineIter iter(parser);
for(iter.SeekBegin(); ! iter.Done(); iter.Next())
{
switch(iter.ArgId())
{
case cTWAdminCmdLine::PARAMS:
for (i = 0; i < iter.NumParams(); ++i)
{
TSTRING strFullPath;
if( iFSServices::GetInstance()->FullPath( strFullPath, iter.ParamAt(i) ) )
mFileList.push_back( strFullPath );
else
mFileList.push_back( iter.ParamAt(i) );
}
break;
case cTWAdminCmdLine::LOCALPASSPHRASE:
ASSERT(iter.NumParams() == 1);
mLocalPassphraseProvided = true;
mLocalPassphrase = cStringUtil::TstrToWstr(iter.ParamAt(0));
break;
case cTWAdminCmdLine::SITEPASSPHRASE:
ASSERT(iter.NumParams() == 1);
mSitePassphraseProvided = true;
mSitePassphrase = cStringUtil::TstrToWstr(iter.ParamAt(0));
break;
}
}
// check that the config file and site key file are in sync...
//
if( ! mCfgFilePath.empty() )
try
{
if (cTWUtil::VerifyCfgSiteKey( mCfgFilePath, mSiteKeyFile ) == false)
cTWUtil::PrintErrorMsg(eTWCfgUnencrypted(_T(""), eError::NON_FATAL|eError::SUPRESS_THIRD_MSG));
}
catch (eTWUtilCfgKeyMismatch& e)
{
e.SetFatality(false);
cTWUtil::PrintErrorMsg(e);
}
return true;
}
int cTWAModeEncrypt::Execute(cErrorQueue* pQueue)
{
cKeyFile siteKeyFile, localKeyFile;
cPrivateKeyProxy siteKey, localKey;
if (mFileList.empty())
{
cTWUtil::PrintErrorMsg(eBadCmdLine(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_NO_FILES_SPECIFIED)));
return 1;
}
bool bResult = true;
std::list<TSTRING>::iterator i;
// We cycle through all the files twice. This first time we
// check for file validity and open any keyfiles needed.
for (i = mFileList.begin(); i != mFileList.end(); /* incrementing done below...*/)
{
try
{
if( cFileUtil::IsDir( i->c_str() ) )
{
// Ignore directories for this particular operation.
// Note: We don't throw here because we don't want to set bResult to false
cTWUtil::PrintErrorMsg(eTWASkippingDirectory(*i, eError::NON_FATAL));
TCERR << std::endl; // extra newline to separate filenames
i = mFileList.erase(i);
continue;
}
else if (!cFileUtil::FileExists(i->c_str()))
{
// tell user we could not open *i
throw eTWAFileNotFound(*i, eError::NON_FATAL);
}
cFileManipulator manip(i->c_str());
manip.Init();
// can't encrypt keyfiles
if (*manip.GetHeaderID() == cKeyFile::GetFileHeaderID())
{
throw eTWAEncryptionChange(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_CAN_NOT_DECRYPT_KEYFILE), manip.GetFileName(), eError::NON_FATAL);
}
if (cFileManipulator::UseSiteKey(*manip.GetHeaderID()))
{
if (!siteKeyFile.KeysLoaded())
cTWUtil::OpenKeyFile(siteKeyFile, mSiteKeyFile);
}
else
{
if (!localKeyFile.KeysLoaded())
cTWUtil::OpenKeyFile(localKeyFile, mLocalKeyFile);
}
// increment the iterator
++i;
}
catch (eError& e)
{
e.SetFatality(false);
cTWUtil::PrintErrorMsg(e);
TCERR << std::endl; // extra newline to separate filenames
// erase this file so that it is skipped in the next round
i = mFileList.erase(i);
bResult = false;
continue;
}
}
// On this second pass we go through and convert all files
for (i = mFileList.begin(); i != mFileList.end(); ++i)
{
if( cFileUtil::IsDir( i->c_str() ) )
{
// Ignore directories for this particular operation.
}
else if (!cFileUtil::FileExists(i->c_str()))
{
// tell user we could not open *i
bResult = false;
}
else
try
{
cFileManipulator manip(i->c_str());
manip.Init();
if (*manip.GetHeaderID() == cKeyFile::GetFileHeaderID())
{
continue;
}
iUserNotify::GetInstance()->Notify(iUserNotify::V_NORMAL, TSS_GetString(cTW, tw::STR_NEWLINE).c_str());
iUserNotify::GetInstance()->Notify(iUserNotify::V_NORMAL,
_T("%s %s\n"),
TSS_GetString(cTWAdmin, twadmin::STR_EXAMINING_FILE).c_str(),
cDisplayEncoder::EncodeInline( manip.GetFileName() ).c_str());
if (NotifyFileType(*manip.GetHeaderID(), manip.GetFileVersion(), iUserNotify::V_VERBOSE) == false)
{
cTWUtil::PrintErrorMsg(eTWAFileTypeUnknown(manip.GetFileName(), eError::NON_FATAL));
TCERR << std::endl; // extra newline to separate filenames
bResult = false;
}
if (NotifyEncryptionType(manip.GetEncoding(), iUserNotify::V_VERBOSE) == false)
{
cTWUtil::PrintErrorMsg(eTWAEncryptionChange(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_ENCODING_TYPE_UNKNOWN), manip.GetFileName(), eError::NON_FATAL));
TCERR << std::endl; // extra newline to separate filenames
bResult = false;
}
else if (manip.GetEncoding() == cFileHeader::ASYM_ENCRYPTION)
{
cTWUtil::PrintErrorMsg(eTWAEncryptionChange(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_FILE_ALREADY_ENCRYPTED), manip.GetFileName(), eError::NON_FATAL));
TCERR << std::endl; // extra newline to separate filenames
bResult = false;
}
else
{
cPrivateKeyProxy* pPrivateKey;
if (cFileManipulator::UseSiteKey(*manip.GetHeaderID()))
{
if (mbLatePassphrase || !siteKey.Valid())
cTWUtil::CreatePrivateKey(siteKey, siteKeyFile, mSitePassphraseProvided ? mSitePassphrase.c_str() : 0, cTWUtil::KEY_SITE);
pPrivateKey = &siteKey;
}
else
{
if (mbLatePassphrase || !localKey.Valid())
cTWUtil::CreatePrivateKey(localKey, localKeyFile, mLocalPassphraseProvided ? mLocalPassphrase.c_str() : 0, cTWUtil::KEY_LOCAL);
pPrivateKey = &localKey;
}
try
{
manip.ChangeEncryption(NULL, pPrivateKey->GetKey(), false);
iUserNotify::GetInstance()->Notify(iUserNotify::V_VERBOSE,
TSS_GetString(cTWAdmin, twadmin::STR_ENCRYPTION_SUCCEEDED).c_str(),
cDisplayEncoder::EncodeInline( manip.GetFileName() ).c_str());
iUserNotify::GetInstance()->Notify(iUserNotify::V_NORMAL,
TSS_GetString(cTW, tw::STR_NEWLINE).c_str(),
cDisplayEncoder::EncodeInline( manip.GetFileName() ).c_str());
}
catch (eFileManip& e)
{
cTWUtil::PrintErrorMsg(e);
TCERR << std::endl; // extra newline to separate filenames
bResult = false;
}
}
}
catch (eFileManip&)
{
continue;
}
}
return bResult == false;
}
///////////////////////////////////////////////////////////////////////////////
// cTWAModeExamine
class cTWAModeExamine : public cTWAModeCommon
{
public:
cTWAModeExamine();
virtual ~cTWAModeExamine();
virtual void InitCmdLineParser(cCmdLineParser& parser);
virtual bool Init (const cConfigFile* cf, const cCmdLineParser& parser);
virtual int Execute (cErrorQueue* pQueue);
virtual TSTRING GetModeUsage() { return TSS_GetString( cTWAdmin, twadmin::STR_TWADMIN_HELP_EXAMINE ); }
virtual bool LoadConfigFile() { return true; }
virtual cTWAdminCmdLine::CmdLineArgs GetModeID() const { return cTWAdminCmdLine::MODE_REMOVE_ENCRYPTION; }
private:
std::list<TSTRING> mFileList;
};
cTWAModeExamine::cTWAModeExamine()
{
}
cTWAModeExamine::~cTWAModeExamine()
{
}
void cTWAModeExamine::InitCmdLineParser(cCmdLineParser& parser)
{
InitCmdLineCommon(parser);
parser.AddArg(cTWAdminCmdLine::MODE_EXAMINE, TSTRING(_T("")), TSTRING(_T("examine")), cCmdLineParser::PARAM_NONE);
parser.AddArg(cTWAdminCmdLine::SITE_KEY_FILE, TSTRING(_T("S")), TSTRING(_T("site-keyfile")), cCmdLineParser::PARAM_ONE);
parser.AddArg(cTWAdminCmdLine::LOCAL_KEY_FILE, TSTRING(_T("L")), TSTRING(_T("local-keyfile")), cCmdLineParser::PARAM_ONE);
parser.AddArg(cTWAdminCmdLine::PARAMS, TSTRING(_T("")), TSTRING(_T("")), cCmdLineParser::PARAM_MANY);
}
bool cTWAModeExamine::Init(const cConfigFile* cf, const cCmdLineParser& parser)
{
int i;
FillOutConfigInfo(cf);
FillOutCmdLineInfo(parser);
cCmdLineIter iter(parser);
for(iter.SeekBegin(); ! iter.Done(); iter.Next())
{
switch(iter.ArgId())
{
case cTWAdminCmdLine::PARAMS:
for (i = 0; i < iter.NumParams(); ++i)
{
TSTRING strFullPath;
if( iFSServices::GetInstance()->FullPath( strFullPath, iter.ParamAt(i) ) )
mFileList.push_back( strFullPath );
else
mFileList.push_back( iter.ParamAt(i) );
}
break;
}
}
// check that the config file and site key file are in sync...
//
if( ! mCfgFilePath.empty() )
try
{
if (cTWUtil::VerifyCfgSiteKey( mCfgFilePath, mSiteKeyFile ) == false)
cTWUtil::PrintErrorMsg(eTWCfgUnencrypted(_T(""), eError::NON_FATAL|eError::SUPRESS_THIRD_MSG));
}
catch (eTWUtilCfgKeyMismatch& e)
{
e.SetFatality(false);
cTWUtil::PrintErrorMsg(e);
}
return true;
}
int cTWAModeExamine::Execute(cErrorQueue* pQueue)
{
if (mFileList.empty())
{
cTWUtil::PrintErrorMsg(eBadCmdLine(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_NO_FILES_SPECIFIED)));
return 1;
}
bool bResult = true;
// Open site and local key up front so we can warn if they fail opening
cKeyFile siteKey, localKey;
try
{
siteKey.ReadFile(mSiteKeyFile.c_str());
}
catch (eKeyFile& e)
{
e.SetFatality(false);
cTWUtil::PrintErrorMsg(e);
bResult = false;
}
catch (eError&)
{
}
try
{
localKey.ReadFile(mLocalKeyFile.c_str());
}
catch (eKeyFile& e)
{
e.SetFatality(false);
cTWUtil::PrintErrorMsg(e);
bResult = false;
}
catch (eError&)
{
}
// now iteratate over files to examine
std::list<TSTRING>::iterator i;
for (i = mFileList.begin(); i != mFileList.end(); ++i)
{
if( cFileUtil::IsDir(i->c_str()))
{
//Ignore directories in examine encryption mode.
cTWUtil::PrintErrorMsg(eTWASkippingDirectory(*i, eError::NON_FATAL));
TCERR << std::endl; // extra newline to separate filenames
}
else if (!cFileUtil::FileExists(i->c_str()))
{
// tell user we could not open *i
cTWUtil::PrintErrorMsg(eTWAFileNotFound(*i, eError::NON_FATAL));
TCERR << std::endl; // extra newline to separate filenames
bResult = false;
}
else
try
{
cFileManipulator manip(i->c_str());
manip.Init();
// print out: "File: filename.ext"
iUserNotify::GetInstance()->Notify(iUserNotify::V_SILENT, TSS_GetString(cTWAdmin, twadmin::STR_FILE).c_str());
iUserNotify::GetInstance()->Notify(iUserNotify::V_SILENT, _T("%s"), cDisplayEncoder::EncodeInline( manip.GetFileName() ).c_str());
iUserNotify::GetInstance()->Notify(iUserNotify::V_SILENT, TSS_GetString(cTWAdmin, twadmin::STR_ENDQUOTE_NEWLINE).c_str());
NotifyFileType(*manip.GetHeaderID(), manip.GetFileVersion(), iUserNotify::V_NORMAL);
NotifyEncryptionType(manip.GetEncoding(), iUserNotify::V_NORMAL);
// Try different keys to see if they decrypt this file
if (manip.GetEncoding() == cFileHeader::ASYM_ENCRYPTION)
{
// Output the keys that decrypt the file.
iUserNotify::GetInstance()->Notify(iUserNotify::V_NORMAL, TSS_GetString(cTWAdmin, twadmin::STR_KEYS_DECRYPT ).c_str());
iUserNotify::GetInstance()->Notify(iUserNotify::V_NORMAL, TSS_GetString(cTW, tw::STR_NEWLINE ).c_str());
bool siteDecrypts = false, localDecrypts = false;
if (siteKey.KeysLoaded())
try
{
if (manip.TestDecryption(*siteKey.GetPublicKey(), false) != false)
{
siteDecrypts = true;
iUserNotify::GetInstance()->Notify(iUserNotify::V_SILENT, TSS_GetString(cTWAdmin, twadmin::STR_SITEKEYFILE ).c_str());
iUserNotify::GetInstance()->Notify(iUserNotify::V_SILENT, cDisplayEncoder::EncodeInline( mSiteKeyFile ).c_str());
iUserNotify::GetInstance()->Notify(iUserNotify::V_SILENT, TSS_GetString(cTW, tw::STR_NEWLINE ).c_str());
}
}
catch (eError&) {}
if (localKey.KeysLoaded())
try
{
if (manip.TestDecryption(*localKey.GetPublicKey(), false) != false)
{
localDecrypts = true;
iUserNotify::GetInstance()->Notify(iUserNotify::V_SILENT, TSS_GetString(cTWAdmin, twadmin::STR_LOCALKEYFILE ).c_str());
iUserNotify::GetInstance()->Notify(iUserNotify::V_SILENT, cDisplayEncoder::EncodeInline( mLocalKeyFile ).c_str());
iUserNotify::GetInstance()->Notify(iUserNotify::V_SILENT, TSS_GetString(cTW, tw::STR_NEWLINE ).c_str());
}
}
catch (eError&) {}
}
TCOUT << std::endl;
}
catch (eFileManip& e)
{
e.SetFatality(false);
cTWUtil::PrintErrorMsg(e);
TCERR << std::endl;
bResult = false;
}
}
return bResult == false;
}
///////////////////////////////////////////////////////////////////////////////
// cTWAModeGenerateKeys
class cTWAModeGenerateKeys : public cTWAModeCommon
{
public:
cTWAModeGenerateKeys();
virtual ~cTWAModeGenerateKeys();
virtual void InitCmdLineParser(cCmdLineParser& parser);
virtual bool Init (const cConfigFile* cf, const cCmdLineParser& parser);
virtual int Execute (cErrorQueue* pQueue);
virtual TSTRING GetModeUsage() { return TSS_GetString( cTWAdmin, twadmin::STR_TWADMIN_HELP_GENERATE_KEYS ); }
virtual bool LoadConfigFile() { return false; }
virtual cTWAdminCmdLine::CmdLineArgs GetModeID() const { return cTWAdminCmdLine::MODE_GENERATE_KEYS; }
private:
bool mSiteProvided; // A site passphrase has been passed.
wc16_string mSitePassphrase;
bool mLocalProvided; // A local passphrase has been passed.
wc16_string mLocalPassphrase;
bool mGenerateSite; // A Site key has been specified.
bool mGenerateLocal; // A Local key has been specified.
};
cTWAModeGenerateKeys::cTWAModeGenerateKeys()
{
mLocalProvided = false;
mSiteProvided = false;
mGenerateSite = false;
mGenerateLocal = false;
}
cTWAModeGenerateKeys::~cTWAModeGenerateKeys()
{
}
void cTWAModeGenerateKeys::InitCmdLineParser(cCmdLineParser& parser)
{
InitCmdLineCommon(parser);
parser.AddArg(cTWAdminCmdLine::MODE_GENERATE_KEYS, TSTRING(_T("")), TSTRING(_T("generate-keys")), cCmdLineParser::PARAM_NONE);
parser.AddArg(cTWAdminCmdLine::SITE_KEY_FILE, TSTRING(_T("S")), TSTRING(_T("site-keyfile")), cCmdLineParser::PARAM_ONE);
parser.AddArg(cTWAdminCmdLine::LOCAL_KEY_FILE, TSTRING(_T("L")), TSTRING(_T("local-keyfile")), cCmdLineParser::PARAM_ONE);
parser.AddArg(cTWAdminCmdLine::SITEPASSPHRASE, TSTRING(_T("Q")), TSTRING(_T("site-passphrase")), cCmdLineParser::PARAM_ONE);
parser.AddArg(cTWAdminCmdLine::LOCALPASSPHRASE, TSTRING(_T("P")), TSTRING(_T("local-passphrase")), cCmdLineParser::PARAM_ONE);
}
bool cTWAModeGenerateKeys::Init(const cConfigFile* cf, const cCmdLineParser& parser)
{
TSTRING str;
// Note: we don't use the config file for anything any more.
FillOutCmdLineInfo(parser);
cCmdLineIter iter(parser);
for(iter.SeekBegin(); ! iter.Done(); iter.Next())
{
switch(iter.ArgId())
{
case cTWAdminCmdLine::SITEPASSPHRASE:
ASSERT(iter.NumParams() == 1);
mSitePassphrase = cStringUtil::TstrToWstr(iter.ParamAt(0));
mSiteProvided = true;
break;
case cTWAdminCmdLine::LOCALPASSPHRASE:
ASSERT(iter.NumParams() == 1);
mLocalPassphrase = cStringUtil::TstrToWstr(iter.ParamAt(0));
mLocalProvided = true;
break;
case cTWAdminCmdLine::SITE_KEY_FILE:
mGenerateSite = true;
break;
case cTWAdminCmdLine::LOCAL_KEY_FILE:
mGenerateLocal = true;
break;
}
}
if (mSiteProvided || mLocalProvided)
iUserNotify::GetInstance()->Notify(iUserNotify::V_VERBOSE,
TSS_GetString(cTWAdmin, twadmin::STR_KEYGEN_VERBOSE_PASSPHRASES).c_str());
return true;
}
int cTWAModeGenerateKeys::Execute(cErrorQueue* pQueue)
{
int i;
if (!mGenerateSite && !mGenerateLocal)
{
cTWUtil::PrintErrorMsg(eBadCmdLine(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_KEYS_NOT_SPECIFIED)));
return 1;
}
if ((mGenerateSite && mSiteKeyFile.empty()) ||
(mGenerateLocal && mLocalKeyFile.empty()))
{
// This case should not occur (it should be caught by Init() logic), but in case it does we will spit out
// a generic error string.
ASSERT(false);
cTWUtil::PrintErrorMsg(eBadCmdLine(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_KEYS_NOT_SPECIFIED)));
return 1;
}
if (!mGenerateSite && mSiteProvided)
{
cTWUtil::PrintErrorMsg(eBadCmdLine(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_LONE_SITE_PASSPHRASE)));
return 1;
}
if (!mGenerateLocal && mLocalProvided)
{
cTWUtil::PrintErrorMsg(eBadCmdLine(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_LONE_LOCAL_PASSPHRASE)));
return 1;
}
if( (mSiteProvided && !mGenerateSite) || (mLocalProvided && !mGenerateLocal) )
{
//This is an error, a passphrase should not be specified if the corresponding key has not been passed.
cTWUtil::PrintErrorMsg(eBadCmdLine(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_PASSPHRASE_NOKEY)));
return 1;
}
if (mSiteKeyFile == mLocalKeyFile)
{
cTWUtil::PrintErrorMsg(eBadCmdLine(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_KEY_FILENAMES_IDENTICAL)));
return 1;
}
if (mGenerateSite && cFileUtil::FileExists(mSiteKeyFile))
{
TSTRING prompt;
prompt += TSS_GetString(cTWAdmin, twadmin::STR_SITEKEY_EXISTS_1);
prompt += cDisplayEncoder::EncodeInline( mSiteKeyFile );
prompt += TSS_GetString(cTWAdmin, twadmin::STR_SITEKEY_EXISTS_2);
if (cTWUtil::ConfirmYN(prompt.c_str()) == false)
return 1;
}
if (mGenerateLocal && cFileUtil::FileExists(mLocalKeyFile))
{
TSTRING prompt;
prompt += TSS_GetString(cTWAdmin, twadmin::STR_LOCALKEY_EXISTS_1);
prompt += cDisplayEncoder::EncodeInline( mLocalKeyFile );
prompt += TSS_GetString(cTWAdmin, twadmin::STR_LOCALKEY_EXISTS_2);
if (cTWUtil::ConfirmYN(prompt.c_str()) == false)
return 1;
}
//
// make sure that we can write to both of the files before we continue
//
if(mGenerateLocal)
cFileUtil::TestFileWritable(mLocalKeyFile);
if(mGenerateSite)
cFileUtil::TestFileWritable(mSiteKeyFile);
wc16_string verify;
bool bPrintedPassphraseHint = false;
if (mGenerateSite)
{
if (!mSiteProvided)
{
// give the user a passphrase hint...
//
if(! bPrintedPassphraseHint)
{
bPrintedPassphraseHint = true;
iUserNotify::GetInstance()->Notify( iUserNotify::V_NORMAL, TSS_GetString(cTWAdmin, twadmin::STR_PASSPHRASE_HINT).c_str() );
}
for (i=1; ; i++)
{
cTWUtil::NoEcho noEcho;
// Note: Since we are interacting directly with the user here,
// I think it is o.k. to use cout directly.
TCOUT << TSS_GetString(cTWAdmin, twadmin::STR_ENTER_SITE_PASS);
cTWUtil::GetString(mSitePassphrase);
TCOUT << TSS_GetString(cTW, tw::STR_NEWLINE);
TCOUT << TSS_GetString(cTWAdmin, twadmin::STR_VERIFY_SITE_PASS);
cTWUtil::GetString(verify);
TCOUT << TSS_GetString(cTW, tw::STR_NEWLINE);
if ( 0 == verify.compare( mSitePassphrase ) )
break;
TCOUT << TSS_GetString(cTW, tw::STR_ERR_WRONG_PASSPHRASE_SITE) << std::endl;
if (i == 3)
return 1;
}
}
iUserNotify::GetInstance()->Notify(iUserNotify::V_VERBOSE,
TSS_GetString(cTWAdmin, twadmin::STR_KEYGEN_VERBOSE_SITEKEY).c_str(),
cDisplayEncoder::EncodeInline( mSiteKeyFile ).c_str());
// backup current file if it exists
cFileUtil::BackupFile(mSiteKeyFile);
if (GenerateKey(mSiteKeyFile.c_str(), mSitePassphrase) == false)
return 1;
}
if (mGenerateLocal)
{
if (!mLocalProvided)
{
// give the user a passphrase hint...
//
if(! bPrintedPassphraseHint)
{
bPrintedPassphraseHint = true;
iUserNotify::GetInstance()->Notify( iUserNotify::V_NORMAL, TSS_GetString(cTWAdmin, twadmin::STR_PASSPHRASE_HINT).c_str() );
}
for (i=1; ; i++)
{
cTWUtil::NoEcho noEcho;
// Note: Since we are interacting directly with the user here,
// I think it is o.k. to use cout directly.
TCOUT << TSS_GetString(cTWAdmin, twadmin::STR_ENTER_LOCAL_PASS);
cTWUtil::GetString(mLocalPassphrase);
TCOUT << TSS_GetString(cTW, tw::STR_NEWLINE);
TCOUT << TSS_GetString(cTWAdmin, twadmin::STR_VERIFY_LOCAL_PASS);
cTWUtil::GetString(verify);
TCOUT << TSS_GetString(cTW, tw::STR_NEWLINE);
if ( 0 == verify.compare( mLocalPassphrase ) )
break;
TCOUT << TSS_GetString(cTW, tw::STR_ERR_WRONG_PASSPHRASE_LOCAL) << std::endl;
if (i == 3)
return 1;
}
}
iUserNotify::GetInstance()->Notify(iUserNotify::V_VERBOSE,
TSS_GetString(cTWAdmin, twadmin::STR_KEYGEN_VERBOSE_LOCALKEY).c_str(),
cDisplayEncoder::EncodeInline( mLocalKeyFile ).c_str());
// backup current file if it exists
cFileUtil::BackupFile(mLocalKeyFile);
if (GenerateKey(mLocalKeyFile.c_str(), mLocalPassphrase) == false)
return 1;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// cTWAModeChangePassphrases
static bool ChangePassphrase(
const TCHAR* keyPath, wc16_string passphraseOld, wc16_string passphrase)
{
// in order to leave original password data intact upon return,
// we must allocate a BIGENDIAN copy
// and delete it before we return.
// auto_ptr does not help (won't work with arrays).
size_t passphraseLenOld = passphraseOld.length() * sizeof(WCHAR16);
size_t passphraseLen = passphrase .length() * sizeof(WCHAR16);
int8 * passphraseCopyOld = new int8[passphraseLenOld];
int8 * passphraseCopy = new int8[passphraseLen];
#ifdef WORDS_BIGENDIAN
memcpy(passphraseCopyOld, passphraseOld.data(), passphraseLenOld);
memcpy(passphraseCopy, passphrase .data(), passphraseLen);
#else
swab(passphraseOld.data(), passphraseCopyOld, passphraseLenOld);
swab(passphrase .data(), passphraseCopy, passphraseLen);
#endif
bool result;
try {
cKeyFile keyfile;
keyfile.ReadFile(keyPath);
keyfile.ChangePassphrase(
passphraseCopyOld, passphraseLenOld,
passphraseCopy, passphraseLen);
keyfile.WriteFile(keyPath);
result = true;
}
catch (eKeyFile & e)
{
cTWUtil::PrintErrorMsg(e);
result = false;
}
delete[] passphraseCopyOld;
delete[] passphraseCopy;
return result;
}
class cTWAModeChangePassphrases : public cTWAModeCommon
{
public:
cTWAModeChangePassphrases();
virtual ~cTWAModeChangePassphrases();
virtual void InitCmdLineParser(cCmdLineParser& parser);
virtual bool Init (const cConfigFile* cf, const cCmdLineParser& parser);
virtual int Execute (cErrorQueue* pQueue);
virtual TSTRING GetModeUsage() { return TSS_GetString( cTWAdmin, twadmin::STR_TWADMIN_HELP_CHANGE_PASSPHRASES ); }
virtual bool LoadConfigFile() { return false; }
virtual cTWAdminCmdLine::CmdLineArgs GetModeID() const { return cTWAdminCmdLine::MODE_CHANGE_PASSPHRASES; }
private:
bool mSiteProvidedOld; // A site passphrase-old has been passed.
wc16_string mSitePassphraseOld;
bool mLocalProvidedOld; // A local passphrase-old has been passed.
wc16_string mLocalPassphraseOld;
bool mSiteProvided; // A site passphrase has been passed.
wc16_string mSitePassphrase;
bool mLocalProvided; // A local passphrase has been passed.
wc16_string mLocalPassphrase;
bool mChangeSite; // A Site key has been specified.
bool mChangeLocal; // A Local key has been specified.
};
cTWAModeChangePassphrases::cTWAModeChangePassphrases()
{
mLocalProvidedOld = false;
mSiteProvidedOld = false;
mLocalProvided = false;
mSiteProvided = false;
mChangeSite = false;
mChangeLocal = false;
}
cTWAModeChangePassphrases::~cTWAModeChangePassphrases()
{
}
void cTWAModeChangePassphrases::InitCmdLineParser(cCmdLineParser& parser)
{
InitCmdLineCommon(parser);
parser.AddArg(cTWAdminCmdLine::MODE_CHANGE_PASSPHRASES,TSTRING(_T("")), TSTRING(_T("change-passphrases")), cCmdLineParser::PARAM_NONE);
parser.AddArg(cTWAdminCmdLine::SITE_KEY_FILE, TSTRING(_T("S")), TSTRING(_T("site-keyfile")), cCmdLineParser::PARAM_ONE);
parser.AddArg(cTWAdminCmdLine::LOCAL_KEY_FILE, TSTRING(_T("L")), TSTRING(_T("local-keyfile")), cCmdLineParser::PARAM_ONE);
parser.AddArg(cTWAdminCmdLine::SITEPASSPHRASE, TSTRING(_T("Q")), TSTRING(_T("site-passphrase")), cCmdLineParser::PARAM_ONE);
parser.AddArg(cTWAdminCmdLine::LOCALPASSPHRASE, TSTRING(_T("P")), TSTRING(_T("local-passphrase")), cCmdLineParser::PARAM_ONE);
parser.AddArg(cTWAdminCmdLine::SITEPASSPHRASEOLD, TSTRING(_T("")), TSTRING(_T("site-passphrase-old")), cCmdLineParser::PARAM_ONE);
parser.AddArg(cTWAdminCmdLine::LOCALPASSPHRASEOLD, TSTRING(_T("")), TSTRING(_T("local-passphrase-old")), cCmdLineParser::PARAM_ONE);
}
bool cTWAModeChangePassphrases::Init(const cConfigFile* cf, const cCmdLineParser& parser)
{
TSTRING str;
// Note: we don't use the config file for anything any more.
FillOutCmdLineInfo(parser);
cCmdLineIter iter(parser);
for(iter.SeekBegin(); ! iter.Done(); iter.Next())
{
switch(iter.ArgId())
{
case cTWAdminCmdLine::SITEPASSPHRASE:
ASSERT(iter.NumParams() == 1);
mSitePassphrase = cStringUtil::TstrToWstr(iter.ParamAt(0));
mSiteProvided = true;
break;
case cTWAdminCmdLine::LOCALPASSPHRASE:
ASSERT(iter.NumParams() == 1);
mLocalPassphrase = cStringUtil::TstrToWstr(iter.ParamAt(0));
mLocalProvided = true;
break;
case cTWAdminCmdLine::SITEPASSPHRASEOLD:
ASSERT(iter.NumParams() == 1);
mSitePassphraseOld = cStringUtil::TstrToWstr(iter.ParamAt(0));
mSiteProvidedOld = true;
break;
case cTWAdminCmdLine::LOCALPASSPHRASEOLD:
ASSERT(iter.NumParams() == 1);
mLocalPassphraseOld = cStringUtil::TstrToWstr(iter.ParamAt(0));
mLocalProvidedOld = true;
break;
case cTWAdminCmdLine::SITE_KEY_FILE:
mChangeSite = true;
break;
case cTWAdminCmdLine::LOCAL_KEY_FILE:
mChangeLocal = true;
break;
}
}
if ((mSiteProvidedOld && mSiteProvided) || (mLocalProvidedOld && mLocalProvided))
iUserNotify::GetInstance()->Notify(iUserNotify::V_VERBOSE,
TSS_GetString(cTWAdmin, twadmin::STR_KEYGEN_VERBOSE_PASSPHRASES).c_str());
return true;
}
int cTWAModeChangePassphrases::Execute(cErrorQueue* pQueue)
{
int i;
bool bSiteProvided = mSiteProvided || mSiteProvidedOld;
bool bLocalProvided = mLocalProvided || mLocalProvidedOld;
if (!mChangeSite && !mChangeLocal)
{
cTWUtil::PrintErrorMsg(eBadCmdLine(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_KEYS_NOT_SPECIFIED)));
return 1;
}
if ((mChangeSite && mSiteKeyFile.empty()) ||
(mChangeLocal && mLocalKeyFile.empty()))
{
// This case should not occur (it should be caught by Init() logic), but in case it does we will spit out
// a generic error string.
ASSERT(false);
cTWUtil::PrintErrorMsg(eBadCmdLine(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_KEYS_NOT_SPECIFIED)));
return 1;
}
if (!mChangeSite && bSiteProvided)
{
cTWUtil::PrintErrorMsg(eBadCmdLine(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_LONE_SITE_PASSPHRASE)));
return 1;
}
if (!mChangeLocal && bLocalProvided)
{
cTWUtil::PrintErrorMsg(eBadCmdLine(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_LONE_LOCAL_PASSPHRASE)));
return 1;
}
if( (bSiteProvided && !mChangeSite) || (bLocalProvided && !mChangeLocal) )
{
//This is an error, a passphrase should not be specified if the corresponding key has not been passed.
cTWUtil::PrintErrorMsg(eBadCmdLine(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_PASSPHRASE_NOKEY)));
return 1;
}
if (mSiteKeyFile == mLocalKeyFile)
{
cTWUtil::PrintErrorMsg(eBadCmdLine(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_KEY_FILENAMES_IDENTICAL)));
return 1;
}
if (mChangeSite && !cFileUtil::FileExists(mSiteKeyFile))
{
cTWUtil::PrintErrorMsg(eBadCmdLine(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_SITE_KEY_DOESNT_EXIST)));
return 1;
}
if (mChangeLocal && !cFileUtil::FileExists(mLocalKeyFile))
{
cTWUtil::PrintErrorMsg(eBadCmdLine(TSS_GetString(cTWAdmin, twadmin::STR_ERR2_LOCAL_KEY_DOESNT_EXIST)));
return 1;
}
//
// make sure that we can write to both of the files before we continue
//
if(mChangeLocal)
cFileUtil::TestFileWritable(mLocalKeyFile);
if(mChangeSite)
cFileUtil::TestFileWritable(mSiteKeyFile);
wc16_string verify;
bool bPrintedPassphraseHint = false;
if (mChangeSite)
{
if (!mSiteProvidedOld)
{
cTWUtil::NoEcho noEcho;
// Note: Since we are interacting directly with the user here,
// I think it is o.k. to use cout directly.
TCOUT << TSS_GetString(cTWAdmin, twadmin::STR_ENTER_SITE_PASS_OLD);
cTWUtil::GetString(mSitePassphraseOld);
TCOUT << TSS_GetString(cTW, tw::STR_NEWLINE);
}
if (!mSiteProvided)
{
// give the user a passphrase hint...
//
if(! bPrintedPassphraseHint)
{
bPrintedPassphraseHint = true;
iUserNotify::GetInstance()->Notify( iUserNotify::V_NORMAL, TSS_GetString(cTWAdmin, twadmin::STR_PASSPHRASE_HINT).c_str() );
}
for (i=1; ; i++)
{
cTWUtil::NoEcho noEcho;
// Note: Since we are interacting directly with the user here,
// I think it is o.k. to use cout directly.
TCOUT << TSS_GetString(cTWAdmin, twadmin::STR_ENTER_SITE_PASS);
cTWUtil::GetString(mSitePassphrase);
TCOUT << TSS_GetString(cTW, tw::STR_NEWLINE);
TCOUT << TSS_GetString(cTWAdmin, twadmin::STR_VERIFY_SITE_PASS);
cTWUtil::GetString(verify);
TCOUT << TSS_GetString(cTW, tw::STR_NEWLINE);
if ( 0 == verify.compare( mSitePassphrase ) )
break;
TCOUT << TSS_GetString(cTW, tw::STR_ERR_WRONG_PASSPHRASE_SITE) << std::endl;
if (i == 3)
return 1;
}
}
iUserNotify::GetInstance()->Notify(iUserNotify::V_VERBOSE,
TSS_GetString(cTWAdmin, twadmin::STR_KEYGEN_VERBOSE_SITEKEY).c_str(),
cDisplayEncoder::EncodeInline( mSiteKeyFile ).c_str());
// backup current file if it exists
cFileUtil::BackupFile(mSiteKeyFile);
if (ChangePassphrase(mSiteKeyFile.c_str(), mSitePassphraseOld, mSitePassphrase) == false)
return 1;
}
if (mChangeLocal)
{
if (!mLocalProvidedOld)
{
cTWUtil::NoEcho noEcho;
// Note: Since we are interacting directly with the user here,
// I think it is o.k. to use cout directly.
TCOUT << TSS_GetString(cTWAdmin, twadmin::STR_ENTER_LOCAL_PASS_OLD);
cTWUtil::GetString(mLocalPassphraseOld);
TCOUT << TSS_GetString(cTW, tw::STR_NEWLINE);
}
if (!mLocalProvided)
{
// give the user a passphrase hint...
//
if(! bPrintedPassphraseHint)
{
bPrintedPassphraseHint = true;
iUserNotify::GetInstance()->Notify( iUserNotify::V_NORMAL, TSS_GetString(cTWAdmin, twadmin::STR_PASSPHRASE_HINT).c_str() );
}
for (i=1; ; i++)
{
cTWUtil::NoEcho noEcho;
// Note: Since we are interacting directly with the user here,
// I think it is o.k. to use cout directly.
TCOUT << TSS_GetString(cTWAdmin, twadmin::STR_ENTER_LOCAL_PASS);
cTWUtil::GetString(mLocalPassphrase);
TCOUT << TSS_GetString(cTW, tw::STR_NEWLINE);
TCOUT << TSS_GetString(cTWAdmin, twadmin::STR_VERIFY_LOCAL_PASS);
cTWUtil::GetString(verify);
TCOUT << TSS_GetString(cTW, tw::STR_NEWLINE);
if ( 0 == verify.compare( mLocalPassphrase ) )
break;
TCOUT << TSS_GetString(cTW, tw::STR_ERR_WRONG_PASSPHRASE_LOCAL) << std::endl;
if (i == 3)
return 1;
}
}
iUserNotify::GetInstance()->Notify(iUserNotify::V_VERBOSE,
TSS_GetString(cTWAdmin, twadmin::STR_KEYGEN_VERBOSE_LOCALKEY).c_str(),
cDisplayEncoder::EncodeInline( mLocalKeyFile ).c_str());
// backup current file if it exists
cFileUtil::BackupFile(mLocalKeyFile);
if (ChangePassphrase(mLocalKeyFile.c_str(), mLocalPassphraseOld, mLocalPassphrase) == false)
return 1;
}
return 0;
}
//#############################################################################
// cTWAModeHelp : A mode for supplying mode specific usage statements
//#############################################################################
class cTWAModeHelp : public iTWAMode
{
public:
cTWAModeHelp() {}
virtual ~cTWAModeHelp() {}
virtual void InitCmdLineParser(cCmdLineParser& cmdLine);
virtual bool Init (const cConfigFile* cf, const cCmdLineParser& cmdLine);
virtual int Execute (cErrorQueue* pQueue);
virtual cTWAdminCmdLine::CmdLineArgs GetModeID ( void ) const;
virtual TSTRING GetModeUsage( ) { return _T(""); } //TODO: dra Output something here?
private:
// A list of modes to output usage statements for:
std::set< TSTRING > mModes;
std::set< TSTRING > mPrinted;
};
///////////////////////////////////////////////////////////////////////////////
// GetModeID
///////////////////////////////////////////////////////////////////////////////
cTWAdminCmdLine::CmdLineArgs cTWAModeHelp::GetModeID( void ) const
{
return cTWAdminCmdLine::MODE_HELP;
}
///////////////////////////////////////////////////////////////////////////////
// InitCmdLineParser
///////////////////////////////////////////////////////////////////////////////
void cTWAModeHelp::InitCmdLineParser(cCmdLineParser& cmdLine)
{
// We're only interested in one parameter, that being help. Anything else
// passed to this mode should be a cmdlineparser error.
cmdLine.AddArg(cTWAdminCmdLine::MODE, TSTRING(_T("m")), TSTRING(_T("")), cCmdLineParser::PARAM_MANY, true );
cmdLine.AddArg(cTWAdminCmdLine::MODE_HELP, TSTRING(_T("?")), TSTRING(_T("help")), cCmdLineParser::PARAM_MANY);
cmdLine.AddArg(cTWAdminCmdLine::MODE_HELP_ALL, TSTRING(_T("")), TSTRING(_T("all")), cCmdLineParser::PARAM_MANY);
cmdLine.AddArg(cTWAdminCmdLine::MODE_CREATE_CONFIG, TSTRING(_T("F")), TSTRING(_T("create-cfgfile")), cCmdLineParser::PARAM_MANY);
cmdLine.AddArg(cTWAdminCmdLine::MODE_PRINT_CONFIG, TSTRING(_T("f")), TSTRING(_T("print-cfgfile")), cCmdLineParser::PARAM_MANY);
cmdLine.AddArg(cTWAdminCmdLine::MODE_CREATE_POLICY, TSTRING(_T("P")), TSTRING(_T("create-polfile")), cCmdLineParser::PARAM_MANY);
cmdLine.AddArg(cTWAdminCmdLine::MODE_PRINT_POLICY, TSTRING(_T("p")), TSTRING(_T("print-polfile")), cCmdLineParser::PARAM_MANY);
cmdLine.AddArg(cTWAdminCmdLine::MODE_REMOVE_ENCRYPTION, TSTRING(_T("R")), TSTRING(_T("remove-encryption")), cCmdLineParser::PARAM_MANY);
cmdLine.AddArg(cTWAdminCmdLine::MODE_ENCRYPT, TSTRING(_T("E")), TSTRING(_T("encrypt")), cCmdLineParser::PARAM_MANY);
cmdLine.AddArg(cTWAdminCmdLine::MODE_EXAMINE, TSTRING(_T("e")), TSTRING(_T("examine")), cCmdLineParser::PARAM_MANY);
cmdLine.AddArg(cTWAdminCmdLine::MODE_GENERATE_KEYS, TSTRING(_T("G")), TSTRING(_T("generate-keys")), cCmdLineParser::PARAM_MANY);
cmdLine.AddArg(cTWAdminCmdLine::MODE_CHANGE_PASSPHRASES,TSTRING(_T("C")), TSTRING(_T("change-passphrases")), cCmdLineParser::PARAM_MANY);
}
///////////////////////////////////////////////////////////////////////////////
// Init
///////////////////////////////////////////////////////////////////////////////
bool cTWAModeHelp::Init(const cConfigFile* cf, const cCmdLineParser& cmdLine)
{
cCmdLineIter iter(cmdLine);
// Grab the arguments from the help parameter:
for(iter.SeekBegin(); ! iter.Done(); iter.Next())
{
switch(iter.ArgId())
{
case cTWAdminCmdLine::MODE_HELP:
{
int i;
for( i = 0; i < iter.NumParams(); ++i )
{
mModes.insert( iter.ParamAt(i) );
}
}
break;
case cTWAdminCmdLine::MODE:
{
int i;
for( i = 0; i < iter.NumParams(); ++i )
{
mModes.insert( iter.ParamAt(i) );
}
}
break;
case cTWAdminCmdLine::MODE_HELP_ALL: //fall through
case cTWAdminCmdLine::MODE_CREATE_CONFIG: //fall through
case cTWAdminCmdLine::MODE_PRINT_CONFIG: //fall through
case cTWAdminCmdLine::MODE_CREATE_POLICY: //fall through
case cTWAdminCmdLine::MODE_PRINT_POLICY: //fall through
case cTWAdminCmdLine::MODE_REMOVE_ENCRYPTION: //fall through
case cTWAdminCmdLine::MODE_ENCRYPT: //fall through
case cTWAdminCmdLine::MODE_EXAMINE: //fall through
case cTWAdminCmdLine::MODE_GENERATE_KEYS:
case cTWAdminCmdLine::MODE_CHANGE_PASSPHRASES:
{
int i;
TSTRING str = iter.ActualParam();
// Kill off the initial "--" or "-"
str.erase( 0, 1 );
if( str.length() != 1)
str.erase( 0, 1 );
// push back the parameter that was actually passed.
mModes.insert( str );
// grab all the "parameters" following the mode/switch, since
// they may be valid modes without the "--" prepended.
for( i = 0; i < iter.NumParams(); ++i )
mModes.insert( iter.ParamAt(i) );
}
break;
default:
// should I do anything, or just ignore this?
// cmdlineparser will catch the bad args.
;
}
}
return true;
}
///////////////////////////////////////////////////////////////////////////////
// Execute
///////////////////////////////////////////////////////////////////////////////
int cTWAModeHelp::Execute(cErrorQueue* pQueue)
{
cDebug d("cTWAModeHelp::Execute");
// The iterator we will use to traverse the list of arguments:
std::set< TSTRING >::iterator it = mModes.begin();
// We'll want to output the version information, regardless:
TCOUT<< TSS_GetString(cTWAdmin, twadmin::STR_TWADMIN_VERSION ) << std::endl;
TCOUT<< TSS_GetString(cTW, tw::STR_VERSION ) << std::endl;
if( it == mModes.end() ) // all that was passed was --help
{
// Output a shorter usage statement for each mode
TCOUT<< TSS_GetString(cTWAdmin, twadmin::STR_TWADMIN_USAGE_SUMMARY);
//
//That's it, return
return 1;
}
for( ; it != mModes.end(); ++it )
{
if( _tcscmp( (*it).c_str(), _T("all")) == 0 )
{
//Since --help all was passed, emit all help messages and return.
TCOUT<< TSS_GetString( cTWAdmin, twadmin::STR_TWADMIN_HELP_CREATE_CFGFILE );
TCOUT<< TSS_GetString( cTWAdmin, twadmin::STR_TWADMIN_HELP_PRINT_CFGFILE );
TCOUT<< TSS_GetString( cTWAdmin, twadmin::STR_TWADMIN_HELP_CREATE_POLFILE );
TCOUT<< TSS_GetString( cTWAdmin, twadmin::STR_TWADMIN_HELP_PRINT_POLFILE );
TCOUT<< TSS_GetString( cTWAdmin, twadmin::STR_TWADMIN_HELP_REMOVE_ENCRYPTION );
TCOUT<< TSS_GetString( cTWAdmin, twadmin::STR_TWADMIN_HELP_ENCRYPT );
TCOUT<< TSS_GetString( cTWAdmin, twadmin::STR_TWADMIN_HELP_EXAMINE );
TCOUT<< TSS_GetString( cTWAdmin, twadmin::STR_TWADMIN_HELP_GENERATE_KEYS );
TCOUT<< TSS_GetString( cTWAdmin, twadmin::STR_TWADMIN_HELP_CHANGE_PASSPHRASES );
//We're done, return
return 1;
}
}
//We need some subset of the usage statements. Figure out which modes have
//been specified:
it = mModes.begin();
for( ; it != mModes.end(); ++it )
{
if ( _tcscmp( (*it).c_str(), _T("create-cfgfile") ) == 0 || _tcscmp( (*it).c_str(), _T("F") ) == 0)
{
//make sure we don't print the same help twice...
if( mPrinted.find(_T("create-cfgfile")) == mPrinted.end() )
{
TCOUT<< TSS_GetString( cTWAdmin, twadmin::STR_TWADMIN_HELP_CREATE_CFGFILE );
mPrinted.insert(_T("create-cfgfile"));
}
}
else if( _tcscmp( (*it).c_str(), _T("print-cfgfile") ) == 0 || _tcscmp( (*it).c_str(), _T("f") ) == 0)
{
if( mPrinted.find(_T("print-cfgfile")) == mPrinted.end() )
{
TCOUT<< TSS_GetString( cTWAdmin, twadmin::STR_TWADMIN_HELP_PRINT_CFGFILE );
mPrinted.insert(_T("print-cfgfile"));
}
}
else if( _tcscmp( (*it).c_str(), _T("create-polfile") ) == 0 || _tcscmp( (*it).c_str(), _T("P") ) == 0)
{
if( mPrinted.find(_T("create-polfile")) == mPrinted.end() )
{
TCOUT<< TSS_GetString( cTWAdmin, twadmin::STR_TWADMIN_HELP_CREATE_POLFILE );
mPrinted.insert(_T("create-polfile"));
}
}
else if( _tcscmp( (*it).c_str(), _T("print-polfile") ) == 0 || _tcscmp( (*it).c_str(), _T("p") ) == 0)
{
if( mPrinted.find(_T("print-polfile")) == mPrinted.end() )
{
TCOUT<< TSS_GetString( cTWAdmin, twadmin::STR_TWADMIN_HELP_PRINT_POLFILE );
mPrinted.insert(_T("print-polfile"));
}
}
else if( _tcscmp( (*it).c_str(), _T("remove-encryption") ) == 0 || _tcscmp( (*it).c_str(), _T("R") ) == 0)
{
if( mPrinted.find(_T("remove-encryption")) == mPrinted.end() )
{
TCOUT<< TSS_GetString( cTWAdmin, twadmin::STR_TWADMIN_HELP_REMOVE_ENCRYPTION );
mPrinted.insert(_T("remove-encryption"));
}
}
else if( _tcscmp( (*it).c_str(), _T("encrypt") ) == 0 || _tcscmp( (*it).c_str(), _T("E") ) == 0)
{
if( mPrinted.find(_T("encrypt")) == mPrinted.end() )
{
TCOUT<< TSS_GetString( cTWAdmin, twadmin::STR_TWADMIN_HELP_ENCRYPT );
mPrinted.insert(_T("encrypt"));
}
}
else if( _tcscmp( (*it).c_str(), _T("examine") ) == 0 || _tcscmp( (*it).c_str(), _T("e") ) == 0)
{
if( mPrinted.find(_T("examine")) == mPrinted.end() )
{
TCOUT<< TSS_GetString( cTWAdmin, twadmin::STR_TWADMIN_HELP_EXAMINE );
mPrinted.insert(_T("examine"));
}
}
else if( _tcscmp( (*it).c_str(), _T("generate-keys") ) == 0 || _tcscmp( (*it).c_str(), _T("G") ) == 0)
{
if( mPrinted.find(_T("generate-keys")) == mPrinted.end() )
{
TCOUT<< TSS_GetString( cTWAdmin, twadmin::STR_TWADMIN_HELP_GENERATE_KEYS );
mPrinted.insert(_T("generate-keys"));
}
}
else if( _tcscmp( (*it).c_str(), _T("change-passphrases") ) == 0 || _tcscmp( (*it).c_str(), _T("C") ) == 0)
{
if( mPrinted.find(_T("change-passphrases")) == mPrinted.end() )
{
TCOUT<< TSS_GetString( cTWAdmin, twadmin::STR_TWADMIN_HELP_CHANGE_PASSPHRASES );
mPrinted.insert(_T("change-passphrases"));
}
}
else
{
cTWUtil::PrintErrorMsg( eTWAInvalidHelpMode( (*it), eError::NON_FATAL ) );
TCOUT << std::endl;
// emit error string, this mode does not exist
}
}
//Everything went okay
return 1;
}
///////////////////////////////////////////////////////////////////////////////
// Version Mode
///////////////////////////////////////////////////////////////////////////////
class cTWAModeVersion : public iTWAMode
{
public:
cTWAModeVersion() {}
virtual ~cTWAModeVersion() {}
virtual void InitCmdLineParser(cCmdLineParser& cmdLine) { ASSERT(false); }
virtual bool Init (const cConfigFile* cf, const cCmdLineParser& cmdLine) { ASSERT(false); return true; }
virtual int Execute (cErrorQueue* pQueue) { ASSERT(false); return 0; }
virtual TSTRING GetModeUsage( ) { ASSERT(false); return _T(""); }
virtual cTWAdminCmdLine::CmdLineArgs GetModeID() const { return cTWAdminCmdLine::MODE_VERSION; }
private:
};
//#############################################################################
///////////////////////////////////////////////////////////////////////////////
// cTWAdminCmdLine::GetMode()
//
iTWAMode* cTWAdminCmdLine::GetMode(int argc, const TCHAR *const * argv)
{
// note -- it is assumed the executable name is the first parameter
if(argc < 2)
{
iUserNotify::GetInstance()->Notify(iUserNotify::V_SILENT, _T("%s"), TSS_GetString(cTWAdmin, twadmin::STR_TWADMIN_VERSION).c_str());
iUserNotify::GetInstance()->Notify(iUserNotify::V_SILENT, TSS_GetString(cTW, tw::STR_NEWLINE).c_str());
iUserNotify::GetInstance()->Notify(iUserNotify::V_SILENT, _T("%s"), TSS_GetString(cTW, tw::STR_VERSION).c_str());
iUserNotify::GetInstance()->Notify(iUserNotify::V_SILENT, TSS_GetString(cTW, tw::STR_NEWLINE).c_str());
iUserNotify::GetInstance()->Notify(iUserNotify::V_SILENT, _T("%s"), TSS_GetString(cTW, tw::STR_GET_HELP).c_str());
iUserNotify::GetInstance()->Notify(iUserNotify::V_SILENT, TSS_GetString(cTW, tw::STR_NEWLINE).c_str());
return NULL;
}
int mode = MODE;
const TCHAR* pcMode;
if(_tcscmp(argv[1], _T("-m")) == 0)
{
if(argc < 3)
{
iUserNotify::GetInstance()->Notify(iUserNotify::V_SILENT, _T("%s"), TSS_GetString(cTWAdmin, twadmin::STR_TWADMIN_VERSION).c_str());
iUserNotify::GetInstance()->Notify(iUserNotify::V_SILENT, TSS_GetString(cTW, tw::STR_NEWLINE).c_str());
iUserNotify::GetInstance()->Notify(iUserNotify::V_SILENT, _T("%s"), TSS_GetString(cTW, tw::STR_VERSION).c_str());
iUserNotify::GetInstance()->Notify(iUserNotify::V_SILENT, TSS_GetString(cTW, tw::STR_NEWLINE).c_str());
cTWUtil::PrintErrorMsg(eBadCmdLine(TSS_GetString(cTW, tw::STR_ERR_NO_MODE), eError::SUPRESS_THIRD_MSG));
iUserNotify::GetInstance()->Notify(iUserNotify::V_SILENT, _T("%s"), TSS_GetString(cTW, tw::STR_GET_HELP).c_str());
iUserNotify::GetInstance()->Notify(iUserNotify::V_SILENT, TSS_GetString(cTW, tw::STR_NEWLINE).c_str());
return NULL;
}
pcMode = argv[2];
if (_tcscmp(argv[2], _T("F")) == 0)
mode = MODE_CREATE_CONFIG;
else if (_tcscmp(argv[2], _T("f")) == 0)
mode = MODE_PRINT_CONFIG;
else if (_tcscmp(argv[2], _T("P")) == 0)
mode = MODE_CREATE_POLICY;
else if (_tcscmp(argv[2], _T("p")) == 0)
mode = MODE_PRINT_POLICY;
else if (_tcscmp(argv[2], _T("R")) == 0)
mode = MODE_REMOVE_ENCRYPTION;
else if (_tcscmp(argv[2], _T("E")) == 0)
mode = MODE_ENCRYPT;
else if (_tcscmp(argv[2], _T("e")) == 0)
mode = MODE_EXAMINE;
else if (_tcscmp(argv[2], _T("G")) == 0)
mode = MODE_GENERATE_KEYS;
else if (_tcscmp(argv[2], _T("C")) == 0)
mode = MODE_CHANGE_PASSPHRASES;
}
else
{
pcMode = argv[1];
if (_tcscmp(argv[1], _T("--create-cfgfile")) == 0)
mode = MODE_CREATE_CONFIG;
else if (_tcscmp(argv[1], _T("--print-cfgfile")) == 0)
mode = MODE_PRINT_CONFIG;
else if (_tcscmp(argv[1], _T("--create-polfile")) == 0)
mode = MODE_CREATE_POLICY;
else if (_tcscmp(argv[1], _T("--print-polfile")) == 0)
mode = MODE_PRINT_POLICY;
else if (_tcscmp(argv[1], _T("--remove-encryption")) == 0)
mode = MODE_REMOVE_ENCRYPTION;
else if (_tcscmp(argv[1], _T("--encrypt")) == 0)
mode = MODE_ENCRYPT;
else if (_tcscmp(argv[1], _T("--examine")) == 0)
mode = MODE_EXAMINE;
else if (_tcscmp(argv[1], _T("--generate-keys")) == 0)
mode = MODE_GENERATE_KEYS;
else if (_tcscmp(argv[1], _T("--change-passphrases")) == 0)
mode = MODE_CHANGE_PASSPHRASES;
else if (_tcscmp(argv[1], _T("--version")) == 0)
mode = MODE_VERSION;
}
// check for --help flag anywhere in the args
int i;
for (i = 1; i < argc; ++i)
if (_tcscmp(argv[i], _T("--help")) == 0 || _tcscmp(argv[i], _T("-?")) == 0)
{
mode = MODE_HELP;
break;
}
if(mode == MODE)
{
// unknown mode switch
cDebug d("cTWAdminCmdLine::GetMode");
d.TraceError("Error: Bad mode switch: %s\n", pcMode);
TSTRING estr = TSS_GetString(cTW, tw::STR_ERR2_BAD_MODE_SWITCH);
estr.append(pcMode);
cTWUtil::PrintErrorMsg(eBadModeSwitch(estr, eError::SUPRESS_THIRD_MSG));
iUserNotify::GetInstance()->Notify(iUserNotify::V_SILENT, _T("%s"), TSS_GetString(cTW, tw::STR_GET_HELP).c_str());
iUserNotify::GetInstance()->Notify(iUserNotify::V_SILENT, TSS_GetString(cTW, tw::STR_NEWLINE).c_str());
return NULL;
}
iTWAMode* pRtn = 0;
switch(mode)
{
case MODE_CREATE_CONFIG:
pRtn = new cTWAModeCreateCfg;
break;
case MODE_CREATE_POLICY:
pRtn = new cTWAModeCreatePol;
break;
case MODE_PRINT_CONFIG:
pRtn = new cTWAModePrintCfg;
break;
case MODE_PRINT_POLICY:
pRtn = new cTWAModePrintPol;
break;
case MODE_REMOVE_ENCRYPTION:
pRtn = new cTWAModeRemoveEncryption;
break;
case MODE_ENCRYPT:
pRtn = new cTWAModeEncrypt;
break;
case MODE_EXAMINE:
pRtn = new cTWAModeExamine;
break;
case MODE_GENERATE_KEYS:
pRtn = new cTWAModeGenerateKeys;
break;
case MODE_CHANGE_PASSPHRASES:
pRtn = new cTWAModeChangePassphrases;
break;
case MODE_HELP:
pRtn = new cTWAModeHelp;
break;
case MODE_VERSION:
pRtn = new cTWAModeVersion;
break;
default:
ASSERT(false);
}
return pRtn;
}
// Calls UserNotify(V_VERBOSE, ...) to print out type of file specified in cFileHeaderID.
// Returns false if cFileHeaderID not recognized.
// Used in changing and removing encryption algorithms
static bool NotifyFileType(const cFileHeaderID& id, uint32 version, iUserNotify::VerboseLevel vl)
{
if (id == cFCODatabaseFile::GetFileHeaderID())
{
iUserNotify::GetInstance()->Notify(vl,
TSS_GetString(cTWAdmin, twadmin::STR_FILE_TYPE_DB).c_str(),
(version & 0xff000000) >> 24,
(version & 0x00ff0000) >> 16,
(version & 0x0000ff00) >> 8,
(version & 0x000000ff));
return true;
}
else if (id == cFCOReport::GetFileHeaderID())
{
iUserNotify::GetInstance()->Notify(vl,
TSS_GetString(cTWAdmin, twadmin::STR_FILE_TYPE_REP).c_str(),
(version & 0xff000000) >> 24,
(version & 0x00ff0000) >> 16,
(version & 0x0000ff00) >> 8,
(version & 0x000000ff));
return true;
}
else if (id == cConfigFile::GetFileHeaderID())
{
iUserNotify::GetInstance()->Notify(vl,
TSS_GetString(cTWAdmin, twadmin::STR_FILE_TYPE_CFG).c_str(),
(version & 0xff000000) >> 24,
(version & 0x00ff0000) >> 16,
(version & 0x0000ff00) >> 8,
(version & 0x000000ff));
return true;
}
else if (id == cPolicyFile::GetFileHeaderID())
{
iUserNotify::GetInstance()->Notify(vl,
TSS_GetString(cTWAdmin, twadmin::STR_FILE_TYPE_POL).c_str(),
(version & 0xff000000) >> 24,
(version & 0x00ff0000) >> 16,
(version & 0x0000ff00) >> 8,
(version & 0x000000ff));
return true;
}
else if (id == cKeyFile::GetFileHeaderID())
{
iUserNotify::GetInstance()->Notify(vl,
TSS_GetString(cTWAdmin, twadmin::STR_FILE_TYPE_KEY).c_str(),
(version & 0xff000000) >> 24,
(version & 0x00ff0000) >> 16,
(version & 0x0000ff00) >> 8,
(version & 0x000000ff));
return true;
}
iUserNotify::GetInstance()->Notify(vl, TSS_GetString(cTWAdmin, twadmin::STR_FILE_TYPE_UNK).c_str());
return false;
}
// Calls UserNotify(V_VERBOSE, ...) to print out type of file specified in cFileHeaderID.
// Returns false if encoding not recognized.
// Used in changing and removing encryption algorithms
static bool NotifyEncryptionType(cFileHeader::Encoding encoding, iUserNotify::VerboseLevel vl)
{
switch (encoding)
{
case cFileHeader::NO_ENCODING:
iUserNotify::GetInstance()->Notify(vl, TSS_GetString(cTWAdmin, twadmin::STR_ENCRYPT_TYPE_NONE).c_str());
return true;
case cFileHeader::COMPRESSED:
iUserNotify::GetInstance()->Notify(vl, TSS_GetString(cTWAdmin, twadmin::STR_ENCRYPT_TYPE_COMP).c_str());
return true;
case cFileHeader::ASYM_ENCRYPTION:
iUserNotify::GetInstance()->Notify(vl, TSS_GetString(cTWAdmin, twadmin::STR_ENCRYPT_TYPE_ASYM).c_str());
return true;
}
iUserNotify::GetInstance()->Notify(vl, TSS_GetString(cTWAdmin, twadmin::STR_ENCRYPT_TYPE_UNK).c_str());
return false;
}