--- loncom/lonencurl.pm 2006/07/14 20:20:52 1.2 +++ loncom/lonencurl.pm 2011/10/01 03:18:57 1.5 @@ -1,7 +1,8 @@ + # The LearningOnline Network # URL translation for encrypted filenames # -# $Id: lonencurl.pm,v 1.2 2006/07/14 20:20:52 albertel Exp $ +# $Id: lonencurl.pm,v 1.5 2011/10/01 03:18:57 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -30,32 +31,72 @@ package Apache::lonencurl; use strict; use Apache::Constants qw(:common :remotehost); -use CGI::Cookie(); use Apache::lonnet; use Apache::lonenc; +use GDBM_File; sub handler { my $r = shift; - my %cookies=CGI::Cookie->parse($r->header_in('Cookie')); - my $lonid=$cookies{'lonID'}; - my $cookie; - if ($lonid) { - my $handle=$lonid->value; - $handle=~s/\W//g; - my $lonidsdir=$r->dir_config('lonIDsDir'); - $env{'request.enc'}=1; - if ((-e "$lonidsdir/$handle.id") && ($handle ne '')) { + + $env{'request.enc'}=1; + + my $handle = &Apache::lonnet::check_for_valid_session($r); + if ($handle ne '') { # Initialize Environment - &Apache::lonnet::transfer_profile_to_env($lonidsdir,$handle); -# Decrypt URL and redirect - my $redirect=&Apache::lonenc::unencrypted($r->uri); - if ($r->args) { $redirect.='?'.$r->args; } - $r->internal_redirect($redirect); - return OK; - } + my $lonidsdir=$r->dir_config('lonIDsDir'); + &Apache::lonnet::transfer_profile_to_env($lonidsdir,$handle); +# Decrypt URL, if appropriate, and redirect + my $redirect; + my ($decrypted,$encnum,$remainder) = &checkdecryption($r->uri); + if (($encnum ne '') && ($remainder ne '')) { + my $referrer = $r->headers_in->{'Referer'} || ''; + my $host = $r->headers_in->{'Host'}; + my $decryptreferrer; + if ($referrer =~ m{^https?://\Q$host\E(/enc/\Q$encnum\E/[^?]+)}) { + ($decryptreferrer) = &checkdecryption($1); + } + if ($decryptreferrer eq '') { + if ($env{'request.course.fn'} ne '') { + my %symbhash; + if (tie(%symbhash,'GDBM_File',$env{'request.course.fn'}.'_symb.db', + &GDBM_READER(),0640)) { + my $lastsymb=$symbhash{'last_known'}; + untie(%symbhash); + (undef,undef,$decryptreferrer)=&Apache::lonnet::decode_symb($lastsymb); + $decryptreferrer = &Apache::lonnet::clutter($decryptreferrer); + } + } + } + if ($decryptreferrer ne '') { + my ($referrerpath) = ($decryptreferrer =~ m{^(.+/)[^/]+$}); + if (($env{'httpref.'.$referrerpath.$remainder} eq $decryptreferrer) || + ($env{'httpref.'.$referrerpath.'*'} eq $decryptreferrer) || + ($env{'httpref.'.$referrerpath} eq $decryptreferrer)) { + $redirect=$referrerpath.$remainder; + } + } + } + if ($redirect eq '') { + $redirect=&Apache::lonenc::unencrypted($r->uri); + } + if ($r->args) { $redirect.='?'.$r->args; } + $r->internal_redirect($redirect); + return OK; } return FORBIDDEN; } +sub checkdecryption { + my ($uri) = @_; + my ($encnum,$encname,$rest) = ($uri =~ m{^/enc/(\d+)/([^.]+)(.*)$}); + my $enclength = length($encname); + my $rem = $enclength%16; + if (($encname =~ /[^a-f0-9]/) || ($rem != 0) || ($enclength < 16)) { + return ('',$encnum,$encname.$rest); + } else { + return (&Apache::lonenc::unencrypted($uri)); + } +} + 1; __END__