3 # onak-mail.pl - Mail processing interface for onak, an OpenPGP Keyserver.
5 # Written by Jonathan McDowell <noodles@earth.li>
6 # Copyright 2002-2005 Project Purple
7 # Released under the GPL.
20 # Reads in our config file. Ignores any command it doesn't understand rather
21 # than having to list all the ones that are of no interest to us.
25 open(CONFIG, "@CONFIG@") or
26 die "Can't read config file: $!";
30 # Ignore; comment line.
31 } elsif (/^this_site (.*)/) {
32 $config{'thissite'} = $1;
33 } elsif (/^logfile (.*)/) {
34 $config{'logfile'} = $1;
35 } elsif (/^maintainer_email (.*)/) {
36 $config{'adminemail'} = $1;
37 } elsif (/^mail_delivery_client (.*)/) {
39 } elsif (/^pks_bin_dir (.*)/) {
40 $config{'pks_bin_dir'} = $1;
41 } elsif (/^db_dir (.*)/) {
42 $config{'db_dir'} = $1;
43 } elsif (/^mail_dir (.*)/) {
44 $config{'mail_dir'} = $1;
45 } elsif (/^syncsite (.*)/) {
46 push @{$config{'syncsites'}}, $1;
58 # Takes an armored OpenPGP stream and submits it to the keyserver. Returns the
59 # difference between what we just added and what we had before (ie the least
60 # data need to get from what we had to what we have).
64 my (@errors, @mergedata);
66 my $pid = open3(\*MERGEIN, \*MERGEOUT, \*MERGEERR,
67 $config{'pks_bin_dir'}."/onak", "-u", "add");
71 @mergedata = <MERGEOUT>;
81 sub processmail($$$$$) {
88 # HELP, ADD, INCREMENTAL, VERBOSE INDEX <keyid>, INDEX <keyid>,
89 # GET <keyid>, LAST <days>
91 if ($subject =~ /^INCREMENTAL$/i) {
95 my @newupdate = submitupdate($body);
99 foreach $i (@{$config{'syncsites'}}) {
100 if (! defined($seenby->{$i})) {
105 open (LOG, ">>$config{'logfile'}");
106 @time = localtime(time);
108 print LOG sprintf "%02d/%02d/%04d %02d:%02d:%02d",
109 $time[3], $time[4] + 1, $time[5] + 1900,
110 $time[2], $time[1], $time[0];
111 print LOG "] onak-mail[$$]: Syncing with $count sites.\n";
114 if ((! defined($newupdate[0])) || $newupdate[0] eq '') {
115 open (LOG, ">>$config{'logfile'}");
117 print LOG sprintf "%02d/%02d/%04d %02d:%02d:%02d",
118 $time[3], $time[4] + 1, $time[5] + 1900,
119 $time[2], $time[1], $time[0];
120 print LOG "] onak-mail[$$]: Nothing to sync.\n";
126 open(MAIL, "|$config{mta}");
127 print MAIL "From: $config{adminemail}\n";
129 foreach $i (@{$config{'syncsites'}}) {
130 if (! defined($seenby->{$i})) {
139 print MAIL "Subject: incremental\n";
140 foreach $site (keys %$seenby) {
141 print MAIL "X-KeyServer-Sent: $site\n";
143 print MAIL "X-KeyServer-Sent: $config{thissite}\n";
144 print MAIL "Precedence: list\n";
145 print MAIL "MIME-Version: 1.0\n";
146 print MAIL "Content-Type: application/pgp-keys\n";
148 print MAIL @newupdate;
151 } elsif ($subject =~ /^(VERBOSE )?INDEX (.*)$/i) {
152 my (@indexdata, $command);
159 my $pid = open3(\*INDEXIN, \*INDEXOUT, \*INDEXERR,
160 $config{'pks_bin_dir'}."/onak", $command, "$2");
162 @indexdata = <INDEXOUT>;
167 open(MAIL, "|$config{mta}");
168 print MAIL "From: $config{adminemail}\n";
169 print MAIL "To: $replyto\n";
170 print MAIL "Subject: Reply to INDEX $2\n";
171 print MAIL "Precedence: list\n";
172 print MAIL "MIME-Version: 1.0\n";
173 print MAIL "Content-Type: text/plain\n";
175 print MAIL "Below follows the reply to your recent keyserver query:\n";
177 print MAIL @indexdata;
182 my ($inheader, %seenby, $subject, $from, $replyto, @body, @syncmail);
187 # First dump the incoming mail to a file; this means that if we're receiving
188 # loads of updates we don't spawn lots of processes but instead leave the
189 # mails on disk to be dealt with sequentially.
191 my @time = localtime;
192 my $tmpfile = sprintf "%s/%04d%02d%02d-%02d%02d%02d-%d.onak",
201 open(MAILFILE, '>'.$tmpfile);
208 # Lock here to ensure that only one copy of us is processing the incoming
209 # mail queue at any point in time.
211 sysopen(LOCKFILE, $config{'db_dir'}.'/onak-mail.lck',
212 O_WRONLY|O_CREAT|O_EXCL) or exit;
217 opendir(MAILDIR, $config{'mail_dir'});
218 while ($file = readdir(MAILDIR)) {
219 next if $file !~ /\.onak$/;
222 $subject = $from = $replyto = "";
226 open(FILE, '<'.$config{'mail_dir'}.'/'.$file);
229 if (/^Subject:\s*(.*)\s*$/i) {
231 } elsif (/^X-KeyServer-Sent:\s*(.*)\s*$/i) {
233 } elsif (/^From:\s*(.*)\s*$/i) {
235 } elsif (/^Reply-To:\s*(.*)\s*$/i) {
245 if (! defined($replyto)) {
249 unlink $config{'mail_dir'}.'/'.$file;
251 processmail($subject, $from, $replyto, \%seenby, \@body);
254 unlink $config{'db_dir'}.'/onak-mail.lck';