Example #1
0
def authenticated_user(aaai_services):
    from Acquire.Crypto import PrivateKey, OTP
    from Acquire.Client import User, Service, Wallet

    username = str(uuid.uuid4())
    password = PrivateKey.random_passphrase()

    result = User.register(username=username,
                           password=password,
                           identity_url="identity")

    otpsecret = result["otpsecret"]
    otp = OTP(otpsecret)

    # now log the user in
    user = User(username=username, identity_url="identity", auto_logout=False)

    result = user.request_login()

    assert (type(result) is dict)

    wallet = Wallet()

    wallet.send_password(url=result["login_url"],
                         username=username,
                         password=password,
                         otpcode=otp.generate(),
                         remember_password=False,
                         remember_device=False)

    user.wait_for_login()

    assert (user.is_logged_in())

    return user
Example #2
0
def test_service_object(tmpdir_factory):
    bucket = tmpdir_factory.mktemp("test_service")
    push_testing_objstore(bucket)
    push_is_running_service()

    try:
        service = Service.create(service_type="identity",
                                 service_url="identity")

        assert(service.uid() is not None)
        assert(service.uid().startswith("STAGE1"))

        service.create_stage2(service_uid="Z9-Z8", response=service.uid())

        assert(service.is_identity_service())
        assert(not service.should_refresh_keys())
        assert(service.is_unlocked())
        assert(not service.is_locked())

        passphrase = PrivateKey.random_passphrase()

        data = service.to_data(passphrase)

        service2 = IdentityService.from_data(data, passphrase)

        assert(service2.uid() == service.uid())
        assert(service2.is_unlocked())
        assert(not service2.is_locked())
        assert(service2.is_identity_service())
        assert(service.canonical_url() == service2.canonical_url())
        assert(not service2.should_refresh_keys())

        keys = service.dump_keys()

        keys = service.load_keys(keys)

        assert(keys[service.private_key().fingerprint()] ==
               service.private_key())
        assert(keys[service.private_certificate().fingerprint()] ==
               service.private_certificate())

        service.refresh_keys()

        assert(service.last_key_update() > service2.last_key_update())
        assert(service.last_certificate().public_key() ==
               service2.public_certificate())
        assert(service.last_key() == service2.private_key())
    except:
        pop_is_running_service()
        pop_testing_objstore()
        raise

    pop_is_running_service()
    pop_testing_objstore()
Example #3
0
    def __init__(self, drive_uid=None, file_uid=None):
        """Create a new ChunkUploader that uploads the specified
           file to the specified drive
        """
        self._drive_uid = None
        self._file_uid = None
        self._chunk_idx = None
        self._service = None

        if drive_uid is not None:
            self._drive_uid = str(drive_uid)
            self._file_uid = str(file_uid)
            from Acquire.Crypto import PrivateKey as _PrivateKey
            self._secret = _PrivateKey.random_passphrase()
Example #4
0
    def challenge_service(self, service):
        """Send a challenge to the passed service, returning the actual
           service returned. This will only pass if our copy of the
           service matches us with the copy returned from the actual
           service. This verifies that there is a real service sitting
           at that URL, and that we have the right keys and certs
        """
        from Acquire.Crypto import PrivateKey as _PrivateKey
        from Acquire.ObjectStore import bytes_to_string as _bytes_to_string
        from Acquire.Service import Service as _Service

        challenge = _PrivateKey.random_passphrase()
        pubkey = service.public_key()
        encrypted_challenge = pubkey.encrypt(challenge)

        args = {"challenge": _bytes_to_string(encrypted_challenge),
                "fingerprint": pubkey.fingerprint()}

        if service.uid().startswith("STAGE"):
            # we cannot call using the service directly, as it is
            # not yet fully constructed
            from Acquire.Service import get_this_service as _get_this_service
            from Acquire.Service import call_function as _call_function
            this_service = _get_this_service(need_private_access=True)
            result = _call_function(service_url=service.service_url(),
                                    function=None,
                                    args=args,
                                    args_key=service.public_key(),
                                    response_key=this_service.private_key(),
                                    public_cert=service.public_certificate())
        else:
            result = service.call_function(function=None, args=args)

        if result["response"] != challenge:
            raise PermissionError(
                "Failure of the service %s to correctly respond "
                "to the challenge!" % service)

        return _Service.from_data(result["service_info"])
    def __init__(self, drive_uid=None, file_uid=None):
        """Create a new ChunkDowloader that downloads the specified
           file from the specified drive
        """
        self._uid = None
        self._drive_uid = None
        self._file_uid = None
        self._service = None

        self._next_index = None
        self._last_filename = None
        self._downloaded_filename = None
        self._FILE = None

        if drive_uid is not None:
            self._drive_uid = str(drive_uid)
            self._file_uid = str(file_uid)
            from Acquire.Crypto import PrivateKey as _PrivateKey
            self._secret = _PrivateKey.random_passphrase()

            from Acquire.ObjectStore import create_uid as _create_uid
            self._uid = _create_uid(short_uid=True)
