#!/usr/bin/perl -w
# vim: set sw=4 ts=4 si et:
# Written by: Guido Socher, Copyright: GPL
#
no locale;
# this is the directory where lfwmC.pm is found:
use lib '/home/webmail/lfwmail';
use strict;
use lfwmC;
use CGI;
use MIME::Words;
# note: you need also MD5 for POP3Client.
use Mail::POP3Client;
sub printmsglist($$$$);
sub msglist($$$$);
#
my $cf=lfwmC::getconfig();
my $url=$cf->{'url'};
# there should not be read access for normal users:
my $secretsdir=$cf->{'secretsdir'};
my $q;
my $VERSION=lfwmC::version();
#
my $gl_pw;
my $gl;
$q=new CGI;
$gl=lfwmC::getACU($q);
# 

if(! $gl->{'cookie'} || $q->param('new')){
    unless($q->param('pw')){
        # generate login page
        print $q->header(-Pragma=> 'no-cache');
        print $q->start_html(-title=>"lfwmail web mail, version $VERSION",
                             'BGCOLOR="#3b5987"');
        print $q->startform(-method=>'POST',
                            -action=>$url);
        print '
<CENTER>
<h2>lfwmail web mail login</h2>
<TABLE BORDER="1" CELLSPACING="2" CELLPADDING="2">
  <TR bgcolor="#bbcaea">
    <TD ALIGN="RIGHT">Login name:</TD>
    <TD><INPUT NAME="uid" SIZE="20" TYPE="text"></TD>
  </TR>
  <TR bgcolor="#bbcaea">
    <TD ALIGN="RIGHT">Password:</TD>
    <TD><INPUT NAME="pw" TYPE="password" SIZE="20"></TD>
  </TR>
</TABLE>
<br>
';
        print $q->submit();
        print $q->endform;
        print "<br><hr><br>\n";
        print $q->end_html;
        print "\n";
        exit 0;
    }else{
        # we have a password. Store it together with the
        # cookie.
        my $cookie;
        my $uid;
        $uid=$gl->{'uid'};
        $cookie=sprintf("%x%x%x%x",rand(254),rand(254),rand(254),rand(254));
        my $pw;
        # check pw:
        $pw=$q->param('pw');
        lfwmC::htmldie_std($q,"Error no uid/pw received.") unless($uid && $pw);

        # check if we have a password map file
        # The syntax of one line in this file is 
        # uid:webmailpassword_in_clear_text:pop_mail_pw:
        if (-f "$secretsdir/.lfwmail.pwmap"){
            open(FF,"$secretsdir/.lfwmail.pwmap")||die "ERROR: can not read $secretsdir/.lfwmail.pwmap, effective uid=$>\n";
            my $authok=0;
            while(<FF>){
                chomp;
                if (/^${uid}:${pw}:([^:]+)/o){
                    $authok=1;
                    # map password
                    $pw =$1;
                }
            }
            close FF;
            lfwmC::htmldie_std($q,"Password authentication error.") unless($authok);
        }else{
            # authenticate by checking pop3 connection
            my $mpop=new Mail::POP3Client(USER =>"$uid",PASSWORD=>"$pw",HOST=>$cf->{'pophost'});
            # Count returns -1 on Authentication Error:
            lfwmC::htmldie_std($q,"Authentication error.") unless($mpop->Count() >=0);
            $mpop->Close();
        }
        # now we are authenticated, store the cookie in a
        # session file
        my $browserid;
        my $tmp;
        $tmp=$q->user_agent()||'unknown_agent';
        $tmp=~s/[^\w\. ]+/ /g;
        $browserid=$tmp;
        $tmp=$ENV{'REMOTE_ADDR'}||'0.0.0.0';
        $tmp=~s/[:;]//g;
        $browserid.=",".$tmp;
        open(FF,">$secretsdir/$uid.session")||die "ERROR: can not write $secretsdir/$uid.session, effective uid=$>\n";
        print FF "${uid};${cookie};${browserid}:${pw}\n";
        close FF;
        chmod 0600,"$secretsdir/$uid.session";
        # clean up old decoded messages if any:
        if (-d $cf->{'mimetmpdir'}."/$uid"){
            system("/bin/rm -rf \"".$cf->{'mimetmpdir'}."/$uid\"");
        }
        # generate frameset first, pass cookie and do not use
        # anymore the real password
        print $q->header(-Pragma=> 'no-cache');
        print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
"http://www.w3.org/TR/html4/frameset.dtd">
<HTML><HEAD><TITLE>lfwmail web mail, version '.$VERSION.'</TITLE>
 <FRAMESET ROWS="40%,60%">
  <FRAME SRC="'.$url.'?c='.$cookie.'&amp;a=msglist&amp;uid='.$uid.'" NAME="tf">
  <FRAME SRC="'.$url.'?c='.$cookie.'&amp;a=empty&amp;uid='.$uid.'" NAME="bf">
 </FRAMESET>
</HEAD>
<body>
  <p>This page works only with frames</p>
</body>
</HTML>
';
        exit 0;
        }
}

