def get_auth_token_saml(account, saml_nameid, appid, ip=None, session=None): """ Authenticate a Rucio account temporarily via SAML. The token lifetime is 1 hour. :param account: Account identifier as a string. :param saml_nameid: SAML NameID of the client. :param appid: The application identifier as a string. :param ip: IP address of the client a a string. :param session: The database session in use. :returns: A models.Token object as saved to the database. """ # Make sure the account exists if not account_exists(account, session=session): return None # remove expired tokens session.query(models.Token).filter(models.Token.expired_at < datetime.datetime.utcnow(), models.Token.account == account).with_for_update(skip_locked=True).delete() tuid = generate_uuid() # NOQA token = '%(account)s-%(saml_nameid)s-%(appid)s-%(tuid)s' % locals() new_token = models.Token(account=account, identity=saml_nameid, token=token, ip=ip) new_token.save(session=session) session.expunge(new_token) return new_token
def get_auth_token_gss(account, gsstoken, appid, ip=None, session=None): """ Authenticate a Rucio account temporarily via a GSS token. The token lifetime is 1 hour. :param account: Account identifier as a string. :param gsscred: GSS principal@REALM as a string. :param appid: The application identifier as a string. :param ip: IP address of the client as a string. :param session: The database session in use. :returns: Authentication token as a Python struct .token string .expired_at datetime """ # Make sure the account exists if not account_exists(account, session=session): return None # remove expired tokens session.query(models.Token).filter( models.Token.expired_at < datetime.datetime.utcnow(), models.Token.account == account).with_for_update( skip_locked=True).delete() # create new rucio-auth-token for account tuid = generate_uuid() # NOQA token = '%(account)s-%(gsstoken)s-%(appid)s-%(tuid)s' % locals() new_token = models.Token(account=account, token=token, ip=ip) new_token.save(session=session) session.expunge(new_token) return new_token
def get_ssh_challenge_token(account, appid, ip=None, session=None): """ Prepare a challenge token for subsequent SSH public key authentication. The challenge lifetime is fixed to 10 seconds. :param account: Account identifier as a string. :param appid: The application identifier as a string. :param ip: IP address of the client as a string. :returns: A models.Token object as saved to the database. """ # Make sure the account exists if not account_exists(account, session=session): return None # Cryptographically secure random number. # This requires a /dev/urandom like device from the OS rng = random.SystemRandom() crypto_rand = rng.randint(0, sys.maxsize) # give the client 10 seconds max to sign the challenge token expiration = datetime.datetime.utcnow() + datetime.timedelta(seconds=10) expiration_unix = expiration.strftime("%s") challenge_token = 'challenge-%(crypto_rand)s-%(account)s-%(expiration_unix)s' % locals() new_challenge_token = models.Token(account=account, token=challenge_token, ip=ip, expired_at=expiration) new_challenge_token.save(session=session) session.expunge(new_challenge_token) return new_challenge_token
def get_auth_token_x509(account, dn, appid, ip=None, session=None): """ Authenticate a Rucio account temporarily via an x509 certificate. The token lifetime is 1 hour. :param account: Account identifier as a string. :param dn: Client certificate distinguished name string, as extracted by Apache/mod_ssl. :param id: The application identifier as a string. :param ipaddr: IP address of the client as a string. :param session: The database session in use. :returns: A models.Token object as saved to the database. """ # Make sure the account exists if not account_exists(account, session=session): return None # remove expired tokens session.query(models.Token).filter(models.Token.expired_at < datetime.datetime.utcnow(), models.Token.account == account).with_for_update(skip_locked=True).delete() # create new rucio-auth-token for account tuid = generate_uuid() # NOQA token = '%(account)s-%(dn)s-%(appid)s-%(tuid)s' % locals() new_token = models.Token(account=account, identity=dn, token=token, ip=ip) new_token.save(session=session) session.expunge(new_token) return new_token
def save_oidc_token(account, lifetime_access=0, lifetime_refresh=0, refresh_token=None, refresh=False, final_state=None): session = get_session() expired_at = datetime.datetime.utcnow() + datetime.timedelta( seconds=lifetime_access) refresh_expired_at = None if lifetime_refresh > 0: refresh_expired_at = datetime.datetime.utcnow() + datetime.timedelta( seconds=lifetime_refresh) if lifetime_refresh == 0 and refresh_token: refresh_expired_at = datetime.datetime.utcnow() new_token = models.Token(account=account, token=rndstr(), refresh_token=refresh_token, refresh=refresh, oidc_scope=json.dumps({'state': final_state}), expired_at=expired_at, refresh_expired_at=refresh_expired_at, identity="SUB=myid, ISS=mockiss") new_token.save(session=session) session.commit() # pylint: disable=no-member session.expunge(new_token) # pylint: disable=no-member return None
def get_auth_token_saml(account, saml_nameid, appid, ip=None, session=None): """ Authenticate a Rucio account temporarily via SAML. The token lifetime is 1 hour. :param account: Account identifier as a string. :param saml_nameid: SAML NameID of the client. :param appid: The application identifier as a string. :param ip: IP address of the client a a string. :param session: The database session in use. :returns: A dict with token and expires_at entries. """ # Make sure the account exists if not account_exists(account, session=session): return None # remove expired tokens __delete_expired_tokens_account(account=account, session=session) tuid = generate_uuid() # NOQA token = '%(account)s-%(saml_nameid)s-%(appid)s-%(tuid)s' % locals() new_token = models.Token(account=account, identity=saml_nameid, token=token, ip=ip) new_token.save(session=session) return token_dictionary(new_token)
def get_auth_token_gss(account, gsstoken, appid, ip=None, session=None): """ Authenticate a Rucio account temporarily via a GSS token. The token lifetime is 1 hour. :param account: Account identifier as a string. :param gsscred: GSS principal@REALM as a string. :param appid: The application identifier as a string. :param ip: IP address of the client as a string. :param session: The database session in use. :returns: A dict with token and expires_at entries. """ # Make sure the account exists if not account_exists(account, session=session): return None # remove expired tokens __delete_expired_tokens_account(account=account, session=session) # create new rucio-auth-token for account tuid = generate_uuid() # NOQA token = '%(account)s-%(gsstoken)s-%(appid)s-%(tuid)s' % locals() new_token = models.Token(account=account, token=token, ip=ip) new_token.save(session=session) return token_dictionary(new_token)
def get_auth_token_x509(account, dn, appid, ip=None, session=None): """ Authenticate a Rucio account temporarily via an x509 certificate. The token lifetime is 1 hour. :param account: Account identifier as a string. :param dn: Client certificate distinguished name string, as extracted by Apache/mod_ssl. :param id: The application identifier as a string. :param ipaddr: IP address of the client as a string. :param session: The database session in use. :returns: A dict with token and expires_at entries. """ # Make sure the account exists if not account_exists(account, session=session): return None # remove expired tokens __delete_expired_tokens_account(account=account, session=session) # create new rucio-auth-token for account tuid = generate_uuid() # NOQA token = '%(account)s-%(dn)s-%(appid)s-%(tuid)s' % locals() new_token = models.Token(account=account, identity=dn, token=token, ip=ip) new_token.save(session=session) return token_dictionary(new_token)
def get_auth_token_user_pass(account, username, password, appid, ip=None, session=None): """ Authenticate a Rucio account temporarily via username and password. The token lifetime is 1 hour. :param account: Account identifier as a string. :param username: Username as a string. :param password: SHA1 hash of the password as a string. :param appid: The application identifier as a string. :param ip: IP address of the client a a string. :param session: The database session in use. :returns: A models.Token object as saved to the database. """ # Make sure the account exists if not account_exists(account, session=session): return None result = session.query(models.Identity).filter_by( identity=username, identity_type=IdentityType.USERPASS).first() db_salt = result['salt'] db_password = result['password'] salted_password = db_salt + password.encode() if db_password != hashlib.sha256(salted_password).hexdigest(): return None # get account identifier result = session.query(models.IdentityAccountAssociation).filter_by( identity=username, identity_type=IdentityType.USERPASS, account=account).first() db_account = result['account'] # remove expired tokens session.query(models.Token).filter( models.Token.expired_at < datetime.datetime.utcnow(), models.Token.account == account).with_for_update( skip_locked=True).delete() # create new rucio-auth-token for account tuid = generate_uuid() # NOQA token = '%(account)s-%(username)s-%(appid)s-%(tuid)s' % locals() new_token = models.Token(account=db_account, identity=username, token=token, ip=ip) new_token.save(session=session) session.expunge(new_token) return new_token
def test_many_tokens(vo, root_account, db_session): """AUTHENTIFICATION (REST): Error when deleting too many tokens.""" for i in range(2000): models.Token( account=root_account, token="dummytoken" + str(i), ip='127.0.0.1', expired_at=datetime.datetime.utcnow()).save(session=db_session) db_session.commit() # Ensures that the tokens are expired time.sleep(1) print( get_auth_token_user_pass(account='root', username='******', password='******', appid='test', ip='127.0.0.1', vo=vo))
def get_auth_token_ssh(account, signature, appid, ip=None, session=None): """ Authenticate a Rucio account temporarily via SSH key exchange. The token lifetime is 1 hour. :param account: Account identifier as a string. :param signature: Response to server challenge signed with SSH private key as string. :param appid: The application identifier as a string. :param ip: IP address of the client as a string. :param session: The database session in use. :returns: A models.Token object as saved to the database. """ if not isinstance(signature, bytes): signature = signature.encode() # Make sure the account exists if not account_exists(account, session=session): return None # get all active challenge tokens for the requested account active_challenge_tokens = session.query(models.Token).filter(models.Token.expired_at >= datetime.datetime.utcnow(), models.Token.account == account, models.Token.token.like('challenge-%')).all() # get all identities for the requested account identities = session.query(models.IdentityAccountAssociation).filter_by(identity_type=IdentityType.SSH, account=account).all() # no challenge tokens found if not active_challenge_tokens: return None # try all available SSH identities for the account with the provided signature match = False for identity in identities: pub_k = paramiko.RSAKey(data=b64decode(identity['identity'].split()[1])) for challenge_token in active_challenge_tokens: if pub_k.verify_ssh_sig(str(challenge_token['token']).encode(), paramiko.Message(signature)): match = True break if match: break if not match: return None # remove expired tokens session.query(models.Token).filter(models.Token.expired_at < datetime.datetime.utcnow(), models.Token.account == account).with_for_update(skip_locked=True).delete() # create new rucio-auth-token for account tuid = generate_uuid() # NOQA token = '%(account)s-ssh:pubkey-%(appid)s-%(tuid)s' % locals() new_token = models.Token(account=account, token=token, ip=ip) new_token.save(session=session) session.expunge(new_token) return new_token