#!/usr/bin/perl -w
#
# dnsupdate.pl - An dynamic DNS update cgi for nsupdate.
# Copyright (C) 2003 Masaki Suzuki.  All rights reserved.
#
# This program 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.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
#
# $Id: dnsupdate.pl,v 1.0 2003/09/22 11:31:31 masaki Exp $

require 5.004;
use strict;

$| = 1;

sub PrintResponse($);

my ($key, $val, %param);

foreach(split('&', $ENV{'QUERY_STRING'})) {
    ($key, $val) = split('=', $_);
    $param{$key} = $val;
}

my $addr   = $ENV{'REMOTE_ADDR'};
my $host   = $param{'hostname'};
my $update = $param{'update'};
my $passwd = $param{'passwd'};

if ($host =~ /^\s*$/) {
    &PrintResponse('Invalid host');
    exit;
}

unless ($update eq 'add' || $update eq 'del') {
    &PrintResponse('Invalid update (update=add or update=del)');
    exit;
}

if ($passwd =~ /^\s*$/) {
    &PrintResponse('Invalid passwd');
    exit;
}

my $DOMAIN      = 'example.com';
my $PASSWD_FILE = "./passwd/$DOMAIN";

open(PASSWD, "$PASSWD_FILE") || (&PrintResponse("Server error: Can't open password file") && exit);
$key = <PASSWD>;
close(PASSWD);
$key =~ tr/\x00-\x1f//d;

unless ($passwd eq $key) {
    &PrintResponse('Invalid passwd');
    exit;
}

my $NSUPDATE = '/usr/local/bin/nsupdate';
my $KEY_FILE = '/usr/local/www/cgi-bin/keys/example.com.key';
my $TTL      = '30';
my $TYPE     = 'A';
$host        = "$host.$DOMAIN";
my @option   = ('-d', '-k'. "$KEY_FILE");

if (open(UPDATE,'|-') || exec $NSUPDATE, @option) {
    if ($update eq 'del') {
        print UPDATE "update delete $host.\n\n";
	close UPDATE;
	&PrintResponse("Update: delete $host");
    } elsif ($update eq 'add') {
        print UPDATE "update delete $host.\n";
        print UPDATE "update add $host. $TTL $TYPE $addr\n\n";
        close UPDATE;
	&PrintResponse("Update: delete $host\nUpdate: add $host $TTL $TYPE $addr");
    }
}

sub PrintResponse($) {
    print "Content-type: Text/Plain;\n\n";
    print "$_[0]\n";
}
