Encrypted File Storage System Documentation

Looking for a good, consistent, command-line driven backup and restore solution for Windows, Mac, and Linux with accurate timestamp, permissions, and owner/group replication? Or just looking to store data securely in a file structure without having to install or compile anything beyond PHP (i.e. not FUSE, not a PHP extension, and runs virtually everywhere)? Then the Encrypted File Storage System (EFSS) is what you are looking for. No, really, you can stop looking.

Important update: Over the past few months, I've been running into fundamental issues with EFSS. It's an experimental product after all, but there are several unfortunate, unsolvable issues. EFSS is most likely going to change from being a backup system to a file system where sensitive hierarchical data can be stored securely. It's a good product but it isn't suitable for conducting offsite backups to third-party services, which is what I really want/need. A new product will most likely be developed that balances both the EFSS and WebCron Site Backup worlds that takes the best of what I learned. EFSS will still be around, but the target audience is going to change fairly dramatically. Even then, EFSS may still play a significant role in backups - for example, put /etc/ on a Linux server into EFSS, then transfer the EFSS data store as part of the new product's backup routine. EFSS just won't be used for the entire backup process.

EFSS is a file system with transparent encryption and compression implemented in userland code in the PHP scripting language. It comes with a robust suite of tools to manage EFSS data stores that includes a command-line shell, a remote incremental backup push/pull manager, and a powerful library that can be used in various PHP programming projects. The specification for the file system is open to allow for portability to other programming languages. This file system is designed specifically for performing rapid rolling off-site incremental backups without needing to decrypt the encrypted blocks of data. This means off-site backup data can be sent to third-party backup providers without giving them direct access to your data. EFSS can also be used to meet needs such as storing hierarchical file-like data securely outside of a database in a low-write, moderate-read, PHP-based web environment.

Features

The Encrypted File Storage System is split into a class that implements the core functionality and a powerful set of tools for managing EFSS data stores. What follows is a short list of features:

And much more.

License

Like Barebones CMS, the Encrypted File Storage System (EFSS) is dual-licensed under a MIT or LGPL license - your choice. The license and restrictions are identical to the Barebones CMS License.

Donations

If you use this product, donate financially or with some of your time, to support future development efforts.

Download

EFSS 1.0RC11 is the eleventh release candidate of the Encrypted File Storage System.

Download efss-1.0rc11.zip

If you find the EFSS useful, please donate toward future development efforts.

EFSS Installation

Installing EFSS may require some programming skills depending upon what you need to do. Regardless, here is what you need to know to install it successfully:

Once the first data store is set up, use some of the other command-line tools to experiment with managing the data store. The command-line tools are documented shortly.

The dual AES256 keys allows for the key and IV pairs to be split. This is useful if you need ridiculous levels of protection for your application. For example, put each key and IV on a separate USB thumbdrive to give to two different people who both have to be present to access the data. Although, doing that for anything short of launching nukes is probably overkill.

Using EFSS For Backups

Everyone I know agrees that everyone needs to backup their files. However, for whatever reason, no one really likes to come out and say what files should be backed up. Maybe it is obvious, but I'm not really sure that it actually is obvious as to what we should back up. So I'm going to go out on a limb here and spell out a few things that should go into backups. Let's start with backups regarding files on personal computers:

For web servers, the list looks similar:

If you want to get up and running quickly, check out 'examples/mybackup_sync.php'. You'll have to modify it for your needs and is it primarily designed to back up a LAMP-based web server as the 'root' user, but it can be used for lots of other purposes too and is generally a nice starting point for a backup strategy. The script syncs data from multiple locations on the box into an EFSS data store and sends an e-mail report.

The EFSS command-line tool for cloning directories and files into an EFSS data store is 'sync.php'. The sync tool clones everything about a directory structure and files (data, permissions, owner, group, timestamp, and file size) from source to target but only does so when it detects that changes have happened in the source. The sync tool itself is generic enough that it can be used to clone items on the local system to another location on the local system (e.g. to an attached external hard drive), but that's not really the purpose of the tool - the primary purpose is to move files into and out of EFSS data stores.