lfwmC::htmldie_std($q,"Error no uid given.") unless($gl->{'uid'});
$gl_pw=lfwmC::cookie2pw($q,$gl->{'cookie'},$gl->{'uid'});
%ENV=();
$ENV{'PATH'}="/bin:/usr/bin";
$ENV{'IFS'}=" ";

if ($gl->{'action'} eq "msglist"){
    printmsglist($q,$gl_pw,$gl->{'uid'},$gl->{'cookie'});
}elsif($gl->{'action'} eq "del"){
    my @names=$q->param;
    my $delnum;
    my $pop=new Mail::POP3Client(USER =>$gl->{'uid'},PASSWORD=>"$gl_pw",HOST=>$cf->{'pophost'});
    for my $i (@names){
        # the name must match di[0-9]
        if($i=~/^di\d/){
            $delnum=$q->param($i)|| next;
            $pop->Delete($delnum);
        }
    }
    $pop->Close();
    printmsglist($q,$gl_pw,$gl->{'uid'},$gl->{'cookie'});
}elsif($gl->{'action'} eq "logout"){
    # logout
    # clean up old decoded messages if any:
    if (-d $cf->{'mimetmpdir'}."/".$gl->{'uid'}){
        system("rm -rf \"".$cf->{'mimetmpdir'}."/".$gl->{'uid'}."\" > /dev/null 2&1");
    }
    unlink($cf->{'secretsdir'}."/".$gl->{'uid'}.".session")||die "ERROR: could not delete session file ".$cf->{'secretsdir'}."/".$gl->{'uid'}.".session, effective uid is $>\n";
    print "Location: ".$url."?new\n\n";
    #
}elsif($gl->{'action'} eq "empty"){
    print $q->header(-Pragma=> 'no-cache');
	print $q->start_html(-title=>"lfwmail web mail, version $VERSION",
'BGCOLOR=#FFFFFF');
    print '<p>please select a message in the list above.</p>
';
    print $q->end_html;
    print "\n";
}else{
    lfwmC::htmldie_std($q,"Error no action found.");
}
# ------------   end of main program

sub printbuttonbar($$){
    my $uid=shift;
    my $cookie=shift;
    print '<small><table border="1" align="right" bgcolor="#BABABA"><tr>';
    print "<td bgcolor=\"#DDDDDD\"><a href=\"${url}_send?c=$cookie&amp;a=n0&amp;uid=$uid\" target=\"bf\">Compose New</a></td>\n";
    print "<td bgcolor=\"#DDDDDD\"><a href=\"${url}?c=$cookie&amp;a=logout&amp;uid=$uid\" target=\"_top\">Logout</a></td>\n";
    print "</tr></table></small>\n";
}

