Apr 142016
 

i have already made this project previuosly using arduino uno, wiznet w5100 ethernet shield and 4 channel relay shield. But using Arduino nano + ENC29J60 lot cheaper. not mention it has smaller size. Once you get this badboy online on your network, you can control every device in your house using your smartphone or any gadget you have(that rely on your coding skill, ofcourse).

let’s the fun begin 🙂

wait, as usual i don’t do lots of talk so here’s the schematic and arduino code.

Continue reading »

Feb 112016
 

i’m switching from courier-imap to dovecot recently. unfortunately on my centos 6.7, i only have dovecot 2.0.9 available. quota work as expected. the only thing that bother me, everytime someone outside world sent email to one of overquota user, dovecot create bounce mail to the sender. which is not good. expert said : “you will create backscattering mail!”.

long time ago when i was using courier-imap, i was creating simple perl daemon to check user quota and disk usage. dovecot have additional mysql table for storing user quota usage/bytes and messages.

so here how i’ve done.

perl daemon

#!/usr/bin/perl
use File::Find;
use strict;
use warnings;
use DBI;
use DBD::mysql;
use Sys::Syslog qw(:DEFAULT setlogsock);
use base qw(Net::Server::PreFork);

#
# Initalize and open syslog.
#
openlog('postfix::CHECK-SIZE::','pid','mail');

__PACKAGE__->run;
exit;

###

sub configure_hook {
        my $self = shift;

        $self->{server}->{port}     = '127.0.0.1:20028';
        $self->{server}->{user}     = 'vmail';
        $self->{server}->{group}    = 'mail';
        $self->{server}->{pid_file} = '/tmp/quota.pid';
        $self->{server}->{setsid}   = 1;
        $self->{basedir}            = "/data/vmail/example.com/";

}

### process the request
sub process_request {
        my $self = shift;
        while(my $line = <STDIN>) {
                chomp($line);
                if ($line=~/^get\s+(.+)/i) {
                        my $user = $1;
                        trim($user);
                        my $sqlsize = checksqlsize($user);
                        if (defined $sqlsize && $sqlsize == 0) {
                                print STDOUT "200 DUNNO\n";
                                #print STDOUT "sqlsize: $sqlsize\n";
                                next;
                        }
                        #print STDOUT "sqlsize: $sqlsize\n";

                        my $usrdirsize = $user;
                        $usrdirsize =~ s/\@example\.com$/\//;
                        my $dir = $self->{basedir} . $usrdirsize;
                        my $sqlusage =  checksqlusage($user);

                        if (defined $sqlusage && defined $sqlsize) {
                        syslog("info","Checking %s maildir size: define=%s, diskusage=%s", $user, $sqlsize, $sqlusage);
                                if ( $sqlusage > $sqlsize) {
                                        print STDOUT "200 REJECT $user is over quota! maildir size: define=$sqlsize, diskusage=$sqlusage\n
";
                                        next;
                                }
                        }
                }
                print STDOUT "200 DUNNO\n";
        }
}

sub trim{
        $_[0]=~s/^\s+//;
        $_[0]=~s/\s+$//;
        return;
}

sub checksqlsize {
        my $user = $_[0];
        my $sqlresult;
        trim($user);
        my $dbh = DBI->connect('DBI:mysql:postfix:localhost', 'postfix', 'yourpassword', { RaiseError => 1 });
        my $sth = $dbh->prepare(qq{SELECT quota FROM mailbox WHERE username='$user'});
        $sth->execute();
        while (my @row = $sth->fetchrow_array) {
                $sqlresult = $row[0];
        }
        $sth->finish();
        $dbh->disconnect;
        if ($sqlresult >= 0 ) {
                return $sqlresult;
        } else {
                return undef;
        }
}

sub checksqlusage {
        my $user = $_[0];
        my $sqlresult;
        trim($user);
        my $dbh = DBI->connect('DBI:mysql:postfix:localhost', 'postfix', 'yourpassword', { RaiseError => 1 });
        my $sth = $dbh->prepare(qq{SELECT bytes FROM quota2 WHERE username='$user'});
        $sth->execute();
        while (my @row = $sth->fetchrow_array) {
                $sqlresult = $row[0];
        }
        $sth->finish();
        $dbh->disconnect;
        if ($sqlresult >= 0 ) {
                return $sqlresult;
        } else {
                return undef;
        }
}

1;

postfix section

smtpd_recipient_restrictions =
        permit_sasl_authenticated,
        permit_mynetworks,
        reject_unauth_destination,
        reject_non_fqdn_sender,
        reject_non_fqdn_recipient,
        reject_unknown_recipient_domain,
        check_recipient_access proxy:tcp:[127.0.0.1]:20028,
        reject_rbl_client zen.spamhaus.org,
        reject_rbl_client bl.spamcop.net,
        reject_rbl_client dnsbl.sorbs.net,

test

# telnet localhost 20028
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
get foo@example.com
200 REJECT foo@example.com is over quota! maildir size: define=102400000, diskusage=147383243

you’re good to go 🙂