Example #1
0
    def from_data(data, password=None):
        """Deserialise this object from the passed data. This will
           only deserialise the private key, private certificate,
           and OTP if a valid password and passcode is supplied
        """

        service = Service()

        if password:
            # get the private info...
            service._privkey = _PrivateKey.from_data(data["private_key"],
                                                     password)

            service._privcert = _PrivateKey.from_data(
                                                data["private_certificate"],
                                                password)

            service._otpsecret = _string_to_bytes(data["otpsecret"])

            service._admin_password = _string_to_bytes(data["admin_password"])
        else:
            service._privkey = None
            service._privcert = None
            service._otpsecret = None

        service._uuid = data["uuid"]
        service._service_type = data["service_type"]
        service._service_url = data["service_url"]
        service._canonical_url = service._service_url

        service._pubkey = _PublicKey.from_data(data["public_key"])
        service._pubcert = _PublicKey.from_data(data["public_certificate"])

        if service.is_identity_service():
            from Acquire.Identity import IdentityService as _IdentityService
            return _IdentityService(service)
        elif service.is_access_service():
            from Acquire.Access import AccessService as _AccessService
            return _AccessService(service)
        elif service.is_accounting_service():
            from Acquire.Accounting import AccountingService \
                                        as _AccountingService
            return _AccountingService(service)
        else:
            return service
Example #2
0
def test_keys():
    privkey = PrivateKey()
    pubkey = privkey.public_key()

    message = "Hello World"

    sig = privkey.sign(message.encode("utf-8"))
    pubkey.verify(sig, message.encode("utf-8"))

    c = pubkey.encrypt(message.encode("utf-8"))

    m = privkey.decrypt(c).decode("utf-8")
    assert (m == message)

    privkey2 = PrivateKey()
    sig2 = privkey2.sign(message.encode("utf-8"))

    with pytest.raises(SignatureVerificationError):
        pubkey.verify(sig2, message.encode("utf-8"))

    bytes = privkey.bytes("testPass32")

    PrivateKey.read_bytes(bytes, "testPass32")

    privkey.write("test.pem", "testPass32")

    PrivateKey.read("test.pem", "testPass32")

    bytes = pubkey.bytes()
    pubkey2 = PublicKey.read_bytes(bytes)

    assert (bytes == pubkey2.bytes())

    long_message = str([random.getrandbits(8)
                        for _ in range(4096)]).encode("utf-8")

    c = pubkey.encrypt(long_message)

    m = privkey.decrypt(c)

    assert (m == long_message)

    os.unlink("test.pem")

    data = pubkey.to_data()

    pubkey2 = PublicKey.from_data(data)

    assert (pubkey.bytes() == pubkey2.bytes())

    data = privkey.to_data("testPass33")

    privkey2 = PrivateKey.from_data(data, "testPass33")

    assert (privkey == privkey2)
Example #3
0
    def from_data(data, passphrase=None):
        """Return a OSPar constructed from the passed json-deserliased
           dictionary

           Args:
                data (dict): JSON-deserialised dictionary from which to
                create OSPar
            Returns:
                OSPar: OSPar object created from dict
        """
        if data is None or len(data) == 0:
            return OSPar()

        from Acquire.ObjectStore import string_to_datetime \
            as _string_to_datetime
        from Acquire.ObjectStore import string_to_bytes \
            as _string_to_bytes

        par = OSPar()

        par._url = _string_to_bytes(data["url"])
        par._key = data["key"]
        par._uid = data["uid"]

        if par._key is not None:
            par._key = str(par._key)

        par._expires_datetime = _string_to_datetime(data["expires_datetime"])
        par._is_readable = data["is_readable"]
        par._is_writeable = data["is_writeable"]

        if "service_url" in data:
            par._service_url = data["service_url"]

        if "privkey" in data:
            if passphrase is not None:
                from Acquire.Crypto import PrivateKey as _PrivateKey
                par._privkey = _PrivateKey.from_data(data["privkey"],
                                                     passphrase)

        # note that we don't load the driver details as this
        # is stored and loaded separately on the service

        return par
Example #4
0
    def from_data(data, passphrase, mangleFunction=None):
        """Return a UserAccount constructed from the passed
           data (dictionary)
        """

        user = UserAccount()

        if data is not None and len(data) > 0:
            from Acquire.Crypto import PrivateKey as _PrivateKey

            user._username = data["username"]
            user._status = data["status"]
            user._uid = data["uid"]
            user._privkey = _PrivateKey.from_data(
                data=data["private_key"],
                passphrase=passphrase,
                mangleFunction=mangleFunction)

        return user
