def test_verify_response(self): invalid_user = duo_web.verify_response(SKEY, INVALID_RESPONSE) self.assertEqual(invalid_user, None) expired_user = duo_web.verify_response(SKEY, EXPIRED_RESPONSE) self.assertEqual(expired_user, None) future_user = duo_web.verify_response(SKEY, FUTURE_RESPONSE) self.assertEqual(future_user, USER)
def do_POST(self): try: sig_response = self.require_post('sig_response') except ValueError: self.error('sig_response post parameter is required') return user = duo_web.verify_response( self.server.ikey, self.server.skey, self.server.akey, sig_response) self.send_response(200) self.end_headers() if user is None: # See if it was a response to an ENROLL_REQUEST user = duo_web.verify_enroll_response( self.server.ikey, self.server.skey, self.server.akey, sig_response) if user is None: self.wfile.write( ('Did not authenticate with Duo.'.encode('utf-8'))) else: self.wfile.write( ('Enrolled with Duo as %s.' % user).encode('utf-8')) else: self.wfile.write( ('Authenticated with Duo as %s.' % user).encode('utf-8'))
def duo_auth(request): if is_duo_authenticated(request): return redirect("index") sig_request = None duo_settings = CONFIG.get("DUO_SETTINGS", {}) if request.POST: sig_response = request.POST.get("sig_response", None) if sig_response: authenticated_username = duo_web.verify_response( duo_settings.get("IKEY"), duo_settings.get("SKEY"), duo_settings.get("AKEY"), sig_response, ) if authenticated_username: duo_authenticate(request) return redirect(request.GET.get("next", "admin:index")) sig_request = duo_web.sign_request( duo_settings.get("IKEY"), duo_settings.get("SKEY"), duo_settings.get("AKEY"), request.user.username, ) context = { "sig_request": sig_request, "host": duo_settings.get("HOST"), "post_action": f"{reverse('duo_auth')}?next={request.GET.get('next')}", } return render(request, "registration/duo.html", context)
def do_admin_login(): if request.form['sig_response'] == 'none' : session['logged_in'] = False POST_USERNAME = str(request.form['username']) POST_PASSWORD = str(request.form['password']) Session = sessionmaker(bind=engine) s = Session() query = s.query(User).filter(User.username.in_([POST_USERNAME]), User.password.in_([POST_PASSWORD]) ) result = query.first() if result: session['logged_in'] = True session['user'] = POST_USERNAME sig_request = duo_web.sign_request(ikey, skey, akey,session['user']) return render_template('duo_mfa.html',host=host,sig_request=sig_request) else: session['logged_in'] = False flash('wrong password!') else: sig_response=request.form['sig_response'] authenticated_username = duo_web.verify_response(ikey, skey, akey, sig_response) if authenticated_username: session['logged_in'] = True session['user']=authenticated_username return home() return home()
def authenticate(self, configurationAttributes, requestParameters, step): duo_host = configurationAttributes.get("duo_host").getValue2() credentials = Identity.instance().getCredentials() user_name = credentials.getUsername() if (step == 1): print "Duo. Authenticate for step 1" user_password = credentials.getPassword() logged_in = False if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)): userService = UserService.instance() logged_in = userService.authenticate(user_name, user_password) if (not logged_in): return False authenticationService = AuthenticationService.instance() user = authenticationService.getAuthenticatedUser() if (self.use_duo_group): print "Duo. Authenticate for step 1. Checking if user belong to Duo group" is_member_duo_group = self.isUserMemberOfGroup(user, self.audit_attribute, self.duo_group) if (is_member_duo_group): print "Duo. Authenticate for step 1. User '" + user.getUserId() + "' member of Duo group" duo_count_login_steps = 2 else: self.processAuditGroup(user) duo_count_login_steps = 1 context = Contexts.getEventContext() context.set("duo_count_login_steps", duo_count_login_steps) return True elif (step == 2): print "Duo. Authenticate for step 2" sig_response_array = requestParameters.get("sig_response") if ArrayHelper.isEmpty(sig_response_array): print "Duo. Authenticate for step 2. sig_response is empty" return False duo_sig_response = sig_response_array[0] print "Duo. Authenticate for step 2. duo_sig_response: " + duo_sig_response authenticated_username = duo_web.verify_response(self.ikey, self.skey, self.akey, duo_sig_response) print "Duo. Authenticate for step 2. authenticated_username: "******", expected user_name: " + user_name if (not StringHelper.equals(user_name, authenticated_username)): return False authenticationService = AuthenticationService.instance() user = authenticationService.getAuthenticatedUser() self.processAuditGroup(user) return True else: return False
def post(self): """ If we have a sig_response argument containig a Duo auth cookie indicating that the current user has logged in to both Google and Duo with matching usernames, write a login cookie and redirect to /. Otherwise, indicate failure. """ user = users.get_current_user() if not user: self.redirect('/') return sig_response = self.request.get('sig_response', '') duo_user = duo_web.verify_response(ikey, skey, akey, sig_response) if duo_user is None: self.write('Did not authenticate.') return # Note that since the secure cookie is never unset, Duo auth is not # required again until it expires, even if Google auth is required. # We can provide redirects on the logout URLs which we present to # unset the cookie, but the user could find and use a Google logout URL # without these. self.set_secure_cookie('logged_in', duo_user) self.redirect('/')
def post(self): """ If we have a sig_response argument containig a Duo auth cookie indicating that the current user has logged in to both Google and Duo with matching usernames, write a login cookie and redirect to /. Otherwise, indicate failure. """ user = users.get_current_user() if not user: self.redirect("/") return sig_response = self.request.get("sig_response", "") duo_user = duo_web.verify_response(ikey, skey, akey, sig_response) if duo_user is None: self.write("Did not authenticate.") return # Note that since the secure cookie is never unset, Duo auth is not # required again until it expires, even if Google auth is required. # We can provide redirects on the logout URLs which we present to # unset the cookie, but the user could find and use a Google logout URL # without these. self.set_secure_cookie("logged_in", duo_user) self.redirect("/")
def duo_auth(request): if is_duo_authenticated(request): return redirect("index") sig_request = None duo_settings = CONFIG.get("DUO_SETTINGS", {}) if request.POST: sig_response = request.POST.get("sig_response", None) if sig_response: authenticated_username = duo_web.verify_response( duo_settings.get("IKEY"), duo_settings.get("SKEY"), duo_settings.get("AKEY"), sig_response, ) if authenticated_username: duo_authenticate(request) return redirect("admin:index") sig_request = duo_web.sign_request( duo_settings.get("IKEY"), duo_settings.get("SKEY"), duo_settings.get("AKEY"), request.user.username, ) context = { "sig_request": sig_request, "host": duo_settings.get("HOST"), "post_action": reverse("duo_auth"), } return render(request, "registration/duo.html", context)
def authenticate(self, handler, data): """Do secondary authentication with Duo, and return the username if successful. Return None otherwise. """ self.log.debug("DUO-DATA: %s", repr(data)[:100]) auth = json.loads( base64.binascii.a2b_base64( data['auth_cache'].encode('ascii')).decode('ascii')) from pprint import pformat self.log.debug(pformat(auth)) sig_response = data['sig_response'] authenticated_username = \ duo_web.verify_response( self.ikey, self.skey, self.akey, sig_response) if authenticated_username == auth.get('name'): self.log.debug("Duo Authentication succeeded for user '%s'", \ auth.get('name')) # XXX: F**K Duo.... This required black-magic and blood-sacrifice to work # -- Michael B. self.log.debug(".... %s:", repr(auth)[:100]) return auth else: self.log.warning("Duo Authentication failed for user '%s'", username) return None
def do_POST(self): try: sig_response = self.require_post('sig_response') except ValueError: self.error('sig_response post parameter is required') return user = duo_web.verify_response(self.server.ikey, self.server.skey, self.server.akey, sig_response) self.send_response(200) self.end_headers() if user is None: # See if it was a response to an ENROLL_REQUEST user = duo_web.verify_enroll_response(self.server.ikey, self.server.skey, self.server.akey, sig_response) if user is None: self.wfile.write( ('Did not authenticate with Duo.'.encode('utf-8'))) else: self.wfile.write( ('Enrolled with Duo as %s.' % user).encode('utf-8')) else: self.wfile.write( ('Authenticated with Duo as %s.' % user).encode('utf-8'))
def duo_validate(): sig_response = request.form["sig_response"] ikey = config.DUO_IKEY skey = config.DUO_SKEY akey = config.SECRET username = duo_web.verify_response(ikey, skey, akey, sig_response) session["username"] = username return redirect(url_for("index"))
def test_verify_response(self): request_sig = duo_web.sign_request(IKEY, SKEY, AKEY, USER) duo_sig, valid_app_sig = request_sig.split(':') request_sig = duo_web.sign_request(IKEY, SKEY, 'invalid' * 6, USER) duo_sig, invalid_app_sig = request_sig.split(':') invalid_user = duo_web.verify_response( IKEY, SKEY, AKEY, INVALID_RESPONSE + ':' + valid_app_sig) self.assertEqual(invalid_user, None) expired_user = duo_web.verify_response( IKEY, SKEY, AKEY, EXPIRED_RESPONSE + ':' + valid_app_sig) self.assertEqual(expired_user, None) future_user = duo_web.verify_response( IKEY, SKEY, AKEY, FUTURE_RESPONSE + ':' + invalid_app_sig) self.assertEqual(future_user, None) future_user = duo_web.verify_response( IKEY, SKEY, AKEY, FUTURE_RESPONSE + ':' + valid_app_sig) self.assertEqual(future_user, USER) future_user = duo_web.verify_response( IKEY, SKEY, AKEY, WRONG_PARAMS_RESPONSE + ':' + valid_app_sig) self.assertEqual(future_user, None) future_user = duo_web.verify_response( IKEY, SKEY, AKEY, FUTURE_RESPONSE + ':' + WRONG_PARAMS_APP) self.assertEqual(future_user, None) future_user = duo_web.verify_response( WRONG_IKEY, SKEY, AKEY, FUTURE_RESPONSE + ':' + valid_app_sig) self.assertEqual(future_user, None)
def test_verify_response(self): request_sig = duo_web.sign_request(IKEY, SKEY, AKEY, USER) duo_sig, valid_app_sig = request_sig.split(':') request_sig = duo_web.sign_request(IKEY, SKEY, 'invalid' * 6, USER) duo_sig, invalid_app_sig = request_sig.split(':') invalid_user = duo_web.verify_response(IKEY, SKEY, AKEY, INVALID_RESPONSE + ':' + valid_app_sig) self.assertEqual(invalid_user, None) expired_user = duo_web.verify_response(IKEY, SKEY, AKEY, EXPIRED_RESPONSE + ':' + valid_app_sig) self.assertEqual(expired_user, None) future_user = duo_web.verify_response(IKEY, SKEY, AKEY, FUTURE_RESPONSE + ':' + invalid_app_sig) self.assertEqual(future_user, None) future_user = duo_web.verify_response(IKEY, SKEY, AKEY, FUTURE_RESPONSE + ':' + valid_app_sig) self.assertEqual(future_user, USER) future_user = duo_web.verify_response(IKEY, SKEY, AKEY, WRONG_PARAMS_RESPONSE + ':' + valid_app_sig) self.assertEqual(future_user, None) future_user = duo_web.verify_response(IKEY, SKEY, AKEY, FUTURE_RESPONSE + ':' + WRONG_PARAMS_APP) self.assertEqual(future_user, None) future_user = duo_web.verify_response(WRONG_IKEY, SKEY, AKEY, FUTURE_RESPONSE + ':' + valid_app_sig) self.assertEqual(future_user, None)
def mfa(): result = grab_keys() sec = duo.sign_request(result['ikey'], result['skey'], result['akey'], "admin") if request.method == 'GET': return render_template('duoframe.html', duohost=result['host'], sig_request=sec) if request.method == 'POST': user = duo.verify_response(result['ikey'], result['skey'], result['akey'], request.args.get('sig_response')) if user: return render_template(url_for('mfa'), user=user)
def home_route(): if request.method == "POST": c.execute("INSERT INTO registered (registered) values(1)") session["username"] = username sig_response = request.args.get("sig_response") authenticated_username = verify_response(ikey, skey, akey, sig_response) if authenticated_username: log_user_in(authenticated_username) return render_template("index.html")
def do_POST(self): try: sig_response = self.require_post("sig_response") except ValueError: self.error("sig_response post parameter is required") return user = duo_web.verify_response(skey, sig_response) if user is None: self.wfile.write("Did not authenticate with Duo.") elif self.get_secure_cookie("user") != user: self.wfile.write("Duo user does not match local user.") else: self.wfile.write("Authenticated with Duo as %s." % user)
def do_POST(self): try: sig_response = self.require_post('sig_response') except ValueError: self.error('sig_response post parameter is required') return user = duo_web.verify_response(skey, sig_response) if user is None: self.wfile.write('Did not authenticate with Duo.') elif self.get_secure_cookie('user') != user: self.wfile.write('Duo user does not match local user.') else: self.wfile.write('Authenticated with Duo as %s.' % user)
def login(request): """ View to authenticate the user locally and with Duo, redirecting to the next argument if given. For a GET, show the Duo form, which posts back with the Duo token. For a POST with successful authorization, redirect to the next argument, or show some default content. Without successful authorization, redirect back here to try again. """ if request.method == 'GET': message = request.GET.get( 'message', 'Secondary authorization required.') next_page = request.GET.get('next') sig_request = duo_web.sign_request( settings.DUO_IKEY, settings.DUO_SKEY, settings.DUO_AKEY, duo_username(request.user)) print duo_username(request.user) context = { 'message': message, 'next': next_page, 'duo_css_src': '/'.join([settings.STATIC_URL, 'Duo-Frame.css']), 'duo_js_src': '/'.join([settings.STATIC_URL, 'Duo-Web-v2.js']), 'duo_host': settings.DUO_HOST, 'post_action': request.path, 'sig_request': sig_request } return render(request, 'duo_login.html', context) elif request.method == 'POST': return HttpResponse('failed') sig_response = request.POST.get('sig_response', '') duo_user = duo_web.verify_response( settings.DUO_IKEY, settings.DUO_SKEY, settings.DUO_AKEY, sig_response) next_page = request.POST.get('next') if duo_user is None: # Redirect user to try again, keeping the next argument. # Note that we don't keep any other arguments. arg_map = {'message': 'Duo access denied.'} if next_page: arg_map['next'] = next_page redirect_url = '%s?%s' % ( request.path, urlencode(arg_map)) return HttpResponseRedirect(redirect_url) else: duo_authenticate(request) if not next_page: next_page = settings.LOGIN_REDIRECT_URL return HttpResponse('ok') return HttpResponseRedirect(next_page)
def mfa(): result = grab_keys() sec = duo.sign_request(result['ikey'], result['skey'], result['akey'], session['user']) if request.method == 'GET': return render_template('duoframe.html', duohost=result['host'], sig_request=sec) if request.method == 'POST': user = duo.verify_response(result['ikey'], result['skey'], result['akey'], request.args.get('sig_response')) if user == session['user']: return render_template(url_for('mfa'), user=user)
def login(request): """ View to authenticate the user locally and with Duo, redirecting to the next argument if given. For a GET, show the Duo form, which posts back with the Duo token. For a POST with successful authorization, redirect to the next argument, or show some default content. Without successful authorization, redirect back here to try again. """ if request.method == 'GET': message = request.GET.get( 'message', 'Secondary authorization required.') next_page = request.GET.get('next') sig_request = duo_web.sign_request( settings.DUO_IKEY, settings.DUO_SKEY, settings.DUO_AKEY, duo_username(request.user)) template = loader.get_template('duo_login.html') context = RequestContext( request, {'message': message, 'next': next_page, 'duo_css_src': '/'.join([settings.STATIC_URL, 'Duo-Frame.css']), 'duo_js_src': '/'.join([settings.STATIC_URL, 'Duo-Web-v2.js']), 'duo_host': settings.DUO_HOST, 'post_action': request.path, 'sig_request': sig_request}) return HttpResponse(template.render(context)) elif request.method == 'POST': sig_response = request.POST.get('sig_response', '') duo_user = duo_web.verify_response( settings.DUO_IKEY, settings.DUO_SKEY, settings.DUO_AKEY, sig_response) next_page = request.POST.get('next') if duo_user is None: # Redirect user to try again, keeping the next argument. # Note that we don't keep any other arguments. arg_map = {'message': 'Duo access denied.'} if next_page: arg_map['next'] = next_page redirect_url = '%s?%s' % ( request.path, urllib.urlencode(arg_map)) return HttpResponseRedirect(redirect_url) else: duo_authenticate(request) if not next_page: next_page = settings.LOGIN_REDIRECT_URL return HttpResponseRedirect(next_page)
async def authenticate(self, handler, data): """Do secondary authentication with Duo, and return the username if successful. Return None otherwise. """ sig_response = data['sig_response'] authenticated_username = duo_web.verify_response(self.ikey,\ self.skey, self.akey, sig_response) if authenticated_username: self.log.debug("Duo Authentication succeeded for user '%s'", \ authenticated_username) return authenticated_username else: self.log.warning("Duo Authentication failed for user '%s'", username) return None
def post(self): duo_user = duo_web.verify_response( ikey, skey, akey, self.request.get('sig_response', '')) if duo_user is None: self.report_error('Improper Duo authentication for user.') return arg_map = self.arg_map(self.request) # post_args from odrequst.message all start with openid. post_args = dict([(key, val) for (key, val) in arg_map.items() if key.startswith('openid.')]) self.render_template( 'prompt', { 'trust_root': arg_map['trust_root'], 'user': users.get_current_user(), 'action': '/login', 'postargs': post_args })
def post(self): duo_user = duo_web.verify_response( ikey, skey, akey, self.request.get('sig_response', '')) if duo_user is None: self.report_error('Improper Duo authentication for user.') return arg_map = self.arg_map(self.request) # post_args from odrequst.message all start with openid. post_args = dict([ (key, val) for (key, val) in arg_map.items() if key.startswith('openid.')]) self.render_template( 'prompt', {'trust_root':arg_map['trust_root'], 'user':users.get_current_user(), 'action':'/login', 'postargs':post_args})
def login(): result = get_duo() print('DUO: {}'.format(result)) print(session['user']) sig_request = duo_web.sign_request(result['ikey'], result['skey'], result['akey'], session['user']) print('sig_request: {}'.format(sig_request)) if request.method == 'GET': return render_template('duoframe.html', duohost=result['host'], sig_request=sig_request) elif request.method == 'POST': user = duo_web.verify_response(result['ikey'], result['skey'], result['akey'], request.args.get('sig_response')) print('AUTH: {}'.format(user)) if user == session['user']: return render_template(url_for('duo_auth.login'), user=user)
def post(self, request): sig_response = request.POST.get('sig_response', '') app_name = request.POST.get('app_name', 'DEFAULT') next_url = request.POST.get('next', settings.LOGIN_REDIRECT_URL) username = self.get_username(settings.DUO_CONFIG[app_name], request) duo_user = duo_web.verify_response( settings.DUO_CONFIG[app_name]["IKEY"], settings.DUO_CONFIG[app_name]["SKEY"], settings.DUO_CONFIG[app_name]["AKEY"], sig_response) if duo_user is None or duo_user != username: logger.info('Duo returned {0} instead of {1}'.format( duo_user, username)) logout(request) else: logger.info('User {0} authenticated using duo'.format(duo_user)) request.session['DUO_STATUS'] = 'COMPLETED' return redirect(next_url)
def duo_callback(): if request.method == "POST": sig_response = request.form.get("sig_response") authenticated_username = duo_web.verify_response( config('DUO_I_KEY'), config('DUO_S_KEY'), config('DUO_A_KEY'), sig_response) if authenticated_username: user_values = user_db.query_user(authenticated_username) if user_values: current_user = User(user_values['email'], user_values['password'], user_values['first_name'], user_values['last_name'], user_values['role']) login_user(current_user, remember=True) flash("Logged in successfully!", category="success") return (redirect(url_for("views.home"))) else: flash( "User value was not equal to what is stored in the database" ) else: flash("Duo login was not successful") return render_template("login.html")
def authenticate(self, configurationAttributes, requestParameters, step): duo_host = configurationAttributes.get("duo_host").getValue2() authenticationService = CdiUtil.bean(AuthenticationService) identity = CdiUtil.bean(Identity) if (step == 1): print "Duo. Authenticate for step 1" # Check if user authenticated already in another custom script user = authenticationService.getAuthenticatedUser() if user == None: credentials = identity.getCredentials() user_name = credentials.getUsername() user_password = credentials.getPassword() logged_in = False if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)): userService = CdiUtil.bean(UserService) logged_in = authenticationService.authenticate(user_name, user_password) if (not logged_in): return False user = authenticationService.getAuthenticatedUser() if (self.use_duo_group): print "Duo. Authenticate for step 1. Checking if user belong to Duo group" is_member_duo_group = self.isUserMemberOfGroup(user, self.audit_attribute, self.duo_group) if (is_member_duo_group): print "Duo. Authenticate for step 1. User '" + user.getUserId() + "' member of Duo group" duo_count_login_steps = 2 else: self.processAuditGroup(user) duo_count_login_steps = 1 identity.setWorkingParameter("duo_count_login_steps", duo_count_login_steps) return True elif (step == 2): print "Duo. Authenticate for step 2" user = authenticationService.getAuthenticatedUser() if user == None: print "Duo. Authenticate for step 2. Failed to determine user name" return False user_name = user.getUserId() sig_response_array = requestParameters.get("sig_response") if ArrayHelper.isEmpty(sig_response_array): print "Duo. Authenticate for step 2. sig_response is empty" return False duo_sig_response = sig_response_array[0] print "Duo. Authenticate for step 2. duo_sig_response: " + duo_sig_response authenticated_username = duo_web.verify_response(self.ikey, self.skey, self.akey, duo_sig_response) print "Duo. Authenticate for step 2. authenticated_username: "******", expected user_name: " + user_name if (not StringHelper.equals(user_name, authenticated_username)): return False self.processAuditGroup(user) return True else: return False
def authenticate(self, configurationAttributes, requestParameters, step): duo_host = configurationAttributes.get("duo_host").getValue2() authenticationService = CdiUtil.bean(AuthenticationService) identity = CdiUtil.bean(Identity) if (step == 1): print "Duo. Authenticate for step 1" # Check if user authenticated alreadyin another custom script user = authenticationService.getAuthenticatedUser() if user == None: credentials = identity.getCredentials() user_name = credentials.getUsername() user_password = credentials.getPassword() logged_in = False if (StringHelper.isNotEmptyString(user_name) and StringHelper.isNotEmptyString(user_password)): userService = CdiUtil.bean(UserService) logged_in = authenticationService.authenticate(user_name, user_password) if (not logged_in): return False user = authenticationService.getAuthenticatedUser() if (self.use_duo_group): print "Duo. Authenticate for step 1. Checking if user belong to Duo group" is_member_duo_group = self.isUserMemberOfGroup(user, self.audit_attribute, self.duo_group) if (is_member_duo_group): print "Duo. Authenticate for step 1. User '" + user.getUserId() + "' member of Duo group" duo_count_login_steps = 2 else: self.processAuditGroup(user) duo_count_login_steps = 1 identity.setWorkingParameter("duo_count_login_steps", duo_count_login_steps) return True elif (step == 2): print "Duo. Authenticate for step 2" user = authenticationService.getAuthenticatedUser() if user == None: print "Duo. Authenticate for step 2. Failed to determine user name" return False user_name = user.getUserId() sig_response_array = requestParameters.get("sig_response") if ArrayHelper.isEmpty(sig_response_array): print "Duo. Authenticate for step 2. sig_response is empty" return False duo_sig_response = sig_response_array[0] print "Duo. Authenticate for step 2. duo_sig_response: " + duo_sig_response authenticated_username = duo_web.verify_response(self.ikey, self.skey, self.akey, duo_sig_response) print "Duo. Authenticate for step 2. authenticated_username: "******", expected user_name: " + user_name if (not StringHelper.equals(user_name, authenticated_username)): return False self.processAuditGroup(user) return True else: return False