The EFSS command-line tool for performing incremental backups of or to a remote resource is 'backup.php'. This tool depends on a web server to expose the official backup API in 'api/backup.php'. An example configuration for the backup API is available in 'api/config.php'.

One of the most important things to do with a backup is to make sure it actually works. The only way you are going to do that is if you put a reminder in your calendar. If you don't do this, you will regret it, especially with EFSS - if you lose your encryption keys or the EFSS data store somehow becomes corrupt, your EFSS data store will be useless. Backups are not fire-and-forget. They require active attention every so often and a monthly checkup is a great way to make sure that the backup gets the attention it needs. Making sure a backup works could be as simple as running the command-line tool 'check.php', which checks the health of a backup by exhaustively mounting each incremental and verifying that it can successfully access each block, directory, and file. If that test passes without issues, follow it up with a recursive directory listing with the 'shell.php' command-line tool using the most recent incremental and just giving the output a cursory look is usually sufficient.

Using EFSS Command-line Tools

EFSS comes with a suite of command-line tools for performing common maintenance tasks with EFSS data stores. Each command-line tool is written in PHP and utilizes the underlying 'support/efss.php' classes to manipulate and navigate EFSS data stores. Each tool has a number of options that can be seen by running the tool without any options. For example, running 'php create.php' will display the options for 'create.php'.

The following is a high-level breakdown of the command-line tools that are available:

Now for an example of a sequence of commands you might run on a Linux server (for the sake of example, hosting the domain yourserver.com):

Assuming a RESTful API is available, the data could be cloned using another computer (for example, your local machine) by running this command every day:

That would save up to 30 incrementals. Note that 'backup.php' does not clone the encryption keys (nor does it need to). The above assumes that 'https://yourserver.com/backup/' is a valid URL exposing a RESTful API. It might be a good idea to not name a directory 'backup' or 'efss_backup' on a web server. At least append some random letters and numbers to the end.

If you automate commands with cron or a similar task scheduler, don't forget that paths need to be absolute instead of relative or the backup files will probably end up in the wrong place (if they show up at all). An example script called 'mybackup_sync.php' is in the 'examples' directory. The script is intended to be used with automation mechanisms like 'cron' to get up and running quickly with a working backup system with reporting. When used correctly, the e-mail reports double as a basic (passive) intrusion detection system. In a corporate environment, the e-mail report can be used to verify changes to the file system with other staff members, holding each other accountable while remaining on the same page.

Configuring the Remote Backup API

The default configuration file in 'api/config.php' contains the default information required to make the optional test suite logic work correctly. However, you probably want to make it work with your setup. If you only have one backup file to deal with, then this is a matter of opening up the file and making changes to the various options.

The default configuration file is geared for a single backup scenario. It isn't that much harder to make it even more powerful by backing it with a MySQL database and web application. When upgrading, take care to not overwrite your own 'config.php' file with the default one.

Writing EFSS Shell Extensions

The shell is fairly powerful and can do a lot of common file system manipulation tasks as-is. The functionality of the shell is implemented in the default shell extension located inside the file 'shell_exts/main.php'. However, it is possible to write a new shell extension to add to the existing set of commands:

First, create a new PHP file inside the 'shell_exts' directory. This file will be loaded whenever 'shell.php' runs.

Next, write the new command. This is easier to do by looking through 'shell_exts/main.php' and finding a similar command to emulate. Each command inside the main file checks the user's input line, displays help information (if necessary), and executes the target command. Errors are displayed but don't cause the shell to exit. Commands take the format of "function shell_cmd_name($line)" where "name" is the command's name.

Finally, test the new command from within the shell.

If you know how to program and that sounds simple, it really is. The shell isn't exactly fancy or complicated because it is mostly just a convenient wrapper around the core EFSS classes located in 'support/efss.php'.

EFSS Limitations

Okay, so EFSS is not perfect. There are a few limitations of this software that hopefully won't be show stopper issues for you. If they are, the forums are there to discuss your needs. As far as I can tell, this is the first product of its kind, so there's probably lots of room for improvement.