Example #6
0
import pytest

from Acquire.Service import call_function
from Acquire.Client import User, Wallet
from Acquire.Identity import Authorisation
from Acquire.Crypto import OTP, PrivateKey

_wallet_password = PrivateKey.random_passphrase()


@pytest.mark.parametrize("username, password",
                         [("testuser", "ABCdef12345"),
                          ("something", "!!DDerfld31"),
                          ("someone", "%$(F*Dj4jij43  kdfjdk")])
def test_login(username, password, aaai_services, tmpdir):
    # register the new user
    result = User.register(username=username,
                           password=password,
                           identity_url="identity")

    assert(type(result) is dict)

    otpsecret = result["otpsecret"]

    otp = OTP(otpsecret)

    user = User(username=username, identity_url="identity",
                auto_logout=False)

    result = user.request_login()
Example #7
0
def aaai_services(tmpdir_factory):
    """This function creates mocked versions of all of the main services
       of the system, returning the json describing each service as
       a dictionary (which is passed to the test functions as the
       fixture)
    """
    from Acquire.Identity import Authorisation
    from Acquire.Crypto import PrivateKey, OTP
    from Acquire.Service import call_function, Service

    _services = {}
    _services["registry"] = tmpdir_factory.mktemp("registry")
    _services["identity"] = tmpdir_factory.mktemp("identity")
    _services["accounting"] = tmpdir_factory.mktemp("accounting")
    _services["access"] = tmpdir_factory.mktemp("access")
    _services["storage"] = tmpdir_factory.mktemp("storage")
    _services["userdata"] = tmpdir_factory.mktemp("userdata")
    _services["compute"] = tmpdir_factory.mktemp("compute")
    _services["hugs"] = tmpdir_factory.mktemp("hugs")

    wallet_dir = tmpdir_factory.mktemp("wallet")
    wallet_password = PrivateKey.random_passphrase()

    _set_services(_services, wallet_dir, wallet_password)

    password = PrivateKey.random_passphrase()
    args = {"password": password}

    responses = {}

    os.environ["SERVICE_PASSWORD"] = "******"
    os.environ["STORAGE_COMPARTMENT"] = str(_services["userdata"])

    args["canonical_url"] = "registry"
    args["service_type"] = "registry"
    args["registry_uid"] = "Z9-Z9"  # UID of testing registry
    response = call_function("registry", function="admin/setup", args=args)

    registry_service = Service.from_data(response["service"])
    registry_otp = OTP(OTP.extract_secret(response["provisioning_uri"]))
    registry_user = _login_admin("registry", "admin", password, registry_otp)
    responses["registry"] = {
        "service": registry_service,
        "user": registry_user,
        "response": response,
    }

    assert registry_service.registry_uid() == registry_service.uid()
    service_uids = [registry_service.uid()]

    args["canonical_url"] = "identity"
    args["service_type"] = "identity"
    response = call_function("identity", function="admin/setup", args=args)

    identity_service = Service.from_data(response["service"])
    identity_otp = OTP(OTP.extract_secret(response["provisioning_uri"]))
    identity_user = _login_admin("identity", "admin", password, identity_otp)
    responses["identity"] = {
        "service": identity_service,
        "user": identity_user,
        "response": response,
    }

    assert identity_service.registry_uid() == registry_service.uid()
    assert identity_service.uid() not in service_uids
    service_uids.append(identity_service.uid())

    args["canonical_url"] = "accounting"
    args["service_type"] = "accounting"
    response = call_function("accounting", function="admin/setup", args=args)
    accounting_service = Service.from_data(response["service"])
    accounting_otp = OTP(OTP.extract_secret(response["provisioning_uri"]))
    accounting_user = _login_admin("accounting", "admin", password,
                                   accounting_otp)
    responses["accounting"] = {
        "service": accounting_service,
        "user": accounting_user,
        "response": response,
    }

    assert accounting_service.registry_uid() == registry_service.uid()
    assert accounting_service.uid() not in service_uids
    service_uids.append(accounting_service.uid())

    args["canonical_url"] = "access"
    args["service_type"] = "access"
    response = call_function("access", function="admin/setup", args=args)
    responses["access"] = response
    access_service = Service.from_data(response["service"])
    access_otp = OTP(OTP.extract_secret(response["provisioning_uri"]))
    access_user = _login_admin("access", "admin", password, access_otp)
    responses["access"] = {
        "service": access_service,
        "user": access_user,
        "response": response,
    }

    assert access_service.registry_uid() == registry_service.uid()
    assert access_service.uid() not in service_uids
    service_uids.append(access_service.uid())

    args["canonical_url"] = "compute"
    args["service_type"] = "compute"
    response = call_function("compute", function="admin/setup", args=args)
    responses["compute"] = response
    compute_service = Service.from_data(response["service"])
    compute_otp = OTP(OTP.extract_secret(response["provisioning_uri"]))
    compute_user = _login_admin("compute", "admin", password, compute_otp)
    responses["compute"] = {
        "service": compute_service,
        "user": compute_user,
        "response": response,
    }

    assert compute_service.registry_uid() == registry_service.uid()
    assert compute_service.uid() not in service_uids
    service_uids.append(compute_service.uid())

    args["canonical_url"] = "storage"
    args["service_type"] = "storage"
    response = call_function("storage", function="admin/setup", args=args)
    storage_service = Service.from_data(response["service"])
    storage_otp = OTP(OTP.extract_secret(response["provisioning_uri"]))
    storage_user = _login_admin("storage", "admin", password, storage_otp)
    responses["storage"] = {
        "service": storage_service,
        "user": storage_user,
        "response": response,
    }

    assert storage_service.registry_uid() == registry_service.uid()
    assert storage_service.uid() not in service_uids
    service_uids.append(storage_service.uid())

    args["canonical_url"] = "hugs"
    args["service_type"] = "hugs"
    response = call_function("hugs", function="admin/setup", args=args)
    responses["hugs"] = response
    hugs_service = Service.from_data(response["service"])
    hugs_otp = OTP(OTP.extract_secret(response["provisioning_uri"]))
    hugs_user = _login_admin("hugs", "admin", password, hugs_otp)
    responses["hugs"] = {
        "service": hugs_service,
        "user": hugs_user,
        "response": response,
    }

    resource = "trust_accounting_service %s" % accounting_service.uid()
    args = {
        "service_url":
        accounting_service.canonical_url(),
        "authorisation":
        Authorisation(user=access_user, resource=resource).to_data(),
    }
    access_service.call_function(function="admin/trust_accounting_service",
                                 args=args)

    responses["_services"] = _services

    return responses
