1#!/usr/bin/perl 2# 3# Tests for factor token handling 4# 5# Written by Jon Robertson <jonrober@stanford.edu> 6# Copyright 2013 7# The Board of Trustees of the Leland Stanford Junior University 8# 9# See LICENSE for licensing terms. 10 11use strict; 12use warnings; 13 14use Test::More tests => 15; 15 16# Ensure we don't pick up the system webkdc.conf. 17BEGIN { $ENV{WEBKDC_CONFIG} = '/nonexistent' } 18 19use lib ('t/lib', 'lib', 'blib/arch'); 20use Util qw (contents get_userinfo getcreds create_keyring); 21 22use CGI; 23use CGI::Cookie; 24use Date::Parse; 25use WebAuth qw(3.00 :const); 26use WebKDC (); 27use WebKDC::Config; 28use WebLogin; 29 30# Set our method to not have password tests complain. 31$ENV{REQUEST_METHOD} = 'POST'; 32 33# Override the WebKDC package in order to put in our own version of a function 34# for testing. 35our ($TEST_STATUS, $TEST_ERROR); 36package WebKDC; 37no warnings 'redefine'; 38sub make_request_token_request { 39 return ($TEST_STATUS, $TEST_ERROR); 40} 41use warnings 'redefine'; 42package main; 43 44############################################################################# 45# Wrapper functions 46############################################################################# 47 48# Initialize the weblogin object, as we'll have to keep touching this over 49# and again. 50sub init_weblogin { 51 my $query = CGI->new ({}); 52 $query->request_method ('POST'); 53 54 my $weblogin = WebLogin->new (QUERY => $query); 55 $weblogin->cgiapp_prerun; 56 $weblogin->param ('debug', 0); 57 $weblogin->param ('logging', 0); 58 $weblogin->param ('script_name', '/login'); 59 60 return $weblogin; 61} 62 63############################################################################# 64# Environment setup 65############################################################################# 66 67# Disable all the memcached stuff for now. 68@WebKDC::Config::MEMCACHED_SERVERS = (); 69 70# Expiration to test against, as epoch seconds and text. 71my $expires_epoch = 1577865600; 72my $expires_text = 'Wed, 01-Jan-2020 08:00:00 GMT'; 73 74# For the tests, we want to assume we are remembering device login unless 75# otherwise told.. 76$WebKDC::Config::REMEMBER_FALLBACK = 'yes'; 77 78############################################################################# 79# Tests 80############################################################################# 81 82my ($status, $error); 83 84# Set up the KDC request with a factor cookie and verify it was found. 85my $weblogin = init_weblogin; 86my $cookie = CGI::Cookie->new (-name => 'webauth_wft', -value => 'test'); 87$ENV{HTTP_COOKIE} = "$cookie"; 88my %cart = CGI::Cookie->fetch; 89$status = $weblogin->setup_kdc_request (%cart); 90ok (!$status, 'setup_kdc_request with factor cookie works'); 91ok ($weblogin->{request}->factor_token, '... and factor_token set'); 92is ($weblogin->{request}->factor_token, 'test', '... to the right value'); 93 94# Check again with no factor cookie. 95$weblogin = init_weblogin; 96$status = $weblogin->setup_kdc_request; 97$ENV{HTTP_COOKIE} = ""; 98ok (!$status, 'setup_kdc_request without factor cookie works'); 99is ($weblogin->{request}->factor_token, undef, '... and factor_token not set'); 100 101# Check to see if we set a factor cookie when we should. Requires digging 102# into the CGI::Application object a little. 103$weblogin = init_weblogin; 104$status = $weblogin->setup_kdc_request; 105$weblogin->{response}->cookie ('webauth_wft', 'test', $expires_epoch); 106my %args = (cookies => $weblogin->{response}->cookies); 107$weblogin->print_headers (\%args); 108$cookie = undef; 109for my $c (@{ $weblogin->{'__HEADER_PROPS'}{'-cookie'} }) { 110 if ($c->name eq 'webauth_wft') { 111 $cookie = $c; 112 } 113} 114is ($cookie->name, 'webauth_wft', 'Factor cookie was set'); 115is ($cookie->expires, $expires_text, '... with the correct expiration time'); 116 117# Check clearing the webauth cookie by giving it an empty value. 118$weblogin = init_weblogin; 119$status = $weblogin->setup_kdc_request; 120$weblogin->{response}->cookie ('webauth_wft', '', $expires_epoch); 121%args = (cookies => $weblogin->{response}->cookies); 122$weblogin->print_headers (\%args); 123$cookie = undef; 124for my $c (@{ $weblogin->{'__HEADER_PROPS'}{'-cookie'} }) { 125 if ($c->name eq 'webauth_wft') { 126 $cookie = $c; 127 } 128} 129is ($cookie->name, 'webauth_wft', 'Factor cookie was set'); 130my $expires = str2time ($cookie->expires); 131is ($expires, time - 60 * 60 * 24, '... with the correct expiration time'); 132 133# Check clearing the webauth cookie by setting the remember_login checkbox. 134$weblogin = init_weblogin; 135$weblogin->query->request_method ('GET'); 136$status = $weblogin->setup_kdc_request; 137$weblogin->query->param (remember_login => 'no'); 138$weblogin->{response}->cookie ('webauth_wft', 'test', $expires_epoch); 139%args = ( 140 cookies => $weblogin->{response}->cookies, 141 confirm_page => 1, 142); 143$weblogin->print_headers (\%args); 144$cookie = undef; 145for my $c (@{ $weblogin->{'__HEADER_PROPS'}{'-cookie'} }) { 146 if ($c->name eq 'webauth_wft') { 147 $cookie = $c; 148 } 149} 150is ($cookie->name, 'webauth_wft', 'Factor cookie on public computer was set'); 151$expires = str2time ($cookie->expires); 152is ($expires, time - 60 * 60 * 24, '... and set to expire now'); 153 154# Check that the webkdc-factor token is left unmodified when no cookies are 155# returned. 156$weblogin = init_weblogin; 157$status = $weblogin->setup_kdc_request; 158%args = (cookies => $weblogin->{response}->cookies); 159$weblogin->{request}->factor_token ('foo'); 160$weblogin->print_headers (\%args); 161$cookie = undef; 162for my $c (@{ $weblogin->{'__HEADER_PROPS'}{'-cookie'} }) { 163 if ($c->name eq 'webauth_wft') { 164 $cookie = $c; 165 } 166} 167is ($cookie, undef, 'Factor token is left alone if no cookies are returned'); 168 169# Check clearing the webauth cookie by not explicitly passing it. 170$weblogin = init_weblogin; 171$status = $weblogin->setup_kdc_request; 172%args = (cookies => $weblogin->{response}->cookies); 173$weblogin->{request}->factor_token ('foo'); 174$weblogin->{response}->cookie ('webauth_wpt_krb5', 'test', $expires_epoch); 175$weblogin->print_headers (\%args); 176$cookie = undef; 177for my $c (@{ $weblogin->{'__HEADER_PROPS'}{'-cookie'} }) { 178 if ($c->name eq 'webauth_wft') { 179 $cookie = $c; 180 } 181} 182is ($cookie->name, 'webauth_wft', 183 'Factor cookie expired when not explicitly passed'); 184$expires = str2time ($cookie->expires); 185is ($expires, time - 60 * 60 * 24, '... and set to expire now'); 186 187# Check clearing the webauth cookie by not explicitly passing it when there 188# was no token from the client.. 189$weblogin = init_weblogin; 190$status = $weblogin->setup_kdc_request; 191%args = (cookies => $weblogin->{response}->cookies); 192$weblogin->print_headers (\%args); 193$cookie = undef; 194for my $c (@{ $weblogin->{'__HEADER_PROPS'}{'-cookie'} }) { 195 if ($c->name eq 'webauth_wft') { 196 $cookie = $c; 197 } 198} 199is ($cookie, undef, 'Factor cookie not expired when not explicitly passed ' 200 .'and none existed before'); 201