One limitation to using EFSS for backups is that all data is encrypted. This means that the encryption keys will also need to be backed up somewhere safe, so that the data can be accessed at a later date. EFSS is designed so that the data can be stored on multiple systems without chugging insane amounts of bandwidth or wasting tons of time transferring zillions of little dinky files. (Transferring one 10MB file is a billion times faster than transferring 50,000 individual 200 byte files). Ideally, the incrementals for each backup EFSS data store are verified by mounting the file system and performing a check of the data for consistency. As long as one system doing backups has a copy of the encryption keys, it can perform occasional sanity checks beyond hash checking. But, of course, only put encryption keys on systems that are trusted.

Another limitation is that EFSS implements a real file system. Like most file systems, this means there will be file fragmentation over time. EFSS does its best to maintain order, but fragmentation is inevitable. EFSS comes with some basic defragmentation tools and the worst case scenario would be having to rebuild the EFSS data store from scratch, which is actually pretty easy to do and each EFSS data store has a unique 2KB serial so that rebuilds are detectable. The trick to avoiding fragmentation is to avoid deleting and recreating files, especially large ones. Let's say you export your multi-gigabyte database to a file. Instead of copying that file into EFSS every single time, store diffs instead and occasionally rebuild the EFSS data store.

Under PHP, there are theoretical, untested limits for EFSS data stores: EFSS data stores under 32-bit PHP are limited to roughly 8.7TB at the default block size of 4096 bytes (2^31 * 4KB). Incrementals are limited to 2.2TB at the default block size of 4096 bytes ((2^31 / 4) * 4096 -- the four comes from the block number mapping file) but it may be easier to think about the incremental limit in terms of the number of blocks (2^31 / 4 = 536.8 million blocks). The absolute limit of EFSS data stores is 70.3TB at a block size of 32,768 bytes (2^31 * 32KB). If you plan on storing more than 1GB of data in EFSS, be sure to run verification checks to make sure that EFSS isn't corrupting itself. However, performance will begin to suffer around 1GB of storage because the hacky solution to the 32-bit PHP 2GB limit is to use relative seeking in 1GB increments to locate each block. PHP will automatically switch to float/double precision when blocknum * blocksize requests exceed the size of an integer and this hacky solution to the problem assumes that floating-point precision is "good enough" to not mess up integer math but floating-point can get to be wonky at times. The test suite shows you where floating-point will fail (on my computer, floating point accuracy fails at ~9PB). If you have large data needs, let's talk on the forums.

EFSS is designed for reading data, not writing data. Performance when writing new files (transparent encryption and compression, after all) and creating new directories is a bit on the sluggish end of things. Reading data, however, is a bit faster, as is to be expected. Incremental backups, where nothing is decrypted, is ridiculously fast. If you need fast, multiple or concurrent writes, you might want to find another solution or open a dialog on the forums.

If an EFSS data store becomes corrupted, especially the first three blocks, there is currently no easy way to fix the data store so that it will mount. I've got a few ideas, but it will take time to implement them. It is better to test backups regularly anyway than rely on a repair tool that may or may not work. If you encounter data corruption with EFSS, ask on the forums.

How EFSS Works

A minimal EFSS data store consists of three files: The main encrypted block file, a file containing last updated timestamps for each block in the main file, and a 2KB file containing a unique serial. If you use 'create.php' to make an EFSS data store, it will also create a PHP file that the other command-line tools will use to be able to mount the file system (i.e. decrypt the block file).

On a backup computer, an EFSS data store will also likely contain "incrementals" that consist of a similar sort of structure to the three main files. There will also be two additional files - one that maps incremental blocks to the correct block location in the base file and one that contains hashes of each block. The hashes file allows the checking tool to verify the entire backup, including incrementals, more quickly.

The file containing the last updated timestamps is what makes performing rapid incremental backups possible. When data is written to an EFSS data store, the first block that is written may be intentionally delayed using sleep() to wait for the system clock to move up by one second past the first block's last write timestamp. You can observe this important behavior with the test suite whenever it "hangs" for a moment. The behavior guarantees that incrementals will always remain in step with the source. All that has to happen is to scan the last updated file for timestamps newer than what is being requested and only return those blocks of data. Scanning the last updated file is very fast even with large EFSS data sets.