Example #8
0
    def create(username,
               password,
               _service_uid=None,
               _service_public_key=None):
        """Create a new account with username 'username', which will
           be secured using the passed password.

           Note that this will create an account with a specified
           user UID, meaning that different users can have the same
           username. We identify the right user via the combination
           of username, password and OTP code.

           Normally the UID of the service, and the skeleton key
           used to encrypt the backup password are obtained
           directly from the service. However, when initialising
           a new service we must pass these directly. In those
           cases, pass the object using _service_uid and
           _service_public_key

           This returns a tuple of the user_uid and OTP for the
           newly-created account
        """
        from Acquire.ObjectStore import create_uuid as _create_uuid
        from Acquire.Crypto import PrivateKey as _PrivateKey
        from Acquire.Crypto import PublicKey as _PublicKey
        from Acquire.ObjectStore import ObjectStore as _ObjectStore
        from Acquire.Service import get_service_account_bucket \
            as _get_service_account_bucket
        from Acquire.ObjectStore import bytes_to_string as _bytes_to_string
        from Acquire.Identity import UserCredentials as _UserCredentials
        from Acquire.ObjectStore import get_datetime_now_to_string \
            as _get_datetime_now_to_string

        if _service_public_key is None:
            from Acquire.Service import get_this_service as _get_this_service
            service_pubkey = _get_this_service().public_skeleton_key()
            assert (service_pubkey is not None)
        else:
            service_pubkey = _service_public_key

        if not isinstance(service_pubkey, _PublicKey):
            raise TypeError("The service public key must be type PublicKey")

        if _service_uid is None:
            from Acquire.Service import get_this_service \
                as _get_this_service
            service_uid = _get_this_service(need_private_access=False).uid()
        else:
            service_uid = _service_uid

        # create a UID for this new user
        user_uid = _create_uuid()

        # now create the primary password for this user and use
        # this to encrypt the special keys for this user
        privkey = _PrivateKey(name="user_secret_key %s %s" %
                              (username, user_uid))
        primary_password = _PrivateKey.random_passphrase()

        bucket = _get_service_account_bucket()

        # now create the credentials used to validate a login
        otp = _UserCredentials.create(user_uid=user_uid,
                                      password=password,
                                      primary_password=primary_password)

        # create the user account
        user = UserAccount(username=username,
                           user_uid=user_uid,
                           private_key=privkey,
                           status="active")

        # now save a lookup from the username to this user_uid
        # (many users can have the same username). Use this lookup
        # to hold a recovery password for this account
        recovery_password = _bytes_to_string(
            service_pubkey.encrypt(primary_password))

        key = "%s/names/%s/%s" % (_user_root, user.encoded_name(), user_uid)
        _ObjectStore.set_string_object(bucket=bucket,
                                       key=key,
                                       string_data=recovery_password)

        # now save a lookup from the hashed username+password
        # to the user_uid, so that we can
        # quickly find matching user_uids (expect few people will have
        # exactly the same username and password). This will
        # save the exact time this username-password combination
        # was set
        encoded_password = _UserCredentials.hash(username=username,
                                                 password=password,
                                                 service_uid=service_uid)

        key = "%s/passwords/%s/%s" % (_user_root, encoded_password, user_uid)
        _ObjectStore.set_string_object(
            bucket=bucket, key=key, string_data=_get_datetime_now_to_string())

        # finally(!) save the account itself to the object store
        key = "%s/uids/%s" % (_user_root, user_uid)
        data = user.to_data(passphrase=primary_password)
        _ObjectStore.set_object_from_json(bucket=bucket, key=key, data=data)

        # return the OTP and user_uid
        return (user_uid, otp)
