CGI-SecureState

 view release on metacpan or  search on metacpan

SecureState.pm  view on Meta::CPAN

    }
    if ($USE_FLOCK) { flock(STATEFILE, LOCK_UN) || $self->errormsg('failed to unlock the state file') }
    close(STATEFILE) || $self->errormsg('failed to close the state file');
}


sub decipher
{
    my $self = shift;
    my ($cipher,$statefile) = @$self{'.cipher','.statefile'};
    my ($length,$extra,$decoded,$buffer,$block);

    if ($AVOID_SYMLINKS) { -l $statefile and $self->errormsg('symlink encountered')}
    sysopen(STATEFILE,$statefile, O_RDONLY) || $self->errormsg('failed to open the state file');
    if ($USE_FLOCK) { flock(STATEFILE, LOCK_SH) || $self->errormsg('failed to lock the state file') }
    binmode STATEFILE;

    #read metadata
    sysread(STATEFILE,$block,8);
    $block = $cipher->decrypt($block);

    #if there is nothing in the file, only set the age; otherwise read the contents
    unless (sysread(STATEFILE,$buffer,8)==8) {
	$self->{'.age'} = unpack("N",substr($block,4,4));
	$buffer = "";
    } else {
	#parse metadata
	$block^=$buffer;
	$self->{'.age'} = unpack("N",substr($block,4,4));
	$length = unpack("N",substr($block,0,4));
	$extra = ($length % 8) ? (8-($length % 8)) : 0;
	$decoded=-8;

	#sanity check
	if ((stat(STATEFILE))[7] != ($length+$extra+8))
	{ $self->errormsg('invalid state file') }

	#read the rest of the file
	sysseek(STATEFILE, 8, $SEEK_SET);
	unless (sysread(STATEFILE,$buffer,$length+$extra) == ($length+$extra))
	{ $self->errormsg('invalid state file') }

	my $next_block;
	$block = $cipher->decrypt(substr($buffer,0,8));
	#decrypt it
	while (($decoded+=8)<$length-8) {
	    $next_block = substr($buffer,$decoded+8,8);
	    $block^=$next_block;
	    substr($buffer, $decoded, 8, $block);
	    $block=$cipher->decrypt($next_block);
	}
	substr($buffer, $decoded, 8, $block);
	substr($buffer, -$extra, $extra, "");

    }
    if ($USE_FLOCK) { flock(STATEFILE, LOCK_UN) || $self->errormsg('failed to unlock the state file') }
    close(STATEFILE) || $self->errormsg('failed to close the state file');

    return($buffer);
}
END_OF_FUNCTIONS
    ;



( run in 0.252 second using v1.01-cache-2.11-cpan-26ccb49234f )