StrongBox module

The StrongBox encrypted P2P backup program. Run ./StrongBox.py -h for details on how to execute.

class StrongBox.DirectoryModificationHandler(dir_modified_flag)

Bases: watchdog.events.FileSystemEventHandler

on_any_event(file_system_event)
exception StrongBox.ManualDisconnectException

Bases: exceptions.Exception

An exception for indicating manual disconnections which should not be treated as errors.

class StrongBox.Metadata

Bases: tuple

Metadata(peer_id, peer_dict, store_id, store_dict, encryption_key, aes_iv, merkle_tree)

aes_iv

Alias for field number 5

encryption_key

Alias for field number 4

merkle_tree

Alias for field number 6

peer_dict

Alias for field number 1

peer_id

Alias for field number 0

store_dict

Alias for field number 3

store_id

Alias for field number 2

class StrongBox.Peer(store_dir=None, debug_verbosity=0, root_directory=None, debug_preamble=None, _metadata=None, lock=None, shutdown_signaled=None, store_modified_flag=None, private_key_contents=None, aes_key=None)

The central component of StrongBox. A peer is the entity that tracks changes to the user’s store and synchronizes backups with other peers.

aes_iv
check_store(force=False)

Check this peer’s own store for changes generating new revision data and a new Merkle tree upon updates.

compute_safe_filename(input_string)

Take any string of characters (e.g. the result of a SHA hash) and reversibly convert it to a valid filename.

compute_store_id(public_key=None)

Store IDs are meant to uniquely identify a store/user. They are essentially the RSA public key, but we use use their SHA-256 hash to “flatten” them to a shorter, predictable length.

connect_to_peer(peer_id, timeout=5)
create_listening_socket(timeout=5)
debug_print(print_tuples)

Optionally print based on the object’s verbosity setting and the required verbosity levels of the inputs. Taking input as a list of tuples allows for multiple statements of differing verbosities to be dispatched from the same call and be displayed under the same preamble and call stack (if any).

Semantically, the levels are (currently) roughly: 0: Minimal (default). 1: Interesting info for demoing. 2: Additionally print uglies such as hashes and ID strings that are of nearly-intelligible length. 3: Additionally print noisy stuff like message receipts and larger data like peer and store dictionaries. 4: “Oh shit, I have no idea where this bug is.” (Addtionally call stack and Merkle trees.) 5: Additionally print file contents.

debug_print_bad_message(message_id, pickled_payload)

Extract the type and contents from an unexpected message and (optionally) print them out.

decrypt(ciphertext)

Decrypt AES-encrypted data.

decrypt_filename(safe_encrypted_filename)
decrypt_own_store_path(encrypted_relative_path)

Convert an encrypted, store-relative path to its original form.

determine_sync_type(peer_id, store_id)

Figure out what type of synchronization (send, receive, or check) we’ll be participating in.

diff_store_to_merkle_tree(store_id, mt_old)

Compute the difference between the current contents of the specified store and those indicated by the older, provided Merkle tree.

do_sync(skt, sync_type, peer_id, store_id)

Initiate a “receive”, “send”, or “check” sync.

encrypt(plaintext)

Deterministically encrypt the input string using AES.

encrypt_filename(filename)
encryption_key

The AES key used for encrypting a user’s store data before transmission.

export_backup_configuration()

Export the (public) configuration data another peer would need to act as a backup for your store.

export_owner_configuration()

Export the (private) configuration data needed to access your store from another machine.

generate_initial_metadata(aes_key)

Generate a peer’s important configuration metadata upon first execution.

generate_peer_id()

Generate a quasi-unique ID for this peer using a hash (SHA-256, which currently has no known collisions) of the owner’s public key “salted” with 32 random bits.

get_merkle_tree(store_id, nonce=None, fresh=False)

Get the locally computed Merkle tree for a store.

get_peer_key(peer_id)

Convenience function to load a peer’s public key.

get_peer_key_path(peer_id)

Convenience function to compute the location of a peer’s recorded public key file.

get_public_network_address()
get_revision_data(peer_id, store_id)

A convenience function for retrieving a given peer’s revision data for a given store.

get_store_hash(store_id, nonce='', fresh=False)