EFSS tracks five different block types within the block file:

Linked lists start with a block number to the next block. The last node references block zero (an impossible reference) to indicate the termination point of the linked list.

A special type of file known as an "inline file" may be written as part of a directory block to avoid wasting space (i.e. file blocks are not used). The rule is that the file data must occupy less than 45% of the block size. If compression is available, the original, uncompressed data could potentially be slightly larger than 45% as long as the compressed data meets the 45% criteria. The shell can help identify inline files via the 'i' flag.

EFSS also does a lot of directory structure traversal operations to calculate absolute paths. A directory block cache exists to save blocks in RAM to avoid hitting the disk too frequently. The relevant directory block cache entry is wiped whenever an associated block is written to disk so that the block is loaded again on the next read operation. This approach does have a minor performance penalty but guarantees the stability of directory structures.

The Core EFSS Class

The power and flexibility of EFSS comes from the extensive core class creatively named 'EFSS' located inside the file 'support/efss.php'. I know, it is dull to be consistent and sensible, but it is better than naming the class "NinjasAreAwesome" (despite the fact that ninjas are awesome). At any rate, using the EFSS class is pretty straightforward: Mount a file system, perform necessary operations, and unmount the file system, making sure to check every response for errors along the way. EFSS can fail at any time for a wide variety of reasons, so error checking is really important.

If you follow my usual documentation habits, you know I like to document everything. In this case, I don't feel it is necessary to do as much documentation. The bulk of the functionality is nearly identical to PHP's file and directory functions with some limitations here and there and a few extra features here and there. The only major difference is the return value, which is always an array. Every function in the EFSS class is tested in the test suite, so there is at least one working example to swipe as well depending on the function in question. Basic and common functions are tested more heavily than others.

That said, there are a bunch of functions outside the purview of PHP's standard set. What follows is that set of core EFSS class member functions:

EFSS::__construct()

Parameters: None.

Returns: Nothing.

This function initializes the EFSS class. Automatically called by PHP.

EFSS::__destruct()

Parameters: None.

Returns: Nothing.

This function unmounts any mounted file system. Automatically called by PHP.

EFSS::Translate()

Parameters: String + arguments

Returns: Nothing.

This function is intended for use in a multilingual support environment to translate human-readable input strings to another language.

EFSS::Create($key1, $iv1, $key2, $iv2, $basefile, ...)

Parameters:

Returns: A standard response array.

This function creates a brand new EFSS data store after evaluating the inputs. A user should not invent values for the first five options and should let a real random number generator do the work. The block size must be a multiple of 4096 and less than or equal to 32768. The timestamp setting dictates how timestamps are stored. The UTC format is highly recommended despite occupying 5 times the storage space so that the backup file can cleanly cross over to another host without being off. The directory mode can be one or more of the following options: EFSS_DIRMODE_COMPRESS, EFSS_DIRMODE_CASE_INSENSITIVE. The default directory mode is recommended.

EFSS::Mount($key1, $iv1, $key2, $iv2, $basefile, $mode, ...)

Parameters:

Returns: A standard response array.

This function mounts an EFSS data store, obtaining an appropriate lock on the data in the process. Note that $blocksize has to be the same value as used for EFSS::Create(). This function also mounts incrementals if they are specified but will only successfully complete the mount if $mode is EFSS_MODE_READ.

EFSS::Unmount()

Parameters: None.

Returns: A standard response array.

This function unmounts a mounted file system.

EFSS::SetDefaultOwner($ownername)

Parameters:

Returns: Nothing.

This function sets the default owner name that will be used when creating directories, files, and symbolic links.

EFSS::SetDefaultGroup($groupname)

Parameters:

Returns: Nothing.

This function sets the default group name that will be used when creating directories, files, and symbolic links.

EFSS::GetDirMode()

Parameters: None.

Returns: An integer containing the mode that the file system was mounted with.

This function just returns the value of the directory mode variable stored in the internal class.

EFSS::fopen_write($filename, ...)

Parameters:

Returns: A standard response array.

