Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

A WebDAV server with authentication

by Corion (Patriarch)
on Dec 23, 2007 at 12:27 UTC ( [id://658773]=sourcecode: print w/replies, xml ) Need Help??
Category: Networking Code
Author/Contact Info /msg Corion
Description:

This is a small WebDAV server I use for serving files to other people. WebDAV is quite convenient for serving files because "all three" operating systems offer a client that allows you to treat a WebDAV share as a remote file system. It extends the sample code of Net::DAV::Server to provide HTTP basic authentication, so it can be exposed on the internet without being completely open.

I've implemented a separation of privileges into "readers" and "writers", but so far I haven't felt the need to export write privileges. So maybe that part shouldn't have been written at all, in the spirit of Dominus.

On the side of prerequisites, this one is quite heavy. It uses Net::DAV::Server, which in turn pulls in XML::LibXML. It uses Filesys::Virtual, Authen::Htpasswd and HTTP::Daemon.

#!/opt/perl/bin/perl5.8.8 -w
use strict;

use Net::DAV::Server;
use Filesys::Virtual::Plain;
use Authen::Htpasswd;
use HTTP::Daemon;
use Cwd;
use Getopt::Long;
use Pod::Usage;

use vars qw($filesys $webdav $can_read $can_write
%permissions
$VERSION);

$VERSION = '0.01';

GetOptions(
    'host:s' => \my $host,
    'port:i' => \my $port,
    'version' => \my $print_version,
    'readers:s' => \my $reader_file,
    'writers:s' => \my $writer_file,
    'path:s' => \my $path,
    'verbose' => \my $verbose,
    'horribly-unsafe' => \my $horribly_unsafe,
    'add-user' => \my $do_add_user,
) || pod2usage(1);

$host ||= 'localhost';
$port ||= 4242;
$reader_file ||= 'readers.htpasswd';
$path ||= getcwd;

$can_read = Authen::Htpasswd->new($reader_file, { encrypt_hash => 'md5
+' });
if ($writer_file) {
    $can_write = Authen::Htpasswd->new($writer_file, { encrypt_hash =>
+ 'md5' });
};

if ($do_add_user) {
    $can_read->update_user(@ARGV);
    print "Added user $ARGV[0] with password $ARGV[1]\n";
    exit
};

%permissions = (
    options  => [ 1 ],
    put      => [ $can_write ],
    get      => [ $can_read, $can_write ],
    head     => [ $can_read, $can_write ],
    post     => [ $can_write ],
    delete   => [ $can_write ],
    trace    => [ $can_read, $can_write ],
    mkcol    => [ $can_write ],
    propfind => [ $can_read, $can_write ],
    copy     => [ $can_write ],
    lock     => [ $can_write ],
    unlock   => [ $can_write ],
    move     => [ $can_write ],
);

$filesys = Filesys::Virtual::Plain->new({root_path => $path});
$webdav = Net::DAV::Server->new();
$webdav->filesys($filesys);
my $d = HTTP::Daemon->new(
    LocalAddr => $host,
    LocalPort => $port,
    ReuseAddr => 1,
) or die "Couldn't create daemon on port $host:$port.";

print "Please contact me at: ", $d->url, "\n";
while (my $c = $d->accept) {
    while (my $request = $c->get_request) {
        my $method = lc $request->method;
        #warn $request->as_string;
        my ($username,$pass) = $request->authorization_basic;
        #warn "User >$username< Pass >$pass<";
        (my $allowed) = (grep { eval { ref $_ ? $_->check_user_passwor
+d($username,$pass) : $_ } }
                        grep { defined $_ } (@{ $permissions{ $method 
+}}));
        $allowed ||= $horribly_unsafe;
        my $response = HTTP::Response->new;
        if ($allowed) {
            $response = $webdav->run($request);
        } else {
            $response->code('401');
            $response->www_authenticate('Basic realm="DAV Server $VERS
+ION"');
            $response->message('Access denied');
        };
        warn "Response: " . $response->code
            if $verbose;
        $c->send_response($response);
    }
    $c->close;
    undef($c);
}

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://658773]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (3)
As of 2024-04-25 14:46 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found