Example #5
0
def get_service_account_bucket(testing_dir=None):
    """This function logs into the object store account of the service account.
       Accessing the object store means being able to access
       all resources and which can authorise the creation
       of access all resources on the object store. Obviously this is
       a powerful account, so only log into it if you need it!!!

       The login information should not be put into a public
       repository or stored in plain text. In this case,
       the login information is held in an environment variable
       (which should be encrypted or hidden in some way...)
    """
    from Acquire.Service import assert_running_service as \
        _assert_running_service

    _assert_running_service()

    # read the password for the secret key from the filesystem
    try:
        with open("secret_key", "r") as FILE:
            password = FILE.readline()[0:-1]
    except:
        password = None

        # we must be in testing mode...
        from Acquire.ObjectStore import use_testing_object_store_backend as \
            _use_testing_object_store_backend

        # see if this is running in testing mode...
        global _current_testing_objstore
        if testing_dir:
            _current_testing_objstore = testing_dir
            return _use_testing_object_store_backend(testing_dir)
        elif _current_testing_objstore:
            return _use_testing_object_store_backend(_current_testing_objstore)

    if password is None:
        from Acquire.Service import ServiceAccountError
        raise ServiceAccountError(
            "You need to supply login credentials via the 'secret_key' "
            "file, and 'SECRET_KEY' and 'SECRET_CONFIG' environment "
            "variables! %s" % testing_dir)

    secret_key = _os.getenv("SECRET_KEY")

    if secret_key is None:
        from Acquire.Service import ServiceAccountError
        raise ServiceAccountError(
            "You must supply the password used to unlock the configuration "
            "key in the 'SECRET_KEY' environment variable")

    try:
        secret_key = _json.loads(secret_key)
    except Exception as e:
        from Acquire.Service import ServiceAccountError
        raise ServiceAccountError(
            "Unable to decode valid JSON from the secret key: %s" % str(e))

    # use the password to decrypt the SECRET_KEY in the config
    try:
        from Acquire.Crypto import PrivateKey as _PrivateKey
        secret_key = _PrivateKey.from_data(secret_key, password)
    except Exception as e:
        from Acquire.Service import ServiceAccountError
        raise ServiceAccountError(
            "Unable to open the private SECRET_KEY using the password "
            "supplied in the 'secret_key' file: %s" % str(e))

    config = _os.getenv("SECRET_CONFIG")

    if config is None:
        from Acquire.Service import ServiceAccountError
        raise ServiceAccountError(
            "You must supply the encrypted config in teh 'SECRET_CONFIG' "
            "environment variable!")

    try:
        from Acquire.ObjectStore import string_to_bytes as _string_to_bytes
        config = secret_key.decrypt(_string_to_bytes(config))
    except Exception as e:
        from Acquire.Service import ServiceAccountError
        raise ServiceAccountError(
            "Cannot decrypt the 'SECRET_CONFIG' with the 'SECRET_KEY'. Are "
            "you sure that the configuration has been set up correctly? %s "
            % str(e))

    # use the secret_key to decrypt the config in SECRET_CONFIG
    try:
        config = _json.loads(config)
    except Exception as e:
        from Acquire.Service import ServiceAccountError
        raise ServiceAccountError(
            "Unable to decode valid JSON from the config: %s" % str(e))

    # get info from this config
    access_data = config["LOGIN"]
    bucket_data = config["BUCKET"]

    # save the service password to the environment
    _os.environ["SERVICE_PASSWORD"] = config["PASSWORD"]

    # save any other decrypted config data to environment variables
    for key in config.keys():
        if key not in ["LOGIN", "BUCKET", "PASSWORD"]:
            _os.environ[key] = config[key]

    # we have OCI login details, so make sure that we are using
    # the OCI object store backend
    from Acquire.ObjectStore import use_oci_object_store_backend as \
        _use_oci_object_store_backend

    _use_oci_object_store_backend()

    # now login and create/load the bucket for this account
    try:
        from ._oci_account import OCIAccount as _OCIAccount

        account_bucket = _OCIAccount.create_and_connect_to_bucket(
                                    access_data,
                                    bucket_data["compartment"],
                                    bucket_data["bucket"])
    except Exception as e:
        from Acquire.Service import ServiceAccountError
        raise ServiceAccountError(
             "Error connecting to the service account: %s" % str(e))

    return account_bucket
    def validate_password(user_uid, username, device_uid, secrets, password,
                          otpcode, remember_device):
        """Validate that the passed password and one-time-code are valid.
           If they are, then return a tuple of the UserAccount of the unlocked
           user, the OTP that is used to generate secrets, and the
           device_uid of the login device

           If 'remember_device' is True and 'device_uid' is None, then
           this creates a new OTP for the login device, which is returned,
           and a new device_uid for that device. The password needed to
           match this device is a MD5 of the normal user password.
        """
        from Acquire.Crypto import PrivateKey as _PrivateKey
        from Acquire.Crypto import OTP as _OTP
        from Acquire.ObjectStore import string_to_bytes as _string_to_bytes

        privkey = _PrivateKey.from_data(data=secrets["private_key"],
                                        passphrase=password)

        # decrypt and validate the OTP code
        data = _string_to_bytes(secrets["otpsecret"])

        otpsecret = privkey.decrypt(data)
        otp = _OTP(secret=otpsecret)
        otp.verify(code=otpcode, once_only=True)

        # everything is ok - we can load the user account via the
        # decrypted primary password
        primary_password = _string_to_bytes(secrets["primary_password"])
        primary_password = privkey.decrypt(primary_password)

        from Acquire.ObjectStore import ObjectStore as _ObjectStore
        from Acquire.Service import get_service_account_bucket \
            as _get_service_account_bucket

        data = None
        secrets = None
        key = "%s/uids/%s" % (_user_root, user_uid)

        bucket = _get_service_account_bucket()

        try:
            data = _ObjectStore.get_object_from_json(bucket=bucket, key=key)
        except:
            pass

        if data is None:
            from Acquire.Identity import UserValidationError
            raise UserValidationError(
                "Unable to validate user as no account data is present!")

        from Acquire.Identity import UserAccount as _UserAccount
        user = _UserAccount.from_data(data=data, passphrase=primary_password)

        if user.uid() != user_uid:
            from Acquire.Identity import UserValidationError
            raise UserValidationError(
                "Unable to validate user as mismatch in user_uids!")

        if device_uid is None and remember_device:
            # create a new OTP that is unique for this device
            from Acquire.ObjectStore import create_uuid as _create_uuid
            from Acquire.Client import Credentials as _Credentials
            device_uid = _create_uuid()
            device_password = _Credentials.encode_device_uid(
                                                encoded_password=password,
                                                device_uid=device_uid)

            otp = UserCredentials.create(user_uid=user_uid,
                                         password=device_password,
                                         primary_password=primary_password,
                                         device_uid=device_uid)

            # now save a lookup so that we can find the user_uid from
            # the username and device-specific password
            encoded_password = UserCredentials.hash(
                                        username=username,
                                        password=device_password)

            key = "%s/passwords/%s/%s" % (_user_root, encoded_password,
                                          user_uid)

            from Acquire.ObjectStore import get_datetime_now_to_string \
                as _get_datetime_now_to_string

            _ObjectStore.set_string_object(
                                bucket=bucket, key=key,
                                string_data=_get_datetime_now_to_string())

        return {"user": user, "otp": otp, "device_uid": device_uid}
