spf-discuss
[Top] [All Lists]

Re: Re: website problem

2005-07-15 14:54:48
On Fri, Jul 15, 2005 at 08:59:36AM -0500, wayne wrote:
| 
| No, the source isn't currently available, but one of the things I
| talked with Meng about was trying to make it available so that any
| registrar/DNS hoster could easily use it.
| 

the source to the wizard page is pretty simple.

I've been asked for a version of this wizard which hosting
providers can link to, and which links back to them after
submission.  That'll be pretty easy.

<%attr>
title => "The SPF Setup Wizard"
</%attr>

<table border="0" cellspacing="0" cellpadding="0">
  <tr>
  <td valign="top"><img src="images/prpolmen.gif" alt="bar with right 
arrows"></td>
  </tr>
<tr><td valign="top" bgcolor="#F8F7F9" class="sub_content">


<%doc>
the illustrator file mechlabel.ai generates the little labels.  transparent 
pngs are antialiased.
the whitesep colour in spf.css should either be white or one of the label 
colours for consistency.

20031212-16:27:43 mengwong(_at_)nutmeg:~/Documents/spf2/website/images% perl 
-le 'my %hash = (qw(09 a 11 mx 13 ptr 25 a: 27 mx: 29 ip4: 41 include: 43 
-all)); while (my ($k, $v) = each %hash) { print "mv mechlabel_$k.png 
label_$v.png" }' | sh; cp *.png /sw/apache/htdocs/spf/images/
</%doc>

<%args>
$use_built_from_args => 0
</%args>

<%once>
my $res = Net::DNS::Resolver->new();
</%once>

<%shared>
my $mydomain;
my $a;
my $mx;
my $a_colon;
my $mx_colon;
my $ip4_colon;
my $include;
my $ptr;
my $all;

my %mxhosts;
my @mx;
my @a;
my $a_ptrdname;
my %a_ptrdnames;
my $Mydomain;
my $built_from_args;
my $built_from_args_length = 40;

my $DEFAULT_INCLUDE   = "myISP.com";
my $DEFAULT_A_COLON   = "regular hostnames";
my $DEFAULT_MX_COLON  = "MX servers";
my $DEFAULT_IP4_COLON = "IP addresses";

my $spfquery;
my $directive_set;

my @record_to_explain;
</%shared>

<%perl>
$mydomain  = $ARGS{mydomain};
$a         = $ARGS{a};
$mx        = $ARGS{mx};
$a_colon   = $ARGS{a_colon};
$mx_colon  = $ARGS{mx_colon};
$ip4_colon = $ARGS{ip4_colon};
$include   = $ARGS{include};
$ptr       = $ARGS{ptr};
$all       = $ARGS{all};


if (! $mydomain) {
#  my $client_host = "mydomain.com";
  my $client_host = gethostbyaddr(inet_aton($ENV{REMOTE_ADDR}), AF_INET) || 
"mydomain.com";
  my @client_host = split /\./, $client_host;
  my $client_domain = join ".", @client_host[ length($client_host[-1]) == 3 ? 
(-2,-1) : (-3,-2,-1) ];

  $mydomain ||= $client_domain;
}
($mydomain) = $mydomain =~ /(\S+)/;
$Mydomain = $mydomain;

$spfquery = Mail::SPF::Query->new(ipv4=>"208.210.125.24", helo=>$Mydomain, 
sender=>"droid\(_at_)$Mydomain");
my $result = $spfquery->result();
$directive_set = $spfquery->{directive_set};

if (defined $directive_set) { # domain already publishes SPF, so we prefill the 
form values

  my $mechanisms = {};
  foreach my $mech ($directive_set->mechanisms) {
    no warnings 'uninitialized';
    my ($prefix, $mech_name, $value) = @$mech;
    $mechanisms->{$mech_name}->{"$prefix$value"} = $mech;
  }
                
  if (not defined $all) {
    $all = ($mechanisms->{all}->{"-"} ? "yes" : "no");
  }

  if (not defined $a)         { $a   = (delete $mechanisms->{a}  ->{"+"} ? 
"yes" : "no"); }
  if (not defined $mx)        { $mx  = (delete $mechanisms->{mx} ->{"+"} ? 
"yes" : "no"); }
  if (not defined $ptr)       { $ptr = (delete $mechanisms->{ptr}->{"+"} ? 
"yes" : "no"); }
  if (not defined $a_colon)   { $a_colon   = join (" ", grep { s/^\+// } keys 
%{$mechanisms->{a}})       || undef; }
  if (not defined $mx_colon)  { $mx_colon  = join (" ", grep { s/^\+// } keys 
%{$mechanisms->{mx}})      || undef; }
  if (not defined $ip4_colon) { $ip4_colon = join (" ", grep { s/^\+// } keys 
%{$mechanisms->{ip4}})     || undef; }
  if (not defined $include)   { $include   = join (" ", grep { s/^\+// } keys 
%{$mechanisms->{include}}) || undef; }

}

if (my $query = $res->query($mydomain, "MX")) { @mx = map { $_->exchange } grep 
{ $_->type eq "MX" } $query->answer }
if (my $query = $res->query($mydomain, "A"))  { @a  = map { $_->address }  grep 
{ $_->type eq "A"  } $query->answer }
@a = keys %{ { map { lc $_ => 1 } @a } };

foreach my $a (@a) {
  my @a_ptr;
  if (my $query = $res->query(join (".", reverse(split /\./, $a), 
"in-addr.arpa"), "PTR"))  { @a_ptr = map { $_->ptrdname } grep { $_->type eq 
"PTR"  } $query->answer }
  $a_ptrdname = $a_ptr[0] || undef;
  @a_ptrdnames{(_at_)a_ptr}=@a_ptr;
}

foreach my $mx (@mx) {
  my @a_for_mx;
  if (my $query  = $res->query($mx, "A"))  { @a_for_mx = map { $_->address }  
grep { $_->type eq "A"  } $query->answer }
  foreach my $mx_ip (@a_for_mx) {
    my @hostnames;
    if (my $query = $res->query(join(".",(reverse split /\./, $mx_ip), 
"in-addr.arpa"), "PTR")) {
        @hostnames = map { $_->ptrdname } grep { $_->type eq "PTR" } 
$query->answer;
    }
    foreach my $ptrdname ($mx, @hostnames) { push @{$mxhosts{$ptrdname}}, 
$mx_ip; }
  }
}

my @built_from_args = ("v=spf1");

if ($ip4_colon ne $DEFAULT_IP4_COLON) { push @built_from_args, map {     
"ip4:$_" } split ' ', $ip4_colon }
if ($a   eq "yes") { push @built_from_args, "a"  }
if ($mx  eq "yes") { push @built_from_args, "mx" }
if ($ptr eq "yes") { push @built_from_args, "ptr" }
if ($a_colon   ne $DEFAULT_A_COLON)   { push @built_from_args, map {       
"a:$_" } split ' ', $a_colon   }
if ($mx_colon  ne $DEFAULT_MX_COLON)  { push @built_from_args, map {      
"mx:$_" } split ' ', $mx_colon  }
if ($include   ne $DEFAULT_INCLUDE)   { push @built_from_args, map { 
"include:$_" } split ' ', $include   }
if   ($all eq "yes") { push @built_from_args, "~all" }
elsif ($all eq "no") { push @built_from_args, "?all" }

$built_from_args = join " ", @built_from_args;
$built_from_args_length = (length $built_from_args < 40 ? 40 : length 
$built_from_args);

my @existing_txt;
if (my $query = $res->query($Mydomain, "TXT")) {
    @existing_txt = (grep { /^v=spf1(\s|$)/i }
                     map { join "", $_->char_str_list }
                            grep { $_->type eq "TXT" } $query->answer);
                     
                 }
    @record_to_explain = ($use_built_from_args 
                          ? @built_from_args 
                          : split ' ', join " ", @existing_txt);
    
</%perl>

<P>Most domains send outbound mail through a relatively
small number of servers.  Domains should describe that set
of servers in an SPF record in their DNS.  Internet email
receivers can then reject forged messages which don't come
from an envelope sender domain's approved servers.  This
wizard helps domain owners identify all the servers which
could be expected to send mail from their domain.</P>

<script language="JavaScript1.3" type="text/javascript">
<!--

function textarea2colon(prefix, textarea) {
  mywords = textarea.value.split(/\s+/);
  for (i in mywords) {
        if (mywords[i].match(/\S/)) {
            newvalue.push(  prefix + ":" + mywords[i]);
        }
    }
}

function update_rsf(myform) {
    newvalue = new Array("v=spf1");

  if (myform.a         && myform.a[0].checked)                         { 
newvalue.push(   "a");             }
  if (myform.mx        && myform.mx[0].checked)                        { 
newvalue.push(  "mx");             }
  if (myform.ptr       && myform.ptr[0].checked)                       { 
newvalue.push( "ptr");             }
  if (myform.a_colon   && myform.a_colon.value.length   && myform.a_colon.value 
  != "<% $DEFAULT_A_COLON   %>") { textarea2colon("a",      myform.a_colon); }
  if (myform.mx_colon  && myform.mx_colon.value.length  && 
myform.mx_colon.value  != "<% $DEFAULT_MX_COLON  %>") { textarea2colon("mx",    
 myform.mx_colon) }
  if (myform.ip4_colon && myform.ip4_colon.value.length && 
myform.ip4_colon.value != "<% $DEFAULT_IP4_COLON %>") { textarea2colon("ip4",   
 myform.ip4_colon)}
  if (myform.include   && myform.include.value.length   && myform.include.value 
  != "<% $DEFAULT_INCLUDE   %>") { textarea2colon("include",myform.include); }
  if (myform.all[0]    && myform.all[0].checked)                       { 
newvalue.push("~all"); }
  if (myform.all[1]    && myform.all[1].checked)                       { 
newvalue.push("?all"); }

    myform.record_so_far.value = "\"" + newvalue.join(" ") + "\"";
}

//-->
</script>



<& .setdomain &> 

<FORM METHOD="GET" ACTION="">
<INPUT TYPE="HIDDEN" NAME="mydomain" VALUE="<% $Mydomain %>">
<TABLE BGCOLOR="#FFFFB0" BORDER=0>
<& .whitesep &><& .mech-a        &>
<& .whitesep &><& .mech-mx       &>
<& .whitesep &><& .mech-ptr      &>
<& .whitesep &><& .mech-others   &>
<& .whitesep &><& .mech-include  &>
<& .whitesep &><& .mech-all      &>
<& .whitesep &><& .record-so-far &>
</TABLE>
</FORM>

<!-- note for GMC -->
% if (! @record_to_explain) {
</table>

% return
% }
<!-- note for GMC -->
<H3><% join " ", @record_to_explain |h %></H3>

<TABLE BORDER=0 CELLPADDING=5 CELLSPACING=0 CLASS="orangeblock">
% foreach my $directive (@record_to_explain) {
% 
%   if ($directive eq "v=spf1") {
      <TR><TD ALIGN=CENTER VALIGN=MIDDLE CLASS="orangeblock"><& .mechlabel, 
label => "v=spf1" &></TD>
         <TH><CODE><% $directive |h%></CODE></TH><TD>This identifies the TXT 
record as an SPF string.</TD></TR>
%   }
% 
%   elsif ($directive =~ /^\+?a(\/.*)?$/i) {
      <TR><TD ALIGN=CENTER VALIGN=MIDDLE CLASS="orangeblock"><& .mechlabel, 
label => "a" &></TD>
         <TH><CODE><% $directive |h%></CODE></TH><TD>
%      if (@a == 0) {
                            <% $Mydomain %> has no IP addresses.  This 
declaration has no effect.
%      } elsif (@a == 1) {
                            <% $Mydomain %>'s IP address is <% $a[0] %><% 
($a_ptrdname && lc $a_ptrdname ne $Mydomain) ? " ($a_ptrdname)" : "" %>.
                            <BR>That server is allowed to send mail from <% 
$Mydomain %>.
%      } else {
                            <% $Mydomain %>'s IP addresses are <& comma_and, 
in=>[map { s/.$Mydomain//i; $_ } keys %a_ptrdnames] &>.
                            <BR>Those servers are allowed to send mail from <% 
$Mydomain %>.
%      }
%      if ($directive =~ /\/(\d+)$/) {
                            <BR>So are any other servers in the same /<%$1%> 
subnet.
%      }
       </TD></TR>
%   }
%
%   elsif ($directive =~ /^\+?mx(\/.*)?$/i) {
      <TR><TD ALIGN=CENTER VALIGN=MIDDLE CLASS="orangeblock"><& .mechlabel, 
label => "mx" &></TD>
         <TH><CODE><% $directive |h%></CODE></TH><TD>
%     if (keys %mxhosts == 0) {
                                <% $Mydomain %> has no MX servers.
%     } elsif (keys %mxhosts == 1) {
                                <% $Mydomain %> has one MX server, <& 
comma_and, in=> [ map { s/.$Mydomain//i; $_ } keys %mxhosts] &>.
                                <BR>It is allowed to send mail from <% 
$Mydomain %>.
                                <BR>If you add more MX servers in the future, 
they'll automatically be allowed, too.
%     } else {
                                This wizard found <% scalar(keys %mxhosts) %> 
names for the MX servers for <% $Mydomain %>: <& comma_and, in=>[map { 
s/.$Mydomain//i; $_ } keys %mxhosts] &>.
                                <BR>(A single machine may go by more than one 
hostname.  All of them are shown.)
                                <BR>The servers behind those names are allowed 
to send mail from <% $Mydomain %>.
%     }
%      if ($directive =~ /\/(\d+)$/) {
                            <BR>So are any other servers in the same /<%$1%> <% 
keys %mxhosts > 1 ? "subnets" : "subnet" %>.
%      }
       </TD></TR>
%   }
%
%   elsif ($directive =~ /^\+?ptr$/i) {
      <TR><TD ALIGN=CENTER VALIGN=MIDDLE CLASS="orangeblock"><& .mechlabel, 
label => "ptr" &></TD>
         <TH><CODE><% $directive |h%></CODE></TH><TD>
                                Any server whose name ends in <% $Mydomain %> 
is allowed to send mail from <% $Mydomain %>.
       </TD></TR>
%   }
%
%   elsif ($directive =~ /^\+?ptr:(\S+)/i) {
      <TR><TD ALIGN=CENTER VALIGN=MIDDLE CLASS="orangeblock"><& .mechlabel, 
label => "ptr" &></TD>
         <TH><CODE><% $directive |h%></CODE></TH><TD>
                                Any server whose name ends in <CODE><% 
$spfquery->macro_substitute($1) %></CODE> is allowed to send mail from <% 
$Mydomain %>.
       </TD></TR>
%   }
%
%   elsif ($directive =~ /^\+?ip4:(\S+)/i) {{
      <TR><TD ALIGN=CENTER VALIGN=MIDDLE CLASS="orangeblock"><& .mechlabel, 
label => "ip4:" &></TD>
         <TH><CODE><% $directive |h%></CODE></TH><TD>
% my $network = $1; $network =~ s/\/32$//;
% if ($network =~ /\//) {
%   my $cidr = Net::CIDR::Lite->new($network);
          Every host in the range <% $cidr->list_range |h%> is allowed to send 
mail from <% $Mydomain %>.
% } else {
          <% $network |h%> is allowed to send mail from <% $Mydomain %>.
% }
      </TD></TR>
%   }}
%
%   elsif ($directive =~ /^\+?mx:([^\/]+)/i) {
      <TR><TD ALIGN=CENTER VALIGN=MIDDLE CLASS="orangeblock"><& .mechlabel, 
label => "mx:" &></TD>
         <TH><CODE><% $directive |h%></CODE></TH><TD>
          The MX servers for <% $1 |h%> are allowed to send mail from <% 
$Mydomain %>.
%      if ($directive =~ /\/(\d+)$/) {
                            <BR>So are any other servers in the same /<%$1%> <% 
keys %mxhosts > 1 ? "subnets" : "subnet" %>.
%      }
      </TD></TR>
%   }
%
%   elsif ($directive =~ /^\+?a:([^\/]+)/i) {
      <TR><TD ALIGN=CENTER VALIGN=MIDDLE CLASS="orangeblock"><& .mechlabel, 
label => "a:" &></TD>
         <TH><CODE><% $directive |h%></CODE></TH><TD>
          <% $1 |h%> is also allowed to send mail from <% $Mydomain %>.
%      if ($directive =~ /\/(\d+)$/) {
                            <BR>So are any other servers in the same /<%$1%> 
subnet.
%      }
      </TD></TR>
%   }
%
%   elsif ($directive =~ /^\+?include:(\S+)/i) {
      <TR><TD ALIGN=CENTER VALIGN=MIDDLE CLASS="orangeblock"><& .mechlabel, 
label => "include:" &></TD>
         <TH><CODE><% $directive |h%></CODE></TH><TD>
          Any server allowed to send mail from <CODE><% 
$spfquery->macro_substitute($1) |h%></CODE> is also allowed to send mail from 
<% $Mydomain %>.
%   # TODO: add a check to ensure the included domains actually have SPF 
records.
%
      </TD></TR>
%   }
%
%   elsif ($directive =~ /^\+?exists:(\S+)/i) {
      <TR><TD ALIGN=CENTER VALIGN=MIDDLE CLASS="orangeblock"><& .mechlabel, 
label => "exists:" &></TD>
         <TH><CODE><% $directive |h%></CODE></TH><TD>
       <CODE><% $1 |h%></CODE> is <A HREF="macros.html">macro-expanded</A>.
       <BR>If the result has an A record, the transaction is approved.
      </TD></TR>
%   }
%
%   elsif ($directive =~ /^([+~?-])all/) {
      <TR><TD ALIGN=CENTER VALIGN=MIDDLE CLASS="orangeblock"><& .mechlabel, 
label => "all" &></TD>
         <TH><CODE><% $directive |h%></CODE></TH><TD>
%      if ($1 eq "+") {
                                                         The entire Internet is 
allowed to send mail from <% $Mydomain %>.
                                                         <BR>This is <BLINK>not 
recommended</BLINK>.
%      } elsif ($1 eq "-" and @record_to_explain == 2) {
                                                         No servers are allowed 
to send mail from <% $Mydomain %>.
                                                         <BR>This is 
appropriate for web-only sites.
%      } elsif ($1 eq "-") {
                                                         No other servers are 
allowed to send mail from <% $Mydomain %>.
                                                         <BR>This is a good 
default for sites particularly concerned about forgery.
%      } elsif ($1 eq "?") {
                                                         SPF queries that do 
not match any other mechanism will return "neutral".
                                                         <BR>Messages that are 
not sent from an approved server should still be accepted as if the SPF record 
did not exist.
%      } elsif ($1 eq "~") {
                                                         SPF queries that do 
not match any other mechanism will return "softfail".
                                                         <BR>Messages that are 
not sent from an approved server should still be accepted but may be subjected 
to greater scrutiny.
%      }
      </TD></TR>
%   }
%
%   elsif ($directive =~ /^redirect=(\S+)/) {
      <TR><TD ALIGN=CENTER VALIGN=MIDDLE CLASS="orangeblock"><& .mechlabel, 
label => "redirect=" &></TD>
         <TH><CODE><% $directive |h%></CODE></TH><TD>
                                          Load the SPF record for <% $1 %> and 
execute it instead.
      </TD></TR>
%   }
%
%   elsif ($directive =~ /^exp=(\S+)/) {
      <TR><TD ALIGN=CENTER VALIGN=MIDDLE CLASS="orangeblock"><& .mechlabel, 
label => "exp=" &></TD>
         <TH><CODE><% $directive |h%></CODE></TH><TD>
%  my @txt_exp = "";
% if (my $query = $res->query($1, "TXT")) { @txt_exp = map { join "", 
$_->char_str_list } grep { $_->type eq "TXT" } $query->answer }
                                          If the message is rejected, the 
explanation string
                                          <BR><% join " ", @txt_exp |h %>
                                          <BR>will be macro-expanded and shown 
to the SMTP client.
      </TD></TR>
%   }
%
%
%   elsif ($directive =~ /^[^:\/]+=/) {
      <TR><TD ALIGN=CENTER VALIGN=MIDDLE CLASS="orangeblock"><& .mechlabel, 
label => "unknown-modifier" &></TD>
         <TH><CODE><% $directive |h%></CODE></TH><TD>
%  my @txt_exp = "";
% if (my $query = $res->query($1, "TXT")) { @txt_exp = map { join "", 
$_->char_str_list } grep { $_->type eq "TXT" } $query->answer }
                                          Unrecognized modifiers are ignored.
      </TD></TR>
%   }
%
%   elsif ($directive =~ /^-/) {
      <TR><TD ALIGN=CENTER VALIGN=MIDDLE CLASS="orangeblock"><& .mechlabel, 
label => "fail" &></TD>
         <TH><CODE><% $directive |h%></CODE></TH><TD>
                                          If this directive matches, SPF will 
return "fail".
      </TD></TR>
%   }
%
%   elsif ($directive =~ /^\?/) {
      <TR><TD ALIGN=CENTER VALIGN=MIDDLE CLASS="orangeblock"><& .mechlabel, 
label => "unknown-mechanism" &></TD>
         <TH><CODE><% $directive |h%></CODE></TH><TD>
                                          If this directive matches, SPF will 
return "unknown".
      </TD></TR>
%   }
%
%   else {
      <TR><TD ALIGN=CENTER VALIGN=MIDDLE CLASS="orangeblock"><& .mechlabel, 
label => "unknown-mechanism" &></TD>
         <TH><CODE><% $directive |h%></CODE></TH><TD>
                                          An SPF client will abort if it 
encounters a mechanism it does not recognize.
      </TD></TR>
%   }
% }
</TABLE>

<HR>
<!-- HIER2 -->
% 
% my @just_a = $mx eq "yes" ? sort grep { lc $_ ne $Mydomain } keys %mxhosts : 
();
% 

<TABLE BORDER=0 CLASS="orangeblock">
 <TR>
  <TD>
   <H3>If you run BIND</H3>
    Paste this into your zone file:

<PRE><% $Mydomain %>. IN TXT "<% join (" ", @record_to_explain) |h %>"</PRE>

% if (@just_a) {

<P>When a mail server sends a bounce message, it uses a null
MAIL FROM: &lt;&gt;, and a HELO address that's supposed to
be its own name.  SPF will still operate, but in "degraded
mode" by using the HELO domain name instead.  Because this
wizard can't tell which name your mail server uses in its
HELO command, it lists all possible names, so there may be
multiple lines shown below.  If you know which hostname your
mail server uses in its HELO command, you should pick out
the appropriate entries and ignore the rest.</P>

<P>So this should also appear in DNS.  You may or may not be in
charge of the DNS for these entries; if you are, add them.</P>

<PRE>\
%    foreach my $mxhost (@just_a) {
<% $mxhost %>. IN TXT "v=spf1 a -all"
%    }
</PRE>
% }

If this wizard was useful to you,  <& SELF:paypal_donate &>

  </TD>
 </TR>
</TABLE>
<P></P>

<TABLE BORDER=0 CLASS="orangeblock">
 <TR>
  <TD>
   <H3>If you run tinydns (djbdns)</H3>

<PRE>\
'<% $Mydomain %>:<% map { s/:/\\072/g; $_ } join (" ", @record_to_explain) |h 
%>:3600
% if (@just_a) {
% foreach my $mxhost (@just_a) {
'<% $mxhost %>:v=spf1 a -all:3600
% }
% }
</PRE>

If you found this wizard helpful, <& SELF:paypal_donate &>

  </TD>
 </TR>
</TABLE>

<P>If you run Windows DNS, <A 
HREF="http://www.michaelbrumm.com/spfwindowsdns/";>further instructions</A> are 
available.</P>

<P>If your site requires more complex configuration than
this, you should read <A HREF="mechanisms.html">more about
mechanisms</A>.  You should also review the tradeoffs
involved in choosing an "all" default: see page 15 of the <A
HREF="http://spf.pobox.com/whitepaper.pdf";>white
paper</A>.</P>

<P>When you've put these records into your DNS, <A
HREF="http://www.infinitepenguins.net/SPF/register.php";>register
at the SPF registry.</A></P>

<P>You can test some pretend scenarios at one of the <A
HREF="faq.html#tools">DNS tools</A>.  MTAs that reject mail
because SPF tests failed will link to the <A
HREF="why.html">why</A> page.</P>

%# TODO: precompile into ip4 notation

%# ---------------------------------------------------------- setdomain

<%def .setdomain>
<FORM METHOD=GET ACTION="">
<TABLE BGCOLOR="#FFFFB0" BORDER=0 WIDTH="100%">
<TR>
 <&| .orangeblock, args=>"COLSPAN=2 ALIGN=CENTER" &>
      Let's set up SPF records for <& .textbox, 
name=>mydomain=>value=>$Mydomain &>
 </&>
 <&| .orangeblock, args=>"ALIGN=CENTER WIDTH=\"30%\"" &>
  <INPUT TYPE=SUBMIT VALUE="Begin">
 </&>
</TR>
</TABLE>
</FORM>
</%def>

%# ---------------------------------------------------------- record-so-far

<%def .record-so-far>
<!-- record-so-far -->
 <TR>
 <&| .orangeblock, args=>"COLSPAN=2 ALIGN=CENTER VALIGN=TOP" &>
 <% $Mydomain %>. IN TXT  <TEXTAREA NAME="record_so_far" ROWS=2 COLS=50>"<% 
$built_from_args %>"</TEXTAREA>
<!-- <% $Mydomain %>. IN TXT  <TEXTAREA NAME="record_so_far" WRAP=virtual 
ROWS=2 COLS=50>"<% $built_from_args %>"</TEXTAREA> -->
 </&>
 <&| .orangeblock, args=>"ALIGN=CENTER" &>
  <INPUT TYPE=HIDDEN NAME="use_built_from_args" VALUE="1">
  <INPUT TYPE=SUBMIT VALUE="Explain">
 </&>
 </TR>
<!-- / record-so-far -->
</%def>

%# ---------------------------------------------------------- mech-a

<%def .mech-a><TR>
  <&| .row-left &>
% if (@a == 0) {
    <% $Mydomain %> does not have an IP address.
% }
% elsif (@a == 1) {
    <% $Mydomain %>'s IP address is <% $a[0] %><% ($a_ptrdname && lc 
$a_ptrdname ne $Mydomain) ? " ($a_ptrdname)" : "" %>.
<BR>Does that server send mail from <% $Mydomain %>?
% }
% else {
    <% $Mydomain %>'s IP addresses are <% join ", ", @a %>.
<BR>Do those servers send mail from <% $Mydomain %>?
% }
  </&>

  <&| .row-mid   &><& .mechlabel, label => "a" &></&>
% if (@a) {
  <&| .row-right &><&| .yesno, name=>"a", selected => $a  &></&></&>
% } else {
  <&| .row-right &></&>
% }

</TR></%def>

%# ---------------------------------------------------------- mech-mx
<%def .mech-mx><TR>
  <&| .row-left &>
% if (keys %mxhosts == 0) {
    <% $Mydomain %> has no MX servers.
% }
% elsif (keys %mxhosts == 1) {
%   my ($mx_ips) = values(%mxhosts);
%   if ("@{[sort @$mx_ips]}" eq "@{[sort @a]}") {
    <% $Mydomain %> has no other MX servers.
    <BR>Do you want to add an explicit MX entry anyway?
    <BR>If you might add other MX servers in the future, say yes.
%   }
%   else {
    <% $Mydomain %> has one MX server, <% keys(%mxhosts) %>.
    <BR>It receives mail <I>for</I> <% $Mydomain %>.
    <BR>Does it also send mail <I>from</I> <% $Mydomain %>?
%   }
% }
% else {
    This wizard found <% scalar(keys %mxhosts) %> names for <% $Mydomain %>'s 
MX servers.
    <BR>MX servers receive mail <I>for</I> <% $Mydomain %>.
    <BR>Do they also send mail <I>from</I> <% $Mydomain %>?
% }
  </&>
  <&| .row-mid   &><& .mechlabel, label => "mx" &></&>

% if (@mx) {
  <&| .row-right &><&| .yesno, name=>"mx", selected => $mx &></&></&>
% } else {
  <&| .row-right &></&>
% }

</TR></%def>

%# ---------------------------------------------------------- mech-others
<%def .mech-others><TR>
<!-- <TR> -->
  <&| .orangeblock, args=>"ROWSPAN=2 VALIGN=TOP" &>
<P>Do any other servers send mail from <% $Mydomain %>?</P>
<P>You can describe them by giving "arguments" to the <B>a:</B>, <B>mx:</B>, 
<B>ip4:</B>, and <B>ptr:</B> mechanisms.
   To keep the wizard short we left out <B>ptr:</B> but it works the same 
way.</P>
</&>
  <&| .row-mid   &><& .mechlabel, label => "a:" &></&>
  <&| .row-right &><&| .textarea, name=>"a_colon" &><% $a_colon || 
$DEFAULT_A_COLON %></&></&>
 </TR>

 <TR>
  <&| .row-mid   &><& .mechlabel, label => "mx:" &></&>
  <&| .row-right &><&| .textarea, name=>"mx_colon" &><% $mx_colon || 
$DEFAULT_MX_COLON %></&></&>
 </TR>

 <TR>
  <&| .orangeblock, args=>"ALIGN=RIGHT" &><BR><I>IP networks can be entered 
using CIDR notation, eg. 192.0.2.0/24</I></&>
  <&| .row-mid   &><& .mechlabel, label => "ip4:" &></&>
  <&| .row-right &><&| .textarea, name=>"ip4_colon" &><% $ip4_colon || 
$DEFAULT_IP4_COLON %></&></&>
 </TR>
<!-- </TR> -->
</%def>

%# ---------------------------------------------------------- mech-ptr
<%def .mech-ptr><TR>
  <&| .row-left &>
    Do you want to just approve any host
    <BR>whose name ends in <% $Mydomain %>?
  </&>
  <&| .row-mid   &><& .mechlabel, label => "ptr" &></&>
  <&| .row-right &><&| .yesno, name=>"ptr", selected => $ptr     &></&></&>
</TR></%def>

%# ---------------------------------------------------------- mech-include
<%def .mech-include><TR>
  <&| .row-left &>
    Could mail from <% $Mydomain %> originate through
    <BR>servers belonging to some other domain?
    <BR>If you send mail through your ISP's servers, name the ISP here. <!-- 
</P> -->
  </&>
  <&| .row-mid   &><& .mechlabel, label => "include:" &></&>
  <&| .row-right &><&| .textbox, name=>"include", value=>$include || 
$DEFAULT_INCLUDE &></&></&>
</TR></%def>

%# ---------------------------------------------------------- mech-all
<%def .mech-all><TR>
  <&| .row-left &>
    Do the above lines describe all the hosts
    <BR>that send mail from <% $Mydomain %>?
  </&>
  <&| .row-mid   &><& .mechlabel, label => "~all" &></&>
  <&| .row-right &><&| .yesno, name=>"all", selected => $all  &></&></&>
</TR></%def>

%# ---------------------------------------------------------- mechlabel

<%def .mechlabel>
<%args>
$label
</%args>
<IMG ALT="[<%$label%>]" SRC="/images/label_<%$label%>.png">
</%def>

%# ---------------------------------------------------------- whitesep

<%def .whitesep>
<%args>
$args => ""
</%args>
<TR><TD CLASS="whitesep" COLSPAN=3 HEIGHT=2></TD></TR>
</%def>

%# ---------------------------------------------------------- orangeblock

<%def .orangeblock>
<%args>
$args => ""
</%args>
  <TD CLASS="orangeblock"<% $args ? " $args" : "" %>>
    <% $m->content %>
  </TD>
</%def>

%# ---------------------------------------------------------- row-left, 
row-mid, row-right

<%def .row-left>
<&| .orangeblock, args => "COLSPAN=1" &><% $m->content %></&>
</%def>

<%def .row-mid>
<&| .orangeblock, args=>"ALIGN=CENTER" &><% $m->content %></&>
</%def>

<%def .row-right>
<&| .orangeblock, args=>"ALIGN=CENTER WIDTH=\"30%\"" &><% $m->content %></&>
</%def>

%# ---------------------------------------------------------- yesno

<%def .yesno>
<%args>
$name
$selected => ""
</%args>
<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0>
  <TR><TD ALIGN=CENTER><INPUT TYPE="radio" NAME="<% $name %>" VALUE="yes"<% 
$selected eq "yes" ? " CHECKED" : "" %> onClick="update_rsf(this.form)"></TD>
      <TD ALIGN=CENTER><INPUT TYPE="radio" NAME="<% $name %>" VALUE="no" <% 
$selected eq "no"  ? " CHECKED" : "" %> onClick="update_rsf(this.form)"></TD>
  </TR>
  <TR><TD ALIGN=CENTER>yes</TD>
      <TD ALIGN=CENTER>no</TD>
  </TR>
</TABLE>
</%def>


%# ---------------------------------------------------------- textbox

<%def .textbox>
<%args>
$name
$value => ""
$onchange => "update_rsf(this.form)"
</%args>
<INPUT TYPE="text" NAME="<% $name %>" VALUE="<% $value %>" <% $onchange ? 
qq(onChange="$onchange") : "" %>>
</%def>


%# ---------------------------------------------------------- textarea

<%def .textarea>
<%args>
$name
$rows => "3"
$cols => "22"
</%args>
<TEXTAREA NAME="<% $name %>" ROWS="<% $rows %>" COLS="<% $cols %>" 
onChange="update_rsf(this.form);"><% $m->content %></TEXTAREA>
</%def>

%# ---------------------------------------------------------- comma_and



<%def comma_and>
<%args>@in</%args>
<%perl>
  if    (@in >=3) { $in[-1] = " and $in[-1]"; $m->out(join ", ", @in) }
  elsif (@in ==2) { $m->out(join " and ", @in) }
  elsif (@in ==1) { $m->out($in[0]) }
  else            {  }
</%perl>
</%def>



</td>
</tr>                   
<tr><td valign="top"><img src="images/7bot.gif" width="721" height="9" 
alt="horizontal line"></td>
</tr>
<!-- GMC2 -->
</table>
<!-- </table> -->

<%method small_panel>
<span class="txtheader">The SPF Setup Wizard</span>
</%method>


<Prev in Thread] Current Thread [Next in Thread>