def get_trusted_registry_service(registry_uid=None,
                                 service_uid=None,
                                 service_url=None):
    """Return the trusted service info for the registry with specified
       registry_uid, or get any trusted registry service using either
       'service_uid' or 'service_url' as a starting hint to
       locate a suitable registry
    """
    if service_uid is not None:
        # for the moment, just try to get one registry. Eventually we should
        # try to get several in case this one is down
        registry_uid = get_primary_registry_uid(service_uid)
        return get_trusted_registry_service(registry_uid=registry_uid)

    if service_url is not None:
        if service_url.find(".") != -1:
            # try the main acquire registry first
            return get_trusted_registry_service(registry_uid="a0-a0")
        else:
            # this must be testing...
            return get_trusted_registry_service(registry_uid="Z9-Z9")

    if registry_uid is None:
        raise PermissionError(
            "You must specify one of registry_uid, service_uid "
            "or service_url")

    from Acquire.Service import get_trusted_service as _get_trusted_service

    try:
        registry_service = _get_trusted_service(service_uid=registry_uid,
                                                autofetch=False)
    except:
        registry_service = None

    if registry_service is not None:
        if not registry_service.is_registry_service():
            from Acquire.Service import ServiceError
            raise ServiceError("The requested service (%s) for %s is NOT a "
                               "registry service!" %
                               (registry_service, registry_uid))

        if registry_service.uid() != registry_uid:
            from Acquire.Service import ServiceError
            raise ServiceError(
                "Disagreement of UID (%s) is NOT the right registry service!" %
                registry_service)

        # everything is ok - we have seen this registry before
        return registry_service

    # boostrapping
    from Acquire.Registry import get_registry_details \
        as _get_registry_details

    details = _get_registry_details(registry_uid)

    from Acquire.Service import call_function as _call_function
    from Acquire.Service import Service as _Service
    from Acquire.Crypto import get_private_key as _get_private_key
    from Acquire.Crypto import PrivateKey as _PrivateKey
    from Acquire.Crypto import PublicKey as _PublicKey
    from Acquire.ObjectStore import bytes_to_string as _bytes_to_string
    from Acquire.ObjectStore import string_to_bytes as _string_to_bytes

    privkey = _get_private_key(key="registry")

    pubkey = _PublicKey.from_data(details["public_key"])
    pubcert = _PublicKey.from_data(details["public_certificate"])

    # ask the registry to return to us their latest details - use
    # a challenge-response to make sure that the response is
    # properly returned
    challenge = _PrivateKey.random_passphrase()
    encrypted_challenge = _bytes_to_string(pubkey.encrypt(challenge))
    args = {
        "challenge": encrypted_challenge,
        "fingerprint": pubkey.fingerprint()
    }

    result = _call_function(service_url=details["canonical_url"],
                            function=None,
                            args=args,
                            args_key=pubkey,
                            response_key=privkey,
                            public_cert=pubcert)

    if result["response"] != challenge:
        from Acquire.Service import ServiceError
        raise ServiceError(
            "The requested service (%s) failed to respond to the challenge!" %
            registry_service)

    registry_service = _Service.from_data(result["service_info"])

    if not registry_service.is_registry_service():
        from Acquire.Service import ServiceError
        raise ServiceError(
            "The requested service (%s) is NOT a registry service!" %
            registry_service)

    if registry_service.uid() != details["uid"]:
        from Acquire.Service import ServiceError
        raise ServiceError(
            "Disagreement of UID (%s) is NOT the right registry service!" %
            registry_service)

    # ok - we've got the registry - add this to the set of
    # trusted services so that we don't need to bootstrap from
    # the registry details again
    from Acquire.Service import trust_service as _trust_service
    _trust_service(registry_service)

    return registry_service
