source: box/trunk/lib/backupstore/BackupStoreFilenameClear.cpp @ 3109

Revision 3109, 10.7 KB checked in by chris, 3 weeks ago (diff)

Revert r3106 as it causes compile failures not seen locally.

  • Property svn:eol-style set to native
Line 
1// --------------------------------------------------------------------------
2//
3// File
4//              Name:    BackupStoreFilenameClear.cpp
5//              Purpose: BackupStoreFilenames in the clear
6//              Created: 2003/08/26
7//
8// --------------------------------------------------------------------------
9
10#include "Box.h"
11#include "BackupStoreFilenameClear.h"
12#include "BackupStoreException.h"
13#include "CipherContext.h"
14#include "CipherBlowfish.h"
15#include "Guards.h"
16#include "Logging.h"
17
18#include "MemLeakFindOn.h"
19
20// Hide private variables from the rest of the world
21namespace
22{
23        int sEncodeMethod = BackupStoreFilename::Encoding_Clear;
24        CipherContext sBlowfishEncrypt;
25        CipherContext sBlowfishDecrypt;
26}
27
28// --------------------------------------------------------------------------
29//
30// Function
31//              Name:    BackupStoreFilenameClear::BackupStoreFilenameClear()
32//              Purpose: Default constructor, creates an invalid filename
33//              Created: 2003/08/26
34//
35// --------------------------------------------------------------------------
36BackupStoreFilenameClear::BackupStoreFilenameClear()
37{
38}
39
40// --------------------------------------------------------------------------
41//
42// Function
43//              Name:    BackupStoreFilenameClear::BackupStoreFilenameClear(const std::string &)
44//              Purpose: Creates a filename, encoding from the given string
45//              Created: 2003/08/26
46//
47// --------------------------------------------------------------------------
48BackupStoreFilenameClear::BackupStoreFilenameClear(const std::string &rToEncode)
49{
50        SetClearFilename(rToEncode);
51}
52
53// --------------------------------------------------------------------------
54//
55// Function
56//              Name:    BackupStoreFilenameClear::BackupStoreFilenameClear(const BackupStoreFilenameClear &)
57//              Purpose: Copy constructor
58//              Created: 2003/08/26
59//
60// --------------------------------------------------------------------------
61BackupStoreFilenameClear::BackupStoreFilenameClear(const BackupStoreFilenameClear &rToCopy)
62: BackupStoreFilename(rToCopy),
63  mClearFilename(rToCopy.mClearFilename)
64{
65}
66
67// --------------------------------------------------------------------------
68//
69// Function
70//              Name:    BackupStoreFilenameClear::BackupStoreFilenameClear(const BackupStoreFilename &rToCopy)
71//              Purpose: Copy from base class
72//              Created: 2003/08/26
73//
74// --------------------------------------------------------------------------
75BackupStoreFilenameClear::BackupStoreFilenameClear(const BackupStoreFilename &rToCopy)
76: BackupStoreFilename(rToCopy)
77{
78        // Will get a clear filename when it's required
79}
80
81// --------------------------------------------------------------------------
82//
83// Function
84//              Name:    BackupStoreFilenameClear::~BackupStoreFilenameClear()
85//              Purpose: Destructor
86//              Created: 2003/08/26
87//
88// --------------------------------------------------------------------------
89BackupStoreFilenameClear::~BackupStoreFilenameClear()
90{
91}
92
93// --------------------------------------------------------------------------
94//
95// Function
96//              Name:    BackupStoreFilenameClear::GetClearFilename()
97//              Purpose: Get the unencoded filename
98//              Created: 2003/08/26
99//
100// --------------------------------------------------------------------------
101#ifdef BACKUPSTOREFILEAME_MALLOC_ALLOC_BASE_TYPE
102const std::string BackupStoreFilenameClear::GetClearFilename() const
103{
104        MakeClearAvailable();
105        // When modifying, remember to change back to reference return if at all possible
106        // -- returns an object rather than a reference to allow easy use with other code.
107        return std::string(mClearFilename.c_str(), mClearFilename.size());
108}
109#else
110const std::string &BackupStoreFilenameClear::GetClearFilename() const
111{
112        MakeClearAvailable();
113        return mClearFilename;
114}
115const std::string &BackupStoreFilenameClear::GetClearFilenameIfPossible(const std::string& alternative) const
116{
117        if(mClearFilename.empty() && !(sBlowfishDecrypt.IsInitialised()))
118        {
119                // encrypted and cannot decrypt
120                return alternative;
121        }
122        else
123        {
124                return GetClearFilename();
125        }
126}
127#endif
128
129// --------------------------------------------------------------------------
130//
131// Function
132//              Name:    BackupStoreFilenameClear::SetClearFilename(const std::string &)
133//              Purpose: Encode and make available the clear filename
134//              Created: 2003/08/26
135//
136// --------------------------------------------------------------------------
137void BackupStoreFilenameClear::SetClearFilename(const std::string &rToEncode)
138{
139        // Only allow Blowfish encodings
140        if(sEncodeMethod != Encoding_Blowfish)
141        {
142                THROW_EXCEPTION(BackupStoreException, FilenameEncryptionNotSetup)
143        }
144
145        // Make an encoded string with blowfish encryption
146        EncryptClear(rToEncode, sBlowfishEncrypt, Encoding_Blowfish);
147               
148        // Store the clear filename
149        mClearFilename.assign(rToEncode.c_str(), rToEncode.size());
150
151        // Make sure we did the right thing
152        if(!CheckValid(false))
153        {
154                THROW_EXCEPTION(BackupStoreException, Internal)
155        }
156}
157
158// --------------------------------------------------------------------------
159//
160// Function
161//              Name:    BackupStoreFilenameClear::MakeClearAvailable()
162//              Purpose: Private. Make sure the clear filename is available
163//              Created: 2003/08/26
164//
165// --------------------------------------------------------------------------
166void BackupStoreFilenameClear::MakeClearAvailable() const
167{
168        if(!mClearFilename.empty())
169                return;         // nothing to do
170
171        // Check valid
172        CheckValid();
173               
174        // Decode the header
175        int size = BACKUPSTOREFILENAME_GET_SIZE(GetEncodedFilename());
176        int encoding = BACKUPSTOREFILENAME_GET_ENCODING(GetEncodedFilename());
177       
178        // Decode based on encoding given in the header
179        switch(encoding)
180        {
181        case Encoding_Clear:
182                BOX_WARNING("**** BackupStoreFilename encoded with "
183                        "Clear encoding ****");
184                mClearFilename.assign(GetEncodedFilename().c_str() + 2,
185                        size - 2);
186                break;
187               
188        case Encoding_Blowfish:
189                DecryptEncoded(sBlowfishDecrypt);
190                break;
191       
192        default:
193                THROW_EXCEPTION(BackupStoreException, UnknownFilenameEncoding)
194                break; 
195        }
196}
197
198
199// Buffer for encoding and decoding -- do this all in one single buffer to
200// avoid lots of string allocation, which stuffs up memory usage.
201// These static memory vars are, of course, not thread safe, but we don't use threads.
202static int sEncDecBufferSize = 0;
203static MemoryBlockGuard<uint8_t *> *spEncDecBuffer = 0;
204
205static void EnsureEncDecBufferSize(int BufSize)
206{
207        if(spEncDecBuffer == 0)
208        {
209#ifndef WIN32
210                BOX_TRACE("Allocating filename encoding/decoding buffer "
211                        "with size " << BufSize);
212#endif
213                spEncDecBuffer = new MemoryBlockGuard<uint8_t *>(BufSize);
214                MEMLEAKFINDER_NOT_A_LEAK(spEncDecBuffer);
215                MEMLEAKFINDER_NOT_A_LEAK(*spEncDecBuffer);
216                sEncDecBufferSize = BufSize;
217        }
218        else
219        {
220                if(sEncDecBufferSize < BufSize)
221                {
222                        BOX_TRACE("Reallocating filename encoding/decoding "
223                                "buffer from " << sEncDecBufferSize <<
224                                " to " << BufSize);
225                        spEncDecBuffer->Resize(BufSize);
226                        sEncDecBufferSize = BufSize;
227                        MEMLEAKFINDER_NOT_A_LEAK(*spEncDecBuffer);
228                }
229        }
230}
231
232// --------------------------------------------------------------------------
233//
234// Function
235//              Name:    BackupStoreFilenameClear::EncryptClear(const std::string &, CipherContext &, int)
236//              Purpose: Private. Assigns the encoded filename string, encrypting.
237//              Created: 1/12/03
238//
239// --------------------------------------------------------------------------
240void BackupStoreFilenameClear::EncryptClear(const std::string &rToEncode, CipherContext &rCipherContext, int StoreAsEncoding)
241{
242        // Work out max size
243        int maxOutSize = rCipherContext.MaxOutSizeForInBufferSize(rToEncode.size()) + 4;
244       
245        // Make sure encode/decode buffer has enough space
246        EnsureEncDecBufferSize(maxOutSize);
247       
248        // Pointer to buffer
249        uint8_t *buffer = *spEncDecBuffer;
250       
251        // Encode -- do entire block in one go
252        int encSize = rCipherContext.TransformBlock(buffer + 2, sEncDecBufferSize - 2, rToEncode.c_str(), rToEncode.size());
253        // and add in header size
254        encSize += 2;
255       
256        // Adjust header
257        BACKUPSTOREFILENAME_MAKE_HDR(buffer, encSize, StoreAsEncoding);
258       
259        // Store the encoded string
260        SetEncodedFilename(std::string((char*)buffer, encSize));
261}
262
263
264// --------------------------------------------------------------------------
265//
266// Function
267//              Name:    BackupStoreFilenameClear::DecryptEncoded(CipherContext &)
268//              Purpose: Decrypt the encoded filename using the cipher context
269//              Created: 1/12/03
270//
271// --------------------------------------------------------------------------
272void BackupStoreFilenameClear::DecryptEncoded(CipherContext &rCipherContext) const
273{
274        const std::string& rEncoded = GetEncodedFilename();
275
276        // Work out max size
277        int maxOutSize = rCipherContext.MaxOutSizeForInBufferSize(rEncoded.size()) + 4;
278       
279        // Make sure encode/decode buffer has enough space
280        EnsureEncDecBufferSize(maxOutSize);
281       
282        // Pointer to buffer
283        uint8_t *buffer = *spEncDecBuffer;
284       
285        // Decrypt
286        const char *str = rEncoded.c_str() + 2;
287        int sizeOut = rCipherContext.TransformBlock(buffer, sEncDecBufferSize, str, rEncoded.size() - 2);
288       
289        // Assign to this
290        mClearFilename.assign((char*)buffer, sizeOut);
291}
292
293
294// --------------------------------------------------------------------------
295//
296// Function
297//              Name:    BackupStoreFilenameClear::EncodedFilenameChanged()
298//              Purpose: The encoded filename stored has changed
299//              Created: 2003/08/26
300//
301// --------------------------------------------------------------------------
302void BackupStoreFilenameClear::EncodedFilenameChanged()
303{
304        BackupStoreFilename::EncodedFilenameChanged();
305
306        // Delete stored filename in clear
307        mClearFilename.erase();
308}
309
310
311// --------------------------------------------------------------------------
312//
313// Function
314//              Name:    BackupStoreFilenameClear::SetBlowfishKey(const void *, int)
315//              Purpose: Set the key used for Blowfish encryption of filenames
316//              Created: 1/12/03
317//
318// --------------------------------------------------------------------------
319void BackupStoreFilenameClear::SetBlowfishKey(const void *pKey, int KeyLength, const void *pIV, int IVLength)
320{
321        // Initialisation vector not used. Can't use a different vector for each filename as
322        // that would stop comparisions on the server working.
323        sBlowfishEncrypt.Reset();
324        sBlowfishEncrypt.Init(CipherContext::Encrypt, CipherBlowfish(CipherDescription::Mode_CBC, pKey, KeyLength));
325        ASSERT(sBlowfishEncrypt.GetIVLength() == IVLength);
326        sBlowfishEncrypt.SetIV(pIV);
327        sBlowfishDecrypt.Reset();
328        sBlowfishDecrypt.Init(CipherContext::Decrypt, CipherBlowfish(CipherDescription::Mode_CBC, pKey, KeyLength));
329        ASSERT(sBlowfishDecrypt.GetIVLength() == IVLength);
330        sBlowfishDecrypt.SetIV(pIV);
331}
332
333// --------------------------------------------------------------------------
334//
335// Function
336//              Name:    BackupStoreFilenameClear::SetEncodingMethod(int)
337//              Purpose: Set the encoding method used for filenames
338//              Created: 1/12/03
339//
340// --------------------------------------------------------------------------
341void BackupStoreFilenameClear::SetEncodingMethod(int Method)
342{
343        sEncodeMethod = Method;
344}
345
346
347
Note: See TracBrowser for help on using the repository browser.