sub printmsglist($$$$){
    my $q=shift;
    my $pw=shift;
    my $uid=shift;
    my $cookie=shift;
    print $q->header(-Pragma=> 'no-cache');
	print $q->start_html(-title=>"lfwmail web mail, version $VERSION",
'BGCOLOR=#FFFFFF');
    printbuttonbar($uid,$cookie);
    print "<center><b>lfwmail, Inbox message list</b></center>\n";
    print "<br clear=\"all\">\n";
    msglist($q,$pw,$uid,$cookie);
    print $q->end_html;
    print "\n";
}

sub msglist($$$$){
    my $q=shift;
    my $pw=shift;
    my $uid=shift;
    my $cookie=shift;
    my $pop=new Mail::POP3Client(USER =>"$uid",PASSWORD=>"$pw",HOST=>$cf->{'pophost'});
    my $messagecount = $pop->Count();
    if ($messagecount<1){
        lfwmC::htmldie_noheader($q,"No message in mailbox");
        $pop->Close();
        exit 0;
    }
    print "<font size=1>$messagecount messages</font><br>\n";
    my @messagesize = $pop->ListArray();
    my $i=1;
    my ($from,$subject,$size,$date);
    print $q->startform(-method=>'POST',
                        -action=>$url);
    print '<input type="hidden" name="c" value="'.$cookie."\">\n";
    print '<input type="hidden" name="uid" value="'.$uid."\">\n";
    print "<table border=\"2\" width=\"95%\">\n";
    print '<tr bgcolor="#BABABA"><th width="60">Msg.<br>Nr.</th><th>From</th>
    <th  width="300">Subject</th><th width="80">Del</th><th width="80">Message<br>Size</th></tr>'."\n";
    while($i<=$messagecount){
        $from='(unknown)';
        $date='(missing date)';
        $subject='(No subject)';
        foreach my $l ( $pop->Head($i) ) {
            if ($l=~/^From:\s*(.+)/){
                $from=(lfwmC::htmlescape($1));
                $from=MIME::Words::decode_mimewords($from);
                next;
            }
            if ($l=~/^Date:\s*(..+)/){
                $date=(lfwmC::htmlescape($1));
                next;
            }
            if ($l=~/^Subject:\s*(..+)/){
                $subject=(lfwmC::htmlescape($1));
                $subject=MIME::Words::decode_mimewords($subject);
                next;
            }
        }
        if (($i % 2) == 0){
            print "<tr bgcolor=\"#bbcaea\">\n";
        }else{
            print "<tr>\n";
        }
        $size=$messagesize[$i]; # element 0 is not used
        $size=0 unless($size); # no undef
        $size=$size / 1024;
        print "<td>$i</td><td><small>$from<br>$date</small></td><td><a href=\"${url}_display?c=$cookie&amp;a=s$i&amp;uid=$uid\" target=\"bf\">$subject</a></td><td> <input type=\"checkbox\" value=\"$i\" name=\"di$i\"></td><td>".sprintf("%5.1fKb",$size)."</td>
</tr>\n";
        $i++;
    }
    print "</table><br>\n";
    print '<input type="hidden" name="a" value="del">'."\n";
    print '<input type="hidden" name="imax" value="'. ($i-1) . "\">\n";
    print $q->submit(-value=>'Refresh list and DELETE Msgs');
    print $q->endform;
    print "<table width=\"95%\" border=\"0\">\n";
    print "<tr><td>";
    print $q->startform(-method=>'POST',
                        -action=>$url);
    print '<input type="hidden" name="c" value="'.$cookie."\">\n";
    print '<input type="hidden" name="uid" value="'.$uid."\">\n";
    print '<input type="hidden" name="a" value="msglist"'."\">\n";
    print $q->submit(-value=>'Refresh list, keep all');
    print $q->endform;
    print "</td><td>";
    printbuttonbar($uid,$cookie);
    print "</td></tr>";
    print "</table>\n";
    print "<br>\n";
    $pop->Close();
}
# end of lfwmail