Retrieve the overall hash value for the user’s store utilizing a nonce as needed.

get_store_key(store_id)

Convenience function to load a store’s public key .

gt_revision_data(store_id, revision_data_1, revision_data_2)

Returns True if revision_data_1 passes signature verification and either is later than revision_data_2 or that revision fails signature verification.

handle_unexpected_message(message_id, pickled_payload)

See if the unexpected message was a disconnect request and respond accordingly. Otherwise, print the message contents and raise an exception.

import_backup_configuration(config_file=None, peer_id=None, network_address=None, public_key_contents=None)

Import the (public) configuration data needed to act as a backup for another peer’s store.

increment_revision()

Create and record new revision data for the peer’s own store.

initialize_directory_structure()

Generate the directories for storing configuration data and the backups of other peers’ stores.

initialize_keys(private_key_contents)

Import, load, or generate the private and public keys for the user and their store.

learn_peer_gossip(gossip_peer_id, gossip_peer_dict, lock=False)

Update our knowledge of peers based on gossip from another peer.

listening_port = 51338
load_metadata_file(aes_key)

Load important configuration metadata that must be persisted to storage.

manually_associate(peer_id, network_address, public_key_file)

Manually associate with a peer and prepare to be a backup for that peer’s store.

merkle_tree

A DirectoryMerkleTree object containing the current state of the user’s store.

metadata

Important metadata about peers and stores. Access is controlled to ensure that all changes are backed up to primary storage.

network_address

The current network address of this peer.

peer_client_session(skt_ssl)

The activities undertaken once connected to a peer server.

peer_dict

A mapping from the IDs of other peers who serve as backups to this peer to important metadata such as their IP address and what revisions they had for stores of interest upon last contact.

peer_id

A quasi-unique identifier for this particular peer.

peer_server_session(skt_ssl, peer_address)

The activities undertaken once a peer client has connected.

receive(skt)

Low-level message receipt. Checks the message’s protocol version, retrieves only the necessary amount of data (to support consecutively sent messages), and unpickles the message body.

receive_expected_message(skt, expected_message_type)

Receive a message, automatically handling situations where the message was not of the type expected.

record_peer_data(peer_id, peer_data, lock_acquired=False)

Update the recorded metadata for an individual peer.

record_peer_pubkey(peer_id, peer_public_key_string)

Used to record a peer’s public key upon first encounter. The key is subsequently used to verify SSL connections and signatures.

record_store_pubkey(store_id, store_public_key_string)

Used to record a store’s public key upon association. The key is subsequently used for signature verification.

run(client_sleep_time=5)

Start operating as a both a peer client and peer server in synchronized threads.

run_peer_client(sleep_time=1, socket_timeout=1)

The peer client thread periodically reaches out to other peers to enact synchronizations.

run_peer_server(socket_timeout=10)

The peer server thread listens for and services connections from other peers.

select_sync_peer()

Select which peer to sync with. This is done by randomly sampling from a probability density function contains, in order of preference, peers with newer revisions of our store or backups, peers with older revisions, peers with whom we share a valid revision, and any other peers (peers that fall in a combination of these categories are also accordingly preferred).

select_sync_store(peer_id)

Select which of a peer server’s stores to sync on.

send(skt, message_id, message_data)

Generic message transmission wrapper that pickles the message to be sent, prepends the protocol version and overall length, and dumps the data into the socket.

send_delete_file_msg(skt, relative_path)

Simple message transmission wrapper.

send_disconnect_req(skt, disconnect_message)

Simple message transmission wrapper.

send_handshake_msg(skt)

Simple message transmission wrapper.

send_merkle_tree_msg(skt, store_id, merkle_tree)

Simple message transmission wrapper.

send_public_key_msg(skt)

Simple message transmission wrapper.

send_sync_complete_msg(skt)

Simple message transmission wrapper.

send_sync_req(skt, store_id)

Simple message transmission wrapper.

send_update_file_msg(skt, relative_path, file_contents)

Simple message transmission wrapper.

send_verify_sync_req(skt, nonce)

Simple message transmission wrapper.

send_verify_sync_resp(skt, verification_hash)

Simple message transmission wrapper.

sign(payload)

