diff options
| -rw-r--r-- | client/src/leap/soledad/client/__init__.py | 255 | ||||
| -rw-r--r-- | client/src/leap/soledad/client/auth.py | 24 | ||||
| -rw-r--r-- | client/src/leap/soledad/client/crypto.py | 62 | ||||
| -rw-r--r-- | client/src/leap/soledad/client/shared_db.py | 58 | ||||
| -rw-r--r-- | client/src/leap/soledad/client/sqlcipher.py | 290 | ||||
| -rw-r--r-- | client/src/leap/soledad/client/target.py | 132 | 
6 files changed, 412 insertions, 409 deletions
| diff --git a/client/src/leap/soledad/client/__init__.py b/client/src/leap/soledad/client/__init__.py index 4c6a41fc..1f54ef8c 100644 --- a/client/src/leap/soledad/client/__init__.py +++ b/client/src/leap/soledad/client/__init__.py @@ -226,25 +226,26 @@ class Soledad(object):          """          Initialize configuration, cryptographic keys and dbs. -        @param uuid: User's uuid. -        @type uuid: str -        @param passphrase: The passphrase for locking and unlocking encryption -            secrets for local and remote storage. -        @type passphrase: str -        @param secrets_path: Path for storing encrypted key used for -            symmetric encryption. -        @type secrets_path: str -        @param local_db_path: Path for local encrypted storage db. -        @type local_db_path: str -        @param server_url: URL for Soledad server. This is used either to sync +        :param uuid: User's uuid. +        :type uuid: str +        :param passphrase: The passphrase for locking and unlocking encryption +                           secrets for local and remote storage. +        :type passphrase: str +        :param secrets_path: Path for storing encrypted key used for +                             symmetric encryption. +        :type secrets_path: str +        :param local_db_path: Path for local encrypted storage db. +        :type local_db_path: str +        :param server_url: URL for Soledad server. This is used either to sync              with the user's remote db and to interact with the shared recovery              database. -        @type server_url: str -        @param cert_file: Path to the SSL certificate to use in the -            connection to the server_url. -        @type cert_file: str -        @param auth_token: Authorization token for accessing remote databases. -        @type auth_token: str +        :type server_url: str +        :param cert_file: Path to the certificate of the ca used +                          to validate the SSL certificate used by the remote +                          soledad server. +        :type cert_file: str +        :param auth_token: Authorization token for accessing remote databases. +        :type auth_token: str          """          # get config params          self._uuid = uuid @@ -339,7 +340,7 @@ class Soledad(object):          """          Create work directories. -        @raise OSError: in case file exists and is not a dir. +        :raise OSError: in case file exists and is not a dir.          """          paths = map(              lambda x: os.path.dirname(x), @@ -418,8 +419,8 @@ class Soledad(object):          Storage secret is encrypted before being stored. This method decrypts          and returns the stored secret. -        @return: The storage secret. -        @rtype: str +        :return: The storage secret. +        :rtype: str          """          # calculate the encryption key          key = scrypt.hash( @@ -478,8 +479,8 @@ class Soledad(object):          """          Return whether there is a storage secret available for use or not. -        @return: Whether there's a storage secret for symmetric encryption. -        @rtype: bool +        :return: Whether there's a storage secret for symmetric encryption. +        :rtype: bool          """          if self._secret_id is None or self._secret_id not in self._secrets:              try: @@ -515,8 +516,8 @@ class Soledad(object):                  }              } -        @return: The id of the generated secret. -        @rtype: str +        :return: The id of the generated secret. +        :rtype: str          """          signal(SOLEDAD_CREATING_KEYS, self._uuid)          # generate random secret @@ -571,10 +572,10 @@ class Soledad(object):          """          Change the passphrase that encrypts the storage secret. -        @param new_passphrase: The new passphrase. -        @type new_passphrase: str +        :param new_passphrase: The new passphrase. +        :type new_passphrase: str -        @raise NoStorageSecret: Raised if there's no storage secret available. +        :raise NoStorageSecret: Raised if there's no storage secret available.          """          # maybe we want to add more checks to guarantee passphrase is          # reasonable? @@ -616,8 +617,8 @@ class Soledad(object):          Calculate a hash for storing/retrieving key material on shared          database, based on user's uuid. -        @return: the hash -        @rtype: str +        :return: the hash +        :rtype: str          """          return sha256(              '%s%s' % ( @@ -639,8 +640,8 @@ class Soledad(object):          Retrieve the document with encrypted key material from the shared          database. -        @return: a document with encrypted key material in its contents -        @rtype: SoledadDocument +        :return: a document with encrypted key material in its contents +        :rtype: SoledadDocument          """          signal(SOLEDAD_DOWNLOADING_KEYS, self._uuid)          db = self._shared_db() @@ -687,11 +688,11 @@ class Soledad(object):          """          Update a document in the local encrypted database. -        @param doc: the document to update -        @type doc: SoledadDocument +        :param doc: the document to update +        :type doc: SoledadDocument -        @return: the new revision identifier for the document -        @rtype: str +        :return: the new revision identifier for the document +        :rtype: str          """          return self._db.put_doc(doc) @@ -699,11 +700,11 @@ class Soledad(object):          """          Delete a document from the local encrypted database. -        @param doc: the document to delete -        @type doc: SoledadDocument +        :param doc: the document to delete +        :type doc: SoledadDocument -        @return: the new revision identifier for the document -        @rtype: str +        :return: the new revision identifier for the document +        :rtype: str          """          return self._db.delete_doc(doc) @@ -711,15 +712,15 @@ class Soledad(object):          """          Retrieve a document from the local encrypted database. -        @param doc_id: the unique document identifier -        @type doc_id: str -        @param include_deleted: if True, deleted documents will be -            returned with empty content; otherwise asking for a deleted -            document will return None -        @type include_deleted: bool +        :param doc_id: the unique document identifier +        :type doc_id: str +        :param include_deleted: if True, deleted documents will be +                                returned with empty content; otherwise asking +                                for a deleted document will return None +        :type include_deleted: bool -        @return: the document object or None -        @rtype: SoledadDocument +        :return: the document object or None +        :rtype: SoledadDocument          """          return self._db.get_doc(doc_id, include_deleted=include_deleted) @@ -728,15 +729,15 @@ class Soledad(object):          """          Get the content for many documents. -        @param doc_ids: a list of document identifiers -        @type doc_ids: list -        @param check_for_conflicts: if set False, then the conflict check will +        :param doc_ids: a list of document identifiers +        :type doc_ids: list +        :param check_for_conflicts: if set False, then the conflict check will              be skipped, and 'None' will be returned instead of True/False -        @type check_for_conflicts: bool +        :type check_for_conflicts: bool -        @return: iterable giving the Document object for each document id +        :return: iterable giving the Document object for each document id              in matching doc_ids order. -        @rtype: generator +        :rtype: generator          """          return self._db.get_docs(doc_ids,                                   check_for_conflicts=check_for_conflicts, @@ -745,12 +746,12 @@ class Soledad(object):      def get_all_docs(self, include_deleted=False):          """Get the JSON content for all documents in the database. -        @param include_deleted: If set to True, deleted documents will be -            returned with empty content. Otherwise deleted documents will not -            be included in the results. -        @return: (generation, [Document]) -            The current generation of the database, followed by a list of all -            the documents in the database. +        :param include_deleted: If set to True, deleted documents will be +                                returned with empty content. Otherwise deleted +                                documents will not be included in the results. +        :return: (generation, [Document]) +                 The current generation of the database, followed by a list of +                 all the documents in the database.          """          return self._db.get_all_docs(include_deleted) @@ -758,13 +759,13 @@ class Soledad(object):          """          Create a new document in the local encrypted database. -        @param content: the contents of the new document -        @type content: dict -        @param doc_id: an optional identifier specifying the document id -        @type doc_id: str +        :param content: the contents of the new document +        :type content: dict +        :param doc_id: an optional identifier specifying the document id +        :type doc_id: str -        @return: the new document -        @rtype: SoledadDocument +        :return: the new document +        :rtype: SoledadDocument          """          return self._db.create_doc(content, doc_id=doc_id) @@ -778,12 +779,12 @@ class Soledad(object):          If the database specifies a maximum document size and the document          exceeds it, create will fail and raise a DocumentTooBig exception. -        @param json: The JSON document string -        @type json: str -        @param doc_id: An optional identifier specifying the document id. -        @type doc_id: -        @return: The new cocument -        @rtype: SoledadDocument +        :param json: The JSON document string +        :type json: str +        :param doc_id: An optional identifier specifying the document id. +        :type doc_id: +        :return: The new cocument +        :rtype: SoledadDocument          """          return self._db.create_doc_from_json(json, doc_id=doc_id) @@ -796,11 +797,11 @@ class Soledad(object):          Creating an index will block until the expressions have been evaluated          and the index generated. -        @param index_name: A unique name which can be used as a key prefix -        @type index_name: str -        @param index_expressions: index expressions defining the index -            information. -        @type index_expressions: dict +        :param index_name: A unique name which can be used as a key prefix +        :type index_name: str +        :param index_expressions: index expressions defining the index +                                  information. +        :type index_expressions: dict              Examples: @@ -816,8 +817,8 @@ class Soledad(object):          """          Remove a named index. -        @param index_name: The name of the index we are removing -        @type index_name: str +        :param index_name: The name of the index we are removing +        :type index_name: str          """          if self._db:              return self._db.delete_index(index_name) @@ -826,8 +827,8 @@ class Soledad(object):          """          List the definitions of all known indexes. -        @return: A list of [('index-name', ['field', 'field2'])] definitions. -        @rtype: list +        :return: A list of [('index-name', ['field', 'field2'])] definitions. +        :rtype: list          """          if self._db:              return self._db.list_indexes() @@ -843,14 +844,14 @@ class Soledad(object):          It is also possible to append a '*' to the last supplied value (eg          'val*', '*', '*' or 'val', 'val*', '*', but not 'val*', 'val', '*') -        @param index_name: The index to query -        @type index_name: str -        @param key_values: values to match. eg, if you have -            an index with 3 fields then you would have: -            get_from_index(index_name, val1, val2, val3) -        @type key_values: tuple -        @return: List of [Document] -        @rtype: list +        :param index_name: The index to query +        :type index_name: str +        :param key_values: values to match. eg, if you have +                           an index with 3 fields then you would have: +                           get_from_index(index_name, val1, val2, val3) +        :type key_values: tuple +        :return: List of [Document] +        :rtype: list          """          if self._db:              return self._db.get_from_index(index_name, *key_values) @@ -869,18 +870,18 @@ class Soledad(object):          possible to append a '*' to the last supplied value (eg 'val*', '*',          '*' or 'val', 'val*', '*', but not 'val*', 'val', '*') -        @param index_name: The index to query -        @type index_name: str -        @param start_values: tuples of values that define the lower bound of +        :param index_name: The index to query +        :type index_name: str +        :param start_values: tuples of values that define the lower bound of              the range. eg, if you have an index with 3 fields then you would              have: (val1, val2, val3) -        @type start_values: tuple -        @param end_values: tuples of values that define the upper bound of the +        :type start_values: tuple +        :param end_values: tuples of values that define the upper bound of the              range. eg, if you have an index with 3 fields then you would have:              (val1, val2, val3) -        @type end_values: tuple -        @return: List of [Document] -        @rtype: list +        :type end_values: tuple +        :return: List of [Document] +        :rtype: list          """          if self._db:              return self._db.get_range_from_index( @@ -890,10 +891,10 @@ class Soledad(object):          """          Return all keys under which documents are indexed in this index. -        @param index_name: The index to query -        @type index_name: str -        @return: [] A list of tuples of indexed keys. -        @rtype: list +        :param index_name: The index to query +        :type index_name: str +        :return: [] A list of tuples of indexed keys. +        :rtype: list          """          if self._db:              return self._db.get_index_keys(index_name) @@ -902,11 +903,11 @@ class Soledad(object):          """          Get the list of conflicts for the given document. -        @param doc_id: the document id -        @type doc_id: str +        :param doc_id: the document id +        :type doc_id: str -        @return: a list of the document entries that are conflicted -        @rtype: list +        :return: a list of the document entries that are conflicted +        :rtype: list          """          if self._db:              return self._db.get_doc_conflicts(doc_id) @@ -915,11 +916,11 @@ class Soledad(object):          """          Mark a document as no longer conflicted. -        @param doc: a document with the new content to be inserted. -        @type doc: SoledadDocument -        @param conflicted_doc_revs: a list of revisions that the new content -            supersedes. -        @type conflicted_doc_revs: list +        :param doc: a document with the new content to be inserted. +        :type doc: SoledadDocument +        :param conflicted_doc_revs: a list of revisions that the new content +                                    supersedes. +        :type conflicted_doc_revs: list          """          if self._db:              return self._db.resolve_doc(doc, conflicted_doc_revs) @@ -928,12 +929,12 @@ class Soledad(object):          """          Synchronize the local encrypted replica with a remote replica. -        @param url: the url of the target replica to sync with -        @type url: str +        :param url: the url of the target replica to sync with +        :type url: str -        @return: the local generation before the synchronisation was +        :return: the local generation before the synchronisation was              performed. -        @rtype: str +        :rtype: str          """          if self._db:              local_gen = self._db.sync( @@ -946,11 +947,11 @@ class Soledad(object):          """          Return if local db replica differs from remote url's replica. -        @param url: The remote replica to compare with local replica. -        @type url: str +        :param url: The remote replica to compare with local replica. +        :type url: str -        @return: Whether remote replica and local replica differ. -        @rtype: bool +        :return: Whether remote replica and local replica differ. +        :rtype: bool          """          target = SoledadSyncTarget(url, creds=self._creds, crypto=self._crypto)          info = target.get_sync_info(self._db._get_replica_uid()) @@ -972,8 +973,8 @@ class Soledad(object):                      'token': '<token>'              } -        @param token: The authentication token. -        @type token: str +        :param token: The authentication token. +        :type token: str          """          self._creds = {              'token': { @@ -1004,11 +1005,11 @@ class Soledad(object):                  self.UUID_KEY: '<uuid>',  # (optional)              } -        @param include_uuid: Should the uuid be included? -        @type include_uuid: bool +        :param include_uuid: Should the uuid be included? +        :type include_uuid: bool -        @return: The recovery document. -        @rtype: dict +        :return: The recovery document. +        :rtype: dict          """          data = {self.STORAGE_SECRETS_KEY: self._secrets}          if include_uuid: @@ -1027,8 +1028,8 @@ class Soledad(object):                  self.UUID_KEY: '<uuid>',  # (optional)              } -        @param data: The recovery document. -        @type data: dict +        :param data: The recovery document. +        :type data: dict          """          # include new secrets in our secret pool.          for secret_id, secret_data in data[self.STORAGE_SECRETS_KEY].items(): @@ -1101,7 +1102,9 @@ SOLEDAD_TIMEOUT = 10  class VerifiedHTTPSConnection(httplib.HTTPSConnection): -    """HTTPSConnection verifying server side certificates.""" +    """ +    HTTPSConnection verifying server side certificates. +    """      # derived from httplib.py      def connect(self): diff --git a/client/src/leap/soledad/client/auth.py b/client/src/leap/soledad/client/auth.py index 3cd6dabe..d85e3ba6 100644 --- a/client/src/leap/soledad/client/auth.py +++ b/client/src/leap/soledad/client/auth.py @@ -37,10 +37,10 @@ class TokenBasedAuth(object):          """          Store given credentials so we can sign the request later. -        @param uuid: The user's uuid. -        @type uuid: str -        @param token: The authentication token. -        @type token: str +        :param uuid: The user's uuid. +        :type uuid: str +        :param token: The authentication token. +        :type token: str          """          self._creds = {'token': (uuid, token)} @@ -51,15 +51,15 @@ class TokenBasedAuth(object):              [('Authorization', 'Token <base64 encoded creds')] -        @param method: The HTTP method. -        @type method: str -        @param url_query: The URL query string. -        @type url_query: str -        @param params: A list with encoded query parameters. -        @type param: list +        :param method: The HTTP method. +        :type method: str +        :param url_query: The URL query string. +        :type url_query: str +        :param params: A list with encoded query parameters. +        :type param: list -        @return: The Authorization header. -        @rtype: list of tuple +        :return: The Authorization header. +        :rtype: list of tuple          """          if 'token' in self._creds:              uuid, token = self._creds['token'] diff --git a/client/src/leap/soledad/client/crypto.py b/client/src/leap/soledad/client/crypto.py index 9fcff8e9..a6372107 100644 --- a/client/src/leap/soledad/client/crypto.py +++ b/client/src/leap/soledad/client/crypto.py @@ -70,8 +70,8 @@ class SoledadCrypto(object):          """          Initialize the crypto object. -        @param soledad: A Soledad instance for key lookup. -        @type soledad: leap.soledad.Soledad +        :param soledad: A Soledad instance for key lookup. +        :type soledad: leap.soledad.Soledad          """          self._soledad = soledad @@ -82,15 +82,15 @@ class SoledadCrypto(object):          Currently, the only  encryption method supported is AES-256 CTR mode. -        @param data: The data to be encrypted. -        @type data: str -        @param key: The key used to encrypt C{data} (must be 256 bits long). -        @type key: str -        @param method: The encryption method to use. -        @type method: str +        :param data: The data to be encrypted. +        :type data: str +        :param key: The key used to encrypt C{data} (must be 256 bits long). +        :type key: str +        :param method: The encryption method to use. +        :type method: str -        @return: A tuple with the initial value and the encrypted data. -        @rtype: (long, str) +        :return: A tuple with the initial value and the encrypted data. +        :rtype: (long, str)          """          soledad_assert_type(key, str) @@ -119,17 +119,17 @@ class SoledadCrypto(object):          Currently, the only encryption method supported is AES-256 CTR mode. -        @param data: The data to be decrypted. -        @type data: str -        @param key: The key used to decrypt C{data} (must be 256 bits long). -        @type key: str -        @param method: The encryption method to use. -        @type method: str -        @param kwargs: Other parameters specific to each encryption method. -        @type kwargs: dict - -        @return: The decrypted data. -        @rtype: str +        :param data: The data to be decrypted. +        :type data: str +        :param key: The key used to decrypt C{data} (must be 256 bits long). +        :type key: str +        :param method: The encryption method to use. +        :type method: str +        :param kwargs: Other parameters specific to each encryption method. +        :type kwargs: dict + +        :return: The decrypted data. +        :rtype: str          """          soledad_assert_type(key, str)          # assert params @@ -160,14 +160,14 @@ class SoledadCrypto(object):          secret stripped from the first MAC_KEY_LENGTH characters. The HMAC          message is C{doc_id}. -        @param doc_id: The id of the document that will be encrypted using +        :param doc_id: The id of the document that will be encrypted using              this passphrase. -        @type doc_id: str +        :type doc_id: str -        @return: The passphrase. -        @rtype: str +        :return: The passphrase. +        :rtype: str -        @raise NoSymmetricSecret: if no symmetric secret was supplied. +        :raise NoSymmetricSecret: if no symmetric secret was supplied.          """          if self.secret is None:              raise NoSymmetricSecret() @@ -187,13 +187,13 @@ class SoledadCrypto(object):          function. The key used for HMAC is the first MAC_KEY_LENGTH characters          of Soledad's storage secret. The HMAC message is C{doc_id}. -        @param doc_id: The id of the document. -        @type doc_id: str +        :param doc_id: The id of the document. +        :type doc_id: str -        @return: The key. -        @rtype: str +        :return: The key. +        :rtype: str -        @raise NoSymmetricSecret: if no symmetric secret was supplied. +        :raise NoSymmetricSecret: if no symmetric secret was supplied.          """          if self.secret is None:              raise NoSymmetricSecret() diff --git a/client/src/leap/soledad/client/shared_db.py b/client/src/leap/soledad/client/shared_db.py index a6ca504d..adcde4e2 100644 --- a/client/src/leap/soledad/client/shared_db.py +++ b/client/src/leap/soledad/client/shared_db.py @@ -61,10 +61,10 @@ class SoledadSharedDatabase(http_database.HTTPDatabase, TokenBasedAuth):          """          Store given credentials so we can sign the request later. -        @param uuid: The user's uuid. -        @type uuid: str -        @param token: The authentication token. -        @type token: str +        :param uuid: The user's uuid. +        :type uuid: str +        :param token: The authentication token. +        :type token: str          """          TokenBasedAuth.set_token_credentials(self, uuid, token) @@ -72,15 +72,15 @@ class SoledadSharedDatabase(http_database.HTTPDatabase, TokenBasedAuth):          """          Return an authorization header to be included in the HTTP request. -        @param method: The HTTP method. -        @type method: str -        @param url_query: The URL query string. -        @type url_query: str -        @param params: A list with encoded query parameters. -        @type param: list +        :param method: The HTTP method. +        :type method: str +        :param url_query: The URL query string. +        :type url_query: str +        :param params: A list with encoded query parameters. +        :type param: list -        @return: The Authorization header. -        @rtype: list of tuple +        :return: The Authorization header. +        :rtype: list of tuple          """          return TokenBasedAuth._sign_request(self, method, url_query, params) @@ -95,16 +95,16 @@ class SoledadSharedDatabase(http_database.HTTPDatabase, TokenBasedAuth):          """          Open a Soledad shared database. -        @param url: URL of the remote database. -        @type url: str -        @param create: Should the database be created if it does not already +        :param url: URL of the remote database. +        :type url: str +        :param create: Should the database be created if it does not already              exist? -        @type create: bool -        @param token: An authentication token for accessing the shared db. -        @type token: str +        :type create: bool +        :param token: An authentication token for accessing the shared db. +        :type token: str -        @return: The shared database in the given url. -        @rtype: SoledadSharedDatabase +        :return: The shared database in the given url. +        :rtype: SoledadSharedDatabase          """          db = SoledadSharedDatabase(url, creds=creds)          db.open(create) @@ -115,10 +115,10 @@ class SoledadSharedDatabase(http_database.HTTPDatabase, TokenBasedAuth):          """          Dummy method that prevents from deleting shared database. -        @raise: This will always raise an Unauthorized exception. +        :raise: This will always raise an Unauthorized exception. -        @param url: The database URL. -        @type url: str +        :param url: The database URL. +        :type url: str          """          raise Unauthorized("Can't delete shared database.") @@ -126,13 +126,13 @@ class SoledadSharedDatabase(http_database.HTTPDatabase, TokenBasedAuth):          """          Initialize database with auth token and encryption powers. -        @param url: URL of the remote database. -        @type url: str -        @param document_factory: A factory for U1BD documents. -        @type document_factory: u1db.Document -        @param creds: A tuple containing the authentication method and +        :param url: URL of the remote database. +        :type url: str +        :param document_factory: A factory for U1BD documents. +        :type document_factory: u1db.Document +        :param creds: A tuple containing the authentication method and              credentials. -        @type creds: tuple +        :type creds: tuple          """          http_database.HTTPDatabase.__init__(self, url, document_factory,                                              creds) diff --git a/client/src/leap/soledad/client/sqlcipher.py b/client/src/leap/soledad/client/sqlcipher.py index c605c28c..3e01a4fb 100644 --- a/client/src/leap/soledad/client/sqlcipher.py +++ b/client/src/leap/soledad/client/sqlcipher.py @@ -79,29 +79,29 @@ def open(path, password, create=True, document_factory=None, crypto=None,      Will raise u1db.errors.DatabaseDoesNotExist if create=False and the      database does not already exist. -    @param path: The filesystem path for the database to open. -    @param type: str -    @param create: True/False, should the database be created if it doesn't +    :param path: The filesystem path for the database to open. +    :param type: str +    :param create: True/False, should the database be created if it doesn't          already exist? -    @param type: bool -    @param document_factory: A function that will be called with the same +    :param type: bool +    :param document_factory: A function that will be called with the same          parameters as Document.__init__. -    @type document_factory: callable -    @param crypto: An instance of SoledadCrypto so we can encrypt/decrypt +    :type document_factory: callable +    :param crypto: An instance of SoledadCrypto so we can encrypt/decrypt          document contents when syncing. -    @type crypto: soledad.crypto.SoledadCrypto -    @param raw_key: Whether C{password} is a raw 64-char hex string or a +    :type crypto: soledad.crypto.SoledadCrypto +    :param raw_key: Whether C{password} is a raw 64-char hex string or a          passphrase that should be hashed to obtain the encyrption key. -    @type raw_key: bool -    @param cipher: The cipher and mode to use. -    @type cipher: str -    @param kdf_iter: The number of iterations to use. -    @type kdf_iter: int -    @param cipher_page_size: The page size. -    @type cipher_page_size: int - -    @return: An instance of Database. -    @rtype SQLCipherDatabase +    :type raw_key: bool +    :param cipher: The cipher and mode to use. +    :type cipher: str +    :param kdf_iter: The number of iterations to use. +    :type kdf_iter: int +    :param cipher_page_size: The page size. +    :type cipher_page_size: int + +    :return: An instance of Database. +    :rtype SQLCipherDatabase      """      return SQLCipherDatabase.open_database(          path, password, create=create, document_factory=document_factory, @@ -143,25 +143,25 @@ class SQLCipherDatabase(sqlite_backend.SQLitePartialExpandDatabase):          """          Create a new sqlcipher file. -        @param sqlcipher_file: The path for the SQLCipher file. -        @type sqlcipher_file: str -        @param password: The password that protects the SQLCipher db. -        @type password: str -        @param document_factory: A function that will be called with the same +        :param sqlcipher_file: The path for the SQLCipher file. +        :type sqlcipher_file: str +        :param password: The password that protects the SQLCipher db. +        :type password: str +        :param document_factory: A function that will be called with the same              parameters as Document.__init__. -        @type document_factory: callable -        @param crypto: An instance of SoledadCrypto so we can encrypt/decrypt +        :type document_factory: callable +        :param crypto: An instance of SoledadCrypto so we can encrypt/decrypt              document contents when syncing. -        @type crypto: soledad.crypto.SoledadCrypto -        @param raw_key: Whether C{password} is a raw 64-char hex string or a +        :type crypto: soledad.crypto.SoledadCrypto +        :param raw_key: Whether C{password} is a raw 64-char hex string or a              passphrase that should be hashed to obtain the encyrption key. -        @type raw_key: bool -        @param cipher: The cipher and mode to use. -        @type cipher: str -        @param kdf_iter: The number of iterations to use. -        @type kdf_iter: int -        @param cipher_page_size: The page size. -        @type cipher_page_size: int +        :type raw_key: bool +        :param cipher: The cipher and mode to use. +        :type cipher: str +        :param kdf_iter: The number of iterations to use. +        :type kdf_iter: int +        :param cipher_page_size: The page size. +        :type cipher_page_size: int          """          # ensure the db is encrypted if the file already exists          if os.path.exists(sqlcipher_file): @@ -195,28 +195,28 @@ class SQLCipherDatabase(sqlite_backend.SQLitePartialExpandDatabase):          """          Open a SQLCipher database. -        @param sqlcipher_file: The path for the SQLCipher file. -        @type sqlcipher_file: str -        @param password: The password that protects the SQLCipher db. -        @type password: str -        @param document_factory: A function that will be called with the same +        :param sqlcipher_file: The path for the SQLCipher file. +        :type sqlcipher_file: str +        :param password: The password that protects the SQLCipher db. +        :type password: str +        :param document_factory: A function that will be called with the same              parameters as Document.__init__. -        @type document_factory: callable -        @param crypto: An instance of SoledadCrypto so we can encrypt/decrypt +        :type document_factory: callable +        :param crypto: An instance of SoledadCrypto so we can encrypt/decrypt              document contents when syncing. -        @type crypto: soledad.crypto.SoledadCrypto -        @param raw_key: Whether C{password} is a raw 64-char hex string or a +        :type crypto: soledad.crypto.SoledadCrypto +        :param raw_key: Whether C{password} is a raw 64-char hex string or a              passphrase that should be hashed to obtain the encyrption key. -        @type raw_key: bool -        @param cipher: The cipher and mode to use. -        @type cipher: str -        @param kdf_iter: The number of iterations to use. -        @type kdf_iter: int -        @param cipher_page_size: The page size. -        @type cipher_page_size: int +        :type raw_key: bool +        :param cipher: The cipher and mode to use. +        :type cipher: str +        :param kdf_iter: The number of iterations to use. +        :type kdf_iter: int +        :param cipher_page_size: The page size. +        :type cipher_page_size: int -        @return: The database object. -        @rtype: SQLCipherDatabase +        :return: The database object. +        :rtype: SQLCipherDatabase          """          if not os.path.isfile(sqlcipher_file):              raise u1db_errors.DatabaseDoesNotExist() @@ -267,33 +267,33 @@ class SQLCipherDatabase(sqlite_backend.SQLitePartialExpandDatabase):          """          Open a SQLCipher database. -        @param sqlcipher_file: The path for the SQLCipher file. -        @type sqlcipher_file: str -        @param password: The password that protects the SQLCipher db. -        @type password: str -        @param create: Should the datbase be created if it does not already +        :param sqlcipher_file: The path for the SQLCipher file. +        :type sqlcipher_file: str +        :param password: The password that protects the SQLCipher db. +        :type password: str +        :param create: Should the datbase be created if it does not already              exist? -        @type: bool -        @param backend_cls: A class to use as backend. -        @type backend_cls: type -        @param document_factory: A function that will be called with the same +        :type: bool +        :param backend_cls: A class to use as backend. +        :type backend_cls: type +        :param document_factory: A function that will be called with the same              parameters as Document.__init__. -        @type document_factory: callable -        @param crypto: An instance of SoledadCrypto so we can encrypt/decrypt +        :type document_factory: callable +        :param crypto: An instance of SoledadCrypto so we can encrypt/decrypt              document contents when syncing. -        @type crypto: soledad.crypto.SoledadCrypto -        @param raw_key: Whether C{password} is a raw 64-char hex string or a +        :type crypto: soledad.crypto.SoledadCrypto +        :param raw_key: Whether C{password} is a raw 64-char hex string or a              passphrase that should be hashed to obtain the encyrption key. -        @type raw_key: bool -        @param cipher: The cipher and mode to use. -        @type cipher: str -        @param kdf_iter: The number of iterations to use. -        @type kdf_iter: int -        @param cipher_page_size: The page size. -        @type cipher_page_size: int +        :type raw_key: bool +        :param cipher: The cipher and mode to use. +        :type cipher: str +        :param kdf_iter: The number of iterations to use. +        :type kdf_iter: int +        :param cipher_page_size: The page size. +        :type cipher_page_size: int -        @return: The database object. -        @rtype: SQLCipherDatabase +        :return: The database object. +        :rtype: SQLCipherDatabase          """          try:              return cls._open_database( @@ -316,16 +316,16 @@ class SQLCipherDatabase(sqlite_backend.SQLitePartialExpandDatabase):          """          Synchronize documents with remote replica exposed at url. -        @param url: The url of the target replica to sync with. -        @type url: str -        @param creds: optional dictionary giving credentials. +        :param url: The url of the target replica to sync with. +        :type url: str +        :param creds: optional dictionary giving credentials.              to authorize the operation with the server. -        @type creds: dict -        @param autocreate: Ask the target to create the db if non-existent. -        @type autocreate: bool +        :type creds: dict +        :param autocreate: Ask the target to create the db if non-existent. +        :type autocreate: bool -        @return: The local generation before the synchronisation was performed. -        @rtype: int +        :return: The local generation before the synchronisation was performed. +        :rtype: int          """          from u1db.sync import Synchronizer          from leap.soledad.client.target import SoledadSyncTarget @@ -343,8 +343,8 @@ class SQLCipherDatabase(sqlite_backend.SQLitePartialExpandDatabase):          method, which is executed when the database schema is created. Here,          we use it to include the "syncable" property for LeapDocuments. -        @param c: The cursor for querying the database. -        @type c: dbapi2.cursor +        :param c: The cursor for querying the database. +        :type c: dbapi2.cursor          """          c.execute(              'ALTER TABLE document ' @@ -354,10 +354,10 @@ class SQLCipherDatabase(sqlite_backend.SQLitePartialExpandDatabase):          """          Update a document and all indexes related to it. -        @param old_doc: The old version of the document. -        @type old_doc: u1db.Document -        @param doc: The new version of the document. -        @type doc: u1db.Document +        :param old_doc: The old version of the document. +        :type old_doc: u1db.Document +        :param doc: The new version of the document. +        :type doc: u1db.Document          """          sqlite_backend.SQLitePartialExpandDatabase._put_and_update_indexes(              self, old_doc, doc) @@ -370,15 +370,15 @@ class SQLCipherDatabase(sqlite_backend.SQLitePartialExpandDatabase):          """          Get just the document content, without fancy handling. -        @param doc_id: The unique document identifier -        @type doc_id: str -        @param include_deleted: If set to True, deleted documents will be +        :param doc_id: The unique document identifier +        :type doc_id: str +        :param include_deleted: If set to True, deleted documents will be              returned with empty content. Otherwise asking for a deleted              document will return None. -        @type include_deleted: bool +        :type include_deleted: bool -        @return: a Document object. -        @type: u1db.Document +        :return: a Document object. +        :type: u1db.Document          """          doc = sqlite_backend.SQLitePartialExpandDatabase._get_doc(              self, doc_id, check_for_conflicts) @@ -411,19 +411,19 @@ class SQLCipherDatabase(sqlite_backend.SQLitePartialExpandDatabase):          which will attempt to read the first page of the database and will          parse the schema. -        @param sqlcipher_file: The path for the SQLCipher file. -        @type sqlcipher_file: str -        @param key: The key that protects the SQLCipher db. -        @type key: str -        @param raw_key: Whether C{key} is a raw 64-char hex string or a +        :param sqlcipher_file: The path for the SQLCipher file. +        :type sqlcipher_file: str +        :param key: The key that protects the SQLCipher db. +        :type key: str +        :param raw_key: Whether C{key} is a raw 64-char hex string or a              passphrase that should be hashed to obtain the encyrption key. -        @type raw_key: bool -        @param cipher: The cipher and mode to use. -        @type cipher: str -        @param kdf_iter: The number of iterations to use. -        @type kdf_iter: int -        @param cipher_page_size: The page size. -        @type cipher_page_size: int +        :type raw_key: bool +        :param cipher: The cipher and mode to use. +        :type cipher: str +        :param kdf_iter: The number of iterations to use. +        :type kdf_iter: int +        :param cipher_page_size: The page size. +        :type cipher_page_size: int          """          try:              # try to open an encrypted database with the regular u1db @@ -473,11 +473,11 @@ class SQLCipherDatabase(sqlite_backend.SQLitePartialExpandDatabase):          * PRAGMA key should generally be called as the first operation on a            database. -        @param key: The key for use with the database. -        @type key: str -        @param raw_key: Whether C{key} is a raw 64-char hex string or a +        :param key: The key for use with the database. +        :type key: str +        :param raw_key: Whether C{key} is a raw 64-char hex string or a              passphrase that should be hashed to obtain the encyrption key. -        @type raw_key: bool +        :type raw_key: bool          """          if raw_key:              cls._pragma_key_raw(db_handle, key) @@ -495,10 +495,10 @@ class SQLCipherDatabase(sqlite_backend.SQLitePartialExpandDatabase):          if you want to do so you should use a raw key instead and derive the          key using your own KDF. -        @param db_handle: A handle to the SQLCipher database. -        @type db_handle: pysqlcipher.Connection -        @param passphrase: The passphrase used to derive the encryption key. -        @type passphrase: str +        :param db_handle: A handle to the SQLCipher database. +        :type db_handle: pysqlcipher.Connection +        :param passphrase: The passphrase used to derive the encryption key. +        :type passphrase: str          """          db_handle.cursor().execute("PRAGMA key = '%s'" % passphrase) @@ -512,10 +512,10 @@ class SQLCipherDatabase(sqlite_backend.SQLitePartialExpandDatabase):          ensure that the data provided is a 64 character hex string, which will          be converted directly to 32 bytes (256 bits) of key data. -        @param db_handle: A handle to the SQLCipher database. -        @type db_handle: pysqlcipher.Connection -        @param key: A 64 character hex string. -        @type key: str +        :param db_handle: A handle to the SQLCipher database. +        :type db_handle: pysqlcipher.Connection +        :param key: A 64 character hex string. +        :type key: str          """          if not all(c in string.hexdigits for c in key):              raise NotAnHexString(key) @@ -546,10 +546,10 @@ class SQLCipherDatabase(sqlite_backend.SQLitePartialExpandDatabase):            widely available and peer-reviewed OpenSSL libcrypto for all            cryptographic functions. -        @param db_handle: A handle to the SQLCipher database. -        @type db_handle: pysqlcipher.Connection -        @param cipher: The cipher and mode to use. -        @type cipher: str +        :param db_handle: A handle to the SQLCipher database. +        :type db_handle: pysqlcipher.Connection +        :param cipher: The cipher and mode to use. +        :type cipher: str          """          db_handle.cursor().execute("PRAGMA cipher = '%s'" % cipher) @@ -575,10 +575,10 @@ class SQLCipherDatabase(sqlite_backend.SQLitePartialExpandDatabase):          * It is not recommended to reduce the number of iterations if a            passphrase is in use. -        @param db_handle: A handle to the SQLCipher database. -        @type db_handle: pysqlcipher.Connection -        @param kdf_iter: The number of iterations to use. -        @type kdf_iter: int +        :param db_handle: A handle to the SQLCipher database. +        :type db_handle: pysqlcipher.Connection +        :param kdf_iter: The number of iterations to use. +        :type kdf_iter: int          """          db_handle.cursor().execute("PRAGMA kdf_iter = '%d'" % kdf_iter) @@ -608,10 +608,10 @@ class SQLCipherDatabase(sqlite_backend.SQLitePartialExpandDatabase):          * If a non-default value is used PRAGMA cipher_page_size to create a            database, it must also be called every time that database is opened. -        @param db_handle: A handle to the SQLCipher database. -        @type db_handle: pysqlcipher.Connection -        @param cipher_page_size: The page size. -        @type cipher_page_size: int +        :param db_handle: A handle to the SQLCipher database. +        :type db_handle: pysqlcipher.Connection +        :param cipher_page_size: The page size. +        :type cipher_page_size: int          """          db_handle.cursor().execute(              "PRAGMA cipher_page_size = '%d'" % cipher_page_size) @@ -637,13 +637,13 @@ class SQLCipherDatabase(sqlite_backend.SQLitePartialExpandDatabase):            code>PRAGMA rekey_kdf_iter. These are deprecated and should not be            used. Instead, use sqlcipher_export(). -        @param db_handle: A handle to the SQLCipher database. -        @type db_handle: pysqlcipher.Connection -        @param new_key: The new key. -        @type new_key: str -        @param raw_key: Whether C{password} is a raw 64-char hex string or a +        :param db_handle: A handle to the SQLCipher database. +        :type db_handle: pysqlcipher.Connection +        :param new_key: The new key. +        :type new_key: str +        :param raw_key: Whether C{password} is a raw 64-char hex string or a              passphrase that should be hashed to obtain the encyrption key. -        @type raw_key: bool +        :type raw_key: bool          """          if raw_key:              cls._pragma_rekey_raw(db_handle, key) @@ -659,10 +659,10 @@ class SQLCipherDatabase(sqlite_backend.SQLitePartialExpandDatabase):          PBKDF2 key derivation. The result is used as the encryption key for          the database. -        @param db_handle: A handle to the SQLCipher database. -        @type db_handle: pysqlcipher.Connection -        @param passphrase: The passphrase used to derive the encryption key. -        @type passphrase: str +        :param db_handle: A handle to the SQLCipher database. +        :type db_handle: pysqlcipher.Connection +        :param passphrase: The passphrase used to derive the encryption key. +        :type passphrase: str          """          db_handle.cursor().execute("PRAGMA rekey = '%s'" % passphrase) @@ -676,10 +676,10 @@ class SQLCipherDatabase(sqlite_backend.SQLitePartialExpandDatabase):          ensure that the data provided is a 64 character hex string, which will          be converted directly to 32 bytes (256 bits) of key data. -        @param db_handle: A handle to the SQLCipher database. -        @type db_handle: pysqlcipher.Connection -        @param key: A 64 character hex string. -        @type key: str +        :param db_handle: A handle to the SQLCipher database. +        :type db_handle: pysqlcipher.Connection +        :param key: A 64 character hex string. +        :type key: str          """          if not all(c in string.hexdigits for c in key):              raise NotAnHexString(key) diff --git a/client/src/leap/soledad/client/target.py b/client/src/leap/soledad/client/target.py index d0bc3706..65639887 100644 --- a/client/src/leap/soledad/client/target.py +++ b/client/src/leap/soledad/client/target.py @@ -98,19 +98,19 @@ def mac_doc(crypto, doc_id, doc_rev, ciphertext, mac_method):          * msg: doc_id + doc_rev + ciphertext          * digestmod: sha256 -    @param crypto: A SoledadCryto instance used to perform the encryption. -    @type crypto: leap.soledad.crypto.SoledadCrypto -    @param doc_id: The id of the document. -    @type doc_id: str -    @param doc_rev: The revision of the document. -    @type doc_rev: str -    @param ciphertext: The content of the document. -    @type ciphertext: str -    @param mac_method: The MAC method to use. -    @type mac_method: str - -    @return: The calculated MAC. -    @rtype: str +    :param crypto: A SoledadCryto instance used to perform the encryption. +    :type crypto: leap.soledad.crypto.SoledadCrypto +    :param doc_id: The id of the document. +    :type doc_id: str +    :param doc_rev: The revision of the document. +    :type doc_rev: str +    :param ciphertext: The content of the document. +    :type ciphertext: str +    :param mac_method: The MAC method to use. +    :type mac_method: str + +    :return: The calculated MAC. +    :rtype: str      """      if mac_method == MacMethods.HMAC:          return hmac.new( @@ -137,14 +137,14 @@ def encrypt_doc(crypto, doc):              MAC_METHOD_KEY: 'hmac'          } -    @param crypto: A SoledadCryto instance used to perform the encryption. -    @type crypto: leap.soledad.crypto.SoledadCrypto -    @param doc: The document with contents to be encrypted. -    @type doc: SoledadDocument +    :param crypto: A SoledadCryto instance used to perform the encryption. +    :type crypto: leap.soledad.crypto.SoledadCrypto +    :param doc: The document with contents to be encrypted. +    :type doc: SoledadDocument -    @return: The JSON serialization of the dict representing the encrypted +    :return: The JSON serialization of the dict representing the encrypted          content. -    @rtype: str +    :rtype: str      """      soledad_assert(doc.is_tombstone() is False)      # encrypt content using AES-256 CTR mode @@ -191,13 +191,13 @@ def decrypt_doc(crypto, doc):      EncryptionSchemes.SYMKEY and C{enc_method} is      EncryptionMethods.AES_256_CTR. -    @param crypto: A SoledadCryto instance to perform the encryption. -    @type crypto: leap.soledad.crypto.SoledadCrypto -    @param doc: The document to be decrypted. -    @type doc: SoledadDocument +    :param crypto: A SoledadCryto instance to perform the encryption. +    :type crypto: leap.soledad.crypto.SoledadCrypto +    :param doc: The document to be decrypted. +    :type doc: SoledadDocument -    @return: The JSON serialization of the decrypted content. -    @rtype: str +    :return: The JSON serialization of the decrypted content. +    :rtype: str      """      soledad_assert(doc.is_tombstone() is False)      soledad_assert(ENC_JSON_KEY in doc.content) @@ -258,10 +258,10 @@ class SoledadSyncTarget(HTTPSyncTarget, TokenBasedAuth):          """          Store given credentials so we can sign the request later. -        @param uuid: The user's uuid. -        @type uuid: str -        @param token: The authentication token. -        @type token: str +        :param uuid: The user's uuid. +        :type uuid: str +        :param token: The authentication token. +        :type token: str          """          TokenBasedAuth.set_token_credentials(self, uuid, token) @@ -269,15 +269,15 @@ class SoledadSyncTarget(HTTPSyncTarget, TokenBasedAuth):          """          Return an authorization header to be included in the HTTP request. -        @param method: The HTTP method. -        @type method: str -        @param url_query: The URL query string. -        @type url_query: str -        @param params: A list with encoded query parameters. -        @type param: list +        :param method: The HTTP method. +        :type method: str +        :param url_query: The URL query string. +        :type url_query: str +        :param params: A list with encoded query parameters. +        :type param: list -        @return: The Authorization header. -        @rtype: list of tuple +        :return: The Authorization header. +        :rtype: list of tuple          """          return TokenBasedAuth._sign_request(self, method, url_query, params) @@ -293,14 +293,14 @@ class SoledadSyncTarget(HTTPSyncTarget, TokenBasedAuth):          """          Initialize the SoledadSyncTarget. -        @param url: The url of the target replica to sync with. -        @type url: str -        @param creds: optional dictionary giving credentials. +        :param url: The url of the target replica to sync with. +        :type url: str +        :param creds: optional dictionary giving credentials.              to authorize the operation with the server. -        @type creds: dict -        @param soledad: An instance of Soledad so we can encrypt/decrypt +        :type creds: dict +        :param soledad: An instance of Soledad so we can encrypt/decrypt              document contents when syncing. -        @type soledad: soledad.Soledad +        :type soledad: soledad.Soledad          """          HTTPSyncTarget.__init__(self, url, creds)          self._crypto = crypto @@ -314,19 +314,19 @@ class SoledadSyncTarget(HTTPSyncTarget, TokenBasedAuth):          EncryptionSchemes.SYMKEY, then this method will decrypt it with          Soledad's symmetric key. -        @param data: The body of the HTTP response. -        @type data: str -        @param return_doc_cb: A callback to insert docs from target. -        @type return_doc_cb: function -        @param ensure_callback: A callback to ensure we have the correct +        :param data: The body of the HTTP response. +        :type data: str +        :param return_doc_cb: A callback to insert docs from target. +        :type return_doc_cb: function +        :param ensure_callback: A callback to ensure we have the correct              target_replica_uid, if it was just created. -        @type ensure_callback: function +        :type ensure_callback: function -        @raise BrokenSyncStream: If C{data} is malformed. +        :raise BrokenSyncStream: If C{data} is malformed. -        @return: A dictionary representing the first line of the response got +        :return: A dictionary representing the first line of the response got              from remote replica. -        @rtype: list of str +        :rtype: list of str          """          parts = data.splitlines()  # one at a time          if not parts or parts[0] != '[': @@ -381,25 +381,25 @@ class SoledadSyncTarget(HTTPSyncTarget, TokenBasedAuth):          This does the same as the parent's method but encrypts content before          syncing. -        @param docs_by_generations: A list of (doc_id, generation, trans_id) +        :param docs_by_generations: A list of (doc_id, generation, trans_id)              of local documents that were changed since the last local              generation the remote replica knows about. -        @type docs_by_generations: list of tuples -        @param source_replica_uid: The uid of the source replica. -        @type source_replica_uid: str -        @param last_known_generation: Target's last known generation. -        @type last_known_generation: int -        @param last_known_trans_id: Target's last known transaction id. -        @type last_known_trans_id: str -        @param return_doc_cb: A callback for inserting received documents from +        :type docs_by_generations: list of tuples +        :param source_replica_uid: The uid of the source replica. +        :type source_replica_uid: str +        :param last_known_generation: Target's last known generation. +        :type last_known_generation: int +        :param last_known_trans_id: Target's last known transaction id. +        :type last_known_trans_id: str +        :param return_doc_cb: A callback for inserting received documents from              target. -        @type return_doc_cb: function -        @param ensure_callback: A callback that ensures we know the target +        :type return_doc_cb: function +        :param ensure_callback: A callback that ensures we know the target              replica uid if the target replica was just created. -        @type ensure_callback: function +        :type ensure_callback: function -        @return: The new generation and transaction id of the target replica. -        @rtype: tuple +        :return: The new generation and transaction id of the target replica. +        :rtype: tuple          """          self._ensure_connection()          if self._trace_hook:  # for tests | 
