X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=cgi-auth-flexible.git;a=blobdiff_plain;f=cgi-auth-flexible.pm;h=940e5dc2223fcbcb47042c84aa02afa22644d66c;hp=eea4bc0946eda50a607fca4a278c70f0f7feb6e9;hb=28a91929befb605f10c4136b426ffcc09950ebf9;hpb=2cc2bcd02ba39b7112ee5428f39bdac95e6fd1f3 diff --git a/cgi-auth-flexible.pm b/cgi-auth-flexible.pm index eea4bc0..940e5dc 100644 --- a/cgi-auth-flexible.pm +++ b/cgi-auth-flexible.pm @@ -32,7 +32,7 @@ BEGIN { @EXPORT = qw(); %EXPORT_TAGS = ( ); # eg: TAG => [ qw!name1 name2! ], - @EXPORT_OK = qw(); + @EXPORT_OK = qw(@default_db_setup_stmts); } our @EXPORT_OK; @@ -77,10 +77,11 @@ sub has_a_param ($$) { sub get_params ($) { my ($r) = @_; - my %p; my $c = $r->{Cgi}; - foreach my $name ($c->param()) { - $p{$name} = [ $c->param($name) ]; + my $vars = $c->Vars(); + my %p; + foreach my $name (keys %$vars) { + $p{$name} = [ split "\0", $vars->{$name} ]; } return \%p; } @@ -201,6 +202,18 @@ sub gen_plain_footer_html ($$) { ''); } +our @default_db_setup_stmts = + ("CREATE TABLE $v->{S}{assocdb_table} (". + " assochash VARCHAR PRIMARY KEY,". + " username VARCHAR NOT NULL,". + " last INTEGER NOT NULL". + ")" + , + "CREATE INDEX $v->{S}{assocdb_table}_timeout_index". + " ON $v->{S}{assocdb_table}". + " (last)" + ); + #---------- licence and source code ---------- sub srcdump_dump ($$$) { @@ -281,8 +294,9 @@ sub srcdump_novcs ($$$$$) { sub srcdump_byvcs ($$$$$$) { my ($c, $v, $dumpdir, $dir, $outfn, $vcs) = @_; #print STDERR "BYVCS GIT $dir\n"; - return srcdump_dir_cpio($c,$v,$dumpdir,$dir,$outfn,$vcs, - $v->{S}{"srcdump_vcsscript_$vcs"}); + my $script = $v->{S}{"srcdump_vcsscript"}{$vcs}; + die "no script for vcs $vcs" unless defined $script; + return srcdump_dir_cpio($c,$v,$dumpdir,$dir,$outfn,$vcs,$script); } sub srcdump_file ($$$$) { @@ -425,6 +439,7 @@ sub new_verifier { assocdb_user => '', assocdb_password => '', assocdb_table => 'caf_assocs', + assocdb_setup_stmts => [@_default_db_setup_statements], random_source => '/dev/urandom', secretbits => 128, # bits hash_algorithm => "SHA-256", @@ -446,14 +461,13 @@ sub new_verifier { get_path_info => sub { $_[0]->path_info() }, get_cookie => sub { $_[0]->cookie($_[1]->{S}{cookie_name}) }, get_method => sub { $_[0]->request_method() }, - check_https => sub { !!$_[0]->https() }, + is_https => sub { !!$_[0]->https() }, get_url => sub { $_[0]->url(); }, is_login => sub { defined $_[1]->_rp('password_param_name') }, login_ok => \&login_ok_password, username_password_error => sub { die }, is_logout => sub { $_[1]->has_a_param('logout_param_names') }, is_loggedout => sub { $_[1]->has_a_param('loggedout_param_names') }, - is_page => sub { return 1 }, handle_divert => sub { return 0 }, do_redirect => \&do_redirect_cgi, # this hook is allowed to throw cookie_path => "/", @@ -477,16 +491,12 @@ sub new_verifier { $_[2] =~ m#^/etc/|^/usr/(?!local/)(?!lib/cgi)#; }, srcdump_process_item => \&srcdump_process_item, - srcdump_vcs_dirs => [qw(.git .hg .bzr .svn CVS)], - srcdump_vcsscript_git => " + srcdump_vcs_dirs => [qw(.git .hg .bzr .svn)], + srcdump_vcsscript => [git => " git ls-files -z git ls-files -z --others --exclude-from=.gitignore find .git -print0 - ", - srcdump_vcsscript_hg => "false hg", - srcdump_vcsscript_bzr => "false bzr", - srcdump_vcsscript_svn => "false svn", - srcdump_vcsscript_cvs => "false cvs", + "], srcdump_byvcs => \&srcdump_byvcs, srcdump_novcs => \&srcdump_novcs, srcdump_excludes => [qw(*~ *.bak *.tmp), '#*#'], @@ -546,14 +556,9 @@ sub _dbopen ($) { } $v->{Dbh} = $dbh; - $v->_db_setup_do("CREATE TABLE $v->{S}{assocdb_table} (". - " assochash VARCHAR PRIMARY KEY,". - " username VARCHAR NOT NULL,". - " last INTEGER NOT NULL". - ")"); - $v->_db_setup_do("CREATE INDEX $v->{S}{assocdb_table}_timeout_index". - " ON $v->{S}{assocdb_table}". - " (last)"); + foreach my $stmt (@default_db_setup_stmts) { + $v->_db_setup_do($stmt); + } return $dbh; } @@ -789,7 +794,7 @@ sub _check_divert_core ($) { my $cooks = $r->_ch('get_cookie'); - if ($r->{S}{encrypted_only} && !$r->_ch('check_https')) { + if ($r->{S}{encrypted_only} && !$r->_ch('is_https')) { return ({ Kind => 'REDIRECT-HTTPS', Message => $r->_gt("Redirecting to secure server..."), CookieSecret => undef, @@ -835,7 +840,7 @@ sub _check_divert_core ($) { " enabled. You must enable cookies". " as we use them for login."), CookieSecret => $r->_fresh_secret(), - Params => $r->chain_params() }) + Params => $r->_chain_params() }) } if (!$cookt || $cookt eq 'n' || $cookh ne $parmh) { $r->_db_revoke($cookh); @@ -853,13 +858,13 @@ sub _check_divert_core ($) { return ({ Kind => 'LOGIN-BAD', Message => $login_errormessage, CookieSecret => $cooks, - Params => $r->chain_params() }) + Params => $r->_chain_params() }) } $r->_db_record_login_ok($parmh,$username); return ({ Kind => 'REDIRECT-LOGGEDIN', Message => $r->_gt("Logging in..."), CookieSecret => $cooks, - Params => $r->chain_params() }); + Params => $r->_chain_params() }); } if ($cookt eq 't') { $cookt = ''; @@ -879,7 +884,7 @@ sub _check_divert_core ($) { return ({ Kind => 'LOGIN-INCOMINGLINK', Message => $r->_gt("You need to log in."), CookieSecret => $news, - Params => $r->chain_params() }); + Params => $r->_chain_params() }); } else { $r->_db_revoke($parmh); return ({ Kind => 'LOGIN-FRESH', @@ -913,7 +918,14 @@ sub _check_divert_core ($) { return undef; } -sub chain_params ($) { +sub _chain_params ($) { +# =item C<< $authreq->_chain_params() >> +# +# Returns a hash of the "relevant" parameters to this request, in a form +# used by C. This is all of the query parameters +# which are not related to CGI::Auth::Flexible. The PATH_INFO from the +# request is returned as the parameter C<< '' >>. + my ($r) = @_; my %p = %{ $r->_ch('get_params') }; foreach my $pncn (keys %{ $r->{S} }) { @@ -1042,8 +1054,7 @@ sub url_with_query_params ($$;$) { my $uri = URI->new($r->_ch('get_url')); $uri->path($uri->path() . $params->{''}[0]) if $params->{''}; my @flatparams = flatten_params($params); - if (defined $nonpagetype - && $r->nonpage_get_needs_secret_hidden($nonpagetype)) { + if (defined $nonpagetype && $r->need_add_hidden('GET',$nonpagetype)) { push @flatparams, $r->{S}{assoc_param_name}, $r->secret_hidden_val(); } $uri->query_form(@flatparams); @@ -1078,7 +1089,7 @@ sub check_ok ($) { } if ($kind =~ m/^REDIRECT-/) { - # for redirects, we honour stored NextParams and SetCookie, + # for redirects, we honour stored Params and Cookie, # as we would for non-divert if ($kind eq 'REDIRECT-LOGGEDOUT') { $params->{$r->{S}{loggedout_param_names}[0]} = [ 1 ]; @@ -1286,30 +1297,39 @@ sub check_mutate ($) { $r->_must_be_post(); } -sub mutate_ok ($) { - my ($r) = @_; - $r->_assert_checked(); - die if $r->{Divert}; - return $r->_is_post(); -} - our %_resource_get_needs_secret_hidden = - (map { $_ => 0 } qw(PAGE FRAME IFRAME SRCDUMP STYLESHEET FAVICON), + (map { $_ => 0 } qw(PAGE FRAME IFRAME SRCDUMP STYLESHEET FAVICON ROBOTS), map { $_ => 1 } qw(IMAGE SCRIPT AJAX-XML AJAX-JSON AJAX-OTHER)); -sub resource_get_needs_secret_hidden ($) { - my ($r, $nonpagetype) = @_; - my $ent = $_resource_get_needs_secret_hidden{$nonpagetype}; - die "unsupported nonpage GET type $nonpagetype" unless defined $ent; - return $ent; +sub update_get_need_add_hidden ($$;$) { + my ($r, $reqtype, $value, $force) = @_; + my $hash = ref $r + ? ($r->{GetNeedsSecretHidden} ||= { }) + : \%_resource_get_needs_secret_hidden; + return if !$force && + (exists $_resource_get_needs_secret_hidden{$reqtype} || + exists $hash->{$reqtype}); + $hash->{$reqtype} = $value; +} + +sub need_add_hidden ($$) { + my ($r, $method, $reqtype) = @_; + return 1 if $method ne 'GET'; + if (ref $r) { + my $ent = $r->{GetNeedsSecretHidden}{$reqtype}; + return $ent if defined $ent; + } + my $ent = $_resource_get_needs_secret_hidden{$reqtype}; + return $ent if defined $ent; + die "unsupported nonpage GET type $reqtype"; } -sub nonpage_ok ($$) { - my ($r, $nonpagetype) = @_; +sub check_nonpage ($$) { + my ($r, $reqtype) = @_; $r->_assert_checked(); return unless $r->resource_get_needs_secret_hidden($nonpagetype); return if $r->{ParmT}; - die "missing hidden secret parameter on nonpage GET $nonpagetype"; + die "missing hidden secret parameter on nonpage request $nonpagetype"; } #---------- output ----------