예제 #1
0
def incorrect_login_handler(spawn, context, session):
    # In nxos device if the first attempt password prompt occur before
    # username prompt, it will get Login incorrect error.
    # Reset the cred_iter to try again
    if 'incorrect_login_attempts' not in session:
        session.pop('cred_iter', None)

    credential = get_current_credential(context=context, session=session)
    if credential and 'incorrect_login_attempts' in session:
        # If credentials have been supplied, there are no login retries.
        # The user must supply appropriate credentials to ensure login
        # does not fail. Skip it for the first attempt
        raise UniconAuthenticationError(
            'Login failure, either wrong username or password')
    else:
        if 'incorrect_login_attempts' not in session:
            session['incorrect_login_attempts'] = 1

        # Let's give a chance for unicon to login with right credentials
        # let's give three attempts
        if session['incorrect_login_attempts'] <= 3:
            session['incorrect_login_attempts'] = \
                session['incorrect_login_attempts'] + 1
        else:
            raise UniconAuthenticationError(
                'Login failure, either wrong username or password')
예제 #2
0
def password_handler(spawn, context, session):
    """ handles password prompt
    """
    credential = get_current_credential(context=context, session=session)
    if credential:
        common_cred_password_handler(
            spawn=spawn, context=context, credential=credential,
            session=session)
    else:
        if 'password_attempts' not in session:
            session['password_attempts'] = 1
        else:
            session['password_attempts'] += 1
        if session.password_attempts > spawn.settings.PASSWORD_ATTEMPTS:
            raise UniconAuthenticationError('Too many password retries')

        if context.get('username', '') == spawn.last_sent.rstrip() or ssh_tacacs_handler(spawn, context):
            spawn.sendline(context['tacacs_password'])
        else:
            spawn.sendline(context['line_password'])

    cred_actions = context.get('cred_action', {}).get(credential, {})
    if cred_actions:
        post_action = cred_actions.get('post', '')
        action = re.match(r'(send|sendline)\((.*)\)', post_action)
        if action:
            method = action.group(1)
            args = action.group(2)
            spawn.log.info('Executing post credential command: {}'.format(post_action))
            getattr(spawn, method)(args)
    elif credential and getattr(spawn.settings, 'SENDLINE_AFTER_CRED', None) == credential:
        spawn.log.info("Sending return after credential '{}'".format(credential))
        spawn.sendline()
예제 #3
0
def get_enable_credential_password(context):
    credentials = context.get('credentials')
    enable_credential_password = ""
    login_creds = context.get('login_creds', [])
    fallback_cred = context.get('default_cred_name', "")
    if not login_creds:
        login_creds=[fallback_cred]
    if not isinstance (login_creds, list):
        login_creds = [login_creds]

    final_credential = login_creds[-1] if login_creds else ""
    if credentials:
        enable_pw_checks = [
            (context.get('previous_credential', ""), 'enable_password'),
            (final_credential, 'enable_password'),
            (fallback_cred, 'enable_password'),
            (ENABLE_CRED_NAME, 'password'),
            (context.get('default_cred_name', ""), 'password'),
        ]
        for cred_name, key in enable_pw_checks:
            if cred_name:
                candidate_enable_pw = credentials.get(cred_name, {}).get(key)
                if candidate_enable_pw:
                    enable_credential_password = candidate_enable_pw
                    break
        else:
            raise UniconAuthenticationError('{}: Could not find an enable credential.'.\
                format(context.get('hostname', "")))
    return to_plaintext(enable_credential_password)
예제 #4
0
def common_cred_username_handler(spawn, context, credential):
    """ Send the current credential's username. """
    try:
        spawn.sendline(to_plaintext(
            context['credentials'][credential]['username']))
    except KeyError:
        raise UniconAuthenticationError("No username found "
            "for credential {}.".format(credential))