Example #10
0
    def __init__(self,
                 location=None,
                 user=None,
                 aclrule=None,
                 expires_datetime=None):
        """Construct a PAR for the specified location,
           authorised by the passed user, giving permissions
           according to the passed 'aclrule' (default is
           ACLRule.reader()).

           The passed 'expires_datetime' is the time at which
           this PAR will expire (by default within 24 hours)
        """
        self._location = None
        self._uid = None
        self._expires_datetime = None

        if location is None:
            return

        from Acquire.Client import Location as _Location
        if not isinstance(location, _Location):
            raise TypeError("The location must be type Location")

        if location.is_null():
            return

        from Acquire.Client import User as _User
        if not isinstance(user, _User):
            raise TypeError("The user must be type User")

        if not user.is_logged_in():
            raise PermissionError("The passed User must be logged in!")

        from Acquire.Client import ACLRule as _ACLRule

        if aclrule is None:
            aclrule = _ACLRule.reader()
        elif not isinstance(aclrule, _ACLRule):
            raise TypeError("The aclrule must be type ACLRule")

        if expires_datetime is None:
            from Acquire.ObjectStore import get_datetime_future \
                as _get_datetime_future
            expires_datetime = _get_datetime_future(days=1)
        else:
            from Acquire.ObjectStore import datetime_to_datetime \
                as _datetime_to_datetime
            expires_datetime = _datetime_to_datetime(expires_datetime)

        self._location = location
        self._expires_datetime = expires_datetime
        self._aclrule = aclrule

        from Acquire.Client import Authorisation as _Authorisation
        auth = _Authorisation(user=user,
                              resource="create_par %s" % self.fingerprint())

        from Acquire.Crypto import PrivateKey as _PrivateKey
        self._secret = _PrivateKey.random_passphrase()

        args = {
            "authorisation": auth.to_data(),
            "par": self.to_data(),
            "secret": self._secret
        }

        service = location.service()

        result = service.call_function(function="create_par", args=args)

        self._set_uid(result["par_uid"])
Example #11
0
    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

        print("Passwords not equal - please try again")

    service_salt = PrivateKey.random_passphrase()
    password = Hash.multi_md5(password, service_salt)

    old_config = None
    service_key = PrivateKey()
    service_key_data = service_key.to_data(passphrase=password)

with open(config_file, "r") as FILE:
    config = load(FILE, Loader=Loader)

if old_config is not None:
    if old_config["service"] != config["service"]:
        for key in config["service"].keys():
            if old_config["service"][key] != config["service"][key]:
                print(
                    "\nDisagree key = %s\n%s\n%s" %