package Win32::Security::EFS;
use strict;
use warnings;
use base qw/Exporter Win32::API::Interface/;
use vars qw/$VERSION @EXPORT_OK %EXPORT_TAGS/;
$VERSION = '0.11';
use File::Spec ();
my %consts;
BEGIN {
%consts = (
FILE_ENCRYPTABLE => 0,
FILE_IS_ENCRYPTED => 1,
FILE_SYSTEM_ATTR => 2,
FILE_ROOT_DIR => 3,
FILE_SYSTEM_DIR => 4,
FILE_UNKNOWN => 5,
FILE_SYSTEM_NOT_SUPPORT => 6,
FILE_USER_DISALLOWED => 7,
FILE_READ_ONLY => 8,
FILE_DIR_DISALLOWED => 9,
);
}
use constant \%consts;
__PACKAGE__->generate(
{
'advapi32' => [
[
'EncryptFile',
'P', 'I', '',
sub {
my ( $self, $filename ) = @_;
return $self->Call( File::Spec->canonpath($filename) );
},
],
[
'DecryptFile',
'PN',
'I',
'',
sub {
my ( $self, $filename, $reserved ) = @_;
return $self->Call( File::Spec->canonpath($filename),
$reserved );
},
],
[
'FileEncryptionStatus',
'PP',
'I',
'',
sub {
my ( $self, $filename, $statusref ) = @_;
$$statusref = "\0" x 4;
return $self->Call( File::Spec->canonpath($filename),
$$statusref );
},
],
[
'EncryptionDisable',
'PI',
'I',
'',
sub {
my ( $self, $filename, $disable ) = @_;
return $self->Call( File::Spec->canonpath($filename),
$disable );
},
],
[
'QueryUsersOnEncryptedFile',
'PP',
'I',
'__QueryUsersOnEncryptedFile',
sub {
my ( $self, $filename, $usersref ) = @_;
my $users = pack("L", 0x0);
my $retval =
$self->Call(
__make_unicode( File::Spec->canonpath($filename) ),
$users );
print STDERR "\nusers: ", unpack("PP", $users), "\n";
},
],
],
}
);
%EXPORT_TAGS = (
consts => [ __PACKAGE__->constant_names ],
api => [ __PACKAGE__->generated ]
);
@EXPORT_OK = ( __PACKAGE__->constant_names, __PACKAGE__->generated );
=head1 NAME
Win32::Security::EFS - Perl interface to functions that assist in working
with EFS (Encrypted File System) under Windows plattforms.
=head1 SYNOPSIS
use Win32::Security::EFS;
if(Win32::Security::EFS->supported()) {
Win32::Security::EFS->encrypt('some/file');
Win32::Security::EFS->decrypt('some/file');
}
=head1 DESCRIPTION
The Encrypted File System, or EFS, was introduced in version 5 of NTFS to
provide an additional level of security for files and directories. It
provides cryptographic protection of individual files on NTFS volumes
using a public-key system. Typically, the access control to file and
directory objects provided by the Windows security model is sufficient to
protect unauthorized access to sensitive information. However, if a laptop
containing sensitive data is lost or stolen, the security protection of
that data may be compromised. Encrypting the files increases security in
this scenario.
=head2 METHODS
=over 4
=item B<supported()>
Returns I<true> iff the underlaying filesystem supports EFS
=cut
sub supported {
require Win32;
my ( undef, $flags, undef ) = Win32::FsType();
return ( $flags & 0x00020000 ) > 0;
}
=item B<constant_names()>
=cut
sub constant_names {
return keys %consts;
}
=item B<encrypt($filename)>
The I<encrypt> function encrypts a file or directory. All data streams in a file are encrypted.
All new files created in an encrypted directory are encrypted.
=cut
sub encrypt {
my ( $self, $filename ) = @_;
return $self->EncryptFile($filename);
}
=item B<decrypt($filename)>
The I<decrypt> function decrypts an encrypted file or directory.
=cut
sub decrypt {
my ( $self, $filename ) = @_;
return $self->DecryptFile( $filename, 0 );
}
=item B<encryption_status($filename)>
The I<encryption_status> function retrieves the encryption status of the specified file.
If the function succeeds, it will return one of the following values see the L</CONSTANTS> section.
=cut
sub encryption_status {
my ( $self, $filename ) = @_;
my $status;
my $result = $self->FileEncryptionStatus( $filename, \$status );
return $result ? unpack( "L*", $status ) : undef;
}
=item B<encryption_disable($dirpath)>
The I<encryption_disable> function disables encryption of the specified directory and the files in it.
It does not affect encryption of subdirectories below the indicated directory.
=cut
sub encryption_disable {
my ( $self, $dirpath ) = @_;
return $self->EncryptionDisable( $dirpath, 1 );
}
=item B<encryption_enable($dirpath)>
The I<encryption_enable> function enables encryption of the specified directory and the files in it.
It does not affect encryption of subdirectories below the indicated directory.
=cut
sub encryption_enable {
my ( $self, $dirpath ) = @_;
return $self->EncryptionDisable( $dirpath, 0 );
}
=back
=head2 FUNCTIONS
You have the possibility to access the plain API directly. Therefore the
following functions can be exported:
use Win32::Security::EFS ':api';
=over 4
=item B<EncryptFile($filename)>
BOOL EncryptFile(
LPCTSTR lpFileName // file name
);
=item B<DecryptFile($filename, $reserved)>
BOOL DecryptFile(
LPCTSTR lpFileName, // file name
DWORD dwReserved // reserved; must be zero
);
=item B<FileEncryptionStatus($filename, \$status)>
BOOL FileEncryptionStatus(
LPCTSTR lpFileName, // file name
LPDWORD lpStatus // encryption status
);
=item B<EncryptionDisable($filename, $disable)>
BOOL EncryptionDisable(
LPCWSTR lpDirPath,
BOOL fDisable
);
=item B<QueryUsersOnEncryptedFile( ... )>
Not yet implemented.
=back
=head1 CONSTANTS
You can import all constants by importing Win32::Security::EFS like
use Win32::Security::EFS ':consts';
=over 4
=item *
encryption_status constants
=over 4
=item *
I<FILE_DIR_DISALLOWED:>
Reserved for future use.
=item *
I<FILE_ENCRYPTABLE:>
The file can be encrypted.
=item *
I<FILE_IS_ENCRYPTED:>
The file is encrypted.
=item *
I<FILE_READ_ONLY:>
The file is a read-only file.
=item *
I<FILE_ROOT_DIR:>
The file is a root directory. Root directories cannot be encrypted.
=item *
I<FILE_SYSTEM_ATTR:>
The file is a system file. System files cannot be encrypted.
=item *
I<FILE_SYSTEM_DIR:>
The file is a system directory. System directories cannot be encrypted.
=item *
I<FILE_SYSTEM_NOT_SUPPORT:>
The file system does not support file encryption.
=item *
I<FILE_UNKNOWN:>
The encryption status is unknown. The file may be encrypted.
=item *
I<FILE_USER_DISALLOWED:>
Reserved for future use.
=back
=back
=head1 AUTHOR
Sascha Kiefer, L<esskar@cpan.org>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2006 Sascha Kiefer
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
=cut
sub __make_unicode {
require Encode;
return map { Encode::encode( 'UTF-16LE', $_, 1 ) } @_;
}
1;