def test_authenticate_chap_challenge_required(): client = TACACSClient('127.0.0.1', 49, None, session_id=12345) with pytest.raises(ValueError): client.authenticate('username', 'pass', authen_type=TAC_PLUS_AUTHEN_TYPE_CHAP, chap_ppp_id='X')
def test_authenticate_chap_challenge_length(): client = TACACSClient('127.0.0.1', 49, None, session_id=12345) with pytest.raises(ValueError) as e: client.authenticate('username', 'pass', authen_type=TAC_PLUS_AUTHEN_TYPE_CHAP, chap_ppp_id='A', chap_challenge='X' * 256) assert 'chap_challenge may not be more 255 bytes' in str(e)
def test_authenticate_chap_ppp_id_length(): client = TACACSClient('127.0.0.1', 49, None, session_id=12345) with pytest.raises(ValueError) as e: client.authenticate('username', 'pass', authen_type=TAC_PLUS_AUTHEN_TYPE_CHAP, chap_ppp_id='AA', chap_challenge='challenge') assert 'chap_ppp_id must be a 1-byte string' in str(e)
class CustomController: def pre_init(self): pass def post_init(self): pass def ldap_authentication(self, user, name, password): if not hasattr(self, "ldap_server"): self.ldap_server = Server(getenv("LDAP_ADDR")) user = f"uid={name},dc=example,dc=com" success = Connection(self.ldap_server, user=user, password=password).bind() return {"name": name, "is_admin": True} if success else False def tacacs_authentication(self, user, name, password): if not hasattr(self, "tacacs_client"): self.tacacs_client = TACACSClient(getenv("TACACS_ADDR"), 49, getenv("TACACS_PASSWORD")) success = self.tacacs_client.authenticate(name, password).valid return {"name": name, "is_admin": True} if success else False def parse_configuration_property(self, device, property, value=None): if not value: value = getattr(device, property) if device.operating_system == "eos" and property == "configuration": value = sub(r"(username.*secret) (.*)", "\g<1> ********", value) return value
def login(): if request.method == 'POST': name = str(request.form['name']) password = str(request.form['password']) user = db.session.query(User).filter_by(name=name).first() if user and cisco_type7.verify(password, user.password): flask_login.login_user(user) return redirect(url_for('base_blueprint.dashboard')) else: try: # tacacs_plus does not support py2 unicode, hence the # conversion to string. # TACACSClient cannot be saved directly to session # as it is not serializable: this temporary fixes will create # a new instance of TACACSClient at each TACACS connection # attemp: clearly suboptimal, to be improved later. encrypted_password = cisco_type7.hash(password) tacacs_server = db.session.query(TacacsServer).one() tacacs_client = TACACSClient( str(tacacs_server.ip_address), int(tacacs_server.port), str(cisco_type7.decode(str(tacacs_server.password)))) if tacacs_client.authenticate( name, password, TAC_PLUS_AUTHEN_TYPE_ASCII).valid: user = User(name=name, password=encrypted_password) db.session.add(user) db.session.commit() flask_login.login_user(user) return redirect(url_for('base_blueprint.dashboard')) except NoResultFound: pass return render_template('errors/page_403.html') if not flask_login.current_user.is_authenticated: form = LoginForm(request.form) return render_template('login/login.html', form=form) return redirect(url_for('base_blueprint.dashboard'))
def test_authenticate_ascii(fake_socket, packets): """ client -> AUTHSTART (username) STATUS_GETPASS <- server client -> AUTHCONTINUE (password) STATUS_PASS <- server """ client = TACACSClient('127.0.0.1', 49, None, session_id=12345) client._sock = fake_socket reply = client.authenticate('username', 'pass') assert reply.valid fake_socket.buff.seek(0) first_header = TACACSHeader.unpacked(fake_socket.buff.read(12)) assert (first_header.version_max, first_header.version_min) == (12, 0) first_body = fake_socket.buff.read(first_header.length) assert TACACSAuthenticationStart( 'username', TAC_PLUS_AUTHEN_TYPE_ASCII).packed == first_body second_header = TACACSHeader.unpacked(fake_socket.buff.read(12)) assert (first_header.version_max, first_header.version_min) == (12, 0) assert second_header.seq_no > first_header.seq_no second_body = fake_socket.buff.read() assert TACACSAuthenticationContinue('pass').packed == second_body
def authenticate(self) -> None: try: client = TACACSClient(host=settings.TACACS_SVR, port=49, secret=settings.TACACS_KEY) if not client.authenticate(self.username, self.password).valid: raise errors.unauth_error("Incorrect username or password", "Basic") except ConnectionRefusedError: raise errors.server_error("Unable to connect to TACACS")
class CustomController: def ldap_authentication(self, user, name, password): if not hasattr(self, "ldap_server"): self.ldap_server = Server(environ.get("LDAP_ADDR")) user = f"uid={name},dc=example,dc=com" success = Connection(self.ldap_server, user=user, password=password).bind() return {"name": name, "is_admin": True} if success else False def tacacs_authentication(self, user, name, password): if not hasattr(self, "tacacs_client"): self.tacacs_client = TACACSClient(environ.get("TACACS_ADDR"), 49, environ.get("TACACS_PASSWORD")) success = self.tacacs_client.authenticate(name, password).valid return {"name": name, "is_admin": True} if success else False
def login(): if request.method == 'POST': name = str(request.form['name']) user_password = str(request.form['password']) user = fetch(User, name=name) if user: if app.config['USE_VAULT']: pwd = vault_helper(app, f'user/{user.name}')['password'] else: pwd = user.password if user_password == pwd: login_user(user) return redirect(url_for('base_blueprint.dashboard')) else: try: # tacacs_plus does not support py2 unicode, hence the # conversion to string. # TACACSClient cannot be saved directly to session # as it is not serializable: this temporary fixes will create # a new instance of TACACSClient at each TACACS connection # attemp: clearly suboptimal, to be improved later. tacacs_server = db.session.query(TacacsServer).one() tacacs_client = TACACSClient( str(tacacs_server.ip_address), int(tacacs_server.port), str(tacacs_server.password) ) if tacacs_client.authenticate( name, user_password, TAC_PLUS_AUTHEN_TYPE_ASCII ).valid: user = User(name=name, password=user_password) db.session.add(user) db.session.commit() login_user(user) return redirect(url_for('base_blueprint.dashboard')) except NoResultFound: pass return render_template('errors/page_403.html') if not current_user.is_authenticated: return render_template( 'login.html', login_form=LoginForm(request.form), create_account_form=CreateAccountForm(request.form) ) return redirect(url_for('base_blueprint.dashboard'))
def test_authenticate_pap(fake_socket, packets): """ client -> AUTHSTART (user+pass) STATUS_PASS <- server """ client = TACACSClient('127.0.0.1', 49, None, session_id=12345) client._sock = fake_socket reply = client.authenticate('username', 'pass', authen_type=TAC_PLUS_AUTHEN_TYPE_PAP) assert reply.valid fake_socket.buff.seek(0) first_header = TACACSHeader.unpacked(fake_socket.buff.read(12)) assert (first_header.version_max, first_header.version_min) == (12, 1) first_body = fake_socket.buff.read(first_header.length) assert TACACSAuthenticationStart('username', TAC_PLUS_AUTHEN_TYPE_PAP, data=six.b('pass')).packed == first_body
def login(): if request.method == 'POST': username = str(request.form['username']) password = str(request.form['password']) user = db.session.query(User).filter_by(username=username).first() if user and password == user.password: flask_login.login_user(user) return redirect(url_for('base_blueprint.dashboard')) else: try: # tacacs_plus does not support py2 unicode, hence the # conversion to string. # TACACSClient cannot be saved directly to session # as it is not serializable: this temporary fixes will create # a new instance of TACACSClient at each TACACS connection # attemp: clearly suboptimal, to be improved later. tacacs_client = TACACSClient( str(session['ip_address']), int(session['port']), str(session['password']) ) if tacacs_client.authenticate( username, password, TAC_PLUS_AUTHEN_TYPE_ASCII ).valid: user = User(username=username, password=password) db.session.add(user) db.session.commit() flask_login.login_user(user) return redirect(url_for('base_blueprint.dashboard')) except KeyError: pass return render_template('errors/page_403.html') if not flask_login.current_user.is_authenticated: form = LoginForm(request.form) return render_template('login/login.html', form=form) return redirect(url_for('base_blueprint.dashboard'))
def test_authenticate_chap(fake_socket, packets): """ client -> AUTHSTART user+md5challenge(pass) STATUS_PASS <- server """ client = TACACSClient('127.0.0.1', 49, None, session_id=12345) client._sock = fake_socket reply = client.authenticate('username', 'pass', authen_type=TAC_PLUS_AUTHEN_TYPE_CHAP, chap_ppp_id='A', chap_challenge='challenge') assert reply.valid fake_socket.buff.seek(0) first_header = TACACSHeader.unpacked(fake_socket.buff.read(12)) assert (first_header.version_max, first_header.version_min) == (12, 1) first_body = fake_socket.buff.read(first_header.length) assert TACACSAuthenticationStart( 'username', TAC_PLUS_AUTHEN_TYPE_CHAP, data=(six.b('A') + six.b('challenge') + md5(six.b('Apasschallenge')).digest())).packed == first_body
secret = arg # Check if necessary options are set if(host == "" or username == "" or password == "" or secret == ""): print("Missing mandatory parameters!") print("check_tacacs.py -h <host> -u <username> -p <password> -s <secret>") sys.exit(3) # initialize TACACS try: cli = TACACSClient(host, 49, secret, timeout=10, family=socket.AF_INET) except: print("Error connecting to TACACS server") exit(3) # authenticate user and pass try: authen = cli.authenticate(username, password) except: print("Error trying authentication") exit(3) if(authen.valid): print("OK") exit(0) else: print("Authentication failed") exit(3)
def get_av_pair(arguments, key, default=None): ret = default for av in arguments: avf = av.split("=") if avf[0] == key: ret = avf[1] break return ret cli = TACACSClient('localhost', 49, 'testing123', timeout=10, family=socket.AF_INET) authen = cli.authenticate(token[0], token[1]) if authen.valid == True: auth = cli.authorize(token[0], arguments=["service=tailf"]) groups = get_av_pair(auth.arguments, key="groups") if groups != None: uid = get_av_pair(auth.arguments, key="uid", default=9000) gid = get_av_pair(auth.arguments, key="gid", default=100) home = "/var/confd/homes/{}".format(token[0]) print("accept {} {} {} {}".format(groups, uid, gid, home)) else: print( "reject Cannot retrieve groups AV pair (tailf service) for user {}" .format(token[0])) else: print("reject")