This function is used when writing files. The default behavior is to just open a file for writing (replacing any existing file). The most interesting feature is the $data option. When $data is a string and is less than 45% of the EFSS block size, the file data is inlined with the directory block. The other options are useful for saving time by avoiding altering the directory block a zillion times for a single file.

EFSS::internal_fflush($fp, $finalize = false)

Parameters:

Returns: A standard response array.

This internal function is used to write out pending data in the buffer to disk either when enough data has been appended to the output buffer or EFSS::fclose() is called. When $finalize is true, the last blocks are written and the directory block is updated with file size information (if necessary).

EFSS::ReadMoreFileData($fp)

Parameters:

Returns: A standard response array.

This internal function is used to read more file data from disk.

EFSS::internal_stat($filename, $lastsymlink)

Parameters:

Returns: A standard response array.

This internal function generates a stat() compatible array.

EFSS::GetFileInfo($filename)

Parameters:

Returns: A standard response array.

This function returns the internal EFSS_DirEntry_DirFile structure for the fully resolved path/file specified by $filename.

EFSS::CheckFS()

Parameters: None.

Returns: A standard response array.

This function does an exhaustive check of the mounted EFSS data store for validity. Similar to 'fsck' and 'chkdsk' but does not repair issues.

EFSS::ResolvePath($path, $dirinfo = false)

Parameters:

Returns: An array containing the mapped directory.

This internal function converts a relative path into an absolute path. It doesn't check it against the mounted EFSS data store.

EFSS::DirInfoToPath($dirinfo)

Parameters:

Returns: A string containing the path.

This internal function converts directory mapping information to a displayable or reusable string.

EFSS::LoadPath($path, ...)

Parameters:

Returns: A standard response array.

This internal function is used extensively by many other EFSS functions to locate directories, files, and symbolic links in the directory hierarchy.

EFSS::ReadDirBlock($blocknum, $findname = false)

Parameters:

Returns: A standard response array.

This internal function is used to load a directory block from disk into the directory block cache or use the block from the cache if it is already loaded.

EFSS::FindDirInsertPos($blocknum, $newname)

Parameters:

Returns: A standard response array.

This internal function locates the block number and position in the entries where a new directory, file, or symbolic link will be inserted based on the supplied $newname. If it already exists, an error will be returned with the block number, directory entries, and position of the existing entry.

EFSS::WriteDirBlock($dir, $blocknum)

Parameters:

Returns: A standard response array.

This internal function writes one or more directory block entries. If a directory block is too big to fit into a single block, it automatically pulls entries off the end until the block fits, then prepends them to the next block. The process repeats until the directory blocks settle.

EFSS::NextUnusedBlock()

Parameters: None.

Returns: A standard response array.

This internal function locates the next unused block and returns its block number to the caller.

EFSS::ReloadUnused()

Parameters: None.

Returns: A standard response array.

This internal function reloads the unused block linked list. Typically called after the current list of unused blocks is exhausted to locate the next section of blocks.

EFSS::FreeLinkedList($blocknum)

Parameters:

Returns: A standard response array.

This internal function frees a linked list of blocks. Writes random data to each unused block before adding it to the list of unused blocks.

EFSS::FreeUsedBlock($blocknum, $flush = false)

Parameters:

Returns: A standard response array.

This internal function frees a single block. The flush option allows a bunch of blocks to be queued up in such a way so as to minimize file system fragmentation.

EFSS::Lock($mode, $waitforlock = true)

Parameters:

Returns: A standard response array.

This internal function is used when creating and mounting the file system to establish the appropriate reader/writer lock.

EFSS::RawWriteBlock($data, $blocknum, $type)

Parameters:

Returns: A standard response array.

This internal function encrypts then writes a block of data to the physical file system.

EFSS::RawReadBlock($blocknum, $type)

Parameters:

Returns: A standard response array.

This internal function reads a block of data from the physical file system, decrypts it, verifies that it isn't corrupt, and that it is of the type that the calling function has asked for.

EFSS::RawDecryptBlock($cipher1, $cipher2, $block, $type)

Parameters:

Returns: A standard response array.

