// distribution boxbackup-0.10 (svn version: 494)
//
// Copyright (c) 2003 - 2006
// Ben Summers and contributors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. All use of this software and associated advertising materials must
// display the following acknowledgment:
// This product includes software developed by Ben Summers.
// 4. The names of the Authors may not be used to endorse or promote
// products derived from this software without specific prior written
// permission.
//
// [Where legally impermissible the Authors do not disclaim liability for
// direct physical injury or death caused solely by defects in the software
// unless it is modified by a third party.]
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//
//
// --------------------------------------------------------------------------
//
// File
// Name: BackupStoreFilenameClear.cpp
// Purpose: BackupStoreFilenames in the clear
// Created: 2003/08/26
//
// --------------------------------------------------------------------------
#include "Box.h"
#include "BackupStoreFilenameClear.h"
#include "BackupStoreException.h"
#include "CipherContext.h"
#include "CipherBlowfish.h"
#include "Guards.h"
#include "MemLeakFindOn.h"
// Hide private variables from the rest of the world
namespace
{
int sEncodeMethod = BackupStoreFilename::Encoding_Clear;
CipherContext sBlowfishEncrypt;
CipherContext sBlowfishDecrypt;
}
// --------------------------------------------------------------------------
//
// Function
// Name: BackupStoreFilenameClear::BackupStoreFilenameClear()
// Purpose: Default constructor, creates an invalid filename
// Created: 2003/08/26
//
// --------------------------------------------------------------------------
BackupStoreFilenameClear::BackupStoreFilenameClear()
{
}
// --------------------------------------------------------------------------
//
// Function
// Name: BackupStoreFilenameClear::BackupStoreFilenameClear(const std::string &)
// Purpose: Creates a filename, encoding from the given string
// Created: 2003/08/26
//
// --------------------------------------------------------------------------
BackupStoreFilenameClear::BackupStoreFilenameClear(const std::string &rToEncode)
{
SetClearFilename(rToEncode);
}
// --------------------------------------------------------------------------
//
// Function
// Name: BackupStoreFilenameClear::BackupStoreFilenameClear(const BackupStoreFilenameClear &)
// Purpose: Copy constructor
// Created: 2003/08/26
//
// --------------------------------------------------------------------------
BackupStoreFilenameClear::BackupStoreFilenameClear(const BackupStoreFilenameClear &rToCopy)
: BackupStoreFilename(rToCopy),
mClearFilename(rToCopy.mClearFilename)
{
}
// --------------------------------------------------------------------------
//
// Function
// Name: BackupStoreFilenameClear::BackupStoreFilenameClear(const BackupStoreFilename &rToCopy)
// Purpose: Copy from base class
// Created: 2003/08/26
//
// --------------------------------------------------------------------------
BackupStoreFilenameClear::BackupStoreFilenameClear(const BackupStoreFilename &rToCopy)
: BackupStoreFilename(rToCopy)
{
// Will get a clear filename when it's required
}
// --------------------------------------------------------------------------
//
// Function
// Name: BackupStoreFilenameClear::~BackupStoreFilenameClear()
// Purpose: Destructor
// Created: 2003/08/26
//
// --------------------------------------------------------------------------
BackupStoreFilenameClear::~BackupStoreFilenameClear()
{
}
// --------------------------------------------------------------------------
//
// Function
// Name: BackupStoreFilenameClear::GetClearFilename()
// Purpose: Get the unencoded filename
// Created: 2003/08/26
//
// --------------------------------------------------------------------------
#ifdef BACKUPSTOREFILEAME_MALLOC_ALLOC_BASE_TYPE
const std::string BackupStoreFilenameClear::GetClearFilename() const
{
MakeClearAvailable();
// When modifying, remember to change back to reference return if at all possible
// -- returns an object rather than a reference to allow easy use with other code.
return std::string(mClearFilename.c_str(), mClearFilename.size());
}
#else
const std::string &BackupStoreFilenameClear::GetClearFilename() const
{
MakeClearAvailable();
return mClearFilename;
}
#endif
// --------------------------------------------------------------------------
//
// Function
// Name: BackupStoreFilenameClear::SetClearFilename(const std::string &)
// Purpose: Encode and make available the clear filename
// Created: 2003/08/26
//
// --------------------------------------------------------------------------
void BackupStoreFilenameClear::SetClearFilename(const std::string &rToEncode)
{
// Only allow Blowfish encodings
if(sEncodeMethod != Encoding_Blowfish)
{
THROW_EXCEPTION(BackupStoreException, FilenameEncryptionNotSetup)
}
// Make an encoded string with blowfish encryption
EncryptClear(rToEncode, sBlowfishEncrypt, Encoding_Blowfish);
// Store the clear filename
mClearFilename.assign(rToEncode.c_str(), rToEncode.size());
// Make sure we did the right thing
if(!CheckValid(false))
{
THROW_EXCEPTION(BackupStoreException, Internal)
}
}
// --------------------------------------------------------------------------
//
// Function
// Name: BackupStoreFilenameClear::MakeClearAvailable()
// Purpose: Private. Make sure the clear filename is available
// Created: 2003/08/26
//
// --------------------------------------------------------------------------
void BackupStoreFilenameClear::MakeClearAvailable() const
{
if(!mClearFilename.empty())
return; // nothing to do
// Check valid
CheckValid();
// Decode the header
int size = BACKUPSTOREFILENAME_GET_SIZE(*this);
int encoding = BACKUPSTOREFILENAME_GET_ENCODING(*this);
// Decode based on encoding given in the header
switch(encoding)
{
case Encoding_Clear:
TRACE0("**** BackupStoreFilename encoded with Clear encoding ****\n");
mClearFilename.assign(c_str() + 2, size - 2);
break;
case Encoding_Blowfish:
DecryptEncoded(sBlowfishDecrypt);
break;
default:
THROW_EXCEPTION(BackupStoreException, UnknownFilenameEncoding)
break;
}
}
// Buffer for encoding and decoding -- do this all in one single buffer to
// avoid lots of string allocation, which stuffs up memory usage.
// These static memory vars are, of course, not thread safe, but we don't use threads.
static int sEncDecBufferSize = 0;
static MemoryBlockGuard<uint8_t *> *spEncDecBuffer = 0;
static void EnsureEncDecBufferSize(int BufSize)
{
if(spEncDecBuffer == 0)
{
#ifndef WIN32
TRACE1("Allocating filename encoding/decoding buffer with size %d\n", BufSize);
#endif
spEncDecBuffer = new MemoryBlockGuard<uint8_t *>(BufSize);
MEMLEAKFINDER_NOT_A_LEAK(spEncDecBuffer);
MEMLEAKFINDER_NOT_A_LEAK(*spEncDecBuffer);
sEncDecBufferSize = BufSize;
}
else
{
if(sEncDecBufferSize < BufSize)
{
#ifndef WIN32
TRACE2("Reallocating filename encoding/decoding buffer from %d to %d\n", sEncDecBufferSize, BufSize);
#endif
spEncDecBuffer->Resize(BufSize);
sEncDecBufferSize = BufSize;
MEMLEAKFINDER_NOT_A_LEAK(*spEncDecBuffer);
}
}
}
// --------------------------------------------------------------------------
//
// Function
// Name: BackupStoreFilenameClear::EncryptClear(const std::string &, CipherContext &, int)
// Purpose: Private. Assigns the encoded filename string, encrypting.
// Created: 1/12/03
//
// --------------------------------------------------------------------------
void BackupStoreFilenameClear::EncryptClear(const std::string &rToEncode, CipherContext &rCipherContext, int StoreAsEncoding)
{
// Work out max size
int maxOutSize = rCipherContext.MaxOutSizeForInBufferSize(rToEncode.size()) + 4;
// Make sure encode/decode buffer has enough space
EnsureEncDecBufferSize(maxOutSize);
// Pointer to buffer
uint8_t *buffer = *spEncDecBuffer;
// Encode -- do entire block in one go
int encSize = rCipherContext.TransformBlock(buffer + 2, sEncDecBufferSize - 2, rToEncode.c_str(), rToEncode.size());
// and add in header size
encSize += 2;
// Adjust header
BACKUPSTOREFILENAME_MAKE_HDR(buffer, encSize, StoreAsEncoding);
// Store the encoded string
assign((char*)buffer, encSize);
}
// --------------------------------------------------------------------------
//
// Function
// Name: BackupStoreFilenameClear::DecryptEncoded(CipherContext &)
// Purpose: Decrypt the encoded filename using the cipher context
// Created: 1/12/03
//
// --------------------------------------------------------------------------
void BackupStoreFilenameClear::DecryptEncoded(CipherContext &rCipherContext) const
{
// Work out max size
int maxOutSize = rCipherContext.MaxOutSizeForInBufferSize(size()) + 4;
// Make sure encode/decode buffer has enough space
EnsureEncDecBufferSize(maxOutSize);
// Pointer to buffer
uint8_t *buffer = *spEncDecBuffer;
// Decrypt
const char *str = c_str() + 2;
int sizeOut = rCipherContext.TransformBlock(buffer, sEncDecBufferSize, str, size() - 2);
// Assign to this
mClearFilename.assign((char*)buffer, sizeOut);
}
// --------------------------------------------------------------------------
//
// Function
// Name: BackupStoreFilenameClear::EncodedFilenameChanged()
// Purpose: The encoded filename stored has changed
// Created: 2003/08/26
//
// --------------------------------------------------------------------------
void BackupStoreFilenameClear::EncodedFilenameChanged()
{
BackupStoreFilename::EncodedFilenameChanged();
// Delete stored filename in clear
mClearFilename.erase();
}
// --------------------------------------------------------------------------
//
// Function
// Name: BackupStoreFilenameClear::SetBlowfishKey(const void *, int)
// Purpose: Set the key used for Blowfish encryption of filenames
// Created: 1/12/03
//
// --------------------------------------------------------------------------
void BackupStoreFilenameClear::SetBlowfishKey(const void *pKey, int KeyLength, const void *pIV, int IVLength)
{
// Initialisation vector not used. Can't use a different vector for each filename as
// that would stop comparisions on the server working.
sBlowfishEncrypt.Reset();
sBlowfishEncrypt.Init(CipherContext::Encrypt, CipherBlowfish(CipherDescription::Mode_CBC, pKey, KeyLength));
ASSERT(sBlowfishEncrypt.GetIVLength() == IVLength);
sBlowfishEncrypt.SetIV(pIV);
sBlowfishDecrypt.Reset();
sBlowfishDecrypt.Init(CipherContext::Decrypt, CipherBlowfish(CipherDescription::Mode_CBC, pKey, KeyLength));
ASSERT(sBlowfishDecrypt.GetIVLength() == IVLength);
sBlowfishDecrypt.SetIV(pIV);
}
// --------------------------------------------------------------------------
//
// Function
// Name: BackupStoreFilenameClear::SetEncodingMethod(int)
// Purpose: Set the encoding method used for filenames
// Created: 1/12/03
//
// --------------------------------------------------------------------------
void BackupStoreFilenameClear::SetEncodingMethod(int Method)
{
sEncodeMethod = Method;
}
syntax highlighted by Code2HTML, v. 0.9.1