# vim: set cindent expandtab ts=4 sw=4:
#
# Copyright (c) 1998-2005 Chi-Keung Ho. All rights reserved.
#
# This programe is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# Extmail - a high-performance webmail to maildir
# $Id$
use strict;
use IO::Socket;

package Ext::Auth::Authlib;
use Exporter;
use vars qw(@ISA @EXPORT);
@ISA = qw(Exporter);
@EXPORT = qw(auth);

sub new {
    my $this = shift;
    my $self = bless {@_}, ref $this || $this;
    $self->init(@_);
    $self;
}

sub init {
    my $self = shift;
    my %opt = @_;

    $opt{path} = '/var/spool/authdaemon/socket' if !$opt{path};
    $self->{opt}=\%opt;

    my $socket;
    $socket = IO::Socket::UNIX->new($opt{path}) or die "Authlib Error: $!\n";
    $self->{socket} = $socket;
}

sub _parse {
    my $str = shift;
    $str =~ s/\n+/\n/sxg;
    my %hash = ();

    for (split(/\n+/, $str)) {
        /^([^=]+)=(.*)/;
        $hash{$1} = $2;
    }
    \%hash;
}

sub search {
    my $self = shift;
    my $socket = $self->{socket};

    my ($user, $pass) = @_;
    my ($serv, $type) = ('extmail', 'login');
    my $len = length($user.$pass.$serv.$type)+4;

    printf($socket "AUTH %s\n%s\n%s\n%s\n%s\n\n",
        $len,    
        $serv,
        $type,
        $user,
        $pass
    );

    my $result = '';
    while (<$socket>) {
        $result .= $_;
    }

    return undef unless $result;
    if ($result =~ /^(FAIL|ERROR)/s) {
        return undef;
    }
    _parse($result);
}

# return value redifination since 0.24-RC2
#
# $rv =  0  LOGIN_OK
# $rv = -1  LOGIN_FAIL
# $rv =  1  LOGIN_DISABLED
#
sub auth {
    my $self = shift;
    my ($username, $password) = (@_);
    my $res = $self->search($username,$password);
    my $rv = -1;

    if($res) {
        if ($res->{OPTIONS} && $res->{OPTIONS} =~ m/disablewebmail=1/i) {
            return 1;
        }
        $self->{INFO} = $self->_fill_user_info($res);
        return 0;
    }
    -1; # default ?:)
}

sub change_passwd {
    my $self = shift;
    my ($user, $old, $new) = @_;
    my $socket = $self->{socket};
    my ($serv, $type) = ('extmail', 'login');

    printf($socket "PASSWD %s\t%s\t%s\t%s\n",
        $serv,
        $user,
        $old,
        $new
    );

    my $result = '';
    while (<$socket>) {
        $result .= $_;
    }

    return 0 unless $result;
    if ($result =~ /^OK/s) {
        return 1;
    }
    0;
}

sub _fill_user_info {
    my $self = shift;
    my $info = $_[0];

    $info->{MAILDIR} ||= "$info->{HOME}/Maildir";
    if ($info->{OPTIONS} && $info->{OPTIONS}=~ m/netdiskquota=([^\,]+)/i) {
        $info->{NETDISKQUOTA} = $1;
    }
    if ($info->{OPTIONS} && $info->{OPTIONS} =~ m/disablenetdisk=1/i) {
        $info->{OPTIONS} = 'disablenetdisk';
    }
    $info;
}

sub DESTROY {
    my $self = shift;
    $self->{socket}->close if ($self->{socket});
}

1;


syntax highlighted by Code2HTML, v. 0.9.1