Example #7
0
service_file = "service.json"

if os.path.exists(service_file):
    with open(service_file, "r") as FILE:
        service_info = json.load(FILE)
        service_salt = service_info["salt"]

    while True:
        password = getpass.getpass(
            prompt="Please enter the service primary password: "******"key"],
                                               passphrase=password)
            break
        except:
            print("Password incorrect. Try again.")

    old_config = service_key.decrypt(string_to_bytes(service_info["config"]))
    old_config = json.loads(old_config)
    keep = True
else:
    while True:
        password = getpass.getpass(
            prompt="Please enter the service primary password: "******"Please enter the password again: ")

        if password == password2:
            break
def login_to_service_account(testing_dir=None):
    """This function logs into the object store account of the service account.
       Accessing the object store means being able to access
       all resources and which can authorise the creation
       of access all resources on the object store. Obviously this is
       a powerful account, so only log into it if you need it!!!

       The login information should not be put into a public
       repository or stored in plain text. In this case,
       the login information is held in an environment variable
       (which should be encrypted or hidden in some way...)
    """

    # read the password for the secret key from the filesystem
    try:
        with open("secret_key", "r") as FILE:
            password = FILE.readline()[0:-1]
    except:
        password = None

        # we must be in testing mode...
        from Acquire.ObjectStore import use_testing_object_store_backend as \
            _use_testing_object_store_backend

        # see if this is running in testing mode...
        global _current_testing_objstore
        if testing_dir:
            _current_testing_objstore = testing_dir
            return _use_testing_object_store_backend(testing_dir)
        elif _current_testing_objstore:
            return _use_testing_object_store_backend(_current_testing_objstore)

    if password is None:
        raise ServiceAccountError(
            "You need to supply login credentials via the 'secret_key' "
            "file, and 'SECRET_KEY' and 'SECRET_CONFIG' environment "
            "variables! %s" % testing_dir)

    # use the password to decrypt the SECRET_KEY in the config
    secret_key = _PrivateKey.from_data(_json.loads(_os.getenv("SECRET_KEY")),
                                       password)

    # use the secret_key to decrypt the config in SECRET_CONFIG
    config = _json.loads(
        secret_key.decrypt(_string_to_bytes(
            _os.getenv("SECRET_CONFIG"))).decode("utf-8"))

    # get info from this config
    access_data = config["LOGIN"]
    bucket_data = config["BUCKET"]

    # save the service password to the environment
    _os.environ["SERVICE_PASSWORD"] = config["PASSWORD"]

    # we have OCI login details, so make sure that we are using
    # the OCI object store backend
    from Acquire.ObjectStore import use_oci_object_store_backend as \
        _use_oci_object_store_backend

    _use_oci_object_store_backend()

    # now login and create/load the bucket for this account
    try:
        from ._oci_account import OCIAccount as _OCIAccount

        account_bucket = _OCIAccount.create_and_connect_to_bucket(
            access_data, bucket_data["compartment"], bucket_data["bucket"])
    except Exception as e:
        raise ServiceAccountError(
            "Error connecting to the service account: %s" % str(e))

    return account_bucket