]> git.refcnt.org Git - distdns.git/blob - server.cgi
Initial commit.
[distdns.git] / server.cgi
1 #!/usr/bin/perl
2 #
3 # Copyright (c) 2013 Michel Ketterle, Steven Schubiger
4 #
5 # This file is part of distdns.
6 #
7 # distdns is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # distdns is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with distdns. If not, see <http://www.gnu.org/licenses/>.
19
20 use strict;
21 use warnings;
22
23 use CGI ();
24 use Fcntl ':flock';
25 use JSON qw(decode_json encode_json);
26
27 my $VERSION = '0.04';
28
29 #-----------------------
30 # Start of configuration
31 #-----------------------
32
33 my $json_file = 'data.json';
34 my $session_file = 'session.dat';
35
36 #---------------------
37 # End of configuration
38 #---------------------
39
40 my $query = CGI->new;
41
42 my @params = qw(netz pc name debug init session);
43 my %params;
44
45 foreach my $param (@params) {
46 $params{$param} = $query->param($param);
47 }
48 $params{ip} = $query->remote_addr;
49
50 if ($params{debug}) {
51 $SIG{__DIE__} = sub
52 {
53 print $query->header('application/json');
54 print encode_json({ entries => [], error => $_[0] });
55 exit;
56 };
57 }
58
59 if ($params{init}) {
60 die "Delete server-side $session_file first\n" if -e $session_file;
61
62 open(my $fh, '>', $session_file) or die "Cannot open server-side $session_file for writing: $!\n";
63 print {$fh} "$params{session}\n";
64 close($fh);
65 }
66 else {
67 open(my $fh, '<', $session_file) or die "Cannot open server-side $session_file for reading: $!\nPerhaps try running --init\n";
68 my $session = do { local $/; <$fh> };
69 chomp $session;
70 close($fh);
71
72 die "Session ID mismatch\n" unless $params{session} eq $session;
73 }
74
75 my @missing_params = grep { not defined $params{$_} && length $params{$_} } @params;
76 if (@missing_params) {
77 my $missing_params = join ', ', map "'$_'", @missing_params;
78 die "Incomplete query: param(s) $missing_params missing or not defined\n";
79 }
80
81 my %access;
82 my $access_file = "$params{netz}.conf";
83
84 if (-e $access_file) {
85 open(my $fh, '<', $access_file) or die "Cannot open $access_file for reading: $!\n";
86 while (my $line = <$fh>) {
87 chomp $line;
88 my ($name, $pc) = split /\s*,\s*/, $line;
89 push @{$access{$name}}, $pc;
90 }
91 close($fh);
92 }
93 else {
94 die "Access file $access_file does not exist\n";
95 }
96
97 if (exists $access{$params{name}} && grep /^$params{pc}$/i, @{$access{$params{name}}}) {
98 open(my $fh, '+<', $json_file) or die "Cannot open $json_file for read/write: $!\n";
99 flock($fh, LOCK_EX) or die "Cannot lock $json_file: $!\n";
100
101 my $json = do { local $/; <$fh> };
102
103 my $data = defined $json && length $json ? decode_json($json) : [];
104
105 for (my $i = 0; $i < @$data; $i++) {
106 if ($params{netz} eq $data->[$i]->{netz}
107 && $params{pc} eq $data->[$i]->{pc}
108 && $params{name} eq $data->[$i]->{name}) {
109 splice @$data, $i--, 1;
110 }
111 }
112 push @$data, { map { $_ => $params{$_} } qw(netz pc name ip) };
113
114 seek($fh, 0, 0) or die "Cannot seek to start of $json_file: $!\n";
115 truncate($fh, 0) or die "Cannot truncate $json_file: $!\n";
116
117 print {$fh} encode_json($data);
118
119 close($fh);
120
121 my @data = grep $_->{netz} eq $params{netz}, @$data;
122
123 print $query->header('application/json');
124 print encode_json({ entries => \@data, error => undef });
125 }
126 else {
127 die "Access not permitted\n";
128 }