예제 #5
0
def enable_password_handler(spawn, context, session):
    credentials = context.get('credentials')
    enable_credential = credentials[ENABLE_CRED_NAME] if credentials else None
    if enable_credential:
        try:
            spawn.sendline(to_plaintext(enable_credential['password']))
        except KeyError as exc:
            raise UniconAuthenticationError("No password has been defined "
                "for credential {}.".format(ENABLE_CRED_NAME))
    else:
        if 'password_attempts' not in session:
            session['password_attempts'] = 1
        else:
            session['password_attempts'] += 1
        if session.password_attempts > spawn.settings.PASSWORD_ATTEMPTS:
            raise UniconAuthenticationError('Too many enable password retries')
        spawn.sendline(context['enable_password'])
예제 #6
0
def sudo_password_handler(spawn, context, session):
    """ Password handler for sudo command
    """
    if 'sudo_attempts' not in session:
        session['sudo_attempts'] = 1
    else:
        raise UniconAuthenticationError('sudo failure')

    credentials = context.get('credentials')
    if credentials:
        try:
            spawn.sendline(
                to_plaintext(credentials['sudo']['password']))
        except KeyError:
            raise UniconAuthenticationError("No password has been defined "
                                            "for sudo credential.")
    else:
        raise UniconAuthenticationError("No credentials has been defined for sudo.")
예제 #7
0
def passphrase_handler(spawn, context, session):
    """ Handles SSH passphrase prompt """
    credential = get_current_credential(context=context, session=session)
    try:
        spawn.sendline(to_plaintext(
            context['credentials'][credential]['passphrase']))
    except KeyError:
        raise UniconAuthenticationError("No passphrase found "
                                        "for credential {}.".format(credential))
예제 #8
0
def incorrect_login_handler(spawn, context, session):
    credential = get_current_credential(context=context, session=session)
    if credential:
        # If credentials have been supplied, there are no login retries.
        # The user must supply appropriate credentials to ensure login
        # does not fail.
        raise UniconAuthenticationError(
            'Login failure, either wrong username or password')
    else:
        if 'incorrect_login_attempts' not in session:
            session['incorrect_login_attempts'] = 1

        # Let's give a change for unicon to login with right credentials
        # let's give three attempts
        if session['incorrect_login_attempts'] <= 3:
            session['incorrect_login_attempts'] = \
                session['incorrect_login_attempts'] + 1
        else:
            raise UniconAuthenticationError(
                'Login failure, either wrong username or password')
예제 #9
0
def enable_password_handler(spawn, context, session):
    if 'password_attempts' not in session:
        session['password_attempts'] = 1
    else:
        session['password_attempts'] += 1
    if session.password_attempts > spawn.settings.PASSWORD_ATTEMPTS:
        raise UniconAuthenticationError('Too many enable password retries')

    credentials = context.get('credentials')
    enable_password = to_plaintext(credentials.get('enable', {}).get('password', ''))
    spawn.sendline(enable_password)
예제 #10
0
def enable_password_handler(spawn, context, session):
    if 'password_attempts' not in session:
        session['password_attempts'] = 1
    else:
        session['password_attempts'] += 1
    if session.password_attempts > spawn.settings.PASSWORD_ATTEMPTS:
        raise UniconAuthenticationError('Too many enable password retries')

    enable_credential_password = get_enable_credential_password(context=context)
    if enable_credential_password:
        spawn.sendline(enable_credential_password)
    else:
        spawn.sendline(context['enable_password'])
예제 #11
0
def enable_password_handler(spawn, context, session):
    credentials = context.get('credentials')
    enable_credential = credentials[ENABLE_CRED_NAME] if credentials else None
    if enable_credential:
        try:
            spawn.sendline(to_plaintext(enable_credential['password']))
        except KeyError as exc:
            raise UniconAuthenticationError(
                "No password has been defined "
                "for credential {}.".format(ENABLE_CRED_NAME))

    else:
        spawn.sendline(context['enable_password'])