This static function decrypts a block, verifies that it isn't corrupt, and that it is of the type that the calling function has asked for.

EFSS::RawSeekBlock($blocknum)

Parameters:

Returns: The return value of fseek().

This internal function seeks to a specific block.

EFSS::RawSeekUpdate($blocknum)

Parameters:

Returns: The return value of fseek().

This internal function seeks to a specific block update.

EFSS::RawSeek($fp, $pos)

Parameters:

Returns: The return value of fseek().

This static function seeks to the desired location in a file. If $pos is greater than 1GB, it seeks 1GB at a time until the amount is less than 1GB and then seeks the remainder.

EFSS::ConvertFromUTCDateTime($ts)

Parameters:

Returns: An integer in local UNIX timestamp format.

This static function converts a UTC string to the local UNIX timestamp. Used extensively by various EFSS functions.

EFSS::ConvertFromLocalDateTime($ts)

Parameters:

Returns: An integer in local UNIX timestamp format.

This static function converts a local timestamp string to the local UNIX timestamp. Used primarily by a couple shell extensions in 'shell_exts/main.php' to convert command-line timestamp strings.

EFSS::ConvertToUTCDateTime($ts)

Parameters:

Returns: A string in "YYYY-MM-DD HH:MM:SS" UTC format right-padded to 20 characters.

This static function takes a local UNIX timestamp and converts it into a UTC EFSS data store friendly format.

EFSS::UnpackInt($data)

Parameters:

Returns: An integer (or float/double) on success, a boolean of false on failure.

This static function takes big-endian strings as input and outputs regular integers (or float/double if a 64-bit number is too large). On error (e.g. not enough data), false is returned.

EFSS::PackInt64($num)

Parameters:

Returns: An eight byte string in big-endian format representing the input with overflow cutoff.

This static function takes integers and floats/doubles as input and outputs a big-endian string representing the number. Due to the precision issues of float/double, large numbers hit a ceiling under 32-bit PHP (a rough limit is detected in the test suite). 64-bit PHP will likely not convert an int to float/double, so the precision issues aren't likely to be an issue.

EFSS Block Types Specification

Earlier, it was mentioned that there are five block types that EFSS understands and each type was briefly covered. In this section, each block type will be covered in gruesome detail. Before beginning though, it is important to mention a few things about the data types that are seen:

Each block type is actually data encoded into a block as follows:

Doing the math shows that 30 bytes of every block is "wasted" on various bits of verification and anti-pattern bytes. It really isn't so bad though, especially when data compression enters the picture.

Without further ado, let's dive into the structure of EFSS block types.

First Block

This is always the first block of any EFSS file system. Its structure is as follows:

The first block tells EFSS how to operate. If any of the first three blocks in EFSS are corrupted, the file system can't be mounted.

Directory Block

This is a linked list containing part or all of a directory. Directories store information about links to directories, files, and symbolic links. Its structure is as follows:

Followed by zero or more encapsulated directory entries as follows:

For directories:

For normal files (not inline):

For inline files:

For symbolic links:

The first (root) directory is always the second block in EFSS. Directories are the most complex block type in EFSS. Depending on the first block settings, directories may be compressed.

File Block

This is a linked list containing part or all of a file. Its structure is as follows:

Depending on the file's flags, the data may be compressed.

Unused List Block

This is a linked list containing a number of unused blocks. Its structure is as follows:

Followed by zero or more of:

Unused blocks are added and removed in stack order. To alleviate fragmentation issues, accumulate a lot of block numbers before flushing reverse order block numbers to disk.

Unused Block

There isn't much to say about this block type. It contains nothing beyond being wrapped as a normal block but with a unique block type. This is done instead of pure random garbage because EFSS::CheckFS() depends on every block being valid. It also doesn't hurt since most of the data is random garbage anyway.

EFSS Copy Helpers

The EFSS "copy helper" classes are designed to act as an abstraction away from real file systems and EFSS file systems to facilitate cloning directories, files, and symlinks. They are used by the command-line tool 'sync.php' to reduce the amount of code required to handle four different scenarios: Real to EFSS, EFSS to real, EFSS to EFSS (but not the same), and real to real.