Convenience primative for computing a signature for any string.

sign_revision(revision_number, store_hash)

A convenience function for appending a signature to generated revision data.

store_delete_item(store_id, item_relative_path)

Delete a file or directory from a locally held store (either the user’s or a backup of another user’s store).

store_dict

A mapping from store IDs to important metadata such as this peer’s current revision for the store and the IDs of peers known to be associated with the store.

store_get_item_contents(store_id, item_relative_path)

Get the contents of a file (or return None for a directory) in preparation for transmission, recording on-the-fly if the item originates from the user’s store.

store_id

A quasi-unique identifier for this peer’s store.

store_put_item(store_id, item_relative_path, file_contents=None)

Save a new directory or file, or update a file within a locally held store (either the user’s or a backup from another user).

sync_check(skt, sync_peer_id, sync_store_id)

Verify the other peer’s store data.

sync_receive(skt, sender_peer_id, sync_store_id)

Conduct a sync as the receiving party.

sync_send(skt, receiver_peer_id, sync_store_id)

Conduct a sync as the sending party.

test_client_handshake(peer_address)
test_client_ssl(peer_address)
test_server_handshake()
test_server_ssl()
unpickle(message_type, pickled_payload)

“Demultiplex” a received message to its specific unpickling method.

unpickle_delete_file_msg(pickled_payload)

A simple wrapper for unpickling.

unpickle_handshake_msg(pickled_payload)

A simple wrapper for unpickling.

unpickle_merkle_tree_msg(pickled_payload)

A simple wrapper for unpickling.

unpickle_public_key_msg(pickled_payload)

A simple wrapper for unpickling.

unpickle_sync_complete_msg(pickled_payload)

A simple wrapper for unpickling.

unpickle_sync_req(pickled_payload)

A simple wrapper for unpickling.

unpickle_update_file_msg(pickled_payload)

A simple wrapper for unpickling.

unpickle_verify_sync_req(pickled_payload)

A simple wrapper for unpickling.

unpickle_verify_sync_resp(pickled_payload)

A simple wrapper for unpickling.

update_metadata(metadata, lock_acquired=False)

All updates to a peer’s stored metadata occur through this function so we can ensure that changes are backed up to primary storage before coming into effect.

update_network_address(lock=False)

Update this peer’s already existing IP address data.

update_peer_revision(peer_id, store_id, invalid=False, lock=None)

After sending a peer synchronization data and verifying their store contents, update our recording of their revision for the store in question to match ours.

update_store_revision(store_id, revision_data, lock=None)

Increment the revision number and recalculate the corresponding hash and revision signature for the current state of the user’s store.

verify(store_id, signature, payload)

Convenience primative for verifying the signature associated with a string.

verify_revision_data(store_id, revision_data)

Verify the signature of a received revision number.

verify_sync(peer_id, store_id)

Check our newly syncronized store against the signed revision data that the sync sender passed us.

class StrongBox.PeerData

Bases: tuple

PeerData(network_address, store_revisions)

network_address

Alias for field number 0

store_revisions

Alias for field number 1

class StrongBox.RevisionData

Bases: tuple

RevisionData(revision_number, store_hash, signature)

revision_number

Alias for field number 0

signature

Alias for field number 2

store_hash

Alias for field number 1

class StrongBox.StoreData

Bases: tuple

StoreData(revision_data, peers)

peers

Alias for field number 1

revision_data

Alias for field number 0

StrongBox.delete_old_configuration()

Delete old configuration data in preparation for initialization.

StrongBox.demo_A()
StrongBox.demo_B()
StrongBox.import_owner_configuration()

Export the (private) configuration file used to allow the owner to access their store from another machine.

StrongBox.initialize_peer_configuration(store_dir=None, debug_verbosity=None)

Generate new initial configuration data for this peer.

StrongBox.main(store_dir=None, debug_verbosity=None)
StrongBox.run_peer_client_only(debug_verbosity=2)

Run in peer client mode only.

StrongBox.run_peer_server_only(debug_verbosity=2)

Run in peer server mode only.

StrongBox.test_handshake()
StrongBox.test_ssl()

Previous topic

StoredConfiguration module

Next topic

test_DirectoryMerkleTree module

This Page