예제 #12
0
def sudo_password_handler(spawn, context):
    """ Password handler for sudo command
    Need a better place for 'sudo' password, using line_password as workaround
    """
    credentials = context.get('credentials')
    if credentials:
        try:
            spawn.sendline(
                to_plaintext(credentials[SUDO_CRED_NAME]['password']))
        except KeyError as exc:
            raise UniconAuthenticationError("No password has been defined "
                "for credential '{}'.".format(SUDO_CRED_NAME))
    else:
        spawn.sendline(context['line_password'])
예제 #13
0
def common_cred_password_handler(spawn, context, session, credential,
        reuse_current_credential=False):
    """ Send the current credential's password.

    The current credential is then invalidated as long as
    reuse_current_credential is set to `False`.

    Invalidating a credential means that if any subsequent usernames/passwords
    are requested, the next credential in session['cred_iter'] is consumed.
    """
    try:
        spawn.sendline(to_plaintext(
            context['credentials'][credential]['password']))
    except KeyError:
        raise UniconAuthenticationError("No password found "
            "for credential {}.".format(credential))
    if not reuse_current_credential:
        invalidate_current_credential(context=context, session=session)
예제 #14
0
def get_enable_credential_password(context):
    """ Get the enable password from the credentials.

    1. If there is a previous credential (the last credential used to respond to
       a password prompt), use its enable_password member if it exists.
    2. Otherwise, if the user specified a list of credentials, pick the final one in the list and
       use its enable_password member if it exists.
    3. Otherwise, if there is a default credential, use its enable_password member if it exists.
    4. Otherwise, use the well known "enable" credential, password member if it exists.
    5. Otherwise, use the default credential "password" member if it exists.
    6. Otherwise, raise error that no enable password could be found.

    """
    credentials = context.get('credentials')
    enable_credential_password = ""
    login_creds = context.get('login_creds', [])
    fallback_cred = context.get('default_cred_name', "")
    if not login_creds:
        login_creds = [fallback_cred]
    if not isinstance(login_creds, list):
        login_creds = [login_creds]

    # Pick the last item in the login_creds list to select the intended
    # credential even if the device does not ask for a password on login
    # and the given credential is not consumed.
    final_credential = login_creds[-1] if login_creds else ""
    if credentials:
        enable_pw_checks = [
            (context.get('previous_credential', ""), 'enable_password'),
            (final_credential, 'enable_password'),
            (fallback_cred, 'enable_password'),
            (ENABLE_CRED_NAME, 'password'),
            (context.get('default_cred_name', ""), 'password'),
        ]
        for cred_name, key in enable_pw_checks:
            if cred_name:
                candidate_enable_pw = credentials.get(cred_name, {}).get(key)
                if candidate_enable_pw:
                    enable_credential_password = candidate_enable_pw
                    break
        else:
            raise UniconAuthenticationError('{}: Could not find an enable credential.'.
                                            format(context.get('hostname', "")))
    return to_plaintext(enable_credential_password)
예제 #15
0
def password_handler(spawn, context, session):
    """ handles password prompt
    """
    credential = get_current_credential(context=context, session=session)
    if credential:
        common_cred_password_handler(
            spawn=spawn, context=context, credential=credential,
            session=session)
    else:
        if 'password_attempts' not in session:
            session['password_attempts'] = 1
        else:
            session['password_attempts'] += 1
        if session.password_attempts > spawn.settings.PASSWORD_ATTEMPTS:
            raise UniconAuthenticationError('Too many password retries')

        if context['username'] == spawn.last_sent.rstrip() or \
            ssh_tacacs_handler(spawn, context):
            spawn.sendline(context['tacacs_password'])
        else:
            spawn.sendline(context['line_password'])
예제 #16
0
def bad_password_handler(spawn):
    """ handles bad password prompt
    """
    raise UniconAuthenticationError('Bad Password sent to device %s' % (str(spawn),))