There are four copy helper classes:

The 'sync.php' script actually isn't 100% file system agnostic, especially when it comes to files. Inline files are a fairly unique feature of EFSS, so 'sync.php' makes sure that files under 1MB use the EFSS file_put_contents() call for target EFSS data stores so that EFSS inlining takes place.

EFSS Incremental Helpers

The EFSS incremental helper static functions are designed to make it easier to generate standard EFSS incremental data sets that the core EFSS class can utilize. These functions read, write, merge, and verify both incrementals and base files. The official backup API ('api/backup.php'), backup command-line tool ('backup.php'), and EFSS checking tool ('check.php') have several examples of usage.

Without further ado, what follows is the set of incremental helper functions:

EFSSIncremental::ForceUnlock($filename)

Parameters:

Returns: Nothing.

This static function forces a locked EFSS data store to become unlocked. It isn't recommended to call this from automated code unless you really know what you are doing. Lock files exist to protect the data store from corruption.

EFSSIncremental::Delete($filename)

Parameters:

Returns: Nothing.

This static function deletes all files related to an EFSS data store (including '.php' files). Take care that users can't call this function somehow (e.g. via a URL parameter) with a rogue filename.

EFSSIncremental::WritePHPFile($basefile, $key1, $iv1, $key2, $iv2, $blocksize, $lockfile)

Parameters:

Returns: Nothing.

This function creates a PHP file for a new or existing backup.

EFSSIncremental::GetLock($lockfile, $writelock, ...)

Parameters:

Returns: A standard response array.

This static function obtains a lock on the specified file in either multiple-read or exclusive write mode.

EFSSIncremental::Read($filename, $since, $startblock, $origlastwrite, ...)

Parameters:

Returns: A standard response array.

This static function assumes a lock has been established with EFSSIncremental::GetLock() and retrieves incremental data since the $since timestamp up to $len bytes or $maxtime expires. The returned array can be used to construct a response to a client or server or just stored in an incremental file locally. The 10MB limit helps avoid PHP memory limits.

EFSSIncremental::Write($filename, $startblock, $blockdata, $lastupdateddata, ...)

Parameters:

Returns: A standard response array.

This static function assumes a lock has been established with EFSSIncremental::GetLock() and writes base file or incremental data to disk. The official backup API verifies that all input data is of the exact and correct size before writing anything out.

EFSSIncremental::WriteFinalize($filename)

Parameters:

Returns: A standard response array.

This static function assumes a lock has been established with EFSSIncremental::GetLock() and finalizes the base or incremental file (primarily deletes the '.partial' file).

EFSSIncremental::MakeReadOnly($basefile, $readonly = true)

Parameters:

Returns: A standard response array.

This static function verifies that the base file exists and isn't an incremental and then creates or deletes a '.readonly' file based on the value of $readonly.

EFSSIncremental::LastUpdated($filename)

Paramaters:

Returns: A standard response array.

This static function assumes a lock has been established with EFSSIncremental::GetLock() and returns the last updated timestamp of the first last updated entry of $filename. The first timestamp is guaranteed to always be the most recent timestamp.

EFSSIncremental::Merge($basefile, $incrementalfile, ...)

Parameters:

Returns: A standard response array.

This static function assumes a lock has been established with EFSSIncremental::GetLock() and merges the incremental data in $incrementalfile into $basefile. When $delete is true, the incremental files are deleted and a '.partial' file is created that has to be deleted directly with code later on. This is useful for managing a rolling incremental backup. Since merges don't check the data being merged (because the data is encrypted), it is a good idea to verify the backup before performing the merge.

EFSSIncremental::Verify($key1, $iv1, $key2, $iv2, $incrementalfile, ...)

Parameters:

Returns: A standard response array.

This static function assumes a lock has been established with EFSSIncremental::GetLock() and then proceeds to verify that the blocks of the incremental are not corrupted. While a base file can be verified using this function (EFSS::CheckFS() is better), this is really intended for incremental verification because incrementals can't be mounted by themselves. If either of the keys or IVs are empty strings, the function attempts to verify using the hashes file.

© CubicleSoft