*~
*.bak
.*.swp
-0*.patch
+*.patch
*.orig
*.rej
.gdb_history
spec.ps
spec.pdf
spec.txt
+spec.utf8
filter*.xml
filter.ps
filter.pdf
nicedate="$(date +"%d %b %Y")"
+if which locale >/dev/null; then
+ charset="$(locale | grep ^LC_CTYPE=)"
+else
+ charset=unknown
+fi
+
exec > "$output"
cat <<EOTEMPLATE
+. # if this file changes, the build process will rebuild everything
+. # locale's charset $charset
.macro version
${EXIM_VER}
.endmacro
notarget:; @echo "** You must specify a target, in the form x.y, where x is 'filter', 'spec',"
@echo "** or 'test', and y is 'xml', 'fo', 'ps', 'pdf', 'html', 'txt', or 'info'."
- @echo "** One other possible target is 'exim.8'".
+ @echo "** One other possible targets 'exim.8', 'spec.utf8'".
exit 1
########################################################################
-.PHONY: local_params
-local_params:
- ./GenLocalParams $@
+# .PHONY doesn't work here, because it forces a rebuild of all dependend
+# targets, always. It sets the internal timestamp of its target to
+# now().
+# But it may happen that local_params does not change
+FORCE:
+local_params: FORCE GenLocalParams
+ @set -e; \
+ trap 'rm -f $$tmp' EXIT; \
+ tmp=`mktemp`; \
+ ./GenLocalParams $$tmp; \
+ cmp -s $@ $$tmp || mv $$tmp $@
############################### FILTER #################################
MyStyle.xsl
/bin/rm -rf filter-txt.html
xmlto -x MyStyle-txt-html.xsl html-nochunks filter-txt.xml
- w3m -dump filter-txt.html | ./Tidytxt >filter.txt
+ LC_ALL=C w3m -dump filter-txt.html | ./Tidytxt >filter.txt
./SanityTestText filter.txt
# I have not found a way of making docbook2texi write its output anywhere
################################ SPEC ##################################
-spec.xml: local_params spec.xfpt
- xfpt spec.xfpt
+spec.xml: spec.xfpt local_params
+ xfpt $<
spec-pr.xml: spec.xml Pre-xml
./Pre-xml -optbreak <spec.xml >spec-pr.xml
###
###
-spec.txt: spec-txt.xml Tidytxt MyStyle-txt-html.xsl MyStyle-html.xsl \
- MyStyle.xsl
- /bin/rm -rf spec-txt.html
- xmlto -x MyStyle-txt-html.xsl html-nochunks spec-txt.xml
- w3m -dump spec-txt.html | ./Tidytxt >spec.txt
+spec-txt.html: spec-txt.xml \
+ MyStyle-txt-html.xsl MyStyle-html.xsl MyStyle.xsl
+ xmlto -x MyStyle-txt-html.xsl html-nochunks $<
+
+spec.utf8: spec-txt.html Tidytxt
+ @grep -iq 'LC_CTYPE=.*utf-\?8' local_params || { \
+ echo 'your current locale does not support UTF-8' >&2; \
+ false; }
+ w3m -dump $< | ./Tidytxt -utf8 >$@
+
+spec.txt: spec-txt.html Tidytxt
+ LC_ALL=C w3m -dump $< | ./Tidytxt >$@
./SanityTestText spec.txt
+
# I have not found a way of making docbook2texi write its output anywhere
# other than the file name that it makes up. The --to-stdout option does not
# work.
#! /usr/bin/perl
+use strict;
+use warnings;
+use Getopt::Long;
+
+
+# For now we can't rely on a perl >= 5.14 on
+# the build sites, thus we throw away all unicode
+# awarness and do the matching byte by byte
+binmode STDIN;
+binmode STDOUT;
+
+GetOptions(
+ 'u|utf8!' => \my $want_utf8, # do not replace unicode characters
+) or die "Usage: $0 [-u|--utf8]\n";
+
# Script to tidy up the output of w3m when it makes a text file. First we
# convert sequences of blank lines into a single blank line, to get everything
# uniform. Then we go through and insert blank lines before chapter and
# (2) It uses U+25CF as its bullet character.
# (3) It inserts a whole slew of "box drawing" characters round the heading.
-@lines = <>;
+my @lines = <>;
+my $lastwasblank = 0;
-$lastwasblank = 0;
-foreach $line (@lines)
+foreach my $line (@lines)
{
# (1) non-break space -> normal space
$line =~ s/\x{c2}\x{a0}/ /g;
- # (2) bullet -> asterisk
- $line =~ s/\x{e2}\x{97}\x{8f}/*/g;
- $line =~ s/\x{e2}\x{80}\x{a2}/*/g; # OpenSUSE
- $line =~ s/\x{e2}\x{96}\x{a1}/*/g; # OpenSUSE
- # (3a) horizontal box drawing -> hyphen
- $line =~ s/\x{e2}\x{94}[\x{80}\x{81}\x{84}\x{85}\x{88}\x{89}]/-/g;
- $line =~ s/\x{e2}\x{95}[\x{8c}\x{8d}\x{90}]/-/g;
- $line =~ s/\x{e2}\x{95}[\x{b4}\x{b6}\x{b8}\x{ba}\x{bc}\x{be}]/-/g;
- # (3b) vertical box drawing -> bar
- $line =~ s/\x{e2}\x{94}[\x{82}\x{83}\x{86}\x{87}\x{8a}\x{8b}]/|/g;
- $line =~ s/\x{e2}\x{95}[\x{8e}\x{8f}\x{91}]/|/g;
- $line =~ s/\x{e2}\x{95}[\x{b5}\x{b7}\x{b9}\x{bb}\x{bd}\x{bf}]/|/g;
- # (3c) corner box drawing -> plus
- $line =~ s/\x{e2}\x{94}[\x{8c}-\x{bf}]/+/g;
- $line =~ s/\x{e2}\x{95}[\x{80}-\x{8b}\x{92}-\x{b0}]/+/g;
- # other
- $line =~ s/\x{e2}\x{95}\x{b1}/\//g;
- $line =~ s/\x{e2}\x{95}\x{b2}/\\/g;
- $line =~ s/\x{e2}\x{95}\x{b3}/X/g;
+
+ unless ($want_utf8)
+ {
+ # (2) bullet -> asterisk
+ $line =~ s/\x{e2}\x{97}\x{8f}/*/g;
+ $line =~ s/\x{e2}\x{80}\x{a2}/*/g; # OpenSUSE
+ $line =~ s/\x{e2}\x{96}\x{a1}/*/g; # OpenSUSE
+ # (3a) horizontal box drawing -> hyphen
+ $line =~ s/\x{e2}\x{94}[\x{80}\x{81}\x{84}\x{85}\x{88}\x{89}]/-/g;
+ $line =~ s/\x{e2}\x{95}[\x{8c}\x{8d}\x{90}]/-/g;
+ $line =~ s/\x{e2}\x{95}[\x{b4}\x{b6}\x{b8}\x{ba}\x{bc}\x{be}]/-/g;
+ # (3b) vertical box drawing -> bar
+ $line =~ s/\x{e2}\x{94}[\x{82}\x{83}\x{86}\x{87}\x{8a}\x{8b}]/|/g;
+ $line =~ s/\x{e2}\x{95}[\x{8e}\x{8f}\x{91}]/|/g;
+ $line =~ s/\x{e2}\x{95}[\x{b5}\x{b7}\x{b9}\x{bb}\x{bd}\x{bf}]/|/g;
+ # (3c) corner box drawing -> plus
+ $line =~ s/\x{e2}\x{94}[\x{8c}-\x{bf}]/+/g;
+ $line =~ s/\x{e2}\x{95}[\x{80}-\x{8b}\x{92}-\x{b0}]/+/g;
+ # other
+ $line =~ s/\x{e2}\x{95}\x{b1}/\//g;
+ $line =~ s/\x{e2}\x{95}\x{b2}/\\/g;
+ $line =~ s/\x{e2}\x{95}\x{b3}/X/g;
+ }
# w3m rendering issue apparently only seen by pdp
# affects section numbers after the ToC, some info on spool-file -lines, etc
# Find start of TOC, uppercasing its title
+my $i = 0;
for ($i = 0; $i < scalar @lines; $i++)
{
$lines[$i] = "TABLE OF CONTENTS\n" if $lines[$i] =~ /^Table of Contents/;
# looking for preceding and following blank lines, and then matching against
# the numbers.
-$chapter = 0;
+my $chapter = 0;
+my $section;
for (; $i < scalar @lines; $i++)
{
next if $lines[$i-1] !~ /^$/ || $lines[$i+1] !~ /^$/;
. Update the Copyright year (only) when changing content.
. /////////////////////////////////////////////////////////////////////////////
-.set previousversion "4.83"
+.set previousversion "4.86"
.include ./local_params
.set ACL "access control lists (ACLs)"
.set I " "
.macro copyyear
-2014
+2015
.endmacro
. /////////////////////////////////////////////////////////////////////////////
waiting for it by the time it recovers, and sending them in a single SMTP
connection is clearly beneficial. Whenever a delivery to a remote host is
deferred,
-.cindex "hints database"
+.cindex "hints database" "deferred deliveries"
Exim makes a note in its hints database, and whenever a successful
SMTP delivery has happened, it looks to see if any other messages are waiting
for the same host. If any are found, they are sent over the same SMTP
in the ASCII character set, and to label them as being in a particular
character set. When Exim is inspecting header lines by means of the &%$h_%&
mechanism, it decodes them, and translates them into a specified character set
-(default ISO-8859-1). The translation is possible only if the operating system
+(default is set at build time). The translation is possible only if the operating system
supports the &[iconv()]& function.
However, some of the operating systems that supply &[iconv()]& do not support
defined. AAAA records (analogous to A records for IPv4) are in use, and are
currently seen as the mainstream. Another record type called A6 was proposed
as better than AAAA because it had more flexibility. However, it was felt to be
-over-complex, and its status was reduced to &"experimental"&. It is not known
-if anyone is actually using A6 records. Exim has support for A6 records, but
-this is included only if you set &`SUPPORT_A6=YES`& in &_Local/Makefile_&. The
-support has not been tested for some time.
+over-complex, and its status was reduced to &"experimental"&.
+Exim used to
+have a compile option for including A6 record support but this has now been
+withdrawn.
.cindex "symbolic link" "to source files"
Symbolic links to relevant source files are installed in the build directory.
-&*Warning*&: The &%-j%& (parallel) flag must not be used with &'make'&; the
-building process fails if it is set.
-
If this is the first time &'make'& has been run, it calls a script that builds
a make file inside the build directory, using the configuration files from the
&_Local_& directory. The new make file is then passed to another instance of
.code
mysql_servers = <value not displayable>
.endd
-If &%configure_file%& is given as an argument, the name of the run time
-configuration file is output.
+If &%config%& is given as an argument, the config is
+output, as it was parsed, any include file resolved, any comment removed.
+
+If &%config_file%& is given as an argument, the name of the run time
+configuration file is output. (&%configure_file%& works too, for
+backward compatibility.)
If a list of configuration files was supplied, the value that is output here
is the name of the file that was actually used.
exim '-D ABC = something' ...
.endd
&%-D%& may be repeated up to 10 times on a command line.
+.new
+Only macro names up to 22 letters long can be set.
+.wen
.vitem &%-d%&<&'debug&~options'&>
Exim's configuration file is divided into a number of different parts. General
option settings must always appear at the start of the file. The other parts
are all optional, and may appear in any order. Each part other than the first
-is introduced by the word &"begin"& followed by the name of the part. The
-optional parts are:
+is introduced by the word &"begin"& followed by at least one literal
+space, and the name of the part. The optional parts are:
.ilist
&'ACL'&: Access control lists for controlling incoming SMTP mail (see chapter
message_size_limit = 100M
.endif
.endd
-sets a message size limit of 50M if the macro &`AAA`& is defined, and 100M
+sets a message size limit of 50M if the macro &`AAA`& is defined
+(or &`A`& or &`AA`&), and 100M
otherwise. If there is more than one macro named on the line, the condition
is true if any of them are defined. That is, it is an &"or"& condition. To
obtain an &"and"& condition, you need to use nested &`.ifdef`&s.
colon in the example above is necessary. If it were not there, the list would
be interpreted as the two items 127.0.0.1:: and 1.
-.section "Changing list separators" "SECID53"
+.section "Changing list separators" "SECTlistsepchange"
.cindex "list separator" "changing"
.cindex "IPv6" "addresses in lists"
Doubling colons in IPv6 addresses is an unwelcome chore, so a mechanism was
If you have hosts for which you trust RFC1413 and need this
information, you can change this.
-This line enables an efficiency SMTP option. It is negociated by clients
+This line enables an efficiency SMTP option. It is negotiated by clients
and not expected to cause problems but can be disabled if needed.
.code
prdr_enable = true
show how you can specify hosts that are permitted to send unqualified sender
and recipient addresses, respectively.
+The &%log_selector%& option is used to increase the detail of logging
+over the default:
+.code
+log_selector = +smtp_protocol_error +smtp_syntax_error \
+ +tls_certificate_verified
+.endd
+
The &%percent_hack_domains%& option is also commented out:
.code
# percent_hack_domains =
.endd
This transport is used for handling deliveries to pipes that are generated by
redirection (aliasing or users' &_.forward_& files). The &%return_output%&
-option specifies that any output generated by the pipe is to be returned to the
-sender.
+option specifies that any output on stdout or stderr generated by the pipe is to
+be returned to the sender.
.code
address_file:
driver = appendfile
lookup. Lookups of this type are conditional expansion items. Different results
can be defined for the cases of lookup success and failure. See chapter
&<<CHAPexpand>>&, where string expansions are described in detail.
+The key for the lookup is specified as part of the string expansion.
.next
Lists of domains, hosts, and email addresses can contain lookup requests as a
way of avoiding excessively long linear lists. In this case, the data that is
returned by the lookup is often (but not always) discarded; whether the lookup
succeeds or fails is what really counts. These kinds of list are described in
chapter &<<CHAPdomhosaddlists>>&.
+The key for the lookup is given by the context in which the list is expanded.
.endlist
String expansions, lists, and lookups interact with each other in such a way
&(pgsql)&: The format of the query is an SQL statement that is passed to a
PostgreSQL database. See section &<<SECTsql>>&.
+.next
+.new
+.cindex "Redis lookup type"
+.cindex lookup Redis
+&(redis)&: The format of the query is an SQL statement that is passed to a
+Redis database. See section &<<SECTsql>>&.
+.wen
+
.next
.cindex "sqlite lookup type"
.cindex "lookup" "sqlite"
&`fail`& keyword causes a &'forced expansion failure'& &-- see section
&<<SECTforexpfai>>& for an explanation of what this means.
-The supported DNS record types are A, CNAME, MX, NS, PTR, SPF, SRV, TLSA and TXT,
-and, when Exim is compiled with IPv6 support, AAAA (and A6 if that is also
-configured). If no type is given, TXT is assumed. When the type is PTR,
-the data can be an IP address, written as normal; inversion and the addition of
-&%in-addr.arpa%& or &%ip6.arpa%& happens automatically. For example:
-.code
-${lookup dnsdb{ptr=192.168.4.5}{$value}fail}
-.endd
-If the data for a PTR record is not a syntactically valid IP address, it is not
-altered and nothing is added.
+The supported DNS record types are A, CNAME, MX, NS, PTR, SOA, SPF, SRV, TLSA
+and TXT, and, when Exim is compiled with IPv6 support, AAAA.
+If no type is given, TXT is assumed.
-For any record type, if multiple records are found (or, for A6 lookups, if a
-single record leads to multiple addresses), the data is returned as a
+For any record type, if multiple records are found, the data is returned as a
concatenation, with newline as the default separator. The order, of course,
depends on the DNS resolver. You can specify a different separator character
between multiple records by putting a right angle-bracket followed immediately
.endd
It is permitted to specify a space as the separator character. Further
white space is ignored.
+For lookup types that return multiple fields per record,
+an alternate field separator can be specified using a comma after the main
+separator character, followed immediately by the field separator.
+
+.cindex "PTR record" "in &(dnsdb)& lookup"
+When the type is PTR,
+the data can be an IP address, written as normal; inversion and the addition of
+&%in-addr.arpa%& or &%ip6.arpa%& happens automatically. For example:
+.code
+${lookup dnsdb{ptr=192.168.4.5}{$value}fail}
+.endd
+If the data for a PTR record is not a syntactically valid IP address, it is not
+altered and nothing is added.
.cindex "MX record" "in &(dnsdb)& lookup"
.cindex "SRV record" "in &(dnsdb)& lookup"
For an MX lookup, both the preference value and the host name are returned for
each record, separated by a space. For an SRV lookup, the priority, weight,
port, and host name are returned for each record, separated by spaces.
-.new
-An alternate field separator can be specified using a comma after the main
-separator character, followed immediately by the field separator.
-.wen
+The field separator can be modified as above.
.cindex "TXT record" "in &(dnsdb)& lookup"
.cindex "SPF record" "in &(dnsdb)& lookup"
For TXT records with multiple items of data, only the first item is returned,
-unless a separator for them is specified using a comma after the separator
-character followed immediately by the TXT record item separator. To concatenate
-items without a separator, use a semicolon instead. For SPF records the
+unless a field separator is specified.
+To concatenate items without a separator, use a semicolon instead.
+For SPF records the
default behaviour is to concatenate multiple items without using a separator.
.code
${lookup dnsdb{>\n,: txt=a.b.example}}
It is permitted to specify a space as the separator character. Further
white space is ignored.
+.cindex "SOA record" "in &(dnsdb)& lookup"
+For an SOA lookup, while no result is obtained the lookup is redone with
+successively more leading components dropped from the given domain.
+Only the primary-nameserver field is returned unless a field separator is
+specified.
+.code
+${lookup dnsdb{>:,; soa=a.b.example.com}}
+.endd
+
+.section "Dnsdb lookup modifiers" "SECTdnsdb_mod"
+.cindex "dnsdb modifiers"
+.cindex "modifiers" "dnsdb"
+.cindex "options" "dnsdb"
+Modifiers for &(dnsdb)& lookups are given by optional keywords,
+each followed by a comma,
+that may appear before the record type.
+
+The &(dnsdb)& lookup fails only if all the DNS lookups fail. If there is a
+temporary DNS error for any of them, the behaviour is controlled by
+a defer-option modifier.
+The possible keywords are
+&"defer_strict"&, &"defer_never"&, and &"defer_lax"&.
+With &"strict"& behaviour, any temporary DNS error causes the
+whole lookup to defer. With &"never"& behaviour, a temporary DNS error is
+ignored, and the behaviour is as if the DNS lookup failed to find anything.
+With &"lax"& behaviour, all the queries are attempted, but a temporary DNS
+error causes the whole lookup to defer only if none of the other lookups
+succeed. The default is &"lax"&, so the following lookups are equivalent:
+.code
+${lookup dnsdb{defer_lax,a=one.host.com:two.host.com}}
+${lookup dnsdb{a=one.host.com:two.host.com}}
+.endd
+Thus, in the default case, as long as at least one of the DNS lookups
+yields some data, the lookup succeeds.
+
+.cindex "DNSSEC" "dns lookup"
+Use of &(DNSSEC)& is controlled by a dnssec modifier.
+The possible keywords are
+&"dnssec_strict"&, &"dnssec_lax"&, and &"dnssec_never"&.
+With &"strict"& or &"lax"& DNSSEC information is requested
+with the lookup.
+With &"strict"& a response from the DNS resolver that
+is not labelled as authenticated data
+is treated as equivalent to a temporary DNS error.
+The default is &"never"&.
+
+See also the &$lookup_dnssec_authenticated$& variable.
+
+.cindex timeout "dns lookup"
+.cindex "DNS" timeout
+Timeout for the dnsdb lookup can be controlled by a retrans modifier.
+The form is &"retrans_VAL"& where VAL is an Exim time specification
+(e.g. &"5s"&).
+The default value is set by the main configuration option &%dns_retrans%&.
+
+Retries for the dnsdb lookup can be controlled by a retry modifier.
+The form if &"retry_VAL"& where VAL is an integer.
+The default count is set by the main configuration option &%dns_retry%&.
+
+.new
+.cindex cacheing "of dns lookup"
+.cindex TTL "of dns lookup"
+.cindex DNS TTL
+Dnsdb lookup results are cached within a single process (and its children).
+The cache entry lifetime is limited to the smallest time-to-live (TTL)
+value of the set of returned DNS records.
+.wen
+
+
.section "Pseudo dnsdb record types" "SECID66"
.cindex "MX record" "in &(dnsdb)& lookup"
By default, both the preference value and the host name are returned for
authorization required but absent, or &"?"& for unknown.
.cindex "A+" "in &(dnsdb)& lookup"
-The pseudo-type A+ performs an A6 lookup (if configured) followed by an AAAA
+The pseudo-type A+ performs an AAAA
and then an A lookup. All results are returned; defer processing
(see below) is handled separately for each lookup. Example:
.code
in the same way that multiple DNS records for a single item are handled. A
different separator can be specified, as described above.
-Modifiers for &(dnsdb)& lookups are givien by optional keywords,
-each followed by a comma,
-that may appear before the record type.
-
-The &(dnsdb)& lookup fails only if all the DNS lookups fail. If there is a
-temporary DNS error for any of them, the behaviour is controlled by
-a defer-option modifier.
-The possible keywords are
-&"defer_strict"&, &"defer_never"&, and &"defer_lax"&.
-With &"strict"& behaviour, any temporary DNS error causes the
-whole lookup to defer. With &"never"& behaviour, a temporary DNS error is
-ignored, and the behaviour is as if the DNS lookup failed to find anything.
-With &"lax"& behaviour, all the queries are attempted, but a temporary DNS
-error causes the whole lookup to defer only if none of the other lookups
-succeed. The default is &"lax"&, so the following lookups are equivalent:
-.code
-${lookup dnsdb{defer_lax,a=one.host.com:two.host.com}}
-${lookup dnsdb{a=one.host.com:two.host.com}}
-.endd
-Thus, in the default case, as long as at least one of the DNS lookups
-yields some data, the lookup succeeds.
-
-.cindex "DNSSEC" "dns lookup"
-Use of &(DNSSEC)& is controlled by a dnssec modifier.
-The possible keywords are
-&"dnssec_strict"&, &"dnssec_lax"&, and &"dnssec_never"&.
-With &"strict"& or &"lax"& DNSSEC information is requested
-with the lookup.
-With &"strict"& a response from the DNS resolver that
-is not labelled as authenticated data
-is treated as equivalent to a temporary DNS error.
-The default is &"never"&.
-
-See also the &$lookup_dnssec_authenticated$& variable.
-
must be &"follow"& (the default) or &"nofollow"&. The latter stops the LDAP
library from trying to follow referrals issued by the LDAP server.
+.cindex LDAP timeout
+.cindex timeout "LDAP lookup"
The name CONNECT is an obsolete name for NETTIME, retained for
backwards compatibility. This timeout (specified as a number of seconds) is
enforced from the client end for operations that can be carried out over a
set a server-side limit on the time taken to complete a search.
The SERVERS parameter allows you to specify an alternate list of ldap servers
-to use for an individual lookup. The global ldap_servers option provides a
+to use for an individual lookup. The global &%ldap_default_servers%& option provides a
default list of ldap servers, and a single lookup can specify a single ldap
server to use. But when you need to do a lookup with a list of servers that is
different than the default list (maybe different order, maybe a completely
The &(ldapdn)& lookup type returns the Distinguished Name from a single entry
as a sequence of values, for example
.code
-cn=manager, o=University of Cambridge, c=UK
+cn=manager,o=University of Cambridge,c=UK
.endd
The &(ldap)& lookup type generates an error if more than one entry matches the
search filter, whereas &(ldapm)& permits this case, and inserts a newline in
In the common case where you specify a single attribute in your LDAP query, the
result is not quoted, and does not contain the attribute name. If the attribute
-has multiple values, they are separated by commas.
+has multiple values, they are separated by commas. Any comma that is
+part of an attribute's value is doubled.
If you specify multiple attributes, the result contains space-separated, quoted
strings, each preceded by the attribute name and an equals sign. Within the
quotes, the quote character, backslash, and newline are escaped with
backslashes, and commas are used to separate multiple values for the attribute.
-.new
Any commas in attribute values are doubled
(permitting treatment of the values as a comma-separated list).
-.wen
Apart from the escaping, the string within quotes takes the same form as the
output when a single attribute is requested. Specifying no attributes is the
same as specifying all of an entry's attributes.
-.new
Here are some examples of the output format. The first line of each pair is an
LDAP query, and the second is the data that is returned. The attribute called
&%attr1%& has two values, one of them with an embedded comma, whereas
-&%attr2%& has only one value:
+&%attr2%& has only one value. Both attributes are derived from &%attr%&
+(they have SUP &%attr%& in their schema definitions).
+
.code
ldap:///o=base?attr1?sub?(uid=fred)
value1.1,value1,,2
ldap:///o=base?attr2?sub?(uid=fred)
value two
+ldap:///o=base?attr?sub?(uid=fred)
+value1.1,value1,,2,value two
+
ldap:///o=base?attr1,attr2?sub?(uid=fred)
attr1="value1.1,value1,,2" attr2="value two"
ldap:///o=base??sub?(uid=fred)
objectClass="top" attr1="value1.1,value1,,2" attr2="value two"
.endd
-.wen
You can
make use of Exim's &%-be%& option to run expansion tests and thereby check the
results of LDAP lookups.
The &%extract%& operator in string expansions can be used to pick out
individual fields from data that consists of &'key'&=&'value'& pairs.
-.new
The &%listextract%& operator should be used to pick out individual values
of attributes, even when only a single value is expected.
The doubling of embedded commas allows you to use the returned data as a
comma separated list (using the "<," syntax for changing the input list separator).
-.wen
.cindex "lookup" "Oracle"
.cindex "InterBase lookup type"
.cindex "lookup" "InterBase"
-Exim can support lookups in InterBase, MySQL, Oracle, PostgreSQL, and SQLite
+.cindex "Redis lookup type"
+.cindex lookup Redis
+Exim can support lookups in InterBase, MySQL, Oracle, PostgreSQL, Redis,
+and SQLite
databases. Queries for these databases contain SQL statements, so an example
might be
.code
with a newline between the data for each row.
-.section "More about MySQL, PostgreSQL, Oracle, and InterBase" "SECID72"
+.section "More about MySQL, PostgreSQL, Oracle, InterBase, and Redis" "SECID72"
.cindex "MySQL" "lookup type"
.cindex "PostgreSQL lookup type"
.cindex "lookup" "MySQL"
.cindex "lookup" "Oracle"
.cindex "InterBase lookup type"
.cindex "lookup" "InterBase"
-If any MySQL, PostgreSQL, Oracle, or InterBase lookups are used, the
-&%mysql_servers%&, &%pgsql_servers%&, &%oracle_servers%&, or &%ibase_servers%&
+.cindex "Redis lookup type"
+.cindex lookup Redis
+If any MySQL, PostgreSQL, Oracle, InterBase or Redis lookups are used, the
+&%mysql_servers%&, &%pgsql_servers%&, &%oracle_servers%&, &%ibase_servers%&,
+or &%redis_servers%&
option (as appropriate) must be set to a colon-separated list of server
information.
-(For MySQL and PostgreSQL only, the global option need not be set if all
+(For MySQL and PostgreSQL, the global option need not be set if all
queries contain their own server information &-- see section
-&<<SECTspeserque>>&.) Each item in the list is a slash-separated list of four
+&<<SECTspeserque>>&.)
+For all but Redis
+each item in the list is a slash-separated list of four
items: host name, database name, user name, and password. In the case of
Oracle, the host name field is used for the &"service name"&, and the database
name field is not used and should be empty. For example:
found, but that is still a successful query. In other words, the list of
servers provides a backup facility, not a list of different places to look.
+.new
+For Redis the global option need not be specified if all queries contain their
+own server information &-- see section &<<SECTspeserque>>&.
+If specified, the option must be set to a colon-separated list of server
+information.
+Each item in the list is a slash-separated list of three items:
+host, database number, and password.
+.olist
+The host is required and may be either an IPv4 address and optional
+port number (separated by a colon, which needs doubling due to the
+higher-level list), or a Unix socket pathname enclosed in parentheses
+.next
+The database number is optional; if present that number is selected in the backend
+.next
+The password is optional; if present it is used to authenticate to the backend
+.endlist
+.wen
+
+.new
The &%quote_mysql%&, &%quote_pgsql%&, and &%quote_oracle%& expansion operators
convert newline, tab, carriage return, and backspace to \n, \t, \r, and \b
respectively, and the characters single-quote, double-quote, and backslash
-itself are escaped with backslashes. The &%quote_pgsql%& expansion operator, in
-addition, escapes the percent and underscore characters. This cannot be done
-for MySQL because these escapes are not recognized in contexts where these
-characters are not special.
+itself are escaped with backslashes.
+
+The &%quote_redis%& expansion operator
+escapes whitespace and backslash characters with a backslash.
+.wen
.section "Specifying the server in the query" "SECTspeserque"
-For MySQL and PostgreSQL lookups (but not currently for Oracle and InterBase),
+For MySQL, PostgreSQL and Redis lookups (but not currently for Oracle and InterBase),
it is possible to specify a list of servers with an individual query. This is
done by starting the query with
.display
.section "Special MySQL features" "SECID73"
For MySQL, an empty host name or the use of &"localhost"& in &%mysql_servers%&
causes a connection to the server on the local host by means of a Unix domain
-socket. An alternate socket can be specified in parentheses. The full syntax of
-each item in &%mysql_servers%& is:
+socket. An alternate socket can be specified in parentheses.
+.new
+An option group name for MySQL option files can be specified in square brackets;
+the default value is &"exim"&.
+.wen
+The full syntax of each item in &%mysql_servers%& is:
.display
-<&'hostname'&>::<&'port'&>(<&'socket name'&>)/<&'database'&>/&&&
- <&'user'&>/<&'password'&>
+<&'hostname'&>::<&'port'&>(<&'socket name'&>)[<&'option group'&>]/&&&
+ <&'database'&>/<&'user'&>/<&'password'&>
.endd
-Any of the three sub-parts of the first field can be omitted. For normal use on
+Any of the four sub-parts of the first field can be omitted. For normal use on
the local host it can be left blank or set to just &"localhost"&.
No database need be supplied &-- but if it is absent here, it must be given in
The only character affected by the &%quote_sqlite%& operator is a single
quote, which it doubles.
+.cindex timeout SQLite
+.cindex sqlite "lookup timeout"
The SQLite library handles multiple simultaneous accesses to the database
internally. Multiple readers are permitted, but only one process can
update at once. Attempts to access the database while it is being updated
different types of pattern for each case are described, but first we cover some
general facilities that apply to all four kinds of list.
+Note that other parts of Exim use a &'string list'& which does not
+support all the complexity available in
+domain, host, address and local part lists.
+
.section "Expansion of lists" "SECID75"
.cindex "&`+ignore_defer`&"
A temporary DNS lookup failure normally causes a defer action (except when
&%dns_again_means_nonexist%& converts it into a permanent error). However,
-host lists can include &`+ignore_defer`& and &`+include_defer`&, analagous to
+host lists can include &`+ignore_defer`& and &`+include_defer`&, analogous to
&`+ignore_unknown`& and &`+include_unknown`&, as described in the previous
section. These options should be used with care, probably only in non-critical
host lists such as whitelists.
.cindex "&%certextract%&" "certificate fields"
.cindex "certificate" "extracting fields"
The <&'certificate'&> must be a variable of type certificate.
-The field name is expanded and used to retrive the relevant field from
+The field name is expanded and used to retrieve the relevant field from
the certificate. Supported fields are:
.display
&`version `&
output a Distinguished Name string which is
not quite
parseable by Exim as a comma-separated tagged list
-(the exceptions being elements containin commas).
+(the exceptions being elements containing commas).
RDN elements of a single type may be selected by
a modifier of the type label; if so the expansion
result is a list (newline-separated by default).
-The separator may be changed by another modifer of
+The separator may be changed by another modifier of
a right angle-bracket followed immediately by the new separator.
Recognised RDN type labels include "CN", "O", "OU" and "DC".
prefix each list element with a type string and an equals sign.
Elements of only one type may be selected by a modifier
which is one of "dns", "uri" or "mail";
-if so the elenment tags are omitted.
+if so the element tags are omitted.
If not otherwise noted field values are presented in human-readable form.
you need to add &%-shared%& to the gcc command. Also, in the Exim build-time
configuration, you must add &%-export-dynamic%& to EXTRALIBS.
+
+.vitem "&*${env{*&<&'key'&>&*}{*&<&'string1'&>&*}{*&<&'string2'&>&*}}*&"
+.cindex "expansion" "extracting value from environment"
+.cindex "environment" "value from"
+The key is first expanded separately, and leading and trailing white space
+removed.
+This is then searched for as a name in the environment.
+If a variable is found then its value is placed in &$value$&
+and <&'string1'&> is expanded, otherwise <&'string2'&> is expanded.
+
+Instead of {<&'string2'&>} the word &"fail"& (not in curly brackets) can
+appear, for example:
+.code
+${env{USER}{$value} fail }
+.endd
+This forces an expansion failure (see section &<<SECTforexpfai>>&);
+{<&'string1'&>} must be present for &"fail"& to be recognized.
+
+If {<&'string2'&>} is omitted an empty string is substituted on
+search failure.
+If {<&'string1'&>} is omitted the search result is substituted on
+search success.
+
+
.vitem "&*${extract{*&<&'key'&>&*}{*&<&'string1'&>&*}{*&<&'string2'&>&*}&&&
{*&<&'string3'&>&*}}*&"
.cindex "expansion" "extracting substrings by key"
Upper case and lower case letters are synonymous in header names. If the
following character is white space, the terminating colon may be omitted, but
this is not recommended, because you may then forget it when it is needed. When
-white space terminates the header name, it is included in the expanded string.
-If the message does not contain the given header, the expansion item is
-replaced by an empty string. (See the &%def%& condition in section
-&<<SECTexpcond>>& for a means of testing for the existence of a header.)
+white space terminates the header name, this white space is included in the
+expanded string. If the message does not contain the given header, the
+expansion item is replaced by an empty string. (See the &%def%& condition in
+section &<<SECTexpcond>>& for a means of testing for the existence of a
+header.)
If there is more than one header with the same name, they are all concatenated
to form the substitution string, up to a maximum length of 64K. Unless
condition = ${if >{$acl_m4}{3}}
.endd
+
+
+.new
+.vitem &*${imapfolder{*&<&'foldername'&>&*}}*&
+.cindex expansion "imap folder"
+.cindex "&%imapfolder%& expansion item"
+This item converts a (possibly multilevel, or with non-ASCII characters)
+folder specification to a Maildir name for filesystem use.
+For information on internationalisation support see &<<SECTi18nMDA>>&.
+.wen
+
+
+
.vitem &*${length{*&<&'string1'&>&*}{*&<&'string2'&>&*}}*&
.cindex "expansion" "string truncation"
.cindex "&%length%& expansion item"
.code
${listextract{-3}{<, x,42,99,& Mailer,,/bin/bash}{result: $value}}
.endd
-yields &"result: 99"&.
+yields &"result: 42"&.
If {<&'string3'&>} is omitted, an empty string is used for string3.
If {<&'string2'&>} is also omitted, the value that was
.cindex "expansion" "inserting from a socket"
.cindex "socket, use of in expansion"
.cindex "&%readsocket%& expansion item"
-This item inserts data from a Unix domain or Internet socket into the expanded
+This item inserts data from a Unix domain or TCP socket into the expanded
string. The minimal way of using it uses just two arguments, as in these
examples:
.code
-.new
.vitem &*${sort{*&<&'string'&>&*}{*&<&'comparator'&>&*}{*&<&'extractor'&>&*}}*&
-.cindex sorting a list
+.cindex sorting "a list"
.cindex list sorting
+.cindex expansion "list sorting"
After expansion, <&'string'&> is interpreted as a list, colon-separated by
default, but the separator can be changed in the usual way.
The <&'comparator'&> argument is interpreted as the operator
.endd
sorts a list of numbers, and
.code
-${sort {$lookup dnsdb{>:,,mx=example.com}} {<} {${listextract{1}{<,$item}}}}
+${sort {${lookup dnsdb{>:,,mx=example.com}}} {<} {${listextract{1}{<,$item}}}}
.endd
will sort an MX lookup into priority order.
-.wen
.vitem &*${substr{*&<&'string1'&>&*}{*&<&'string2'&>&*}{*&<&'string3'&>&*}}*&
To clarify "list of addresses in RFC 2822 format" mentioned above, Exim follows
a strict interpretation of header line formatting. Exim parses the bare,
unquoted portion of an email address and if it finds a comma, treats it as an
-email address seperator. For the example header line:
+email address separator. For the example header line:
.code
From: =?iso-8859-2?Q?Last=2C_First?= <user@example.com>
.endd
byte value 127 is converted to &`\x7f`&.
+.new
+.vitem &*${ipv6denorm:*&<&'string'&>&*}*&
+.cindex "&%ipv6denorm%& expansion item"
+.cindex "IP address" normalisation
+This expands an IPv6 address to a full eight-element colon-separated set
+of hex digits including leading zeroes.
+A trailing ipv4-style dotted-decimal set is converted to hex.
+Pure IPv4 addresses are converted to IPv4-mapped IPv6.
+
+.vitem &*${ipv6norm:*&<&'string'&>&*}*&
+.cindex "&%ipv6norm%& expansion item"
+.cindex "IP address" normalisation
+.cindex "IP address" "canonical form"
+This converts an IPv6 address to canonical form.
+Leading zeroes of groups are omitted, and the longest
+set of zero-valued groups is replaced with a double colon.
+A trailing ipv4-style dotted-decimal set is converted to hex.
+Pure IPv4 addresses are converted to IPv4-mapped IPv6.
+.wen
+
+
.vitem &*${lc:*&<&'string'&>&*}*&
.cindex "case forcing in strings"
.cindex "string" "case forcing"
.vitem &*${md5:*&<&'string'&>&*}*&
.cindex "MD5 hash"
.cindex "expansion" "MD5 hash"
-.cindex "certificate fingerprint"
+.cindex certificate fingerprint
.cindex "&%md5%& expansion item"
The &%md5%& operator computes the MD5 hash value of the string, and returns it
as a 32-digit hexadecimal number, in which any letters are in lower case.
+If the string is a single variable of type certificate,
+returns the MD5 hash fingerprint of the certificate.
+
.vitem &*${nhash_*&<&'n'&>&*_*&<&'m'&>&*:*&<&'string'&>&*}*&
.cindex "expansion" "numeric hash"
.vitem &*${reverse_ip:*&<&'ipaddr'&>&*}*&
.cindex "expansion" "IP address"
This operator reverses an IP address; for IPv4 addresses, the result is in
-dotted-quad decimal form, while for IPv6 addreses the result is in
+dotted-quad decimal form, while for IPv6 addresses the result is in
dotted-nibble hexadecimal form. In both cases, this is the "natural" form
for DNS. For example,
.code
This operator encodes text according to the rules of RFC 2047. This is an
encoding that is used in header lines to encode non-ASCII characters. It is
assumed that the input string is in the encoding specified by the
-&%headers_charset%& option, which defaults to ISO-8859-1. If the string
+&%headers_charset%& option, which gets its default at build time. If the string
contains only characters in the range 33&--126, and no instances of the
characters
.code
.vitem &*${sha1:*&<&'string'&>&*}*&
.cindex "SHA-1 hash"
.cindex "expansion" "SHA-1 hashing"
-.cindex "certificate fingerprint"
+.cindex certificate fingerprint
.cindex "&%sha2%& expansion item"
The &%sha1%& operator computes the SHA-1 hash value of the string, and returns
it as a 40-digit hexadecimal number, in which any letters are in upper case.
+If the string is a single variable of type certificate,
+returns the SHA-1 hash fingerprint of the certificate.
+
.vitem &*${sha256:*&<&'certificate'&>&*}*&
.cindex "SHA-256 hash"
-.cindex "certificate fingerprint"
+.cindex certificate fingerprint
.cindex "expansion" "SHA-256 hashing"
.cindex "&%sha256%& expansion item"
The &%sha256%& operator computes the SHA-256 hash fingerprint of the
.cindex "expansion" "utf-8 forcing"
.cindex "&%utf8clean%& expansion item"
This replaces any invalid utf-8 sequence in the string by the character &`?`&.
+
+.new
+.vitem "&*${utf8_domain_to_alabel:*&<&'string'&>&*}*&" &&&
+ "&*${utf8_domain_from_alabel:*&<&'string'&>&*}*&" &&&
+ "&*${utf8_localpart_to_alabel:*&<&'string'&>&*}*&" &&&
+ "&*${utf8_localpart_from_alabel:*&<&'string'&>&*}*&"
+.cindex expansion UTF-8
+.cindex UTF-8 expansion
+.cindex EAI
+.cindex internationalisation
+.cindex "&%utf8_domain_to_alabel%& expansion item"
+.cindex "&%utf8_domain_from_alabel%& expansion item"
+.cindex "&%utf8_localpart_to_alabel%& expansion item"
+.cindex "&%utf8_localpart_from_alabel%& expansion item"
+These convert EAI mail name components between UTF-8 and a-label forms.
+For information on internationalisation support see &<<SECTi18nMTA>>&.
+.wen
.endlist
When a &%match%& expansion condition succeeds, these variables contain the
captured substrings identified by the regular expression during subsequent
processing of the success string of the containing &%if%& expansion item.
-However, they do not retain their values afterwards; in fact, their previous
+In the expansion condition case
+they do not retain their values afterwards; in fact, their previous
values are restored at the end of processing an &%if%& item. The numerical
variables may also be set externally by some other matching process which
precedes the expansion of the string. For example, the commands available in
.vitem "&$auth1$& &-- &$auth3$&"
.vindex "&$auth1$&, &$auth2$&, etc"
These variables are used in SMTP authenticators (see chapters
-&<<CHAPplaintext>>&&--&<<CHAPspa>>&). Elsewhere, they are empty.
+&<<CHAPplaintext>>&&--&<<CHAPtlsauth>>&). Elsewhere, they are empty.
.vitem &$authenticated_id$&
.cindex "authentication" "id"
&$originator_uid$&). If Exim re-execs itself, this variable in the new
incarnation normally contains the Exim uid.
-.vitem &$compile_date$&
-.vindex "&$compile_date$&"
-The date on which the Exim binary was compiled.
+.vitem &$callout_address$&
+.vindex "&$callout_address$&"
+After a callout for verification, spamd or malware daemon service, the
+address that was connected to.
.vitem &$compile_number$&
.vindex "&$compile_number$&"
content-scanning extension and the obsolete &%demime%& condition. For details,
see section &<<SECTdemimecond>>&.
+.vitem &$dkim_cur_signer$& &&&
+ &$dkim_verify_status$& &&&
+ &$dkim_verify_reason$& &&&
+ &$dkim_domain$& &&&
+ &$dkim_identity$& &&&
+ &$dkim_selector$& &&&
+ &$dkim_algo$& &&&
+ &$dkim_canon_body$& &&&
+ &$dkim_canon_headers$& &&&
+ &$dkim_copiedheaders$& &&&
+ &$dkim_bodylength$& &&&
+ &$dkim_created$& &&&
+ &$dkim_expires$& &&&
+ &$dkim_headernames$& &&&
+ &$dkim_key_testing$& &&&
+ &$dkim_key_nosubdomains$& &&&
+ &$dkim_key_srvtype$& &&&
+ &$dkim_key_granularity$& &&&
+ &$dkim_key_notes$& &&&
+ &$dkim_key_length$&
+These variables are only available within the DKIM ACL.
+For details see chapter &<<CHAPdkim>>&.
+
+.vitem &$dkim_signers$&
+.vindex &$dkim_signers$&
+When a message has been received this variable contains
+a colon-separated list of signer domains and identities for the message.
+For details see chapter &<<CHAPdkim>>&.
+
.vitem &$dnslist_domain$& &&&
&$dnslist_matched$& &&&
&$dnslist_text$& &&&
This variable contains the numerical value of the Exim user id.
.vitem &$exim_version$&
-.vindex "&$exim_uid$&"
+.vindex "&$exim_version$&"
This variable contains the version string of the Exim build.
The first character is a major version number, currently 4.
Then after a dot, the next group of digits is a minor version number.
.vindex "&$lookup_dnssec_authenticated$&"
This variable is set after a DNS lookup done by
a dnsdb lookup expansion, dnslookup router or smtp transport.
+.cindex "DNS" "DNSSEC"
It will be empty if &(DNSSEC)& was not requested,
&"no"& if the result was not labelled as authenticated data
and &"yes"& if it was.
+Results that are labelled as authoritative answer that match
+the &%dns_trust_aa%& configuration variable count also
+as authenticated data.
.vitem &$mailstore_basename$&
.vindex "&$mailstore_basename$&"
qualified host name. See also &$smtp_active_hostname$&.
+.new
+.vitem &$proxy_host_address$& &&&
+ &$proxy_host_port$& &&&
+ &$proxy_target_address$& &&&
+ &$proxy_target_port$& &&&
+ &$proxy_session$&
+These variables are only available when built with Proxy Protocol
+or Socks5 support
+For details see chapter &<<SECTproxyInbound>>&.
+.wen
+
+.new
+.vitem &$prdr_requested$&
+.cindex "PRDR" "variable for"
+This variable is set to &"yes"& if PRDR was requested by the client for the
+current message, otherwise &"no"&.
+.wen
+
.vitem &$prvscheck_address$&
This variable is used in conjunction with the &%prvscheck%& expansion item,
which is described in sections &<<SECTexpansionitems>>& and
values of &$received_ip_address$& and &$received_port$& are saved with any
messages that are received, thus making these variables available at delivery
time.
-
-&*Note:*& There are no equivalent variables for outgoing connections, because
-the values are unknown (unless they are explicitly set by options of the
-&(smtp)& transport).
+For outbound connections see &$sending_ip_address$&.
.vitem &$received_port$&
.vindex "&$received_port$&"
This variable is set to contain the matching regular expression after a
&%regex%& ACL condition has matched (see section &<<SECTscanregex>>&).
+.vitem "&$regex1$&, &$regex2$&, etc"
+.cindex "regex submatch variables (&$1regex$& &$2regex$& etc)"
+When a &%regex%& or &%mime_regex%& ACL condition succeeds,
+these variables contain the
+captured substrings identified by the regular expression.
+
.vitem &$reply_address$&
.vindex "&$reply_address$&"
the argument of a HELO or EHLO command. This is omitted if it is identical to
the verified host name or to the host's IP address in square brackets.
+.vitem &$sender_helo_dnssec$&
+.vindex "&$sender_helo_dnssec$&"
+This boolean variable is true if a successful HELO verification was
+.cindex "DNS" "DNSSEC"
+done using DNS information the resolver library stated was authenticated data.
+
.vitem &$sender_helo_name$&
.vindex "&$sender_helo_name$&"
When a message is received from a remote host that has issued a HELO or EHLO
If an attempt to populate &$sender_host_name$& has been made
(by reference, &%hosts_lookup%& or
otherwise) then this boolean will have been set true if, and only if, the
-resolver library states that the reverse DNS was authenticated data. At all
+resolver library states that both
+the reverse and forward DNS were authenticated data. At all
other times, this variable is false.
+.cindex "DNS" "DNSSEC"
It is likely that you will need to coerce DNSSEC support on in the resolver
library, by setting:
.code
.endd
Exim does not perform DNSSEC validation itself, instead leaving that to a
-validating resolver (eg, unbound, or bind with suitable configuration).
-
-Exim does not (currently) check to see if the forward DNS was also secured
-with DNSSEC, only the reverse DNS.
+validating resolver (e.g. unbound, or bind with suitable configuration).
If you have changed &%host_lookup_order%& so that &`bydns`& is not the first
mechanism in the list, then this variable will be false.
.vitem &$tls_in_ourcert$&
.vindex "&$tls_in_ourcert$&"
+.cindex certificate veriables
This variable refers to the certificate presented to the peer of an
inbound connection when the message was received.
It is only useful as the argument of a
-.new
&%certextract%& expansion item, &%md5%&, &%sha1%& or &%sha256%& operator,
-.wen
or a &%def%& condition.
.vitem &$tls_in_peercert$&
This variable refers to the certificate presented by the peer of an
inbound connection when the message was received.
It is only useful as the argument of a
-.new
&%certextract%& expansion item, &%md5%&, &%sha1%& or &%sha256%& operator,
-.wen
or a &%def%& condition.
+If certificate verification fails it may refer to a failing chain element
+which is not the leaf.
.vitem &$tls_out_ourcert$&
.vindex "&$tls_out_ourcert$&"
This variable refers to the certificate presented to the peer of an
outbound connection. It is only useful as the argument of a
-.new
&%certextract%& expansion item, &%md5%&, &%sha1%& or &%sha256%& operator,
-.wen
or a &%def%& condition.
.vitem &$tls_out_peercert$&
.vindex "&$tls_out_peercert$&"
This variable refers to the certificate presented by the peer of an
outbound connection. It is only useful as the argument of a
-.new
&%certextract%& expansion item, &%md5%&, &%sha1%& or &%sha256%& operator,
-.wen
or a &%def%& condition.
+If certificate verification fails it may refer to a failing chain element
+which is not the leaf.
.vitem &$tls_in_certificate_verified$&
.vindex "&$tls_in_certificate_verified$&"
This variable is set to &"1"& if a TLS certificate was verified when the
message was received, and &"0"& otherwise.
-The deprecated &$tls_certificate_verfied$& variable refers to the inbound side
+The deprecated &$tls_certificate_verified$& variable refers to the inbound side
except when used in the context of an outbound SMTP delivery, when it refers to
the outbound.
.vitem &$tls_in_peerdn$&
.vindex "&$tls_in_peerdn$&"
.vindex "&$tls_peerdn$&"
+.cindex certificate "extracting fields"
When a message is received from a remote host over an encrypted SMTP
connection, and Exim is configured to request a certificate from the client,
the value of the Distinguished Name of the certificate is made available in the
&$tls_in_peerdn$& during subsequent processing.
+If certificate verification fails it may refer to a failing chain element
+which is not the leaf.
The deprecated &$tls_peerdn$& variable refers to the inbound side
except when used in the context of an outbound SMTP delivery, when it refers to
connection, and Exim is configured to request a certificate from the server,
the value of the Distinguished Name of the certificate is made available in the
&$tls_out_peerdn$& during subsequent processing.
+If certificate verification fails it may refer to a failing chain element
+which is not the leaf.
.vitem &$tls_in_sni$&
.vindex "&$tls_in_sni$&"
.section "Logging" "SECID99"
.table2
+.row &%event_action%& "custom logging"
.row &%hosts_connection_nolog%& "exemption from connect logging"
.row &%log_file_path%& "override compiled-in value"
.row &%log_selector%& "set/unset optional logging"
.row &%message_logs%& "create per-message logs"
.row &%preserve_message_logs%& "after message completion"
.row &%process_log_path%& "for SIGUSR1 and &'exiwhat'&"
+.row &%slow_lookup_log%& "control logging of slow DNS lookups"
.row &%syslog_duplication%& "controls duplicate log lines on syslog"
.row &%syslog_facility%& "set syslog &""facility""& field"
.row &%syslog_processname%& "set syslog &""ident""& field"
.row &%acl_smtp_mail%& "ACL for MAIL"
.row &%acl_smtp_mailauth%& "ACL for AUTH on MAIL command"
.row &%acl_smtp_mime%& "ACL for MIME parts"
+.row &%acl_smtp_notquit%& "ACL for non-QUIT terminations"
.row &%acl_smtp_predata%& "ACL for start of data"
.row &%acl_smtp_quit%& "ACL for QUIT"
.row &%acl_smtp_rcpt%& "ACL for RCPT"
.row &%helo_verify_hosts%& "HELO hard-checked for these hosts"
.row &%host_lookup%& "host name looked up for these hosts"
.row &%host_lookup_order%& "order of DNS and local name lookups"
+.row &%hosts_proxy%& "use proxy protocol for these hosts"
.row &%host_reject_connection%& "reject connection from these hosts"
.row &%hosts_treat_as_local%& "useful in some cluster configurations"
.row &%local_scan_timeout%& "timeout for &[local_scan()]&"
.row &%tls_crl%& "certificate revocation list"
.row &%tls_dh_max_bits%& "clamp D-H bit count suggestion"
.row &%tls_dhparam%& "DH parameters for server"
+.row &%tls_eccurve%& "EC curve selection for server"
.row &%tls_ocsp_file%& "location of server certificate status proof"
.row &%tls_on_connect_ports%& "specify SSMTP (SMTPS) ports"
.row &%tls_privatekey%& "location of server private key"
See also the &'Policy controls'& section above.
.table2
+.row &%dkim_verify_signers%& "DKIM domain for which DKIM ACL is run"
.row &%host_lookup%& "host name looked up for these hosts"
.row &%host_lookup_order%& "order of DNS and local name lookups"
.row &%recipient_unqualified_hosts%& "may send unqualified recipients"
.row &%ignore_fromline_local%& "allow &""From ""& from local SMTP"
.row &%pipelining_advertise_hosts%& "advertise pipelining to these hosts"
.row &%prdr_enable%& "advertise PRDR to all hosts"
+.row &%smtputf8_advertise_hosts%& "advertise SMTPUTF8 to these hosts"
.row &%tls_advertise_hosts%& "advertise TLS to these hosts"
.endtable
.row &%dns_ipv4_lookup%& "only v4 lookup for these domains"
.row &%dns_retrans%& "parameter for resolver"
.row &%dns_retry%& "parameter for resolver"
+.row &%dns_trust_aa%& "DNS zones trusted as authentic"
.row &%dns_use_edns0%& "parameter for resolver"
.row &%hold_domains%& "hold delivery for these domains"
.row &%local_interfaces%& "for routing checks"
processed and the message itself has been received, but before the
acknowledgment is sent. See chapter &<<CHAPACL>>& for further details.
+.option acl_smtp_dkim main string&!! unset
+.cindex DKIM "ACL for"
+This option defines the ACL that is run for each DKIM signature
+of a received message.
+See chapter &<<CHAPdkim>>& for further details.
+
.option acl_smtp_etrn main string&!! unset
.cindex "ETRN" "ACL for"
This option defines the ACL that is run when an SMTP ETRN command is
extension. It defines the ACL that is run for each MIME part in a message. See
section &<<SECTscanmimepart>>& for details.
+.option acl_smtp_notquit main string&!! unset
+.cindex "not-QUIT, ACL for"
+This option defines the ACL that is run when an SMTP session
+ends without a QUIT command being received.
+See chapter &<<CHAPACL>>& for further details.
+
.option acl_smtp_predata main string&!! unset
This option defines the ACL that is run when an SMTP DATA command is
received, before the message itself is received. See chapter &<<CHAPACL>>& for
It appears that more and more DNS zone administrators are breaking the rules
and putting domain names that look like IP addresses on the right hand side of
MX records. Exim follows the rules and rejects this, giving an error message
-that explains the mis-configuration. However, some other MTAs support this
+that explains the misconfiguration. However, some other MTAs support this
practice, so to avoid &"Why can't Exim do this?"& complaints,
&%allow_mx_to_ip%& exists, in order to enable this heinous activity. It is not
recommended, except when you have no other choice.
to handle IPv6 literal addresses.
+.option dkim_verify_signers main "domain list&!!" $dkim_signers
+.cindex DKIM "controlling calls to the ACL"
+This option gives a list of DKIM domains for which the DKIM ACL is run.
+It is expanded after the message is received; by default it runs
+the ACL once for each signature in the message.
+See chapter &<<CHAPdkim>>&.
+
+
.option dns_again_means_nonexist main "domain list&!!" unset
.cindex "DNS" "&""try again""& response; overriding"
DNS lookups give a &"try again"& response for the DNS errors
.option dns_retrans main time 0s
.cindex "DNS" "resolver options"
+.cindex timeout "dns lookup"
+.cindex "DNS" timeout
The options &%dns_retrans%& and &%dns_retry%& can be used to set the
retransmission and retry parameters for DNS lookups. Values of zero (the
defaults) leave the system default settings unchanged. The first value is the
parameter values are available in the external resolver interface structure,
but nowhere does it seem to describe how they are used or what you might want
to set in them.
+See also the &%slow_lookup_log%& option.
.option dns_retry main integer 0
See &%dns_retrans%& above.
+.option dns_trust_aa main "domain list&!!" unset
+.cindex "DNS" "resolver options"
+.cindex "DNS" "DNSSEC"
+If this option is set then lookup results marked with the AA bit
+(Authoritative Answer) are trusted the same way as if they were
+DNSSEC-verified. The authority section's name of the answer must
+match with this expanded domain list.
+
+Use this option only if you talk directly to a resolver that is
+authoritative for some zones and does not set the AD (Authentic Data)
+bit in the answer. Some DNS servers may have an configuration option to
+mark the answers from their own zones as verified (they set the AD bit).
+Others do not have this option. It is considered as poor practice using
+a resolver that is an authoritative server for some zones.
+
+Use this option only if you really have to (e.g. if you want
+to use DANE for remote delivery to a server that is listed in the DNS
+zones that your resolver is authoritative for).
+
+If the DNS answer packet has the AA bit set and contains resource record
+in the answer section, the name of the first NS record appearing in the
+authority section is compared against the list. If the answer packet is
+authoritative but the answer section is empty, the name of the first SOA
+record in the authoritative section is used instead.
+
+.cindex "DNS" "resolver options"
.option dns_use_edns0 main integer -1
.cindex "DNS" "resolver options"
.cindex "DNS" "EDNS0"
Exim's transports have an option for adding an &'Envelope-to:'& header to a
message when it is delivered, in exactly the same way as &'Return-path:'& is
handled. &'Envelope-to:'& records the original recipient address from the
-messages's envelope that caused the delivery to happen. Such headers should not
+message's envelope that caused the delivery to happen. Such headers should not
be present in incoming messages, and this option causes them to be removed at
the time the message is received, to avoid any problems that might occur when a
delivered message is subsequently sent on to some other recipient.
not used.
+.new
+.option event_action main string&!! unset
+.cindex events
+This option declares a string to be expanded for Exim's events mechanism.
+For details see &<<CHAPevents>>&.
+.wen
+
+
.option exim_group main string "compile-time configured"
.cindex "gid (group id)" "Exim's own"
.cindex "Exim group"
. Allow this long option name to split; give it unsplit as a fifth argument
. for the automatic .oindex that is generated by .option.
-.option "extract_addresses_remove_ &~&~arguments" main boolean true &&&
+.option "extract_addresses_remove_arguments" main boolean true &&&
extract_addresses_remove_arguments
.oindex "&%-t%&"
.cindex "command line" "addresses with &%-t%&"
matches the host name that Exim obtains by doing a reverse lookup of the
calling host address, or
.next
-when looked up using &[gethostbyname()]& (or &[getipnodebyname()]& when
-available) yields the calling host address.
+when looked up in DNS yields the calling host address.
.endlist
However, the EHLO or HELO command is not rejected if any of the checks
fail. Processing continues, but the result of the check is remembered, and can
be detected later in an ACL by the &`verify = helo`& condition.
+If DNS was used for successful verification, the variable
+.cindex "DNS" "DNSSEC"
+&$helo_verify_dnssec$& records the DNSSEC status of the lookups.
+
.option helo_verify_hosts main "host list&!!" unset
.cindex "HELO verifying" "mandatory"
.cindex "EHLO" "verifying, mandatory"
+.new
+.option hosts_proxy main "host list&!!" unset
+.cindex proxy "proxy protocol"
+This option enables use of Proxy Protocol proxies for incoming
+connections. For details see &<<SECTproxyInbound>>&.
+.wen
+
+
.option hosts_treat_as_local main "domain list&!!" unset
.cindex "local host" "domains treated as"
.cindex "host" "treated as local"
.option ldap_ca_cert_dir main string unset
.cindex "LDAP", "TLS CA certificate directory"
+.cindex certificate "directory for LDAP"
This option indicates which directory contains CA certificates for verifying
a TLS certificate presented by an LDAP server.
While Exim does not provide a default value, your SSL library may.
.option ldap_ca_cert_file main string unset
.cindex "LDAP", "TLS CA certificate file"
+.cindex certificate "file for LDAP"
This option indicates which file contains CA certificates for verifying
a TLS certificate presented by an LDAP server.
While Exim does not provide a default value, your SSL library may.
.option ldap_cert_file main string unset
.cindex "LDAP" "TLS client certificate file"
+.cindex certificate "file for LDAP"
This option indicates which file contains an TLS client certificate which
Exim should present to the LDAP server during TLS negotiation.
Should be used together with &%ldap_cert_key%&.
.option ldap_cert_key main string unset
.cindex "LDAP" "TLS client key file"
+.cindex certificate "key for LDAP"
This option indicates which file contains the secret/private key to use
to prove identity to the LDAP server during TLS negotiation.
Should be used together with &%ldap_cert_file%&, which contains the
This option sets the path which is used to determine the names of Exim's log
files, or indicates that logging is to be to syslog, or both. It is expanded
when Exim is entered, so it can, for example, contain a reference to the host
-name. If no specific path is set for the log files at compile or run time, they
-are written in a sub-directory called &_log_& in Exim's spool directory.
+name. If no specific path is set for the log files at compile or run time,
+or if the option is unset at run time (i.e. &`log_file_path = `&)
+they are written in a sub-directory called &_log_& in Exim's spool directory.
Chapter &<<CHAPlog>>& contains further details about Exim's logging, and
section &<<SECTwhelogwri>>& describes how the contents of &%log_file_path%& are
used. If this string is fixed at your installation (contains no expansion
maximum size that your virus-scanner is configured to support, you may get
failures triggered by large mails. The right size to configure for the
virus-scanner depends upon what data is passed and the options in use but it's
-probably safest to just set it to a little larger than this value. Eg, with a
+probably safest to just set it to a little larger than this value. E.g., with a
default Exim message size of 50M and a default ClamAV StreamMaxLength of 10M,
some problems may result.
This option can be used to enable the Per-Recipient Data Response extension
to SMTP, defined by Eric Hall.
If the option is set, PRDR is advertised by Exim when operating as a server.
-If the client requests PRDR, and more than one recipient, for a message
+If the client requests PRDR, and more than one recipient, for a message
an additional ACL is called for each recipient after the message content
-is recieved. See section &<<SECTPRDRACL>>&.
+is received. See section &<<SECTPRDRACL>>&.
.option preserve_message_logs main boolean false
.cindex "message logs" "preserving"
using TCP/IP), and the &%-bnq%& option was not set.
+.option slow_lookup_log main integer 0
+.cindex "logging" "slow lookups"
+.cindex "dns" "logging slow lookups"
+This option controls logging of slow lookups.
+If the value is nonzero it is taken as a number of milliseconds
+and lookups taking longer than this are logged.
+Currently this applies only to DNS lookups.
+
+
+
.option smtp_accept_keepalive main boolean true
.cindex "keepalive" "on incoming connection"
This option controls the setting of the SO_KEEPALIVE option on incoming
550 failing address in "From" header is: <user@dom.ain
.endd
+
+.new
+.option smtputf8_advertise_hosts main "host list&!!" *
+.cindex "SMTPUTF8" "advertising"
+When Exim is built with support for internationalised mail names,
+the availability therof is advertised in
+response to EHLO only to those client hosts that match this option. See
+chapter &<<CHAPi18n>>& for details of Exim's support for internationalisation.
+.wen
+
+
.option spamd_address main string "see below"
This option is available when Exim is compiled with the content-scanning
extension. It specifies how Exim connects to SpamAssassin's &%spamd%& daemon.
unfortunately not all, operating systems.
-.option tls_advertise_hosts main "host list&!!" unset
+.new
+.option tls_advertise_hosts main "host list&!!" *
+.wen
.cindex "TLS" "advertising"
.cindex "encryption" "on SMTP connection"
.cindex "SMTP" "encrypted connection"
of the STARTTLS command to set up an encrypted session is advertised in
response to EHLO only to those client hosts that match this option. See
chapter &<<CHAPTLS>>& for details of Exim's support for TLS.
+.new
+Note that the default value requires that a certificate be supplied
+using the &%tls_certificate%& option. If no certificate is available then
+the &%tls_advertise_hosts%& option should be set empty.
+.wen
.option tls_certificate main string&!! unset
acceptable bound from 1024 to 2048.
+.option tls_eccurve main string&!! prime256v1
+.cindex TLS "EC cryptography"
+If built with a recent-enough version of OpenSSL,
+this option selects a EC curve for use by Exim.
+
+Curve names of the form &'prime256v1'& are accepted.
+For even more-recent library versions, names of the form &'P-512'&
+are also accepted, plus the special value &'auto'&
+which tell the library to choose.
+
+If the option is set to an empty string, no EC curves will be enabled.
+
+
.option tls_ocsp_file main string&!! unset
+.cindex TLS "certificate status"
+.cindex TLS "OCSP proof file"
This option
must if set expand to the absolute path to a file which contains a current
status proof for the server's certificate, as obtained from the
Certificate Authority.
+.new
+Usable for GnuTLS 3.4.4 or 3.3.17 or OpenSSL 1.1.0 (or later).
+.wen
+
.option tls_on_connect_ports main "string list" unset
+.cindex SSMTP
+.cindex SMTPS
This option specifies a list of incoming SSMTP (aka SMTPS) ports that should
operate the obsolete SSMTP (SMTPS) protocol, where a TLS session is immediately
set up without waiting for the client to issue a STARTTLS command. For
and will be taken as empty; an explicit location
must be specified.
-The use of a directory for the option value is not avilable for GnuTLS versions
+The use of a directory for the option value is not available for GnuTLS versions
preceding 3.3.6 and a single file must be used.
With OpenSSL the certificates specified
of the other precondition options are common special cases that could in fact
be specified using &%condition%&.
-.new
Historical note: We have &%condition%& on ACLs and on Routers. Routers
are far older, and use one set of semantics. ACLs are newer and when
they were created, the ACL &%condition%& process was given far stricter
match an explicit false value. This can be tricky to debug. By
contrast, in an ACL either of those strings will always result in an
expansion error because the result doesn't look sufficiently boolean.
-.wen
.option debug_print routers string&!! unset
unless you really, really know what you are doing. See also the generic
transport option of the same name.
+.option dnssec_request_domains routers "domain list&!!" unset
+.cindex "MX record" "security"
+.cindex "DNSSEC" "MX lookup"
+.cindex "security" "MX lookup"
+.cindex "DNS" "DNSSEC"
+DNS lookups for domains matching &%dnssec_request_domains%& will be done with
+the dnssec request bit set.
+This applies to all of the SRV, MX, AAAA, A lookup sequence.
+
+.option dnssec_require_domains routers "domain list&!!" unset
+.cindex "MX record" "security"
+.cindex "DNSSEC" "MX lookup"
+.cindex "security" "MX lookup"
+.cindex "DNS" "DNSSEC"
+DNS lookups for domains matching &%dnssec_request_domains%& will be done with
+the dnssec request bit set. Any returns not having the Authenticated Data bit
+(AD bit) set will be ignored and logged as a host-lookup failure.
+This applies to all of the SRV, MX, AAAA, A lookup sequence.
+
.option domains routers&!? "domain list&!!" unset
.cindex "router" "restricting to specific domains"
.option headers_add routers list&!! unset
.cindex "header lines" "adding"
.cindex "router" "adding header lines"
-This option specifies a list of text headers, newline-separated,
+This option specifies a list of text headers,
+newline-separated (by default, changeable in the usual way),
that is associated with any addresses that are accepted by the router.
Each item is separately expanded, at routing time. However, this
option has no effect when an address is just being verified. The way in which
.option headers_remove routers list&!! unset
.cindex "header lines" "removing"
.cindex "router" "removing header lines"
-This option specifies a list of text headers, colon-separated,
+This option specifies a list of text headers,
+colon-separated (by default, changeable in the usual way),
that is associated with any addresses that are accepted by the router.
Each item is separately expanded, at routing time. However, this
option has no effect when an address is just being verified. The way in which
routers, and this can lead to problems with duplicates -- see the similar
warning for &%headers_add%& above.
+&*Warning 3*&: Because of the separate expansion of the list items,
+items that contain a list separator must have it doubled.
+To avoid this, change the list separator (&<<SECTlistsepchange>>&).
+
+
.option ignore_target_hosts routers "host list&!!" unset
.cindex "IP address" "discarding"
.section "Problems with DNS lookups" "SECTprowitdnsloo"
There have been problems with DNS servers when SRV records are looked up.
-Some mis-behaving servers return a DNS error or timeout when a non-existent
+Some misbehaving servers return a DNS error or timeout when a non-existent
SRV record is sought. Similar problems have in the past been reported for
MX records. The global &%dns_again_means_nonexist%& option can help with this
problem, but it is heavy-handed because it is a global option.
an address; if such a router is expected to handle "all remaining non-local
domains", then it is important to set &%no_more%&.
+The router will defer rather than decline if the domain
+is found in the &%fail_defer_domains%& router option.
+
Reasons for a &(dnslookup)& router to decline currently include:
.ilist
The domain does not exist in DNS
-.option dnssec_request_domains dnslookup "domain list&!!" unset
-.cindex "MX record" "security"
-.cindex "DNSSEC" "MX lookup"
-.cindex "security" "MX lookup"
-.cindex "DNS" "DNSSEC"
-DNS lookups for domains matching &%dnssec_request_domains%& will be done with
-the dnssec request bit set.
-This applies to all of the SRV, MX A6, AAAA, A lookup sequence.
-
-
-
-.option dnssec_require_domains dnslookup "domain list&!!" unset
-.cindex "MX record" "security"
-.cindex "DNSSEC" "MX lookup"
-.cindex "security" "MX lookup"
-.cindex "DNS" "DNSSEC"
-DNS lookups for domains matching &%dnssec_request_domains%& will be done with
-the dnssec request bit set. Any returns not having the Authenticated Data bit
-(AD bit) set wil be ignored and logged as a host-lookup failure.
-This applies to all of the SRV, MX A6, AAAA, A lookup sequence.
+.option fail_defer_domains dnslookup "domain list&!!" unset
+.cindex "MX record" "not found"
+DNS lookups for domains matching &%fail_defer_domains%&
+which find no matching record will cause the router to defer
+rather than the default behaviour of decline.
+This maybe be useful for queueing messages for a newly created
+domain while the DNS configuration is not ready.
+However, it will result in any message with mistyped domains
+also being queued.
.option mx_domains dnslookup "domain list&!!" unset
.cindex "black hole"
.cindex "abandoning mail"
&':blackhole:'& can be used. It does what its name implies. No delivery is
-done, and no error message is generated. This has the same effect as specifing
+done, and no error message is generated. This has the same effect as specifying
&_/dev/null_& as a destination, but it can be independently disabled.
&*Warning*&: If &':blackhole:'& appears anywhere in a redirection list, no
resent to other recipients.
+.option event_action transports string&!! unset
+.cindex events
+This option declares a string to be expanded for Exim's events mechanism.
+For details see &<<CHAPevents>>&.
+.wen
+
+
.option group transports string&!! "Exim group"
.cindex "transport" "group; specifying"
This option specifies a gid for running the transport process, overriding any
.option headers_add transports list&!! unset
.cindex "header lines" "adding in transport"
.cindex "transport" "header lines; adding"
-This option specifies a list of text headers, newline-separated,
+This option specifies a list of text headers,
+newline-separated (by default, changeable in the usual way),
which are (separately) expanded and added to the header
portion of a message as it is transported, as described in section
&<<SECTheadersaddrem>>&. Additional header lines can also be specified by
.option headers_remove transports list&!! unset
.cindex "header lines" "removing"
.cindex "transport" "header lines; removing"
-This option specifies a list of header names, colon-separated;
+This option specifies a list of header names,
+colon-separated (by default, changeable in the usual way);
these headers are omitted from the message as it is transported, as described
in section &<<SECTheadersaddrem>>&. Header removal can also be specified by
routers.
Unlike most options, &%headers_remove%& can be specified multiple times
for a router; all listed headers are removed.
+&*Warning*&: Because of the separate expansion of the list items,
+items that contain a list separator must have it doubled.
+To avoid this, change the list separator (&<<SECTlistsepchange>>&).
+
.option headers_rewrite transports string unset
to ensure that any additional groups associated with the uid are set up.
+.new
+.option max_parallel transports integer&!! unset
+.cindex limit "transport parallelism"
+.cindex transport "parallel processes"
+.cindex transport "concurrency limit"
+.cindex "delivery" "parallelism for transport"
+If this option is set and expands to an integer greater than zero
+it limits the number of concurrent runs of the transport.
+The control does not apply to shadow transports.
+
+.cindex "hints database" "transport concurrency control"
+Exim implements this control by means of a hints database in which a record is
+incremented whenever a transport process is beaing created. The record
+is decremented and possibly removed when the process terminates.
+Obviously there is scope for
+records to get left lying around if there is a system or program crash. To
+guard against this, Exim ignores any records that are more than six hours old.
+
+If you use this option, you should also arrange to delete the
+relevant hints database whenever your system reboots. The names of the files
+start with &_misc_& and they are kept in the &_spool/db_& directory. There
+may be one or two files, depending on the type of DBM in use. The same files
+are used for ETRN and smtp transport serialization.
+.wen
+
+
.option message_size_limit transports string&!! 0
.cindex "limit" "message size per transport"
.cindex "size" "of message, limit"
This option sets up a filtering (in the Unix shell sense) process for messages
at transport time. It should not be confused with mail filtering as set up by
individual users or via a system filter.
+.new
+If unset, or expanding to an empty string, no filtering is done.
+.wen
When the message is about to be written out, the command specified by
&%transport_filter%& is started up in a separate, parallel process, and
delivery, the two pipe transports may be run concurrently. You must ensure that
any pipe commands you set up are robust against this happening. If the commands
write to a file, the &%exim_lock%& utility might be of use.
+.new
+Alternatively the &%max_parallel%& option could be used with a value
+of "1" to enforce serialization.
+.wen
&%force_command%& is set, expanding out to the original argument vector as
separate items, similarly to a Unix shell &`"$@"`& construct.
+
.option ignore_status pipe boolean false
If this option is true, the status returned by the subprocess that is set up to
run the command is ignored, and Exim behaves as if zero had been returned.
&*Note*&: This option does not apply to timeouts, which do not return a status.
See the &%timeout_defer%& option for how timeouts are handled.
+
.option log_defer_output pipe boolean false
.cindex "&(pipe)& transport" "logging output"
If this option is set, and the status returned by the command is
one of the codes listed in &%temp_errors%& (that is, delivery was deferred),
-and any output was produced, the first line of it is written to the main log.
+and any output was produced on stdout or stderr, the first line of it is
+written to the main log.
.option log_fail_output pipe boolean false
-If this option is set, and the command returns any output, and also ends with a
-return code that is neither zero nor one of the return codes listed in
-&%temp_errors%& (that is, the delivery failed), the first line of output is
-written to the main log. This option and &%log_output%& are mutually exclusive.
-Only one of them may be set.
-
+If this option is set, and the command returns any output on stdout or
+stderr, and also ends with a return code that is neither zero nor one of
+the return codes listed in &%temp_errors%& (that is, the delivery
+failed), the first line of output is written to the main log. This
+option and &%log_output%& are mutually exclusive. Only one of them may
+be set.
.option log_output pipe boolean false
-If this option is set and the command returns any output, the first line of
-output is written to the main log, whatever the return code. This option and
-&%log_fail_output%& are mutually exclusive. Only one of them may be set.
-
+If this option is set and the command returns any output on stdout or
+stderr, the first line of output is written to the main log, whatever
+the return code. This option and &%log_fail_output%& are mutually
+exclusive. Only one of them may be set.
.option max_output pipe integer 20K
.cindex "DNS" "DNSSEC"
DNS lookups for domains matching &%dnssec_request_domains%& will be done with
the dnssec request bit set.
-This applies to all of the SRV, MX A6, AAAA, A lookup sequence.
+This applies to all of the SRV, MX, AAAA, A lookup sequence.
.cindex "DNS" "DNSSEC"
DNS lookups for domains matching &%dnssec_request_domains%& will be done with
the dnssec request bit set. Any returns not having the Authenticated Data bit
-(AD bit) set wil be ignored and logged as a host-lookup failure.
-This applies to all of the SRV, MX A6, AAAA, A lookup sequence.
+(AD bit) set will be ignored and logged as a host-lookup failure.
+This applies to all of the SRV, MX, AAAA, A lookup sequence.
Exim will not try to start a TLS session when delivering to any host that
matches this list. See chapter &<<CHAPTLS>>& for details of TLS.
-.option hosts_verify_avoid_tls smtp "host list&!!" *
+.option hosts_verify_avoid_tls smtp "host list&!!" unset
.cindex "TLS" "avoiding for certain hosts"
Exim will not try to start a TLS session for a verify callout,
or when delivering in cutthrough mode,
to any host that matches this list.
-Note that the default is to not use TLS.
.option hosts_max_try smtp integer 5
deliveries into closed message stores. Exim also has support for running LMTP
over a pipe to a local process &-- see chapter &<<CHAPLMTP>>&.
-If this option is set to &"smtps"&, the default vaule for the &%port%& option
+If this option is set to &"smtps"&, the default value for the &%port%& option
changes to &"smtps"&, and the transport initiates TLS immediately after
connecting, as an outbound SSL-on-connect, instead of using STARTTLS to upgrade.
The Internet standards bodies strongly discourage use of this mode.
may be one or two files, depending on the type of DBM in use. The same files
are used for ETRN serialization.
+.new
+See also the &%max_parallel%& generic transport option.
+.wen
+
.option size_addition smtp integer 1024
.cindex "SMTP" "SIZE"
the use of the SIZE option altogether.
+.new
+.option socks_proxy smtp string&!! unset
+.cindex proxy SOCKS
+This option enables use of SOCKS proxies for connections made by the
+transport. For details see &<<SECTproxySOCKS>>&.
+.wen
+
+
.option tls_certificate smtp string&!! unset
.cindex "TLS" "client certificate, location of"
.cindex "certificate" "client, location of"
is taken as empty and an explicit location
must be specified.
-The use of a directory for the option value is not avilable for GnuTLS versions
+The use of a directory for the option value is not available for GnuTLS versions
preceding 3.3.6 and a single file must be used.
With OpenSSL the certificates specified
&$host_address$& are set to the name and address of the server during the
expansion of this option. See chapter &<<CHAPTLS>>& for details of TLS.
-For back-compatability,
+For back-compatibility,
if neither tls_verify_hosts nor tls_try_verify_hosts are set
(a single-colon empty list counts as being set)
and certificate verification fails the TLS connection is closed.
2822 address, including the angle brackets if necessary. If text outside angle
brackets contains a character whose value is greater than 126 or less than 32
(except for tab), the text is encoded according to RFC 2047. The character set
-is taken from &%headers_charset%&, which defaults to ISO-8859-1.
+is taken from &%headers_charset%&, which gets its default at build time.
When the &"w"& flag is set on a rule that causes an envelope address to be
rewritten, all but the working part of the replacement address is discarded.
legitimate reasons for this (host died, network died), but if it repeats a lot
for the same host, it indicates something odd.
+.vitem &%lookup%&
+A DNS lookup for a host failed.
+Note that a &%dnslookup%& router will need to have matched
+its &%fail_defer_domains%& option for this retry type to be usable.
+Also note that a &%manualroute%& router will probably need
+its &%host_find_failed%& option set to &%defer%&.
+
.vitem &%refused_MX%&
A connection to a host obtained from an MX record was refused.
AUTH_HEIMDAL_GSSAPI=yes
AUTH_PLAINTEXT=yes
AUTH_SPA=yes
+AUTH_TLS=yes
.endd
in &_Local/Makefile_&, respectively. The first of these supports the CRAM-MD5
authentication mechanism (RFC 2195), and the second provides an interface to
the PLAIN authentication mechanism (RFC 2595) or the LOGIN mechanism, which is
not formally documented, but used by several MUAs. The seventh authenticator
supports Microsoft's &'Secure Password Authentication'& mechanism.
+The eighth is an Exim authenticator but not an SMTP one;
+instead it can use information from a TLS negotiation.
The authenticators are configured using the same syntax as other drivers (see
section &<<SECTfordricon>>&). If no authenticators are required, no
.option client_set_id authenticators string&!! unset
When client authentication succeeds, this condition is expanded; the
-result is used in the log lines for outbound messasges.
+result is used in the log lines for outbound messages.
Typically it will be the user name used for authentication.
driver = cram_md5
public_name = CRAM-MD5
server_secret = ${lookup{$auth1:mail.example.org:userPassword}\
- dbmjz{/etc/sasldb2}}
+ dbmjz{/etc/sasldb2}{$value}fail}
server_set_id = $auth1
.endd
.option server_service heimdal_gssapi string&!! "smtp"
This option specifies the service identifier used, in conjunction with
-&%server_hostname%&, for building the identifer for finding credentials
+&%server_hostname%&, for building the identifier for finding credentials
from the keytab.
+. ////////////////////////////////////////////////////////////////////////////
+. ////////////////////////////////////////////////////////////////////////////
+
+.chapter "The tls authenticator" "CHAPtlsauth"
+.scindex IIDtlsauth1 "&(tls)& authenticator"
+.scindex IIDtlsauth2 "authenticators" "&(tls)&"
+.cindex "authentication" "Client Certificate"
+.cindex "authentication" "X509"
+.cindex "Certificate-based authentication"
+The &(tls)& authenticator provides server support for
+authentication based on client certificates.
+
+It is not an SMTP authentication mechanism and is not
+advertised by the server as part of the SMTP EHLO response.
+It is an Exim authenticator in the sense that it affects
+the protocol element of the log line, can be tested for
+by the &%authenticated%& ACL condition, and can set
+the &$authenticated_id$& variable.
+
+The client must present a verifiable certificate,
+for which it must have been requested via the
+&%tls_verify_hosts%& or &%tls_try_verify_hosts%& main options
+(see &<<CHAPTLS>>&).
+
+If an authenticator of this type is configured it is
+run before any SMTP-level communication is done,
+and can authenticate the connection.
+If it does, SMTP authentication is not offered.
+
+A maximum of one authenticator of this type may be present.
+
+
+.cindex "options" "&(tls)& authenticator (server)"
+The &(tls)& authenticator has three server options:
+
+.option server_param1 tls string&!! unset
+.cindex "variables (&$auth1$& &$auth2$& etc)" "in &(tls)& authenticator"
+This option is expanded after the TLS negotiation and
+the result is placed in &$auth1$&.
+If the expansion is forced to fail, authentication fails. Any other expansion
+failure causes a temporary error code to be returned.
+
+.option server_param2 tls string&!! unset
+.option server_param3 tls string&!! unset
+As above, for &$auth2$& and &$auth3$&.
+
+&%server_param1%& may also be spelled &%server_param%&.
+
+
+Example:
+.code
+tls:
+ driver = tls
+ server_param1 = ${certextract {subj_altname,mail,>:} \
+ {$tls_in_peercert}}
+ server_condition = ${if forany {$auth1} \
+ {!= {0} \
+ {${lookup ldap{ldap:///\
+ mailname=${quote_ldap_dn:${lc:$item}},\
+ ou=users,LDAP_DC?mailid} {$value}{0} \
+ } } } }
+ server_set_id = ${if = {1}{${listcount:$auth1}} {$auth1}{}}
+.endd
+This accepts a client certificate that is verifiable against any
+of your configured trust-anchors
+which usually means the full set of public CAs)
+and which has a SAN with a good account name.
+Note that the client cert is on the wire in-clear, including the SAN,
+whereas a plaintext SMTP AUTH done inside TLS is not.
+
+. An alternative might use
+. .code
+. server_param1 = ${sha256:$tls_in_peercert}
+. .endd
+. to require one of a set of specific certs that define a given account
+. (the verification is still required, but mostly irrelevant).
+. This would help for per-device use.
+.
+. However, for the future we really need support for checking a
+. user cert in LDAP - which probably wants a base-64 DER.
+
+.ecindex IIDtlsauth1
+.ecindex IIDtlsauth2
+
+
+Note that because authentication is traditionally an SMTP operation,
+the &%authenticated%& ACL condition cannot be used in
+a connect- or helo-ACL.
+
+
+
. ////////////////////////////////////////////////////////////////////////////
. ////////////////////////////////////////////////////////////////////////////
proof expires. The downside is that it requires server support.
Unless Exim is built with the support disabled,
-or with GnuTLS earlier than version 3.1.3,
+.new
+or with GnuTLS earlier than version 3.3.16 / 3.4.8
+.wen
support for OCSP stapling is included.
There is a global option called &%tls_ocsp_file%&.
If the &%tls_verify_certificates%& option is set on the &(smtp)& transport, it
specifies a collection of expected server certificates.
-These may be the system default set (depeding on library version),
+These may be the system default set (depending on library version),
a file or,
-depnding on liibrary version, a directory,
+depending on library version, a directory,
must name a file or,
for OpenSSL only (not GnuTLS), a directory.
The client verifies the server's certificate
within and possibly choose to use different certificates and keys (and more)
for this session.
-This is analagous to HTTP's &"Host:"& header, and is the main mechanism by
+This is analogous to HTTP's &"Host:"& header, and is the main mechanism by
which HTTPS-enabled web-sites can be virtual-hosted, many sites to one IP
address.
&%tls_verify_certificates%&
.next
.vindex "&%tls_ocsp_file%&"
-&%tls_verify_certificates%&
+&%tls_ocsp_file%&
.endlist
Great care should be taken to deal with matters of case, various injection
The Exim developers are proceeding cautiously and so far no other TLS options
are re-expanded.
-When Exim is built againt OpenSSL, OpenSSL must have been built with support
+When Exim is built against OpenSSL, OpenSSL must have been built with support
for TLS Extensions. This holds true for OpenSSL 1.0.0+ and 0.9.8+ with
enable-tlsext in EXTRACONFIGURE. If you invoke &(openssl s_client -h)& and
see &`-servername`& in the output, then OpenSSL has support.
.cindex "EXPN" "ACL for"
.cindex "HELO" "ACL for"
.cindex "EHLO" "ACL for"
+.cindex "DKIM" "ACL for"
.cindex "MAIL" "ACL for"
.cindex "QUIT, ACL for"
.cindex "RCPT" "ACL for"
.irow &%acl_smtp_connect%& "ACL for start of SMTP connection"
.irow &%acl_smtp_data%& "ACL after DATA is complete"
.irow &%acl_smtp_data_prdr%& "ACL for each recipient, after DATA is complete"
+.irow &%acl_smtp_dkim%& "ACL for each DKIM signer"
.irow &%acl_smtp_etrn%& "ACL for ETRN"
.irow &%acl_smtp_expn%& "ACL for EXPN"
.irow &%acl_smtp_helo%& "ACL for HELO or EHLO"
client and server for a message, and more than one recipient
has been accepted.
-The ACL test specfied by &%acl_smtp_data_prdr%& happens after a message
-has been recieved, and is executed once for each recipient of the message
+The ACL test specified by &%acl_smtp_data_prdr%& happens after a message
+has been received, and is executed once for each recipient of the message
with &$local_part$& and &$domain$& valid.
-The test may accept, defer or deny for inividual recipients.
+The test may accept, defer or deny for individual recipients.
The &%acl_smtp_data%& will still be called after this ACL and
can reject the message overall, even if this ACL has accepted it
for some or all recipients.
PRDR may be used to support per-user content filtering. Without it
one must defer any recipient after the first that has a different
content-filter configuration. With PRDR, the RCPT-time check
-for this can be disabled when the MAIL-time $smtp_command included
-"PRDR". Any required difference in behaviour of the main DATA-time
+.new
+.cindex "PRDR" "variable for"
+for this can be disabled when the variable &$prdr_requested$&
+is &"yes"&.
+.wen
+Any required difference in behaviour of the main DATA-time
ACL should however depend on the PRDR-time ACL having run, as Exim
-will avoid doing so in some situations (eg. single-recipient mails).
+will avoid doing so in some situations (e.g. single-recipient mails).
See also the &%prdr_enable%& global option
and the &%hosts_try_prdr%& smtp transport option.
.cindex "QUIT, ACL for"
The ACL for the SMTP QUIT command is anomalous, in that the outcome of the ACL
does not affect the response code to QUIT, which is always 221. Thus, the ACL
-does not in fact control any access. For this reason, the only verbs that are
-permitted are &%accept%& and &%warn%&.
+does not in fact control any access.
+For this reason, it may only accept
+or warn as its final result.
This ACL can be used for tasks such as custom logging at the end of an SMTP
session. For example, you can use ACL variables in other ACLs to count
response.
.vindex "&$acl_verify_message$&"
-.new
For ACLs that are called by an &%acl =%& ACL condition, the message is
stored in &$acl_verify_message$&, from which the calling ACL may use it.
-.wen
If &%message%& is used on a statement that verifies an address, the message
specified overrides any message that is generated by the verification process.
.cindex "&ACL;" "cutthrough routing"
.cindex "cutthrough" "requesting"
This option requests delivery be attempted while the item is being received.
-It is usable in the RCPT ACL and valid only for single-recipient mails forwarded
-from one SMTP connection to another. If a recipient-verify callout connection is
-requested in the same ACL it is held open and used for the data, otherwise one is made
-after the ACL completes.
+
+The option is usable in the RCPT ACL.
+If enabled for a message received via smtp and routed to an smtp transport,
+and only one transport, interface, destination host and port combination
+is used for all recipients of the message,
+then the delivery connection is made while the receiving connection is open
+and data is copied from one to the other.
+
+An attempt to set this option for any recipient but the first
+for a mail will be quietly ignored.
+If a recipient-verify callout connection is subsequently
+requested in the same ACL it is held open and used for
+any subsequent recipients and the data,
+otherwise one is made after the initial RCPT ACL completes.
Note that routers are used in verify mode,
and cannot depend on content of received headers.
Cutthrough delivery is not supported via transport-filters or when DKIM signing
of outgoing messages is done, because it sends data to the ultimate destination
before the entire message has been received from the source.
+It is not supported for messages received with the SMTP PRDR option in use.
Should the ultimate destination system positively accept or reject the mail,
a corresponding indication is given to the source system and nothing is queued.
If there is a temporary error the item is queued for later delivery in the
-usual fashion. If the item is successfully delivered in cutthrough mode the log line
-is tagged with ">>" rather than "=>" and appears before the acceptance "<="
-line.
+usual fashion. If the item is successfully delivered in cutthrough mode
+the delivery log lines are tagged with ">>" rather than "=>" and appear
+before the acceptance "<=" line.
-Delivery in this mode avoids the generation of a bounce mail to a (possibly faked)
+Delivery in this mode avoids the generation of a bounce mail to a
+(possibly faked)
sender when the destination system is doing content-scan based rejection.
&*Note:*& This control applies only to the current message, not to any others
that are being submitted at the same time using &%-bs%& or &%-bS%&.
+
+.new
+.vitem &*control&~=&~utf8_downconvert*&
+This control enables conversion of UTF-8 in message addresses
+to a-label form.
+For details see &<<SECTi18nMTA>>&.
+.wen
.endlist vlist
received, that is, in an ACL specified by &%acl_smtp_data%& or
&%acl_not_smtp%&. It checks the syntax of all header lines that can contain
lists of addresses (&'Sender:'&, &'From:'&, &'Reply-To:'&, &'To:'&, &'Cc:'&,
-and &'Bcc:'&). Unqualified addresses (local parts without domains) are
+and &'Bcc:'&), returning true if there are no problems.
+Unqualified addresses (local parts without domains) are
permitted only in locally generated messages and from hosts that match
&%sender_unqualified_hosts%& or &%recipient_unqualified_hosts%&, as
appropriate.
address, and in that case, the subsequent value of &$address_data$& is the
value for the child address.
-.vitem &*verify&~=&~reverse_host_lookup*&
+.vitem &*verify&~=&~reverse_host_lookup/*&<&'options'&>
.cindex "&%verify%& ACL condition"
.cindex "&ACL;" "verifying host reverse lookup"
.cindex "host" "verifying reverse lookup"
one of its aliases, does, when it is itself looked up in the DNS, yield the
original IP address.
+There is one possible option, &`defer_ok`&. If this is present and a
+DNS operation returns a temporary error, the verify condition succeeds.
+
If this condition is used for a locally generated message (that is, when there
is no client host involved), it always succeeds.
warn message = X-Warn: sending host is on dialups list
dnslists = dialups.mail-abuse.org
.endd
-DNS list lookups are cached by Exim for the duration of the SMTP session,
+.cindex cacheing "of dns lookup"
+.cindex DNS TTL
+DNS list lookups are cached by Exim for the duration of the SMTP session
+.new
+(but limited by the DNS return TTL value),
+.wen
so a lookup based on the IP address is done at most once for any incoming
-connection. Exim does not share information between multiple incoming
+connection (assuming long-enough TTL).
+Exim does not share information between multiple incoming
connections (but your local name server cache should be active).
accepted. It can be used in the &%acl_smtp_rcpt%&, &%acl_smtp_predata%&,
&%acl_smtp_mime%&, &%acl_smtp_data%&, or &%acl_smtp_rcpt%& ACLs. In
&%acl_smtp_rcpt%& the rate is updated one recipient at a time; in the other
-ACLs the rate is updated with the total recipient count in one go. Note that
+ACLs the rate is updated with the total (accepted) recipient count in one go. Note that
in either case the rate limiting engine will see a message with many
recipients as a large high-speed burst.
.vitem &%avast%&
.cindex "virus scanners" "avast"
This is the scanner daemon of Avast. It has been tested with Avast Core
-Security (currenty at version 1.1.7).
+Security (currently at version 1.1.7).
You can get a trial version at &url(http://www.avast.com) or for Linux
at &url(http://www.avast.com/linux-server-antivirus).
This scanner type takes one option,
If you use a remote host,
you need to make Exim's spool directory available to it,
as the scanner is passed a file path, not file contents.
-For information about available commands and their options you may use
+For information about available commands and their options you may use
.code
$ socat UNIX:/var/run/avast/scan.sock STDIO:
FLAGS
This daemon-type scanner is GPL and free. You can get it at
&url(http://www.clamav.net/). Some older versions of clamd do not seem to
unpack MIME containers, so it used to be recommended to unpack MIME attachments
-in the MIME ACL. This no longer believed to be necessary. One option is
-required: either the path and name of a UNIX socket file, or a hostname or IP
-number, and a port, separated by space, as in the second of these examples:
+in the MIME ACL. This is no longer believed to be necessary.
+
+The options are a list of server specifiers, which may be
+a UNIX socket specification,
+a TCP socket specification,
+or a (global) option.
+
+A socket specification consists of a space-separated list.
+For a Unix socket the first element is a full path for the socket,
+for a TCP socket the first element is the IP address
+and the second a port number,
+Any further elements are per-server (non-global) options.
+These per-server options are supported:
+.code
+retry=<timespec> Retry on connect fail
+.endd
+
+The &`retry`& option specifies a time after which a single retry for
+a failed connect is made. The default is to not retry.
+
+If a Unix socket file is specified, only one server is supported.
+
+Examples:
.code
av_scanner = clamd:/opt/clamd/socket
av_scanner = clamd:192.0.2.3 1234
av_scanner = clamd:192.0.2.3 1234:local
+av_scanner = clamd:192.0.2.3 1234 retry=10s
av_scanner = clamd:192.0.2.3 1234 : 192.0.2.4 1234
.endd
-If the value of av_scanner points to a UNIX socket file or contains the local
-keyword, then the ClamAV interface will pass a filename containing the data
+If the value of av_scanner points to a UNIX socket file or contains the
+&`local`&
+option, then the ClamAV interface will pass a filename containing the data
to be scanned, which will should normally result in less I/O happening and be
more efficient. Normally in the TCP case, the data is streamed to ClamAV as
Exim does not assume that there is a common filesystem with the remote host.
If you omit the argument, the default path &_/usr/local/drweb/run/drwebd.sock_&
is used. Thanks to Alex Miller for contributing the code for this scanner.
+.vitem &%f-protd%&
+.cindex "virus scanners" "f-protd"
+The f-protd scanner is accessed via HTTP over TCP.
+One argument is taken, being a space-separated hostname and port number
+(or port-range).
+For example:
+.code
+av_scanner = f-protd:localhost 10200-10204
+.endd
+If you omit the argument, the default values show above are used.
+
.vitem &%fsecure%&
.cindex "virus scanners" "F-Secure"
The F-Secure daemon scanner (&url(http://www.f-secure.com)) takes one
This is a general-purpose way of talking to simple scanner daemons
running on the local machine.
There are four options:
-an address (which may be an IP addres and port, or the path of a Unix socket),
+an address (which may be an IP address and port, or the path of a Unix socket),
a commandline to send (may include a single %s which will be replaced with
the path to the mail file to be scanned),
an RE to trigger on from the returned data,
.endd
A timeout causes the ACL to defer.
+.vindex "&$callout_address$&"
+When a connection is made to the scanner the expansion variable &$callout_address$&
+is set to record the actual address used.
+
.vindex "&$malware_name$&"
When a virus is found, the condition sets up an expansion variable called
&$malware_name$& that contains the name of the virus. You can use it in a
.endd
-.section "Scanning with SpamAssassin" "SECTscanspamass"
+.section "Scanning with SpamAssassin and Rspamd" "SECTscanspamass"
.cindex "content scanning" "for spam"
.cindex "spam scanning"
.cindex "SpamAssassin"
+.cindex "Rspamd"
The &%spam%& ACL condition calls SpamAssassin's &%spamd%& daemon to get a spam
-score and a report for the message. You can get SpamAssassin at
-&url(http://www.spamassassin.org), or, if you have a working Perl
-installation, you can use CPAN by running:
+score and a report for the message.
+Support is also provided for Rspamd.
+
+For more information about installation and configuration of SpamAssassin or
+Rspamd refer to their respective websites at
+&url(http://spamassassin.apache.org) and &url(http://www.rspamd.com)
+
+SpamAssassin can be installed with CPAN by running:
.code
perl -MCPAN -e 'install Mail::SpamAssassin'
.endd
nicely, however.
.oindex "&%spamd_address%&"
-After having installed and configured SpamAssassin, start the &%spamd%& daemon.
-By default, it listens on 127.0.0.1, TCP port 783. If you use another host or
-port for &%spamd%&, you must set the &%spamd_address%& option in the global
-part of the Exim configuration as follows (example):
+By default, SpamAssassin listens on 127.0.0.1, TCP port 783 and if you
+intend to use an instance running on the local host you do not need to set
+&%spamd_address%&. If you intend to use another host or port for SpamAssassin,
+you must set the &%spamd_address%& option in the global part of the Exim
+configuration as follows (example):
.code
spamd_address = 192.168.99.45 387
.endd
-You do not need to set this option if you use the default. As of version 2.60,
-&%spamd%& also supports communication over UNIX sockets. If you want to use
-these, supply &%spamd_address%& with an absolute file name instead of a
-address/port pair:
+
+To use Rspamd (which by default listens on all local addresses
+on TCP port 11333)
+you should add &%variant=rspamd%& after the address/port pair, for example:
+.code
+spamd_address = 127.0.0.1 11333 variant=rspamd
+.endd
+
+As of version 2.60, &%SpamAssassin%& also supports communication over UNIX
+sockets. If you want to us these, supply &%spamd_address%& with an absolute
+file name instead of an address/port pair:
.code
spamd_address = /var/run/spamd_socket
.endd
You can have multiple &%spamd%& servers to improve scalability. These can
reside on other hardware reachable over the network. To specify multiple
&%spamd%& servers, put multiple address/port pairs in the &%spamd_address%&
-option, separated with colons:
+option, separated with colons (the separator can be changed in the usual way):
.code
spamd_address = 192.168.2.10 783 : \
192.168.2.11 783 : \
192.168.2.12 783
.endd
-Up to 32 &%spamd%& servers are supported. The servers are queried in a random
-fashion. When a server fails to respond to the connection attempt, all other
+Up to 32 &%spamd%& servers are supported.
+When a server fails to respond to the connection attempt, all other
servers are tried until one succeeds. If no server responds, the &%spam%&
condition defers.
-&*Warning*&: It is not possible to use the UNIX socket connection method with
-multiple &%spamd%& servers.
+Unix and TCP socket specifications may be mixed in any order.
+Each element of the list is a list itself, space-separated by default
+and changeable in the usual way.
+
+For TCP socket specifications a host name or IP (v4 or v6, but
+subject to list-separator quoting rules) address can be used,
+and the port can be one or a dash-separated pair.
+In the latter case, the range is tried in strict order.
+
+Elements after the first for Unix sockets, or second for TCP socket,
+are options.
+The supported options are:
+.code
+pri=<priority> Selection priority
+weight=<value> Selection bias
+time=<start>-<end> Use only between these times of day
+retry=<timespec> Retry on connect fail
+tmo=<timespec> Connection time limit
+variant=rspamd Use Rspamd rather than SpamAssassin protocol
+.endd
+
+The &`pri`& option specifies a priority for the server within the list,
+higher values being tried first.
+The default priority is 1.
+
+The &`weight`& option specifies a selection bias.
+Within a priority set
+servers are queried in a random fashion, weighted by this value.
+The default value for selection bias is 1.
+
+Time specifications for the &`time`& option are <hour>.<minute>.<second>
+in the local time zone; each element being one or more digits.
+Either the seconds or both minutes and seconds, plus the leading &`.`&
+characters, may be omitted and will be taken as zero.
+
+Timeout specifications for the &`retry`& and &`tmo`& options
+are the usual Exim time interval standard, e.g. &`20s`& or &`1m`&.
+
+The &`tmo`& option specifies an overall timeout for communication.
+The default value is two minutes.
+
+The &`retry`& option specifies a time after which a single retry for
+a failed connect is made.
+The default is to not retry.
The &%spamd_address%& variable is expanded before use if it starts with
a dollar sign. In this case, the expansion may return a string that is
used as the list so that multiple spamd servers can be the result of an
expansion.
+.vindex "&$callout_address$&"
+When a connection is made to the server the expansion variable &$callout_address$&
+is set to record the actual address used.
+
.section "Calling SpamAssassin from an Exim ACL" "SECID206"
Here is a simple example of the use of the &%spam%& condition in a DATA ACL:
.code
relevant if you have set up multiple SpamAssassin profiles. If you do not want
to scan using a specific profile, but rather use the SpamAssassin system-wide
default profile, you can scan for an unknown name, or simply use &"nobody"&.
-However, you must put something on the right-hand side.
+Rspamd does not use this setting. However, you must put something on the
+right-hand side.
The name allows you to use per-domain or per-user antispam profiles in
principle, but this is not straightforward in practice, because a message may
have multiple recipients, not necessarily all in the same domain. Because the
-&%spam%& condition has to be called from a DATA ACL in order to be able to
+&%spam%& condition has to be called from a DATA-time ACL in order to be able to
read the contents of the message, the variables &$local_part$& and &$domain$&
are not set.
+Careful enforcement of single-recipient messages
+(e.g. by responding with defer in the recipient ACL for all recipients
+after the first),
+or the use of PRDR,
+.cindex "PRDR" "use for per-user SpamAssassin profiles"
+are needed to use this feature.
The right-hand side of the &%spam%& condition is expanded before being used, so
you can put lookups or conditions there. When the right-hand side evaluates to
.cindex "spam scanning" "returned variables"
When the &%spam%& condition is run, it sets up a number of expansion
-variables. These variables are saved with the received message, thus they are
+variables.
+Except for &$spam_report$&,
+these variables are saved with the received message so are
available for use at delivery time.
.vlist
A string consisting of a number of &"+"& or &"-"& characters, representing the
integer part of the spam score value. A spam score of 4.4 would have a
&$spam_bar$& value of &"++++"&. This is useful for inclusion in warning
-headers, since MUAs can match on such strings.
+headers, since MUAs can match on such strings. The maximum length of the
+spam bar is 50 characters.
.vitem &$spam_report$&
A multiline text table, containing the full SpamAssassin report for the
message. Useful for inclusion in headers or reject messages.
+This variable is only usable in a DATA-time ACL.
+
+.vitem &$spam_action$&
+For SpamAssassin either 'reject' or 'no action' depending on the
+spam score versus threshold.
+For Rspamd, the recommended action.
+
.endlist
The &%spam%& condition caches its results unless expansion in
This is perhaps the most important of the MIME variables. It contains a
proposed filename for an attachment, if one was found in either the
&'Content-Type:'& or &'Content-Disposition:'& headers. The filename will be
-RFC2047 decoded, but no additional sanity checks are done. If no filename was
+RFC2047
+or RFC2231
+decoded, but no additional sanity checks are done.
+ If no filename was
found, this variable contains the empty string.
.vitem &$mime_is_coverletter$&
The conditions returns true if any one of the regular expressions matches. The
&$regex_match_string$& expansion variable is then set up and contains the
matching regular expression.
+The expansion variables &$regex1$& &$regex2$& etc
+are set to any substrings captured by the regular expression.
&*Warning*&: With large messages, these conditions can be fairly
CPU-intensive.
.code
log_file_path = $spool_directory/log/%slog
.endd
-If you do not specify anything at build time or run time, that is where the
-logs are written.
+If you do not specify anything at build time or run time,
+or if you unset the option at run time (i.e. &`log_file_path = `&),
+that is where the logs are written.
A log file path may also contain &`%D`& or &`%M`& if datestamped log file names
are in use &-- see section &<<SECTdatlogfil>>& below.
session was encrypted, there is an additional X field that records the cipher
suite that was used.
+.cindex log protocol
The protocol is set to &"esmtpsa"& or &"esmtpa"& for messages received from
hosts that have authenticated themselves using the SMTP AUTH command. The first
value is used when the SMTP connection was encrypted (&"secure"&). In this case
.cindex "log" "delivery line"
The format of the single-line entry in the main log that is written for every
delivery is shown in one of the examples below, for local and remote
-deliveries, respectively. Each example has been split into two lines in order
+deliveries, respectively. Each example has been split into multiple lines in order
to fit it on the page:
.code
2002-10-31 08:59:13 16ZCW1-0005MB-00 => marv
&`id `& message id for incoming message
&`P `& on &`<=`& lines: protocol used
&` `& on &`=>`& and &`**`& lines: return path
+&`PRX `& on &'<='& and&`=>`& lines: proxy address
&`QT `& on &`=>`& lines: time spent on queue so far
&` `& on &"Completed"& lines: time spent on queue
&`R `& on &`<=`& lines: reference for local bounce
&`*etrn `& ETRN commands
&`*host_lookup_failed `& as it says
&` ident_timeout `& timeout for ident connection
-&` incoming_interface `& incoming interface on <= lines
-&` incoming_port `& incoming port on <= lines
+&` incoming_interface `& local interface on <= and => lines
+&` incoming_port `& remote port on <= lines
&`*lost_incoming_connection `& as it says (includes timeouts)
+.new
+&` outgoing_interface `& local interface on => lines
+.wen
&` outgoing_port `& add remote port to => lines
&`*queue_run `& start and end queue runs
&` queue_time `& time on queue for one recipient
&` queue_time_overall `& time on queue for whole message
&` pid `& Exim process id
+.new
+&` proxy `& proxy address on <= and => lines
+.wen
&` received_recipients `& recipients on <= lines
&` received_sender `& sender on <= lines
&`*rejected_header `& header contents on reject log
&`*size_reject `& rejection because too big
&`*skip_delivery `& delivery skipped in a queue run
&`*smtp_confirmation `& SMTP confirmation on => lines
-&` smtp_connection `& SMTP connections
+&` smtp_connection `& incoming SMTP connections
&` smtp_incomplete_transaction`& incomplete SMTP transactions
&` smtp_mailauth `& AUTH argument to MAIL commands
&` smtp_no_mail `& session with no MAIL commands
&` all `& all of the above
.endd
+See also the &%slow_lookup_log%& main configuration option,
+section &<<SECID99>>&
+
More details on each of these items follows:
.ilist
client's ident port times out.
.next
.cindex "log" "incoming interface"
+.cindex "log" "local interface"
+.cindex "log" "local address and port"
+.cindex "TCP/IP" "logging local address and port"
.cindex "interface" "logging"
&%incoming_interface%&: The interface on which a message was received is added
to the &"<="& line as an IP address in square brackets, tagged by I= and
followed by a colon and the port number. The local interface and port are also
-added to other SMTP log lines, for example &"SMTP connection from"&, and to
-rejection lines.
+added to other SMTP log lines, for example &"SMTP connection from"&, to
+rejection lines, and (despite the name) to outgoing &"=>"& and &"->"& lines.
+.new
+The latter can be disabled by turning off the &%outgoing_interface%& option.
+.wen
+.next
+.new
+.cindex log "incoming proxy address"
+.cindex proxy "logging proxy address"
+.cindex "TCP/IP" "logging proxy address"
+&%proxy%&: The internal (closest to the system running Exim) IP address
+of the proxy, tagged by PRX=, on the &"<="& line for a message accepted
+on a proxied connection
+or the &"=>"& line for a message delivered on a proxied connection..
+See &<<SECTproxyInbound>>& for more information.
+.wen
.next
.cindex "log" "incoming remote port"
.cindex "port" "logging remote"
&%lost_incoming_connection%&: A log line is written when an incoming SMTP
connection is unexpectedly dropped.
.next
+.cindex "log" "outgoing interface"
+.cindex "log" "local interface"
+.cindex "log" "local address and port"
+.cindex "TCP/IP" "logging local address and port"
+.cindex "interface" "logging"
+.new
+&%outgoing_interface%&: If &%incoming_interface%& is turned on, then the
+interface on which a message was sent is added to delivery lines as an I= tag
+followed by IP address in square brackets. You can disable this by turning
+off the &%outgoing_interface%& option.
+.wen
+.next
.cindex "log" "outgoing remote port"
.cindex "port" "logging outgoint remote"
.cindex "TCP/IP" "logging ougtoing remote port"
&%outgoing_port%&: The remote port number is added to delivery log lines (those
-containing => tags) following the IP address. This option is not included in
-the default setting, because for most ordinary configurations, the remote port
-number is always 25 (the SMTP port).
+containing => tags) following the IP address.
+.new
+The local port is also added if &%incoming_interface%& and
+&%outgoing_interface%& are both enabled.
+.wen
+This option is not included in the default setting, because for most ordinary
+configurations, the remote port number is always 25 (the SMTP port), and the
+local port is a random ephemeral port.
.next
.cindex "log" "process ids in"
.cindex "pid (process id)" "in log lines"
.next
.cindex "log" "SMTP connections"
.cindex "SMTP" "logging connections"
-&%smtp_connection%&: A log line is written whenever an SMTP connection is
+&%smtp_connection%&: A log line is written whenever an incoming SMTP connection is
established or closed, unless the connection is from a host that matches
&%hosts_connection_nolog%&. (In contrast, &%lost_incoming_connection%& applies
only when the closure is unexpected.) This applies to connections from local
shows that the client issued QUIT straight after EHLO. If there were fewer
than 20 commands, they are all listed. If there were more than 20 commands,
the last 20 are listed, preceded by &"..."&. However, with the default
-setting of 10 for &%smtp_accep_max_nonmail%&, the connection will in any case
+setting of 10 for &%smtp_accept_max_nonmail%&, the connection will in any case
have been aborted before 20 non-mail commands are processed.
.next
&%smtp_mailauth%&: A third subfield with the authenticated sender,
The &*-C*& option is used to specify an alternate &_exim.conf_& which might
contain alternate exim configuration the queue management might be using.
-to obtain a queue listing, and then greps the output to select messages
+to obtain a queue listing, and then greps the output to select messages
that match given criteria. The following selection options are available:
.vlist
exiqgrep -f '^<>$'
.endd
.vitem &*-r*&&~<&'regex'&>
-Match a recipient address using a case-insensitve search. The field that is
+Match a recipient address using a case-insensitive search. The field that is
tested is not enclosed in angle brackets.
.vitem &*-s*&&~<&'regex'&>
The input files can be in Exim log format or syslog format.
If a matching log line is not associated with a specific message, it is
included in &'exigrep'&'s output without any additional lines. The usage is:
-.new
.display
&`exigrep [-t<`&&'n'&&`>] [-I] [-l] [-M] [-v] <`&&'pattern'&&`> [<`&&'log file'&&`>] ...`&
.endd
-.wen
If no log file names are given on the command line, the standard input is read.
The &%-t%& argument specifies a number of seconds. It adds an additional
The &%-v%& option inverts the matching condition. That is, a line is selected
if it does &'not'& match the pattern.
-.new
The &%-M%& options means &"related messages"&. &'exigrep'& will show messages
that are generated as a result/response to a message that &'exigrep'& matched
normally.
when searching for &"user_a"& will show both messages since the bounce is
&"related"& to or a &"result"& of the first message that was found by the
search term.
-.wen
If the location of a &'zcat'& command is known from the definition of
ZCAT_COMMAND in &_Local/Makefile_&, &'exigrep'& automatically passes any file
whose name ends in COMPRESS_SUFFIX through &'zcat'& as it searches it.
+If the ZCAT_COMMAND is not executable, &'exigrep'& tries to use
+autodetection of some well known compression extensions.
.section "Selecting messages by various criteria (exipick)" "SECTexipick"
.next
Serializing delivery to a specific host (when &%serialize_hosts%& is set in an
&(smtp)& transport)
+.next
+Limiting the concurrency of specific transports (when &%max_parallel%& is set
+in a transport)
.endlist
Administrators who use embedded Perl are advised to explore how Perl's
taint checking might apply to their usage.
.next
-Use of &%${expand...}%& is somewhat analagous to shell's eval builtin and
+Use of &%${expand...}%& is somewhat analogous to shell's eval builtin and
administrators are well advised to view its use with suspicion, in case (for
instance) it allows a local-part to contain embedded Exim directives.
.next
DKIM is documented in RFC 4871.
Since version 4.70, DKIM support is compiled into Exim by default. It can be
-disabled by setting DISABLE_DKIM=yes in Local/Makefile.
+disabled by setting DISABLE_DKIM=yes in &_Local/Makefile_&.
Exim's DKIM implementation allows to
.olist
&%acl_smtp_dkim%& ACL. By default, this ACL is called once for each
syntactically(!) correct signature in the incoming message.
A missing ACL definition defaults to accept.
-If any ACL call does not acccept, the message is not accepted.
+If any ACL call does not accept, the message is not accepted.
If a cutthrough delivery was in progress for the message it is
summarily dropped (having wasted the transmission effort).
&%pass%&: The signature passed verification. It is valid.
.endlist
.vitem &%$dkim_verify_reason%&
-A string giving a litte bit more detail when &%$dkim_verify_status%& is either
+A string giving a little bit more detail when &%$dkim_verify_status%& is either
"fail" or "invalid". One of
.ilist
&%pubkey_unavailable%& (when &%$dkim_verify_status%&="invalid"): The public
in the key record.
.vitem &%$dkim_key_notes%&
Notes from the key record (tag n=).
+.vitem &%$dkim_key_length%&
+Number of bits in the key.
.endlist
In addition, two ACL conditions are provided:
. ////////////////////////////////////////////////////////////////////////////
. ////////////////////////////////////////////////////////////////////////////
+.chapter "Proxies" "CHAPproxies" &&&
+ "Proxy support"
+.cindex "proxy support"
+.cindex "proxy" "access via"
+
+.new
+A proxy is an intermediate system through which communication is passed.
+Proxies may provide a security, availability or load-distribution function.
+
+
+.section "Inbound proxies" SECTproxyInbound
+.cindex proxy inbound
+.cindex proxy "server side"
+.cindex proxy "Proxy protocol"
+.cindex "Proxy protocol" proxy
+
+Exim has support for receiving inbound SMTP connections via a proxy
+that uses &"Proxy Protocol"& to speak to it.
+To include this support, include &"SUPPORT_PROXY=yes"&
+in Local/Makefile.
+
+It was built on specifications from:
+http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt
+That URL was revised in May 2014 to version 2 spec:
+http://git.1wt.eu/web?p=haproxy.git;a=commitdiff;h=afb768340c9d7e50d8e
+
+The purpose of this facility is so that an application load balancer,
+such as HAProxy, can sit in front of several Exim servers
+to distribute load.
+Exim uses the local protocol communication with the proxy to obtain
+the remote SMTP system IP address and port information.
+There is no logging if a host passes or
+fails Proxy Protocol negotiation, but it can easily be determined and
+recorded in an ACL (example is below).
+
+Use of a proxy is enabled by setting the &%hosts_proxy%&
+main configuration option to a hostlist; connections from these
+hosts will use Proxy Protocol.
+
+The following expansion variables are usable
+(&"internal"& and &"external"& here refer to the interfaces
+of the proxy):
+.display
+&'proxy_host_address '& internal IP address of the proxy
+&'proxy_host_port '& internal TCP port of the proxy
+&'proxy_target_address '& external IP address of the proxy
+&'proxy_target_port '& external TCP port of the proxy
+&'proxy_session '& boolean: SMTP connection via proxy
+.endd
+If &$proxy_session$& is set but &$proxy_host_address$& is empty
+there was a protocol error.
+
+Since the real connections are all coming from the proxy, and the
+per host connection tracking is done before Proxy Protocol is
+evaluated, &%smtp_accept_max_per_host%& must be set high enough to
+handle all of the parallel volume you expect per inbound proxy.
+With the option set so high, you lose the ability
+to protect your server from many connections from one IP.
+In order to prevent your server from overload, you
+need to add a per connection ratelimit to your connect ACL.
+A possible solution is:
+.display
+ # Set max number of connections per host
+ LIMIT = 5
+ # Or do some kind of IP lookup in a flat file or database
+ # LIMIT = ${lookup{$sender_host_address}iplsearch{/etc/exim/proxy_limits}}
+
+ defer message = Too many connections from this IP right now
+ ratelimit = LIMIT / 5s / per_conn / strict
+.endd
+
+
+
+.section "Outbound proxies" SECTproxySOCKS
+.cindex proxy outbound
+.cindex proxy "client side"
+.cindex proxy SOCKS
+.cindex SOCKS proxy
+Exim has support for sending outbound SMTP via a proxy
+using a protocol called SOCKS5 (defined by RFC1928).
+The support can be optionally included by defining SUPPORT_SOCKS=yes in
+Local/Makefile.
+
+Use of a proxy is enabled by setting the &%socks_proxy%& option
+on an smtp transport.
+The option value is expanded and should then be a list
+(colon-separated by default) of proxy specifiers.
+Each proxy specifier is a list
+(space-separated by default) where the initial element
+is an IP address and any subsequent elements are options.
+
+Options are a string <name>=<value>.
+The list of options is in the following table:
+.display
+&'auth '& authentication method
+&'name '& authentication username
+&'pass '& authentication password
+&'port '& tcp port
+&'tmo '& connection timeout
+&'pri '& priority
+&'weight '& selection bias
+.endd
+
+More details on each of these options follows:
+
+.ilist
+.cindex authentication "to proxy"
+.cindex proxy authentication
+&%auth%&: Either &"none"& (default) or &"name"&.
+Using &"name"& selects username/password authentication per RFC 1929
+for access to the proxy.
+Default is &"none"&.
+.next
+&%name%&: sets the username for the &"name"& authentication method.
+Default is empty.
+.next
+&%pass%&: sets the password for the &"name"& authentication method.
+Default is empty.
+.next
+&%port%&: the TCP port number to use for the connection to the proxy.
+Default is 1080.
+.next
+&%tmo%&: sets a connection timeout in seconds for this proxy.
+Default is 5.
+.next
+&%pri%&: specifies a priority for the proxy within the list,
+higher values being tried first.
+The default priority is 1.
+.next
+&%weight%&: specifies a selection bias.
+Within a priority set servers are queried in a random fashion,
+weighted by this value.
+The default value for selection bias is 1.
+.endlist
+
+Proxies from the list are tried according to their priority
+and weight settings until one responds. The timeout for the
+overall connection applies to the set of proxied attempts.
+
+.section Logging SECTproxyLog
+To log the (local) IP of a proxy in the incoming or delivery logline,
+add &"+proxy"& to the &%log_selector%& option.
+This will add a component tagged with &"PRX="& to the line.
+.wen
+
+. ////////////////////////////////////////////////////////////////////////////
+. ////////////////////////////////////////////////////////////////////////////
+
+.chapter "Internationalisation" "CHAPi18n" &&&
+ "Internationalisation""
+.cindex internationalisation "email address"
+.cindex EAI
+.cindex i18n
+.cindex UTF-8 "mail name handling"
+
+.new
+Exim has support for Internationalised mail names.
+To include this it must be built with SUPPORT_I18N and the libidn library.
+Standards supported are RFCs 2060, 5890, 6530 and 6533.
+
+.section "MTA operations" SECTi18nMTA
+.cindex SMTPUTF8 "ESMTP option"
+The main configuration option &%smtputf8_advertise_hosts%& specifies
+a host list. If this matches the sending host and
+accept_8bitmime is true (the default) then the ESMTP option
+SMTPUTF8 will be advertised.
+
+If the sender specifies the SMTPUTF8 option on a MAIL command
+international handling for the message is enabled and
+the expansion variable &$message_smtputf8$& will have value TRUE.
+
+The option &%allow_utf8_domains%& is set to true for this
+message. All DNS lookups are converted to a-label form
+whatever the setting of &%allow_utf8_domains%&
+when Exim is built with SUPPORT_I18N.
+
+Both localparts and domain are maintained as the original
+UTF-8 form internally; any comparison or regular-expression use will
+require appropriate care. Filenames created, eg. by
+the appendfile transport, will have UTF-8 names.
+
+HELO names sent by the smtp transport will have any UTF-8
+components expanded to a-label form,
+and any certificate name checks will be done using the a-label
+form of the name.
+
+.cindex log protocol
+.cindex SMTPUTF8 logging
+Log lines and Received-by: header lines will acquire a "utf8"
+prefix on the protocol element, eg. utf8esmtp.
+
+The following expansion operator can be used:
+.code
+${utf8_domain_to_alabel:str}
+${utf8_domain_from_alabel:str}
+${utf8_localpart_to_alabel:str}
+${utf8_localpart_from_alabel:str}
+.endd
+
+ACLs may use the following modifier:
+.display
+control = utf8_downconvert
+control = utf8_downconvert/<value>
+.endd
+This sets a flag requiring that addresses are converted to
+a-label form before smtp delivery, for use in a
+Message Submission Agent context.
+If a value is appended it may be:
+.display
+&`1 `& (default) mandatory downconversion
+&`0 `& no downconversion
+&`-1 `& if SMTPUTF8 not supported by destination host
+.endd
+
+If mua_wrapper is set, the utf8_downconvert control
+is initially set to -1.
+
+
+There is no explicit support for VRFY and EXPN.
+Configurations supporting these should inspect
+&$smtp_command_argument$& for an SMTPUTF8 argument.
+
+There is no support for LMTP on Unix sockets.
+Using the "lmtp" protocol option on an smtp transport,
+for LMTP over TCP, should work as expected.
+
+There is no support for DSN unitext handling,
+and no provision for converting logging from or to UTF-8.
+
+
+
+.section "MDA operations" SECTi18nMDA
+To aid in constructing names suitable for IMAP folders
+the following expansion operator can be used:
+.code
+${imapfolder {<string>} {<sep>} {<specials>}}
+.endd
+
+The string is converted from the charset specified by
+the "headers charset" command (in a filter file)
+or &%headers_charset%& main configuration option (otherwise),
+to the
+modified UTF-7 encoding specified by RFC 2060,
+with the following exception: All occurences of <sep>
+(which has to be a single character)
+are replaced with periods ("."), and all periods and slashes that are not
+<sep> and are not in the <specials> string are BASE64 encoded.
+
+The third argument can be omitted, defaulting to an empty string.
+The second argument can be omitted, defaulting to "/".
+
+This is the encoding used by Courier for Maildir names on disk, and followed
+by many other IMAP servers.
+
+Examples:
+.display
+&`${imapfolder {Foo/Bar}} `& yields &`Foo.Bar`&
+&`${imapfolder {Foo/Bar}{.}{/}} `& yields &`Foo&&AC8-Bar`&
+&`${imapfolder {Räksmörgås}} `& yields &`R&&AOQ-ksm&&APY-rg&&AOU-s`&
+.endd
+
+Note that the source charset setting is vital, and also that characters
+must be representable in UTF-16.
+
+.wen
+
+. ////////////////////////////////////////////////////////////////////////////
+. ////////////////////////////////////////////////////////////////////////////
+
+.chapter "Events" "CHAPevents" &&&
+ "Events"
+.cindex events
+
+.new
+The events mechanism in Exim can be used to intercept processing at a number
+of points. It was originally invented to giave a way to do customised logging
+actions (for example, to a database) but can also be used to modify some
+processing actions.
+
+Most installations will never need to use Events.
+The support can be left out of a build by defining DISABLE_EVENT=yes
+in &_Local/Makefile_&.
+
+There are two major classes of events: main and transport.
+The main configuration option &%event_action%& controls reception events;
+a transport option &%event_action%& controls delivery events.
+
+Both options are a string which is expanded when the event fires.
+An example might look like:
+.cindex logging custom
+.code
+event_action = ${if eq {msg:delivery}{$event_name} \
+{${lookup pgsql {SELECT * FROM record_Delivery( \
+ '${quote_pgsql:$sender_address_domain}',\
+ '${quote_pgsql:${lc:$sender_address_local_part}}', \
+ '${quote_pgsql:$domain}', \
+ '${quote_pgsql:${lc:$local_part}}', \
+ '${quote_pgsql:$host_address}', \
+ '${quote_pgsql:${lc:$host}}', \
+ '${quote_pgsql:$message_exim_id}')}} \
+} {}}
+.endd
+
+Events have names which correspond to the point in process at which they fire.
+The name is placed in the variable &$event_name$& and the event action
+expansion must check this, as it will be called for every possible event type.
+
+The current list of events is:
+.display
+&`msg:complete after main `& per message
+&`msg:delivery after transport `& per recipient
+&`msg:rcpt:host:defer after transport `& per recipient per host
+&`msg:rcpt:defer after transport `& per recipient
+&`msg:host:defer after transport `& per attempt
+&`msg:fail:delivery after main `& per recipient
+&`msg:fail:internal after main `& per recipient
+&`tcp:connect before transport `& per connection
+&`tcp:close after transport `& per connection
+&`tls:cert before both `& per certificate in verification chain
+&`smtp:connect after transport `& per connection
+.endd
+New event types may be added in future.
+
+The event name is a colon-separated list, defining the type of
+event in a tree of possibilities. It may be used as a list
+or just matched on as a whole. There will be no spaces in the name.
+
+The second column in the table above describes whether the event fires
+before or after the action is associates with. Those which fire before
+can be used to affect that action (more on this below).
+
+An additional variable, &$event_data$&, is filled with information varying
+with the event type:
+.display
+&`msg:delivery `& smtp confirmation mssage
+&`msg:rcpt:host:defer `& error string
+&`msg:rcpt:defer `& error string
+&`msg:host:defer `& error string
+&`tls:cert `& verification chain depth
+&`smtp:connect `& smtp banner
+.endd
+
+The :defer events populate one extra variable: &$event_defer_errno$&.
+
+For complex operations an ACL expansion can be used in &%event_action%&
+however due to the multiple contextx that Exim operates in during
+the course of its processing:
+.ilist
+variables set in transport events will not be visible outside that
+transport call
+.next
+acl_m variables in a server context are lost on a new connection,
+and after smtp helo/ehlo/mail/starttls/rset commands
+.endlist
+Using an ACL expansion with the logwrite modifier can be
+a useful way of writing to the main log.
+
+The expansion of the event_action option should normally
+return an empty string. Should it return anything else the
+following will be forced:
+.display
+&`msg:delivery `& (ignored)
+&`msg:host:defer `& (ignored)
+&`msg:fail:delivery`& (ignored)
+&`tcp:connect `& do not connect
+&`tcp:close `& (ignored)
+&`tls:cert `& refuse verification
+&`smtp:connect `& close connection
+.endd
+No other use is made of the result string.
+
+For a tcp:connect event, if the connection is being made to a proxy
+then the address and port variables will be that of the proxy and not
+the target system.
+
+For tls:cert events, if GnuTLS is in use this will trigger only per
+chain element received on the connection.
+For OpenSSL it will trigger for every chain element including those
+loaded locally.
+.wen
+
+. ////////////////////////////////////////////////////////////////////////////
+. ////////////////////////////////////////////////////////////////////////////
+
.chapter "Adding new drivers or lookup types" "CHID13" &&&
"Adding drivers or lookups"
.cindex "adding drivers"
-------------------------------------------
+Exim version 4.87
+-----------------
+JH/01 Bug 1664: Disable OCSP for GnuTLS library versions at/before 3.3.16
+ and 3.4.4 - once the server is enabled to respond to an OCSP request
+ it does even when not requested, resulting in a stapling non-aware
+ client dropping the TLS connection.
+
+TF/01 Code cleanup: Overhaul the debug_selector and log_selector machinery to
+ support variable-length bit vectors. No functional change.
+
+TF/02 Improve the consistency of logging incoming and outgoing interfaces.
+ The I= interface field on outgoing lines is now after the H= remote
+ host field, same as incoming lines. There is a separate
+ outgoing_interface log selector which allows you to disable the
+ outgoing I= field.
+
+JH/02 Bug 728: Close logfiles after a daemon-process "exceptional" log write.
+ If not running log_selector +smtp_connection the mainlog would be held
+ open indefinitely after a "too many connections" event, including to a
+ deleted file after a log rotate. Leave the per net connection logging
+ leaving it open for efficiency as that will be quickly detected by the
+ check on the next write.
+
+HS/01 Bug 1671: Fix post transport crash.
+ Processing the wait-<transport> messages could crash the delivery
+ process if the message IDs didn't exist for some reason. When
+ using 'split_spool_directory=yes' the construction of the spool
+ file name failed already, exposing the same netto behaviour.
+
+JH/03 Bug 425: Capture substrings in $regex1, $regex2 etc from regex &
+ mime_regex ACL conditions.
+
+JH/04 Bug 1686: When compiled with EXPERIMENTAL_DSN_INFO: Add extra information
+ to DSN fail messages (bounces): remote IP, remote greeting, remote response
+ to HELO, local diagnostic string.
+
+JH/05 Downgrade message for a TLS-certificate-based authentication fail from
+ log line to debug. Even when configured with a tls authenticator many
+ client connections are expected to not authenticate in this way, so
+ an authenticate fail is not an error.
+
+HS/02 Add the Exim version string to the process info. This way exiwhat
+ gives some more detail about the running daemon.
+
+JH/06 Bug 1395: time-limit cacheing of DNS lookups, to the TTL value. This may
+ matter for fast-change records such as DNSBLs.
+
+JH/07 Bug 1678: Always record an interface option value, if set, as part of a
+ retry record, even if constant. There may be multiple transports with
+ different interface settings and the retry behaviour needs to be kept
+ distinct.
+
+JH/08 Bug 1586: exiqgrep now refuses to run if there are unexpected arguments.
+
+JH/09 Bug 1700: ignore space & tab embedded in base64 during decode.
+
+JH/10 Bug 840: fix log_defer_output option of pipe transport
+
+JH/11 Bug 830: use same host for all RCPTS of a message, even under
+ hosts_randomize. This matters a lot when combined with mua_wrapper.
+
+JH/12 Bug 1706: percent and underbar characters are no longer escaped by the
+ ${quote_pgsql:<string>} operator.
+
+JH/13 Bug 1708: avoid misaligned access in cached lookup.
+
+JH/14 Change header file name for freeradius-client. Relevant if compiling
+ with Radius support; from the Gentoo tree and checked under Fedora.
+
+JH/15 Bug 1712: Introduce $prdr_requested flag variable
+
+JH/16 Bug 1714: Permit an empty string as expansion result for transport
+ option transport_filter, meaning no filtering.
+
+JH/17 Bug 1713: Fix non-PDKIM_DEBUG build. Patch from Jasen Betts.
+
+JH/18 Bug 1709: When built with TLS support, the tls_advertise_hosts option now
+ defaults to "*" (all hosts). The variable is now available when not built
+ with TLS, default unset, mainly to enable keeping the testuite sane.
+ If a server certificate is not supplied (via tls_certificate) an error is
+ logged, and clients will find TLS connections fail on startup. Presumably
+ they will retry in-clear.
+ Packagers of Exim are strongly encouraged to create a server certificate
+ at installation time.
+
+HS/03 Add -bP config_file as a synonym for -bP configure_file, for consistency
+ with the $config_file variable.
+
+JH/19 Two additional event types: msg:rcpt:defer and msg:rcpt:host:defer. Both
+ in transport context, after the attempt, and per-recipient. The latter type
+ is per host attempted. The event data is the error message, and the errno
+ information encodes the lookup type (A vs. MX) used for the (first) host,
+ and the trailing two digits of the smtp 4xx reponse.
+
+GF/01 Bug 1715: Fix for race condition in exicyclog, where exim could attempt
+ to write to mainlog (or rejectlog, paniclog) in the window between file
+ creation and permissions/ownership being changed. Particularly affects
+ installations where exicyclog is run as root, rather than exim user;
+ result is that the running daemon panics and dies.
+
+JH/20 Bug 1701: For MySQL lookups, support MySQL config file option group names.
+
+JH/21 Bug 1720: Add support for priority groups and weighted-random proxy
+ selection for the EXPERIMENTAL_SOCKS feature, via new per-proxy options
+ "pri" and "weight". Note that the previous implicit priority given by the
+ list order is no longer honoured.
+
+JH/22 Bugs 963, 1721: Fix some corner cases in message body canonicalisation
+ for DKIM processing.
+
+JH/23 Move SOCKS5 support from Experimental to mainline, enabled for a build
+ by defining SUPPORT_SOCKS.
+
+JH/26 Move PROXY support from Experimental to mainline, enabled for a build
+ by defining SUPPORT_PROXY. Note that the proxy_required_hosts option
+ is renamed to hosts_proxy, and the proxy_{host,target}_{address,port}.
+ variables are renamed to proxy_{local,external}_{address,port}.
+
+JH/27 Move Internationalisation support from Experimental to mainline, enabled
+ for a build by defining SUPPORT_I18N
+
+JH/28 Bug 1745: Fix redis lookups to handle (quoted) spaces embedded in parts
+ of the query string, and make ${quote_redis:} do that quoting.
+
+JH/29 Move Events support from Experimental to mainline, enabled by default
+ and removable for a build by defining DISABLE_EVENT.
+
+JH/30 Updated DANE implementation code to current from Viktor Dukhovni.
+
+JH/31 Fix bug with hosts_connection_nolog and named-lists which were wrongly
+ cached by the daemon.
+
+JH/32 Move Redis support from Experimental to mainline, enabled for a build
+ by defining LOOKUP_REDIS. The libhiredis library is required.
+
+JH/33 Bug 1748: Permit ACL dnslists= condition in non-smtp ACLs if explicit
+ keys are given for lookup.
+
+
Exim version 4.86
-----------------
JH/01 Bug 1545: The smtp transport option "retry_include_ip_address" is now
it.
JH/04 Certificate name checking on server certificates, when exim is a client,
- is now done by default. The transport option tls_verify_cert_hostname
+ is now done by default. The transport option tls_verify_cert_hostnames
can be used to disable this per-host. The build option
EXPERIMENTAL_CERTNAMES is withdrawn.
JH/09 A timeout of 2 minutes is now applied to all malware scanner types by
default, modifiable by a malware= option. The list separator for
- the options can now be changed in the usual way.
+ the options can now be changed in the usual way. Bug 68.
JH/10 The smtp_receive_timeout main option is now expanded before use.
+JH/11 The incoming_interface log option now also enables logging of the
+ local interface on delivery outgoing connections.
+
+JH/12 The cutthrough-routing facility now supports multi-recipient mails,
+ if the interface and destination host and port all match.
+
+JH/13 Bug 344: The verify = reverse_host_lookup ACL condition now accepts a
+ /defer_ok option.
+
+JH/14 Bug 1573: The spam= ACL condition now additionally supports Rspamd.
+ Patch from Andrew Lewis.
+
+JH/15 Bug 670: The spamd_address main option (for the spam= ACL condition)
+ now supports optional time-restrictions, weighting, and priority
+ modifiers per server. Patch originally by <rommer@active.by>.
+
+JH/16 The spamd_address main option now supports a mixed list of local
+ and remote servers. Remote servers can be IPv6 addresses, and
+ specify a port-range.
+
+JH/17 Bug 68: The spamd_address main option now supports an optional
+ timeout value per server.
+
+JH/18 Bug 1581: Router and transport options headers_add/remove can
+ now have the list separator specified.
+
+JH/19 Bug 392: spamd_address, and clamd av_scanner, now support retry
+ option values.
+
+JH/20 Bug 1571: Ensure that $tls_in_peerdn is set, when verification fails
+ under OpenSSL.
+
+JH/21 Support for the A6 type of dns record is withdrawn.
+
+JH/22 Bug 608: The result of a QUIT or not-QUIT toplevel ACL now matters
+ rather than the verbs used.
+
+JH/23 Bug 1572: Increase limit on SMTP confirmation message copy size
+ from 255 to 1024 chars.
+
+JH/24 Verification callouts now attempt to use TLS by default.
+
+HS/01 DNSSEC options (dnssec_require_domains, dnssec_request_domains)
+ are generic router options now. The defaults didn't change.
+
+JH/25 Bug 466: Add RFC2322 support for MIME attachment filenames.
+ Original patch from Alexander Shikoff, worked over by JH.
+
+HS/02 Bug 1575: exigrep falls back to autodetection of compressed
+ files if ZCAT_COMMAND is not executable.
+
+JH/26 Bug 1539: Add timout/retry options on dnsdb lookups.
+
+JH/27 Bug 286: Support SOA lookup in dnsdb lookups.
+
+JH/28 Bug 1588: Do not use the A lookup following an AAAA for setting the FQDN.
+ Normally benign, it bites when the pair was led to by a CNAME;
+ modern usage is to not canoicalize the domain to a CNAME target
+ (and we were inconsistent anyway for A-only vs AAAA+A).
+
+JH/29 Bug 1632: Removed the word "rejected" from line logged for ACL discards.
+
+JH/30 Check the forward DNS lookup for DNSSEC, in addition to the reverse,
+ when evaluating $sender_host_dnssec.
+
+JH/31 Check the HELO verification lookup for DNSSEC, adding new
+ $sender_helo_dnssec variable.
+
+JH/32 Bug 1397: Enable ECDHE on OpenSSL, just the NIST P-256 curve.
+
+JH/33 Bug 1346: Note MAIL cmd seen in -bS batch, to avoid smtp_no_mail log.
+
+JH/34 Bug 1648: Fix a memory leak seen with "mailq" and large queues.
+
+JH/35 Bug 1642: Fix support of $spam_ variables at delivery time. Was
+ documented as working, but never had. Support all but $spam_report.
+
+JH/36 Bug 1659: Guard checking of input smtp commands again pseudo-command
+ added for tls authenticator.
Exim version 4.85
option "timezone" setting for output formatting, and are consistent
between OpenSSL and GnuTLS compilations. Bug 1541.
-JH/11 Fix a crash in mime ACL when meeting a zero-length parameter in the
- incoming message.
+JH/11 Fix a crash in mime ACL when meeting a zero-length, quoted or RFC2047-
+ encoded parameter in the incoming message. Bug 1558.
JH/12 Bug 1527: Autogrow buffer used in reading spool files. Since they now
include certificate info, eximon was claiming there were spoolfile
syntax errors.
-JH/13 Buf 1521: Fix ldap lookup for single-attr request, multiple-attr return.
+JH/13 Bug 1521: Fix ldap lookup for single-attr request, multiple-attr return.
JH/14 Log delivery-related information more consistently, using the sequence
"H=<name> [<ip>]" wherever possible.
+TL/07 Bug 1547: Omit RFCs from release. Draft and RFCs have licenses which
+ are problematic for Debian distribution, omit them from the release
+ tarball.
+
+JH/15 Updates and fixes to the EXPERIMENTAL_DSN feature.
+
+JH/16 Fix string representation of time values on 64bit time_t anchitectures.
+ Bug 1561.
+
+JH/17 Fix a null-indirection in certextract expansions when a nondefault
+ output list separator was used.
+
Exim version 4.84
-----------------
test from the snapshots or the CVS before the documentation is updated. Once
the documentation is updated, this file is reduced to a short list.
+Version 4.87
+------------
+
+ 1. The ACL conditions regex and mime_regex now capture substrings
+ into numeric variables $regex1 to 9, like the "match" expansion condition.
+
+ 2. New $callout_address variable records the address used for a spam=,
+ malware= or verify= callout.
+
+ 3. Transports now take a "max_parallel" option, to limit concurrency.
+
+ 4. Expansion operators ${ipv6norm:<string>} and ${ipv6denorm:<string>}.
+ The latter expands to a 8-element colon-sep set of hex digits including
+ leading zeroes. A trailing ipv4-style dotted-decimal set is converted
+ to hex. Pure ipv4 addresses are converted to IPv4-mapped IPv6.
+ The former operator strips leading zeroes and collapses the longest
+ set of 0-groups to a double-colon.
+
+ 5. New "-bP config" support, to dump the effective configuration.
+
+ 6. New $dkim_key_length variable.
+
+
Version 4.86
------------
3. New "malware=" support for Avast.
+ 4. New "spam=" variant option for Rspamd.
+
+ 5. Assorted options on malware= and spam= scanners.
+
+ 6. A commandline option to write a comment into the logfile.
+
+ 7. If built with EXPERIMENTAL_SOCKS feature enabled, the smtp transport can
+ be configured to make connections via socks5 proxies.
+
+ 8. If built with EXPERIMENTAL_INTERNATIONAL, support is included for
+ the transmission of UTF-8 envelope addresses.
+
+ 9. If built with EXPERIMENTAL_INTERNATIONAL, an expansion item for a commonly
+ used encoding of Maildir folder names.
+
+10. A logging option for slow DNS lookups.
+
+11. New ${env {<variable>}} expansion.
+
+12. A non-SMTP authenticator using information from TLS client certificates.
+
+13. Main option "tls_eccurve" for selecting an Elliptic Curve for TLS.
+ Patch originally by Wolfgang Breyha.
+
+14. Main option "dns_trust_aa" for trusting your local nameserver at the
+ same level as DNSSEC.
+
+
Version 4.85
------------
would relax host matching rules to a broader network range.
+A lookup expansion is also available. It takes an email
+address as the key and an IP address as the database:
+
+ $lookup (username@domain} spf {ip.ip.ip.ip}}
+
+The lookup will return the same result strings as they can appear in
+$spf_result (pass,fail,softfail,neutral,none,err_perm,err_temp).
+Currently, only IPv4 addresses are supported.
+
+
+
SRS (Sender Rewriting Scheme) Support
--------------------------------------------------------------
DCC Support
--------------------------------------------------------------
+Distributed Checksum Clearinghouse; http://www.rhyolite.com/dcc/
*) Building exim
configure a dmarc_forensic_sender because the default sender address
construction might be inadequate.
- control = dmarc_forensic_enable
+ control = dmarc_enable_forensic
(AGAIN: You can choose not to send these forensic reports by simply
-not putting the dmarc_forensic_enable control line at any point in
+not putting the dmarc_enable_forensic control line at any point in
your exim config. If you don't tell it to send them, it will not
send them.)
deny dmarc_status = reject
!authenticated = *
- message = Message from $domain_used_domain failed sender's DMARC policy, REJECT
-
-
-
-Event Actions
---------------------------------------------------------------
-
-(Renamed from TPDA, Transport post-delivery actions)
-
-An arbitrary per-transport string can be expanded upon various transport events.
-Additionally a main-section configuration option can be expanded on some
-per-message events.
-This feature may be used, for example, to write exim internal log information
-(not available otherwise) into a database.
-
-In order to use the feature, you must compile with
-
-EXPERIMENTAL_EVENT=yes
-
-in your Local/Makefile
-
-and define one or both of
-- the event_action option in the transport
-- the event_action main option
-to be expanded when the event fires.
-
-A new variable, $event_name, is set to the event type when the
-expansion is done. The current list of events is:
-
- msg:complete after main per message
- msg:delivery after transport per recipient
- msg:host:defer after transport per attempt
- msg:fail:delivery after main per recipient
- msg:fail:internal after main per recipient
- tcp:connect before transport per connection
- tcp:close after transport per connection
- tls:cert before both per certificate in verification chain
- smtp:connect after transport per connection
-
-The expansion is called for all event types, and should use the $event_name
-value to decide when to act. The variable data is a colon-separated
-list, describing an event tree.
-
-There is an auxilary variable, $event_data, for which the
-content is event_dependent:
-
- msg:delivery smtp confirmation mssage
- msg:host:defer error string
- tls:cert verification chain depth
- smtp:connect smtp banner
-
-The msg:host:defer event populates one extra variable, $event_defer_errno.
-
-The following variables are likely to be useful depending on the event type:
-
- router_name, transport_name
- local_part, domain
- host, host_address, host_port
- tls_out_peercert
- lookup_dnssec_authenticated, tls_out_dane
- sending_ip_address, sending_port
- message_exim_id, verify_mode
-
-
-An example might look like:
-
-event_action = ${if = {msg:delivery}{$event_name} \
-{${lookup pgsql {SELECT * FROM record_Delivery( \
- '${quote_pgsql:$sender_address_domain}',\
- '${quote_pgsql:${lc:$sender_address_local_part}}', \
- '${quote_pgsql:$domain}', \
- '${quote_pgsql:${lc:$local_part}}', \
- '${quote_pgsql:$host_address}', \
- '${quote_pgsql:${lc:$host}}', \
- '${quote_pgsql:$message_exim_id}')}} \
-} {}}
-
-The string is expanded when each of the supported events occur
-and any side-effects of the expansion will happen.
-Note that for complex operations an ACL expansion can be used.
-
-
-The expansion of the event_action option should normally
-return an empty string. Should it return anything else the
-following will be forced:
-
- msg:delivery (ignored)
- msg:host:defer (ignored)
- msg:fail:delivery (ignored)
- tcp:connect do not connect
- tcp:close (ignored)
- tls:cert refuse verification
- smtp:connect close connection
-
-No other use is made of the result string.
-
-
-Known issues:
-- the tls:cert event is only called for the cert chain elements
- received over the wire, with GnuTLS. OpenSSL gives the entire
- chain including thse loaded locally.
-
-
-Redis Lookup
---------------------------------------------------------------
-
-Redis is open source advanced key-value data store. This document
-does not explain the fundamentals, you should read and understand how
-it works by visiting the website at http://www.redis.io/.
-
-Redis lookup support is added via the hiredis library. Visit:
-
- https://github.com/redis/hiredis
-
-to obtain a copy, or find it in your operating systems package repository.
-If building from source, this description assumes that headers will be in
-/usr/local/include, and that the libraries are in /usr/local/lib.
-
-1. In order to build exim with Redis lookup support add
-
-EXPERIMENTAL_REDIS=yes
-
-to your Local/Makefile. (Re-)build/install exim. exim -d should show
-Experimental_Redis in the line "Support for:".
-
-EXPERIMENTAL_REDIS=yes
-LDFLAGS += -lhiredis
-# CFLAGS += -I/usr/local/include
-# LDFLAGS += -L/usr/local/lib
-
-The first line sets the feature to include the correct code, and
-the second line says to link the hiredis libraries into the
-exim binary. The commented out lines should be uncommented if you
-built hiredis from source and installed in the default location.
-Adjust the paths if you installed them elsewhere, but you do not
-need to uncomment them if an rpm (or you) installed them in the
-package controlled locations (/usr/include and /usr/lib).
-
-
-2. Use the following global settings to configure Redis lookup support:
-
-Required:
-redis_servers This option provides a list of Redis servers
- and associated connection data, to be used in
- conjunction with redis lookups. The option is
- only available if Exim is configured with Redis
- support.
-
-For example:
-
-redis_servers = 127.0.0.1/10/ - using database 10 with no password
-redis_servers = 127.0.0.1//password - to make use of the default database of 0 with a password
-redis_servers = 127.0.0.1// - for default database of 0 with no password
-
-3. Once you have the Redis servers defined you can then make use of the
-experimental Redis lookup by specifying ${lookup redis{}} in a lookup query.
-
-4. Example usage:
-
-(Host List)
-hostlist relay_from_ips = <\n ${lookup redis{SMEMBERS relay_from_ips}}
-
-Where relay_from_ips is a Redis set which contains entries such as "192.168.0.0/24" "10.0.0.0/8" and so on.
-The result set is returned as
-192.168.0.0/24
-10.0.0.0/8
-..
-.
-
-(Domain list)
-domainlist virtual_domains = ${lookup redis {HGET $domain domain}}
-
-Where $domain is a hash which includes the key 'domain' and the value '$domain'.
-
-(Adding or updating an existing key)
-set acl_c_spammer = ${if eq{${lookup redis{SPAMMER_SET}}}{OK}}
-
-Where SPAMMER_SET is a macro and it is defined as
-
-"SET SPAMMER <some_value>"
-
-(Getting a value from Redis)
-
-set acl_c_spam_host = ${lookup redis{GET...}}
-
-
-Proxy Protocol Support
---------------------------------------------------------------
-
-Exim now has Experimental "Proxy Protocol" support. It was built on
-specifications from:
-http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt
-Above URL revised May 2014 to change version 2 spec:
-http://git.1wt.eu/web?p=haproxy.git;a=commitdiff;h=afb768340c9d7e50d8e
-
-The purpose of this function is so that an application load balancer,
-such as HAProxy, can sit in front of several Exim servers and Exim
-will log the IP that is connecting to the proxy server instead of
-the IP of the proxy server when it connects to Exim. It resets the
-$sender_address_host and $sender_address_port to the IP:port of the
-connection to the proxy. It also re-queries the DNS information for
-this new IP address so that the original sender's hostname and IP
-get logged in the Exim logfile. There is no logging if a host passes or
-fails Proxy Protocol negotiation, but it can easily be determined and
-recorded in an ACL (example is below).
-
-1. To compile Exim with Proxy Protocol support, put this in
-Local/Makefile:
-
-EXPERIMENTAL_PROXY=yes
-
-2. Global configuration settings:
-
-proxy_required_hosts = HOSTLIST
-
-The proxy_required_hosts option will require any IP in that hostlist
-to use Proxy Protocol. The specification of Proxy Protocol is very
-strict, and if proxy negotiation fails, Exim will not allow any SMTP
-command other than QUIT. (See end of this section for an example.)
-The option is expanded when used, so it can be a hostlist as well as
-string of IP addresses. Since it is expanded, specifying an alternate
-separator is supported for ease of use with IPv6 addresses.
-
-To log the IP of the proxy in the incoming logline, add:
- log_selector = +proxy
-
-A default incoming logline (wrapped for appearance) will look like this:
-
- 2013-11-04 09:25:06 1VdNti-0001OY-1V <= me@example.net
- H=mail.example.net [1.2.3.4] P=esmtp S=433
-
-With the log selector enabled, an email that was proxied through a
-Proxy Protocol server at 192.168.1.2 will look like this:
-
- 2013-11-04 09:25:06 1VdNti-0001OY-1V <= me@example.net
- H=mail.example.net [1.2.3.4] P=esmtp PRX=192.168.1.2 S=433
-
-3. In the ACL's the following expansion variables are available.
-
-proxy_host_address The (internal) src IP of the proxy server
- making the connection to the Exim server.
-proxy_host_port The (internal) src port the proxy server is
- using to connect to the Exim server.
-proxy_target_address The dest (public) IP of the remote host to
- the proxy server.
-proxy_target_port The dest port the remote host is using to
- connect to the proxy server.
-proxy_session Boolean, yes/no, the connected host is required
- to use Proxy Protocol.
-
-There is no expansion for a failed proxy session, however you can detect
-it by checking if $proxy_session is true but $proxy_host is empty. As
-an example, in my connect ACL, I have:
-
- warn condition = ${if and{ {bool{$proxy_session}} \
- {eq{$proxy_host_address}{}} } }
- log_message = Failed required proxy protocol negotiation \
- from $sender_host_name [$sender_host_address]
-
- warn condition = ${if and{ {bool{$proxy_session}} \
- {!eq{$proxy_host_address}{}} } }
- # But don't log health probes from the proxy itself
- condition = ${if eq{$proxy_host_address}{$sender_host_address} \
- {false}{true}}
- log_message = Successfully proxied from $sender_host_name \
- [$sender_host_address] through proxy protocol \
- host $proxy_host_address
-
- # Possibly more clear
- warn logwrite = Remote Source Address: $sender_host_address:$sender_host_port
- logwrite = Proxy Target Address: $proxy_target_address:$proxy_target_port
- logwrite = Proxy Internal Address: $proxy_host_address:$proxy_host_port
- logwrite = Internal Server Address: $received_ip_address:$received_port
-
-
-4. Recommended ACL additions:
- - Since the real connections are all coming from your proxy, and the
- per host connection tracking is done before Proxy Protocol is
- evaluated, smtp_accept_max_per_host must be set high enough to
- handle all of the parallel volume you expect per inbound proxy.
- - With the smtp_accept_max_per_host set so high, you lose the ability
- to protect your server from massive numbers of inbound connections
- from one IP. In order to prevent your server from being DOS'd, you
- need to add a per connection ratelimit to your connect ACL. I
- suggest something like this:
-
- # Set max number of connections per host
- LIMIT = 5
- # Or do some kind of IP lookup in a flat file or database
- # LIMIT = ${lookup{$sender_host_address}iplsearch{/etc/exim/proxy_limits}}
-
- defer message = Too many connections from this IP right now
- ratelimit = LIMIT / 5s / per_conn / strict
-
-
-5. Runtime issues to be aware of:
- - The proxy has 3 seconds (hard-coded in the source code) to send the
- required Proxy Protocol header after it connects. If it does not,
- the response to any commands will be:
- "503 Command refused, required Proxy negotiation failed"
- - If the incoming connection is configured in Exim to be a Proxy
- Protocol host, but the proxy is not sending the header, the banner
- does not get sent until the timeout occurs. If the sending host
- sent any input (before the banner), this causes a standard Exim
- synchronization error (i.e. trying to pipeline before PIPELINING
- was advertised).
- - This is not advised, but is mentioned for completeness if you have
- a specific internal configuration that you want this: If the Exim
- server only has an internal IP address and no other machines in your
- organization will connect to it to try to send email, you may
- simply set the hostlist to "*", however, this will prevent local
- mail programs from working because that would require mail from
- localhost to use Proxy Protocol. Again, not advised!
-
-6. Example of a refused connection because the Proxy Protocol header was
-not sent from a host configured to use Proxy Protocol. In the example,
-the 3 second timeout occurred (when a Proxy Protocol banner should have
-been sent), the banner was displayed to the user, but all commands are
-rejected except for QUIT:
-
-# nc mail.example.net 25
-220-mail.example.net, ESMTP Exim 4.82+proxy, Mon, 04 Nov 2013 10:45:59
-220 -0800 RFC's enforced
-EHLO localhost
-503 Command refused, required Proxy negotiation failed
-QUIT
-221 mail.example.net closing connection
-
+ message = Message from $dmarc_used_domain failed sender's DMARC policy, REJECT
A TLSA lookup will be done if either of the above options match
and the host-lookup succeded using dnssec.
-If the TLSA lookup succeeds, a TLS connection will be required
-for the host.
+If a TLSA lookup is done and succeeds, a DANE-verified TLS connection
+will be required for the host.
(TODO: specify when fallback happens vs. when the host is not used)
-If dane is in use the following transport options are ignored:
+If DANE is requested and useable (see above) the following transport
+options are ignored:
hosts_require_tls
tls_verify_hosts
tls_try_verify_hosts
tls_crl
tls_verify_cert_hostnames
+If DANE is not usable, whether requested or not, and CA-anchored
+verification evaluation is wanted, the above variables should be set
+appropriately.
+
Currently dnssec_request_domains must be active (need to think about that)
and dnssec_require_domains is ignored.
$tls_out_tlsa_usage (detailed above).
+
+DSN extra information
+---------------------
+If compiled with EXPERIMENTAL_DSN_INFO extra information will be added
+to DSN fail messages ("bounces"), when available. The intent is to aid
+tracing of specific failing messages, when presented with a "bounce"
+complaint and needing to search logs.
+
+
+The remote MTA IP address, with port number if nonstandard.
+Example:
+ Remote-MTA: X-ip; [127.0.0.1]:587
+Rationale:
+ Several addresses may correspond to the (already available)
+ dns name for the remote MTA.
+
+The remote MTA connect-time greeting.
+Example:
+ X-Remote-MTA-smtp-greeting: X-str; 220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+Rationale:
+ This string sometimes presents the remote MTA's idea of its
+ own name, and sometimes identifies the MTA software.
+
+The remote MTA response to HELO or EHLO.
+Example:
+ X-Remote-MTA-helo-response: X-str; 250-the.local.host.name Hello localhost [127.0.0.1]
+Limitations:
+ Only the first line of a multiline response is recorded.
+Rationale:
+ This string sometimes presents the remote MTA's view of
+ the peer IP connecting to it.
+
+The reporting MTA detailed diagnostic.
+Example:
+ X-Exim-Diagnostic: X-str; SMTP error from remote mail server after RCPT TO:<d3@myhost.test.ex>: 550 hard error
+Rationale:
+ This string somtimes give extra information over the
+ existing (already available) Diagnostic-Code field.
+
+
+Note that non-RFC-documented field names and data types are used.
+
+
+
+
--------------------------------------------------------------
End of file
--------------------------------------------------------------
}
my $srcdir = File::Spec->catdir( $context->{release_tree}, 'src', 'src' );
- chdir $srcdir or die "chdir $srcdir: $\n";
+ chdir $srcdir or die "chdir $srcdir: $!\n";
if ( -f "version.sh" ) {
print( "WARNING: version.sh already exists - leaving it in place\n" );
my @cmd = (
$genpath, '--spec', $spec, '--filter',
$filter, '--latest', $context->{trelease}, '--tmpl',
- $templates, '--docroot', $dir, '--localstatic',
- (($verbose||$debug) ? '--verbose' : '')
+ $templates, '--docroot', $dir, '--localstatic'
);
+ push @cmd, '--verbose' if $verbose or $debug;
print "Executing ", join( ' ', @cmd ), "\n";
system(@cmd);
my $docdir = File::Spec->catdir( $context->{release_tree}, 'doc', 'doc-docbook' );
# documentation building gets the truncated release, without RC
- system("cd '$docdir' && ./OS-Fixups && make EXIM_VER=$context->{trelease} everything") == 0
+ system("cd '$docdir' && ./OS-Fixups && $context->{make_cmd} EXIM_VER=$context->{trelease} everything") == 0
|| croak "Doc build failed";
copy_docbook_files($context);
next
if ( ( $fn eq 'ABOUT' )
|| ( $fn eq 'ChangeLog.0' )
- || ( $fn eq 'test-harness.txt' ) );
+ || ( $fn eq 'test-harness.txt' )
+ # Debian issue re licensing of RFCs
+ || ( $fn =~ /^draft-ietf-.*/ )
+ || ( $fn =~ /^rfc.*/ )
+ );
move( $file, File::Spec->catfile( $new_docdir, $fn ) );
}
}
my $context = shift;
print "Cleaning up\n" if ($verbose);
+ chdir( $context->{directory} ) || die;
rmtree( $context->{release_tree}, { verbose => $debug } );
rmtree( $context->{docbook}, { verbose => $debug } );
rmtree( $context->{pkgdirs}, { verbose => $debug } );
tmp_dir => File::Temp->newdir(),
webgen_base => "$FindBin::Bin/../../../exim-website",
tar_cmd => 'tar',
+ make_cmd => 'make',
compressors => {
gzip => 1,
bzip2 => 1,
GetOptions(
'directory=s' => \$context->{directory},
'webgen_base=s' => \$context->{webgen_base},
- 'tar' => \$context->{tar_cmd},
+ 'tar=s' => \$context->{tar_cmd},
+ 'make=s' => \$context->{make_cmd},
'lzip!' => \$context->{compressors}{lzip},
'verbose!' => \$verbose,
'debug!' => \$debug,
--help display this help and exits
--man displays man page
--tar=cmd command to use for tar
+ --make=cmd command to use for make
--directory=dir dir to package
--no-lzip do not create .tar.lz files
--delete Delete packaging directory at start
gtar, and if not found use tar. Need GNU tar for lzip, unless --no-lzip is
used.
+=item B<--make>
+
+Use to override the path/name of the make command.
+Useful sometimes to force gmake.
+
=item B<--lzip>
Build the lzip tarballs.
Local
build-*
tags
-cscope.out
+cscope.*
Tom Kistner DKIM. Content scanning. SPA.
Todd Lyons
Nigel Metheringham Transitioning out of Default Victim status.
-Phil Pennock Release Coordinator. Breaks lots of things.
+Phil Pennock Mostly idle; some security bits still.
David Woodhouse Dynamic modules. Security.
Samuel Thibault Patch fixing IPv6 interface address detection on Hurd
Martin Tscholak Reported issue with TLS anonymous ciphersuites
Stephen Usher Patch fixing use of Oracle's LDAP libraries on Solaris
+Jasper Wallace Patch for LibreSSL compatibility
Holger Weiß Patch leting ${run} return more data than OS pipe
buffer size
Moritz Wilhelmy Pointed out PCRE_PRERELEASE glitch
# appropriate links, and then creating and running the main makefile in that
# directory.
-# Copyright (c) University of Cambridge, 1995 - 2014
+# Copyright (c) University of Cambridge, 1995 - 2015
# See the file NOTICE for conditions of use and distribution.
# IRIX make uses the shell that is in the SHELL variable, which often defaults
all: Local/Makefile configure
@cd build-$(buildname); $(MAKE) SHELL=$(SHELL) $(MFLAGS)
+
+# This pair for the convinience of of the Debian maintainers
+exim: Local/Makefile configure
+ @cd build-$(buildname); $(MAKE) SHELL=$(SHELL) $(MFLAGS) exim
+utils: Local/Makefile configure
+ @cd build-$(buildname); $(MAKE) SHELL=$(SHELL) $(MFLAGS) utils
+
+
Local/Makefile:
@echo ""
@echo "*** Please create Local/Makefile by copying src/EDITME and making"
find src Local OS exim_monitor -name "*.[cshyl]" -print \
-o -name "os.h*" -print \
-o -name "*akefile*" -print \
+ -o -name config.h.defaults -print \
-o -name EDITME -print >> $@
ls OS/* >> $@
SHELL = $(MAKE_SHELL)
SCRIPTS = ../scripts
+O = ../OS
EDITME = ../Local/Makefile
EXIMON_EDITME = ../Local/eximon.conf
# up-to-date. Then the os-specific source files and the C configuration file
# are set up, and finally it goes to the main Exim target.
-all: allexim
-config: $(EDITME) checklocalmake Makefile os.h os.c config.h version.h
+all: utils exim
+config: $(EDITME) checklocalmake Makefile os.c config.h version.h
-checklocalmake:
+checklocalmake:
@if $(SHELL) $(SCRIPTS)/newer $(EDITME)-$(OSTYPE) $(EDITME) || \
$(SHELL) $(SCRIPTS)/newer $(EDITME)-$(ARCHTYPE) $(EDITME) || \
$(SHELL) $(SCRIPTS)/newer $(EDITME)-$(OSTYPE)-$(ARCHTYPE) $(EDITME); \
# Build (link) the os.h file
-os.h:
+os.h: $(SCRIPTS)/Configure-os.h \
+ $(O)/os.h-AIX $(O)/os.h-BSDI $(O)/os.h-cygwin \
+ $(O)/os.h-Darwin $(O)/os.h-DGUX $(O)/os.h-DragonFly \
+ $(O)/os.h-FreeBSD $(O)/os.h-GNU $(O)/os.h-GNUkFreeBSD \
+ $(O)/os.h-GNUkNetBSD $(O)/os.h-HI-OSF \
+ $(O)/os.h-HI-UX $(O)/os.h-HP-UX $(O)/os.h-HP-UX-9 \
+ $(O)/os.h-IRIX $(O)/os.h-IRIX6 $(O)/os.h-IRIX632 \
+ $(O)/os.h-IRIX65 $(O)/os.h-Linux $(O)/os.h-mips \
+ $(O)/os.h-NetBSD $(O)/os.h-NetBSD-a.out \
+ $(O)/os.h-OpenBSD $(O)/os.h-OpenUNIX $(O)/os.h-OSF1 \
+ $(O)/os.h-QNX $(O)/os.h-SCO $(O)/os.h-SCO_SV \
+ $(O)/os.h-SunOS4 $(O)/os.h-SunOS5 $(O)/os.h-SunOS5-hal \
+ $(O)/os.h-ULTRIX $(O)/os.h-UNIX_SV \
+ $(O)/os.h-Unixware7 $(O)/os.h-USG
$(SHELL) $(SCRIPTS)/Configure-os.h
# Build the os.c file
-os.c: ../src/os.c
+os.c: ../src/os.c \
+ $(SCRIPTS)/Configure-os.c \
+ $(O)/os.c-cygwin $(O)/os.c-GNU $(O)/os.c-HI-OSF \
+ $(O)/os.c-IRIX $(O)/os.c-IRIX6 $(O)/os.c-IRIX632 \
+ $(O)/os.c-IRIX65 $(O)/os.c-Linux $(O)/os.c-OSF1
$(SHELL) $(SCRIPTS)/Configure-os.c
# Build the config.h file.
# therefore always be run, even if the files exist. This shouldn't in fact be a
# problem, but it does no harm. Other make programs will just ignore this.
-.PHONY: all config allexim buildauths buildlookups buildpdkim buildrouters \
+.PHONY: all config utils \
+ buildauths buildlookups buildpdkim buildrouters \
buildtransports checklocalmake clean
-# This is the real default target for all the various exim binaries and
-# scripts, once the configuring stuff is done.
-
-allexim: $(EXIM_MONITOR) exicyclog exinext exiwhat \
+utils: $(EXIM_MONITOR) exicyclog exinext exiwhat \
exigrep eximstats exipick exiqgrep exiqsumm \
transport-filter.pl convert4r3 convert4r4 \
exim_checkaccess \
- exim_dbmbuild exim_dumpdb exim_fixdb exim_tidydb exim_lock \
- exim
+ exim_dbmbuild exim_dumpdb exim_fixdb exim_tidydb exim_lock
# Targets for special-purpose configuration header builders
OBJ_WITH_CONTENT_SCAN = malware.o mime.o regex.o spam.o spool_mbox.o
OBJ_WITH_OLD_DEMIME = demime.o
-OBJ_EXPERIMENTAL = bmi_spam.o spf.o srs.o dcc.o dmarc.o dane.o
+OBJ_EXPERIMENTAL = bmi_spam.o \
+ dane.o \
+ dcc.o \
+ dmarc.o \
+ imap_utf7.o \
+ spf.o \
+ srs.o \
+ utf8.o
# Targets for final binaries; the main one has a build number which is
# updated each time. We don't bother with that for the auxiliaries.
# The utility for locking a mailbox while messing around with it
-exim_lock: exim_lock.c
+exim_lock: exim_lock.c os.h
@echo "$(CC) exim_lock.c"
$(FE)$(CC) -c $(CFLAGS) $(INCLUDE) exim_lock.c
@echo "$(LNCC) -o exim_lock"
# in one. This list is overkill, but it doesn't really take much time to
# rebuild Exim on a modern computer.
-HDRS = config.h dbfunctions.h dbstuff.h exim.h functions.h globals.h local_scan.h macros.h mytypes.h structs.h
-PHDRS = ../config.h ../dbfunctions.h ../dbstuff.h ../exim.h ../functions.h ../globals.h ../local_scan.h ../macros.h ../mytypes.h ../structs.h
+HDRS = config.h \
+ dbfunctions.h \
+ dbstuff.h \
+ exim.h \
+ functions.h \
+ globals.h \
+ local_scan.h \
+ macros.h \
+ mytypes.h \
+ structs.h \
+ os.h
+PHDRS = ../config.h \
+ ../dbfunctions.h \
+ ../dbstuff.h \
+ ../exim.h \
+ ../functions.h \
+ ../globals.h \
+ ../local_scan.h \
+ ../macros.h \
+ ../mytypes.h \
+ ../structs.h \
+ ../os.h
.SUFFIXES: .o .c
.c.o:; @echo "$(CC) $*.c"
std-crypto.o: $(HDRS) std-crypto.c
store.o: $(HDRS) store.c
string.o: $(HDRS) string.c
-tls.o: $(HDRS) tls.c tls-gnu.c tlscert-gnu.c tls-openssl.c tlscert-openssl.c
+tls.o: $(HDRS) tls.c setenv.c \
+ tls-gnu.c tlscert-gnu.c \
+ tls-openssl.c tlscert-openssl.c
tod.o: $(HDRS) tod.c
transport.o: $(HDRS) transport.c
tree.o: $(HDRS) tree.c
verify.o: $(HDRS) verify.c
-dkim.o: $(HDRS) dkim.c
+dkim.o: $(HDRS) pdkim/pdkim.h dkim.c
# Dependencies for WITH_CONTENT_SCAN modules
# Dependencies for WITH_OLD_DEMIME modules
-demime.o: $(HDRS) demime.c
+demime.o: $(HDRS) demime.c
# Dependencies for EXPERIMENTAL_* modules
-bmi_spam.o: $(HDRS) bmi_spam.c
-dane.o: $(HDRS) dane.c dane-gnu.c dane-openssl.c
-dcc.o: $(HDRS) dcc.h dcc.c
-dmarc.o: $(HDRS) dmarc.h dmarc.c
-spf.o: $(HDRS) spf.h spf.c
-srs.o: $(HDRS) srs.h srs.c
+bmi_spam.o: $(HDRS) bmi_spam.c
+dane.o: $(HDRS) dane.c dane-gnu.c dane-openssl.c
+dcc.o: $(HDRS) dcc.h dcc.c
+dmarc.o: $(HDRS) pdkim/pdkim.h dmarc.h dmarc.c
+imap_utf7.o: $(HDRS) imap_utf7.c
+spf.o: $(HDRS) spf.h spf.c
+srs.o: $(HDRS) srs.h srs.c
+utf8.o: $(HDRS) utf8.c
# The module containing tables of available lookups, routers, auths, and
# transports must be rebuilt if any of them are. However, because the makefiles
# These are the test targets themselves
test_dbfn: config.h dbfn.c dummies.o sa-globals.o sa-os.o store.o \
- string.o tod.o version.o
+ string.o tod.o version.o utf8.o
$(CC) -c $(CFLAGS) $(INCLUDE) -DSTAND_ALONE dbfn.c
$(LNCC) -o test_dbfn $(LFLAGS) dbfn.o \
dummies.o sa-globals.o sa-os.o store.o string.o \
- tod.o version.o $(LIBS) $(DBMLIB)
+ tod.o version.o utf8.o $(LIBS) $(DBMLIB) $(LDFLAGS)
rm -f dbfn.o
test_host: config.h child.c host.c dns.c dummies.c sa-globals.o os.o \
tod.o tree.o $(LIBS) $(LIBRESOLV)
rm -f child.o dummies.o host.o dns.o
-test_os: os.h os.c dummies.o sa-globals.o store.o string.o tod.o
+test_os: os.h os.c dummies.o sa-globals.o store.o string.o tod.o utf8.o
$(CC) -c $(CFLAGS) $(INCLUDE) -DSTAND_ALONE os.c
$(LNCC) -o test_os $(LFLAGS) os.o dummies.o \
- sa-globals.o store.o string.o tod.o $(LIBS)
+ sa-globals.o store.o string.o tod.o utf8.o $(LIBS) $(LDFLAGS)
rm -f os.o
test_parse: config.h parse.c dummies.o sa-globals.o \
- store.o string.o tod.o version.o
+ store.o string.o tod.o version.o utf8.o
$(CC) -c $(CFLAGS) $(INCLUDE) -DSTAND_ALONE parse.c
$(LNCC) -o test_parse $(LFLAGS) parse.o \
- dummies.o sa-globals.o store.o string.o tod.o version.o
+ dummies.o sa-globals.o store.o string.o tod.o version.o \
+ utf8.o $(LDFLAGS)
rm -f parse.o
-test_string: config.h string.c dummies.o sa-globals.o store.o tod.o
+test_string: config.h string.c dummies.o sa-globals.o store.o tod.o utf8.o
$(CC) -c $(CFLAGS) $(INCLUDE) -DSTAND_ALONE string.c
$(LNCC) -o test_string $(LFLAGS) -DSTAND_ALONE string.o \
- dummies.o sa-globals.o store.o tod.o $(LIBS)
+ dummies.o sa-globals.o store.o tod.o utf8.o $(LIBS) $(LDFLAGS)
rm -f string.o
# End
# This file provided by Pierre A. Humblet <Pierre.Humblet@ieee.org>
+HAVE_IPV6 = yes
HAVE_ICONV = yes
-CFLAGS= -g -Wall -O2
+# Use c99 to have %z
+CFLAGS= -g -Wall -std=c99 -U __STRICT_ANSI__
LIBS= -lcrypt -lresolv
LIBS_EXIM= -liconv
EXIWHAT_PS_ARG=-as
SUPPORT_PAM=yes
CFLAGS += -DINCLUDE_PAM -I ../pam -I ../../pam
-APPENDFILE_MODE = 0644 # default if no ntsec
-APPENDFILE_DIRECTORY_MODE = 0777
-APPENDFILE_LOCKFILE_MODE = 0666
-EXIMDB_DIRECTORY_MODE = 0777
+# All modes are in octal and must start with 0
+EXIMDB_DIRECTORY_MODE = 01777
EXIMDB_MODE = 0666
EXIMDB_LOCKFILE_MODE = 0666
-INPUT_DIRECTORY_MODE = 0777
-LOG_DIRECTORY_MODE = 0777
+INPUT_DIRECTORY_MODE = 01777
+LOG_DIRECTORY_MODE = 01777
LOG_MODE = 0666
-MSGLOG_DIRECTORY_MODE = 0777
-SPOOL_DIRECTORY_MODE = 0777
-SPOOL_MODE = 0666
+MSGLOG_DIRECTORY_MODE = 01777
+SPOOL_DIRECTORY_MODE = 01777
+SPOOL_MODE = 0600
# End
# IPV6_USE_INET_PTON=yes
-# Setting the next option brings in support for A6 DNS records for IPV6. These
-# were at one time expected to supplant AAAA records, but were eventually
-# rejected. The code remains in Exim, but has not been compiled or tested for
-# quite some time. Do not set this unless you know what you are doing.
-
-# SUPPORT_A6=yes
-
-
# HOSTNAME_COMMAND contains the path to the "hostname" command, which varies
# from OS to OS. This is used when building the Exim monitor script only. (See
# also BASENAME_COMMAND.) If HOSTNAME_COMMAND is set to "look_for_it" then the
* Exim - an Internet mail transport agent *
*************************************************/
-/* Cygwin-specific code. December 2002
- This is concatenated onto the generic src/os.c file.
+/* Cygwin-specific code. December 2002. Updated Jan 2015.
+ This is prefixed to the src/os.c file.
This code was supplied by Pierre A. Humblet <Pierre.Humblet@ieee.org>
*/
return mkdir(p, mode);
}
-/* We have strsignal but cannot use #define
- because types don't match */
-#define OS_STRSIGNAL /* src/os.c need not provide it */
-char * os_strsignal(int sig)
-{
- return (char *) strsignal(sig);
-}
-
#ifndef COMPILE_UTILITY /* Utilities don't need special code */
-#ifdef INCLUDE_MINIRES
-#include "../minires/minires.c"
-#include "../minires/os-interface.c"
-#endif
#ifdef INCLUDE_PAM
#include "../pam/pam.c"
#endif
+#include <alloca.h>
unsigned int cygwin_WinVersion;
#endif
#include <windows.h>
+#include <ntstatus.h>
+#include <lmcons.h>
+
#define EqualLuid(Luid1, Luid2) \
((Luid1.LowPart == Luid2.LowPart) && (Luid1.HighPart == Luid2.HighPart))
#include <sys/cygwin.h>
/* Special static variables */
static BOOL cygwin_debug = FALSE;
-static int privileged = 1; /* when not privileged, setuid = noop */
+static int fakesetugid = 1; /* when not privileged, setugid = noop */
#undef setuid
int cygwin_setuid(uid_t uid )
{
- int res;
- if (privileged <= 0) return 0;
- else {
+ int res = 0;
+ if (fakesetugid == 0) {
res = setuid(uid);
if (cygwin_debug)
- fprintf(stderr, "setuid %lu %lu %d pid: %d\n",
+ fprintf(stderr, "setuid %u %u %d pid: %d\n",
uid, getuid(),res, getpid());
}
return res;
#undef setgid
int cygwin_setgid(gid_t gid )
{
- int res;
- if (privileged <= 0) return 0;
- else {
+ int res = 0;
+ if (fakesetugid == 0) {
res = setgid(gid);
if (cygwin_debug)
- fprintf(stderr, "setgid %lu %lu %d pid: %d\n",
+ fprintf(stderr, "setgid %u %u %d pid: %d\n",
gid, getgid(), res, getpid());
}
return res;
Next byte: 0
Next byte: minor version of OS
Low byte: major version of OS (3 or 4 for for NT, 5 for 2000 and XP) */
-#define VERSION_IS_58M(x) (x & 0x80000000) /* 95, 98, Me */
-#define VERSION_IS_NT(x) ((x & 0XFF) < 5) /* NT 4 or 3.51 */
+//#define VERSION_IS_58M(x) (x & 0x80000000) /* 95, 98, Me */
+//#define VERSION_IS_NT(x) ((x & 0XFF) < 5) /* NT 4 or 3.51 */
/*
Routine to find if process or thread is privileged
enum {
CREATE_BIT = 1,
- RESTORE_BIT = 2
};
static DWORD get_privileges ()
for (i = 0; i < privs->PrivilegeCount; i++) {
if (EqualLuid(privs->Privileges[i].Luid, cluid))
ret |= CREATE_BIT;
- else if (EqualLuid(privs->Privileges[i].Luid, rluid))
- ret |= RESTORE_BIT;
- else continue;
- if (ret == (CREATE_BIT | RESTORE_BIT))
+ if (ret == (CREATE_BIT))
break;
}
}
else
- fprintf(stderr, "has_create_token_privilege %ld\n", GetLastError());
+ fprintf(stderr, "has_create_token_privilege %u\n", GetLastError());
if (hToken)
CloseHandle(hToken);
return ret;
}
-/* We use a special routine to initialize
- cygwin_init is called from the OS_INIT macro in main(). */
-
-void cygwin_init(int argc, char ** argv, void * rup,
- void * eup, void * egp, void * cup, void * cgp)
+/*
+ We use cygwin_premain to fake a few things
+ and to provide some debug info
+*/
+void cygwin_premain2(int argc, char ** argv, struct per_process * ptr)
{
- int i;
+ int i, res, is_daemon = 0, is_spoolwritable, is_privileged, is_eximuser;
uid_t myuid, systemuid;
gid_t mygid, adminsgid;
- struct passwd * pwp;
- char *cygenv, win32_path[MAX_PATH];
+ struct passwd * pwp = NULL;
+ struct stat buf;
+ char *cygenv;
SID(1, SystemSid, SECURITY_LOCAL_SYSTEM_RID);
SID(2, AdminsSid, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS);
DWORD priv_flags;
for (i = 1; i < argc; i++) {
if (argv[i][0] == '-') {
if (argv[i][1] == 'c') {
+ ssize_t size;
+ wchar_t *win32_path;
argv[i][1] = 'n'; /* Replace -c by -n */
cygwin_debug = TRUE;
- fprintf(stderr, "CYGWIN = \"%s\".", cygenv);
- cygwin_conv_to_win32_path("/", win32_path);
- fprintf(stderr, " Root / mapped to %s.\n", win32_path);
+ fprintf(stderr, "CYGWIN = \"%s\".\n", cygenv);
+ if (((size = cygwin_conv_path(CCP_POSIX_TO_WIN_W,"/", win32_path, 0)) > 0)
+ && ((win32_path = malloc(size)) != NULL)
+ && (cygwin_conv_path(CCP_POSIX_TO_WIN_W,"/", win32_path, size) == 0)) {
+ fprintf(stderr, " Root / mapped to %ls.\n", win32_path);
+ free(win32_path);
+ }
}
- else if (argv[i][1] == 'b' && argv[i][2] == 'd')
+ else if (argv[i][1] == 'b' && argv[i][2] == 'd') {
+ is_daemon = 1;
cygwin_setpriority();
}
}
- if (VERSION_IS_58M(cygwin_WinVersion)) {
- * (uid_t *) rup = myuid; /* Pretend we are root */
- * (uid_t *) eup = myuid; /* ... and exim */
- * (gid_t *) egp = mygid;
- return;
}
+
/* Nt/2000/XP
- We initially set the exim uid & gid to those of the "real exim",
+ We initially set the exim uid & gid to those of the "exim user",
or to the root uid (SYSTEM) and exim gid (ADMINS),
If privileged, we setuid to those.
We always set the configure uid to the system uid.
We always set the root uid to the real uid
- to avoid useless execs following forks.
+ to allow exim imposed restrictions (bypassable by recompiling)
+ and to avoid exec that cause loss of privilege
If not privileged and unable to chown,
we set the exim uid to our uid.
- If unprivileged, we fake all subsequent setuid. */
+ If unprivileged and /var/spool/exim is writable and not runing as listening daemon,
+ we fake all subsequent setuid. */
+
+ /* Get the system and admins uid from their sids */
+ if ((systemuid = cygwin_internal(CW_GET_UID_FROM_SID, & SystemSid)) == -1) {
+ fprintf(stderr, "Cannot map System sid. Aborting\n");
+ exit(1);
+ }
+ if ((adminsgid = cygwin_internal(CW_GET_GID_FROM_SID, & AdminsSid)) == -1) {
+ fprintf(stderr, "Cannot map Admins sid. Aborting\n");
+ exit(1);
+ }
priv_flags = get_privileges ();
- privileged = !!(priv_flags & CREATE_BIT);
-
- /* Get the system and admins uid from their sids,
- or use the default values from the Makefile. */
- if ((systemuid = cygwin_internal(CW_GET_UID_FROM_SID, & SystemSid)) == -1)
- systemuid = * (uid_t *) eup;
- if ((adminsgid = cygwin_internal(CW_GET_GID_FROM_SID, & AdminsSid)) == -1)
- adminsgid = * (gid_t *) egp;
-
- if ((pwp = getpwnam("exim")) != NULL) {
- * (uid_t *) eup = pwp->pw_uid; /* Set it according to passwd */
- * (gid_t *) egp = pwp->pw_gid;
+ is_privileged = !!(priv_flags & CREATE_BIT);
+
+ /* Call getpwnam for account exim after getting the local exim name */
+ char exim_username[DNLEN + UNLEN + 2];
+ if (cygwin_internal(CW_CYGNAME_FROM_WINNAME, "exim", exim_username, sizeof exim_username) != 0)
+ pwp = getpwnam (exim_username);
+
+ /* If cannot setuid to exim or and is not the daemon (which is assumed to be
+ able to chown or to be the exim user) set the exim ugid to our ugid to avoid
+ chown failures after creating files and to be able to setuid to exim in
+ exim.c ( "privilege not needed" ). */
+ if ((is_privileged == 0) && (!is_daemon)) {
+ exim_uid = myuid;
+ exim_gid = mygid;
+ }
+ else if (pwp != NULL) {
+ exim_uid = pwp->pw_uid; /* Set it according to passwd */
+ exim_gid = pwp->pw_gid;
+ is_eximuser = 1;
}
else {
- * (uid_t *) eup = systemuid;
- * (gid_t *) egp = adminsgid;
+ exim_uid = systemuid;
+ exim_gid = adminsgid;
+ is_eximuser = 0;
}
- /* Set the configuration uid and gid to the system uid and admins gid.
- Note that exim uid is also accepted as owner of exim.conf. */
- * (uid_t *) cup = systemuid;
- * (gid_t *) cgp = adminsgid;
+ res = stat("/var/spool/exim", &buf);
+ /* Check if writable (and can be stat) */
+ is_spoolwritable = ((res == 0) && ((buf.st_mode & S_IWOTH) != 0));
+
+ fakesetugid = (is_privileged == 0) && (is_daemon == 0) && (is_spoolwritable == 1);
- if (privileged) { /* Can setuid */
- if (cygwin_setgid(* (gid_t *) egp) /* Setuid to exim */
- || cygwin_setuid(* (uid_t *) eup))
- privileged = -1; /* Problem... Perhaps not in 544 */
+ if (is_privileged) { /* Can setuid */
+ if (cygwin_setgid(exim_gid) /* Setuid to exim */
+ || cygwin_setuid(exim_uid)) {
+ fprintf(stderr, "Unable to setuid/gid to exim. priv_flags: %x\n", priv_flags);
+ exit(0); /* Problem... Perhaps not in 544 */
+ }
}
- /* Pretend we are root to avoid useless execs.
- We are limited by file access rights */
- * (uid_t *) rup = getuid ();
+ /* Set the configuration file uid and gid to the system uid and admins gid. */
+ config_uid = systemuid;
+ config_gid = adminsgid;
- /* If we have not setuid to exim and cannot chown,
- set the exim uid to our uid to avoid chown failures */
- if (privileged <= 0 && !(priv_flags & RESTORE_BIT))
- * (uid_t *) eup = * (uid_t *) rup;
+ /* Pretend we are root to avoid useless exec
+ and avoid exim set limitations.
+ We are limited by file access rights */
+ root_uid = getuid ();
if (cygwin_debug) {
- fprintf(stderr, "Starting uid %ld, gid %ld, ntsec %lu, privileged %d.\n",
- myuid, mygid, cygwin_internal(CW_CHECK_NTSEC, NULL), privileged);
- fprintf(stderr, "root_uid %ld, exim_uid %ld, exim_gid %ld, config_uid %ld, config_gid %ld.\n",
- * (uid_t *) rup, * (uid_t *) eup, * (gid_t *) egp, * (uid_t *) cup, * (gid_t *) cgp);
+ fprintf(stderr, "Starting uid %u, gid %u, priv_flags %x, is_privileged %d, is_daemon %d, is_spoolwritable %d.\n",
+ myuid, mygid, priv_flags, is_privileged, is_daemon, is_spoolwritable);
+ fprintf(stderr, "root_uid %u, exim_uid %u, exim_gid %u, config_uid %u, config_gid %u, is_eximuser %d.\n",
+ root_uid, exim_uid, exim_gid, config_uid, config_gid, is_eximuser);
}
return;
}
#define OS_LOAD_AVERAGE /* src/os.c need not provide it */
/*****************************************************************
- *
Functions for average load measurements
- There are two methods, which work only on NT.
+ Uses NtQuerySystemInformation.
+ This requires definitions that are not part of
+ standard include files.
- The first one uses the HKEY_PERFORMANCE_DATA registry to
- get performance data. It is complex but well documented
- and works on all NT versions.
-
- The second one uses NtQuerySystemInformation.
- Its use is discouraged starting with WinXP.
-
- Until 4.43, the Cygwin port of exim was using the first
- method.
-
-*****************************************************************/
-#define PERF_METHOD2
+ This is discouraged starting with WinXP.
+*************************************************************/
/* Structure to compute the load average efficiently */
typedef struct {
DWORD Lock;
unsigned long long LastCounter; /* Last measurement counter */
unsigned long long PerfFreq; /* Perf counter frequency */
int LastLoad; /* Last reported load, or -1 */
-#ifdef PERF_METHOD1
- PPERF_DATA_BLOCK PerfData; /* Pointer to a buffer to get the data */
- DWORD BufferSize; /* Size of PerfData */
- LPSTR * NamesArray; /* Temporary (malloc) buffer for index */
-#endif
} cygwin_perf_t;
static struct {
cygwin_perf_t *perf;
} cygwin_load = {NULL, 0, NULL};
-#ifdef PERF_METHOD1
-/*************************************************************
- METHOD 1
-
- Obtaining statistics in Windows is done at a low level by
- calling registry functions, in particular the key
- HKEY_PERFORMANCE_DATA on NT and successors.
- Something equivalent exists on Win95, see Microsoft article
- HOWTO: Access the Performance Registry Under Windows 95 (KB 174631)
- but it is not implemented here.
-
- The list of objects to be polled is specified in the string
- passed to RegQueryValueEx in ReadStat() below.
- On NT, all objects are polled even if info about only one is
- required. This is fixed in Windows 2000. See articles
- INFO: Perflib Calling Close Procedure in Windows 2000 (KB 270127)
- INFO: Performance Data Changes Between Windows NT 4.0 and Windows
- 2000 (KB 296523)
-
- It is unclear to me how the counters are primarily identified.
- Whether it's by name strings or by the offset of their strings
- as mapped in X:\Winnt\system32\perfc009.dat [or equivalently as
- reported by the registry functions in GetNameStrings( ) below].
- Microsoft documentation seems to say that both methods should
- work.
-
- In the interest of speed and language independence, the main
- code below relies on offsets. However if debug is enabled, the
- code verifies that the names of the corresponding strings are
- as expected.
-
-*****************************************************************/
-
-/* Object and counter indices and names */
-#define PROCESSOR_OBJECT_INDEX 238
-#define PROCESSOR_OBJECT_STRING "238"
-#define PROCESSOR_OBJECT_NAME "Processor"
-#define PROCESSOR_TIME_COUNTER 6
-#define PROCESSOR_TIME_NAME "% Processor Time"
-
-#define BYTEINCREMENT 800 /* Block to add to PerfData */
-
-/*****************************************************************
- *
- Macros to navigate through the performance data.
-
- *****************************************************************/
-#define FirstObject(PerfData)\
- ((PPERF_OBJECT_TYPE)((PBYTE)PerfData + PerfData->HeaderLength))
-#define NextObject(PerfObj)\
- ((PPERF_OBJECT_TYPE)((PBYTE)PerfObj + PerfObj->TotalByteLength))
-#define ObjectCounterBlock(PerfObj)\
- ((PPERF_COUNTER_BLOCK)(PBYTE)PerfObj + PerfObj->DefinitionLength )
-#define FirstInstance(PerfObj )\
- ((PPERF_INSTANCE_DEFINITION)((PBYTE)PerfObj + PerfObj->DefinitionLength))
-#define InstanceCounterBlock(PerfInst)\
- ((PPERF_COUNTER_BLOCK) ((PBYTE)PerfInst + PerfInst->ByteLength ))
-#define NextInstance(PerfInst )\
- ((PPERF_INSTANCE_DEFINITION)((PBYTE)InstanceCounterBlock(PerfInst) + \
- InstanceCounterBlock(PerfInst)->ByteLength) )
-#define FirstCounter(PerfObj)\
- ((PPERF_COUNTER_DEFINITION) ((PBYTE)PerfObj + PerfObj->HeaderLength))
-#define NextCounter(PerfCntr)\
- ((PPERF_COUNTER_DEFINITION)((PBYTE)PerfCntr + PerfCntr->ByteLength))
-
-/*****************************************************************
- *
- Load the counter and object names from the registry
- to cygwin_load.perf->NameStrings
- and index them in cygwin_load.perf->NamesArray
-
- NameStrings seems to be taken from the file
- X:\Winnt\system32\perfc009.dat
-
- This is used only for name verification during initialization,
- if DEBUG(D_load) is TRUE.
-
-*****************************************************************/
-static BOOL GetNameStrings( )
-{
- HKEY hKeyPerflib; // handle to registry key
- DWORD dwArraySize; // size for array
- DWORD dwNamesSize; // size for strings
- LPSTR lpCurrentString; // pointer for enumerating data strings
- DWORD dwCounter; // current counter index
- LONG res;
-
- /* Get the number of Counter items into dwArraySize. */
- if ((res = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
- "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib",
- 0,
- KEY_QUERY_VALUE, /* KEY_READ, */
- &hKeyPerflib))
- != ERROR_SUCCESS) {
- DEBUG(D_load) debug_printf("RegOpenKeyEx (1): error %ld (Windows)\n", res);
- return FALSE;
- }
- dwNamesSize = sizeof(dwArraySize); /* Temporary reuse */
- if ((res = RegQueryValueEx( hKeyPerflib,
- "Last Counter",
- NULL,
- NULL,
- (LPBYTE) &dwArraySize,
- &dwNamesSize ))
- != ERROR_SUCCESS) {
- DEBUG(D_load) debug_printf("RegQueryValueEx (1): error %ld (Windows)\n", res);
- return FALSE;
- }
- RegCloseKey( hKeyPerflib );
- /* Open the key containing the counter and object names. */
- if ((res = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
- "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib\\009",
- 0,
- KEY_READ,
- &hKeyPerflib))
- != ERROR_SUCCESS) {
- DEBUG(D_load) debug_printf("RegOpenKeyEx (2): error %ld (Windows)\n", res);
- return FALSE;
- }
- /* Get the size of the Counter value in the key
- and then read the value in the tail of NamesArray */
- dwNamesSize = 0;
- lpCurrentString = NULL;
- while (1) {
- res = RegQueryValueEx( hKeyPerflib,
- "Counter",
- NULL,
- NULL,
- (unsigned char *) lpCurrentString,
- &dwNamesSize);
- if ((res == ERROR_SUCCESS) && /* Bug (NT 4.0): SUCCESS was returned on first call */
- (cygwin_load.perf->NamesArray != NULL)) break;
- if ((res == ERROR_SUCCESS) || /* but cygwin_load.perf->NamesArrays == NULL */
- (res == ERROR_MORE_DATA)) {
- /* Allocate memory BOTH for the names array and for the counter and object names */
- if ((cygwin_load.perf->NamesArray =
- (LPSTR *) malloc( (dwArraySize + 1) * sizeof(LPSTR) + dwNamesSize * sizeof(CHAR)))
- != NULL) {
- /* Point to area for the counter and object names */
- lpCurrentString = (LPSTR) & cygwin_load.perf->NamesArray[dwArraySize + 1];
- continue;
- }
- DEBUG(D_load) debug_printf("Malloc: errno %d (%s)\n", errno, strerror(errno));
- }
- else { /* Serious error */
- DEBUG(D_load) debug_printf("RegQueryValueEx (2): error %ld (Windows)\n", res);
- }
- return FALSE;
- }
- RegCloseKey( hKeyPerflib );
- /* Index the names into an array. */
- while (*lpCurrentString) {
- dwCounter = atol( lpCurrentString );
- lpCurrentString += (lstrlen(lpCurrentString)+1);
- cygwin_load.perf->NamesArray[dwCounter] = lpCurrentString;
- lpCurrentString += (strlen(lpCurrentString)+1);
- }
- return TRUE;
-}
-
-/*****************************************************************
- *
- Find the value of the Processor Time counter
-
-*****************************************************************/
-static BOOL ReadTimeCtr(PPERF_OBJECT_TYPE PerfObj,
- PPERF_COUNTER_DEFINITION CurCntr,
- PPERF_COUNTER_BLOCK PtrToCntr,
- unsigned long long * TimePtr){
- int j;
- /* Scan all counters. */
- for( j = 0; j < PerfObj->NumCounters; j++ ) {
- if (CurCntr->CounterNameTitleIndex == PROCESSOR_TIME_COUNTER) {
- /* Verify it is really the proc time counter */
- if ((CurCntr->CounterType != PERF_100NSEC_TIMER_INV) || /* Wrong type */
- ((cygwin_load.perf->NamesArray != NULL) && /* Verify name */
- (strcmp(cygwin_load.perf->NamesArray[CurCntr->CounterNameTitleIndex],
- PROCESSOR_TIME_NAME)))) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "Incorrect Perf counter type or name %x %s",
- (unsigned) CurCntr->CounterType,
- cygwin_load.perf->NamesArray[CurCntr->CounterNameTitleIndex]);
- return FALSE;
- }
- *TimePtr += *(unsigned long long int *) ((PBYTE) PtrToCntr + CurCntr->CounterOffset);
- return TRUE; /* return TRUE as soon as we found the counter */
- }
- /* Get the next counter. */
- CurCntr = NextCounter( CurCntr );
- }
- return FALSE;
-}
-
-/*****************************************************************
- *
- ReadStat()
- Measures current Time100ns and IdleCount
- Return TRUE if success.
-
- *****************************************************************/
-static BOOL ReadStat(unsigned long long int *Time100nsPtr,
- unsigned long long int * IdleCountPtr)
-{
- PPERF_OBJECT_TYPE PerfObj;
- PPERF_INSTANCE_DEFINITION PerfInst;
- PPERF_COUNTER_DEFINITION PerfCntr;
- PPERF_COUNTER_BLOCK PtrToCntr;
- DWORD i, k, res;
-
- /* Get the performance data for the Processor object
- There is no need to open a key.
- We may need to blindly increase the buffer size.
- BufferSize does not return info but may be changed */
- while (1) {
- DWORD BufferSize = cygwin_load.perf->BufferSize;
- res = RegQueryValueEx( HKEY_PERFORMANCE_DATA,
- PROCESSOR_OBJECT_STRING,
- NULL,
- NULL,
- (LPBYTE) cygwin_load.perf->PerfData,
- &BufferSize );
- if (res == ERROR_SUCCESS) break;
- if (res == ERROR_MORE_DATA ) {
- /* Increment if necessary to get a buffer that is big enough. */
- cygwin_load.perf->BufferSize += BYTEINCREMENT;
- if ((cygwin_load.perf->PerfData =
- (PPERF_DATA_BLOCK) realloc( cygwin_load.perf->PerfData, cygwin_load.perf->BufferSize ))
- != NULL) continue;
- DEBUG(D_load) debug_printf("Malloc: errno %d (%s)\n", errno, strerror(errno));
- }
- else { /* Serious error */
- DEBUG(D_load) debug_printf("RegQueryValueEx (3): error %ld (Windows)\n", res);
- }
- return FALSE;
- }
- /* Initialize the counters */
- *Time100nsPtr = 0;
- *IdleCountPtr = 0;
- /* We should only have one object, but write general code just in case. */
- PerfObj = FirstObject( cygwin_load.perf->PerfData );
- for( i = 0; i < cygwin_load.perf->PerfData->NumObjectTypes; i++ ) {
- /* We are only interested in the processor object */
- if ( PerfObj->ObjectNameTitleIndex == PROCESSOR_OBJECT_INDEX) {
- /* Possibly verify it is really the Processor object. */
- if ((cygwin_load.perf->NamesArray != NULL) &&
- (strcmp(cygwin_load.perf->NamesArray[PerfObj->ObjectNameTitleIndex],
- PROCESSOR_OBJECT_NAME))) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "Incorrect Perf object name %s",
- cygwin_load.perf->NamesArray[PerfObj->ObjectNameTitleIndex]);
- return FALSE;
- }
- /* Get the first counter */
- PerfCntr = FirstCounter( PerfObj );
- /* See if the object has instances.
- It should, but write general code. */
- if( PerfObj->NumInstances != PERF_NO_INSTANCES ) {
- PerfInst = FirstInstance( PerfObj );
- for( k = 0; k < PerfObj->NumInstances; k++ ) {
- /* There can be several processors.
- Accumulate both the Time100ns and the idle counter.
- Starting with Win2000 there is an instance named "_Total".
- Do not use it. We only use instances with a single
- character in the name.
- If we examine the object names, we also look at the instance
- names and their lengths and issue reports */
- if ( cygwin_load.perf->NamesArray != NULL) {
- CHAR ascii[30]; /* The name is in unicode */
- wsprintf(ascii,"%.29lS",
- (char *)((PBYTE)PerfInst + PerfInst->NameOffset));
- log_write(0, LOG_MAIN,
- "Perf: Found processor instance \"%s\", length %d",
- ascii, PerfInst->NameLength);
- if ((PerfInst->NameLength != 4) &&
- (strcmp(ascii, "_Total") != 0)) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "Perf: WARNING: Unexpected processor instance name");
- return FALSE;
- }
- }
- if (PerfInst->NameLength == 4) {
- *Time100nsPtr += cygwin_load.perf->PerfData->PerfTime100nSec.QuadPart;
- PtrToCntr = InstanceCounterBlock(PerfInst);
- if (! ReadTimeCtr(PerfObj, PerfCntr, PtrToCntr, IdleCountPtr)) {
- return FALSE;
- }
- }
- PerfInst = NextInstance( PerfInst );
- }
- return (*Time100nsPtr != 0); /* Something was read */
- }
- else { /* No instance, just the counter data */
- *Time100nsPtr = cygwin_load.perf->PerfData->PerfTime100nSec.QuadPart;
- PtrToCntr = ObjectCounterBlock(PerfObj);
- return ReadTimeCtr(PerfObj, PerfCntr, PtrToCntr, IdleCountPtr);
- }
- }
- PerfObj = NextObject( PerfObj );
- }
- return FALSE; /* Did not find the Processor object */
-}
-
-#elif defined(PERF_METHOD2)
-
-/*************************************************************
- METHOD 2
-
- Uses NtQuerySystemInformation.
- This requires definitions that are not part of
- standard include files.
-*************************************************************/
#include <ntdef.h>
typedef enum _SYSTEM_INFORMATION_CLASS
return TRUE;
DEBUG(D_load)
- debug_printf("perf: load: %ld (Windows)\n", GetLastError());
+ debug_printf("perf: load: %u (Windows)\n", GetLastError());
return FALSE;
}
-
/*****************************************************************
*
ReadStat()
(PVOID) &sbi, sizeof sbi, NULL))
!= STATUS_SUCCESS) {
DEBUG(D_load)
- debug_printf("Perf: NtQuerySystemInformation: %lu (Windows)\n",
+ debug_printf("Perf: NtQuerySystemInformation: %u (Windows)\n",
RtlNtStatusToDosError(ret));
}
else if (!(spt = (PSYSTEM_PROCESSOR_TIMES) alloca(sizeof(spt[0]) * sbi.NumberProcessors))) {
sizeof spt[0] * sbi.NumberProcessors, NULL))
!= STATUS_SUCCESS) {
DEBUG(D_load)
- debug_printf("Perf: NtQuerySystemInformation: %lu (Windows)\n",
+ debug_printf("Perf: NtQuerySystemInformation: %u (Windows)\n",
RtlNtStatusToDosError(ret));
}
else {
}
return FALSE;
}
-#endif /* PERF_METHODX */
/*****************************************************************
*
QueryPerformanceFrequency((LARGE_INTEGER *)& this->PerfFreq);
QueryPerformanceCounter((LARGE_INTEGER *)& this->LastCounter);
-#ifdef PERF_METHOD1
- DEBUG(D_load) {
- /* Get the name strings through the registry
- to verify that the object and counter numbers
- have the names we expect */
- success = GetNameStrings();
- }
-#endif
/* Get initial values for Time100ns and IdleCount */
success = success
&& ReadStat( & this->Time100ns,
log_write(0, LOG_MAIN, "Cannot obtain Load Average");
this->LastLoad = -1;
}
-#ifdef PERF_METHOD1
- /* Free the buffer created for debug name verification */
- if (this->NamesArray != NULL) {
- free(this->NamesArray);
- this->NamesArray = NULL;
- }
-#endif
}
BOOL new;
cygwin_load.pid = newpid;
-#ifdef PERF_METHOD2
if (!LoadNtdll()) {
log_write(0, LOG_MAIN, "Cannot obtain Load Average");
cygwin_load.perf = NULL;
return -1;
}
-#endif
if ((new = !cygwin_load.handle)) {
cygwin_load.handle = CreateFileMapping (INVALID_HANDLE_VALUE, &sa, PAGE_READWRITE,
0, sizeof(cygwin_perf_t), NULL);
DEBUG(D_load)
- debug_printf("Perf: CreateFileMapping: handle %x\n", (unsigned) cygwin_load.handle);
+ debug_printf("Perf: CreateFileMapping: handle %p\n", (void *) cygwin_load.handle);
}
cygwin_load.perf = (cygwin_perf_t *) MapViewOfFile (cygwin_load.handle,
FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
DEBUG(D_load)
- debug_printf("Perf: MapViewOfFile: addr %x\n", (unsigned) cygwin_load.perf);
+ debug_printf("Perf: MapViewOfFile: addr %p\n", (void *) cygwin_load.perf);
if (new && cygwin_load.perf)
InitLoadAvg(cygwin_load.perf);
}
typedef struct flock flock_t;
+/* default is non-const */
+#define ICONV_ARG2_TYPE const char **
+
+
/* End */
typedef struct flock flock_t;
+/* default is non-const */
+#define ICONV_ARG2_TYPE const char **
+
/* End */
#define NO_IP_OPTIONS
+/* default is non-const */
+#define ICONV_ARG2_TYPE const char **
+
/* End */
#define OFF_T_FMT "%lld"
#define LONGLONG_T long int
+/* default is non-const */
+#define ICONV_ARG2_TYPE const char **
+
/* End */
typedef struct flock flock_t;
+/* default is non-const */
+#define ICONV_ARG2_TYPE const char **
+
/* End */
typedef struct flock flock_t;
+/* default is non-const */
+#define ICONV_ARG2_TYPE const char **
+
/* End */
/* Hurd-specific bits below */
+/* default is non-const */
+#define ICONV_ARG2_TYPE const char **
+
/* End */
#define HAVE_SYS_MOUNT_H
#define SIOCGIFCONF_GIVES_ADDR
+/* default is non-const */
+#define ICONV_ARG2_TYPE const char **
+
/* End */
#define HAVE_SYS_MOUNT_H
#define SIOCGIFCONF_GIVES_ADDR
+/* default is non-const */
+#define ICONV_ARG2_TYPE const char **
+
/* End */
#define F_FREESP O_TRUNC
#define DN_EXPAND_ARG4_TYPE u_char *
+/* default is non-const */
+#define ICONV_ARG2_TYPE const char **
+
/* End */
typedef struct flock flock_t;
+/* default is non-const */
+#define ICONV_ARG2_TYPE const char **
+
/* End */
/* Exim: OS-specific C header file for HP-UX versions greater than 9 */
-#define ICONV_ARG2_TYPE char **
#define EXIM_SOCKLEN_T size_t
#define LOAD_AVG_NEEDS_ROOT
#define FSCALE 1.0
#define HAVE_SYS_STATVFS_H
+#define MISSING_UNSETENV_3
#define F_FREESP O_TRUNC
#define NEED_H_ERRNO 1
#define strtoll(a,b,c) strtoimax(a,b,c)
+/* Determined by sockaddr_un */
+
+struct sockaddr_storage
+{
+ short ss_family;
+ char __ss_padding[92];
+};
+
/* End */
typedef struct flock flock_t;
+/* default is non-const */
+#define ICONV_ARG2_TYPE const char **
+
/* End */
#define F_FAVAIL f_favail
#define vfork fork
-/* Other OS have "const" in here */
-#define ICONV_ARG2_TYPE char **
-
/* End */
#define F_FAVAIL f_favail
#define vfork fork
-/* Other OS have "const" in here */
-#define ICONV_ARG2_TYPE char **
-
/* End */
#define F_FAVAIL f_favail
#define vfork fork
-/* Other OS have "const" in here */
-#define ICONV_ARG2_TYPE char **
-
/* End */
#define F_FAVAIL f_favail
#define vfork fork
-/* Other OS have "const" in here */
-#define ICONV_ARG2_TYPE char **
-
/* End */
#define NEED_SYNC_DIRECTORY
-/* Other OS have "const" in here */
-#define ICONV_ARG2_TYPE char **
-
#define os_find_running_interfaces os_find_running_interfaces_linux
/* Need a prototype for the Linux-specific function. The structure hasn't
#define HAVE_SYS_STATVFS_H
#endif
+/* default is non-const */
+#define ICONV_ARG2_TYPE const char **
+
/* End */
/* Still not "socklen_t", which is the most common setting */
#define EXIM_SOCKLEN_T int
-/* The default for this is "const char **" */
-#define ICONV_ARG2_TYPE char **
-
/* End */
typedef struct __res_state *res_state;
+/* default is non-const */
+#define ICONV_ARG2_TYPE const char **
+
/* End */
#define _SVID3
#define NEED_H_ERRNO
+/* default is non-const */
+#define ICONV_ARG2_TYPE const char **
+
/* End */
extern int h_errno;
+/* default is non-const */
+#define ICONV_ARG2_TYPE const char **
+
/* End */
#define _SVID3
#define NEED_H_ERRNO
+/* default is non-const */
+#define ICONV_ARG2_TYPE const char **
+
/* End */
#define _SVID3
#define NEED_H_ERRNO
+/* default is non-const */
+#define ICONV_ARG2_TYPE const char **
+
/* End */
#define FUDGE_GETC_AND_FRIENDS
+/* default is non-const */
+#define ICONV_ARG2_TYPE const char **
+
/* End */
#define PAM_CONVERSE_ARG2_TYPE struct pam_message
+
+/* default is non-const */
+#define ICONV_ARG2_TYPE const char **
+
+#if _POSIX_C_SOURCE < 200112L
+# define MISSING_UNSETENV_3
+#endof
+
+
/* End */
#define LOAD_AVG_SYMBOL "avenrun_1min"
#define LOAD_AVG_FIELD value.ul
+/* default is non-const */
+#define ICONV_ARG2_TYPE const char **
+
/* End */
#define NO_OPENLOG
typedef struct flock flock_t;
+/* default is non-const */
+#define ICONV_ARG2_TYPE const char **
+
/* End */
#define _SVID3
#define NEED_H_ERRNO
+/* default is non-const */
+#define ICONV_ARG2_TYPE const char **
+
/* End */
#define _SVID3
#define NEED_H_ERRNO
+/* default is non-const */
+#define ICONV_ARG2_TYPE const char **
+
/* End */
#define NO_SYSEXITS
-#define ICONV_ARG2_TYPE char **
#define EXIM_SOCKLEN_T size_t
#define LOAD_AVG_NEEDS_ROOT
/* Exim: OS-specific C header file for Cygwin */
-/* This code was supplied by Pierre A. Humblet <Pierre.Humblet@ieee.org> */
-
-/* Define the OS_INIT macro that we insert in exim.c:main()
- to set the root and exim uid depending on the system */
-/* We use a special routine to initialize */
-void cygwin_init(int, char **, void *, void *, void *, void *, void *);
-#define OS_INIT\
- cygwin_init(argc, (char **) argv, &root_uid, &exim_uid, &exim_gid, &config_uid, &config_gid);
-
-/* We need a special mkdir that
- allows names starting with // */
-#include <sys/stat.h> /* Do not redefine mkdir in sys/stat.h */
-int cygwin_mkdir( const char *_path, mode_t __mode );
-#define mkdir cygwin_mkdir /* redefine mkdir elsewhere */
+/* This code was supplied by Pierre A. Humblet <Pierre.Humblet@ieee.org>
+ December 2002. Updated Jan 2015. */
/* Redefine the set*id calls to run when faking root */
#include <unistd.h> /* Do not redefine in unitsd.h */
#define setuid cygwin_setuid
#define setgid cygwin_setgid
-extern unsigned int cygwin_WinVersion;
-
+#define os_strsignal strsignal
+#define OS_STRSIGNAL
#define BASE_62 36 /* Windows aliases lower and upper cases in filenames.
Consider reducing MAX_LOCALHOST_NUMBER */
#define CRYPT_H
#define HAVE_SYS_VFS_H
#define NO_IP_VAR_H
#define NO_IP_OPTIONS
-#define F_FREESP O_TRUNC
/* Defining LOAD_AVG_NEEDS_ROOT causes an initial
call to os_getloadavg. In our case this is beneficial
because it initializes the counts */
DWORD SubAuthority[n]; \
} name = { SID_REVISION, n, {SECURITY_NT_AUTHORITY}, {sid}}
+/* default is non-const */
+#define ICONV_ARG2_TYPE const char **
+
/* End */
extern int sys_nerr;
extern char *sys_errlist[];
+/* default is non-const */
+#define ICONV_ARG2_TYPE const char **
+
/* End */
* Exim Monitor *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2012 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
# Firstly the lookups
mkdir lookups
cd lookups
-ln -s ../../src/lookups/README README
# Makefile is generated
-ln -s ../../src/lookups/cdb.c cdb.c
-ln -s ../../src/lookups/dbmdb.c dbmdb.c
-ln -s ../../src/lookups/dnsdb.c dnsdb.c
-ln -s ../../src/lookups/dsearch.c dsearch.c
-ln -s ../../src/lookups/ibase.c ibase.c
-ln -s ../../src/lookups/ldap.h ldap.h
-ln -s ../../src/lookups/ldap.c ldap.c
-ln -s ../../src/lookups/lsearch.c lsearch.c
-ln -s ../../src/lookups/mysql.c mysql.c
-ln -s ../../src/lookups/redis.c redis.c
-ln -s ../../src/lookups/nis.c nis.c
-ln -s ../../src/lookups/nisplus.c nisplus.c
-ln -s ../../src/lookups/oracle.c oracle.c
-ln -s ../../src/lookups/passwd.c passwd.c
-ln -s ../../src/lookups/pgsql.c pgsql.c
-ln -s ../../src/lookups/spf.c spf.c
-ln -s ../../src/lookups/sqlite.c sqlite.c
-ln -s ../../src/lookups/testdb.c testdb.c
-ln -s ../../src/lookups/whoson.c whoson.c
-
-ln -s ../../src/lookups/lf_functions.h lf_functions.h
-ln -s ../../src/lookups/lf_check_file.c lf_check_file.c
-ln -s ../../src/lookups/lf_quote.c lf_quote.c
-ln -s ../../src/lookups/lf_sqlperform.c lf_sqlperform.c
+for f in README cdb.c dbmdb.c dnsdb.c dsearch.c ibase.c ldap.h ldap.c \
+ lsearch.c mysql.c redis.c nis.c nisplus.c oracle.c passwd.c \
+ pgsql.c spf.c sqlite.c testdb.c whoson.c \
+ lf_functions.h lf_check_file.c lf_quote.c lf_sqlperform.c
+do
+ ln -s ../../src/lookups/$f $f
+done
cd ..
# Likewise for the code for the routers
mkdir routers
cd routers
-ln -s ../../src/routers/README README
-ln -s ../../src/routers/Makefile Makefile
-ln -s ../../src/routers/accept.h accept.h
-ln -s ../../src/routers/accept.c accept.c
-ln -s ../../src/routers/dnslookup.h dnslookup.h
-ln -s ../../src/routers/dnslookup.c dnslookup.c
-ln -s ../../src/routers/ipliteral.h ipliteral.h
-ln -s ../../src/routers/ipliteral.c ipliteral.c
-ln -s ../../src/routers/iplookup.h iplookup.h
-ln -s ../../src/routers/iplookup.c iplookup.c
-ln -s ../../src/routers/manualroute.h manualroute.h
-ln -s ../../src/routers/manualroute.c manualroute.c
-ln -s ../../src/routers/queryprogram.h queryprogram.h
-ln -s ../../src/routers/queryprogram.c queryprogram.c
-ln -s ../../src/routers/redirect.h redirect.h
-ln -s ../../src/routers/redirect.c redirect.c
-
-ln -s ../../src/routers/rf_functions.h rf_functions.h
-ln -s ../../src/routers/rf_change_domain.c rf_change_domain.c
-ln -s ../../src/routers/rf_expand_data.c rf_expand_data.c
-ln -s ../../src/routers/rf_get_errors_address.c rf_get_errors_address.c
-ln -s ../../src/routers/rf_get_munge_headers.c rf_get_munge_headers.c
-ln -s ../../src/routers/rf_get_transport.c rf_get_transport.c
-ln -s ../../src/routers/rf_get_ugid.c rf_get_ugid.c
-ln -s ../../src/routers/rf_queue_add.c rf_queue_add.c
-ln -s ../../src/routers/rf_lookup_hostlist.c rf_lookup_hostlist.c
-ln -s ../../src/routers/rf_self_action.c rf_self_action.c
-ln -s ../../src/routers/rf_set_ugid.c rf_set_ugid.c
+for f in README Makefile accept.h accept.c dnslookup.h dnslookup.c \
+ ipliteral.h ipliteral.c iplookup.h iplookup.c manualroute.h \
+ manualroute.c queryprogram.h queryprogram.c redirect.h redirect.c \
+ rf_functions.h rf_change_domain.c rf_expand_data.c rf_get_errors_address.c \
+ rf_get_munge_headers.c rf_get_transport.c rf_get_ugid.c rf_queue_add.c \
+ rf_lookup_hostlist.c rf_self_action.c rf_set_ugid.c
+do
+ ln -s ../../src/routers/$f $f
+done
cd ..
# Likewise for the code for the transports
mkdir transports
cd transports
-ln -s ../../src/transports/README README
-ln -s ../../src/transports/Makefile Makefile
-ln -s ../../src/transports/appendfile.h appendfile.h
-ln -s ../../src/transports/appendfile.c appendfile.c
-ln -s ../../src/transports/autoreply.h autoreply.h
-ln -s ../../src/transports/autoreply.c autoreply.c
-ln -s ../../src/transports/lmtp.h lmtp.h
-ln -s ../../src/transports/lmtp.c lmtp.c
-ln -s ../../src/transports/pipe.h pipe.h
-ln -s ../../src/transports/pipe.c pipe.c
-ln -s ../../src/transports/smtp.h smtp.h
-ln -s ../../src/transports/smtp.c smtp.c
-
-ln -s ../../src/transports/tf_maildir.c tf_maildir.c
-ln -s ../../src/transports/tf_maildir.h tf_maildir.h
+for f in README Makefile appendfile.h appendfile.c autoreply.h \
+ autoreply.c lmtp.h lmtp.c pipe.h pipe.c smtp.h smtp.c smtp_socks.c \
+ tf_maildir.c tf_maildir.h
+do
+ ln -s ../../src/transports/$f $f
+done
cd ..
# Likewise for the code for the authorization functions
mkdir auths
cd auths
-ln -s ../../src/auths/README README
-ln -s ../../src/auths/Makefile Makefile
-ln -s ../../src/auths/b64encode.c b64encode.c
-ln -s ../../src/auths/b64decode.c b64decode.c
-ln -s ../../src/auths/call_pam.c call_pam.c
-ln -s ../../src/auths/call_pwcheck.c call_pwcheck.c
-ln -s ../../src/auths/call_radius.c call_radius.c
-ln -s ../../src/auths/check_serv_cond.c check_serv_cond.c
-ln -s ../../src/auths/cyrus_sasl.c cyrus_sasl.c
-ln -s ../../src/auths/cyrus_sasl.h cyrus_sasl.h
-ln -s ../../src/auths/gsasl_exim.c gsasl_exim.c
-ln -s ../../src/auths/gsasl_exim.h gsasl_exim.h
-ln -s ../../src/auths/get_data.c get_data.c
-ln -s ../../src/auths/get_no64_data.c get_no64_data.c
-ln -s ../../src/auths/heimdal_gssapi.c heimdal_gssapi.c
-ln -s ../../src/auths/heimdal_gssapi.h heimdal_gssapi.h
-ln -s ../../src/auths/md5.c md5.c
-ln -s ../../src/auths/xtextencode.c xtextencode.c
-ln -s ../../src/auths/xtextdecode.c xtextdecode.c
-ln -s ../../src/auths/cram_md5.c cram_md5.c
-ln -s ../../src/auths/cram_md5.h cram_md5.h
-ln -s ../../src/auths/plaintext.c plaintext.c
-ln -s ../../src/auths/plaintext.h plaintext.h
-ln -s ../../src/auths/pwcheck.c pwcheck.c
-ln -s ../../src/auths/pwcheck.h pwcheck.h
-ln -s ../../src/auths/auth-spa.c auth-spa.c
-ln -s ../../src/auths/auth-spa.h auth-spa.h
-ln -s ../../src/auths/dovecot.c dovecot.c
-ln -s ../../src/auths/dovecot.h dovecot.h
-ln -s ../../src/auths/sha1.c sha1.c
-ln -s ../../src/auths/spa.c spa.c
-ln -s ../../src/auths/spa.h spa.h
+for f in README Makefile b64encode.c b64decode.c call_pam.c call_pwcheck.c \
+ call_radius.c check_serv_cond.c cyrus_sasl.c cyrus_sasl.h gsasl_exim.c \
+ gsasl_exim.h get_data.c get_no64_data.c heimdal_gssapi.c heimdal_gssapi.h \
+ md5.c xtextencode.c xtextdecode.c cram_md5.c cram_md5.h plaintext.c plaintext.h \
+ pwcheck.c pwcheck.h auth-spa.c auth-spa.h dovecot.c dovecot.h sha1.c spa.c \
+ spa.h tls.c tls.h
+do
+ ln -s ../../src/auths/$f $f
+done
cd ..
# Likewise for the code for the PDKIM library
mkdir pdkim
cd pdkim
-ln -s ../../src/pdkim/README README
-ln -s ../../src/pdkim/Makefile Makefile
-ln -s ../../src/pdkim/base64.c base64.c
-ln -s ../../src/pdkim/base64.h base64.h
-ln -s ../../src/pdkim/bignum.c bignum.c
-ln -s ../../src/pdkim/bignum.h bignum.h
-ln -s ../../src/pdkim/bn_mul.h bn_mul.h
-ln -s ../../src/pdkim/pdkim.c pdkim.c
-ln -s ../../src/pdkim/pdkim.h pdkim.h
-ln -s ../../src/pdkim/rsa.c rsa.c
-ln -s ../../src/pdkim/rsa.h rsa.h
-ln -s ../../src/pdkim/sha1.c sha1.c
-ln -s ../../src/pdkim/sha1.h sha1.h
-ln -s ../../src/pdkim/sha2.c sha2.c
-ln -s ../../src/pdkim/sha2.h sha2.h
-cd ..
+for f in README Makefile base64.c bignum.c part-x509parse.c pdkim.c \
+ pdkim.h pdkim-rsa.c pdkim-rsa.h rsa.c sha1.c sha2.c
+do
+ ln -s ../../src/pdkim/$f $f
+done
+mkdir polarssl
+cd polarssl
+for i in `ls ../../../src/pdkim/polarssl/` ; do
+ ln -s ../../../src/pdkim/polarssl/$i $i
+done
+cd ../..
# The basic source files for Exim and utilities. NB local_scan.h gets linked,
# but local_scan.c does not, because its location is taken from the build-time
# configuration. Likewise for the os.c file, which gets build dynamically.
-ln -s ../src/dbfunctions.h dbfunctions.h
-ln -s ../src/dbstuff.h dbstuff.h
-ln -s ../src/exim.h exim.h
-ln -s ../src/functions.h functions.h
-ln -s ../src/globals.h globals.h
-ln -s ../src/local_scan.h local_scan.h
-ln -s ../src/macros.h macros.h
-ln -s ../src/mytypes.h mytypes.h
-ln -s ../src/osfunctions.h osfunctions.h
-ln -s ../src/store.h store.h
-ln -s ../src/structs.h structs.h
-ln -s ../src/lookupapi.h lookupapi.h
-
-ln -s ../src/acl.c acl.c
-ln -s ../src/buildconfig.c buildconfig.c
-ln -s ../src/child.c child.c
-ln -s ../src/crypt16.c crypt16.c
-ln -s ../src/daemon.c daemon.c
-ln -s ../src/dbfn.c dbfn.c
-ln -s ../src/debug.c debug.c
-ln -s ../src/deliver.c deliver.c
-ln -s ../src/directory.c directory.c
-ln -s ../src/dns.c dns.c
-ln -s ../src/drtables.c drtables.c
-ln -s ../src/dummies.c dummies.c
-ln -s ../src/enq.c enq.c
-ln -s ../src/exim.c exim.c
-ln -s ../src/exim_dbmbuild.c exim_dbmbuild.c
-ln -s ../src/exim_dbutil.c exim_dbutil.c
-ln -s ../src/exim_lock.c exim_lock.c
-ln -s ../src/expand.c expand.c
-ln -s ../src/filter.c filter.c
-ln -s ../src/filtertest.c filtertest.c
-ln -s ../src/globals.c globals.c
-ln -s ../src/header.c header.c
-ln -s ../src/host.c host.c
-ln -s ../src/ip.c ip.c
-ln -s ../src/log.c log.c
-ln -s ../src/lss.c lss.c
-ln -s ../src/match.c match.c
-ln -s ../src/moan.c moan.c
-ln -s ../src/parse.c parse.c
-ln -s ../src/perl.c perl.c
-ln -s ../src/queue.c queue.c
-ln -s ../src/rda.c rda.c
-ln -s ../src/readconf.c readconf.c
-ln -s ../src/receive.c receive.c
-ln -s ../src/retry.c retry.c
-ln -s ../src/rewrite.c rewrite.c
-ln -s ../src/rfc2047.c rfc2047.c
-ln -s ../src/route.c route.c
-ln -s ../src/search.c search.c
-ln -s ../src/sieve.c sieve.c
-ln -s ../src/smtp_in.c smtp_in.c
-ln -s ../src/smtp_out.c smtp_out.c
-ln -s ../src/spool_in.c spool_in.c
-ln -s ../src/spool_out.c spool_out.c
-ln -s ../src/std-crypto.c std-crypto.c
-ln -s ../src/store.c store.c
-ln -s ../src/string.c string.c
-ln -s ../src/tls.c tls.c
-ln -s ../src/tlscert-gnu.c tlscert-gnu.c
-ln -s ../src/tlscert-openssl.c tlscert-openssl.c
-ln -s ../src/tls-gnu.c tls-gnu.c
-ln -s ../src/tls-openssl.c tls-openssl.c
-ln -s ../src/tod.c tod.c
-ln -s ../src/transport.c transport.c
-ln -s ../src/tree.c tree.c
-ln -s ../src/verify.c verify.c
-ln -s ../src/version.c version.c
-ln -s ../src/dkim.c dkim.c
-ln -s ../src/dkim.h dkim.h
-ln -s ../src/dmarc.c dmarc.c
-ln -s ../src/dmarc.h dmarc.h
-ln -s ../src/valgrind.h valgrind.h
-ln -s ../src/memcheck.h memcheck.h
+for f in dbfunctions.h dbstuff.h exim.h functions.h globals.h local_scan.h \
+ macros.h mytypes.h osfunctions.h store.h structs.h lookupapi.h \
+ \
+ acl.c buildconfig.c child.c crypt16.c daemon.c dbfn.c debug.c deliver.c \
+ directory.c dns.c drtables.c dummies.c enq.c exim.c exim_dbmbuild.c \
+ exim_dbutil.c exim_lock.c expand.c filter.c filtertest.c globals.c \
+ header.c host.c ip.c log.c lss.c match.c moan.c parse.c perl.c queue.c \
+ rda.c readconf.c receive.c retry.c rewrite.c rfc2047.c route.c search.c \
+ setenv.c \
+ sieve.c smtp_in.c smtp_out.c spool_in.c spool_out.c std-crypto.c store.c \
+ string.c tls.c tlscert-gnu.c tlscert-openssl.c tls-gnu.c tls-openssl.c \
+ tod.c transport.c tree.c verify.c version.c dkim.c dkim.h dmarc.c dmarc.h \
+ valgrind.h memcheck.h
+do
+ ln -s ../src/$f $f
+done
# WITH_CONTENT_SCAN
-ln -s ../src/spam.c spam.c
-ln -s ../src/spam.h spam.h
-ln -s ../src/spool_mbox.c spool_mbox.c
-ln -s ../src/regex.c regex.c
-ln -s ../src/mime.c mime.c
-ln -s ../src/mime.h mime.h
-ln -s ../src/malware.c malware.c
+for f in spam.c spam.h spool_mbox.c regex.c mime.c mime.h malware.c
+do
+ ln -s ../src/$f $f
+done
# WITH_OLD_DEMIME
-ln -s ../src/demime.c demime.c
-ln -s ../src/demime.h demime.h
+for f in demime.c demime.h
+do
+ ln -s ../src/$f $f
+done
# EXPERIMENTAL_*
-ln -s ../src/bmi_spam.c bmi_spam.c
-ln -s ../src/bmi_spam.h bmi_spam.h
-ln -s ../src/spf.c spf.c
-ln -s ../src/spf.h spf.h
-ln -s ../src/srs.c srs.c
-ln -s ../src/srs.h srs.h
-ln -s ../src/dcc.c dcc.c
-ln -s ../src/dcc.h dcc.h
-ln -s ../src/dane.c dane.c
-ln -s ../src/dane-gnu.c dane-gnu.c
-ln -s ../src/dane-openssl.c dane-openssl.c
-ln -s ../src/danessl.h danessl.h
+for f in bmi_spam.c bmi_spam.h dcc.c dcc.h dane.c dane-gnu.c dane-openssl.c \
+ danessl.h imap_utf7.c spf.c spf.h srs.c srs.h utf8.c
+do
+ ln -s ../src/$f $f
+done
# End of MakeLinks
for name_mod in \
CDB DBM:dbmdb DNSDB DSEARCH IBASE LSEARCH MYSQL NIS NISPLUS ORACLE \
- PASSWD PGSQL SQLITE TESTDB WHOSON
+ PASSWD PGSQL REDIS SQLITE TESTDB WHOSON
do
emit_module_rule $name_mod
done
OBJ="${OBJ} spf.o"
-# Because the variable is EXPERIMENTAL_REDIS and not LOOKUP_REDIS we
-# use a different function to check for EXPERIMENTAL_* features
-# requested. Don't use the SPF method with dummy functions above.
-if want_experimental REDIS
-then
- OBJ="${OBJ} redis.o"
-fi
-
echo "MODS = $MODS"
echo "OBJ = $OBJ"
# library.
# NOTE: LDAP cannot be built as a module!
#
+# For Redis you need to have hiredis installed on your system
+# (https://github.com/redis/hiredis).
+# Depending on where it is installed you may have to edit the CFLAGS
+# (often += -I/usr/local/include) and LDFLAGS (-lhiredis) lines.
+
# If your system has pkg-config then the _INCLUDE/_LIBS setting can be
# handled for you automatically by also defining the _PC variable to reference
# the name of the pkg-config package, if such is available.
# LOOKUP_ORACLE=yes
# LOOKUP_PASSWD=yes
# LOOKUP_PGSQL=yes
+# LOOKUP_REDIS=yes
# LOOKUP_SQLITE=yes
# LOOKUP_SQLITE_PC=sqlite3
# LOOKUP_WHOSON=yes
#------------------------------------------------------------------------------
-# The PCRE library is required for exim. There is no longer an embedded
+# The PCRE library is required for Exim. There is no longer an embedded
# version of the PCRE library included with the source code, instead you
# must use a system library or build your own copy of PCRE.
# In either case you must specify the library link info here. If the
# the command for linking Exim itself, not on any auxiliary programs. You
# don't need to set LOOKUP_INCLUDE if the relevant directories are already
# specified in INCLUDE. The settings below are just examples; -lpq is for
-# PostgreSQL, -lgds is for Interbase, -lsqlite3 is for SQLite.
+# PostgreSQL, -lgds is for Interbase, -lsqlite3 is for SQLite, -lhiredis
+# is for Redis.
#
# You do not need to use this for any lookup information added via pkg-config.
# WITH_OLD_DEMIME=yes
+#------------------------------------------------------------------------------
# If you're using ClamAV and are backporting fixes to an old version, instead
# of staying current (which is the more usual approach) then you may need to
# use an older API which uses a STREAM command, now deprecated, instead of
#
# WITH_OLD_CLAMAV_STREAM=yes
+
#------------------------------------------------------------------------------
# By default Exim includes code to support DKIM (DomainKeys Identified
# Mail, RFC4871) signing and verification. Verification of signatures is
# By default, Exim has support for checking the AD bit in a DNS response, to
# determine if DNSSEC validation was successful. If your system libraries
# do not support that bit, then set DISABLE_DNSSEC to "yes"
+# Note: Enabling EXPERIMENTAL_DANE unconditionally overrides this setting.
# DISABLE_DNSSEC=yes
+# To disable support for Events set DISABLE_EVENT to "yes"
+
+# DISABLE_EVENT=yes
+
#------------------------------------------------------------------------------
# Compiling Exim with experimental features. These are documented in
# Uncomment the following line to add support for talking to dccifd. This
# defaults the socket path to /usr/local/dcc/var/dccifd.
+# Doing so will also explicitly turn on the WITH_CONTENT_SCAN option.
# EXPERIMENTAL_DCC=yes
# CFLAGS += -I/usr/local/include
# LDFLAGS += -lopendmarc
-
-# Uncomment the following line to support Events,
-# eg. for logging to a database.
-# EXPERIMENTAL_EVENT=yes
-
-# Uncomment the following line to add Redis lookup support
-# You need to have hiredis installed on your system (https://github.com/redis/hiredis).
-# Depending on where it is installed you may have to edit the CFLAGS and LDFLAGS lines.
-# EXPERIMENTAL_REDIS=yes
-# CFLAGS += -I/usr/local/include
-# LDFLAGS += -lhiredis
-
-# Uncomment the following line to enable Experimental Proxy Protocol
-# EXPERIMENTAL_PROXY=yes
-
-# Uncomment the following line to enable support for checking certiticate
-# ownership
-# EXPERIMENTAL_CERTNAMES=yes
-
# Uncomment the following line to add DANE support
+# Note: Enabling this unconditionally overrides DISABLE_DNSSEC
# EXPERIMENTAL_DANE=yes
+# Uncomment the following to include extra information in fail DSN message (bounces)
+# EXPERIMENTAL_DSN_INFO=yes
+
###############################################################################
# THESE ARE THINGS YOU MIGHT WANT TO SPECIFY #
###############################################################################
# AUTH_HEIMDAL_GSSAPI_PC=heimdal-gssapi
# AUTH_PLAINTEXT=yes
# AUTH_SPA=yes
+# AUTH_TLS=yes
#------------------------------------------------------------------------------
# with the extension "texinfo" in the doc directory. You may find that the
# version number of the texinfo files is different to your Exim version number,
# because the main documentation isn't updated as often as the code. For
-# example, if you have Exim version 4.43, the source tarball upacks into a
+# example, if you have Exim version 4.43, the source tarball unpacks into a
# directory called exim-4.43, but the texinfo tarball unpacks into exim-4.40.
# In this case, move the contents of exim-4.40/doc into exim-4.43/doc after you
# have unpacked them. Then set INFO_DIRECTORY to the location of your info
# If the exigrep utility is fed compressed log files, it tries to uncompress
# them using this command.
+# Leave it empty to enforce autodetection at runtime:
+# ZCAT_COMMAND=
+#
+# Omit the path if you want to use your system's PATH:
+# ZCAT_COMMAND=zcat
+#
+# Or specify the full pathname:
ZCAT_COMMAND=/usr/bin/zcat
-
#------------------------------------------------------------------------------
# Compiling in support for embedded Perl: If you want to be able to
# use Perl code in Exim's string manipulation language and you have Perl
# GNU/Linux -ldl is also needed.
+#------------------------------------------------------------------------------
+# Proxying.
+#
+# If you may want to use outbound (client-side) proxying, using Socks5,
+# uncomment the line below.
+
+# SUPPORT_SOCKS=yes
+
+# If you may want to use inbound (server-side) proxying, using Proxy Protocol,
+# uncomment the line below.
+
+# SUPPORT_PROXY=yes
+
+
+#------------------------------------------------------------------------------
+# Internationalisation.
+#
+# Uncomment the following to include Internationalisation features. This is the
+# SMTPUTF8 ESMTP extension, and associated facilities for handling UTF8 domain
+# and localparts, per RFCs 5890, 6530 and 6533.
+# You need to have the IDN library installed.
+
+# SUPPORT_I18N=yes
+# LDFLAGS += -lidn
+
+
#------------------------------------------------------------------------------
# Support for authentication via Radius is also available. The Exim support,
# which is intended for use in conjunction with the SMTP AUTH facilities,
# There is no need to install all of SASL on your system. You just need to run
# ./configure --with-pwcheck, cd to the pwcheck directory within the sources,
# make and make install. You must create the socket directory (default
-# /var/pwcheck) and chown it to exim's user and group. Once you have installed
+# /var/pwcheck) and chown it to Exim's user and group. Once you have installed
# pwcheck, you should arrange for it to be started by root at boot time.
# CYRUS_PWCHECK_SOCKET=/var/pwcheck/pwcheck
#------------------------------------------------------------------------------
# Support for authentication via the Cyrus SASL saslauthd daemon is available.
-# The Exim support, which is intented for use in conjunction with the SMTP AUTH
+# The Exim support, which is intended for use in conjunction with the SMTP AUTH
# facilities, is included only when requested by setting the following
# parameter to the location of the saslauthd daemon's socket.
#
# ./configure --with-saslauthd (and any other options you need, for example, to
# select or deselect authentication mechanisms), cd to the saslauthd directory
# within the sources, make and make install. You must create the socket
-# directory (default /var/state/saslauthd) and chown it to exim's user and
+# directory (default /var/state/saslauthd) and chown it to Exim's user and
# group. Once you have installed saslauthd, you should arrange for it to be
# started by root at boot time.
# to handle the different cases. If CONFIGURE_FILE_USE_EUID is defined, then
# Exim will first look for a configuration file whose name is that defined
# by CONFIGURE_FILE, with the effective uid tacked on the end, separated by
-# a period (for eximple, /usr/exim/configure.0). If this file does not exist,
+# a period (for example, /usr/exim/configure.0). If this file does not exist,
# then the bare configuration file name is tried. In the case when both
# CONFIGURE_FILE_USE_EUID and CONFIGURE_FILE_USE_NODE are set, four files
# are tried: <name>.<euid>.<node>, <name>.<node>, <name>.<euid>, and <name>.
#------------------------------------------------------------------------------
-# Expanding match_* second paramters: BE CAREFUL IF ENABLING THIS!
+# Expanding match_* second parameters: BE CAREFUL IF ENABLING THIS!
# It has proven too easy in practice for administrators to configure security
# problems into their Exim install, by treating match_domain{}{} and friends
# as a form of string comparison, where the second string comes from untrusted
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Code for handling Access Control Lists (ACLs) */
enum {
CONTROL_AUTH_UNADVERTISED,
- #ifdef EXPERIMENTAL_BRIGHTMAIL
+#ifdef EXPERIMENTAL_BRIGHTMAIL
CONTROL_BMI_RUN,
- #endif
+#endif
CONTROL_DEBUG,
- #ifndef DISABLE_DKIM
+#ifndef DISABLE_DKIM
CONTROL_DKIM_VERIFY,
- #endif
- #ifdef EXPERIMENTAL_DMARC
+#endif
+#ifdef EXPERIMENTAL_DMARC
CONTROL_DMARC_VERIFY,
CONTROL_DMARC_FORENSIC,
- #endif
+#endif
CONTROL_DSCP,
CONTROL_ERROR,
CONTROL_CASEFUL_LOCAL_PART,
CONTROL_QUEUE_ONLY,
CONTROL_SUBMISSION,
CONTROL_SUPPRESS_LOCAL_FIXUPS,
- #ifdef WITH_CONTENT_SCAN
+#ifdef WITH_CONTENT_SCAN
CONTROL_NO_MBOX_UNSPOOL,
- #endif
+#endif
CONTROL_FAKEDEFER,
CONTROL_FAKEREJECT,
+#ifdef SUPPORT_I18N
+ CONTROL_UTF8_DOWNCONVERT,
+#endif
CONTROL_NO_MULTILINE,
CONTROL_NO_PIPELINING,
CONTROL_NO_DELAY_FLUSH,
static uschar *controls[] = {
US"allow_auth_unadvertised",
- #ifdef EXPERIMENTAL_BRIGHTMAIL
+#ifdef EXPERIMENTAL_BRIGHTMAIL
US"bmi_run",
- #endif
+#endif
US"debug",
- #ifndef DISABLE_DKIM
+#ifndef DISABLE_DKIM
US"dkim_disable_verify",
- #endif
- #ifdef EXPERIMENTAL_DMARC
+#endif
+#ifdef EXPERIMENTAL_DMARC
US"dmarc_disable_verify",
US"dmarc_enable_forensic",
- #endif
+#endif
US"dscp",
US"error",
US"caseful_local_part",
US"queue_only",
US"submission",
US"suppress_local_fixups",
- #ifdef WITH_CONTENT_SCAN
+#ifdef WITH_CONTENT_SCAN
US"no_mbox_unspool",
- #endif
+#endif
US"fakedefer",
US"fakereject",
+#ifdef SUPPORT_I18N
+ US"utf8_downconvert",
+#endif
US"no_multiline_responses",
US"no_pipelining",
US"no_delay_flush",
~(1<<ACL_WHERE_DATA), /* dmarc_status */
#endif
- (1<<ACL_WHERE_NOTSMTP)| /* dnslists */
- (1<<ACL_WHERE_NOTSMTP_START),
+ /* Explicit key lookups can be made in non-smtp ACLs so pass
+ always and check in the verify processing itself. */
+
+ 0, /* dnslists */
(unsigned int)
~((1<<ACL_WHERE_RCPT) /* domains */
(unsigned int)
~((1<<ACL_WHERE_CONNECT)|(1<<ACL_WHERE_HELO)), /* allow_auth_unadvertised */
- #ifdef EXPERIMENTAL_BRIGHTMAIL
+#ifdef EXPERIMENTAL_BRIGHTMAIL
0, /* bmi_run */
- #endif
+#endif
0, /* debug */
- #ifndef DISABLE_DKIM
+#ifndef DISABLE_DKIM
(1<<ACL_WHERE_DATA)|(1<<ACL_WHERE_NOTSMTP)| /* dkim_disable_verify */
- #ifndef DISABLE_PRDR
+# ifndef DISABLE_PRDR
(1<<ACL_WHERE_PRDR)|
- #endif
+# endif
(1<<ACL_WHERE_NOTSMTP_START),
- #endif
+#endif
- #ifdef EXPERIMENTAL_DMARC
+#ifdef EXPERIMENTAL_DMARC
(1<<ACL_WHERE_DATA)|(1<<ACL_WHERE_NOTSMTP)| /* dmarc_disable_verify */
(1<<ACL_WHERE_NOTSMTP_START),
(1<<ACL_WHERE_DATA)|(1<<ACL_WHERE_NOTSMTP)| /* dmarc_enable_forensic */
(1<<ACL_WHERE_NOTSMTP_START),
- #endif
+#endif
(1<<ACL_WHERE_NOTSMTP)|
(1<<ACL_WHERE_NOTSMTP_START)|
(1<<ACL_WHERE_PREDATA)|
(1<<ACL_WHERE_NOTSMTP_START)),
- #ifdef WITH_CONTENT_SCAN
+#ifdef WITH_CONTENT_SCAN
(unsigned int)
~((1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_RCPT)| /* no_mbox_unspool */
(1<<ACL_WHERE_PREDATA)|(1<<ACL_WHERE_DATA)|
// (1<<ACL_WHERE_PRDR)| /* Not allow one user to freeze for all */
(1<<ACL_WHERE_MIME)),
- #endif
+#endif
(unsigned int)
~((1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_RCPT)| /* fakedefer */
(1<<ACL_WHERE_PREDATA)|(1<<ACL_WHERE_DATA)|
- #ifndef DISABLE_PRDR
+#ifndef DISABLE_PRDR
(1<<ACL_WHERE_PRDR)|
- #endif
+#endif
(1<<ACL_WHERE_MIME)),
(unsigned int)
~((1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_RCPT)| /* fakereject */
(1<<ACL_WHERE_PREDATA)|(1<<ACL_WHERE_DATA)|
- #ifndef DISABLE_PRDR
+#ifndef DISABLE_PRDR
(1<<ACL_WHERE_PRDR)|
- #endif
+#endif
(1<<ACL_WHERE_MIME)),
+#ifdef SUPPORT_I18N
+ 0, /* utf8_downconvert */
+#endif
+
(1<<ACL_WHERE_NOTSMTP)| /* no_multiline */
(1<<ACL_WHERE_NOTSMTP_START),
} control_def;
static control_def controls_list[] = {
- { US"allow_auth_unadvertised", CONTROL_AUTH_UNADVERTISED, FALSE },
+ { US"allow_auth_unadvertised", CONTROL_AUTH_UNADVERTISED, FALSE },
#ifdef EXPERIMENTAL_BRIGHTMAIL
- { US"bmi_run", CONTROL_BMI_RUN, FALSE },
+ { US"bmi_run", CONTROL_BMI_RUN, FALSE },
#endif
- { US"debug", CONTROL_DEBUG, TRUE },
+ { US"debug", CONTROL_DEBUG, TRUE },
#ifndef DISABLE_DKIM
- { US"dkim_disable_verify", CONTROL_DKIM_VERIFY, FALSE },
+ { US"dkim_disable_verify", CONTROL_DKIM_VERIFY, FALSE },
#endif
#ifdef EXPERIMENTAL_DMARC
- { US"dmarc_disable_verify", CONTROL_DMARC_VERIFY, FALSE },
- { US"dmarc_enable_forensic", CONTROL_DMARC_FORENSIC, FALSE },
+ { US"dmarc_disable_verify", CONTROL_DMARC_VERIFY, FALSE },
+ { US"dmarc_enable_forensic", CONTROL_DMARC_FORENSIC, FALSE },
#endif
- { US"dscp", CONTROL_DSCP, TRUE },
- { US"caseful_local_part", CONTROL_CASEFUL_LOCAL_PART, FALSE },
- { US"caselower_local_part", CONTROL_CASELOWER_LOCAL_PART, FALSE },
- { US"enforce_sync", CONTROL_ENFORCE_SYNC, FALSE },
- { US"freeze", CONTROL_FREEZE, TRUE },
- { US"no_callout_flush", CONTROL_NO_CALLOUT_FLUSH, FALSE },
- { US"no_delay_flush", CONTROL_NO_DELAY_FLUSH, FALSE },
- { US"no_enforce_sync", CONTROL_NO_ENFORCE_SYNC, FALSE },
- { US"no_multiline_responses", CONTROL_NO_MULTILINE, FALSE },
- { US"no_pipelining", CONTROL_NO_PIPELINING, FALSE },
- { US"queue_only", CONTROL_QUEUE_ONLY, FALSE },
+ { US"dscp", CONTROL_DSCP, TRUE },
+ { US"caseful_local_part", CONTROL_CASEFUL_LOCAL_PART, FALSE },
+ { US"caselower_local_part", CONTROL_CASELOWER_LOCAL_PART, FALSE },
+ { US"enforce_sync", CONTROL_ENFORCE_SYNC, FALSE },
+ { US"freeze", CONTROL_FREEZE, TRUE },
+ { US"no_callout_flush", CONTROL_NO_CALLOUT_FLUSH, FALSE },
+ { US"no_delay_flush", CONTROL_NO_DELAY_FLUSH, FALSE },
+ { US"no_enforce_sync", CONTROL_NO_ENFORCE_SYNC, FALSE },
+ { US"no_multiline_responses", CONTROL_NO_MULTILINE, FALSE },
+ { US"no_pipelining", CONTROL_NO_PIPELINING, FALSE },
+ { US"queue_only", CONTROL_QUEUE_ONLY, FALSE },
#ifdef WITH_CONTENT_SCAN
- { US"no_mbox_unspool", CONTROL_NO_MBOX_UNSPOOL, FALSE },
+ { US"no_mbox_unspool", CONTROL_NO_MBOX_UNSPOOL, FALSE },
#endif
- { US"fakedefer", CONTROL_FAKEDEFER, TRUE },
- { US"fakereject", CONTROL_FAKEREJECT, TRUE },
- { US"submission", CONTROL_SUBMISSION, TRUE },
+ { US"fakedefer", CONTROL_FAKEDEFER, TRUE },
+ { US"fakereject", CONTROL_FAKEREJECT, TRUE },
+ { US"submission", CONTROL_SUBMISSION, TRUE },
{ US"suppress_local_fixups", CONTROL_SUPPRESS_LOCAL_FIXUPS, FALSE },
- { US"cutthrough_delivery", CONTROL_CUTTHROUGH_DELIVERY, FALSE }
+ { US"cutthrough_delivery", CONTROL_CUTTHROUGH_DELIVERY, FALSE },
+#ifdef SUPPORT_I18N
+ { US"utf8_downconvert", CONTROL_UTF8_DOWNCONVERT, TRUE }
+#endif
};
/* Support data structures for Client SMTP Authorization. acl_verify_csa()
/* Enable recursion between acl_check_internal() and acl_check_condition() */
-static int acl_check_wargs(int, address_item *, uschar *, int, uschar **,
+static int acl_check_wargs(int, address_item *, const uschar *, int, uschar **,
uschar **);
*/
static void
-setup_header(uschar *hstring)
+setup_header(const uschar *hstring)
{
-uschar *p, *q;
+const uschar *p, *q;
int hlen = Ustrlen(hstring);
/* Ignore any leading newlines */
/* An empty string does nothing; ensure exactly one final newline. */
if (hlen <= 0) return;
-if (hstring[--hlen] != '\n') hstring = string_sprintf("%s\n", hstring);
-else while(hstring[--hlen] == '\n') hstring[hlen+1] = '\0';
+if (hstring[--hlen] != '\n')
+ q = string_sprintf("%s\n", hstring);
+else if (hstring[hlen-1] == '\n')
+ {
+ uschar * s = string_copy(hstring);
+ while(s[--hlen] == '\n')
+ s[hlen+1] = '\0';
+ q = s;
+ }
+else
+ q = hstring;
/* Loop for multiple header lines, taking care about continuations */
-for (p = q = hstring; *p != 0; )
+for (p = q; *p != 0; )
{
- uschar *s;
+ const uschar *s;
+ uschar * hdr;
int newtype = htype_add_bot;
header_line **hptr = &acl_added_headers;
if (*s == ':' || !isgraph(*s)) break;
}
- s = string_sprintf("%s%.*s", (*s == ':')? "" : "X-ACL-Warn: ", (int) (q - p), p);
- hlen = Ustrlen(s);
+ hdr = string_sprintf("%s%.*s", (*s == ':')? "" : "X-ACL-Warn: ", (int) (q - p), p);
+ hlen = Ustrlen(hdr);
/* See if this line has already been added */
while (*hptr != NULL)
{
- if (Ustrncmp((*hptr)->text, s, hlen) == 0) break;
+ if (Ustrncmp((*hptr)->text, hdr, hlen) == 0) break;
hptr = &((*hptr)->next);
}
if (*hptr == NULL)
{
header_line *h = store_get(sizeof(header_line));
- h->text = s;
+ h->text = hdr;
h->next = NULL;
h->type = newtype;
h->slen = hlen;
*/
static void
-setup_remove_header(uschar *hnames)
+setup_remove_header(const uschar *hnames)
{
if (*hnames != 0)
- {
- if (acl_removed_headers == NULL)
- acl_removed_headers = hnames;
- else
- acl_removed_headers = string_sprintf("%s : %s", acl_removed_headers, hnames);
- }
+ acl_removed_headers = acl_removed_headers
+ ? string_sprintf("%s : %s", acl_removed_headers, hnames)
+ : string_copy(hnames);
}
if (rr->type != T_A
#if HAVE_IPV6
&& rr->type != T_AAAA
- #ifdef SUPPORT_A6
- && rr->type != T_A6
- #endif
#endif
) continue;
*/
static int
-acl_verify_csa(uschar *domain)
+acl_verify_csa(const uschar *domain)
{
tree_node *t;
-uschar *found, *p;
+const uschar *found;
+uschar *p;
int priority, weight, port;
dns_answer dnsa;
dns_scan dnss;
if (domain[0] == '[')
{
- uschar *start = Ustrchr(domain, ':');
+ const uschar *start = Ustrchr(domain, ':');
if (start == NULL) start = domain;
domain = string_copyn(start + 1, Ustrlen(start) - 2);
}
assertion: legitimate SMTP clients are all explicitly authorized with CSA
SRV records of their own. */
- if (found != domain)
+ if (Ustrcmp(found, domain) != 0)
{
if (port & 1)
return t->data.val = CSA_FAIL_EXPLICIT;
type = T_A;
-#if HAVE_IPV6 && defined(SUPPORT_A6)
-DNS_LOOKUP_AGAIN:
-#endif
-
lookup_dnssec_authenticated = NULL;
switch (dns_lookup(&dnsa, target, type, NULL))
{
/* If something bad happened (most commonly DNS_AGAIN), defer. */
default:
- return t->data.val = CSA_DEFER_ADDR;
+ return t->data.val = CSA_DEFER_ADDR;
/* If the query succeeded, scan the addresses and return the result. */
case DNS_SUCCEED:
- rc = acl_verify_csa_address(&dnsa, &dnss, RESET_ANSWERS, target);
- if (rc != CSA_FAIL_NOADDR) return t->data.val = rc;
- /* else fall through */
+ rc = acl_verify_csa_address(&dnsa, &dnss, RESET_ANSWERS, target);
+ if (rc != CSA_FAIL_NOADDR) return t->data.val = rc;
+ /* else fall through */
/* If the target has no IP addresses, the client cannot have an authorized
IP address. However, if the target site uses A6 records (not AAAA records)
case DNS_NOMATCH:
case DNS_NODATA:
-
- #if HAVE_IPV6 && defined(SUPPORT_A6)
- if (type == T_AAAA) { type = T_A6; goto DNS_LOOKUP_AGAIN; }
- #endif
-
- return t->data.val = CSA_FAIL_NOADDR;
+ return t->data.val = CSA_FAIL_NOADDR;
}
}
unsigned alt_opt_sep; /* >0 Non-/ option separator (custom parser) */
} verify_type_t;
static verify_type_t verify_type_list[] = {
- { US"reverse_host_lookup", VERIFY_REV_HOST_LKUP, ~0, TRUE, 0 },
+ { US"reverse_host_lookup", VERIFY_REV_HOST_LKUP, ~0, FALSE, 0 },
{ US"certificate", VERIFY_CERT, ~0, TRUE, 0 },
{ US"helo", VERIFY_HELO, ~0, TRUE, 0 },
{ US"csa", VERIFY_CSA, ~0, FALSE, 0 },
*/
static int
-acl_verify(int where, address_item *addr, uschar *arg,
+acl_verify(int where, address_item *addr, const uschar *arg,
uschar **user_msgptr, uschar **log_msgptr, int *basic_errno)
{
int sep = '/';
*/
uschar *slash = Ustrchr(arg, '/');
-uschar *list = arg;
+const uschar *list = arg;
uschar *ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size);
verify_type_t * vp;
{
case VERIFY_REV_HOST_LKUP:
if (sender_host_address == NULL) return OK;
- return acl_verify_reverse(user_msgptr, log_msgptr);
+ if ((rc = acl_verify_reverse(user_msgptr, log_msgptr)) == DEFER)
+ while ((ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)))
+ if (strcmpic(ss, US"defer_ok") == 0)
+ return OK;
+ return rc;
case VERIFY_CERT:
/* TLS certificate verification is done at STARTTLS time; here we just
test whether it was successful or not. (This is for optional verification; for
mandatory verification, the connection doesn't last this long.) */
- if (tls_in.certificate_verified) return OK;
- *user_msgptr = US"no verified certificate";
- return FAIL;
+ if (tls_in.certificate_verified) return OK;
+ *user_msgptr = US"no verified certificate";
+ return FAIL;
case VERIFY_HELO:
/* We can test the result of optional HELO verification that might have
occurred earlier. If not, we can attempt the verification now. */
- if (!helo_verified && !helo_verify_failed) smtp_verify_helo();
- return helo_verified? OK : FAIL;
+ if (!helo_verified && !helo_verify_failed) smtp_verify_helo();
+ return helo_verified? OK : FAIL;
case VERIFY_CSA:
/* Do Client SMTP Authorization checks in a separate function, and turn the
result code into user-friendly strings. */
- rc = acl_verify_csa(list);
- *log_msgptr = *user_msgptr = string_sprintf("client SMTP authorization %s",
+ rc = acl_verify_csa(list);
+ *log_msgptr = *user_msgptr = string_sprintf("client SMTP authorization %s",
csa_reason_string[rc]);
- csa_status = csa_status_string[rc];
- DEBUG(D_acl) debug_printf("CSA result %s\n", csa_status);
- return csa_return_code[rc];
+ csa_status = csa_status_string[rc];
+ DEBUG(D_acl) debug_printf("CSA result %s\n", csa_status);
+ return csa_return_code[rc];
case VERIFY_HDR_SYNTAX:
/* Check that all relevant header lines have the correct syntax. If there is
always). */
rc = verify_check_headers(log_msgptr);
- if (rc != OK && smtp_return_error_details && *log_msgptr != NULL)
- *user_msgptr = string_sprintf("Rejected after DATA: %s", *log_msgptr);
+ if (rc != OK && *log_msgptr)
+ if (smtp_return_error_details)
+ *user_msgptr = string_sprintf("Rejected after DATA: %s", *log_msgptr);
+ else
+ acl_verify_message = *log_msgptr;
return rc;
case VERIFY_HDR_NAMES_ASCII:
while (isspace(*ss)) ss++;
if (*ss++ == '=')
{
+ const uschar * sublist = ss;
int optsep = ',';
uschar *opt;
uschar buffer[256];
- while (isspace(*ss)) ss++;
+ while (isspace(*sublist)) sublist++;
- while ((opt = string_nextinlist(&ss, &optsep, buffer, sizeof(buffer)))
+ while ((opt = string_nextinlist(&sublist, &optsep, buffer, sizeof(buffer)))
!= NULL)
{
callout_opt_t * op;
uschar *save_address_data = deliver_address_data;
sender_vaddr = deliver_make_addr(verify_sender_address, TRUE);
+#ifdef SUPPORT_I18N
+ if ((sender_vaddr->prop.utf8_msg = message_smtputf8))
+ {
+ sender_vaddr->prop.utf8_downcvt = message_utf8_downconvert == 1;
+ sender_vaddr->prop.utf8_downcvt_maybe = message_utf8_downconvert == -1;
+ }
+#endif
if (no_details) setflag(sender_vaddr, af_sverify_told);
if (verify_sender_address[0] != 0)
{
/* Put the sender address_data value into $sender_address_data */
- sender_address_data = sender_vaddr->p.address_data;
+ sender_address_data = sender_vaddr->prop.address_data;
}
/* A recipient address just gets a straightforward verify; again we must handle
if (testflag((&addr2), af_pass_message)) acl_temp_details = TRUE;
/* Make $address_data visible */
- deliver_address_data = addr2.p.address_data;
+ deliver_address_data = addr2.prop.address_data;
}
/* We have a result from the relevant test. Handle defer overrides first. */
if (rc != OK && verify_sender_address != NULL)
{
if (rc != DEFER)
- {
*log_msgptr = *user_msgptr = US"Sender verify failed";
- }
else if (*basic_errno != ERRNO_CALLOUTDEFER)
- {
*log_msgptr = *user_msgptr = US"Could not complete sender verify";
- }
else
{
*log_msgptr = US"Could not complete sender verify callout";
*/
static int
-decode_control(uschar *arg, uschar **pptr, int where, uschar **log_msgptr)
+decode_control(const uschar *arg, const uschar **pptr, int where, uschar **log_msgptr)
{
int len;
control_def *d;
*/
static int
-acl_ratelimit(uschar *arg, int where, uschar **log_msgptr)
+acl_ratelimit(const uschar *arg, int where, uschar **log_msgptr)
{
double limit, period, count;
uschar *ss;
sender_rate_limit = string_nextinlist(&arg, &sep, NULL, 0);
if (sender_rate_limit == NULL)
+ {
limit = -1.0;
+ ss = NULL; /* compiler quietening */
+ }
else
{
limit = Ustrtod(sender_rate_limit, &ss);
*/
static int
-acl_udpsend(uschar *arg, uschar **log_msgptr)
+acl_udpsend(const uschar *arg, uschar **log_msgptr)
{
int sep = 0;
uschar *hostname;
uschar *log_message = NULL;
uschar *debug_tag = NULL;
uschar *debug_opts = NULL;
-uschar *p = NULL;
int rc = OK;
#ifdef WITH_CONTENT_SCAN
int sep = -'/';
for (; cb != NULL; cb = cb->next)
{
- uschar *arg;
+ const uschar *arg;
int control_type;
/* The message and log_message items set up messages to be used in
break;
case ACLC_CONTROL:
- control_type = decode_control(arg, &p, where, log_msgptr);
-
- /* Check if this control makes sense at this time */
-
- if ((control_forbids[control_type] & (1 << where)) != 0)
{
- *log_msgptr = string_sprintf("cannot use \"control=%s\" in %s ACL",
- controls[control_type], acl_wherenames[where]);
- return ERROR;
- }
+ const uschar *p = NULL;
+ control_type = decode_control(arg, &p, where, log_msgptr);
- switch(control_type)
- {
- case CONTROL_AUTH_UNADVERTISED:
- allow_auth_unadvertised = TRUE;
- break;
+ /* Check if this control makes sense at this time */
- #ifdef EXPERIMENTAL_BRIGHTMAIL
- case CONTROL_BMI_RUN:
- bmi_run = 1;
- break;
- #endif
-
- #ifndef DISABLE_DKIM
- case CONTROL_DKIM_VERIFY:
- dkim_disable_verify = TRUE;
- #ifdef EXPERIMENTAL_DMARC
- /* Since DKIM was blocked, skip DMARC too */
- dmarc_disable_verify = TRUE;
- dmarc_enable_forensic = FALSE;
- #endif
- break;
- #endif
+ if ((control_forbids[control_type] & (1 << where)) != 0)
+ {
+ *log_msgptr = string_sprintf("cannot use \"control=%s\" in %s ACL",
+ controls[control_type], acl_wherenames[where]);
+ return ERROR;
+ }
- #ifdef EXPERIMENTAL_DMARC
- case CONTROL_DMARC_VERIFY:
- dmarc_disable_verify = TRUE;
- break;
+ switch(control_type)
+ {
+ case CONTROL_AUTH_UNADVERTISED:
+ allow_auth_unadvertised = TRUE;
+ break;
- case CONTROL_DMARC_FORENSIC:
- dmarc_enable_forensic = TRUE;
- break;
- #endif
+ #ifdef EXPERIMENTAL_BRIGHTMAIL
+ case CONTROL_BMI_RUN:
+ bmi_run = 1;
+ break;
+ #endif
+
+ #ifndef DISABLE_DKIM
+ case CONTROL_DKIM_VERIFY:
+ dkim_disable_verify = TRUE;
+ #ifdef EXPERIMENTAL_DMARC
+ /* Since DKIM was blocked, skip DMARC too */
+ dmarc_disable_verify = TRUE;
+ dmarc_enable_forensic = FALSE;
+ #endif
+ break;
+ #endif
- case CONTROL_DSCP:
- if (*p == '/')
- {
- int fd, af, level, optname, value;
- /* If we are acting on stdin, the setsockopt may fail if stdin is not
- a socket; we can accept that, we'll just debug-log failures anyway. */
- fd = fileno(smtp_in);
- af = ip_get_address_family(fd);
- if (af < 0)
- {
- HDEBUG(D_acl)
- debug_printf("smtp input is probably not a socket [%s], not setting DSCP\n",
- strerror(errno));
- break;
- }
- if (dscp_lookup(p+1, af, &level, &optname, &value))
- {
- if (setsockopt(fd, level, optname, &value, sizeof(value)) < 0)
- {
- HDEBUG(D_acl) debug_printf("failed to set input DSCP[%s]: %s\n",
- p+1, strerror(errno));
- }
- else
- {
- HDEBUG(D_acl) debug_printf("set input DSCP to \"%s\"\n", p+1);
- }
- }
- else
- {
- *log_msgptr = string_sprintf("unrecognised DSCP value in \"control=%s\"", arg);
- return ERROR;
- }
- }
- else
- {
- *log_msgptr = string_sprintf("syntax error in \"control=%s\"", arg);
- return ERROR;
- }
- break;
+ #ifdef EXPERIMENTAL_DMARC
+ case CONTROL_DMARC_VERIFY:
+ dmarc_disable_verify = TRUE;
+ break;
- case CONTROL_ERROR:
- return ERROR;
+ case CONTROL_DMARC_FORENSIC:
+ dmarc_enable_forensic = TRUE;
+ break;
+ #endif
- case CONTROL_CASEFUL_LOCAL_PART:
- deliver_localpart = addr->cc_local_part;
- break;
+ case CONTROL_DSCP:
+ if (*p == '/')
+ {
+ int fd, af, level, optname, value;
+ /* If we are acting on stdin, the setsockopt may fail if stdin is not
+ a socket; we can accept that, we'll just debug-log failures anyway. */
+ fd = fileno(smtp_in);
+ af = ip_get_address_family(fd);
+ if (af < 0)
+ {
+ HDEBUG(D_acl)
+ debug_printf("smtp input is probably not a socket [%s], not setting DSCP\n",
+ strerror(errno));
+ break;
+ }
+ if (dscp_lookup(p+1, af, &level, &optname, &value))
+ {
+ if (setsockopt(fd, level, optname, &value, sizeof(value)) < 0)
+ {
+ HDEBUG(D_acl) debug_printf("failed to set input DSCP[%s]: %s\n",
+ p+1, strerror(errno));
+ }
+ else
+ {
+ HDEBUG(D_acl) debug_printf("set input DSCP to \"%s\"\n", p+1);
+ }
+ }
+ else
+ {
+ *log_msgptr = string_sprintf("unrecognised DSCP value in \"control=%s\"", arg);
+ return ERROR;
+ }
+ }
+ else
+ {
+ *log_msgptr = string_sprintf("syntax error in \"control=%s\"", arg);
+ return ERROR;
+ }
+ break;
- case CONTROL_CASELOWER_LOCAL_PART:
- deliver_localpart = addr->lc_local_part;
- break;
+ case CONTROL_ERROR:
+ return ERROR;
- case CONTROL_ENFORCE_SYNC:
- smtp_enforce_sync = TRUE;
- break;
+ case CONTROL_CASEFUL_LOCAL_PART:
+ deliver_localpart = addr->cc_local_part;
+ break;
- case CONTROL_NO_ENFORCE_SYNC:
- smtp_enforce_sync = FALSE;
- break;
+ case CONTROL_CASELOWER_LOCAL_PART:
+ deliver_localpart = addr->lc_local_part;
+ break;
- #ifdef WITH_CONTENT_SCAN
- case CONTROL_NO_MBOX_UNSPOOL:
- no_mbox_unspool = TRUE;
- break;
- #endif
+ case CONTROL_ENFORCE_SYNC:
+ smtp_enforce_sync = TRUE;
+ break;
- case CONTROL_NO_MULTILINE:
- no_multiline_responses = TRUE;
- break;
+ case CONTROL_NO_ENFORCE_SYNC:
+ smtp_enforce_sync = FALSE;
+ break;
- case CONTROL_NO_PIPELINING:
- pipelining_enable = FALSE;
- break;
+ #ifdef WITH_CONTENT_SCAN
+ case CONTROL_NO_MBOX_UNSPOOL:
+ no_mbox_unspool = TRUE;
+ break;
+ #endif
- case CONTROL_NO_DELAY_FLUSH:
- disable_delay_flush = TRUE;
- break;
+ case CONTROL_NO_MULTILINE:
+ no_multiline_responses = TRUE;
+ break;
- case CONTROL_NO_CALLOUT_FLUSH:
- disable_callout_flush = TRUE;
- break;
+ case CONTROL_NO_PIPELINING:
+ pipelining_enable = FALSE;
+ break;
- case CONTROL_FAKEREJECT:
- cancel_cutthrough_connection("fakereject");
- case CONTROL_FAKEDEFER:
- fake_response = (control_type == CONTROL_FAKEDEFER) ? DEFER : FAIL;
- if (*p == '/')
- {
- uschar *pp = p + 1;
- while (*pp != 0) pp++;
- fake_response_text = expand_string(string_copyn(p+1, pp-p-1));
- p = pp;
- }
- else
- {
- /* Explicitly reset to default string */
- fake_response_text = US"Your message has been rejected but is being kept for evaluation.\nIf it was a legitimate message, it may still be delivered to the target recipient(s).";
- }
- break;
+ case CONTROL_NO_DELAY_FLUSH:
+ disable_delay_flush = TRUE;
+ break;
- case CONTROL_FREEZE:
- deliver_freeze = TRUE;
- deliver_frozen_at = time(NULL);
- freeze_tell = freeze_tell_config; /* Reset to configured value */
- if (Ustrncmp(p, "/no_tell", 8) == 0)
- {
- p += 8;
- freeze_tell = NULL;
- }
- if (*p != 0)
- {
- *log_msgptr = string_sprintf("syntax error in \"control=%s\"", arg);
- return ERROR;
- }
- cancel_cutthrough_connection("item frozen");
- break;
+ case CONTROL_NO_CALLOUT_FLUSH:
+ disable_callout_flush = TRUE;
+ break;
- case CONTROL_QUEUE_ONLY:
- queue_only_policy = TRUE;
- cancel_cutthrough_connection("queueing forced");
- break;
+ case CONTROL_FAKEREJECT:
+ cancel_cutthrough_connection("fakereject");
+ case CONTROL_FAKEDEFER:
+ fake_response = (control_type == CONTROL_FAKEDEFER) ? DEFER : FAIL;
+ if (*p == '/')
+ {
+ const uschar *pp = p + 1;
+ while (*pp != 0) pp++;
+ fake_response_text = expand_string(string_copyn(p+1, pp-p-1));
+ p = pp;
+ }
+ else
+ {
+ /* Explicitly reset to default string */
+ fake_response_text = US"Your message has been rejected but is being kept for evaluation.\nIf it was a legitimate message, it may still be delivered to the target recipient(s).";
+ }
+ break;
- case CONTROL_SUBMISSION:
- originator_name = US"";
- submission_mode = TRUE;
- while (*p == '/')
- {
- if (Ustrncmp(p, "/sender_retain", 14) == 0)
- {
- p += 14;
- active_local_sender_retain = TRUE;
- active_local_from_check = FALSE;
- }
- else if (Ustrncmp(p, "/domain=", 8) == 0)
- {
- uschar *pp = p + 8;
- while (*pp != 0 && *pp != '/') pp++;
- submission_domain = string_copyn(p+8, pp-p-8);
- p = pp;
- }
- /* The name= option must be last, because it swallows the rest of
- the string. */
- else if (Ustrncmp(p, "/name=", 6) == 0)
- {
- uschar *pp = p + 6;
- while (*pp != 0) pp++;
- submission_name = string_copy(parse_fix_phrase(p+6, pp-p-6,
- big_buffer, big_buffer_size));
- p = pp;
- }
- else break;
- }
- if (*p != 0)
- {
- *log_msgptr = string_sprintf("syntax error in \"control=%s\"", arg);
- return ERROR;
- }
- break;
+ case CONTROL_FREEZE:
+ deliver_freeze = TRUE;
+ deliver_frozen_at = time(NULL);
+ freeze_tell = freeze_tell_config; /* Reset to configured value */
+ if (Ustrncmp(p, "/no_tell", 8) == 0)
+ {
+ p += 8;
+ freeze_tell = NULL;
+ }
+ if (*p != 0)
+ {
+ *log_msgptr = string_sprintf("syntax error in \"control=%s\"", arg);
+ return ERROR;
+ }
+ cancel_cutthrough_connection("item frozen");
+ break;
- case CONTROL_DEBUG:
- while (*p == '/')
- {
- if (Ustrncmp(p, "/tag=", 5) == 0)
- {
- uschar *pp = p + 5;
- while (*pp != '\0' && *pp != '/') pp++;
- debug_tag = string_copyn(p+5, pp-p-5);
- p = pp;
- }
- else if (Ustrncmp(p, "/opts=", 6) == 0)
- {
- uschar *pp = p + 6;
- while (*pp != '\0' && *pp != '/') pp++;
- debug_opts = string_copyn(p+6, pp-p-6);
- p = pp;
- }
- }
- debug_logging_activate(debug_tag, debug_opts);
- break;
+ case CONTROL_QUEUE_ONLY:
+ queue_only_policy = TRUE;
+ cancel_cutthrough_connection("queueing forced");
+ break;
- case CONTROL_SUPPRESS_LOCAL_FIXUPS:
- suppress_local_fixups = TRUE;
- break;
+ case CONTROL_SUBMISSION:
+ originator_name = US"";
+ submission_mode = TRUE;
+ while (*p == '/')
+ {
+ if (Ustrncmp(p, "/sender_retain", 14) == 0)
+ {
+ p += 14;
+ active_local_sender_retain = TRUE;
+ active_local_from_check = FALSE;
+ }
+ else if (Ustrncmp(p, "/domain=", 8) == 0)
+ {
+ const uschar *pp = p + 8;
+ while (*pp != 0 && *pp != '/') pp++;
+ submission_domain = string_copyn(p+8, pp-p-8);
+ p = pp;
+ }
+ /* The name= option must be last, because it swallows the rest of
+ the string. */
+ else if (Ustrncmp(p, "/name=", 6) == 0)
+ {
+ const uschar *pp = p + 6;
+ while (*pp != 0) pp++;
+ submission_name = string_copy(parse_fix_phrase(p+6, pp-p-6,
+ big_buffer, big_buffer_size));
+ p = pp;
+ }
+ else break;
+ }
+ if (*p != 0)
+ {
+ *log_msgptr = string_sprintf("syntax error in \"control=%s\"", arg);
+ return ERROR;
+ }
+ break;
- case CONTROL_CUTTHROUGH_DELIVERY:
- if (deliver_freeze)
- *log_msgptr = US"frozen";
- else if (queue_only_policy)
- *log_msgptr = US"queue-only";
- else if (fake_response == FAIL)
- *log_msgptr = US"fakereject";
- else
- {
- cutthrough_delivery = TRUE;
+ case CONTROL_DEBUG:
+ while (*p == '/')
+ {
+ if (Ustrncmp(p, "/tag=", 5) == 0)
+ {
+ const uschar *pp = p + 5;
+ while (*pp != '\0' && *pp != '/') pp++;
+ debug_tag = string_copyn(p+5, pp-p-5);
+ p = pp;
+ }
+ else if (Ustrncmp(p, "/opts=", 6) == 0)
+ {
+ const uschar *pp = p + 6;
+ while (*pp != '\0' && *pp != '/') pp++;
+ debug_opts = string_copyn(p+6, pp-p-6);
+ p = pp;
+ }
+ }
+ debug_logging_activate(debug_tag, debug_opts);
break;
+
+ case CONTROL_SUPPRESS_LOCAL_FIXUPS:
+ suppress_local_fixups = TRUE;
+ break;
+
+ case CONTROL_CUTTHROUGH_DELIVERY:
+#ifndef DISABLE_PRDR
+ if (prdr_requested)
+#else
+ if (0)
+#endif
+ /* Too hard to think about for now. We might in future cutthrough
+ the case where both sides handle prdr and this-node prdr acl
+ is "accept" */
+ *log_msgptr = string_sprintf("PRDR on %s reception\n", arg);
+ else
+ {
+ if (deliver_freeze)
+ *log_msgptr = US"frozen";
+ else if (queue_only_policy)
+ *log_msgptr = US"queue-only";
+ else if (fake_response == FAIL)
+ *log_msgptr = US"fakereject";
+ else
+ {
+ if (rcpt_count == 1) cutthrough.delivery = TRUE;
+ break;
+ }
+ *log_msgptr = string_sprintf("\"control=%s\" on %s item",
+ arg, *log_msgptr);
+ }
+ return ERROR;
+
+#ifdef SUPPORT_I18N
+ case CONTROL_UTF8_DOWNCONVERT:
+ if (*p == '/')
+ {
+ if (p[1] == '1')
+ {
+ message_utf8_downconvert = 1;
+ addr->prop.utf8_downcvt = TRUE;
+ addr->prop.utf8_downcvt_maybe = FALSE;
+ p += 2;
+ break;
+ }
+ if (p[1] == '0')
+ {
+ message_utf8_downconvert = 0;
+ addr->prop.utf8_downcvt = FALSE;
+ addr->prop.utf8_downcvt_maybe = FALSE;
+ p += 2;
+ break;
+ }
+ if (p[1] == '-' && p[2] == '1')
+ {
+ message_utf8_downconvert = -1;
+ addr->prop.utf8_downcvt = FALSE;
+ addr->prop.utf8_downcvt_maybe = TRUE;
+ p += 3;
+ break;
+ }
+ *log_msgptr = US"bad option value for control=utf8_downconvert";
+ }
+ else
+ {
+ message_utf8_downconvert = 1;
+ addr->prop.utf8_downcvt = TRUE;
+ addr->prop.utf8_downcvt_maybe = FALSE;
+ break;
+ }
+ return ERROR;
+#endif
+
}
- *log_msgptr = string_sprintf("\"control=%s\" on %s item",
- arg, *log_msgptr);
- return ERROR;
+ break;
}
- break;
#ifdef EXPERIMENTAL_DCC
case ACLC_DCC:
{
/* Seperate the regular expression and any optional parameters. */
- uschar *ss = string_nextinlist(&arg, &sep, big_buffer, big_buffer_size);
+ const uschar * list = arg;
+ uschar *ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size);
/* Run the dcc backend. */
rc = dcc_process(&ss);
/* Modify return code based upon the existance of options. */
- while ((ss = string_nextinlist(&arg, &sep, big_buffer, big_buffer_size))
- != NULL) {
+ while ((ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)))
if (strcmpic(ss, US"defer_ok") == 0 && rc == DEFER)
- {
- /* FAIL so that the message is passed to the next ACL */
- rc = FAIL;
- }
- }
+ rc = FAIL; /* FAIL so that the message is passed to the next ACL */
}
break;
#endif
debug_printf("delay skipped in -bh checking mode\n");
}
+ /* NOTE 1: Remember that we may be
+ dealing with stdin/stdout here, in addition to TCP/IP connections.
+ Also, delays may be specified for non-SMTP input, where smtp_out and
+ smtp_in will be NULL. Whatever is done must work in all cases.
+
+ NOTE 2: The added feature of flushing the output before a delay must
+ apply only to SMTP input. Hence the test for smtp_out being non-NULL.
+ */
+
+ else
+ {
+ if (smtp_out != NULL && !disable_delay_flush)
+ mac_smtp_fflush();
+
+#if !defined(NO_POLL_H) && defined (POLLRDHUP)
+ {
+ struct pollfd p;
+ nfds_t n = 0;
+ if (smtp_out)
+ {
+ p.fd = fileno(smtp_out);
+ p.events = POLLRDHUP;
+ n = 1;
+ }
+ if (poll(&p, n, delay*1000) > 0)
+ HDEBUG(D_acl) debug_printf("delay cancelled by peer close\n");
+ }
+#else
/* It appears to be impossible to detect that a TCP/IP connection has
gone away without reading from it. This means that we cannot shorten
the delay below if the client goes away, because we cannot discover
Exim process is not held up unnecessarily. However, it seems that we
can't. The poll() function does not do the right thing, and in any case
it is not always available.
-
- NOTE 1: If ever this state of affairs changes, remember that we may be
- dealing with stdin/stdout here, in addition to TCP/IP connections.
- Also, delays may be specified for non-SMTP input, where smtp_out and
- smtp_in will be NULL. Whatever is done must work in all cases.
-
- NOTE 2: The added feature of flushing the output before a delay must
- apply only to SMTP input. Hence the test for smtp_out being non-NULL.
*/
- else
- {
- if (smtp_out != NULL && !disable_delay_flush) mac_smtp_fflush();
while (delay > 0) delay = sleep(delay);
+#endif
}
}
}
#endif
case ACLC_DNSLISTS:
- rc = verify_check_dnsbl(&arg);
+ rc = verify_check_dnsbl(where, &arg, log_msgptr);
break;
case ACLC_DOMAINS:
rc = match_isinlist(addr->domain, &arg, 0, &domainlist_anchor,
- addr->domain_cache, MCL_DOMAIN, TRUE, &deliver_domain_data);
+ addr->domain_cache, MCL_DOMAIN, TRUE, CUSS &deliver_domain_data);
break;
/* The value in tls_cipher is the full cipher name, for example,
case ACLC_HOSTS:
rc = verify_check_this_host(&arg, sender_host_cache, NULL,
- (sender_host_address == NULL)? US"" : sender_host_address, &host_data);
- if (host_data != NULL) host_data = string_copy_malloc(host_data);
+ (sender_host_address == NULL)? US"" : sender_host_address,
+ CUSS &host_data);
+ if (rc == DEFER) *log_msgptr = search_error_message;
+ if (host_data) host_data = string_copy_malloc(host_data);
break;
case ACLC_LOCAL_PARTS:
rc = match_isinlist(addr->cc_local_part, &arg, 0,
&localpartlist_anchor, addr->localpart_cache, MCL_LOCALPART, TRUE,
- &deliver_localpart_data);
+ CUSS &deliver_localpart_data);
break;
case ACLC_LOG_REJECT_TARGET:
{
int logbits = 0;
int sep = 0;
- uschar *s = arg;
+ const uschar *s = arg;
uschar *ss;
- while ((ss = string_nextinlist(&s, &sep, big_buffer, big_buffer_size))
- != NULL)
+ while ((ss = string_nextinlist(&s, &sep, big_buffer, big_buffer_size)))
{
if (Ustrcmp(ss, "main") == 0) logbits |= LOG_MAIN;
else if (Ustrcmp(ss, "panic") == 0) logbits |= LOG_PANIC;
case ACLC_LOGWRITE:
{
int logbits = 0;
- uschar *s = arg;
+ const uschar *s = arg;
if (*s == ':')
{
s++;
case ACLC_MALWARE: /* Run the malware backend. */
{
/* Separate the regular expression and any optional parameters. */
- uschar *ss = string_nextinlist(&arg, &sep, big_buffer, big_buffer_size);
+ const uschar * list = arg;
+ uschar *ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size);
uschar *opt;
BOOL defer_ok = FALSE;
int timeout = 0;
- while ((opt = string_nextinlist(&arg, &sep, NULL, 0)))
+ while ((opt = string_nextinlist(&list, &sep, NULL, 0)))
if (strcmpic(opt, US"defer_ok") == 0)
defer_ok = TRUE;
else if ( strncmpic(opt, US"tmo=", 4) == 0
break;
case ACLC_RECIPIENTS:
- rc = match_address_list(addr->address, TRUE, TRUE, &arg, NULL, -1, 0,
- &recipient_data);
+ rc = match_address_list((const uschar *)addr->address, TRUE, TRUE, &arg, NULL, -1, 0,
+ CUSS &recipient_data);
break;
#ifdef WITH_CONTENT_SCAN
break;
case ACLC_SENDERS:
- rc = match_address_list(sender_address, TRUE, TRUE, &arg,
- sender_address_cache, -1, 0, &sender_data);
+ rc = match_address_list((const uschar *)sender_address, TRUE, TRUE, &arg,
+ sender_address_cache, -1, 0, CUSS &sender_data);
break;
/* Connection variables must persist forever */
case ACLC_SET:
{
int old_pool = store_pool;
- if (cb->u.varname[0] == 'c') store_pool = POOL_PERM;
+ if ( cb->u.varname[0] == 'c'
+#ifndef DISABLE_EVENT
+ || event_name /* An event is being delivered */
+#endif
+ )
+ store_pool = POOL_PERM;
acl_var_create(cb->u.varname)->data.ptr = string_copy(arg);
store_pool = old_pool;
}
case ACLC_SPAM:
{
/* Seperate the regular expression and any optional parameters. */
- uschar *ss = string_nextinlist(&arg, &sep, big_buffer, big_buffer_size);
+ const uschar * list = arg;
+ uschar *ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size);
/* Run the spam backend. */
- rc = spam(&ss);
+ rc = spam(CUSS &ss);
/* Modify return code based upon the existance of options. */
- while ((ss = string_nextinlist(&arg, &sep, big_buffer, big_buffer_size))
+ while ((ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size))
!= NULL) {
if (strcmpic(ss, US"defer_ok") == 0 && rc == DEFER)
{
case ACLC_VERIFY:
rc = acl_verify(where, addr, arg, user_msgptr, log_msgptr, basic_errno);
- acl_verify_message = *user_msgptr;
+ if (*user_msgptr)
+ acl_verify_message = *user_msgptr;
if (verb == ACL_WARN) *user_msgptr = NULL;
break;
int cond;
int basic_errno = 0;
BOOL endpass_seen = FALSE;
+ BOOL acl_quit_check = level == 0
+ && (where == ACL_WHERE_QUIT || where == ACL_WHERE_NOTQUIT);
*log_msgptr = *user_msgptr = NULL;
acl_temp_details = FALSE;
- if ((where == ACL_WHERE_QUIT || where == ACL_WHERE_NOTQUIT) &&
- acl->verb != ACL_ACCEPT &&
- acl->verb != ACL_WARN)
- {
- *log_msgptr = string_sprintf("\"%s\" is not allowed in a QUIT or not-QUIT ACL",
- verbs[acl->verb]);
- return ERROR;
- }
-
HDEBUG(D_acl) debug_printf("processing \"%s\"\n", verbs[acl->verb]);
/* Clear out any search error message from a previous check before testing
if (cond == OK)
{
HDEBUG(D_acl) debug_printf("end of %s: DEFER\n", acl_name);
+ if (acl_quit_check) goto badquit;
acl_temp_details = TRUE;
return DEFER;
}
if (cond == OK)
{
HDEBUG(D_acl) debug_printf("end of %s: DENY\n", acl_name);
+ if (acl_quit_check) goto badquit;
return FAIL;
}
break;
if (cond == OK || cond == DISCARD)
{
HDEBUG(D_acl) debug_printf("end of %s: DISCARD\n", acl_name);
+ if (acl_quit_check) goto badquit;
return DISCARD;
}
if (endpass_seen)
if (cond == OK)
{
HDEBUG(D_acl) debug_printf("end of %s: DROP\n", acl_name);
+ if (acl_quit_check) goto badquit;
return FAIL_DROP;
}
break;
if (cond != OK)
{
HDEBUG(D_acl) debug_printf("end of %s: not OK\n", acl_name);
+ if (acl_quit_check) goto badquit;
return cond;
}
break;
case ACL_WARN:
if (cond == OK)
acl_warn(where, *user_msgptr, *log_msgptr);
- else if (cond == DEFER && (log_extra_selector & LX_acl_warn_skipped) != 0)
+ else if (cond == DEFER && LOGGING(acl_warn_skipped))
log_write(0, LOG_MAIN, "%s Warning: ACL \"warn\" statement skipped: "
"condition test deferred%s%s", host_and_ident(TRUE),
(*log_msgptr == NULL)? US"" : US": ",
HDEBUG(D_acl) debug_printf("end of %s: implicit DENY\n", acl_name);
return FAIL;
+
+badquit:
+ *log_msgptr = string_sprintf("QUIT or not-QUIT teplevel ACL may not fail "
+ "('%s' verb used incorrectly)", verbs[acl->verb]);
+ return ERROR;
}
the name of an ACL followed optionally by up to 9 space-separated arguments.
The name and args are separately expanded. Args go into $acl_arg globals. */
static int
-acl_check_wargs(int where, address_item *addr, uschar *s, int level,
+acl_check_wargs(int where, address_item *addr, const uschar *s, int level,
uschar **user_msgptr, uschar **log_msgptr)
{
uschar * tmp;
log_reject_target = LOG_MAIN|LOG_REJECT;
#ifndef DISABLE_PRDR
-if (where == ACL_WHERE_RCPT || where == ACL_WHERE_PRDR )
+if (where == ACL_WHERE_RCPT || where == ACL_WHERE_PRDR)
#else
-if (where == ACL_WHERE_RCPT )
+if (where == ACL_WHERE_RCPT)
#endif
{
adb = address_defaults;
*log_msgptr = US"defer in percent_hack_domains check";
return DEFER;
}
+#ifdef SUPPORT_I18N
+ if ((addr->prop.utf8_msg = message_smtputf8))
+ {
+ addr->prop.utf8_downcvt = message_utf8_downconvert == 1;
+ addr->prop.utf8_downcvt_maybe = message_utf8_downconvert == -1;
+ }
+#endif
deliver_domain = addr->domain;
deliver_localpart = addr->local_part;
}
#ifndef DISABLE_PRDR
case ACL_WHERE_PRDR:
#endif
- if( rcpt_count > 1 )
- cancel_cutthrough_connection("more than one recipient");
- else if (rc == OK && cutthrough_delivery && cutthrough_fd < 0)
+ if (rc == OK && cutthrough.delivery && rcpt_count > cutthrough.nrcpt)
open_cutthrough_connection(addr);
break;
call_radius.o check_serv_cond.o cram_md5.o cyrus_sasl.o dovecot.o \
get_data.o get_no64_data.o gsasl_exim.o heimdal_gssapi.o \
md5.o plaintext.o pwcheck.o sha1.o \
- spa.o xtextdecode.o xtextencode.o
+ spa.o tls.o xtextdecode.o xtextencode.o
auths.a: $(OBJ)
@$(RM_COMMAND) -f auths.a
heimdal_gssapi.o: $(HDRS) heimdal_gssapi.c heimdal_gssapi.h
plaintext.o: $(HDRS) plaintext.c plaintext.h
spa.o: $(HDRS) spa.c spa.h
+tls.o: $(HDRS) tls.c tls.h
# End
static const char base64digits[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-#define BAD -1
+#define BAD (char) -1
static const char base64val[] = {
BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD,
BAD,
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
#include "../exim.h"
this to work on Solaris 2.6, so static variables are used instead. */
static int pam_conv_had_error;
-static uschar *pam_args;
+static const uschar *pam_args;
static BOOL pam_arg_ended;
*/
int
-auth_call_pam(uschar *s, uschar **errptr)
+auth_call_pam(const uschar *s, uschar **errptr)
{
pam_handle_t *pamh = NULL;
struct pam_conv pamc;
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* This module contains interface functions to the two Cyrus authentication
*/
int
-auth_call_saslauthd(uschar *username, uschar *password, uschar *service,
- uschar *realm, uschar **errptr)
+auth_call_saslauthd(const uschar *username, const uschar *password,
+ const uschar *service, const uschar *realm, uschar **errptr)
{
uschar *reply = NULL;
/* This file was originally supplied by Ian Kirk. The libradius support came
from Alex Kiernan. */
+/* ugly hack to work around redefinition of ENV by radiusclient.h and
+ * db.h: define _DB_H_ so the db.h include thinks it's already included,
+ * we can get away with it like this, since this file doesn't use any db
+ * functions. */
+#ifndef _DB_H_
+# define _DB_H_ 1
+# define _DB_EXT_PROT_IN_ 1
+# define DB void
+#endif
+
#include "../exim.h"
/* This module contains functions that call the Radius authentication
#include <radlib.h>
#else
#if !defined(RADIUS_LIB_RADIUSCLIENT) && !defined(RADIUS_LIB_RADIUSCLIENTNEW)
- #define RADIUS_LIB_RADIUSCLIENT
+ # define RADIUS_LIB_RADIUSCLIENT
+ #endif
+
+ #ifdef RADIUS_LIB_RADIUSCLIENTNEW
+ # include <freeradius-client.h>
+ #else
+ # include <radiusclient.h>
#endif
- #include <radiusclient.h>
#endif
*/
int
-auth_call_radius(uschar *s, uschar **errptr)
+auth_call_radius(const uschar *s, uschar **errptr)
{
uschar *user;
-uschar *radius_args = s;
+const uschar *radius_args = s;
int result;
int sep = 0;
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2012 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* This code was originally contributed by Matthew Byng-Maddick */
{
auth_cyrus_sasl_options_block *ob =
(auth_cyrus_sasl_options_block *)(ablock->options_block);
-uschar *list, *listptr, *buffer;
+const uschar *list, *listptr, *buffer;
int rc, i;
unsigned int len;
uschar *rs_point, *expanded_hostname;
log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: "
"couldn't initialise Cyrus SASL server connection.", ablock->name);
-rc=sasl_listmech(conn, NULL, "", ":", "", (const char **)(&list), &len, &i);
+rc=sasl_listmech(conn, NULL, "", ":", "", (const char **)&list, &len, &i);
if( rc != SASL_OK )
log_write(0, LOG_PANIC_DIE|LOG_CONFIG_FOR, "%s authenticator: "
"couldn't get Cyrus SASL mechanism list.", ablock->name);
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
#include "../exim.h"
{
auth_plaintext_options_block *ob =
(auth_plaintext_options_block *)(ablock->options_block);
-uschar *prompts = ob->server_prompts;
+const uschar *prompts = ob->server_prompts;
uschar *clear, *end, *s;
int number = 1;
int len, rc;
if (prompts != NULL)
{
- prompts = expand_string(prompts);
+ prompts = expand_cstring(prompts);
if (prompts == NULL)
{
auth_defer_msg = expand_string_message;
{
auth_plaintext_options_block *ob =
(auth_plaintext_options_block *)(ablock->options_block);
-uschar *text = ob->client_send;
+const uschar *text = ob->client_send;
uschar *s;
BOOL first = TRUE;
int sep = 0;
--- /dev/null
+/*************************************************
+* Exim - an Internet mail transport agent *
+*************************************************/
+
+/* Copyright (c) Jeremy Harris 2015 */
+/* See the file NOTICE for conditions of use and distribution. */
+
+/* This file provides an Exim authenticator driver for
+a server to verify a client SSL certificate
+*/
+
+
+#include "../exim.h"
+#include "tls.h"
+
+/* Options specific to the tls authentication mechanism. */
+
+optionlist auth_tls_options[] = {
+ { "server_param", opt_stringptr,
+ (void *)(offsetof(auth_tls_options_block, server_param1)) },
+ { "server_param1", opt_stringptr,
+ (void *)(offsetof(auth_tls_options_block, server_param1)) },
+ { "server_param2", opt_stringptr,
+ (void *)(offsetof(auth_tls_options_block, server_param2)) },
+ { "server_param3", opt_stringptr,
+ (void *)(offsetof(auth_tls_options_block, server_param3)) },
+};
+
+/* Size of the options list. An extern variable has to be used so that its
+address can appear in the tables drtables.c. */
+
+int auth_tls_options_count = nelem(auth_tls_options);
+
+/* Default private options block for the authentication method. */
+
+auth_tls_options_block auth_tls_option_defaults = {
+ NULL, /* server_param1 */
+ NULL, /* server_param2 */
+ NULL, /* server_param3 */
+};
+
+
+/*************************************************
+* Initialization entry point *
+*************************************************/
+
+/* Called for each instance, after its options have been read, to
+enable consistency checks to be done, or anything else that needs
+to be set up. */
+
+void
+auth_tls_init(auth_instance *ablock)
+{
+ablock->public_name = ablock->name; /* needed for core code */
+}
+
+
+
+/*************************************************
+* Server entry point *
+*************************************************/
+
+/* For interface, see auths/README */
+
+int
+auth_tls_server(auth_instance *ablock, uschar *data)
+{
+auth_tls_options_block * ob = (auth_tls_options_block *)ablock->options_block;
+
+if (ob->server_param1)
+ auth_vars[expand_nmax++] = expand_string(ob->server_param1);
+if (ob->server_param2)
+ auth_vars[expand_nmax++] = expand_string(ob->server_param2);
+if (ob->server_param2)
+ auth_vars[expand_nmax++] = expand_string(ob->server_param3);
+return auth_check_serv_cond(ablock);
+}
+
+
+/* End of tls.c */
--- /dev/null
+/*************************************************
+* Exim - an Internet mail transport agent *
+*************************************************/
+
+/* Copyright (c) Jeremy Harris 2015 */
+/* See the file NOTICE for conditions of use and distribution. */
+
+/* Private structure for the private options. */
+
+typedef struct {
+ uschar * server_param1;
+ uschar * server_param2;
+ uschar * server_param3;
+} auth_tls_options_block;
+
+/* Data for reading the private options. */
+
+extern optionlist auth_tls_options[];
+extern int auth_tls_options_count;
+
+/* Block containing default values. */
+
+extern auth_tls_options_block auth_tls_option_defaults;
+
+/* The entry points for the mechanism */
+
+extern void auth_tls_init(auth_instance *);
+extern int auth_tls_server(auth_instance *, uschar *);
+
+/* End of sa.h */
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
failure. We know that there will always be at least one extra option in the
call when exec() is done here, so it can be used to add to the panic data. */
-DEBUG(D_exec) debug_print_argv(argv);
+DEBUG(D_exec) debug_print_argv(CUSS argv);
exim_nullstd(); /* Make sure std{in,out,err} exist */
execv(CS argv[0], (char *const *)argv);
*/
pid_t
-child_open_uid(uschar **argv, uschar **envp, int newumask, uid_t *newuid,
- gid_t *newgid, int *infdptr, int *outfdptr, uschar *wd, BOOL make_leader)
+child_open_uid(const uschar **argv, const uschar **envp, int newumask,
+ uid_t *newuid, gid_t *newgid, int *infdptr, int *outfdptr, uschar *wd,
+ BOOL make_leader)
{
int save_errno;
int inpfd[2], outpfd[2];
/* Now do the exec */
if (envp == NULL) execv(CS argv[0], (char *const *)argv);
- else execve(CS argv[0], (char *const *)argv, (char *const *)envp);
+ else execve(CS argv[0], (char *const *)argv, (char *const *)envp);
/* Failed to execv. Signal this failure using EX_EXECFAILED. We are
losing the actual errno we got back, because there is no way to return
child_open(uschar **argv, uschar **envp, int newumask, int *infdptr,
int *outfdptr, BOOL make_leader)
{
-return child_open_uid(argv, envp, newumask, NULL, NULL, infdptr, outfdptr,
- NULL, make_leader);
+return child_open_uid(CUSS argv, CUSS envp, newumask, NULL, NULL,
+ infdptr, outfdptr, NULL, make_leader);
}
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* The default settings for Exim configuration variables. A #define without
#define AUTH_HEIMDAL_GSSAPI
#define AUTH_PLAINTEXT
#define AUTH_SPA
+#define AUTH_TLS
#define AUTH_VARS 3
#define DEFAULT_CRYPT crypt
#define DELIVER_IN_BUFFER_SIZE 8192
#define DELIVER_OUT_BUFFER_SIZE 8192
+#define DISABLE_DNSSEC
#define DISABLE_DKIM
+#define DISABLE_EVENT
#define DISABLE_PRDR
#define DISABLE_OCSP
-#define DISABLE_DNSSEC
#define DISABLE_D_OPTION
#define ENABLE_DISABLE_FSYNC
#define LOOKUP_ORACLE
#define LOOKUP_PASSWD
#define LOOKUP_PGSQL
+#define LOOKUP_REDIS
#define LOOKUP_SQLITE
#define LOOKUP_TESTDB
#define LOOKUP_WHOSON
#define RADIUS_CONFIG_FILE
#define RADIUS_LIB_TYPE
+#define REGEX_VARS 9
+
#define ROUTER_ACCEPT
#define ROUTER_DNSLOOKUP
#define ROUTER_IPLITERAL
#define SPOOL_MODE 0640
#define STRING_SPRINTF_BUFFER_SIZE (8192 * 4)
-#define SUPPORT_A6
#define SUPPORT_CRYPTEQ
+#define SUPPORT_I18N
#define SUPPORT_MAILDIR
#define SUPPORT_MAILSTORE
#define SUPPORT_MBX
#define SUPPORT_MOVE_FROZEN_MESSAGES
#define SUPPORT_PAM
+#define SUPPORT_PROXY
+#define SUPPORT_SOCKS
#define SUPPORT_TLS
#define SUPPORT_TRANSLATE_IP_ADDRESS
#define EXPERIMENTAL_BRIGHTMAIL
#define EXPERIMENTAL_DANE
#define EXPERIMENTAL_DCC
+#define EXPERIMENTAL_DSN_INFO
#define EXPERIMENTAL_DMARC
-#define EXPERIMENTAL_PROXY
-#define EXPERIMENTAL_REDIS
#define EXPERIMENTAL_SPF
#define EXPERIMENTAL_SRS
-#define EXPERIMENTAL_EVENT
/* For developers */
#define WANT_DEEPER_PRINTF_CHECKS
#rfc1413_query_timeout = 5s
+# Enable an efficiency feature. We advertise the feature; clients
+# may request to use it. For multi-recipient mails we then can
+# reject or accept per-user after the message is received.
+#
+prdr_enable = true
+
+
# By default, Exim expects all envelope addresses to be fully qualified, that
# is, they must contain both a local part and a domain. If you want to accept
# unqualified addresses (just a local part) from certain hosts, you can specify
# and/or qualify_recipient (see above).
+# Unless you run a high-volume site you probably want more logging
+# detail than the default. Adjust to suit.
+
+log_selector = +smtp_protocol_error +smtp_syntax_error \
+ +tls_certificate_verified
+
+
# If you want Exim to support the "percent hack" for certain domains,
# uncomment the following line and provide a list of domains. The "percent
# hack" is the feature by which mail addressed to x%y@z (where z is one of
acl_check_data:
+ # Deny if the message contains an overlong line. Per the standards
+ # we should never receive one such via SMTP.
+ #
+ deny condition = ${if > {$max_received_linelength}{998}}
+
# Deny if the message contains a virus. Before enabling this check, you
# must install a virus scanner and set the av_scanner option above.
#
# This transport is used for delivering messages over SMTP connections.
+# Refuse to send any messsage with over-long lines, which could have
+# been receved other than via SMTP. The use of message_size_limit to
+# enforce this is a red herring.
remote_smtp:
driver = smtp
+ message_size_limit = ${if > {$max_received_linelength}{998} {1}{0}}
# This transport is used for local delivery to user mailboxes in traditional
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Functions concerned with running Exim as a daemon */
int max_for_this_host = 0;
int wfsize = 0;
int wfptr = 0;
-int use_log_write_selector = log_write_selector;
+int save_log_selector = *log_selector;
uschar *whofrom = NULL;
void *reset_point = store_get(0);
whofrom = string_append(whofrom, &wfsize, &wfptr, 3, "[", sender_host_address, "]");
-if ((log_extra_selector & LX_incoming_port) != 0)
+if (LOGGING(incoming_port))
whofrom = string_append(whofrom, &wfsize, &wfptr, 2, ":", string_sprintf("%d",
sender_host_port));
-if ((log_extra_selector & LX_incoming_interface) != 0)
+if (LOGGING(incoming_interface))
whofrom = string_append(whofrom, &wfsize, &wfptr, 4, " I=[",
interface_address, "]:", string_sprintf("%d", interface_port));
selector is set, check whether the host is on the list for logging. If not,
arrange to unset the selector in the subprocess. */
-if ((log_write_selector & L_smtp_connection) != 0)
+if (LOGGING(smtp_connection))
{
uschar *list = hosts_connection_nolog;
+ memset(sender_host_cache, 0, sizeof(sender_host_cache));
if (list != NULL && verify_check_host(&list) == OK)
- use_log_write_selector &= ~L_smtp_connection;
+ save_log_selector &= ~L_smtp_connection;
else
log_write(L_smtp_connection, LOG_MAIN, "SMTP connection from %s "
"(TCP/IP connection count = %d)", whofrom, smtp_accept_count + 1);
/* May have been modified for the subprocess */
- log_write_selector = use_log_write_selector;
+ *log_selector = save_log_selector;
/* Get the local interface address into permanent store */
/* Release any store used in this process, including the store used for holding
the incoming host address and an expanded active_hostname. */
+log_close_all();
store_reset(reset_point);
sender_host_address = NULL;
}
int sep;
int pct = 0;
uschar *s;
- uschar *list;
+ const uschar * list;
uschar *local_iface_source = US"local_interfaces";
ip_address_item *ipa;
ip_address_item **pipa;
list = override_local_interfaces;
sep = 0;
- while ((s = string_nextinlist(&list,&sep,big_buffer,big_buffer_size))
- != NULL)
+ while ((s = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)))
{
uschar joinstr[4];
uschar **ptr;
list = daemon_smtp_port;
sep = 0;
- while ((s = string_nextinlist(&list,&sep,big_buffer,big_buffer_size)))
+ while ((s = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)))
pct++;
default_smtp_port = store_get((pct+1) * sizeof(int));
list = daemon_smtp_port;
sep = 0;
for (pct = 0;
- (s = string_nextinlist(&list,&sep,big_buffer,big_buffer_size));
+ (s = string_nextinlist(&list, &sep, big_buffer, big_buffer_size));
pct++)
{
if (isdigit(*s))
log_write(0, LOG_MAIN,
"exim %s daemon started: pid=%d, launched with listening socket, %s",
version_string, getpid(), big_buffer);
- set_process_info("daemon: pre-listening socket");
+ set_process_info("daemon(%s): pre-listening socket", version_string);
/* set up the timeout logic */
sigalrm_seen = 1;
log_write(0, LOG_MAIN,
"exim %s daemon started: pid=%d, %s, listening for %s",
version_string, getpid(), qinfo, big_buffer);
- set_process_info("daemon: %s, listening for %s", qinfo, big_buffer);
+ set_process_info("daemon(%s): %s, listening for %s", version_string, qinfo, big_buffer);
}
else
log_write(0, LOG_MAIN,
"exim %s daemon started: pid=%d, -q%s, not listening for SMTP",
version_string, getpid(), readconf_printtime(queue_interval));
- set_process_info("daemon: -q%s, not listening",
+ set_process_info("daemon(%s): -q%s, not listening",
+ version_string,
readconf_printtime(queue_interval));
}
+/*
+ * Author: Viktor Dukhovni
+ * License: THIS CODE IS IN THE PUBLIC DOMAIN.
+ */
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/evp.h>
+#include <openssl/bn.h>
#if OPENSSL_VERSION_NUMBER < 0x1000000fL
# error "OpenSSL 1.0.0 or higher required"
#else /* remainder of file */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#define X509_up_ref(x) CRYPTO_add(&((x)->references), 1, CRYPTO_LOCK_X509)
+#endif
+
#include "danessl.h"
-#define DANE_F_ADD_SKID 100
-#define DANE_F_CHECK_END_ENTITY 101
-#define DANE_F_GROW_CHAIN 102
-#define DANE_F_LIST_ALLOC 103
-#define DANE_F_MATCH 104
-#define DANE_F_PUSH_EXT 105
-#define DANE_F_SET_TRUST_ANCHOR 106
-#define DANE_F_SSL_CTX_DANE_INIT 107
-#define DANE_F_SSL_DANE_ADD_TLSA 108
-#define DANE_F_SSL_DANE_INIT 109
-#define DANE_F_SSL_DANE_LIBRARY_INIT 110
-#define DANE_F_VERIFY_CERT 111
-#define DANE_F_WRAP_CERT 112
-
-#define DANE_R_BAD_CERT 100
-#define DANE_R_BAD_CERT_PKEY 101
-#define DANE_R_BAD_DATA_LENGTH 102
-#define DANE_R_BAD_DIGEST 103
-#define DANE_R_BAD_NULL_DATA 104
-#define DANE_R_BAD_PKEY 105
-#define DANE_R_BAD_SELECTOR 106
-#define DANE_R_BAD_USAGE 107
-#define DANE_R_DANE_INIT 108
-#define DANE_R_DANE_SUPPORT 109
-#define DANE_R_LIBRARY_INIT 110
-#define DANE_R_NOSIGN_KEY 111
-#define DANE_R_SCTX_INIT 112
+#define DANESSL_F_ADD_SKID 100
+#define DANESSL_F_ADD_TLSA 101
+#define DANESSL_F_CHECK_END_ENTITY 102
+#define DANESSL_F_CTX_INIT 103
+#define DANESSL_F_GROW_CHAIN 104
+#define DANESSL_F_INIT 105
+#define DANESSL_F_LIBRARY_INIT 106
+#define DANESSL_F_LIST_ALLOC 107
+#define DANESSL_F_MATCH 108
+#define DANESSL_F_PUSH_EXT 109
+#define DANESSL_F_SET_TRUST_ANCHOR 110
+#define DANESSL_F_VERIFY_CERT 111
+#define DANESSL_F_WRAP_CERT 112
+
+#define DANESSL_R_BAD_CERT 100
+#define DANESSL_R_BAD_CERT_PKEY 101
+#define DANESSL_R_BAD_DATA_LENGTH 102
+#define DANESSL_R_BAD_DIGEST 103
+#define DANESSL_R_BAD_NULL_DATA 104
+#define DANESSL_R_BAD_PKEY 105
+#define DANESSL_R_BAD_SELECTOR 106
+#define DANESSL_R_BAD_USAGE 107
+#define DANESSL_R_INIT 108
+#define DANESSL_R_LIBRARY_INIT 109
+#define DANESSL_R_NOSIGN_KEY 110
+#define DANESSL_R_SCTX_INIT 111
+#define DANESSL_R_SUPPORT 112
#ifndef OPENSSL_NO_ERR
-# define DANE_F_PLACEHOLDER 0 /* FIRST! Value TBD */
-static ERR_STRING_DATA dane_str_functs[] =
-{
- {DANE_F_PLACEHOLDER, "DANE library"}, /* FIRST!!! */
- {DANE_F_ADD_SKID, "add_skid"},
- {DANE_F_CHECK_END_ENTITY, "check_end_entity"},
- {DANE_F_GROW_CHAIN, "grow_chain"},
- {DANE_F_LIST_ALLOC, "list_alloc"},
- {DANE_F_MATCH, "match"},
- {DANE_F_PUSH_EXT, "push_ext"},
- {DANE_F_SET_TRUST_ANCHOR, "set_trust_anchor"},
- {DANE_F_SSL_CTX_DANE_INIT, "SSL_CTX_dane_init"},
- {DANE_F_SSL_DANE_ADD_TLSA, "SSL_dane_add_tlsa"},
- {DANE_F_SSL_DANE_INIT, "SSL_dane_init"},
- {DANE_F_SSL_DANE_LIBRARY_INIT, "SSL_dane_library_init"},
- {DANE_F_VERIFY_CERT, "verify_cert"},
- {DANE_F_WRAP_CERT, "wrap_cert"},
- {0, NULL}
+#define DANESSL_F_PLACEHOLDER 0 /* FIRST! Value TBD */
+static ERR_STRING_DATA dane_str_functs[] = {
+ {DANESSL_F_PLACEHOLDER, "DANE library"}, /* FIRST!!! */
+ {DANESSL_F_ADD_SKID, "add_skid"},
+ {DANESSL_F_ADD_TLSA, "DANESSL_add_tlsa"},
+ {DANESSL_F_CHECK_END_ENTITY, "check_end_entity"},
+ {DANESSL_F_CTX_INIT, "DANESSL_CTX_init"},
+ {DANESSL_F_GROW_CHAIN, "grow_chain"},
+ {DANESSL_F_INIT, "DANESSL_init"},
+ {DANESSL_F_LIBRARY_INIT, "DANESSL_library_init"},
+ {DANESSL_F_LIST_ALLOC, "list_alloc"},
+ {DANESSL_F_MATCH, "match"},
+ {DANESSL_F_PUSH_EXT, "push_ext"},
+ {DANESSL_F_SET_TRUST_ANCHOR, "set_trust_anchor"},
+ {DANESSL_F_VERIFY_CERT, "verify_cert"},
+ {DANESSL_F_WRAP_CERT, "wrap_cert"},
+ {0, NULL}
};
-static ERR_STRING_DATA dane_str_reasons[] =
-{
- {DANE_R_BAD_CERT, "Bad TLSA record certificate"},
- {DANE_R_BAD_CERT_PKEY, "Bad TLSA record certificate public key"},
- {DANE_R_BAD_DATA_LENGTH, "Bad TLSA record digest length"},
- {DANE_R_BAD_DIGEST, "Bad TLSA record digest"},
- {DANE_R_BAD_NULL_DATA, "Bad TLSA record null data"},
- {DANE_R_BAD_PKEY, "Bad TLSA record public key"},
- {DANE_R_BAD_SELECTOR, "Bad TLSA record selector"},
- {DANE_R_BAD_USAGE, "Bad TLSA record usage"},
- {DANE_R_DANE_INIT, "SSL_dane_init() required"},
- {DANE_R_DANE_SUPPORT, "DANE library features not supported"},
- {DANE_R_LIBRARY_INIT, "SSL_dane_library_init() required"},
- {DANE_R_SCTX_INIT, "SSL_CTX_dane_init() required"},
- {DANE_R_NOSIGN_KEY, "Certificate usage 2 requires EC support"},
- {0, NULL}
+static ERR_STRING_DATA dane_str_reasons[] = {
+ {DANESSL_R_BAD_CERT, "Bad TLSA record certificate"},
+ {DANESSL_R_BAD_CERT_PKEY, "Bad TLSA record certificate public key"},
+ {DANESSL_R_BAD_DATA_LENGTH, "Bad TLSA record digest length"},
+ {DANESSL_R_BAD_DIGEST, "Bad TLSA record digest"},
+ {DANESSL_R_BAD_NULL_DATA, "Bad TLSA record null data"},
+ {DANESSL_R_BAD_PKEY, "Bad TLSA record public key"},
+ {DANESSL_R_BAD_SELECTOR, "Bad TLSA record selector"},
+ {DANESSL_R_BAD_USAGE, "Bad TLSA record usage"},
+ {DANESSL_R_INIT, "DANESSL_init() required"},
+ {DANESSL_R_LIBRARY_INIT, "DANESSL_library_init() required"},
+ {DANESSL_R_NOSIGN_KEY, "Certificate usage 2 requires EC support"},
+ {DANESSL_R_SCTX_INIT, "DANESSL_CTX_init() required"},
+ {DANESSL_R_SUPPORT, "DANE library features not supported"},
+ {0, NULL}
};
-#endif /*OPENSSL_NO_ERR*/
+#endif
#define DANEerr(f, r) ERR_PUT_error(err_lib_dane, (f), (r), __FILE__, __LINE__)
int (*verify)(X509_STORE_CTX *);
STACK_OF(X509) *roots;
STACK_OF(X509) *chain;
- const char *thost; /* TLSA base domain */
- char *mhost; /* Matched, peer name */
+ X509 *match; /* Matched cert */
+ const char *thost; /* TLSA base domain */
+ char *mhost; /* Matched peer name */
dane_pkey_list pkeys;
dane_cert_list certs;
dane_host_list hosts;
- dane_selector_list selectors[SSL_DANE_USAGE_LAST + 1];
+ dane_selector_list selectors[DANESSL_USAGE_LAST + 1];
int depth;
- int multi; /* Multi-label wildcards? */
- int count; /* Number of TLSA records */
+ int mdpth; /* Depth of matched cert */
+ int multi; /* Multi-label wildcards? */
+ int count; /* Number of TLSA records */
} ssl_dane;
#ifndef X509_V_ERR_HOSTNAME_MISMATCH
# define X509_V_ERR_HOSTNAME_MISMATCH X509_V_ERR_APPLICATION_VERIFICATION
#endif
+
+
static int
match(dane_selector_list slist, X509 *cert, int depth)
{
* pkey digest or a certificate digest. We return MATCHED_PKEY or
* MATCHED_CERT accordingly.
*/
-#define MATCHED_CERT (SSL_DANE_SELECTOR_CERT + 1)
-#define MATCHED_PKEY (SSL_DANE_SELECTOR_SPKI + 1)
+#define MATCHED_CERT (DANESSL_SELECTOR_CERT + 1)
+#define MATCHED_PKEY (DANESSL_SELECTOR_SPKI + 1)
/*
* Loop over each selector, mtype, and associated data element looking
* for a match.
*/
-for(matched = 0; !matched && slist; slist = slist->next)
+for (matched = 0; !matched && slist; slist = slist->next)
{
dane_mtype_list m;
unsigned char mdbuf[EVP_MAX_MD_SIZE];
*/
switch(slist->value->selector)
{
- case SSL_DANE_SELECTOR_CERT:
+ case DANESSL_SELECTOR_CERT:
len = i2d_X509(cert, NULL);
buf2 = buf = (unsigned char *) OPENSSL_malloc(len);
if(buf) i2d_X509(cert, &buf2);
break;
- case SSL_DANE_SELECTOR_SPKI:
+ case DANESSL_SELECTOR_SPKI:
len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), NULL);
buf2 = buf = (unsigned char *) OPENSSL_malloc(len);
if(buf) i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &buf2);
break;
}
- if(!buf)
+ if (!buf)
{
- DANEerr(DANE_F_MATCH, ERR_R_MALLOC_FAILURE);
+ DANEerr(DANESSL_F_MATCH, ERR_R_MALLOC_FAILURE);
return 0;
}
OPENSSL_assert(buf2 - buf == len);
/*
* Loop over each mtype and data element
*/
- for(m = slist->value->mtype; !matched && m; m = m->next)
+ for (m = slist->value->mtype; !matched && m; m = m->next)
{
dane_data_list d;
unsigned char *cmpbuf = buf;
* If it is a digest, compute the corresponding digest of the
* DER data for comparison, otherwise, use the full object.
*/
- if(m->value->md)
+ if (m->value->md)
{
cmpbuf = mdbuf;
- if(!EVP_Digest(buf, len, cmpbuf, &cmplen, m->value->md, 0))
+ if (!EVP_Digest(buf, len, cmpbuf, &cmplen, m->value->md, 0))
matched = -1;
}
- for(d = m->value->data; !matched && d; d = d->next)
- if( cmplen == d->value->datalen
- && memcmp(cmpbuf, d->value->data, cmplen) == 0)
+ for (d = m->value->data; !matched && d; d = d->next)
+ if ( cmplen == d->value->datalen
+ && memcmp(cmpbuf, d->value->data, cmplen) == 0)
matched = slist->value->selector + 1;
}
static int
push_ext(X509 *cert, X509_EXTENSION *ext)
{
-X509_EXTENSIONS *exts;
-
-if(ext)
- {
- if(!(exts = cert->cert_info->extensions))
- exts = cert->cert_info->extensions = sk_X509_EXTENSION_new_null();
- if (exts && sk_X509_EXTENSION_push(exts, ext))
- return 1;
- X509_EXTENSION_free(ext);
- }
-DANEerr(DANE_F_PUSH_EXT, ERR_R_MALLOC_FAILURE);
-return 0;
+ if (ext) {
+ if (X509_add_ext(cert, ext, -1))
+ return 1;
+ X509_EXTENSION_free(ext);
+ }
+ DANEerr(DANESSL_F_PUSH_EXT, ERR_R_MALLOC_FAILURE);
+ return 0;
}
static int
int ret = 0;
BIGNUM *bn;
-if(akid && akid->serial)
+if (akid && akid->serial)
return (X509_set_serialNumber(cert, akid->serial));
/*
* Add one to subject's serial to avoid collisions between TA serial and
* serial of signing root.
*/
-if( (bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(subject), 0)) != 0
- && BN_add_word(bn, 1)
- && BN_to_ASN1_INTEGER(bn, X509_get_serialNumber(cert)))
+if ( (bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(subject), 0)) != 0
+ && BN_add_word(bn, 1)
+ && BN_to_ASN1_INTEGER(bn, X509_get_serialNumber(cert)))
ret = 1;
-if(bn)
+if (bn)
BN_free(bn);
return ret;
}
* exempt from any potential (off by default for now in OpenSSL)
* self-signature checks!
*/
-id = (ASN1_STRING *) ((akid && akid->keyid) ? akid->keyid : 0);
-if(id && M_ASN1_STRING_length(id) == 1 && *M_ASN1_STRING_data(id) == c)
+id = (akid && akid->keyid) ? akid->keyid : 0;
+if (id && ASN1_STRING_length(id) == 1 && *ASN1_STRING_data(id) == c)
c = 1;
-if( (akid = AUTHORITY_KEYID_new()) != 0
- && (akid->keyid = ASN1_OCTET_STRING_new()) != 0
- && M_ASN1_OCTET_STRING_set(akid->keyid, (void *) &c, 1)
- && X509_add1_ext_i2d(cert, nid, akid, 0, X509V3_ADD_APPEND))
+if ( (akid = AUTHORITY_KEYID_new()) != 0
+ && (akid->keyid = ASN1_OCTET_STRING_new()) != 0
+ && M_ASN1_OCTET_STRING_set(akid->keyid, (void *) &c, 1)
+ && X509_add1_ext_i2d(cert, nid, akid, 0, X509V3_ADD_APPEND))
ret = 1;
-if(akid)
+if (akid)
AUTHORITY_KEYID_free(akid);
return ret;
}
{
int nid = NID_subject_key_identifier;
-if(!akid || !akid->keyid)
+if (!akid || !akid->keyid)
return add_ext(0, cert, nid, "hash");
return X509_add1_ext_i2d(cert, nid, akid->keyid, 0, X509V3_ADD_APPEND) > 0;
}
static X509_NAME *
akid_issuer_name(AUTHORITY_KEYID *akid)
{
-if(akid && akid->issuer)
+if (akid && akid->issuer)
{
int i;
GENERAL_NAMES *gens = akid->issuer;
- for(i = 0; i < sk_GENERAL_NAME_num(gens); ++i)
+ for (i = 0; i < sk_GENERAL_NAME_num(gens); ++i)
{
GENERAL_NAME *gn = sk_GENERAL_NAME_value(gens, i);
- if(gn->type == GEN_DIRNAME)
+ if (gn->type == GEN_DIRNAME)
return (gn->d.dirn);
}
}
#define UNTRUSTED 0
#define TRUSTED 1
-if( trusted && !serverAuth
- && !(serverAuth = OBJ_nid2obj(NID_server_auth)))
+if ( trusted && !serverAuth
+ && !(serverAuth = OBJ_nid2obj(NID_server_auth)))
{
- DANEerr(DANE_F_GROW_CHAIN, ERR_R_MALLOC_FAILURE);
+ DANEerr(DANESSL_F_GROW_CHAIN, ERR_R_MALLOC_FAILURE);
return 0;
}
-if(!*xs && !(*xs = sk_X509_new_null()))
+if (!*xs && !(*xs = sk_X509_new_null()))
{
- DANEerr(DANE_F_GROW_CHAIN, ERR_R_MALLOC_FAILURE);
+ DANEerr(DANESSL_F_GROW_CHAIN, ERR_R_MALLOC_FAILURE);
return 0;
}
-if(cert)
+if (cert)
{
- if(trusted && !X509_add1_trust_object(cert, serverAuth))
+ if (trusted && !X509_add1_trust_object(cert, serverAuth))
return 0;
CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
if (!sk_X509_push(*xs, cert))
{
X509_free(cert);
- DANEerr(DANE_F_GROW_CHAIN, ERR_R_MALLOC_FAILURE);
+ DANEerr(DANESSL_F_GROW_CHAIN, ERR_R_MALLOC_FAILURE);
return 0;
}
}
#define WRAP_MID 0 /* Ensure intermediate. */
#define WRAP_TOP 1 /* Ensure self-signed. */
-if(!name || !newkey || !(cert = X509_new()))
+if (!name || !newkey || !(cert = X509_new()))
return 0;
/*
* Record the depth of the trust-anchor certificate.
*/
-if(dane->depth < 0)
+if (dane->depth < 0)
dane->depth = depth + 1;
/*
*
* CA cert valid for +/- 30 days
*/
-if( !X509_set_version(cert, 2)
- || !set_serial(cert, akid, subject)
- || !X509_set_subject_name(cert, name)
- || !set_issuer_name(cert, akid)
- || !X509_gmtime_adj(X509_get_notBefore(cert), -30 * 86400L)
- || !X509_gmtime_adj(X509_get_notAfter(cert), 30 * 86400L)
- || !X509_set_pubkey(cert, newkey)
- || !add_ext(0, cert, NID_basic_constraints, "CA:TRUE")
- || (!top && !add_akid(cert, akid))
- || !add_skid(cert, akid)
- || ( !top && wrap_to_root
- && !wrap_issuer(dane, newkey, cert, depth, WRAP_TOP)))
+if ( !X509_set_version(cert, 2)
+ || !set_serial(cert, akid, subject)
+ || !X509_set_subject_name(cert, name)
+ || !set_issuer_name(cert, akid)
+ || !X509_gmtime_adj(X509_get_notBefore(cert), -30 * 86400L)
+ || !X509_gmtime_adj(X509_get_notAfter(cert), 30 * 86400L)
+ || !X509_set_pubkey(cert, newkey)
+ || !add_ext(0, cert, NID_basic_constraints, "CA:TRUE")
+ || (!top && !add_akid(cert, akid))
+ || !add_skid(cert, akid)
+ || ( !top && wrap_to_root
+ && !wrap_issuer(dane, newkey, cert, depth, WRAP_TOP)))
ret = 0;
-if(akid)
+if (akid)
AUTHORITY_KEYID_free(akid);
-if(!key)
+if (!key)
EVP_PKEY_free(newkey);
-if(ret)
+if (ret)
ret = grow_chain(dane, !top && wrap_to_root ? UNTRUSTED : TRUSTED, cert);
-if(cert)
+if (cert)
X509_free(cert);
return ret;
}
static int
wrap_cert(ssl_dane *dane, X509 *tacert, int depth)
{
-if(dane->depth < 0)
+if (dane->depth < 0)
dane->depth = depth + 1;
/*
* If the TA certificate is self-issued, or need not be, use it directly.
* Otherwise, synthesize requisuite ancestors.
*/
-if( !wrap_to_root
- || X509_check_issued(tacert, tacert) == X509_V_OK)
+if ( !wrap_to_root
+ || X509_check_issued(tacert, tacert) == X509_V_OK)
return grow_chain(dane, TRUSTED, tacert);
-if(wrap_issuer(dane, 0, tacert, depth, WRAP_MID))
+if (wrap_issuer(dane, 0, tacert, depth, WRAP_MID))
return grow_chain(dane, UNTRUSTED, tacert);
return 0;
}
*/
for (x = dane->certs; !done && x; x = x->next)
{
- if(X509_check_issued(x->value, cert) == X509_V_OK)
+ if (X509_check_issued(x->value, cert) == X509_V_OK)
{
- if(!(pk = X509_get_pubkey(x->value)))
+ if (!(pk = X509_get_pubkey(x->value)))
{
/*
* The cert originally contained a valid pkey, which does
break;
}
/* Check signature, since some other TA may work if not this. */
- if(X509_verify(cert, pk) > 0)
+ if (X509_verify(cert, pk) > 0)
done = wrap_cert(dane, x->value, depth) ? 1 : -1;
EVP_PKEY_free(pk);
}
* This may push errors onto the stack when the certificate signature is
* not of the right type or length, throw these away,
*/
-for(k = dane->pkeys; !done && k; k = k->next)
- if(X509_verify(cert, k->value) > 0)
+for (k = dane->pkeys; !done && k; k = k->next)
+ if (X509_verify(cert, k->value) > 0)
done = wrap_issuer(dane, k->value, cert, depth, WRAP_MID) ? 1 : -1;
else
ERR_clear_error();
X509 *ca;
STACK_OF(X509) *in = ctx->untrusted; /* XXX: Accessor? */
-if(!grow_chain(dane, UNTRUSTED, 0))
+if (!grow_chain(dane, UNTRUSTED, 0))
return -1;
/*
* Accept a degenerate case: depth 0 self-signed trust-anchor.
*/
-if(X509_check_issued(cert, cert) == X509_V_OK)
+if (X509_check_issued(cert, cert) == X509_V_OK)
{
dane->depth = 0;
- matched = match(dane->selectors[SSL_DANE_USAGE_TRUSTED_CA], cert, 0);
- if(matched > 0 && !grow_chain(dane, TRUSTED, cert))
+ matched = match(dane->selectors[DANESSL_USAGE_DANE_TA], cert, 0);
+ if (matched > 0 && !grow_chain(dane, TRUSTED, cert))
matched = -1;
return matched;
}
/* Make a shallow copy of the input untrusted chain. */
-if(!(in = sk_X509_dup(in)))
+if (!(in = sk_X509_dup(in)))
{
- DANEerr(DANE_F_SET_TRUST_ANCHOR, ERR_R_MALLOC_FAILURE);
+ DANEerr(DANESSL_F_SET_TRUST_ANCHOR, ERR_R_MALLOC_FAILURE);
return -1;
}
*
* Caller ensures that the initial certificate is not self-signed.
*/
-for(n = sk_X509_num(in); n > 0; --n, ++depth)
+for (n = sk_X509_num(in); n > 0; --n, ++depth)
{
- for(i = 0; i < n; ++i)
- if(X509_check_issued(sk_X509_value(in, i), cert) == X509_V_OK)
+ for (i = 0; i < n; ++i)
+ if (X509_check_issued(sk_X509_value(in, i), cert) == X509_V_OK)
break;
/*
* Final untrusted element with no issuer in the peer's chain, it may
* however be signed by a pkey or cert obtained via a TLSA RR.
*/
- if(i == n)
+ if (i == n)
break;
/* Peer's chain contains an issuer ca. */
ca = sk_X509_delete(in, i);
/* If not a trust anchor, record untrusted ca and continue. */
- if((matched = match(dane->selectors[SSL_DANE_USAGE_TRUSTED_CA], ca, depth+1))
- == 0)
+ if ((matched = match(dane->selectors[DANESSL_USAGE_DANE_TA], ca,
+ depth + 1)) == 0)
{
- if(grow_chain(dane, UNTRUSTED, ca))
+ if (grow_chain(dane, UNTRUSTED, ca))
{
- if(!X509_check_issued(ca, ca) == X509_V_OK)
+ if (!X509_check_issued(ca, ca) == X509_V_OK)
{
/* Restart with issuer as subject */
cert = ca;
}
else if(matched == MATCHED_PKEY)
{
- if( !(takey = X509_get_pubkey(ca))
- || !wrap_issuer(dane, takey, cert, depth, WRAP_MID))
+ if ( !(takey = X509_get_pubkey(ca))
+ || !wrap_issuer(dane, takey, cert, depth, WRAP_MID))
{
- if(takey)
+ if (takey)
EVP_PKEY_free(takey);
else
- DANEerr(DANE_F_SET_TRUST_ANCHOR, ERR_R_MALLOC_FAILURE);
+ DANEerr(DANESSL_F_SET_TRUST_ANCHOR, ERR_R_MALLOC_FAILURE);
matched = -1;
}
}
* no issuer in the chain, we check for a possible signature via a DNS
* obtained TA cert or public key.
*/
-if(matched == 0 && cert)
+if (matched == 0 && cert)
matched = ta_signed(dane, cert, depth);
return matched;
{
int matched;
-matched = match(dane->selectors[SSL_DANE_USAGE_FIXED_LEAF], cert, 0);
-if(matched > 0)
+matched = match(dane->selectors[DANESSL_USAGE_DANE_EE], cert, 0);
+if (matched > 0)
+ {
+ dane->mdpth = 0;
+ dane->match = cert;
+ X509_up_ref(cert);
if(!ctx->chain)
{
- if( (ctx->chain = sk_X509_new_null())
- && sk_X509_push(ctx->chain, cert))
- CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
+ if ( (ctx->chain = sk_X509_new_null()) != 0
+ && sk_X509_push(ctx->chain, cert))
+ X509_up_ref(cert);
else
{
- DANEerr(DANE_F_CHECK_END_ENTITY, ERR_R_MALLOC_FAILURE);
+ DANEerr(DANESSL_F_CHECK_END_ENTITY, ERR_R_MALLOC_FAILURE);
return -1;
}
}
+ }
return matched;
}
int multi = dane->multi;
dane_host_list hosts;
-for(hosts = dane->hosts; hosts; hosts = hosts->next)
+for (hosts = dane->hosts; hosts; hosts = hosts->next)
{
int match_subdomain = 0;
const char *domain = hosts->value;
int idlen;
int domlen;
- if(*domain == '.' && domain[1] != '\0')
+ if (*domain == '.' && domain[1] != '\0')
{
++domain;
match_subdomain = 1;
*/
if(match_subdomain)
{
- if( (idlen = strlen(certid)) > (domlen = strlen(domain)) + 1
- && certid[idlen - domlen - 1] == '.'
- && !strcasecmp(certid + (idlen - domlen), domain))
+ if ( (idlen = strlen(certid)) > (domlen = strlen(domain)) + 1
+ && certid[idlen - domlen - 1] == '.'
+ && !strcasecmp(certid + (idlen - domlen), domain))
return 1;
else
continue;
* matches one (if multi is false) or more hostname components under
* the condition that the certid contains multiple hostname components.
*/
- if( !strcasecmp(certid, domain)
- || ( certid[0] == '*' && certid[1] == '.' && certid[2] != 0
- && (parent = strchr(domain, '.')) != 0
- && (idlen = strlen(certid + 1)) <= (domlen = strlen(parent))
- && strcasecmp(multi ? parent + domlen - idlen : parent, certid+1) == 0))
+ if ( !strcasecmp(certid, domain)
+ || ( certid[0] == '*' && certid[1] == '.' && certid[2] != 0
+ && (parent = strchr(domain, '.')) != 0
+ && (idlen = strlen(certid + 1)) <= (domlen = strlen(parent))
+ && strcasecmp(multi ? parent + domlen - idlen : parent, certid+1) == 0))
return 1;
}
return 0;
{
char *cp = name + len;
-while(len > 0 && !*--cp)
+while (len > 0 && !*--cp)
--len; /* Ignore trailing NULs */
-if(len <= 0)
+if (len <= 0)
return 0;
-for(cp = name; *cp; cp++)
+for (cp = name; *cp; cp++)
{
char c = *cp;
if (!((c >= 'a' && c <= 'z') ||
(c == '*')))
return 0; /* Only LDH, '.' and '*' */
}
-if(cp - name != len) /* Guard against internal NULs */
+if (cp - name != len) /* Guard against internal NULs */
return 0;
return name;
}
static char *
parse_dns_name(const GENERAL_NAME *gn)
{
-if(gn->type != GEN_DNS)
+if (gn->type != GEN_DNS)
return 0;
-if(ASN1_STRING_type(gn->d.ia5) != V_ASN1_IA5STRING)
+if (ASN1_STRING_type(gn->d.ia5) != V_ASN1_IA5STRING)
return 0;
return check_name((char *) ASN1_STRING_data(gn->d.ia5),
ASN1_STRING_length(gn->d.ia5));
int len;
int i;
-if(!name || (i = X509_NAME_get_index_by_NID(name, nid, -1)) < 0)
+if (!name || (i = X509_NAME_get_index_by_NID(name, nid, -1)) < 0)
return 0;
-if(!(entry = X509_NAME_get_entry(name, i)))
+if (!(entry = X509_NAME_get_entry(name, i)))
return 0;
-if(!(entry_str = X509_NAME_ENTRY_get_data(entry)))
+if (!(entry_str = X509_NAME_ENTRY_get_data(entry)))
return 0;
-if((len = ASN1_STRING_to_UTF8(&namebuf, entry_str)) < 0)
+if ((len = ASN1_STRING_to_UTF8(&namebuf, entry_str)) < 0)
return 0;
-if(len <= 0 || check_name((char *) namebuf, len) == 0)
+if (len <= 0 || check_name((char *) namebuf, len) == 0)
{
OPENSSL_free(namebuf);
return 0;
GENERAL_NAMES *gens;
gens = X509_get_ext_d2i(cert, NID_subject_alt_name, 0, 0);
-if(gens)
+if (gens)
{
int n = sk_GENERAL_NAME_num(gens);
int i;
- for(i = 0; i < n; ++i)
+ for (i = 0; i < n; ++i)
{
const GENERAL_NAME *gn = sk_GENERAL_NAME_value(gens, i);
const char *certid;
- if(gn->type != GEN_DNS)
+ if (gn->type != GEN_DNS)
continue;
got_altname = TRUE;
certid = parse_dns_name(gn);
- if(certid && *certid)
+ if (certid && *certid)
{
- if((matched = match_name(certid, dane)) == 0)
+ if ((matched = match_name(certid, dane)) == 0)
continue;
- if(!(dane->mhost = OPENSSL_strdup(certid)))
+ if (!(dane->mhost = OPENSSL_strdup(certid)))
matched = -1;
+ DEBUG(D_tls) debug_printf("Dane name_check: matched SAN %s\n", certid);
break;
}
}
* XXX: Should the subjectName be skipped when *any* altnames are present,
* or only when DNS altnames are present?
*/
-if(got_altname)
+if (!got_altname)
{
char *certid = parse_subject_name(cert);
- if(certid != 0 && *certid && (matched = match_name(certid, dane)) != 0)
- dane->mhost = certid; /* Already a copy */
+ if (certid != 0 && *certid && (matched = match_name(certid, dane)) != 0)
+ {
+ DEBUG(D_tls) debug_printf("Dane name_check: matched SN %s\n", certid);
+ dane->mhost = OPENSSL_strdup(certid);
+ }
+ if (certid)
+ OPENSSL_free(certid);
}
return matched;
}
int matched = 0;
int chain_length = sk_X509_num(ctx->chain);
-DEBUG(D_tls) debug_printf("Dane verify-chain\n");
+DEBUG(D_tls) debug_printf("Dane verify_chain\n");
-issuer_rrs = dane->selectors[SSL_DANE_USAGE_LIMIT_ISSUER];
-leaf_rrs = dane->selectors[SSL_DANE_USAGE_LIMIT_LEAF];
+issuer_rrs = dane->selectors[DANESSL_USAGE_PKIX_TA];
+leaf_rrs = dane->selectors[DANESSL_USAGE_PKIX_EE];
ctx->verify = dane->verify;
-if((matched = name_check(dane, cert)) < 0)
+if ((matched = name_check(dane, cert)) < 0)
{
X509_STORE_CTX_set_error(ctx, X509_V_ERR_OUT_OF_MEM);
return 0;
}
-if(!matched)
+if (!matched)
{
ctx->error_depth = 0;
ctx->current_cert = cert;
X509_STORE_CTX_set_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH);
- if(!cb(0, ctx))
+ if (!cb(0, ctx))
return 0;
}
matched = 0;
* XXX: internal_verify() doesn't callback with top certs that are not
* self-issued. This should be fixed in a future OpenSSL.
*/
-if(dane->roots && sk_X509_num(dane->roots))
+if (dane->roots && sk_X509_num(dane->roots))
{
-#ifndef NO_CALLBACK_WORKAROUND
X509 *top = sk_X509_value(ctx->chain, dane->depth);
- if(X509_check_issued(top, top) != X509_V_OK)
+ dane->mdpth = dane->depth;
+ dane->match = top;
+ X509_up_ref(top);
+
+#ifndef NO_CALLBACK_WORKAROUND
+ if (X509_check_issued(top, top) != X509_V_OK)
{
ctx->error_depth = dane->depth;
ctx->current_cert = top;
- if(!cb(1, ctx))
+ if (!cb(1, ctx))
return 0;
}
#endif
while (--chain_length > dane->depth)
X509_free(sk_X509_pop(ctx->chain));
}
-else if(issuer_rrs || leaf_rrs)
+else
{
- int n = chain_length;
+ int n = 0;
+ X509 *xn = cert;
/*
* Check for an EE match, then a CA match at depths > 0, and
* finally, if the EE cert is self-issued, for a depth 0 CA match.
*/
- if(leaf_rrs)
- matched = match(leaf_rrs, cert, 0);
- while(!matched && issuer_rrs && --n >= 0)
- {
- X509 *xn = sk_X509_value(ctx->chain, n);
-
- if(n > 0 || X509_check_issued(xn, xn) == X509_V_OK)
- matched = match(issuer_rrs, xn, n);
- }
+ if (leaf_rrs)
+ matched = match(leaf_rrs, xn, 0);
+ if (matched) DEBUG(D_tls) debug_printf("Dane verify_chain: matched EE\n");
- if(matched < 0)
- {
- X509_STORE_CTX_set_error(ctx, X509_V_ERR_OUT_OF_MEM);
- return 0;
- }
+ if (!matched && issuer_rrs)
+ for (n = chain_length-1; !matched && n >= 0; --n)
+ {
+ xn = sk_X509_value(ctx->chain, n);
+ if (n > 0 || X509_check_issued(xn, xn) == X509_V_OK)
+ matched = match(issuer_rrs, xn, n);
+ }
+ if (matched) DEBUG(D_tls) debug_printf("Dane verify_chain: matched %s\n",
+ n>0 ? "CA" : "selfisssued EE");
- if(!matched)
+ if (!matched)
{
ctx->current_cert = cert;
ctx->error_depth = 0;
X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_UNTRUSTED);
- if(!cb(0, ctx))
+ if (!cb(0, ctx))
return 0;
}
+ else
+ {
+ dane->mdpth = n;
+ dane->match = xn;
+ X509_up_ref(xn);
+ }
}
return ctx->verify(ctx);
}
+static void
+dane_reset(ssl_dane *dane)
+{
+dane->depth = -1;
+if (dane->mhost)
+ {
+ OPENSSL_free(dane->mhost);
+ dane->mhost = 0;
+ }
+if (dane->roots)
+ {
+ sk_X509_pop_free(dane->roots, X509_free);
+ dane->roots = 0;
+ }
+if (dane->chain)
+ {
+ sk_X509_pop_free(dane->chain, X509_free);
+ dane->chain = 0;
+ }
+if (dane->match)
+ {
+ X509_free(dane->match);
+ dane->match = 0;
+ }
+dane->mdpth = -1;
+}
+
static int
verify_cert(X509_STORE_CTX *ctx, void *unused_ctx)
{
int matched;
X509 *cert = ctx->cert; /* XXX: accessor? */
-DEBUG(D_tls) debug_printf("Dane verify-cert\n");
+DEBUG(D_tls) debug_printf("Dane verify_cert\n");
-if(ssl_idx < 0)
+if (ssl_idx < 0)
ssl_idx = SSL_get_ex_data_X509_STORE_CTX_idx();
-if(dane_idx < 0)
+if (dane_idx < 0)
{
- DANEerr(DANE_F_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
+ DANEerr(DANESSL_F_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
return -1;
}
ssl = X509_STORE_CTX_get_ex_data(ctx, ssl_idx);
-if(!(dane = SSL_get_ex_data(ssl, dane_idx)) || !cert)
+if (!(dane = SSL_get_ex_data(ssl, dane_idx)) || !cert)
return X509_verify_cert(ctx);
-if(dane->selectors[SSL_DANE_USAGE_FIXED_LEAF])
+/* Reset for verification of a new chain, perhaps a renegotiation. */
+dane_reset(dane);
+
+if (dane->selectors[DANESSL_USAGE_DANE_EE])
{
- if((matched = check_end_entity(ctx, dane, cert)) > 0)
+ if ((matched = check_end_entity(ctx, dane, cert)) > 0)
{
ctx->error_depth = 0;
ctx->current_cert = cert;
return cb(1, ctx);
}
- if(matched < 0)
+ if (matched < 0)
{
X509_STORE_CTX_set_error(ctx, X509_V_ERR_OUT_OF_MEM);
return -1;
}
}
-if(dane->selectors[SSL_DANE_USAGE_TRUSTED_CA])
- {
- if((matched = set_trust_anchor(ctx, dane, cert)) < 0)
- {
- X509_STORE_CTX_set_error(ctx, X509_V_ERR_OUT_OF_MEM);
- return -1;
- }
- if(matched)
+ if (dane->selectors[DANESSL_USAGE_DANE_TA])
{
- /*
- * Check that setting the untrusted chain updates the expected
- * structure member at the expected offset.
- */
- X509_STORE_CTX_trusted_stack(ctx, dane->roots);
- X509_STORE_CTX_set_chain(ctx, dane->chain);
- OPENSSL_assert(ctx->untrusted == dane->chain);
+ if ((matched = set_trust_anchor(ctx, dane, cert)) < 0)
+ {
+ X509_STORE_CTX_set_error(ctx, X509_V_ERR_OUT_OF_MEM);
+ return -1;
+ }
+ if (matched)
+ {
+ /*
+ * Check that setting the untrusted chain updates the expected
+ * structure member at the expected offset.
+ */
+ X509_STORE_CTX_trusted_stack(ctx, dane->roots);
+ X509_STORE_CTX_set_chain(ctx, dane->chain);
+ OPENSSL_assert(ctx->untrusted == dane->chain);
+ }
}
- }
-/*
- * Name checks and usage 0/1 constraint enforcement are delayed until
- * X509_verify_cert() builds the full chain and calls our verify_chain()
- * wrapper.
- */
-dane->verify = ctx->verify;
-ctx->verify = verify_chain;
+ /*
+ * Name checks and usage 0/1 constraint enforcement are delayed until
+ * X509_verify_cert() builds the full chain and calls our verify_chain()
+ * wrapper.
+ */
+ dane->verify = ctx->verify;
+ ctx->verify = verify_chain;
-return X509_verify_cert(ctx);
+ if (X509_verify_cert(ctx))
+ return 1;
+
+ /*
+ * If the chain is invalid, clear any matching cert or hostname, to
+ * protect callers that might erroneously rely on these alone without
+ * checking the validation status.
+ */
+ if (dane->match)
+ {
+ X509_free(dane->match);
+ dane->match = 0;
+ }
+ if (dane->mhost)
+ {
+ OPENSSL_free(dane->mhost);
+ dane->mhost = 0;
+ }
+ return 0;
}
static dane_list
void *value = (void *) OPENSSL_malloc(vsize);
dane_list l;
-if(!value)
+if (!value)
{
- DANEerr(DANE_F_LIST_ALLOC, ERR_R_MALLOC_FAILURE);
+ DANEerr(DANESSL_F_LIST_ALLOC, ERR_R_MALLOC_FAILURE);
return 0;
}
-if(!(l = (dane_list) OPENSSL_malloc(sizeof(*l))))
+if (!(l = (dane_list) OPENSSL_malloc(sizeof(*l))))
{
OPENSSL_free(value);
- DANEerr(DANE_F_LIST_ALLOC, ERR_R_MALLOC_FAILURE);
+ DANEerr(DANESSL_F_LIST_ALLOC, ERR_R_MALLOC_FAILURE);
return 0;
}
l->next = 0;
dane_list head;
dane_list next;
-for(head = (dane_list) list; head; head = next)
+for (head = (dane_list) list; head; head = next)
{
next = head->next;
if (f && head->value)
static void
dane_mtype_free(void *p)
{
-list_free(((dane_mtype) p)->data, OPENSSL_freeFunc);
+list_free(((dane_mtype) p)->data, CRYPTO_free);
OPENSSL_free(p);
}
DEBUG(D_tls) debug_printf("Dane lib-cleanup\n");
-if(dane_idx < 0 || !(dane = SSL_get_ex_data(ssl, dane_idx)))
+if (dane_idx < 0 || !(dane = SSL_get_ex_data(ssl, dane_idx)))
return;
(void) SSL_set_ex_data(ssl, dane_idx, 0);
-if(dane->hosts)
- list_free(dane->hosts, OPENSSL_freeFunc);
-if(dane->mhost)
- OPENSSL_free(dane->mhost);
-for(u = 0; u <= SSL_DANE_USAGE_LAST; ++u)
- if(dane->selectors[u])
+dane_reset(dane);
+if (dane->hosts)
+ list_free(dane->hosts, CRYPTO_free);
+for (u = 0; u <= DANESSL_USAGE_LAST; ++u)
+ if (dane->selectors[u])
list_free(dane->selectors[u], dane_selector_free);
-if(dane->pkeys)
+if (dane->pkeys)
list_free(dane->pkeys, pkey_free);
-if(dane->certs)
+if (dane->certs)
list_free(dane->certs, cert_free);
-if(dane->roots)
- sk_X509_pop_free(dane->roots, X509_free);
-if(dane->chain)
- sk_X509_pop_free(dane->chain, X509_free);
OPENSSL_free(dane);
}
{
dane_host_list head = NULL;
-while(*src)
+while (*src)
{
dane_host_list elem = (dane_host_list) OPENSSL_malloc(sizeof(*elem));
- if(!elem)
+ if (elem == 0)
{
- list_free(head, OPENSSL_freeFunc);
+ list_free(head, CRYPTO_free);
return 0;
}
elem->value = OPENSSL_strdup(*src++);
}
+int
+DANESSL_get_match_cert(SSL *ssl, X509 **match, const char **mhost, int *depth)
+{
+ssl_dane *dane;
+
+if (dane_idx < 0 || (dane = SSL_get_ex_data(ssl, dane_idx)) == 0)
+ {
+ DANEerr(DANESSL_F_ADD_TLSA, DANESSL_R_INIT);
+ return -1;
+ }
+
+if (dane->match)
+ {
+ if (match)
+ *match = dane->match;
+ if (mhost)
+ *mhost = dane->mhost;
+ if (depth)
+ *depth = dane->mdpth;
+ }
+
+ return (dane->match != 0);
+}
+
+
+#ifdef never_called
+int
+DANESSL_verify_chain(SSL *ssl, STACK_OF(X509) *chain)
+{
+int ret;
+X509 *cert;
+X509_STORE_CTX store_ctx;
+SSL_CTX *ssl_ctx = SSL_get_SSL_CTX(ssl);
+X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx);
+int store_ctx_idx = SSL_get_ex_data_X509_STORE_CTX_idx();
+
+cert = sk_X509_value(chain, 0);
+if (!X509_STORE_CTX_init(&store_ctx, store, cert, chain))
+ return 0;
+X509_STORE_CTX_set_ex_data(&store_ctx, store_ctx_idx, ssl);
+
+X509_STORE_CTX_set_default(&store_ctx,
+ SSL_is_server(ssl) ? "ssl_client" : "ssl_server");
+X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&store_ctx),
+ SSL_get0_param(ssl));
+
+if (SSL_get_verify_callback(ssl))
+ X509_STORE_CTX_set_verify_cb(&store_ctx, SSL_get_verify_callback(ssl));
+
+ret = verify_cert(&store_ctx, NULL);
+
+SSL_set_verify_result(ssl, X509_STORE_CTX_get_error(&store_ctx));
+X509_STORE_CTX_cleanup(&store_ctx);
+
+return (ret);
+}
+#endif
+
+
/*
if(dane_idx < 0 || !(dane = SSL_get_ex_data(ssl, dane_idx)))
{
- DANEerr(DANE_F_SSL_DANE_ADD_TLSA, DANE_R_DANE_INIT);
+ DANEerr(DANESSL_F_ADD_TLSA, DANESSL_R_INIT);
return -1;
}
-if(usage > SSL_DANE_USAGE_LAST)
- {
- DANEerr(DANE_F_SSL_DANE_ADD_TLSA, DANE_R_BAD_USAGE);
- return 0;
- }
-if(selector > SSL_DANE_SELECTOR_LAST)
- {
- DANEerr(DANE_F_SSL_DANE_ADD_TLSA, DANE_R_BAD_SELECTOR);
- return 0;
- }
-if(mdname && !(md = EVP_get_digestbyname(mdname)))
- {
- DANEerr(DANE_F_SSL_DANE_ADD_TLSA, DANE_R_BAD_DIGEST);
- return 0;
- }
-if(!data)
+if (usage > DANESSL_USAGE_LAST)
{
- DANEerr(DANE_F_SSL_DANE_ADD_TLSA, DANE_R_BAD_NULL_DATA);
+ DANEerr(DANESSL_F_ADD_TLSA, DANESSL_R_BAD_USAGE);
return 0;
}
-if(mdname && dlen != EVP_MD_size(md))
+if (selector > DANESSL_SELECTOR_LAST)
{
- DANEerr(DANE_F_SSL_DANE_ADD_TLSA, DANE_R_BAD_DATA_LENGTH);
+ DANEerr(DANESSL_F_ADD_TLSA, DANESSL_R_BAD_SELECTOR);
return 0;
}
-if(!mdname)
- {
- X509 *x = 0;
- EVP_PKEY *k = 0;
- const unsigned char *p = data;
+ /* Support built-in standard one-digit mtypes */
+ if (mdname && *mdname && mdname[1] == '\0')
+ switch (*mdname - '0')
+ {
+ case DANESSL_MATCHING_FULL: mdname = 0; break;
+ case DANESSL_MATCHING_2256: mdname = "sha256"; break;
+ case DANESSL_MATCHING_2512: mdname = "sha512"; break;
+ }
+ if (mdname && *mdname && (md = EVP_get_digestbyname(mdname)) == 0)
+ {
+ DANEerr(DANESSL_F_ADD_TLSA, DANESSL_R_BAD_DIGEST);
+ return 0;
+ }
+ if (mdname && *mdname && dlen != EVP_MD_size(md))
+ {
+ DANEerr(DANESSL_F_ADD_TLSA, DANESSL_R_BAD_DATA_LENGTH);
+ return 0;
+ }
+ if (!data)
+ {
+ DANEerr(DANESSL_F_ADD_TLSA, DANESSL_R_BAD_NULL_DATA);
+ return 0;
+ }
+
+ /*
+ * Full Certificate or Public Key when NULL or empty digest name
+ */
+ if (!mdname || !*mdname)
+ {
+ X509 *x = 0;
+ EVP_PKEY *k = 0;
+ const unsigned char *p = data;
#define xklistinit(lvar, ltype, var, freeFunc) do { \
- (lvar) = (ltype) OPENSSL_malloc(sizeof(*(lvar))); \
- if (!(lvar)) { \
- DANEerr(DANE_F_SSL_DANE_ADD_TLSA, ERR_R_MALLOC_FAILURE); \
- freeFunc((var)); \
- return 0; \
- } \
- (lvar)->next = 0; \
- lvar->value = var; \
- } while (0)
+ (lvar) = (ltype) OPENSSL_malloc(sizeof(*(lvar))); \
+ if ((lvar) == 0) { \
+ DANEerr(DANESSL_F_ADD_TLSA, ERR_R_MALLOC_FAILURE); \
+ freeFunc((var)); \
+ return 0; \
+ } \
+ (lvar)->next = 0; \
+ lvar->value = var; \
+ } while (0)
#define xkfreeret(ret) do { \
- if (xlist) list_free(xlist, cert_free); \
- if (klist) list_free(klist, pkey_free); \
- return (ret); \
- } while (0)
+ if (xlist) list_free(xlist, cert_free); \
+ if (klist) list_free(klist, pkey_free); \
+ return (ret); \
+ } while (0)
- switch(selector)
+ switch (selector)
{
- case SSL_DANE_SELECTOR_CERT:
- if(!d2i_X509(&x, &p, dlen) || dlen != p - data)
+ case DANESSL_SELECTOR_CERT:
+ if (!d2i_X509(&x, &p, dlen) || dlen != p - data)
{
if (x)
- X509_free(x);
- DANEerr(DANE_F_SSL_DANE_ADD_TLSA, DANE_R_BAD_CERT);
+ X509_free(x);
+ DANEerr(DANESSL_F_ADD_TLSA, DANESSL_R_BAD_CERT);
return 0;
}
k = X509_get_pubkey(x);
EVP_PKEY_free(k);
- if(!k)
+ if (k == 0)
{
X509_free(x);
- DANEerr(DANE_F_SSL_DANE_ADD_TLSA, DANE_R_BAD_CERT_PKEY);
+ DANEerr(DANESSL_F_ADD_TLSA, DANESSL_R_BAD_CERT_PKEY);
return 0;
}
- if(usage == SSL_DANE_USAGE_TRUSTED_CA)
+ if (usage == DANESSL_USAGE_DANE_TA)
xklistinit(xlist, dane_cert_list, x, X509_free);
break;
- case SSL_DANE_SELECTOR_SPKI:
- if(!d2i_PUBKEY(&k, &p, dlen) || dlen != p - data)
+ case DANESSL_SELECTOR_SPKI:
+ if (!d2i_PUBKEY(&k, &p, dlen) || dlen != p - data)
{
- if(k)
+ if (k)
EVP_PKEY_free(k);
- DANEerr(DANE_F_SSL_DANE_ADD_TLSA, DANE_R_BAD_PKEY);
- return 0;
+ DANEerr(DANESSL_F_ADD_TLSA, DANESSL_R_BAD_PKEY);
+ return 0;
}
- if(usage == SSL_DANE_USAGE_TRUSTED_CA)
+ if (usage == DANESSL_USAGE_DANE_TA)
xklistinit(klist, dane_pkey_list, k, EVP_PKEY_free);
break;
}
}
/* Find insertion point and don't add duplicate elements. */
-for(s = dane->selectors[usage]; s; s = s->next)
- if(s->value->selector == selector)
- for(m = s->value->mtype; m; m = m->next)
- if(m->value->md == md)
- for(d = m->value->data; d; d = d->next)
- if( d->value->datalen == dlen
- && memcmp(d->value->data, data, dlen) == 0)
+for (s = dane->selectors[usage]; s; s = s->next)
+ if (s->value->selector == selector)
+ {
+ for (m = s->value->mtype; m; m = m->next)
+ if (m->value->md == md)
+ {
+ for (d = m->value->data; d; d = d->next)
+ if ( d->value->datalen == dlen
+ && memcmp(d->value->data, data, dlen) == 0)
xkfreeret(1);
+ break;
+ }
+ break;
+ }
-if(!(d = (dane_data_list) list_alloc(sizeof(*d->value) + dlen)))
+if ((d = (dane_data_list) list_alloc(sizeof(*d->value) + dlen)) == 0)
xkfreeret(0);
d->value->datalen = dlen;
memcpy(d->value->data, data, dlen);
-if(!m)
+if (!m)
{
- if(!(m = (dane_mtype_list) list_alloc(sizeof(*m->value))))
+ if ((m = (dane_mtype_list) list_alloc(sizeof(*m->value))) == 0)
{
- list_free(d, OPENSSL_freeFunc);
+ list_free(d, CRYPTO_free);
xkfreeret(0);
}
m->value->data = 0;
- if((m->value->md = md) != 0)
+ if ((m->value->md = md) != 0)
m->value->mdlen = dlen;
- if(!s)
+ if (!s)
{
- if(!(s = (dane_selector_list) list_alloc(sizeof(*s->value))))
+ if ((s = (dane_selector_list) list_alloc(sizeof(*s->value))) == 0)
{
list_free(m, dane_mtype_free);
xkfreeret(0);
}
LINSERT(m->value->data, d);
-if(xlist)
+if (xlist)
LINSERT(dane->certs, xlist);
-else if(klist)
+else if (klist)
LINSERT(dane->pkeys, klist);
++dane->count;
return 1;
{
ssl_dane *dane;
int i;
-#ifdef OPENSSL_INTERNAL
-SSL_CTX *sctx = SSL_get_SSL_CTX(ssl);
-
-if(sctx->app_verify_callback != verify_cert)
+DEBUG(D_tls) debug_printf("Dane ssl_init\n");
+if (dane_idx < 0)
{
- DANEerr(DANE_F_SSL_DANE_INIT, DANE_R_SCTX_INIT);
+ DANEerr(DANESSL_F_INIT, DANESSL_R_LIBRARY_INIT);
return -1;
}
-#else
-DEBUG(D_tls) debug_printf("Dane ssl-init\n");
-if(dane_idx < 0)
- {
- DANEerr(DANE_F_SSL_DANE_INIT, DANE_R_LIBRARY_INIT);
- return -1;
- }
-#endif
-if(sni_domain && !SSL_set_tlsext_host_name(ssl, sni_domain))
- return 0;
+if (sni_domain && !SSL_set_tlsext_host_name(ssl, sni_domain))
+ return 0;
-if(!(dane = (ssl_dane *) OPENSSL_malloc(sizeof(ssl_dane))))
+if ((dane = (ssl_dane *) OPENSSL_malloc(sizeof(ssl_dane))) == 0)
{
- DANEerr(DANE_F_SSL_DANE_INIT, ERR_R_MALLOC_FAILURE);
+ DANEerr(DANESSL_F_INIT, ERR_R_MALLOC_FAILURE);
return 0;
}
-if(!SSL_set_ex_data(ssl, dane_idx, dane))
+if (!SSL_set_ex_data(ssl, dane_idx, dane))
{
- DANEerr(DANE_F_SSL_DANE_INIT, ERR_R_MALLOC_FAILURE);
+ DANEerr(DANESSL_F_INIT, ERR_R_MALLOC_FAILURE);
OPENSSL_free(dane);
return 0;
}
dane->pkeys = 0;
dane->certs = 0;
dane->chain = 0;
+dane->match = 0;
dane->roots = 0;
dane->depth = -1;
-dane->mhost = 0; /* Future SSL control interface */
-dane->multi = 0; /* Future SSL control interface */
+dane->mhost = 0; /* Future SSL control interface */
+dane->mdpth = 0; /* Future SSL control interface */
+dane->multi = 0; /* Future SSL control interface */
dane->count = 0;
+dane->hosts = 0;
-for(i = 0; i <= SSL_DANE_USAGE_LAST; ++i)
- dane->selectors[i] = 0;
+for (i = 0; i <= DANESSL_USAGE_LAST; ++i)
+ dane->selectors[i] = 0;
-if(hostnames && !(dane->hosts = host_list_init(hostnames)))
+if (hostnames && (dane->hosts = host_list_init(hostnames)) == 0)
{
- DANEerr(DANE_F_SSL_DANE_INIT, ERR_R_MALLOC_FAILURE);
+ DANEerr(DANESSL_F_INIT, ERR_R_MALLOC_FAILURE);
DANESSL_cleanup(ssl);
return 0;
}
DANESSL_CTX_init(SSL_CTX *ctx)
{
DEBUG(D_tls) debug_printf("Dane ctx-init\n");
-if(dane_idx >= 0)
+if (dane_idx >= 0)
{
SSL_CTX_set_cert_verify_callback(ctx, verify_cert, 0);
return 1;
}
-DANEerr(DANE_F_SSL_CTX_DANE_INIT, DANE_R_LIBRARY_INIT);
+DANEerr(DANESSL_F_CTX_INIT, DANESSL_R_LIBRARY_INIT);
return -1;
}
int wlock = 0;
CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
-if(*value < 0)
+if (*value < 0)
{
CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
wlock = 1;
- if(*value < 0)
+ if (*value < 0)
{
*value = init();
- if(postinit)
+ if (postinit)
postinit();
}
}
* Register SHA-2 digests, if implemented and not already registered.
*/
#if defined(LN_sha256) && defined(NID_sha256) && !defined(OPENSSL_NO_SHA256)
-if(!EVP_get_digestbyname(LN_sha224)) EVP_add_digest(EVP_sha224());
-if(!EVP_get_digestbyname(LN_sha256)) EVP_add_digest(EVP_sha256());
+if (!EVP_get_digestbyname(LN_sha224)) EVP_add_digest(EVP_sha224());
+if (!EVP_get_digestbyname(LN_sha256)) EVP_add_digest(EVP_sha256());
#endif
#if defined(LN_sha512) && defined(NID_sha512) && !defined(OPENSSL_NO_SHA512)
-if(!EVP_get_digestbyname(LN_sha384)) EVP_add_digest(EVP_sha384());
-if(!EVP_get_digestbyname(LN_sha512)) EVP_add_digest(EVP_sha512());
+if (!EVP_get_digestbyname(LN_sha384)) EVP_add_digest(EVP_sha384());
+if (!EVP_get_digestbyname(LN_sha512)) EVP_add_digest(EVP_sha512());
#endif
/*
DANESSL_library_init(void)
{
DEBUG(D_tls) debug_printf("Dane lib-init\n");
-if(err_lib_dane < 0)
+if (err_lib_dane < 0)
init_once(&err_lib_dane, ERR_get_next_error_library, dane_init);
#if defined(LN_sha256)
/* No DANE without SHA256 support */
-if(dane_idx >= 0 && EVP_get_digestbyname(LN_sha256) != 0)
+if (dane_idx >= 0 && EVP_get_digestbyname(LN_sha256) != 0)
return 1;
#endif
-
-DANEerr(DANE_F_SSL_DANE_LIBRARY_INIT, DANE_R_DANE_SUPPORT);
+DANEerr(DANESSL_F_LIBRARY_INIT, DANESSL_R_SUPPORT);
return 0;
}
# error DANE support requires that TLS support must be enabled. Abort build.
# endif
+/* DNSSEC support is also required */
+# ifndef RES_USE_DNSSEC
+# error DANE support requires that the DNS reolver library supports DNSSEC
+# endif
+
# ifdef USE_GNUTLS
# include "dane-gnu.c"
# else
-#ifndef HEADER_SSL_DANE_H
-#define HEADER_SSL_DANE_H
+/*
+ * Author: Viktor Dukhovni
+ * License: THIS CODE IS IN THE PUBLIC DOMAIN.
+ */
+#ifndef HEADER_DANESSL_H
+#define HEADER_DANESSL_H
#include <stdint.h>
#include <openssl/ssl.h>
* Certificate usages:
* https://tools.ietf.org/html/rfc6698#section-2.1.1
*/
-#define SSL_DANE_USAGE_LIMIT_ISSUER 0
-#define SSL_DANE_USAGE_LIMIT_LEAF 1
-#define SSL_DANE_USAGE_TRUSTED_CA 2
-#define SSL_DANE_USAGE_FIXED_LEAF 3
-#define SSL_DANE_USAGE_LAST SSL_DANE_USAGE_FIXED_LEAF
+#define DANESSL_USAGE_PKIX_TA 0
+#define DANESSL_USAGE_PKIX_EE 1
+#define DANESSL_USAGE_DANE_TA 2
+#define DANESSL_USAGE_DANE_EE 3
+#define DANESSL_USAGE_LAST DANESSL_USAGE_DANE_EE
/*-
* Selectors:
* https://tools.ietf.org/html/rfc6698#section-2.1.2
*/
-#define SSL_DANE_SELECTOR_CERT 0
-#define SSL_DANE_SELECTOR_SPKI 1
-#define SSL_DANE_SELECTOR_LAST SSL_DANE_SELECTOR_SPKI
+#define DANESSL_SELECTOR_CERT 0
+#define DANESSL_SELECTOR_SPKI 1
+#define DANESSL_SELECTOR_LAST DANESSL_SELECTOR_SPKI
+
+/*-
+ * Matching types:
+ * https://tools.ietf.org/html/rfc6698#section-2.1.3
+ */
+#define DANESSL_MATCHING_FULL 0
+#define DANESSL_MATCHING_2256 1
+#define DANESSL_MATCHING_2512 2
+#define DANESSL_MATCHING_LAST DANESSL_MATCHING_2512
extern int DANESSL_library_init(void);
extern int DANESSL_CTX_init(SSL_CTX *);
extern int DANESSL_init(SSL *, const char *, const char **);
extern void DANESSL_cleanup(SSL *);
extern int DANESSL_add_tlsa(SSL *, uint8_t, uint8_t, const char *,
- unsigned const char *, size_t);
+ unsigned const char *, size_t);
+extern int DANESSL_get_match_cert(SSL *, X509 **, const char **, int *);
+extern int DANESSL_verify_chain(SSL *, STACK_OF(X509) *);
+
#endif
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
*/
void *
-dbfn_read_with_length(open_db *dbblock, uschar *key, int *length)
+dbfn_read_with_length(open_db *dbblock, const uschar *key, int *length)
{
void *yield;
EXIM_DATUM key_datum, result_datum;
+int klen = Ustrlen(key) + 1;
+uschar * key_copy = store_get(klen);
+
+memcpy(key_copy, key, klen);
DEBUG(D_hints_lookup) debug_printf("dbfn_read: key=%s\n", key);
EXIM_DATUM_INIT(key_datum); /* Some DBM libraries require the datum */
EXIM_DATUM_INIT(result_datum); /* to be cleared before use. */
-EXIM_DATUM_DATA(key_datum) = CS key;
-EXIM_DATUM_SIZE(key_datum) = Ustrlen(key) + 1;
+EXIM_DATUM_DATA(key_datum) = CS key_copy;
+EXIM_DATUM_SIZE(key_datum) = klen;
if (!EXIM_DBGET(dbblock->dbptr, key_datum, result_datum)) return NULL;
*/
int
-dbfn_write(open_db *dbblock, uschar *key, void *ptr, int length)
+dbfn_write(open_db *dbblock, const uschar *key, void *ptr, int length)
{
EXIM_DATUM key_datum, value_datum;
dbdata_generic *gptr = (dbdata_generic *)ptr;
+int klen = Ustrlen(key) + 1;
+uschar * key_copy = store_get(klen);
+
+memcpy(key_copy, key, klen);
gptr->time_stamp = time(NULL);
DEBUG(D_hints_lookup) debug_printf("dbfn_write: key=%s\n", key);
EXIM_DATUM_INIT(key_datum); /* Some DBM libraries require the datum */
EXIM_DATUM_INIT(value_datum); /* to be cleared before use. */
-EXIM_DATUM_DATA(key_datum) = CS key;
-EXIM_DATUM_SIZE(key_datum) = Ustrlen(key) + 1;
+EXIM_DATUM_DATA(key_datum) = CS key_copy;
+EXIM_DATUM_SIZE(key_datum) = klen;
EXIM_DATUM_DATA(value_datum) = CS ptr;
EXIM_DATUM_SIZE(value_datum) = length;
return EXIM_DBPUT(dbblock->dbptr, key_datum, value_datum);
*/
int
-dbfn_delete(open_db *dbblock, uschar *key)
+dbfn_delete(open_db *dbblock, const uschar *key)
{
+int klen = Ustrlen(key) + 1;
+uschar * key_copy = store_get(klen);
+
+memcpy(key_copy, key, klen);
EXIM_DATUM key_datum;
EXIM_DATUM_INIT(key_datum); /* Some DBM libraries require clearing */
-EXIM_DATUM_DATA(key_datum) = CS key;
-EXIM_DATUM_SIZE(key_datum) = Ustrlen(key) + 1;
+EXIM_DATUM_DATA(key_datum) = CS key_copy;
+EXIM_DATUM_SIZE(key_datum) = klen;
return EXIM_DBDEL(dbblock->dbptr, key_datum);
}
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Functions for reading/writing exim database files */
void dbfn_close(open_db *);
-int dbfn_delete(open_db *, uschar *);
+int dbfn_delete(open_db *, const uschar *);
open_db *dbfn_open(uschar *, int, open_db *, BOOL);
-void *dbfn_read_with_length(open_db *, uschar *, int *);
+void *dbfn_read_with_length(open_db *, const uschar *, int *);
uschar *dbfn_scan(open_db *, BOOL, EXIM_CURSOR **);
-int dbfn_write(open_db *, uschar *, void *, int);
+int dbfn_write(open_db *, const uschar *, void *, int);
/* Macro for the common call to read without wanting to know the length. */
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) Wolfgang Breyha 2005-2013
+/* Copyright (c) Wolfgang Breyha 2005 - 2015
* Vienna University Computer Center
* wbreyha@gmx.net
* See the file NOTICE for conditions of use and distribution.
return retval;
}
-int dcc_process(uschar **listptr) {
+int
+dcc_process(uschar **listptr)
+{
int sep = 0;
- uschar *list = *listptr;
+ const uschar *list = *listptr;
FILE *data_file;
uschar *dcc_default_ip_option = US"127.0.0.1";
uschar *dcc_helo_option = US"localhost";
bzero(opts,sizeof(opts));
Ustrncpy(opts, dccifd_options, sizeof(opts)-1);
/* if $acl_m_dcc_override_client_ip is set use it */
- if (((override_client_ip = expand_string(US"$acl_m_dcc_override_client_ip")) != NULL) &&
+ if (((override_client_ip = expand_string(US"$acl_m_dcc_override_client_ip")) != NULL) &&
(override_client_ip[0] != '\0')) {
Ustrncpy(client_ip, override_client_ip, sizeof(client_ip)-1);
DEBUG(D_acl)
debug_printf("DCC: Client IP (overridden): %s\n", client_ip);
- }
+ }
else if(sender_host_address) {
/* else if $sender_host_address is available use that? */
Ustrncpy(client_ip, sender_host_address, sizeof(client_ip)-1);
DEBUG(D_acl)
debug_printf("DCC: Client IP (sender_host_address): %s\n", client_ip);
- }
+ }
else {
/* sender_host_address is NULL which means it comes from localhost */
Ustrncpy(client_ip, dcc_default_ip_option, sizeof(client_ip)-1);
/* The third and following lines are the X-DCC header,
* so we store it in dcc_header_str. */
/* check if we don't get more than we can handle */
- if(k < sizeof(dcc_header_str)) {
+ if(k < sizeof(dcc_header_str)) {
dcc_header_str[k] = recvbuf[i];
k++;
}
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
*/
void
-debug_print_argv(uschar **argv)
+debug_print_argv(const uschar ** argv)
{
debug_printf("exec");
while (*argv != NULL) debug_printf(" %.256s", *argv++);
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* The main code for delivering a message. */
#include "exim.h"
+#include <assert.h>
/* Data block for keeping track of subprocesses for parallel remote
void
deliver_set_expansions(address_item *addr)
{
-if (addr == NULL)
+if (!addr)
{
- uschar ***p = address_expansions;
- while (*p != NULL) **p++ = NULL;
+ const uschar ***p = address_expansions;
+ while (*p) **p++ = NULL;
return;
}
what they contain. These first ones are always set, taking their values from
the first address. */
-if (addr->host_list == NULL)
+if (!addr->host_list)
{
deliver_host = deliver_host_address = US"";
deliver_host_port = 0;
}
deliver_recipients = addr;
-deliver_address_data = addr->p.address_data;
-deliver_domain_data = addr->p.domain_data;
-deliver_localpart_data = addr->p.localpart_data;
+deliver_address_data = addr->prop.address_data;
+deliver_domain_data = addr->prop.domain_data;
+deliver_localpart_data = addr->prop.localpart_data;
/* These may be unset for multiple addresses */
/* If there's only one address we can set everything. */
-if (addr->next == NULL)
+if (!addr->next)
{
address_item *addr_orig;
deliver_localpart_prefix = addr->prefix;
deliver_localpart_suffix = addr->suffix;
- for (addr_orig = addr; addr_orig->parent != NULL;
- addr_orig = addr_orig->parent);
+ for (addr_orig = addr; addr_orig->parent; addr_orig = addr_orig->parent) ;
deliver_domain_orig = addr_orig->domain;
/* Re-instate any prefix and suffix in the original local part. In all
filter sets up a pipe, file, or autoreply delivery, no router is involved.
In this case, though, there won't be any prefix or suffix to worry about. */
- deliver_localpart_orig = (addr_orig->router == NULL)? addr_orig->local_part :
- addr_orig->router->caseful_local_part?
- addr_orig->cc_local_part : addr_orig->lc_local_part;
+ deliver_localpart_orig = !addr_orig->router
+ ? addr_orig->local_part
+ : addr_orig->router->caseful_local_part
+ ? addr_orig->cc_local_part
+ : addr_orig->lc_local_part;
/* If there's a parent, make its domain and local part available, and if
delivering to a pipe or file, or sending an autoreply, get the local
part from the parent. For pipes and files, put the pipe or file string
into address_pipe and address_file. */
- if (addr->parent != NULL)
+ if (addr->parent)
{
deliver_domain_parent = addr->parent->domain;
- deliver_localpart_parent = (addr->parent->router == NULL)?
- addr->parent->local_part :
- addr->parent->router->caseful_local_part?
- addr->parent->cc_local_part : addr->parent->lc_local_part;
+ deliver_localpart_parent = !addr->parent->router
+ ? addr->parent->local_part
+ : addr->parent->router->caseful_local_part
+ ? addr->parent->cc_local_part
+ : addr->parent->lc_local_part;
/* File deliveries have their own flag because they need to be picked out
as special more often. */
if (testflag(addr, af_pfr))
{
- if (testflag(addr, af_file)) address_file = addr->local_part;
- else if (deliver_localpart[0] == '|') address_pipe = addr->local_part;
+ if (testflag(addr, af_file)) address_file = addr->local_part;
+ else if (deliver_localpart[0] == '|') address_pipe = addr->local_part;
deliver_localpart = addr->parent->local_part;
deliver_localpart_prefix = addr->parent->prefix;
deliver_localpart_suffix = addr->parent->suffix;
/* get message delivery status (0 - don't deliver | 1 - deliver) */
bmi_deliver = bmi_get_delivery_status(bmi_base64_verdict);
/* if message is to be delivered, get eventual alternate location */
- if (bmi_deliver == 1) {
+ if (bmi_deliver == 1)
bmi_alt_location = bmi_get_alt_location(bmi_base64_verdict);
- };
#endif
}
address_item *addr2;
if (testflag(addr, af_pfr))
{
- if (testflag(addr, af_file)) address_file = addr->local_part;
- else if (addr->local_part[0] == '|') address_pipe = addr->local_part;
+ if (testflag(addr, af_file)) address_file = addr->local_part;
+ else if (addr->local_part[0] == '|') address_pipe = addr->local_part;
}
- for (addr2 = addr->next; addr2 != NULL; addr2 = addr2->next)
+ for (addr2 = addr->next; addr2; addr2 = addr2->next)
{
- if (deliver_domain != NULL &&
- Ustrcmp(deliver_domain, addr2->domain) != 0)
+ if (deliver_domain && Ustrcmp(deliver_domain, addr2->domain) != 0)
deliver_domain = NULL;
- if (self_hostname != NULL && (addr2->self_hostname == NULL ||
- Ustrcmp(self_hostname, addr2->self_hostname) != 0))
+ if ( self_hostname
+ && ( !addr2->self_hostname
+ || Ustrcmp(self_hostname, addr2->self_hostname) != 0
+ ) )
self_hostname = NULL;
- if (deliver_domain == NULL && self_hostname == NULL) break;
+ if (!deliver_domain && !self_hostname) break;
}
}
}
replicate_status(address_item *addr)
{
address_item *addr2;
-for (addr2 = addr->next; addr2 != NULL; addr2 = addr2->next)
+for (addr2 = addr->next; addr2; addr2 = addr2->next)
{
- addr2->transport = addr->transport;
+ addr2->transport = addr->transport;
addr2->transport_return = addr->transport_return;
- addr2->basic_errno = addr->basic_errno;
- addr2->more_errno = addr->more_errno;
- addr2->special_action = addr->special_action;
- addr2->message = addr->message;
- addr2->user_message = addr->user_message;
+ addr2->basic_errno = addr->basic_errno;
+ addr2->more_errno = addr->more_errno;
+ addr2->special_action = addr->special_action;
+ addr2->message = addr->message;
+ addr2->user_message = addr->user_message;
}
}
static BOOL
same_hosts(host_item *one, host_item *two)
{
-while (one != NULL && two != NULL)
+while (one && two)
{
if (Ustrcmp(one->name, two->name) != 0)
{
/* Find the ends of the shortest sequence of identical MX values */
- while (end_one->next != NULL && end_one->next->mx == mx &&
- end_two->next != NULL && end_two->next->mx == mx)
+ while ( end_one->next && end_one->next->mx == mx
+ && end_two->next && end_two->next->mx == mx)
{
end_one = end_one->next;
end_two = end_two->next;
static BOOL
same_headers(header_line *one, header_line *two)
{
-for (;;)
+for (;; one = one->next, two = two->next)
{
if (one == two) return TRUE; /* Includes the case where both NULL */
- if (one == NULL || two == NULL) return FALSE;
+ if (!one || !two) return FALSE;
if (Ustrcmp(one->text, two->text) != 0) return FALSE;
- one = one->next;
- two = two->next;
}
}
same_strings(uschar *one, uschar *two)
{
if (one == two) return TRUE; /* Includes the case where both NULL */
-if (one == NULL || two == NULL) return FALSE;
+if (!one || !two) return FALSE;
return (Ustrcmp(one, two) == 0);
}
static BOOL
same_ugid(transport_instance *tp, address_item *addr1, address_item *addr2)
{
-if (!tp->uid_set && tp->expand_uid == NULL && !tp->deliver_as_creator)
- {
- if (testflag(addr1, af_uid_set) != testflag(addr2, af_gid_set) ||
- (testflag(addr1, af_uid_set) &&
- (addr1->uid != addr2->uid ||
- testflag(addr1, af_initgroups) != testflag(addr2, af_initgroups))))
- return FALSE;
- }
+if ( !tp->uid_set && !tp->expand_uid
+ && !tp->deliver_as_creator
+ && ( testflag(addr1, af_uid_set) != testflag(addr2, af_gid_set)
+ || ( testflag(addr1, af_uid_set)
+ && ( addr1->uid != addr2->uid
+ || testflag(addr1, af_initgroups) != testflag(addr2, af_initgroups)
+ ) ) ) )
+ return FALSE;
-if (!tp->gid_set && tp->expand_gid == NULL)
- {
- if (testflag(addr1, af_gid_set) != testflag(addr2, af_gid_set) ||
- (testflag(addr1, af_gid_set) && addr1->gid != addr2->gid))
- return FALSE;
- }
+if ( !tp->gid_set && !tp->expand_gid
+ && ( testflag(addr1, af_gid_set) != testflag(addr2, af_gid_set)
+ || ( testflag(addr1, af_gid_set)
+ && addr1->gid != addr2->gid
+ ) ) )
+ return FALSE;
return TRUE;
}
/* Top-level address */
-if (addr->parent == NULL)
+if (!addr->parent)
{
tree_add_nonrecipient(addr->unique);
tree_add_nonrecipient(addr->address);
else if (testflag(addr, af_homonym))
{
- if (addr->transport != NULL)
- {
+ if (addr->transport)
tree_add_nonrecipient(
string_sprintf("%s/%s", addr->unique + 3, addr->transport->name));
- }
}
/* Non-homonymous child address */
/* Check the list of duplicate addresses and ensure they are now marked
done as well. */
-for (dup = addr_duplicate; dup != NULL; dup = dup->next)
- {
+for (dup = addr_duplicate; dup; dup = dup->next)
if (Ustrcmp(addr->unique, dup->unique) == 0)
{
tree_add_nonrecipient(dup->unique);
child_done(dup, now);
}
- }
}
child_done(address_item *addr, uschar *now)
{
address_item *aa;
-while (addr->parent != NULL)
+while (addr->parent)
{
addr = addr->parent;
if ((addr->child_count -= 1) > 0) return; /* Incomplete parent */
/* Log the completion of all descendents only when there is no ancestor with
the same original address. */
- for (aa = addr->parent; aa != NULL; aa = aa->parent)
+ for (aa = addr->parent; aa; aa = aa->parent)
if (Ustrcmp(aa->address, addr->address) == 0) break;
- if (aa != NULL) continue;
+ if (aa) continue;
deliver_msglog("%s %s: children all complete\n", now, addr->address);
DEBUG(D_deliver) debug_printf("%s: children all complete\n", addr->address);
+/*************************************************
+* Delivery logging support functions *
+*************************************************/
+
+/* The LOGGING() checks in d_log_interface() are complicated for backwards
+compatibility. When outgoing interface logging was originally added, it was
+conditional on just incoming_interface (which is off by default). The
+outgoing_interface option is on by default to preserve this behaviour, but
+you can enable incoming_interface and disable outgoing_interface to get I=
+fields on incoming lines only.
+
+Arguments:
+ s The log line buffer
+ sizep Pointer to the buffer size
+ ptrp Pointer to current index into buffer
+ addr The address to be logged
+
+Returns: New value for s
+*/
+
+static uschar *
+d_log_interface(uschar *s, int *sizep, int *ptrp)
+{
+if (LOGGING(incoming_interface) && LOGGING(outgoing_interface)
+ && sending_ip_address)
+ {
+ s = string_append(s, sizep, ptrp, 2, US" I=[", sending_ip_address);
+ s = LOGGING(outgoing_port)
+ ? string_append(s, sizep, ptrp, 2, US"]:",
+ string_sprintf("%d", sending_port))
+ : string_cat(s, sizep, ptrp, US"]", 1);
+ }
+return s;
+}
+
+
static uschar *
-d_hostlog(uschar * s, int * sizep, int * ptrp, address_item * addr)
+d_hostlog(uschar *s, int *sizep, int *ptrp, address_item *addr)
{
- s = string_append(s, sizep, ptrp, 5, US" H=", addr->host_used->name,
- US" [", addr->host_used->address, US"]");
- if ((log_extra_selector & LX_outgoing_port) != 0)
+s = string_append(s, sizep, ptrp, 5, US" H=", addr->host_used->name,
+ US" [", addr->host_used->address, US"]");
+if (LOGGING(outgoing_port))
+ s = string_append(s, sizep, ptrp, 2, US":", string_sprintf("%d",
+ addr->host_used->port));
+
+#ifdef SUPPORT_SOCKS
+if (LOGGING(proxy) && proxy_local_address)
+ {
+ s = string_append(s, sizep, ptrp, 3, US" PRX=[", proxy_local_address, US"]");
+ if (LOGGING(outgoing_port))
s = string_append(s, sizep, ptrp, 2, US":", string_sprintf("%d",
- addr->host_used->port));
- return s;
+ proxy_local_port));
+ }
+#endif
+
+return d_log_interface(s, sizep, ptrp);
}
+
+
+
+
#ifdef SUPPORT_TLS
static uschar *
d_tlslog(uschar * s, int * sizep, int * ptrp, address_item * addr)
{
- if ((log_extra_selector & LX_tls_cipher) != 0 && addr->cipher != NULL)
- s = string_append(s, sizep, ptrp, 2, US" X=", addr->cipher);
- if ((log_extra_selector & LX_tls_certificate_verified) != 0 &&
- addr->cipher != NULL)
- s = string_append(s, sizep, ptrp, 2, US" CV=",
- testflag(addr, af_cert_verified)
- ?
+if (LOGGING(tls_cipher) && addr->cipher)
+ s = string_append(s, sizep, ptrp, 2, US" X=", addr->cipher);
+if (LOGGING(tls_certificate_verified) && addr->cipher)
+ s = string_append(s, sizep, ptrp, 2, US" CV=",
+ testflag(addr, af_cert_verified)
+ ?
#ifdef EXPERIMENTAL_DANE
- testflag(addr, af_dane_verified)
- ? "dane"
- :
+ testflag(addr, af_dane_verified)
+ ? "dane"
+ :
#endif
- "yes"
- : "no");
- if ((log_extra_selector & LX_tls_peerdn) != 0 && addr->peerdn != NULL)
- s = string_append(s, sizep, ptrp, 3, US" DN=\"",
- string_printing(addr->peerdn), US"\"");
- return s;
+ "yes"
+ : "no");
+if (LOGGING(tls_peerdn) && addr->peerdn)
+ s = string_append(s, sizep, ptrp, 3, US" DN=\"",
+ string_printing(addr->peerdn), US"\"");
+return s;
}
#endif
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
uschar *
-event_raise(uschar * action, uschar * event, uschar * ev_data)
+event_raise(uschar * action, const uschar * event, uschar * ev_data)
{
uschar * s;
if (action)
return NULL;
}
-static void
-msg_event_raise(uschar * event, address_item * addr)
+void
+msg_event_raise(const uschar * event, const address_item * addr)
{
-uschar * save_domain = deliver_domain;
+const uschar * save_domain = deliver_domain;
uschar * save_local = deliver_localpart;
-uschar * save_host = deliver_host;
+const uschar * save_host = deliver_host;
+const uschar * save_address = deliver_host_address;
+const int save_port = deliver_host_port;
if (!addr->transport)
return;
deliver_host = addr->host_used ? addr->host_used->name : NULL;
(void) event_raise(addr->transport->event_action, event,
- addr->host_used || Ustrcmp(addr->transport->driver_name, "lmtp") == 0
- ? addr->message : NULL);
+ addr->host_used
+ || Ustrcmp(addr->transport->driver_name, "smtp") == 0
+ || Ustrcmp(addr->transport->driver_name, "lmtp") == 0
+ ? addr->message : NULL);
+deliver_host_port = save_port;
+deliver_host_address = save_address;
deliver_host = save_host;
deliver_localpart = save_local;
deliver_domain = save_domain;
router_name = transport_name = NULL;
}
-#endif /*EXPERIMENTAL_EVENT*/
+#endif /*DISABLE_EVENT*/
have a pointer to the host item that succeeded; local deliveries can have a
pointer to a single host item in their host list, for use by the transport. */
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
/* presume no successful remote delivery */
lookup_dnssec_authenticated = NULL;
#endif
s = reset_point = store_get(size);
-log_address = string_log_address(addr, (log_write_selector & L_all_parents) != 0, TRUE);
+log_address = string_log_address(addr, LOGGING(all_parents), TRUE);
if (msg)
s = string_append(s, &size, &ptr, 3, host_and_ident(TRUE), US" ", log_address);
else
s = string_append(s, &size, &ptr, 2, US"> ", log_address);
}
-if ((log_extra_selector & LX_sender_on_delivery) != 0 || msg)
- s = string_append(s, &size, &ptr, 3, US" F=<", sender_address, US">");
+if (LOGGING(sender_on_delivery) || msg)
+ s = string_append(s, &size, &ptr, 3, US" F=<",
+#ifdef SUPPORT_I18N
+ testflag(addr, af_utf8_downcvt)
+ ? string_address_utf8_to_alabel(sender_address, NULL)
+ :
+#endif
+ sender_address,
+ US">");
#ifdef EXPERIMENTAL_SRS
-if(addr->p.srs_sender)
- s = string_append(s, &size, &ptr, 3, US" SRS=<", addr->p.srs_sender, US">");
+if(addr->prop.srs_sender)
+ s = string_append(s, &size, &ptr, 3, US" SRS=<", addr->prop.srs_sender, US">");
#endif
/* You might think that the return path must always be set for a successful
when it is not set is for a delivery to /dev/null which is optimised by not
being run at all. */
-if (used_return_path != NULL &&
- (log_extra_selector & LX_return_path_on_delivery) != 0)
+if (used_return_path && LOGGING(return_path_on_delivery))
s = string_append(s, &size, &ptr, 3, US" P=<", used_return_path, US">");
if (msg)
s = string_append(s, &size, &ptr, 2, US" ", msg);
/* For a delivery from a system filter, there may not be a router */
-if (addr->router != NULL)
+if (addr->router)
s = string_append(s, &size, &ptr, 2, US" R=", addr->router->name);
s = string_append(s, &size, &ptr, 2, US" T=", addr->transport->name);
-if ((log_extra_selector & LX_delivery_size) != 0)
+if (LOGGING(delivery_size))
s = string_append(s, &size, &ptr, 2, US" S=",
string_sprintf("%d", transport_count));
{
if (addr->host_list)
s = string_append(s, &size, &ptr, 2, US" H=", addr->host_list->name);
- if (addr->shadow_message != NULL)
+ s = d_log_interface(s, &size, &ptr);
+ if (addr->shadow_message)
s = string_cat(s, &size, &ptr, addr->shadow_message,
Ustrlen(addr->shadow_message));
}
if (continue_sequence > 1)
s = string_cat(s, &size, &ptr, US"*", 1);
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
deliver_host_address = addr->host_used->address;
deliver_host_port = addr->host_used->port;
deliver_host = addr->host_used->name;
if (addr->auth_id)
{
s = string_append(s, &size, &ptr, 2, US":", addr->auth_id);
- if (log_extra_selector & LX_smtp_mailauth && addr->auth_sndr)
+ if (LOGGING(smtp_mailauth) && addr->auth_sndr)
s = string_append(s, &size, &ptr, 2, US":", addr->auth_sndr);
}
}
/* confirmation message (SMTP (host_used) and LMTP (driver_name)) */
-if (log_extra_selector & LX_smtp_confirmation &&
- addr->message &&
- (addr->host_used || Ustrcmp(addr->transport->driver_name, "lmtp") == 0))
+if ( LOGGING(smtp_confirmation)
+ && addr->message
+ && (addr->host_used || Ustrcmp(addr->transport->driver_name, "lmtp") == 0)
+ )
{
- int i;
+ unsigned i;
+ unsigned lim = big_buffer_size < 1024 ? big_buffer_size : 1024;
uschar *p = big_buffer;
uschar *ss = addr->message;
*p++ = '\"';
- for (i = 0; i < 256 && ss[i] != 0; i++) /* limit logged amount */
+ for (i = 0; i < lim && ss[i] != 0; i++) /* limit logged amount */
{
if (ss[i] == '\"' || ss[i] == '\\') *p++ = '\\'; /* quote \ and " */
*p++ = ss[i];
/* Time on queue and actual time taken to deliver */
-if ((log_extra_selector & LX_queue_time) != 0)
+if (LOGGING(queue_time))
s = string_append(s, &size, &ptr, 2, US" QT=",
readconf_printtime( (int) ((long)time(NULL) - (long)received_time)) );
-if ((log_extra_selector & LX_deliver_time) != 0)
+if (LOGGING(deliver_time))
s = string_append(s, &size, &ptr, 2, US" DT=",
readconf_printtime(addr->more_errno));
s[ptr] = 0;
log_write(0, flags, "%s", s);
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
if (!msg) msg_event_raise(US"msg:delivery", addr);
#endif
if (driver_type == DTYPE_TRANSPORT)
{
- if (addr->transport != NULL)
+ if (addr->transport)
{
driver_name = addr->transport->name;
driver_kind = US" transport";
}
else if (driver_type == DTYPE_ROUTER)
{
- if (addr->router != NULL)
+ if (addr->router)
{
driver_name = addr->router->name;
driver_kind = US" router";
fudge, but I don't know a cleaner way of doing this. (If the item is badly
malformed, it won't ever have gone near LDAP.) */
-if (addr->message != NULL)
+if (addr->message)
{
- addr->message = string_printing(addr->message);
- if (((Ustrstr(addr->message, "failed to expand") != NULL) || (Ustrstr(addr->message, "expansion of ") != NULL)) &&
- (Ustrstr(addr->message, "mysql") != NULL ||
- Ustrstr(addr->message, "pgsql") != NULL ||
-#ifdef EXPERIMENTAL_REDIS
- Ustrstr(addr->message, "redis") != NULL ||
-#endif
- Ustrstr(addr->message, "sqlite") != NULL ||
- Ustrstr(addr->message, "ldap:") != NULL ||
- Ustrstr(addr->message, "ldapdn:") != NULL ||
- Ustrstr(addr->message, "ldapm:") != NULL))
- {
- addr->message = string_sprintf("Temporary internal error");
- }
+ const uschar * s = string_printing(addr->message);
+ if (s != addr->message)
+ addr->message = US s;
+ /* deconst cast ok as string_printing known to have alloc'n'copied */
+ if ( ( Ustrstr(s, "failed to expand") != NULL
+ || Ustrstr(s, "expansion of ") != NULL
+ )
+ && ( Ustrstr(s, "mysql") != NULL
+ || Ustrstr(s, "pgsql") != NULL
+ || Ustrstr(s, "redis") != NULL
+ || Ustrstr(s, "sqlite") != NULL
+ || Ustrstr(s, "ldap:") != NULL
+ || Ustrstr(s, "ldapdn:") != NULL
+ || Ustrstr(s, "ldapm:") != NULL
+ ) )
+ addr->message = string_sprintf("Temporary internal error");
}
/* If we used a transport that has one of the "return_output" options set, and
In any case, we close the message file, because we cannot afford to leave a
file-descriptor for one address while processing (maybe very many) others. */
-if (addr->return_file >= 0 && addr->return_filename != NULL)
+if (addr->return_file >= 0 && addr->return_filename)
{
BOOL return_output = FALSE;
struct stat statbuf;
/* Handle logging options */
- if (tb->log_output || (result == FAIL && tb->log_fail_output) ||
- (result == DEFER && tb->log_defer_output))
+ if ( tb->log_output
+ || result == FAIL && tb->log_fail_output
+ || result == DEFER && tb->log_defer_output
+ )
{
uschar *s;
FILE *f = Ufopen(addr->return_filename, "rb");
- if (f == NULL)
+ if (!f)
log_write(0, LOG_MAIN|LOG_PANIC, "failed to open %s to log output "
"from %s transport: %s", addr->return_filename, tb->name,
strerror(errno));
else
- {
- s = US Ufgets(big_buffer, big_buffer_size, f);
- if (s != NULL)
+ if ((s = US Ufgets(big_buffer, big_buffer_size, f)))
{
uschar *p = big_buffer + Ustrlen(big_buffer);
+ const uschar * sp;
while (p > big_buffer && isspace(p[-1])) p--;
*p = 0;
- s = string_printing(big_buffer);
+ sp = string_printing(big_buffer);
log_write(0, LOG_MAIN, "<%s>: %s transport output: %s",
- addr->address, tb->name, s);
+ addr->address, tb->name, sp);
}
(void)fclose(f);
- }
}
/* Handle returning options, but only if there is an address to return
the text to. */
- if (sender_address[0] != 0 || addr->p.errors_address != NULL)
- {
+ if (sender_address[0] != 0 || addr->prop.errors_address)
if (tb->return_output)
{
addr->transport_return = result = FAIL;
- if (addr->basic_errno == 0 && addr->message == NULL)
+ if (addr->basic_errno == 0 && !addr->message)
addr->message = US"return message generated";
return_output = TRUE;
}
else
if (tb->return_fail_output && result == FAIL) return_output = TRUE;
- }
}
/* Get rid of the file unless it might be returned, but close it in
address_done(addr, now);
DEBUG(D_deliver) debug_printf("%s delivered\n", addr->address);
- if (addr->parent == NULL)
+ if (!addr->parent)
deliver_msglog("%s %s: %s%s succeeded\n", now, addr->address,
driver_name, driver_kind);
else
delivery_log(LOG_MAIN, addr, logchar, NULL);
#ifdef SUPPORT_TLS
- if (tls_out.ourcert)
- {
- tls_free_cert(tls_out.ourcert);
- tls_out.ourcert = NULL;
- }
- if (tls_out.peercert)
- {
- tls_free_cert(tls_out.peercert);
- tls_out.peercert = NULL;
- }
+ tls_free_cert(&tls_out.ourcert);
+ tls_free_cert(&tls_out.peercert);
tls_out.cipher = NULL;
tls_out.peerdn = NULL;
tls_out.ocsp = OCSP_NOT_REQ;
of error number is negative, and all the retry ones are less than any
others. */
- unsigned int use_log_selector = (addr->basic_errno <= ERRNO_RETRY_BASE)?
- L_retry_defer : 0;
+ unsigned int use_log_selector = addr->basic_errno <= ERRNO_RETRY_BASE
+ ? L_retry_defer : 0;
/* Build up the line that is used for both the message log and the main
log. */
/* Create the address string for logging. Must not do this earlier, because
an OK result may be changed to FAIL when a pipe returns text. */
- log_address = string_log_address(addr,
- (log_write_selector & L_all_parents) != 0, result == OK);
+ log_address = string_log_address(addr, LOGGING(all_parents), result == OK);
s = string_cat(s, &size, &ptr, log_address, Ustrlen(log_address));
space, if all routing has been deferred. When a domain has been held,
so nothing has been done at all, both variables contain null strings. */
- if (driver_name == NULL)
+ if (driver_name)
{
- if (driver_kind != NULL)
- s = string_append(s, &size, &ptr, 2, US" ", driver_kind);
- }
- else
- {
- if (driver_kind[1] == 't' && addr->router != NULL)
+ if (driver_kind[1] == 't' && addr->router)
s = string_append(s, &size, &ptr, 2, US" R=", addr->router->name);
Ustrcpy(ss, " ?=");
ss[1] = toupper(driver_kind[1]);
s = string_append(s, &size, &ptr, 2, ss, driver_name);
}
+ else if (driver_kind)
+ s = string_append(s, &size, &ptr, 2, US" ", driver_kind);
sprintf(CS ss, " defer (%d)", addr->basic_errno);
s = string_cat(s, &size, &ptr, ss, Ustrlen(ss));
US strerror(addr->basic_errno));
if (addr->host_used)
+ {
s = string_append(s, &size, &ptr, 5,
US" H=", addr->host_used->name,
US" [", addr->host_used->address, US"]");
+ if (LOGGING(outgoing_port))
+ {
+ int port = addr->host_used->port;
+ s = string_append(s, &size, &ptr, 2,
+ US":", port == PORT_NONE ? US"25" : string_sprintf("%d", port));
+ }
+ }
- if (addr->message != NULL)
+ if (addr->message)
s = string_append(s, &size, &ptr, 2, US": ", addr->message);
s[ptr] = 0;
to ignore occurs later, instead of sending a message. Logging of freezing
occurs later, just before writing the -H file. */
- if (!testflag(addr, af_ignore_error) &&
- (addr->special_action == SPECIAL_FREEZE ||
- (sender_address[0] == 0 && addr->p.errors_address == NULL)
- ))
+ if ( !testflag(addr, af_ignore_error)
+ && ( addr->special_action == SPECIAL_FREEZE
+ || (sender_address[0] == 0 && !addr->prop.errors_address)
+ ) )
{
- frozen_info = (addr->special_action == SPECIAL_FREEZE)? US"" :
- (sender_local && !local_error_message)?
- US" (message created with -f <>)" : US" (delivery error message)";
+ frozen_info = addr->special_action == SPECIAL_FREEZE
+ ? US""
+ : sender_local && !local_error_message
+ ? US" (message created with -f <>)"
+ : US" (delivery error message)";
deliver_freeze = TRUE;
deliver_frozen_at = time(NULL);
update_spool = TRUE;
/* Create the address string for logging. Must not do this earlier, because
an OK result may be changed to FAIL when a pipe returns text. */
- log_address = string_log_address(addr,
- (log_write_selector & L_all_parents) != 0, result == OK);
+ log_address = string_log_address(addr, LOGGING(all_parents), result == OK);
s = string_cat(s, &size, &ptr, log_address, Ustrlen(log_address));
- if ((log_extra_selector & LX_sender_on_delivery) != 0)
+ if (LOGGING(sender_on_delivery))
s = string_append(s, &size, &ptr, 3, US" F=<", sender_address, US">");
/* Return path may not be set if no delivery actually happened */
- if (used_return_path != NULL &&
- (log_extra_selector & LX_return_path_on_delivery) != 0)
+ if (used_return_path && LOGGING(return_path_on_delivery))
s = string_append(s, &size, &ptr, 3, US" P=<", used_return_path, US">");
- if (addr->router != NULL)
+ if (addr->router)
s = string_append(s, &size, &ptr, 2, US" R=", addr->router->name);
- if (addr->transport != NULL)
+ if (addr->transport)
s = string_append(s, &size, &ptr, 2, US" T=", addr->transport->name);
- if (addr->host_used != NULL)
+ if (addr->host_used)
s = d_hostlog(s, &size, &ptr, addr);
#ifdef SUPPORT_TLS
s = string_append(s, &size, &ptr, 2, US": ",
US strerror(addr->basic_errno));
- if (addr->message != NULL)
+ if (addr->message)
s = string_append(s, &size, &ptr, 2, US": ", addr->message);
s[ptr] = 0;
/* Do the logging. For the message log, "routing failed" for those cases,
just to make it clearer. */
- if (driver_name == NULL)
- deliver_msglog("%s %s failed for %s\n", now, driver_kind, s);
- else
+ if (driver_name)
deliver_msglog("%s %s\n", now, s);
+ else
+ deliver_msglog("%s %s failed for %s\n", now, driver_kind, s);
log_write(0, LOG_MAIN, "** %s", s);
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
msg_event_raise(US"msg:fail:delivery", addr);
#endif
address_item *addr2;
addr->basic_errno = code;
-if (format != NULL)
+if (format)
{
va_list ap;
uschar buffer[512];
addr->message = string_copy(buffer);
}
-for (addr2 = addr->next; addr2 != NULL; addr2 = addr2->next)
+for (addr2 = addr->next; addr2; addr2 = addr2->next)
{
addr2->basic_errno = code;
addr2->message = addr->message;
check_never_users(uid_t uid, uid_t *nusers)
{
int i;
-if (nusers == NULL) return FALSE;
+if (!nusers) return FALSE;
for (i = 1; i <= (int)(nusers[0]); i++) if (nusers[i] == uid) return TRUE;
return FALSE;
}
findugid(address_item *addr, transport_instance *tp, uid_t *uidp, gid_t *gidp,
BOOL *igfp)
{
-uschar *nuname = NULL;
+uschar *nuname;
BOOL gid_set = FALSE;
/* Default initgroups flag comes from the transport */
*gidp = tp->gid;
gid_set = TRUE;
}
-else if (tp->expand_gid != NULL)
+else if (tp->expand_gid)
{
- if (route_find_expanded_group(tp->expand_gid, tp->name, US"transport", gidp,
- &(addr->message))) gid_set = TRUE;
- else
+ if (!route_find_expanded_group(tp->expand_gid, tp->name, US"transport", gidp,
+ &(addr->message)))
{
common_error(FALSE, addr, ERRNO_GIDFAIL, NULL);
return FALSE;
}
+ gid_set = TRUE;
}
/* If the transport did not set a group, see if the router did. */
/* Otherwise, try for an expandable uid field. If it ends up as a numeric id,
it does not provide a passwd value from which a gid can be taken. */
-else if (tp->expand_uid != NULL)
+else if (tp->expand_uid)
{
struct passwd *pw;
if (!route_find_expanded_user(tp->expand_uid, tp->name, US"transport", &pw,
common_error(FALSE, addr, ERRNO_UIDFAIL, NULL);
return FALSE;
}
- if (!gid_set && pw != NULL)
+ if (!gid_set && pw)
{
*gidp = pw->pw_gid;
gid_set = TRUE;
/* Check that the uid is not on the lists of banned uids that may not be used
for delivery processes. */
-if (check_never_users(*uidp, never_users))
- nuname = US"never_users";
-else if (check_never_users(*uidp, fixed_never_users))
- nuname = US"fixed_never_users";
-
-if (nuname != NULL)
+nuname = check_never_users(*uidp, never_users)
+ ? US"never_users"
+ : check_never_users(*uidp, fixed_never_users)
+ ? US"fixed_never_users"
+ : NULL;
+if (nuname)
{
common_error(TRUE, addr, ERRNO_UIDFAIL, US"User %ld set for %s transport "
"is on the %s list", (long int)(*uidp), tp->name, nuname);
size_limit = expand_string_integer(tp->message_size_limit, TRUE);
deliver_set_expansions(NULL);
-if (expand_string_message != NULL)
+if (expand_string_message)
{
rc = DEFER;
- if (size_limit == -1)
- addr->message = string_sprintf("failed to expand message_size_limit "
- "in %s transport: %s", tp->name, expand_string_message);
- else
- addr->message = string_sprintf("invalid message_size_limit "
+ addr->message = size_limit == -1
+ ? string_sprintf("failed to expand message_size_limit "
+ "in %s transport: %s", tp->name, expand_string_message)
+ : string_sprintf("invalid message_size_limit "
"in %s transport: %s", tp->name, expand_string_message);
}
else if (size_limit > 0 && message_size > size_limit)
/* Set up the return path from the errors or sender address. If the transport
has its own return path setting, expand it and replace the existing value. */
-if(addr->p.errors_address != NULL)
- return_path = addr->p.errors_address;
+if(addr->prop.errors_address)
+ return_path = addr->prop.errors_address;
#ifdef EXPERIMENTAL_SRS
-else if(addr->p.srs_sender != NULL)
- return_path = addr->p.srs_sender;
+else if (addr->prop.srs_sender)
+ return_path = addr->prop.srs_sender;
#endif
else
return_path = sender_address;
-if (tp->return_path != NULL)
+if (tp->return_path)
{
uschar *new_return_path = expand_string(tp->return_path);
- if (new_return_path == NULL)
+ if (!new_return_path)
{
if (!expand_string_forcedfail)
{
home directory set in the address may already be expanded; a flag is set to
indicate that. In other cases we must expand it. */
-if ((deliver_home = tp->home_dir) != NULL || /* Set in transport, or */
- ((deliver_home = addr->home_dir) != NULL && /* Set in address and */
- !testflag(addr, af_home_expanded))) /* not expanded */
+if ( (deliver_home = tp->home_dir) /* Set in transport, or */
+ || ( (deliver_home = addr->home_dir) /* Set in address and */
+ && !testflag(addr, af_home_expanded) /* not expanded */
+ ) )
{
uschar *rawhome = deliver_home;
deliver_home = NULL; /* in case it contains $home */
- deliver_home = expand_string(rawhome);
- if (deliver_home == NULL)
+ if (!(deliver_home = expand_string(rawhome)))
{
common_error(TRUE, addr, ERRNO_EXPANDFAIL, US"home directory \"%s\" failed "
"to expand for %s transport: %s", rawhome, tp->name,
operating systems when running pipes, as some commands (e.g. "rm" under Solaris
2.5) require this. */
-working_directory = (tp->current_dir != NULL)?
- tp->current_dir : addr->current_dir;
-
-if (working_directory != NULL)
+working_directory = tp->current_dir ? tp->current_dir : addr->current_dir;
+if (working_directory)
{
uschar *raw = working_directory;
- working_directory = expand_string(raw);
- if (working_directory == NULL)
+ if (!(working_directory = expand_string(raw)))
{
common_error(TRUE, addr, ERRNO_EXPANDFAIL, US"current directory \"%s\" "
"failed to expand for %s transport: %s", raw, tp->name,
return;
}
}
-else working_directory = (deliver_home == NULL)? US"/" : deliver_home;
+else working_directory = deliver_home ? deliver_home : US"/";
/* If one of the return_output flags is set on the transport, create and open a
file in the message log directory for the transport to write its output onto.
This is mainly used by pipe transports. The file needs to be unique to the
address. This feature is not available for shadow transports. */
-if (!shadowing && (tp->return_output || tp->return_fail_output ||
- tp->log_output || tp->log_fail_output))
+if ( !shadowing
+ && ( tp->return_output || tp->return_fail_output
+ || tp->log_output || tp->log_fail_output || tp->log_defer_output
+ ) )
{
uschar *error;
addr->return_filename =
privileged. (Appendfile uses this to expand quota, for example, while
able to read private files.) */
- if (addr->transport->setup != NULL)
- {
+ if (addr->transport->setup)
switch((addr->transport->setup)(addr->transport, addr, NULL, uid, gid,
&(addr->message)))
{
case DEFER:
- addr->transport_return = DEFER;
- goto PASS_BACK;
+ addr->transport_return = DEFER;
+ goto PASS_BACK;
case FAIL:
- addr->transport_return = PANIC;
- goto PASS_BACK;
+ addr->transport_return = PANIC;
+ goto PASS_BACK;
}
- }
/* Ignore SIGINT and SIGTERM during delivery. Also ignore SIGUSR1, as
when the process becomes unprivileged, it won't be able to write to the
{
address_item *batched;
debug_printf(" home=%s current=%s\n", deliver_home, working_directory);
- for (batched = addr->next; batched != NULL; batched = batched->next)
+ for (batched = addr->next; batched; batched = batched->next)
debug_printf("additional batched address: %s\n", batched->address);
}
/* If a transport filter has been specified, set up its argument list.
Any errors will get put into the address, and FALSE yielded. */
- if (addr->transport->filter_command != NULL)
+ if (addr->transport->filter_command)
{
ok = transport_set_up_command(&transport_filter_argv,
addr->transport->filter_command,
PASS_BACK:
if (replicate) replicate_status(addr);
- for (addr2 = addr; addr2 != NULL; addr2 = addr2->next)
+ for (addr2 = addr; addr2; addr2 = addr2->next)
{
int i;
int local_part_length = Ustrlen(addr2->local_part);
uschar *s;
int ret;
- if( (ret = write(pfd[pipe_write], (void *)&(addr2->transport_return), sizeof(int))) != sizeof(int)
- || (ret = write(pfd[pipe_write], (void *)&transport_count, sizeof(transport_count))) != sizeof(transport_count)
- || (ret = write(pfd[pipe_write], (void *)&(addr2->flags), sizeof(addr2->flags))) != sizeof(addr2->flags)
- || (ret = write(pfd[pipe_write], (void *)&(addr2->basic_errno), sizeof(int))) != sizeof(int)
- || (ret = write(pfd[pipe_write], (void *)&(addr2->more_errno), sizeof(int))) != sizeof(int)
- || (ret = write(pfd[pipe_write], (void *)&(addr2->special_action), sizeof(int))) != sizeof(int)
- || (ret = write(pfd[pipe_write], (void *)&(addr2->transport),
+ if( (ret = write(pfd[pipe_write], &addr2->transport_return, sizeof(int))) != sizeof(int)
+ || (ret = write(pfd[pipe_write], &transport_count, sizeof(transport_count))) != sizeof(transport_count)
+ || (ret = write(pfd[pipe_write], &addr2->flags, sizeof(addr2->flags))) != sizeof(addr2->flags)
+ || (ret = write(pfd[pipe_write], &addr2->basic_errno, sizeof(int))) != sizeof(int)
+ || (ret = write(pfd[pipe_write], &addr2->more_errno, sizeof(int))) != sizeof(int)
+ || (ret = write(pfd[pipe_write], &addr2->special_action, sizeof(int))) != sizeof(int)
+ || (ret = write(pfd[pipe_write], &addr2->transport,
sizeof(transport_instance *))) != sizeof(transport_instance *)
/* For a file delivery, pass back the local part, in case the original
logging. */
|| (testflag(addr2, af_file)
- && ( (ret = write(pfd[pipe_write], (void *)&local_part_length, sizeof(int))) != sizeof(int)
+ && ( (ret = write(pfd[pipe_write], &local_part_length, sizeof(int))) != sizeof(int)
|| (ret = write(pfd[pipe_write], addr2->local_part, local_part_length)) != local_part_length
)
)
for (i = 0, s = addr2->message; i < 2; i++, s = addr2->user_message)
{
- int message_length = (s == NULL)? 0 : Ustrlen(s) + 1;
- if( (ret = write(pfd[pipe_write], (void *)&message_length, sizeof(int))) != sizeof(int)
- || (message_length > 0 && (ret = write(pfd[pipe_write], s, message_length)) != message_length)
+ int message_length = s ? Ustrlen(s) + 1 : 0;
+ if( (ret = write(pfd[pipe_write], &message_length, sizeof(int))) != sizeof(int)
+ || message_length > 0 && (ret = write(pfd[pipe_write], s, message_length)) != message_length
)
log_write(0, LOG_MAIN|LOG_PANIC, "Failed writing transport results to pipe: %s\n",
ret == -1 ? strerror(errno) : "short write");
(void)close(pfd[pipe_write]);
-for (addr2 = addr; addr2 != NULL; addr2 = addr2->next)
+for (addr2 = addr; addr2; addr2 = addr2->next)
{
- len = read(pfd[pipe_read], (void *)&status, sizeof(int));
+ len = read(pfd[pipe_read], &status, sizeof(int));
if (len > 0)
{
int i;
uschar **sptr;
addr2->transport_return = status;
- len = read(pfd[pipe_read], (void *)&transport_count,
+ len = read(pfd[pipe_read], &transport_count,
sizeof(transport_count));
- len = read(pfd[pipe_read], (void *)&(addr2->flags), sizeof(addr2->flags));
- len = read(pfd[pipe_read], (void *)&(addr2->basic_errno), sizeof(int));
- len = read(pfd[pipe_read], (void *)&(addr2->more_errno), sizeof(int));
- len = read(pfd[pipe_read], (void *)&(addr2->special_action), sizeof(int));
- len = read(pfd[pipe_read], (void *)&(addr2->transport),
+ len = read(pfd[pipe_read], &addr2->flags, sizeof(addr2->flags));
+ len = read(pfd[pipe_read], &addr2->basic_errno, sizeof(int));
+ len = read(pfd[pipe_read], &addr2->more_errno, sizeof(int));
+ len = read(pfd[pipe_read], &addr2->special_action, sizeof(int));
+ len = read(pfd[pipe_read], &addr2->transport,
sizeof(transport_instance *));
if (testflag(addr2, af_file))
{
int local_part_length;
- len = read(pfd[pipe_read], (void *)&local_part_length, sizeof(int));
- len = read(pfd[pipe_read], (void *)big_buffer, local_part_length);
+ len = read(pfd[pipe_read], &local_part_length, sizeof(int));
+ len = read(pfd[pipe_read], big_buffer, local_part_length);
big_buffer[local_part_length] = 0;
addr2->local_part = string_copy(big_buffer);
}
- for (i = 0, sptr = &(addr2->message); i < 2;
- i++, sptr = &(addr2->user_message))
+ for (i = 0, sptr = &addr2->message; i < 2; i++, sptr = &addr2->user_message)
{
int message_length;
- len = read(pfd[pipe_read], (void *)&message_length, sizeof(int));
+ len = read(pfd[pipe_read], &message_length, sizeof(int));
if (message_length > 0)
{
- len = read(pfd[pipe_read], (void *)big_buffer, message_length);
+ len = read(pfd[pipe_read], big_buffer, message_length);
if (len > 0) *sptr = string_copy(big_buffer);
}
}
if (!shadowing)
{
- for (addr2 = addr; addr2 != NULL; addr2 = addr2->next)
- {
- if (addr2->transport_return != OK) continue;
-
- if (testflag(addr2, af_homonym))
- sprintf(CS big_buffer, "%.500s/%s\n", addr2->unique + 3, tp->name);
- else
- sprintf(CS big_buffer, "%.500s\n", addr2->unique);
+ for (addr2 = addr; addr2; addr2 = addr2->next)
+ if (addr2->transport_return == OK)
+ {
+ if (testflag(addr2, af_homonym))
+ sprintf(CS big_buffer, "%.500s/%s\n", addr2->unique + 3, tp->name);
+ else
+ sprintf(CS big_buffer, "%.500s\n", addr2->unique);
- /* In the test harness, wait just a bit to let the subprocess finish off
- any debug output etc first. */
+ /* In the test harness, wait just a bit to let the subprocess finish off
+ any debug output etc first. */
- if (running_in_test_harness) millisleep(300);
+ if (running_in_test_harness) millisleep(300);
- DEBUG(D_deliver) debug_printf("journalling %s", big_buffer);
- len = Ustrlen(big_buffer);
- if (write(journal_fd, big_buffer, len) != len)
- log_write(0, LOG_MAIN|LOG_PANIC, "failed to update journal for %s: %s",
- big_buffer, strerror(errno));
- }
+ DEBUG(D_deliver) debug_printf("journalling %s", big_buffer);
+ len = Ustrlen(big_buffer);
+ if (write(journal_fd, big_buffer, len) != len)
+ log_write(0, LOG_MAIN|LOG_PANIC, "failed to update journal for %s: %s",
+ big_buffer, strerror(errno));
+ }
/* Ensure the journal file is pushed out to disk. */
resets SIGCHLD to SIG_DFL, but this code should still be robust. */
while ((rc = wait(&status)) != pid)
- {
if (rc < 0 && errno == ECHILD) /* Process has vanished */
{
log_write(0, LOG_MAIN, "%s transport process vanished unexpectedly",
status = 0;
break;
}
- }
if ((status & 0xffff) != 0)
{
"status 0x%04x: %s %d",
addr->transport->driver_name,
status,
- (msb == 0)? "terminated by signal" : "exit code",
+ msb == 0 ? "terminated by signal" : "exit code",
code);
}
/* If SPECIAL_WARN is set in the top address, send a warning message. */
-if (addr->special_action == SPECIAL_WARN &&
- addr->transport->warn_message != NULL)
+if (addr->special_action == SPECIAL_WARN && addr->transport->warn_message)
{
int fd;
uschar *warn_message;
+ pid_t pid;
DEBUG(D_deliver) debug_printf("Warning message requested by transport\n");
- warn_message = expand_string(addr->transport->warn_message);
- if (warn_message == NULL)
+ if (!(warn_message = expand_string(addr->transport->warn_message)))
log_write(0, LOG_MAIN|LOG_PANIC, "Failed to expand \"%s\" (warning "
"message for %s transport): %s", addr->transport->warn_message,
addr->transport->name, expand_string_message);
- else
+
+ else if ((pid = child_open_exim(&fd)) > 0)
{
- pid_t pid = child_open_exim(&fd);
- if (pid > 0)
- {
- FILE *f = fdopen(fd, "wb");
- if (errors_reply_to != NULL &&
- !contains_header(US"Reply-To", warn_message))
- fprintf(f, "Reply-To: %s\n", errors_reply_to);
- fprintf(f, "Auto-Submitted: auto-replied\n");
- if (!contains_header(US"From", warn_message)) moan_write_from(f);
- fprintf(f, "%s", CS warn_message);
+ FILE *f = fdopen(fd, "wb");
+ if (errors_reply_to && !contains_header(US"Reply-To", warn_message))
+ fprintf(f, "Reply-To: %s\n", errors_reply_to);
+ fprintf(f, "Auto-Submitted: auto-replied\n");
+ if (!contains_header(US"From", warn_message))
+ moan_write_from(f);
+ fprintf(f, "%s", CS warn_message);
- /* Close and wait for child process to complete, without a timeout. */
+ /* Close and wait for child process to complete, without a timeout. */
- (void)fclose(f);
- (void)child_close(pid, 0);
- }
+ (void)fclose(f);
+ (void)child_close(pid, 0);
}
addr->special_action = SPECIAL_NONE;
+
+/* Check transport for the given concurrency limit. Return TRUE if over
+the limit (or an expansion failure), else FALSE and if there was a limit,
+the key for the hints database used for the concurrency count. */
+
+static BOOL
+tpt_parallel_check(transport_instance * tp, address_item * addr, uschar ** key)
+{
+unsigned max_parallel;
+
+if (!tp->max_parallel) return FALSE;
+
+max_parallel = (unsigned) expand_string_integer(tp->max_parallel, TRUE);
+if (expand_string_message)
+ {
+ log_write(0, LOG_MAIN|LOG_PANIC, "Failed to expand max_parallel option "
+ "in %s transport (%s): %s", tp->name, addr->address,
+ expand_string_message);
+ return TRUE;
+ }
+
+if (max_parallel > 0)
+ {
+ uschar * serialize_key = string_sprintf("tpt-serialize-%s", tp->name);
+ if (!enq_start(serialize_key, max_parallel))
+ {
+ address_item * next;
+ DEBUG(D_transport)
+ debug_printf("skipping tpt %s because concurrency limit %u reached\n",
+ tp->name, max_parallel);
+ do
+ {
+ next = addr->next;
+ addr->message = US"concurrency limit reached for transport";
+ addr->basic_errno = ERRNO_TRETRY;
+ post_process_one(addr, DEFER, LOG_MAIN, DTYPE_TRANSPORT, 0);
+ } while ((addr = next));
+ return TRUE;
+ }
+ *key = serialize_key;
+ }
+return FALSE;
+}
+
+
+
/*************************************************
* Do local deliveries *
*************************************************/
/* Loop until we have exhausted the supply of local deliveries */
-while (addr_local != NULL)
+while (addr_local)
{
time_t delivery_start;
int deliver_time;
int logflags = LOG_MAIN;
int logchar = dont_deliver? '*' : '=';
transport_instance *tp;
+ uschar * serialize_key = NULL;
/* Pick the first undelivered address off the chain */
/* An internal disaster if there is no transport. Should not occur! */
- if ((tp = addr->transport) == NULL)
+ if (!(tp = addr->transport))
{
logflags |= LOG_PANIC;
disable_logging = FALSE; /* Jic */
- addr->message =
- (addr->router != NULL)?
- string_sprintf("No transport set by %s router", addr->router->name)
- :
- string_sprintf("No transport set by system filter");
+ addr->message = addr->router
+ ? string_sprintf("No transport set by %s router", addr->router->name)
+ : string_sprintf("No transport set by system filter");
post_process_one(addr, DEFER, logflags, DTYPE_TRANSPORT, 0);
continue;
}
if either batch_max <= 1 or there aren't any other addresses for local
delivery. */
- if (tp->batch_max > 1 && addr_local != NULL)
+ if (tp->batch_max > 1 && addr_local)
{
int batch_count = 1;
BOOL uses_dom = readconf_depends((driver_instance *)tp, US"domain");
- BOOL uses_lp = (testflag(addr, af_pfr) &&
- (testflag(addr, af_file) || addr->local_part[0] == '|')) ||
- readconf_depends((driver_instance *)tp, US"local_part");
+ BOOL uses_lp = ( testflag(addr, af_pfr)
+ && (testflag(addr, af_file) || addr->local_part[0] == '|')
+ )
+ || readconf_depends((driver_instance *)tp, US"local_part");
uschar *batch_id = NULL;
address_item **anchor = &addr_local;
address_item *last = addr;
/* Expand the batch_id string for comparison with other addresses.
Expansion failure suppresses batching. */
- if (tp->batch_id != NULL)
+ if (tp->batch_id)
{
deliver_set_expansions(addr);
batch_id = expand_string(tp->batch_id);
deliver_set_expansions(NULL);
- if (batch_id == NULL)
+ if (!batch_id)
{
log_write(0, LOG_MAIN|LOG_PANIC, "Failed to expand batch_id option "
"in %s transport (%s): %s", tp->name, addr->address,
same first host if a host list is set
*/
- while ((next = *anchor) != NULL && batch_count < tp->batch_max)
+ while ((next = *anchor) && batch_count < tp->batch_max)
{
BOOL ok =
- tp == next->transport &&
- !previously_transported(next, TRUE) &&
- (addr->flags & (af_pfr|af_file)) == (next->flags & (af_pfr|af_file)) &&
- (!uses_lp || Ustrcmp(next->local_part, addr->local_part) == 0) &&
- (!uses_dom || Ustrcmp(next->domain, addr->domain) == 0) &&
- same_strings(next->p.errors_address, addr->p.errors_address) &&
- same_headers(next->p.extra_headers, addr->p.extra_headers) &&
- same_strings(next->p.remove_headers, addr->p.remove_headers) &&
- same_ugid(tp, addr, next) &&
- ((addr->host_list == NULL && next->host_list == NULL) ||
- (addr->host_list != NULL && next->host_list != NULL &&
- Ustrcmp(addr->host_list->name, next->host_list->name) == 0));
+ tp == next->transport
+ && !previously_transported(next, TRUE)
+ && (addr->flags & (af_pfr|af_file)) == (next->flags & (af_pfr|af_file))
+ && (!uses_lp || Ustrcmp(next->local_part, addr->local_part) == 0)
+ && (!uses_dom || Ustrcmp(next->domain, addr->domain) == 0)
+ && same_strings(next->prop.errors_address, addr->prop.errors_address)
+ && same_headers(next->prop.extra_headers, addr->prop.extra_headers)
+ && same_strings(next->prop.remove_headers, addr->prop.remove_headers)
+ && same_ugid(tp, addr, next)
+ && ( !addr->host_list && !next->host_list
+ || addr->host_list
+ && next->host_list
+ && Ustrcmp(addr->host_list->name, next->host_list->name) == 0
+ );
/* If the transport has a batch_id setting, batch_id will be non-NULL
from the expansion outside the loop. Expand for this address and compare.
Expansion failure makes this address ineligible for batching. */
- if (ok && batch_id != NULL)
+ if (ok && batch_id)
{
uschar *bid;
address_item *save_nextnext = next->next;
next->next = save_nextnext;
bid = expand_string(tp->batch_id);
deliver_set_expansions(NULL);
- if (bid == NULL)
+ if (!bid)
{
log_write(0, LOG_MAIN|LOG_PANIC, "Failed to expand batch_id option "
"in %s transport (%s): %s", tp->name, next->address,
last = next;
batch_count++;
}
- else anchor = &(next->next); /* Skip the address */
+ else anchor = &next->next; /* Skip the address */
}
}
fail them all forthwith. If the expansion fails, or does not yield an
integer, defer delivery. */
- if (tp->message_size_limit != NULL)
+ if (tp->message_size_limit)
{
int rc = check_message_size(tp, addr);
if (rc != OK)
{
replicate_status(addr);
- while (addr != NULL)
+ while (addr)
{
addr2 = addr->next;
post_process_one(addr, rc, logflags, DTYPE_TRANSPORT, 0);
of these checks, rather than for all local deliveries, because some local
deliveries (e.g. to pipes) can take a substantial time. */
- dbm_file = dbfn_open(US"retry", O_RDONLY, &dbblock, FALSE);
- if (dbm_file == NULL)
+ if (!(dbm_file = dbfn_open(US"retry", O_RDONLY, &dbblock, FALSE)))
{
DEBUG(D_deliver|D_retry|D_hints_lookup)
debug_printf("no retry data available\n");
addr2 = addr;
addr3 = NULL;
- while (addr2 != NULL)
+ while (addr2)
{
BOOL ok = TRUE; /* to deliver this address */
uschar *retry_key;
a routing delay. */
retry_key = string_copy(
- (tp->retry_use_local_part)? addr2->address_retry_key :
+ tp->retry_use_local_part ? addr2->address_retry_key :
addr2->domain_retry_key);
*retry_key = 'T';
/* Inspect the retry data. If there is no hints file, delivery happens. */
- if (dbm_file != NULL)
+ if (dbm_file)
{
dbdata_retry *retry_record = dbfn_read(dbm_file, retry_key);
/* If there is no retry record, delivery happens. If there is,
remember it exists so it can be deleted after a successful delivery. */
- if (retry_record != NULL)
+ if (retry_record)
{
setflag(addr2, af_lt_retry_exists);
if (queue_running && !deliver_force)
{
- ok = (now - retry_record->time_stamp > retry_data_expire) ||
- (now >= retry_record->next_try) ||
- retry_record->expired;
+ ok = (now - retry_record->time_stamp > retry_data_expire)
+ || (now >= retry_record->next_try)
+ || retry_record->expired;
/* If we haven't reached the retry time, there is one more check
to do, which is for the ultimate address timeout. */
address_item *this = addr2;
this->message = US"Retry time not yet reached";
this->basic_errno = ERRNO_LRETRY;
- if (addr3 == NULL) addr2 = addr = addr2->next;
- else addr2 = addr3->next = addr2->next;
+ addr2 = addr3 ? (addr3->next = addr2->next)
+ : (addr = addr2->next);
post_process_one(this, DEFER, logflags, DTYPE_TRANSPORT, 0);
}
}
- if (dbm_file != NULL) dbfn_close(dbm_file);
+ if (dbm_file) dbfn_close(dbm_file);
/* If there are no addresses left on the chain, they all deferred. Loop
for the next set of addresses. */
- if (addr == NULL) continue;
+ if (!addr) continue;
+
+ /* If the transport is limited for parallellism, enforce that here.
+ We use a hints DB entry, incremented here and decremented after
+ the transport (and any shadow transport) completes. */
+
+ if (tpt_parallel_check(tp, addr, &serialize_key))
+ {
+ if (expand_string_message)
+ {
+ logflags |= LOG_PANIC;
+ do
+ {
+ addr = addr->next;
+ post_process_one(addr, DEFER, logflags, DTYPE_TRANSPORT, 0);
+ } while ((addr = addr2));
+ }
+ continue; /* Loop for the next set of addresses. */
+ }
+
/* So, finally, we do have some addresses that can be passed to the
transport. Before doing so, set up variables that are relevant to a
NOTE: if the condition fails because of a lookup defer, there is nothing we
can do! */
- if (tp->shadow != NULL &&
- (tp->shadow_condition == NULL ||
- expand_check_condition(tp->shadow_condition, tp->name, US"transport")))
+ if ( tp->shadow
+ && ( !tp->shadow_condition
+ || expand_check_condition(tp->shadow_condition, tp->name, US"transport")
+ ) )
{
transport_instance *stp;
address_item *shadow_addr = NULL;
address_item **last = &shadow_addr;
- for (stp = transports; stp != NULL; stp = stp->next)
+ for (stp = transports; stp; stp = stp->next)
if (Ustrcmp(stp->name, tp->shadow) == 0) break;
- if (stp == NULL)
+ if (!stp)
log_write(0, LOG_MAIN|LOG_PANIC, "shadow transport \"%s\" not found ",
tp->shadow);
the shadow_message field a pointer to the shadow_message field of the real
address. */
- else for (addr2 = addr; addr2 != NULL; addr2 = addr2->next)
- {
- if (addr2->transport_return != OK) continue;
- addr3 = store_get(sizeof(address_item));
- *addr3 = *addr2;
- addr3->next = NULL;
- addr3->shadow_message = (uschar *)(&(addr2->shadow_message));
- addr3->transport = stp;
- addr3->transport_return = DEFER;
- addr3->return_filename = NULL;
- addr3->return_file = -1;
- *last = addr3;
- last = &(addr3->next);
- }
+ else for (addr2 = addr; addr2; addr2 = addr2->next)
+ if (addr2->transport_return == OK)
+ {
+ addr3 = store_get(sizeof(address_item));
+ *addr3 = *addr2;
+ addr3->next = NULL;
+ addr3->shadow_message = (uschar *) &(addr2->shadow_message);
+ addr3->transport = stp;
+ addr3->transport_return = DEFER;
+ addr3->return_filename = NULL;
+ addr3->return_file = -1;
+ *last = addr3;
+ last = &(addr3->next);
+ }
/* If we found any addresses to shadow, run the delivery, and stick any
message back into the shadow_message field in the original. */
- if (shadow_addr != NULL)
+ if (shadow_addr)
{
int save_count = transport_count;
debug_printf(">>>>>>>>>>>>>>>> Shadow delivery >>>>>>>>>>>>>>>>\n");
deliver_local(shadow_addr, TRUE);
- for(; shadow_addr != NULL; shadow_addr = shadow_addr->next)
+ for(; shadow_addr; shadow_addr = shadow_addr->next)
{
int sresult = shadow_addr->transport_return;
- *((uschar **)(shadow_addr->shadow_message)) = (sresult == OK)?
- string_sprintf(" ST=%s", stp->name) :
- string_sprintf(" ST=%s (%s%s%s)", stp->name,
- (shadow_addr->basic_errno <= 0)?
- US"" : US strerror(shadow_addr->basic_errno),
- (shadow_addr->basic_errno <= 0 || shadow_addr->message == NULL)?
- US"" : US": ",
- (shadow_addr->message != NULL)? shadow_addr->message :
- (shadow_addr->basic_errno <= 0)? US"unknown error" : US"");
+ *(uschar **)shadow_addr->shadow_message =
+ sresult == OK
+ ? string_sprintf(" ST=%s", stp->name)
+ : string_sprintf(" ST=%s (%s%s%s)", stp->name,
+ shadow_addr->basic_errno <= 0
+ ? US""
+ : US strerror(shadow_addr->basic_errno),
+ shadow_addr->basic_errno <= 0 || !shadow_addr->message
+ ? US""
+ : US": ",
+ shadow_addr->message
+ ? shadow_addr->message
+ : shadow_addr->basic_errno <= 0
+ ? US"unknown error"
+ : US"");
DEBUG(D_deliver|D_transport)
debug_printf("%s shadow transport returned %s for %s\n",
stp->name,
- (sresult == OK)? "OK" :
- (sresult == DEFER)? "DEFER" :
- (sresult == FAIL)? "FAIL" :
- (sresult == PANIC)? "PANIC" : "?",
+ sresult == OK ? "OK" :
+ sresult == DEFER ? "DEFER" :
+ sresult == FAIL ? "FAIL" :
+ sresult == PANIC ? "PANIC" : "?",
shadow_addr->address);
}
deliver_set_expansions(NULL);
+ /* If the transport was parallelism-limited, decrement the hints DB record. */
+
+ if (serialize_key) enq_end(serialize_key);
+
/* Now we can process the results of the real transport. We must take each
address off the chain first, because post_process_one() puts it on another
chain. */
- for (addr2 = addr; addr2 != NULL; addr2 = nextaddr)
+ for (addr2 = addr; addr2; addr2 = nextaddr)
{
int result = addr2->transport_return;
nextaddr = addr2->next;
DEBUG(D_deliver|D_transport)
debug_printf("%s transport returned %s for %s\n",
tp->name,
- (result == OK)? "OK" :
- (result == DEFER)? "DEFER" :
- (result == FAIL)? "FAIL" :
- (result == PANIC)? "PANIC" : "?",
+ result == OK ? "OK" :
+ result == DEFER ? "DEFER" :
+ result == FAIL ? "FAIL" :
+ result == PANIC ? "PANIC" : "?",
addr2->address);
/* If there is a retry_record, or if delivery is deferred, build a retry
if (result == DEFER || testflag(addr2, af_lt_retry_exists))
{
- int flags = (result == DEFER)? 0 : rf_delete;
- uschar *retry_key = string_copy((tp->retry_use_local_part)?
- addr2->address_retry_key : addr2->domain_retry_key);
+ int flags = result == DEFER ? 0 : rf_delete;
+ uschar *retry_key = string_copy(tp->retry_use_local_part
+ ? addr2->address_retry_key : addr2->domain_retry_key);
*retry_key = 'T';
retry_add_item(addr2, retry_key, flags);
}
if (addr2->transport_return != result)
{
- for (addr3 = nextaddr; addr3 != NULL; addr3 = addr3->next)
+ for (addr3 = nextaddr; addr3; addr3 = addr3->next)
{
addr3->transport_return = addr2->transport_return;
addr3->basic_errno = addr2->basic_errno;
{
int sep = 0;
address_item **aptr = &addr_remote;
-uschar *listptr = remote_sort_domains;
+const uschar *listptr = remote_sort_domains;
uschar *pattern;
uschar patbuf[256];
-while (*aptr != NULL &&
- (pattern = string_nextinlist(&listptr, &sep, patbuf, sizeof(patbuf)))
- != NULL)
+while ( *aptr
+ && (pattern = string_nextinlist(&listptr, &sep, patbuf, sizeof(patbuf)))
+ )
{
address_item *moved = NULL;
address_item **bptr = &moved;
- while (*aptr != NULL)
+ while (*aptr)
{
address_item **next;
deliver_domain = (*aptr)->domain; /* set $domain */
- if (match_isinlist(deliver_domain, &pattern, UCHAR_MAX+1,
+ if (match_isinlist(deliver_domain, (const uschar **)&pattern, UCHAR_MAX+1,
&domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL) == OK)
{
- aptr = &((*aptr)->next);
+ aptr = &(*aptr)->next;
continue;
}
- next = &((*aptr)->next);
- while (*next != NULL &&
- (deliver_domain = (*next)->domain, /* Set $domain */
- match_isinlist(deliver_domain, &pattern, UCHAR_MAX+1,
- &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL)) != OK)
- next = &((*next)->next);
+ next = &(*aptr)->next;
+ while ( *next
+ && (deliver_domain = (*next)->domain, /* Set $domain */
+ match_isinlist(deliver_domain, (const uschar **)&pattern, UCHAR_MAX+1,
+ &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL)) != OK
+ )
+ next = &(*next)->next;
/* If the batch of non-matchers is at the end, add on any that were
extracted further up the chain, and end this iteration. Otherwise,
extract them from the chain and hang on the moved chain. */
- if (*next == NULL)
+ if (!*next)
{
*next = moved;
break;
*aptr = *next;
*next = NULL;
bptr = next;
- aptr = &((*aptr)->next);
+ aptr = &(*aptr)->next;
}
/* If the loop ended because the final address matched, *aptr will
is, there was a string of non-matching addresses at the end. In this
case the extracted addresses have already been added on the end. */
- if (*aptr == NULL) *aptr = moved;
+ if (!*aptr) *aptr = moved;
}
DEBUG(D_deliver)
{
address_item *addr;
debug_printf("remote addresses after sorting:\n");
- for (addr = addr_remote; addr != NULL; addr = addr->next)
+ for (addr = addr_remote; addr; addr = addr->next)
debug_printf(" %s\n", addr->address);
}
}
/* copy and read header */
memcpy(header, ptr, PIPE_HEADER_SIZE);
- header[PIPE_HEADER_SIZE] = '\0';
+ header[PIPE_HEADER_SIZE] = '\0';
id = header[0];
subid = header[1];
required = Ustrtol(header + 2, &endc, 10) + PIPE_HEADER_SIZE; /* header + data */
}
DEBUG(D_deliver)
- debug_printf("header read id:%c,subid:%c,size:%s,required:%d,remaining:%d,unfinished:%d\n",
+ debug_printf("header read id:%c,subid:%c,size:%s,required:%d,remaining:%d,unfinished:%d\n",
id, subid, header+2, required, remaining, unfinished);
/* is there room for the dataset we want to read ? */
break;
}
- /* we wrote all datasets with atomic write() calls
+ /* we wrote all datasets with atomic write() calls
remaining < required only happens if big_buffer was too small
- to get all available data from pipe. unfinished has to be true
+ to get all available data from pipe. unfinished has to be true
as well. */
if (remaining < required)
{
if (unfinished)
continue;
msg = string_sprintf("failed to read pipe from transport process "
- "%d for transport %s: required size=%d > remaining size=%d and unfinished=false",
+ "%d for transport %s: required size=%d > remaining size=%d and unfinished=false",
pid, addr->transport->driver_name, required, remaining);
done = TRUE;
break;
/* step behind the header */
ptr += PIPE_HEADER_SIZE;
-
+
/* Handle each possible type of item, assuming the complete item is
available in store. */
up by checking the IP address. */
case 'H':
- for (h = addrlist->host_list; h != NULL; h = h->next)
+ for (h = addrlist->host_list; h; h = h->next)
{
- if (h->address == NULL || Ustrcmp(h->address, ptr+2) != 0) continue;
+ if (!h->address || Ustrcmp(h->address, ptr+2) != 0) continue;
h->status = ptr[0];
h->why = ptr[1];
}
that a "delete" item is dropped in favour of an "add" item. */
case 'R':
- if (addr == NULL) goto ADDR_MISMATCH;
+ if (!addr) goto ADDR_MISMATCH;
DEBUG(D_deliver|D_retry)
debug_printf("reading retry information for %s from subprocess\n",
/* Cut out any "delete" items on the list. */
- for (rp = &(addr->retries); (r = *rp) != NULL; rp = &(r->next))
- {
+ for (rp = &(addr->retries); (r = *rp); rp = &r->next)
if (Ustrcmp(r->key, ptr+1) == 0) /* Found item with same key */
{
if ((r->flags & rf_delete) == 0) break; /* It was not "delete" */
DEBUG(D_deliver|D_retry)
debug_printf(" existing delete item dropped\n");
}
- }
/* We want to add a delete item only if there is no non-delete item;
however we still have to step ptr through the data. */
- if (r == NULL || (*ptr & rf_delete) == 0)
+ if (!r || (*ptr & rf_delete) == 0)
{
r = store_get(sizeof(retry_item));
r->next = addr->retries;
#ifdef SUPPORT_TLS
case 'X':
- if (addr == NULL) goto ADDR_MISMATCH; /* Below, in 'A' handler */
+ if (!addr) goto ADDR_MISMATCH; /* Below, in 'A' handler */
switch (subid)
{
case '1':
break;
case '2':
- addr->peercert = NULL;
if (*ptr)
(void) tls_import_cert(ptr, &addr->peercert);
+ else
+ addr->peercert = NULL;
break;
case '3':
- addr->ourcert = NULL;
if (*ptr)
(void) tls_import_cert(ptr, &addr->ourcert);
+ else
+ addr->ourcert = NULL;
break;
# ifndef DISABLE_OCSP
#endif
case 'D':
- if (addr == NULL) goto ADDR_MISMATCH;
+ if (!addr) goto ADDR_MISMATCH;
memcpy(&(addr->dsn_aware), ptr, sizeof(addr->dsn_aware));
ptr += sizeof(addr->dsn_aware);
DEBUG(D_deliver) debug_printf("DSN read: addr->dsn_aware = %d\n", addr->dsn_aware);
break;
case 'A':
- if (addr == NULL)
+ if (!addr)
{
ADDR_MISMATCH:
msg = string_sprintf("address count mismatch for data read from pipe "
break;
}
- addr->transport_return = *ptr++;
- addr->special_action = *ptr++;
- memcpy(&(addr->basic_errno), ptr, sizeof(addr->basic_errno));
- ptr += sizeof(addr->basic_errno);
- memcpy(&(addr->more_errno), ptr, sizeof(addr->more_errno));
- ptr += sizeof(addr->more_errno);
- memcpy(&(addr->flags), ptr, sizeof(addr->flags));
- ptr += sizeof(addr->flags);
- addr->message = (*ptr)? string_copy(ptr) : NULL;
- while(*ptr++);
- addr->user_message = (*ptr)? string_copy(ptr) : NULL;
- while(*ptr++);
+ switch (subid)
+ {
+#ifdef SUPPORT_SOCKS
+ case '2': /* proxy information; must arrive before A0 and applies to that addr XXX oops*/
+ proxy_session = TRUE; /*XXX shouod this be cleared somewhere? */
+ if (*ptr == 0)
+ ptr++;
+ else
+ {
+ proxy_local_address = string_copy(ptr);
+ while(*ptr++);
+ memcpy(&proxy_local_port, ptr, sizeof(proxy_local_port));
+ ptr += sizeof(proxy_local_port);
+ }
+ break;
+#endif
- /* Always two strings for host information, followed by the port number and DNSSEC mark */
+#ifdef EXPERIMENTAL_DSN_INFO
+ case '1': /* must arrive before A0, and applies to that addr */
+ /* Two strings: smtp_greeting and helo_response */
+ addr->smtp_greeting = string_copy(ptr);
+ while(*ptr++);
+ addr->helo_response = string_copy(ptr);
+ while(*ptr++);
+ break;
+#endif
- if (*ptr != 0)
- {
- h = store_get(sizeof(host_item));
- h->name = string_copy(ptr);
- while (*ptr++);
- h->address = string_copy(ptr);
- while(*ptr++);
- memcpy(&(h->port), ptr, sizeof(h->port));
- ptr += sizeof(h->port);
- h->dnssec = *ptr == '2' ? DS_YES
- : *ptr == '1' ? DS_NO
- : DS_UNK;
- ptr++;
- addr->host_used = h;
- }
- else ptr++;
+ case '0':
+ addr->transport_return = *ptr++;
+ addr->special_action = *ptr++;
+ memcpy(&(addr->basic_errno), ptr, sizeof(addr->basic_errno));
+ ptr += sizeof(addr->basic_errno);
+ memcpy(&(addr->more_errno), ptr, sizeof(addr->more_errno));
+ ptr += sizeof(addr->more_errno);
+ memcpy(&(addr->flags), ptr, sizeof(addr->flags));
+ ptr += sizeof(addr->flags);
+ addr->message = (*ptr)? string_copy(ptr) : NULL;
+ while(*ptr++);
+ addr->user_message = (*ptr)? string_copy(ptr) : NULL;
+ while(*ptr++);
- /* Finished with this address */
+ /* Always two strings for host information, followed by the port number and DNSSEC mark */
- addr = addr->next;
+ if (*ptr != 0)
+ {
+ h = store_get(sizeof(host_item));
+ h->name = string_copy(ptr);
+ while (*ptr++);
+ h->address = string_copy(ptr);
+ while(*ptr++);
+ memcpy(&(h->port), ptr, sizeof(h->port));
+ ptr += sizeof(h->port);
+ h->dnssec = *ptr == '2' ? DS_YES
+ : *ptr == '1' ? DS_NO
+ : DS_UNK;
+ ptr++;
+ addr->host_used = h;
+ }
+ else ptr++;
+
+ /* Finished with this address */
+
+ addr = addr->next;
+ break;
+ }
+ break;
+
+ /* Local interface address/port */
+ case 'I':
+ if (*ptr) sending_ip_address = string_copy(ptr);
+ while (*ptr++) ;
+ if (*ptr) sending_port = atoi(CS ptr);
+ while (*ptr++) ;
break;
/* Z marks the logical end of the data. It is followed by '0' if
/* If we have finished without error, but haven't had data for every address,
something is wrong. */
-if (msg == NULL && addr != NULL)
+if (!msg && addr)
msg = string_sprintf("insufficient address data read from pipe "
"for transport process %d for transport %s", pid,
addr->transport->driver_name);
/* If an error message is set, something has gone wrong in getting back
the delivery data. Put the message into each address and freeze it. */
-if (msg != NULL)
- {
- for (addr = addrlist; addr != NULL; addr = addr->next)
+if (msg)
+ for (addr = addrlist; addr; addr = addr->next)
{
addr->transport_return = DEFER;
addr->special_action = SPECIAL_FREEZE;
addr->message = msg;
}
- }
/* Return TRUE to indicate we have got all we need from this process, even
if it hasn't actually finished yet. */
/* If any host addresses were found to be unusable, add them to the unusable
tree so that subsequent deliveries don't try them. */
-for (h = addr->host_list; h != NULL; h = h->next)
- {
- if (h->address == NULL) continue;
- if (h->status >= hstatus_unusable) tree_add_unusable(h);
- }
+for (h = addr->host_list; h; h = h->next)
+ if (h->address)
+ if (h->status >= hstatus_unusable) tree_add_unusable(h);
/* Now handle each address on the chain. The transport has placed '=' or '-'
into the special_action field for each successful delivery. */
-while (addr != NULL)
+while (addr)
{
address_item *next = addr->next;
processing the main hosts and there are fallback hosts available, put the
address on the list for fallback delivery. */
- if (addr->transport_return == DEFER &&
- addr->fallback_hosts != NULL &&
- !fallback &&
- msg == NULL)
+ if ( addr->transport_return == DEFER
+ && addr->fallback_hosts
+ && !fallback
+ && !msg
+ )
{
addr->host_list = addr->fallback_hosts;
addr->next = addr_fallback;
else
{
- if (msg != NULL)
+ if (msg)
{
addr->message = msg;
addr->transport_return = DEFER;
we have logged that delivery, set continue_sequence to 1 so that
any subsequent deliveries don't get "*" incorrectly logged. */
-if (continue_transport == NULL) continue_sequence = 1;
+if (!continue_transport) continue_sequence = 1;
}
readycount > 0 && poffset < remote_max_parallel;
poffset++)
{
- if ((pid = parlist[poffset].pid) != 0 &&
- FD_ISSET(parlist[poffset].fd, &select_pipes))
+ if ( (pid = parlist[poffset].pid) != 0
+ && FD_ISSET(parlist[poffset].fd, &select_pipes)
+ )
{
readycount--;
if (par_read_pipe(poffset, FALSE)) /* Finished with this pipe */
if (msb != 0 || (code != SIGTERM && code != SIGKILL && code != SIGQUIT))
addrlist->special_action = SPECIAL_FREEZE;
- for (addr = addrlist; addr != NULL; addr = addr->next)
+ for (addr = addrlist; addr; addr = addr->next)
{
addr->transport_return = DEFER;
addr->message = msg;
while (parcount > max)
{
address_item *doneaddr = par_wait();
- if (doneaddr == NULL)
+ if (!doneaddr)
{
log_write(0, LOG_MAIN|LOG_PANIC,
"remote delivery process count got out of step");
parcount = 0;
}
- else remote_post_process(doneaddr, LOG_MAIN, NULL, fallback);
+ else
+ {
+ transport_instance * tp = doneaddr->transport;
+ if (tp->max_parallel)
+ enq_end(string_sprintf("tpt-serialize-%s", tp->name));
+
+ remote_post_process(doneaddr, LOG_MAIN, NULL, fallback);
+ }
}
}
/* complain to log if someone tries with buffer sizes we can't handle*/
if (size > 99999)
-{
- log_write(0, LOG_MAIN|LOG_PANIC_DIE,
+ {
+ log_write(0, LOG_MAIN|LOG_PANIC_DIE,
"Failed writing transport result to pipe: can't handle buffers > 99999 bytes. truncating!\n");
size = 99999;
-}
+ }
/* to keep the write() atomic we build header in writebuffer and copy buf behind */
/* two write() calls would increase the complexity of reading from pipe */
/* convert size to human readable string prepended by id and subid */
header_length = snprintf(CS writebuffer, PIPE_HEADER_SIZE+1, "%c%c%05d", id, subid, size);
if (header_length != PIPE_HEADER_SIZE)
-{
+ {
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "header snprintf failed\n");
writebuffer[0] = '\0';
-}
+ }
-DEBUG(D_deliver) debug_printf("header write id:%c,subid:%c,size:%d,final:%s\n",
+DEBUG(D_deliver) debug_printf("header write id:%c,subid:%c,size:%d,final:%s\n",
id, subid, size, writebuffer);
if (buf && size > 0)
We use a local variable (parmax) to hold the maximum number of processes;
this gets reduced from remote_max_parallel if we can't create enough pipes. */
-if (continue_transport != NULL) remote_max_parallel = 1;
+if (continue_transport) remote_max_parallel = 1;
parmax = remote_max_parallel;
/* If the data for keeping a list of processes hasn't yet been
set up, do so. */
-if (parlist == NULL)
+if (!parlist)
{
parlist = store_get(remote_max_parallel * sizeof(pardata));
for (poffset = 0; poffset < remote_max_parallel; poffset++)
/* Now loop for each remote delivery */
-for (delivery_count = 0; addr_remote != NULL; delivery_count++)
+for (delivery_count = 0; addr_remote; delivery_count++)
{
pid_t pid;
uid_t uid;
address_item *addr = addr_remote;
address_item *last = addr;
address_item *next;
+ uschar * panicmsg;
+ uschar * serialize_key = NULL;
/* Pull the first address right off the list. */
/* If no transport has been set, there has been a big screw-up somewhere. */
- if ((tp = addr->transport) == NULL)
+ if (!(tp = addr->transport))
{
disable_logging = FALSE; /* Jic */
- remote_post_process(addr, LOG_MAIN|LOG_PANIC,
- US"No transport set by router", fallback);
- continue;
+ panicmsg = US"No transport set by router";
+ goto panic_continue;
}
/* Check that this base address hasn't previously been delivered to this
/* Force failure if the message is too big. */
- if (tp->message_size_limit != NULL)
+ if (tp->message_size_limit)
{
int rc = check_message_size(tp, addr);
if (rc != OK)
&multi_domain) != OK)
{
deliver_set_expansions(NULL);
- remote_post_process(addr, LOG_MAIN|LOG_PANIC, addr->message, fallback);
- continue;
+ panicmsg = addr->message;
+ goto panic_continue;
}
/* Get the maximum it can handle in one envelope, with zero meaning
the use of these variables, but as it is so likely they will be used when the
maximum is 1, we don't bother. Just leave the value alone. */
- if (address_count_max != 1 &&
- address_count_max < remote_delivery_count/remote_max_parallel)
+ if ( address_count_max != 1
+ && address_count_max < remote_delivery_count/remote_max_parallel
+ )
{
int new_max = remote_delivery_count/remote_max_parallel;
int message_max = tp->connection_max_messages;
and if it might need a per-address check for this, re-evaluate it.
*/
- while ((next = *anchor) != NULL && address_count < address_count_max)
+ while ((next = *anchor) && address_count < address_count_max)
{
BOOL md;
if ( (multi_domain || Ustrcmp(next->domain, addr->domain) == 0)
&& tp == next->transport
&& same_hosts(next->host_list, addr->host_list)
- && same_strings(next->p.errors_address, addr->p.errors_address)
- && same_headers(next->p.extra_headers, addr->p.extra_headers)
+ && same_strings(next->prop.errors_address, addr->prop.errors_address)
+ && same_headers(next->prop.extra_headers, addr->prop.extra_headers)
&& same_ugid(tp, next, addr)
- && ( next->p.remove_headers == addr->p.remove_headers
- || ( next->p.remove_headers != NULL
- && addr->p.remove_headers != NULL
- && Ustrcmp(next->p.remove_headers, addr->p.remove_headers) == 0
+ && ( next->prop.remove_headers == addr->prop.remove_headers
+ || ( next->prop.remove_headers
+ && addr->prop.remove_headers
+ && Ustrcmp(next->prop.remove_headers, addr->prop.remove_headers) == 0
) )
&& ( !multi_domain
|| ( (
/* If we are acting as an MUA wrapper, all addresses must go in a single
transaction. If not, put them back on the chain and yield FALSE. */
- if (mua_wrapper && addr_remote != NULL)
+ if (mua_wrapper && addr_remote)
{
last->next = addr_remote;
addr_remote = addr;
return FALSE;
}
+ /* If the transport is limited for parallellism, enforce that here.
+ The hints DB entry is decremented in par_reduce(), when we reap the
+ transport process. */
+
+ if (tpt_parallel_check(tp, addr, &serialize_key))
+ if ((panicmsg = expand_string_message))
+ goto panic_continue;
+ else
+ continue; /* Loop for the next set of addresses. */
+
/* Set up the expansion variables for this set of addresses */
deliver_set_expansions(addr);
/* Compute the return path, expanding a new one if required. The old one
must be set first, as it might be referred to in the expansion. */
- if(addr->p.errors_address != NULL)
- return_path = addr->p.errors_address;
+ if(addr->prop.errors_address)
+ return_path = addr->prop.errors_address;
#ifdef EXPERIMENTAL_SRS
- else if(addr->p.srs_sender != NULL)
- return_path = addr->p.srs_sender;
+ else if(addr->prop.srs_sender)
+ return_path = addr->prop.srs_sender;
#endif
else
return_path = sender_address;
- if (tp->return_path != NULL)
+ if (tp->return_path)
{
uschar *new_return_path = expand_string(tp->return_path);
- if (new_return_path == NULL)
+ if (new_return_path)
+ return_path = new_return_path;
+ else if (!expand_string_forcedfail)
{
- if (!expand_string_forcedfail)
- {
- remote_post_process(addr, LOG_MAIN|LOG_PANIC,
- string_sprintf("Failed to expand return path \"%s\": %s",
- tp->return_path, expand_string_message), fallback);
- continue;
- }
+ panicmsg = string_sprintf("Failed to expand return path \"%s\": %s",
+ tp->return_path, expand_string_message);
+ goto enq_continue;
}
- else return_path = new_return_path;
}
/* Find the uid, gid, and use_initgroups setting for this transport. Failure
if (!findugid(addr, tp, &uid, &gid, &use_initgroups))
{
- remote_post_process(addr, LOG_MAIN|LOG_PANIC, NULL, fallback);
- continue;
+ panicmsg = NULL;
+ goto enq_continue;
}
/* If this transport has a setup function, call it now so that it gets
That is why it is called at this point, before the continue delivery
processing, because that might use the fallback hosts. */
- if (tp->setup != NULL)
+ if (tp->setup)
(void)((tp->setup)(addr->transport, addr, NULL, uid, gid, NULL));
/* If this is a run to continue delivery down an already-established
host is set in the transport. */
continue_more = FALSE; /* In case got set for the last lot */
- if (continue_transport != NULL)
+ if (continue_transport)
{
BOOL ok = Ustrcmp(continue_transport, tp->name) == 0;
- if (ok && addr->host_list != NULL)
+ if (ok && addr->host_list)
{
host_item *h;
ok = FALSE;
- for (h = addr->host_list; h != NULL; h = h->next)
- {
+ for (h = addr->host_list; h; h = h->next)
if (Ustrcmp(h->name, continue_hostname) == 0)
{ ok = TRUE; break; }
- }
}
/* Addresses not suitable; defer or queue for fallback hosts (which
if (!ok)
{
DEBUG(D_deliver) debug_printf("not suitable for continue_transport\n");
- next = addr;
+ if (serialize_key) enq_end(serialize_key);
- if (addr->fallback_hosts != NULL && !fallback)
+ if (addr->fallback_hosts && !fallback)
{
- for (;;)
+ for (next = addr; ; next = next->next)
{
next->host_list = next->fallback_hosts;
DEBUG(D_deliver) debug_printf("%s queued for fallback host(s)\n", next->address);
- if (next->next == NULL) break;
- next = next->next;
+ if (!next->next) break;
}
next->next = addr_fallback;
addr_fallback = addr;
}
else
- {
- while (next->next != NULL) next = next->next;
- next->next = addr_defer;
- addr_defer = addr;
- }
+ {
+ while (next->next) next = next->next;
+ next->next = addr_defer;
+ addr_defer = addr;
+ }
continue;
}
the continued host. This tells the transport to leave the channel open,
but not to pass it to another delivery process. */
- for (next = addr_remote; next != NULL; next = next->next)
+ for (next = addr_remote; next; next = next->next)
{
host_item *h;
- for (h = next->host_list; h != NULL; h = h->next)
- {
+ for (h = next->host_list; h; h = h->next)
if (Ustrcmp(h->name, continue_hostname) == 0)
{ continue_more = TRUE; break; }
- }
}
}
if (!pipe_done)
{
- remote_post_process(addr, LOG_MAIN|LOG_PANIC,
- string_sprintf("unable to create pipe: %s", strerror(errno)), fallback);
- continue;
+ panicmsg = string_sprintf("unable to create pipe: %s", strerror(errno));
+ goto enq_continue;
}
/* Find a free slot in the pardata list. Must do this after the possible
up a slot. */
for (poffset = 0; poffset < remote_max_parallel; poffset++)
- if (parlist[poffset].pid == 0) break;
+ if (parlist[poffset].pid == 0)
+ break;
/* If there isn't one, there has been a horrible disaster. */
{
(void)close(pfd[pipe_write]);
(void)close(pfd[pipe_read]);
- remote_post_process(addr, LOG_MAIN|LOG_PANIC,
- US"Unexpectedly no free subprocess slot", fallback);
- continue;
+ panicmsg = US"Unexpectedly no free subprocess slot";
+ goto enq_continue;
}
/* Now fork a subprocess to do the remote delivery, but before doing so,
/* Show pids on debug output if parallelism possible */
- if (parmax > 1 && (parcount > 0 || addr_remote != NULL))
+ if (parmax > 1 && (parcount > 0 || addr_remote))
{
DEBUG(D_any|D_v) debug_selector |= D_pid;
DEBUG(D_deliver) debug_printf("Remote delivery process started\n");
if (!(tp->info->code)(addr->transport, addr)) replicate_status(addr);
set_process_info("delivering %s (just run %s for %s%s in subprocess)",
- message_id, tp->name, addr->address, (addr->next == NULL)? "" : ", ...");
+ message_id, tp->name, addr->address, addr->next ? ", ..." : "");
/* Ensure any cached resources that we used are now released */
/* Host unusability information: for most success cases this will
be null. */
- for (h = addr->host_list; h != NULL; h = h->next)
+ for (h = addr->host_list; h; h = h->next)
{
- if (h->address == NULL || h->status < hstatus_unusable) continue;
+ if (!h->address || h->status < hstatus_unusable) continue;
sprintf(CS big_buffer, "%c%c%s", h->status, h->why, h->address);
rmt_dlv_checked_write(fd, 'H', '0', big_buffer, Ustrlen(big_buffer+2) + 3);
}
item for any client-auth info followed by 'R' items for any retry settings,
and finally an 'A' item for the remaining data. */
- for(; addr != NULL; addr = addr->next)
+ for(; addr; addr = addr->next)
{
uschar *ptr;
retry_item *r;
#ifdef SUPPORT_TLS
if (addr->cipher)
{
- ptr = big_buffer;
- sprintf(CS ptr, "%.128s", addr->cipher);
- while(*ptr++);
+ ptr = big_buffer + sprintf(CS big_buffer, "%.128s", addr->cipher) + 1;
if (!addr->peerdn)
*ptr++ = 0;
else
{
- sprintf(CS ptr, "%.512s", addr->peerdn);
- while(*ptr++);
+ ptr += sprintf(CS ptr, "%.512s", addr->peerdn);
+ ptr++;
}
rmt_dlv_checked_write(fd, 'X', '1', big_buffer, ptr - big_buffer);
# ifndef DISABLE_OCSP
if (addr->ocsp > OCSP_NOT_REQ)
{
- ptr = big_buffer;
- sprintf(CS ptr, "%c", addr->ocsp + '0');
- while(*ptr++);
+ ptr = big_buffer + sprintf(CS big_buffer, "%c", addr->ocsp + '0') + 1;
rmt_dlv_checked_write(fd, 'X', '4', big_buffer, ptr - big_buffer);
}
# endif
if (client_authenticator)
{
- ptr = big_buffer;
- sprintf(CS big_buffer, "%.64s", client_authenticator);
- while(*ptr++);
+ ptr = big_buffer + sprintf(CS big_buffer, "%.64s", client_authenticator) + 1;
rmt_dlv_checked_write(fd, 'C', '1', big_buffer, ptr - big_buffer);
}
if (client_authenticated_id)
{
- ptr = big_buffer;
- sprintf(CS big_buffer, "%.64s", client_authenticated_id);
- while(*ptr++);
+ ptr = big_buffer + sprintf(CS big_buffer, "%.64s", client_authenticated_id) + 1;
rmt_dlv_checked_write(fd, 'C', '2', big_buffer, ptr - big_buffer);
}
if (client_authenticated_sender)
{
- ptr = big_buffer;
- sprintf(CS big_buffer, "%.64s", client_authenticated_sender);
- while(*ptr++);
+ ptr = big_buffer + sprintf(CS big_buffer, "%.64s", client_authenticated_sender) + 1;
rmt_dlv_checked_write(fd, 'C', '3', big_buffer, ptr - big_buffer);
}
/* Retry information: for most success cases this will be null. */
- for (r = addr->retries; r != NULL; r = r->next)
+ for (r = addr->retries; r; r = r->next)
{
- uschar *ptr;
sprintf(CS big_buffer, "%c%.500s", r->flags, r->key);
ptr = big_buffer + Ustrlen(big_buffer+2) + 3;
memcpy(ptr, &(r->basic_errno), sizeof(r->basic_errno));
ptr += sizeof(r->basic_errno);
memcpy(ptr, &(r->more_errno), sizeof(r->more_errno));
ptr += sizeof(r->more_errno);
- if (r->message == NULL) *ptr++ = 0; else
+ if (!r->message) *ptr++ = 0; else
{
sprintf(CS ptr, "%.512s", r->message);
while(*ptr++);
rmt_dlv_checked_write(fd, 'R', '0', big_buffer, ptr - big_buffer);
}
- /* The rest of the information goes in an 'A' item. */
+#ifdef SUPPORT_SOCKS
+ if (LOGGING(proxy) && proxy_session)
+ {
+ ptr = big_buffer;
+ if (proxy_local_address)
+ {
+ DEBUG(D_deliver) debug_printf("proxy_local_address '%s'\n", proxy_local_address);
+ ptr = big_buffer + sprintf(CS ptr, "%.128s", proxy_local_address) + 1;
+ DEBUG(D_deliver) debug_printf("proxy_local_port %d\n", proxy_local_port);
+ memcpy(ptr, &proxy_local_port, sizeof(proxy_local_port));
+ ptr += sizeof(proxy_local_port);
+ }
+ else
+ *ptr++ = '\0';
+ rmt_dlv_checked_write(fd, 'A', '2', big_buffer, ptr - big_buffer);
+ }
+#endif
+#ifdef EXPERIMENTAL_DSN_INFO
+/*um, are they really per-addr? Other per-conn stuff is not (auth, tls). But host_used is! */
+ if (addr->smtp_greeting)
+ {
+ DEBUG(D_deliver) debug_printf("smtp_greeting '%s'\n", addr->smtp_greeting);
+ ptr = big_buffer + sprintf(CS big_buffer, "%.128s", addr->smtp_greeting) + 1;
+ if (addr->helo_response)
+ {
+ DEBUG(D_deliver) debug_printf("helo_response '%s'\n", addr->helo_response);
+ ptr += sprintf(CS ptr, "%.128s", addr->helo_response) + 1;
+ }
+ else
+ *ptr++ = '\0';
+ rmt_dlv_checked_write(fd, 'A', '1', big_buffer, ptr - big_buffer);
+ }
+#endif
+
+ /* The rest of the information goes in an 'A0' item. */
+
+ sprintf(CS big_buffer, "%c%c", addr->transport_return, addr->special_action);
ptr = big_buffer + 2;
- sprintf(CS big_buffer, "%c%c", addr->transport_return,
- addr->special_action);
memcpy(ptr, &(addr->basic_errno), sizeof(addr->basic_errno));
ptr += sizeof(addr->basic_errno);
memcpy(ptr, &(addr->more_errno), sizeof(addr->more_errno));
memcpy(ptr, &(addr->flags), sizeof(addr->flags));
ptr += sizeof(addr->flags);
- if (addr->message == NULL) *ptr++ = 0; else
- {
- sprintf(CS ptr, "%.1024s", addr->message);
- while(*ptr++);
- }
+ if (!addr->message) *ptr++ = 0; else
+ ptr += sprintf(CS ptr, "%.1024s", addr->message) + 1;
- if (addr->user_message == NULL) *ptr++ = 0; else
- {
- sprintf(CS ptr, "%.1024s", addr->user_message);
- while(*ptr++);
- }
+ if (!addr->user_message) *ptr++ = 0; else
+ ptr += sprintf(CS ptr, "%.1024s", addr->user_message) + 1;
- if (addr->host_used == NULL) *ptr++ = 0; else
+ if (!addr->host_used) *ptr++ = 0; else
{
- sprintf(CS ptr, "%.256s", addr->host_used->name);
- while(*ptr++);
- sprintf(CS ptr, "%.64s", addr->host_used->address);
- while(*ptr++);
+ ptr += sprintf(CS ptr, "%.256s", addr->host_used->name) + 1;
+ ptr += sprintf(CS ptr, "%.64s", addr->host_used->address) + 1;
memcpy(ptr, &(addr->host_used->port), sizeof(addr->host_used->port));
ptr += sizeof(addr->host_used->port);
rmt_dlv_checked_write(fd, 'A', '0', big_buffer, ptr - big_buffer);
}
+ /* Local interface address/port */
+#ifdef EXPERIMENTAL_DSN_INFO
+ if (sending_ip_address)
+#else
+ if (LOGGING(incoming_interface) && sending_ip_address)
+#endif
+ {
+ uschar * ptr;
+ ptr = big_buffer + sprintf(CS big_buffer, "%.128s", sending_ip_address) + 1;
+ ptr += sprintf(CS ptr, "%d", sending_port) + 1;
+ rmt_dlv_checked_write(fd, 'I', '0', big_buffer, ptr - big_buffer);
+ }
+
/* Add termination flag, close the pipe, and that's it. The character
after 'Z' indicates whether continue_transport is now NULL or not.
A change from non-NULL to NULL indicates a problem with a continuing
connection. */
- big_buffer[0] = (continue_transport == NULL)? '0' : '1';
+ big_buffer[0] = continue_transport ? '1' : '0';
rmt_dlv_checked_write(fd, 'Z', '0', big_buffer, 1);
(void)close(fd);
exit(EXIT_SUCCESS);
if (pid < 0)
{
(void)close(pfd[pipe_read]);
- remote_post_process(addr, LOG_MAIN|LOG_PANIC,
- string_sprintf("fork failed for remote delivery to %s: %s",
- addr->domain, strerror(errno)), fallback);
- continue;
+ panicmsg = string_sprintf("fork failed for remote delivery to %s: %s",
+ addr->domain, strerror(errno));
+ goto enq_continue;
}
/* Fork succeeded; increment the count, and remember relevant data for
(continue_transport gets set to NULL) before we consider any other addresses
in this message. */
- if (continue_transport != NULL) par_reduce(0, fallback);
+ if (continue_transport) par_reduce(0, fallback);
/* Otherwise, if we are running in the test harness, wait a bit, to let the
newly created process get going before we create another process. This should
ensure repeatability in the tests. We only need to wait a tad. */
else if (running_in_test_harness) millisleep(500);
+
+ continue;
+
+enq_continue:
+ if (serialize_key) enq_end(serialize_key);
+panic_continue:
+ remote_post_process(addr, LOG_MAIN|LOG_PANIC, panicmsg, fallback);
+ continue;
}
/* Reached the end of the list of addresses. Wait for all the subprocesses that
/* We do the percent hack only for those domains that are listed in
percent_hack_domains. A loop is required, to copy with multiple %-hacks. */
-if (percent_hack_domains != NULL)
+if (percent_hack_domains)
{
int rc;
uschar *new_address = NULL;
deliver_domain = addr->domain; /* set $domain */
- while ((rc = match_isinlist(deliver_domain, &percent_hack_domains, 0,
- &domainlist_anchor, addr->domain_cache, MCL_DOMAIN, TRUE, NULL))
- == OK &&
- (t = Ustrrchr(local_part, '%')) != NULL)
+ while ( (rc = match_isinlist(deliver_domain, (const uschar **)&percent_hack_domains, 0,
+ &domainlist_anchor, addr->domain_cache, MCL_DOMAIN, TRUE, NULL))
+ == OK
+ && (t = Ustrrchr(local_part, '%')) != NULL
+ )
{
new_address = string_copy(local_part);
new_address[t - local_part] = '@';
/* If hackery happened, set up new parent and alter the current address. */
- if (new_address != NULL)
+ if (new_address)
{
address_item *new_parent = store_get(sizeof(address_item));
*new_parent = *addr;
uschar *para, *yield;
uschar buffer[256];
-if (f == NULL) return NULL;
+if (!f) return NULL;
-if (Ufgets(buffer, sizeof(buffer), f) == NULL ||
- Ustrcmp(buffer, "****\n") == 0) return NULL;
+if (!Ufgets(buffer, sizeof(buffer), f) || Ustrcmp(buffer, "****\n") == 0)
+ return NULL;
para = store_get(size);
for (;;)
{
para = string_cat(para, &size, &ptr, buffer, Ustrlen(buffer));
- if (Ufgets(buffer, sizeof(buffer), f) == NULL ||
- Ustrcmp(buffer, "****\n") == 0) break;
+ if (!Ufgets(buffer, sizeof(buffer), f) || Ustrcmp(buffer, "****\n") == 0)
+ break;
}
para[ptr] = 0;
-yield = expand_string(para);
-if (yield != NULL) return yield;
+if ((yield = expand_string(para)))
+ return yield;
log_write(0, LOG_MAIN|LOG_PANIC, "Failed to expand string from "
"bounce_message_file or warn_message_file (%s): %s", which,
static int
continue_closedown(void)
{
-if (continue_transport != NULL)
+if (continue_transport)
{
transport_instance *t;
- for (t = transports; t != NULL; t = t->next)
- {
+ for (t = transports; t; t = t->next)
if (Ustrcmp(t->name, continue_transport) == 0)
{
- if (t->info->closedown != NULL) (t->info->closedown)(t);
+ if (t->info->closedown) (t->info->closedown)(t);
break;
}
- }
}
return DELIVER_NOT_ATTEMPTED;
}
BOOL yield = TRUE;
uschar *printed = US"";
address_item *ancestor = addr;
-while (ancestor->parent != NULL) ancestor = ancestor->parent;
+while (ancestor->parent) ancestor = ancestor->parent;
fprintf(f, "%s", CS si);
-if (addr->parent != NULL && testflag(addr, af_hide_child))
+if (addr->parent && testflag(addr, af_hide_child))
{
printed = US"an undisclosed address";
yield = FALSE;
}
-else if (!testflag(addr, af_pfr) || addr->parent == NULL)
+else if (!testflag(addr, af_pfr) || !addr->parent)
printed = addr->address;
else
if (ancestor != addr)
{
- uschar *original = (ancestor->onetime_parent == NULL)?
- ancestor->address : ancestor->onetime_parent;
+ uschar *original = ancestor->onetime_parent;
+ if (!original) original= ancestor->address;
if (strcmpic(original, printed) != 0)
fprintf(f, "%s(%sgenerated from %s)", sc,
- (ancestor != addr->parent)? "ultimately " : "",
+ ancestor != addr->parent ? "ultimately " : "",
string_printing(original));
}
int count = Ustrlen(t);
uschar *s = testflag(addr, af_pass_message)? addr->message : NULL;
-if (s == NULL)
- {
- if (addr->user_message != NULL) s = addr->user_message; else return;
- }
+if (!s && !(s = addr->user_message))
+ return;
fprintf(f, "\n %s", t);
-while (*s != 0)
- {
+while (*s)
if (*s == '\\' && s[1] == 'n')
{
fprintf(f, "\n ");
count = 0;
}
}
- }
}
a bounce or a warning message. It tries to format the message reasonably as
required by RFC 3461 by adding a space after each newline
-we assume that this function is only called if addr->host_used is set and if so
-a useable addr->message is available containing some Exim description with ": \n"
-ending, followed by the L/SMTP error message.
+it uses the same logic as print_address_error() above. if af_pass_message is true
+and addr->message is set it uses the remote host answer. if not addr->user_message
+is used instead if available.
Arguments:
addr the address
static void
print_dsn_diagnostic_code(const address_item *addr, FILE *f)
{
-uschar * s;
-
-/* check host_used, af_pass_message flag and addr->message for safety reasons */
-if (!addr->host_used && testflag(addr, af_pass_message) && addr->message)
- return;
+uschar *s = testflag(addr, af_pass_message) ? addr->message : NULL;
-/* search first ": ". we assume to find the remote-MTA answer there */
-DEBUG(D_deliver)
- debug_printf("DSN Diagnostic-Code: addr->dsn_message = %s\n", addr->message);
-if (!(s = Ustrstr(addr->message, ": ")))
- return; /* not found, bail out */
+/* af_pass_message and addr->message set ? print remote host answer */
+if (s)
+ {
+ DEBUG(D_deliver)
+ debug_printf("DSN Diagnostic-Code: addr->message = %s\n", addr->message);
-fprintf(f, "Diagnostic-Code: smtp; ");
+ /* search first ": ". we assume to find the remote-MTA answer there */
+ if (!(s = Ustrstr(addr->message, ": ")))
+ return; /* not found, bail out */
+ s += 2; /* skip ": " */
+ fprintf(f, "Diagnostic-Code: smtp; ");
+ }
+/* no message available. do nothing */
+else return;
-s += 2; /* skip ": " */
while (*s)
if (*s == '\\' && s[1] == 'n')
{
do_duplicate_check(address_item **anchor)
{
address_item *addr;
-while ((addr = *anchor) != NULL)
+while ((addr = *anchor))
{
tree_node *tnode;
if (testflag(addr, af_pfr))
{
anchor = &(addr->next);
}
- else if ((tnode = tree_search(tree_duplicates, addr->unique)) != NULL)
+ else if ((tnode = tree_search(tree_duplicates, addr->unique)))
{
DEBUG(D_deliver|D_route)
debug_printf("%s is a duplicate address: discarded\n", addr->unique);
open_db *dbm_file;
extern int acl_where;
-uschar *info = (queue_run_pid == (pid_t)0)?
- string_sprintf("delivering %s", id) :
- string_sprintf("delivering %s (queue run pid %d)", id, queue_run_pid);
+uschar *info = queue_run_pid == (pid_t)0
+ ? string_sprintf("delivering %s", id)
+ : string_sprintf("delivering %s (queue run pid %d)", id, queue_run_pid);
/* If the D_process_info bit is on, set_process_info() will output debugging
information. If not, we want to show this initial information if D_deliver or
set_process_info("%s", info);
-if ((debug_selector & D_process_info) == 0 &&
- (debug_selector & (D_deliver|D_queue_run|D_v)) != 0)
+if ( !(debug_selector & D_process_info)
+ && (debug_selector & (D_deliver|D_queue_run|D_v))
+ )
debug_printf("%s\n", info);
/* Ensure that we catch any subprocesses that are created. Although Exim
sprintf(CS spoolname, "%s/input/%s/%s-J", spool_directory, message_subdir, id);
jread = Ufopen(spoolname, "rb");
-if (jread != NULL)
+if (jread)
{
- while (Ufgets(big_buffer, big_buffer_size, jread) != NULL)
+ while (Ufgets(big_buffer, big_buffer_size, jread))
{
int n = Ustrlen(big_buffer);
big_buffer[n-1] = 0;
/* A null recipients list indicates some kind of disaster. */
-if (recipients_list == NULL)
+if (!recipients_list)
{
(void)close(deliver_datafile);
deliver_datafile = -1;
tools must be used to deal with it. Logging of this action happens in
spool_move_message() and its subfunctions. */
- if (move_frozen_messages &&
- spool_move_message(id, message_subdir, US"", US"F"))
+ if ( move_frozen_messages
+ && spool_move_message(id, message_subdir, US"", US"F")
+ )
return continue_closedown(); /* yields DELIVER_NOT_ATTEMPTED */
#endif
else
{
- if ((sender_address[0] == 0 ||
- auto_thaw <= 0 ||
- now <= deliver_frozen_at + auto_thaw
- )
- &&
- (!forced || !deliver_force_thaw || !admin_user ||
- continue_hostname != NULL
- ))
+ if ( ( sender_address[0] == 0
+ || auto_thaw <= 0
+ || now <= deliver_frozen_at + auto_thaw
+ )
+ && ( !forced || !deliver_force_thaw
+ || !admin_user || continue_hostname
+ ) )
{
(void)close(deliver_datafile);
deliver_datafile = -1;
/* Make a C stream out of it. */
- message_log = fdopen(fd, "a");
- if (message_log == NULL)
+ if (!(message_log = fdopen(fd, "a")))
{
log_write(0, LOG_MAIN|LOG_PANIC, "Couldn't fdopen message log %s: %s",
spoolname, strerror(errno));
if (give_up)
{
struct passwd *pw = getpwuid(real_uid);
- log_write(0, LOG_MAIN, "cancelled by %s", (pw != NULL)?
- US pw->pw_name : string_sprintf("uid %ld", (long int)real_uid));
+ log_write(0, LOG_MAIN, "cancelled by %s",
+ pw ? US pw->pw_name : string_sprintf("uid %ld", (long int)real_uid));
process_recipients = RECIP_FAIL;
}
ignore the true recipients of the message. Failure of the filter file is
logged, and the delivery attempt fails. */
-else if (system_filter != NULL && process_recipients != RECIP_FAIL_TIMEOUT)
+else if (system_filter && process_recipients != RECIP_FAIL_TIMEOUT)
{
int rc;
int filtertype;
system_filtering = FALSE;
enable_dollar_recipients = FALSE;
- if (filter_message != NULL && filter_message[0] == 0) filter_message = NULL;
+ if (filter_message && filter_message[0] == 0) filter_message = NULL;
/* Save the values of the system filter variables so that user filters
can use them. */
deliver_frozen_at = time(NULL);
process_recipients = RECIP_DEFER;
frozen_info = string_sprintf(" by the system filter%s%s",
- (filter_message == NULL)? US"" : US": ",
- (filter_message == NULL)? US"" : filter_message);
+ filter_message ? US": " : US"",
+ filter_message ? filter_message : US"");
}
/* The filter can request that a message be failed. The error message may be
process_recipients = RECIP_FAIL_FILTER;
- if (filter_message != NULL)
+ if (filter_message)
{
uschar *logend;
colon = US": ";
- if (filter_message[0] == '<' && filter_message[1] == '<' &&
- (logend = Ustrstr(filter_message, ">>")) != NULL)
+ if ( filter_message[0] == '<'
+ && filter_message[1] == '<'
+ && (logend = Ustrstr(filter_message, ">>"))
+ )
{
logmsg = filter_message + 2;
loglen = logend - logmsg;
else if (rc == FF_DELIVERED)
{
process_recipients = RECIP_IGNORE;
- if (addr_new == NULL)
- log_write(0, LOG_MAIN, "=> discarded (system filter)");
- else
+ if (addr_new)
log_write(0, LOG_MAIN, "original recipients ignored (system filter)");
+ else
+ log_write(0, LOG_MAIN, "=> discarded (system filter)");
}
/* If any new addresses were created by the filter, fake up a "parent"
pipes, files, and autoreplies, and run them as the filter uid if set,
otherwise as the current uid. */
- if (addr_new != NULL)
+ if (addr_new)
{
int uid = (system_filter_uid_set)? system_filter_uid : geteuid();
int gid = (system_filter_gid_set)? system_filter_gid : getegid();
at the final address. This is used if we go on to add addresses for the
original recipients. */
- while (p != NULL)
+ while (p)
{
if (parent->child_count == SHRT_MAX)
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "system filter generated more "
/* Now find the actual transport, first expanding the name. We have
set address_file or address_pipe above. */
- if (tpname != NULL)
+ if (tpname)
{
uschar *tmp = expand_string(tpname);
address_file = address_pipe = NULL;
- if (tmp == NULL)
+ if (!tmp)
p->message = string_sprintf("failed to expand \"%s\" as a "
"system filter transport name", tpname);
tpname = tmp;
type);
}
- if (tpname != NULL)
+ if (tpname)
{
transport_instance *tp;
- for (tp = transports; tp != NULL; tp = tp->next)
+ for (tp = transports; tp; tp = tp->next)
{
if (Ustrcmp(tp->name, tpname) == 0)
{
break;
}
}
- if (tp == NULL)
+ if (!tp)
p->message = string_sprintf("failed to find \"%s\" transport "
"for system filter delivery", tpname);
}
/* If we couldn't set up a transport, defer the delivery, putting the
error on the panic log as well as the main log. */
- if (p->transport == NULL)
+ if (!p->transport)
{
address_item *badp = p;
p = p->next;
- if (addr_last == NULL) addr_new = p; else addr_last->next = p;
+ if (!addr_last) addr_new = p; else addr_last->next = p;
badp->local_part = badp->address; /* Needed for log line */
post_process_one(badp, DEFER, LOG_MAIN|LOG_PANIC, DTYPE_ROUTER, 0);
continue;
{
for (i = 0; i < recipients_count; i++)
{
- if (tree_search(tree_nonrecipients, recipients_list[i].address) == NULL)
+ if (!tree_search(tree_nonrecipients, recipients_list[i].address))
{
recipient_item *r = recipients_list + i;
address_item *new = deliver_make_addr(r->address, FALSE);
- new->p.errors_address = r->errors_to;
+ new->prop.errors_address = r->errors_to;
+#ifdef SUPPORT_I18N
+ if ((new->prop.utf8_msg = message_smtputf8))
+ {
+ new->prop.utf8_downcvt = message_utf8_downconvert == 1;
+ new->prop.utf8_downcvt_maybe = message_utf8_downconvert == -1;
+ DEBUG(D_deliver) debug_printf("utf8, downconvert %s\n",
+ new->prop.utf8_downcvt ? "yes"
+ : new->prop.utf8_downcvt_maybe ? "ifneeded"
+ : "no");
+ }
+#endif
if (r->pno >= 0)
new->onetime_parent = recipients_list[r->pno].address;
- /* If DSN support is enabled, set the dsn flags and the original receipt
+ /* If DSN support is enabled, set the dsn flags and the original receipt
to be passed on to other DSN enabled MTAs */
new->dsn_flags = r->dsn_flags & rf_dsnflags;
new->dsn_orcpt = r->orcpt;
- DEBUG(D_deliver) debug_printf("DSN: set orcpt: %s flags: %d\n", new->dsn_orcpt, new->dsn_flags);
+ DEBUG(D_deliver) debug_printf("DSN: set orcpt: %s flags: %d\n",
+ new->dsn_orcpt, new->dsn_flags);
switch (process_recipients)
{
case RECIP_FAIL_FILTER:
new->message =
- (filter_message == NULL)? US"delivery cancelled" : filter_message;
+ filter_message ? filter_message : US"delivery cancelled";
setflag(new, af_pass_message);
goto RECIP_QUEUE_FAILED; /* below */
/* Value should be RECIP_ACCEPT; take this as the safe default. */
default:
- if (addr_new == NULL) addr_new = new; else addr_last->next = new;
+ if (!addr_new) addr_new = new; else addr_last->next = new;
addr_last = new;
break;
}
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
if (process_recipients != RECIP_ACCEPT)
{
uschar * save_local = deliver_localpart;
- uschar * save_domain = deliver_domain;
+ const uschar * save_domain = deliver_domain;
deliver_localpart = expand_string(
string_sprintf("${local_part:%s}", new->address));
DEBUG(D_deliver)
{
- address_item *p = addr_new;
+ address_item *p;
debug_printf("Delivery address list:\n");
- while (p != NULL)
- {
- debug_printf(" %s %s\n", p->address, (p->onetime_parent == NULL)? US"" :
- p->onetime_parent);
- p = p->next;
- }
+ for (p = addr_new; p; p = p->next)
+ debug_printf(" %s %s\n", p->address,
+ p->onetime_parent ? p->onetime_parent : US"");
}
/* Set up the buffers used for copying over the file when delivering. */
*/
header_rewritten = FALSE; /* No headers rewritten yet */
-while (addr_new != NULL) /* Loop until all addresses dealt with */
+while (addr_new) /* Loop until all addresses dealt with */
{
address_item *addr, *parent;
- dbm_file = dbfn_open(US"retry", O_RDONLY, &dbblock, FALSE);
/* Failure to open the retry database is treated the same as if it does
not exist. In both cases, dbm_file is NULL. */
- if (dbm_file == NULL)
+ if (!(dbm_file = dbfn_open(US"retry", O_RDONLY, &dbblock, FALSE)))
{
DEBUG(D_deliver|D_retry|D_route|D_hints_lookup)
debug_printf("no retry data available\n");
/* Scan the current batch of new addresses, to handle pipes, files and
autoreplies, and determine which others are ready for routing. */
- while (addr_new != NULL)
+ while (addr_new)
{
int rc;
uschar *p;
if (addr->address[0] == '>')
{
- while (tree_search(tree_duplicates, addr->unique) != NULL)
+ while (tree_search(tree_duplicates, addr->unique))
addr->unique = string_sprintf(">%s", addr->unique);
}
- else if ((tnode = tree_search(tree_duplicates, addr->unique)) != NULL)
+ else if ((tnode = tree_search(tree_duplicates, addr->unique)))
{
DEBUG(D_deliver|D_route)
debug_printf("%s is a duplicate address: discarded\n", addr->address);
/* Check for previous delivery */
- if (tree_search(tree_nonrecipients, addr->unique) != NULL)
+ if (tree_search(tree_nonrecipients, addr->unique))
{
DEBUG(D_deliver|D_route)
debug_printf("%s was previously delivered: discarded\n", addr->address);
delivery was forced by hand. */
deliver_domain = addr->domain; /* set $domain */
- if (!forced && hold_domains != NULL &&
- (rc = match_isinlist(addr->domain, &hold_domains, 0,
+ if ( !forced && hold_domains
+ && (rc = match_isinlist(addr->domain, (const uschar **)&hold_domains, 0,
&domainlist_anchor, addr->domain_cache, MCL_DOMAIN, TRUE,
- NULL)) != FAIL)
+ NULL)) != FAIL
+ )
{
if (rc == DEFER)
{
The "unique" field is initialized to the same value as the "address" field,
but gets changed here to cope with identically-named descendents. */
- for (parent = addr->parent; parent != NULL; parent = parent->parent)
+ for (parent = addr->parent; parent; parent = parent->parent)
if (strcmpic(addr->address, parent->address) == 0) break;
/* If there's an ancestor with the same name, set the homonym flag. This
work. This means that siblings or cousins with the same names are treated
as duplicates, which is what we want. */
- if (parent != NULL)
+ if (parent)
{
setflag(addr, af_homonym);
if (parent->unique[0] != '\\')
DEBUG(D_deliver|D_route) debug_printf("unique = %s\n", addr->unique);
- if (tree_search(tree_nonrecipients, addr->unique) != NULL)
+ if (tree_search(tree_nonrecipients, addr->unique))
{
DEBUG(D_deliver|D_route)
debug_printf("%s was previously delivered: discarded\n", addr->unique);
addr->address_retry_key = string_sprintf("R:%s@%s", addr->local_part,
addr->domain);
- if (dbm_file == NULL)
- domain_retry_record = address_retry_record = NULL;
- else
+ if (dbm_file)
{
domain_retry_record = dbfn_read(dbm_file, addr->domain_retry_key);
- if (domain_retry_record != NULL &&
- now - domain_retry_record->time_stamp > retry_data_expire)
+ if ( domain_retry_record
+ && now - domain_retry_record->time_stamp > retry_data_expire
+ )
domain_retry_record = NULL; /* Ignore if too old */
address_retry_record = dbfn_read(dbm_file, addr->address_retry_key);
- if (address_retry_record != NULL &&
- now - address_retry_record->time_stamp > retry_data_expire)
+ if ( address_retry_record
+ && now - address_retry_record->time_stamp > retry_data_expire
+ )
address_retry_record = NULL; /* Ignore if too old */
- if (address_retry_record == NULL)
+ if (!address_retry_record)
{
uschar *altkey = string_sprintf("%s:<%s>", addr->address_retry_key,
sender_address);
address_retry_record = dbfn_read(dbm_file, altkey);
- if (address_retry_record != NULL &&
- now - address_retry_record->time_stamp > retry_data_expire)
+ if ( address_retry_record
+ && now - address_retry_record->time_stamp > retry_data_expire)
address_retry_record = NULL; /* Ignore if too old */
}
}
+ else
+ domain_retry_record = address_retry_record = NULL;
DEBUG(D_deliver|D_retry)
{
- if (domain_retry_record == NULL)
+ if (!domain_retry_record)
debug_printf("no domain retry record\n");
- if (address_retry_record == NULL)
+ if (!address_retry_record)
debug_printf("no address retry record\n");
}
The reason for not doing the same for address retries is that they normally
arise from 4xx responses, not DNS timeouts. */
- if (continue_hostname != NULL && domain_retry_record != NULL)
+ if (continue_hostname && domain_retry_record)
{
addr->message = US"reusing SMTP connection skips previous routing defer";
addr->basic_errno = ERRNO_RRETRY;
which keep the retry record fresh, which can lead to us perpetually
deferring messages. */
- else if (((queue_running && !deliver_force) || continue_hostname != NULL)
- &&
- ((domain_retry_record != NULL &&
- now < domain_retry_record->next_try &&
- !domain_retry_record->expired)
- ||
- (address_retry_record != NULL &&
- now < address_retry_record->next_try))
- &&
- (domain_retry_record != NULL ||
- address_retry_record == NULL ||
- !retry_ultimate_address_timeout(addr->address_retry_key,
- addr->domain, address_retry_record, now)))
+ else if ( ( queue_running && !deliver_force
+ || continue_hostname
+ )
+ && ( ( domain_retry_record
+ && now < domain_retry_record->next_try
+ && !domain_retry_record->expired
+ )
+ || ( address_retry_record
+ && now < address_retry_record->next_try
+ ) )
+ && ( domain_retry_record
+ || !address_retry_record
+ || !retry_ultimate_address_timeout(addr->address_retry_key,
+ addr->domain, address_retry_record, now)
+ ) )
{
addr->message = US"retry time not reached";
addr->basic_errno = ERRNO_RRETRY;
else
{
- if (domain_retry_record != NULL || address_retry_record != NULL)
+ if (domain_retry_record || address_retry_record)
setflag(addr, af_dr_retry_exists);
addr->next = addr_route;
addr_route = addr;
/* The database is closed while routing is actually happening. Requests to
update it are put on a chain and all processed together at the end. */
- if (dbm_file != NULL) dbfn_close(dbm_file);
+ if (dbm_file) dbfn_close(dbm_file);
/* If queue_domains is set, we don't even want to try routing addresses in
those domains. During queue runs, queue_domains is forced to be unset.
Optimize by skipping this pass through the addresses if nothing is set. */
- if (!deliver_force && queue_domains != NULL)
+ if (!deliver_force && queue_domains)
{
address_item *okaddr = NULL;
- while (addr_route != NULL)
+ while (addr_route)
{
address_item *addr = addr_route;
addr_route = addr->next;
deliver_domain = addr->domain; /* set $domain */
- if ((rc = match_isinlist(addr->domain, &queue_domains, 0,
+ if ((rc = match_isinlist(addr->domain, (const uschar **)&queue_domains, 0,
&domainlist_anchor, addr->domain_cache, MCL_DOMAIN, TRUE, NULL))
!= OK)
{
/* Now route those addresses that are not deferred. */
- while (addr_route != NULL)
+ while (addr_route)
{
int rc;
address_item *addr = addr_route;
- uschar *old_domain = addr->domain;
+ const uschar *old_domain = addr->domain;
uschar *old_unique = addr->unique;
addr_route = addr->next;
addr->next = NULL;
/* Just in case some router parameter refers to it. */
- return_path = (addr->p.errors_address != NULL)?
- addr->p.errors_address : sender_address;
+ if (!(return_path = addr->prop.errors_address))
+ return_path = sender_address;
/* If a router defers an address, add a retry item. Whether or not to
use the local part in the key is a property of the router. */
if ((rc = route_address(addr, &addr_local, &addr_remote, &addr_new,
&addr_succeed, v_none)) == DEFER)
- retry_add_item(addr, (addr->router->retry_use_local_part)?
- string_sprintf("R:%s@%s", addr->local_part, addr->domain) :
- string_sprintf("R:%s", addr->domain), 0);
+ retry_add_item(addr,
+ addr->router->retry_use_local_part
+ ? string_sprintf("R:%s@%s", addr->local_part, addr->domain)
+ : string_sprintf("R:%s", addr->domain),
+ 0);
/* Otherwise, if there is an existing retry record in the database, add
retry items to delete both forms. We must also allow for the possibility
has already been delivered, because it's the unique address that finally
gets recorded. */
- if (addr->unique != old_unique &&
- tree_search(tree_nonrecipients, addr->unique) != 0)
+ if ( addr->unique != old_unique
+ && tree_search(tree_nonrecipients, addr->unique) != 0
+ )
{
DEBUG(D_deliver|D_route) debug_printf("%s was previously delivered: "
"discarded\n", addr->address);
to a remote transport, there are no header changes, and the domain was not
modified by the router. */
- if (addr_remote == addr &&
- addr->router->same_domain_copy_routing &&
- addr->p.extra_headers == NULL &&
- addr->p.remove_headers == NULL &&
- old_domain == addr->domain)
+ if ( addr_remote == addr
+ && addr->router->same_domain_copy_routing
+ && !addr->prop.extra_headers
+ && !addr->prop.remove_headers
+ && old_domain == addr->domain
+ )
{
address_item **chain = &addr_route;
- while (*chain != NULL)
+ while (*chain)
{
address_item *addr2 = *chain;
if (Ustrcmp(addr2->domain, addr->domain) != 0)
addr2->transport = addr->transport;
addr2->host_list = addr->host_list;
addr2->fallback_hosts = addr->fallback_hosts;
- addr2->p.errors_address = addr->p.errors_address;
+ addr2->prop.errors_address = addr->prop.errors_address;
copyflag(addr2, addr, af_hide_child | af_local_host_removed);
DEBUG(D_deliver|D_route)
DEBUG(D_deliver|D_retry|D_route)
{
- address_item *p = addr_local;
+ address_item *p;
debug_printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
debug_printf("After routing:\n Local deliveries:\n");
- while (p != NULL)
- {
+ for (p = addr_local; p; p = p->next)
debug_printf(" %s\n", p->address);
- p = p->next;
- }
- p = addr_remote;
debug_printf(" Remote deliveries:\n");
- while (p != NULL)
- {
+ for (p = addr_remote; p; p = p->next)
debug_printf(" %s\n", p->address);
- p = p->next;
- }
- p = addr_failed;
debug_printf(" Failed addresses:\n");
- while (p != NULL)
- {
+ for (p = addr_failed; p; p = p->next)
debug_printf(" %s\n", p->address);
- p = p->next;
- }
- p = addr_defer;
debug_printf(" Deferred addresses:\n");
- while (p != NULL)
- {
+ for (p = addr_defer; p; p = p->next)
debug_printf(" %s\n", p->address);
- p = p->next;
- }
}
/* Free any resources that were cached during routing. */
remote transport. The check that they all end up in one transaction happens in
the do_remote_deliveries() function. */
-if (mua_wrapper && (addr_local != NULL || addr_failed != NULL ||
- addr_defer != NULL))
+if ( mua_wrapper
+ && (addr_local || addr_failed || addr_defer)
+ )
{
address_item *addr;
uschar *which, *colon, *msg;
- if (addr_local != NULL)
+ if (addr_local)
{
addr = addr_local;
which = US"local";
}
- else if (addr_defer != NULL)
+ else if (addr_defer)
{
addr = addr_defer;
which = US"deferred";
which = US"failed";
}
- while (addr->parent != NULL) addr = addr->parent;
+ while (addr->parent) addr = addr->parent;
- if (addr->message != NULL)
+ if (addr->message)
{
colon = US": ";
msg = addr->message;
/* If this is a run to continue deliveries to an external channel that is
already set up, defer any local deliveries. */
-if (continue_transport != NULL)
+if (continue_transport)
{
- if (addr_defer == NULL) addr_defer = addr_local; else
+ if (addr_defer)
{
address_item *addr = addr_defer;
- while (addr->next != NULL) addr = addr->next;
+ while (addr->next) addr = addr->next;
addr->next = addr_local;
}
+ else
+ addr_defer = addr_local;
addr_local = NULL;
}
there is only address to be delivered - if it succeeds the spool write need not
happen. */
-if (header_rewritten &&
- ((addr_local != NULL &&
- (addr_local->next != NULL || addr_remote != NULL)) ||
- (addr_remote != NULL && addr_remote->next != NULL)))
+if ( header_rewritten
+ && ( ( addr_local
+ && (addr_local->next || addr_remote)
+ )
+ || (addr_remote && addr_remote->next)
+ ) )
{
/* Panic-dies on error */
(void)spool_write_header(message_id, SW_DELIVERING, NULL);
journal is found to exist at the start of delivery, the addresses listed
therein are added to the non-recipients. */
-if (addr_local != NULL || addr_remote != NULL)
+if (addr_local || addr_remote)
{
sprintf(CS spoolname, "%s/input/%s/%s-J", spool_directory, message_subdir, id);
journal_fd = Uopen(spoolname, O_WRONLY|O_APPEND|O_CREAT, SPOOL_MODE);
to an LHLO command, if is isn't already compiled. This may be used on both
local and remote LMTP deliveries. */
-if (regex_IGNOREQUOTA == NULL) regex_IGNOREQUOTA =
- regex_must_compile(US"\\n250[\\s\\-]IGNOREQUOTA(\\s|\\n|$)", FALSE, TRUE);
+if (!regex_IGNOREQUOTA)
+ regex_IGNOREQUOTA =
+ regex_must_compile(US"\\n250[\\s\\-]IGNOREQUOTA(\\s|\\n|$)", FALSE, TRUE);
/* Handle local deliveries */
-if (addr_local != NULL)
+if (addr_local)
{
DEBUG(D_deliver|D_transport)
debug_printf(">>>>>>>>>>>>>>>> Local deliveries >>>>>>>>>>>>>>>>\n");
so just queue them all. */
if (queue_run_local)
- {
- while (addr_remote != NULL)
+ while (addr_remote)
{
address_item *addr = addr_remote;
addr_remote = addr->next;
addr->message = US"remote deliveries suppressed";
(void)post_process_one(addr, DEFER, LOG_MAIN, DTYPE_TRANSPORT, 0);
}
- }
/* Handle remote deliveries */
-if (addr_remote != NULL)
+if (addr_remote)
{
DEBUG(D_deliver|D_transport)
debug_printf(">>>>>>>>>>>>>>>> Remote deliveries >>>>>>>>>>>>>>>>\n");
do_remote_deliveries is FALSE when mua_wrapper is set and all addresses
cannot be delivered in one transaction. */
- if (remote_sort_domains != NULL) sort_remote_deliveries();
+ if (remote_sort_domains) sort_remote_deliveries();
if (!do_remote_deliveries(FALSE))
{
log_write(0, LOG_MAIN, "** mua_wrapper is set but recipients cannot all "
host is used for many domains, so all can be sent in a single transaction
(if appropriately configured). */
- if (addr_fallback != NULL && !mua_wrapper)
+ if (addr_fallback && !mua_wrapper)
{
DEBUG(D_deliver) debug_printf("Delivering to fallback hosts\n");
addr_remote = addr_fallback;
addr_fallback = NULL;
- if (remote_sort_domains != NULL) sort_remote_deliveries();
+ if (remote_sort_domains) sort_remote_deliveries();
do_remote_deliveries(TRUE);
}
disable_logging = FALSE;
if (mua_wrapper)
{
- if (addr_defer != NULL)
+ if (addr_defer)
{
address_item *addr, *nextaddr;
- for (addr = addr_defer; addr != NULL; addr = nextaddr)
+ for (addr = addr_defer; addr; addr = nextaddr)
{
log_write(0, LOG_MAIN, "** %s mua_wrapper forced failure for deferred "
"delivery", addr->address);
/* Now all should either have succeeded or failed. */
- if (addr_failed == NULL) final_yield = DELIVER_MUA_SUCCEEDED; else
+ if (!addr_failed)
+ final_yield = DELIVER_MUA_SUCCEEDED;
+ else
{
- uschar *s = (addr_failed->user_message != NULL)?
- addr_failed->user_message : addr_failed->message;
host_item * host;
+ uschar *s = addr_failed->user_message;
+
+ if (!s) s = addr_failed->message;
fprintf(stderr, "Delivery failed: ");
if (addr_failed->basic_errno > 0)
{
fprintf(stderr, "%s", strerror(addr_failed->basic_errno));
- if (s != NULL) fprintf(stderr, ": ");
+ if (s) fprintf(stderr, ": ");
}
if ((host = addr_failed->host_used))
fprintf(stderr, "H=%s [%s]: ", host->name, host->address);
- if (s == NULL)
- {
- if (addr_failed->basic_errno <= 0) fprintf(stderr, "unknown error");
- }
- else fprintf(stderr, "%s", CS s);
+ if (s)
+ fprintf(stderr, "%s", CS s);
+ else if (addr_failed->basic_errno <= 0)
+ fprintf(stderr, "unknown error");
fprintf(stderr, "\n");
final_yield = DELIVER_MUA_FAILED;
updating of the database if the -N flag is set, which is a debugging thing that
prevents actual delivery. */
-else if (!dont_deliver) retry_update(&addr_defer, &addr_failed, &addr_succeed);
+else if (!dont_deliver)
+ retry_update(&addr_defer, &addr_failed, &addr_succeed);
-/* Send DSN for successful messages */
-addr_dsntmp = addr_succeed;
+/* Send DSN for successful messages if requested */
addr_senddsn = NULL;
-while(addr_dsntmp != NULL)
+for (addr_dsntmp = addr_succeed; addr_dsntmp; addr_dsntmp = addr_dsntmp->next)
{
- DEBUG(D_deliver)
- debug_printf("DSN: processing router : %s\n", addr_dsntmp->router->name);
-
- DEBUG(D_deliver)
- debug_printf("DSN: processing successful delivery address: %s\n", addr_dsntmp->address);
-
/* af_ignore_error not honored here. it's not an error */
-
- DEBUG(D_deliver) debug_printf("DSN: Sender_address: %s\n", sender_address);
- DEBUG(D_deliver) debug_printf("DSN: orcpt: %s flags: %d\n", addr_dsntmp->dsn_orcpt, addr_dsntmp->dsn_flags);
- DEBUG(D_deliver) debug_printf("DSN: envid: %s ret: %d\n", dsn_envid, dsn_ret);
- DEBUG(D_deliver) debug_printf("DSN: Final recipient: %s\n", addr_dsntmp->address);
- DEBUG(D_deliver) debug_printf("DSN: Remote SMTP server supports DSN: %d\n", addr_dsntmp->dsn_aware);
+ DEBUG(D_deliver) debug_printf("DSN: processing router : %s\n"
+ "DSN: processing successful delivery address: %s\n"
+ "DSN: Sender_address: %s\n"
+ "DSN: orcpt: %s flags: %d\n"
+ "DSN: envid: %s ret: %d\n"
+ "DSN: Final recipient: %s\n"
+ "DSN: Remote SMTP server supports DSN: %d\n",
+ addr_dsntmp->router->name,
+ addr_dsntmp->address,
+ sender_address,
+ addr_dsntmp->dsn_orcpt, addr_dsntmp->dsn_flags,
+ dsn_envid, dsn_ret,
+ addr_dsntmp->address,
+ addr_dsntmp->dsn_aware
+ );
/* send report if next hop not DSN aware or a router flagged "last DSN hop"
and a report was requested */
- if (((addr_dsntmp->dsn_aware != dsn_support_yes) ||
- ((addr_dsntmp->dsn_flags & rf_dsnlasthop) != 0))
- &&
- (((addr_dsntmp->dsn_flags & rf_dsnflags) != 0) &&
- ((addr_dsntmp->dsn_flags & rf_notify_success) != 0)))
+ if ( ( addr_dsntmp->dsn_aware != dsn_support_yes
+ || addr_dsntmp->dsn_flags & rf_dsnlasthop
+ )
+ && addr_dsntmp->dsn_flags & rf_dsnflags
+ && addr_dsntmp->dsn_flags & rf_notify_success
+ )
{
/* copy and relink address_item and send report with all of them at once later */
address_item *addr_next;
addr_senddsn->next = addr_next;
}
else
- {
- DEBUG(D_deliver) debug_printf("DSN: *** NOT SENDING DSN SUCCESS Message ***\n");
- }
-
- addr_dsntmp = addr_dsntmp->next;
+ DEBUG(D_deliver) debug_printf("DSN: not sending DSN success message\n");
}
-if (addr_senddsn != NULL)
+if (addr_senddsn)
{
pid_t pid;
int fd;
- /* create exim process to send message */
+ /* create exim process to send message */
pid = child_open_exim(&fd);
DEBUG(D_deliver) debug_printf("DSN: child_open_exim returns: %d\n", pid);
-
+
if (pid < 0) /* Creation of child failed */
{
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Process %d (parent %d) failed to "
"create child process to send failure message: %s", getpid(),
getppid(), strerror(errno));
- DEBUG(D_deliver) debug_printf("DSN: child_open_exim failed\n");
-
- }
+ DEBUG(D_deliver) debug_printf("DSN: child_open_exim failed\n");
+ }
else /* Creation of child succeeded */
{
FILE *f = fdopen(fd, "wb");
/* header only as required by RFC. only failure DSN needs to honor RET=FULL */
int topt = topt_add_return_path | topt_no_body;
uschar * bound;
-
- DEBUG(D_deliver) debug_printf("sending error message to: %s\n", sender_address);
-
+
+ DEBUG(D_deliver)
+ debug_printf("sending error message to: %s\n", sender_address);
+
/* build unique id for MIME boundary */
bound = string_sprintf(TIME_T_FMT "-eximdsn-%d", time(NULL), rand());
DEBUG(D_deliver) debug_printf("DSN: MIME boundary: %s\n", bound);
-
+
if (errors_reply_to)
fprintf(f, "Reply-To: %s\n", errors_reply_to);
-
+
fprintf(f, "Auto-Submitted: auto-generated\n"
"From: Mail Delivery System <Mailer-Daemon@%s>\n"
"To: %s\n"
"--%s\n"
"Content-type: text/plain; charset=us-ascii\n\n"
-
+
"This message was created automatically by mail delivery software.\n"
" ----- The following addresses had successful delivery notifications -----\n",
qualify_domain_sender, sender_address, bound, bound);
- addr_dsntmp = addr_senddsn;
- while(addr_dsntmp)
- {
+ for (addr_dsntmp = addr_senddsn; addr_dsntmp;
+ addr_dsntmp = addr_dsntmp->next)
fprintf(f, "<%s> (relayed %s)\n\n",
addr_dsntmp->address,
(addr_dsntmp->dsn_flags & rf_dsnlasthop) == 1
? "to non-DSN-aware mailer"
: "via non \"Remote SMTP\" router"
);
- addr_dsntmp = addr_dsntmp->next;
- }
+
fprintf(f, "--%s\n"
"Content-type: message/delivery-status\n\n"
"Reporting-MTA: dns; %s\n",
bound, smtp_active_hostname);
- if (dsn_envid != NULL) {
- /* must be decoded from xtext: see RFC 3461:6.3a */
+ if (dsn_envid)
+ { /* must be decoded from xtext: see RFC 3461:6.3a */
uschar *xdec_envid;
if (auth_xtextdecode(dsn_envid, &xdec_envid) > 0)
fprintf(f, "Original-Envelope-ID: %s\n", dsn_envid);
addr_dsntmp->address);
if (addr_dsntmp->host_used && addr_dsntmp->host_used->name)
- fprintf(f, "Remote-MTA: dns; %s\nDiagnostic-Code: smtp; 250 Ok\n",
+ fprintf(f, "Remote-MTA: dns; %s\nDiagnostic-Code: smtp; 250 Ok\n\n",
addr_dsntmp->host_used->name);
else
- fprintf(f,"Diagnostic-Code: X-Exim; relayed via non %s router\n",
+ fprintf(f, "Diagnostic-Code: X-Exim; relayed via non %s router\n\n",
(addr_dsntmp->dsn_flags & rf_dsnlasthop) == 1 ? "DSN" : "SMTP");
- fputc('\n', f);
}
fprintf(f, "--%s\nContent-type: text/rfc822-headers\n\n", bound);
-
+
fflush(f);
transport_filter_argv = NULL; /* Just in case */
return_path = sender_address; /* In case not previously set */
-
+
/* Write the original email out */
transport_write_message(NULL, fileno(f), topt, 0, NULL, NULL, NULL, NULL, NULL, 0);
fflush(f);
several messages to get sent if there are addresses with different
requirements. */
-while (addr_failed != NULL)
+while (addr_failed)
{
pid_t pid;
int fd;
there may not be a transport (address failed by a router). */
disable_logging = FALSE;
- if (addr_failed->transport != NULL)
+ if (addr_failed->transport)
disable_logging = addr_failed->transport->disable_logging;
DEBUG(D_deliver)
If neither of these cases obtains, something has gone wrong. Log the
incident, but then ignore the error. */
- if (sender_address[0] == 0 && addr_failed->p.errors_address == NULL)
+ if (sender_address[0] == 0 && !addr_failed->prop.errors_address)
{
- if (!testflag(addr_failed, af_retry_timedout) &&
- !testflag(addr_failed, af_ignore_error))
+ if ( !testflag(addr_failed, af_retry_timedout)
+ && !testflag(addr_failed, af_ignore_error))
{
log_write(0, LOG_MAIN|LOG_PANIC, "internal error: bounce message "
"failure is neither frozen nor ignored (it's been ignored)");
mark the recipient done. */
if ( testflag(addr_failed, af_ignore_error)
- || ( ((addr_failed->dsn_flags & rf_dsnflags) != 0)
- && ((addr_failed->dsn_flags & rf_notify_failure) != rf_notify_failure))
- )
- {
+ || ( addr_failed->dsn_flags & rf_dsnflags
+ && (addr_failed->dsn_flags & rf_notify_failure) != rf_notify_failure
+ ) )
+ {
addr = addr_failed;
addr_failed = addr->next;
- if (addr->return_filename != NULL) Uunlink(addr->return_filename);
+ if (addr->return_filename) Uunlink(addr->return_filename);
log_write(0, LOG_MAIN, "%s%s%s%s: error ignored",
addr->address,
- (addr->parent == NULL)? US"" : US" <",
- (addr->parent == NULL)? US"" : addr->parent->address,
- (addr->parent == NULL)? US"" : US">");
+ !addr->parent ? US"" : US" <",
+ !addr->parent ? US"" : addr->parent->address,
+ !addr->parent ? US"" : US">");
address_done(addr, logtod);
child_done(addr, logtod);
else
{
- bounce_recipient = (addr_failed->p.errors_address == NULL)?
- sender_address : addr_failed->p.errors_address;
+ if (!(bounce_recipient = addr_failed->prop.errors_address))
+ bounce_recipient = sender_address;
/* Make a subprocess to send a message */
- pid = child_open_exim(&fd);
-
- /* Creation of child failed */
-
- if (pid < 0)
+ if ((pid = child_open_exim(&fd)) < 0)
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Process %d (parent %d) failed to "
"create child process to send failure message: %s", getpid(),
getppid(), strerror(errno));
them from the addr_failed chain, and putting them on msgchain. */
paddr = &addr_failed;
- for (addr = addr_failed; addr != NULL; addr = *paddr)
- {
- if (Ustrcmp(bounce_recipient, (addr->p.errors_address == NULL)?
- sender_address : addr->p.errors_address) != 0)
- {
- paddr = &(addr->next); /* Not the same; skip */
- }
- else /* The same - dechain */
- {
+ for (addr = addr_failed; addr; addr = *paddr)
+ if (Ustrcmp(bounce_recipient, addr->prop.errors_address
+ ? addr->prop.errors_address : sender_address) == 0)
+ { /* The same - dechain */
*paddr = addr->next;
*pmsgchain = addr;
addr->next = NULL;
pmsgchain = &(addr->next);
}
- }
+ else
+ paddr = &addr->next; /* Not the same; skip */
/* Include X-Failed-Recipients: for automatic interpretation, but do
not let any one header line get too long. We do this by starting a
new header every 50 recipients. Omit any addresses for which the
"hide_child" flag is set. */
- for (addr = msgchain; addr != NULL; addr = addr->next)
+ for (addr = msgchain; addr; addr = addr->next)
{
if (testflag(addr, af_hide_child)) continue;
if (rcount >= 50)
rcount = 0;
}
fprintf(f, "%s%s",
- (rcount++ == 0)? "X-Failed-Recipients: " : ",\n ",
- (testflag(addr, af_pfr) && addr->parent != NULL)?
- string_printing(addr->parent->address) :
- string_printing(addr->address));
+ rcount++ == 0
+ ? "X-Failed-Recipients: "
+ : ",\n ",
+ testflag(addr, af_pfr) && addr->parent
+ ? string_printing(addr->parent->address)
+ : string_printing(addr->address));
}
if (rcount > 0) fprintf(f, "\n");
/* Output the standard headers */
- if (errors_reply_to != NULL)
+ if (errors_reply_to)
fprintf(f, "Reply-To: %s\n", errors_reply_to);
fprintf(f, "Auto-Submitted: auto-replied\n");
moan_write_from(f);
hidden. */
paddr = &msgchain;
- for (addr = msgchain; addr != NULL; addr = *paddr)
+ for (addr = msgchain; addr; addr = *paddr)
{
if (print_address_information(addr, f, US" ", US"\n ", US""))
print_address_error(addr, f, US"");
"The following text was generated during the delivery "
"attempt%s:\n", (filecount > 1)? "s" : "");
- for (addr = msgchain; addr != NULL; addr = nextaddr)
+ for (addr = msgchain; addr; addr = nextaddr)
{
FILE *fm;
address_item *topaddr = addr;
/* Now copy the file */
- fm = Ufopen(addr->return_filename, "rb");
-
- if (fm == NULL)
+ if (!(fm = Ufopen(addr->return_filename, "rb")))
fprintf(f, " +++ Exim error... failed to open text file: %s\n",
strerror(errno));
else
}
/* output machine readable part */
- fprintf(f, "--%s\n"
- "Content-type: message/delivery-status\n\n"
- "Reporting-MTA: dns; %s\n",
- bound, smtp_active_hostname);
+#ifdef SUPPORT_I18N
+ if (message_smtputf8)
+ fprintf(f, "--%s\n"
+ "Content-type: message/global-delivery-status\n\n"
+ "Reporting-MTA: dns; %s\n",
+ bound, smtp_active_hostname);
+ else
+#endif
+ fprintf(f, "--%s\n"
+ "Content-type: message/delivery-status\n\n"
+ "Reporting-MTA: dns; %s\n",
+ bound, smtp_active_hostname);
if (dsn_envid)
{
fprintf(f, "X-Original-Envelope-ID: error decoding xtext formated ENVID\n");
}
fputc('\n', f);
-
+
for (addr = handled_addr; addr; addr = addr->next)
{
+ host_item * hu;
fprintf(f, "Action: failed\n"
"Final-Recipient: rfc822;%s\n"
"Status: 5.0.0\n",
addr->address);
- if (addr->host_used && addr->host_used->name)
- {
- fprintf(f, "Remote-MTA: dns; %s\n",
- addr->host_used->name);
- print_dsn_diagnostic_code(addr, f);
- }
+ if ((hu = addr->host_used) && hu->name)
+ {
+ const uschar * s;
+ fprintf(f, "Remote-MTA: dns; %s\n", hu->name);
+#ifdef EXPERIMENTAL_DSN_INFO
+ if (hu->address)
+ {
+ uschar * p = hu->port == 25
+ ? US"" : string_sprintf(":%d", hu->port);
+ fprintf(f, "Remote-MTA: X-ip; [%s]%s\n", hu->address, p);
+ }
+ if ((s = addr->smtp_greeting) && *s)
+ fprintf(f, "X-Remote-MTA-smtp-greeting: X-str; %s\n", s);
+ if ((s = addr->helo_response) && *s)
+ fprintf(f, "X-Remote-MTA-helo-response: X-str; %s\n", s);
+ if ((s = addr->message) && *s)
+ fprintf(f, "X-Exim-Diagnostic: X-str; %s\n", s);
+#endif
+ print_dsn_diagnostic_code(addr, f);
+ }
+ fputc('\n', f);
}
/* Now copy the message, trying to give an intelligible comment if
emf_text = next_emf(emf, US"copy");
/* add message body
- we ignore the intro text from template and add
+ we ignore the intro text from template and add
the text for bounce_return_size_limit at the end.
-
+
bounce_return_message is ignored
in case RET= is defined we honor these values
otherwise bounce_return_body is honored.
-
+
bounce_return_size_limit is always honored.
*/
-
- fprintf(f, "\n--%s\n", bound);
+
+ fprintf(f, "--%s\n", bound);
dsnlimitmsg = US"X-Exim-DSN-Information: Due to administrative limits only headers are returned";
dsnnotifyhdr = NULL;
dsnnotifyhdr = dsnlimitmsg;
}
}
-
- if (topt & topt_no_body)
- fprintf(f,"Content-type: text/rfc822-headers\n\n");
+
+#ifdef SUPPORT_I18N
+ if (message_smtputf8)
+ fputs(topt & topt_no_body ? "Content-type: message/global-headers\n\n"
+ : "Content-type: message/global\n\n",
+ f);
else
- fprintf(f,"Content-type: message/rfc822\n\n");
+#endif
+ fputs(topt & topt_no_body ? "Content-type: text/rfc822-headers\n\n"
+ : "Content-type: message/rfc822\n\n",
+ f);
fflush(f);
transport_filter_argv = NULL; /* Just in case */
transport_write_message(NULL, fileno(f), topt,
0, dsnnotifyhdr, NULL, NULL, NULL, NULL, 0);
fflush(f);
-
+
/* we never add the final text. close the file */
if (emf)
(void)fclose(emf);
-
+
fprintf(f, "\n--%s--\n", bound);
/* Close the file, which should send an EOF to the child process
if (rc != 0)
{
uschar *s = US"";
- if (now - received_time < retry_maximum_timeout && addr_defer == NULL)
+ if (now - received_time < retry_maximum_timeout && !addr_defer)
{
addr_defer = (address_item *)(+1);
deliver_freeze = TRUE;
else
{
- for (addr = handled_addr; addr != NULL; addr = addr->next)
+ for (addr = handled_addr; addr; addr = addr->next)
{
address_done(addr, logtod);
child_done(addr, logtod);
message log if so configured, and we are using them. Otherwise, sling it.
Then delete the message itself. */
-if (addr_defer == NULL)
+if (!addr_defer)
{
if (message_logs)
{
"msglog.OLD directory", spoolname);
}
else
- {
if (Uunlink(spoolname) < 0)
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to unlink %s: %s",
spoolname, strerror(errno));
- }
}
/* Remove the two message files. */
/* Log the end of this message, with queue time if requested. */
- if ((log_extra_selector & LX_queue_time_overall) != 0)
+ if (LOGGING(queue_time_overall))
log_write(0, LOG_MAIN, "Completed QT=%s",
readconf_printtime( (int) ((long)time(NULL) - (long)received_time)) );
else
/* Unset deliver_freeze so that we won't try to move the spool files further down */
deliver_freeze = FALSE;
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
(void) event_raise(event_action, US"msg:complete", NULL);
#endif
-}
+ }
/* If there are deferred addresses, we are keeping this message because it is
not yet completed. Lose any temporary files that were catching output from
uschar *recipients = US"";
BOOL delivery_attempted = FALSE;
- deliver_domain = testflag(addr_defer, af_pfr)?
- addr_defer->parent->domain : addr_defer->domain;
+ deliver_domain = testflag(addr_defer, af_pfr)
+ ? addr_defer->parent->domain : addr_defer->domain;
- for (addr = addr_defer; addr != NULL; addr = addr->next)
+ for (addr = addr_defer; addr; addr = addr->next)
{
address_item *otaddr;
if (addr->basic_errno > ERRNO_RETRY_BASE) delivery_attempted = TRUE;
- if (deliver_domain != NULL)
+ if (deliver_domain)
{
- uschar *d = (testflag(addr, af_pfr))? addr->parent->domain : addr->domain;
+ const uschar *d = testflag(addr, af_pfr)
+ ? addr->parent->domain : addr->domain;
/* The domain may be unset for an address that has never been routed
because the system filter froze the message. */
- if (d == NULL || Ustrcmp(d, deliver_domain) != 0) deliver_domain = NULL;
+ if (!d || Ustrcmp(d, deliver_domain) != 0)
+ deliver_domain = NULL;
}
- if (addr->return_filename != NULL) Uunlink(addr->return_filename);
+ if (addr->return_filename) Uunlink(addr->return_filename);
/* Handle the case of one-time aliases. If any address in the ancestry
of this one is flagged, ensure it is in the recipients list, suitably
flagged, and that its parent is marked delivered. */
- for (otaddr = addr; otaddr != NULL; otaddr = otaddr->parent)
- if (otaddr->onetime_parent != NULL) break;
+ for (otaddr = addr; otaddr; otaddr = otaddr->parent)
+ if (otaddr->onetime_parent) break;
- if (otaddr != NULL)
+ if (otaddr)
{
int i;
int t = recipients_count;
DEBUG(D_deliver) debug_printf("one_time: adding %s in place of %s\n",
otaddr->address, otaddr->parent->address);
receive_add_recipient(otaddr->address, t);
- recipients_list[recipients_count-1].errors_to = otaddr->p.errors_address;
+ recipients_list[recipients_count-1].errors_to = otaddr->prop.errors_address;
tree_add_nonrecipient(otaddr->parent->address);
update_spool = TRUE;
}
list of recipients for a warning message. */
if (sender_address[0] != 0)
- {
- if (addr->p.errors_address == NULL)
+ if (addr->prop.errors_address)
{
- if (Ustrstr(recipients, sender_address) == NULL)
+ if (Ustrstr(recipients, addr->prop.errors_address) == NULL)
recipients = string_sprintf("%s%s%s", recipients,
- (recipients[0] == 0)? "" : ",", sender_address);
+ (recipients[0] == 0)? "" : ",", addr->prop.errors_address);
}
else
{
- if (Ustrstr(recipients, addr->p.errors_address) == NULL)
+ if (Ustrstr(recipients, sender_address) == NULL)
recipients = string_sprintf("%s%s%s", recipients,
- (recipients[0] == 0)? "" : ",", addr->p.errors_address);
+ (recipients[0] == 0)? "" : ",", sender_address);
}
- }
}
/* Send a warning message if the conditions are right. If the condition check
)
&& delay_warning[1] > 0
&& sender_address[0] != 0
- && ( delay_warning_condition == NULL
+ && ( !delay_warning_condition
|| expand_check_condition(delay_warning_condition,
US"delay_warning", US"option")
)
uschar * bound;
if (warn_message_file)
- {
- wmf = Ufopen(warn_message_file, "rb");
- if (wmf == NULL)
+ if (!(wmf = Ufopen(warn_message_file, "rb")))
log_write(0, LOG_MAIN|LOG_PANIC, "Failed to open %s for warning "
"message texts: %s", warn_message_file, strerror(errno));
- }
warnmsg_recipients = recipients;
- warnmsg_delay = (queue_time < 120*60)?
- string_sprintf("%d minutes", show_time/60):
- string_sprintf("%d hours", show_time/3600);
+ warnmsg_delay = queue_time < 120*60
+ ? string_sprintf("%d minutes", show_time/60)
+ : string_sprintf("%d hours", show_time/3600);
if (errors_reply_to)
fprintf(f, "Reply-To: %s\n", errors_reply_to);
"The message identifier is: %s\n",
warnmsg_delay, primary_hostname, message_id);
- for (h = header_list; h != NULL; h = h->next)
+ for (h = header_list; h; h = h->next)
if (strncmpic(h->text, US"Subject:", 8) == 0)
fprintf(f, "The subject of the message is: %s", h->text + 9);
else if (strncmpic(h->text, US"Date:", 5) == 0)
"Reporting-MTA: dns; %s\n",
bound,
smtp_active_hostname);
-
+
if (dsn_envid)
{
}
fputc('\n', f);
- while (addr_dsndefer)
+ for ( ; addr_dsndefer; addr_dsndefer = addr_dsndefer->next)
{
if (addr_dsndefer->dsn_orcpt)
- fprintf(f,"Original-Recipient: %s\n", addr_dsndefer->dsn_orcpt);
+ fprintf(f, "Original-Recipient: %s\n", addr_dsndefer->dsn_orcpt);
- fprintf(f,"Action: delayed\n");
- fprintf(f,"Final-Recipient: rfc822;%s\n", addr_dsndefer->address);
- fprintf(f,"Status: 4.0.0\n");
+ fprintf(f, "Action: delayed\n"
+ "Final-Recipient: rfc822;%s\n"
+ "Status: 4.0.0\n",
+ addr_dsndefer->address);
if (addr_dsndefer->host_used && addr_dsndefer->host_used->name)
{
- fprintf(f,"Remote-MTA: dns; %s\n",
+ fprintf(f, "Remote-MTA: dns; %s\n",
addr_dsndefer->host_used->name);
print_dsn_diagnostic_code(addr_dsndefer, f);
}
- addr_dsndefer = addr_dsndefer->next;
+ fputc('\n', f);
}
- fprintf(f, "\n--%s\n"
+ fprintf(f, "--%s\n"
"Content-type: text/rfc822-headers\n\n",
bound);
if (deliver_freeze)
{
- if (freeze_tell != NULL && freeze_tell[0] != 0 && !local_error_message)
+ if (freeze_tell && freeze_tell[0] != 0 && !local_error_message)
{
uschar *s = string_copy(frozen_info);
uschar *ss = Ustrstr(s, " by the system filter: ");
regex_must_compile(US"\\n250[\\s\\-]PRDR(\\s|\\n|$)", FALSE, TRUE);
#endif
+#ifdef SUPPORT_I18N
+if (!regex_UTF8) regex_UTF8 =
+ regex_must_compile(US"\\n250[\\s\\-]SMTPUTF8(\\s|\\n|$)", FALSE, TRUE);
+#endif
+
if (!regex_DSN) regex_DSN =
regex_must_compile(US"\\n250[\\s\\-]DSN(\\s|\\n|$)", FALSE, TRUE);
}
+uschar *
+deliver_get_sender_address (uschar * id)
+{
+int rc;
+uschar * new_sender_address,
+ * save_sender_address;
+
+if (!spool_open_datafile(id))
+ return NULL;
+
+/* Save and restore the global sender_address. I'm not sure if we should
+not save/restore all the other global variables too, because
+spool_read_header() may change all of them. But OTOH, when this
+deliver_get_sender_address() gets called, the current message is done
+already and nobody needs the globals anymore. (HS12, 2015-08-21) */
+
+sprintf(CS spoolname, "%s-H", id);
+save_sender_address = sender_address;
+
+rc = spool_read_header(spoolname, TRUE, TRUE);
+
+new_sender_address = sender_address;
+sender_address = save_sender_address;
+
+if (rc != spool_read_OK)
+ return NULL;
+
+assert(new_sender_address);
+
+(void)close(deliver_datafile);
+deliver_datafile = -1;
+
+return new_sender_address;
+}
+
/* vi: aw ai sw=2
*/
/* End of deliver.c */
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge, 1995 - 2007 */
+/* Copyright (c) University of Cambridge, 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Code for DKIM support. Other DKIM relevant code is in
#include "pdkim/pdkim.h"
-pdkim_ctx *dkim_verify_ctx = NULL;
+pdkim_ctx *dkim_verify_ctx = NULL;
pdkim_signature *dkim_signatures = NULL;
-pdkim_signature *dkim_cur_sig = NULL;
-
-int dkim_exim_query_dns_txt(char *name, char *answer) {
- dns_answer dnsa;
- dns_scan dnss;
- dns_record *rr;
-
- lookup_dnssec_authenticated = NULL;
- if (dns_lookup(&dnsa, (uschar *)name, T_TXT, NULL) != DNS_SUCCEED) return PDKIM_FAIL;
-
- /* Search for TXT record */
- for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
- rr != NULL;
- rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
- if (rr->type == T_TXT) break;
-
- /* Copy record content to the answer buffer */
- if (rr != NULL) {
+pdkim_signature *dkim_cur_sig = NULL;
+
+static int
+dkim_exim_query_dns_txt(char *name, char *answer)
+{
+dns_answer dnsa;
+dns_scan dnss;
+dns_record *rr;
+
+lookup_dnssec_authenticated = NULL;
+if (dns_lookup(&dnsa, US name, T_TXT, NULL) != DNS_SUCCEED)
+ return PDKIM_FAIL;
+
+/* Search for TXT record */
+
+for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
+ rr;
+ rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
+ if (rr->type == T_TXT)
+ {
int rr_offset = 0;
int answer_offset = 0;
- while (rr_offset < rr->size) {
- uschar len = (rr->data)[rr_offset++];
- snprintf(answer+(answer_offset),
- PDKIM_DNS_TXT_MAX_RECLEN-(answer_offset),
- "%.*s", (int)len, (char *)((rr->data)+rr_offset));
- rr_offset+=len;
- answer_offset+=len;
- if (answer_offset >= PDKIM_DNS_TXT_MAX_RECLEN) {
- return PDKIM_FAIL;
+
+ /* Copy record content to the answer buffer */
+
+ while (rr_offset < rr->size)
+ {
+ uschar len = rr->data[rr_offset++];
+ snprintf(answer + answer_offset,
+ PDKIM_DNS_TXT_MAX_RECLEN - answer_offset,
+ "%.*s", (int)len, (char *) (rr->data + rr_offset));
+ rr_offset += len;
+ answer_offset += len;
+ if (answer_offset >= PDKIM_DNS_TXT_MAX_RECLEN)
+ return PDKIM_FAIL;
}
+ return PDKIM_OK;
}
- }
- else return PDKIM_FAIL;
- return PDKIM_OK;
+return PDKIM_FAIL;
}
-void dkim_exim_verify_init(void) {
+void
+dkim_exim_verify_init(void)
+{
+/* Free previous context if there is one */
- /* Free previous context if there is one */
- if (dkim_verify_ctx) pdkim_free_ctx(dkim_verify_ctx);
+if (dkim_verify_ctx)
+ pdkim_free_ctx(dkim_verify_ctx);
- /* Create new context */
- dkim_verify_ctx = pdkim_init_verify(PDKIM_INPUT_SMTP,
- &dkim_exim_query_dns_txt
- );
-
- if (dkim_verify_ctx != NULL) {
- dkim_collect_input = TRUE;
- pdkim_set_debug_stream(dkim_verify_ctx,debug_file);
- }
- else dkim_collect_input = FALSE;
+/* Create new context */
+dkim_verify_ctx = pdkim_init_verify(&dkim_exim_query_dns_txt);
+dkim_collect_input = !!dkim_verify_ctx;
}
-void dkim_exim_verify_feed(uschar *data, int len) {
- if (dkim_collect_input &&
- pdkim_feed(dkim_verify_ctx,
- (char *)data,
- len) != PDKIM_OK) dkim_collect_input = FALSE;
+void
+dkim_exim_verify_feed(uschar * data, int len)
+{
+if ( dkim_collect_input
+ && pdkim_feed(dkim_verify_ctx, (char *)data, len) != PDKIM_OK)
+ dkim_collect_input = FALSE;
}
-void dkim_exim_verify_finish(void) {
- pdkim_signature *sig = NULL;
- int dkim_signers_size = 0;
- int dkim_signers_ptr = 0;
- dkim_signers = NULL;
+void
+dkim_exim_verify_finish(void)
+{
+pdkim_signature *sig = NULL;
+int dkim_signers_size = 0;
+int dkim_signers_ptr = 0;
+dkim_signers = NULL;
- /* Delete eventual previous signature chain */
- dkim_signatures = NULL;
+/* Delete eventual previous signature chain */
- /* If we have arrived here with dkim_collect_input == FALSE, it
- means there was a processing error somewhere along the way.
- Log the incident and disable futher verification. */
- if (!dkim_collect_input) {
- log_write(0, LOG_MAIN, "DKIM: Error while running this message through validation, disabling signature verification.");
- dkim_disable_verify = TRUE;
- return;
+dkim_signatures = NULL;
+
+/* If we have arrived here with dkim_collect_input == FALSE, it
+means there was a processing error somewhere along the way.
+Log the incident and disable futher verification. */
+
+if (!dkim_collect_input)
+ {
+ log_write(0, LOG_MAIN,
+ "DKIM: Error while running this message through validation,"
+ " disabling signature verification.");
+ dkim_disable_verify = TRUE;
+ return;
}
- dkim_collect_input = FALSE;
- /* Finish DKIM operation and fetch link to signatures chain */
- if (pdkim_feed_finish(dkim_verify_ctx,&dkim_signatures) != PDKIM_OK) return;
-
- sig = dkim_signatures;
- while (sig != NULL) {
- int size = 0;
- int ptr = 0;
- /* Log a line for each signature */
- uschar *logmsg = string_append(NULL, &size, &ptr, 5,
-
- string_sprintf( "d=%s s=%s c=%s/%s a=%s ",
- sig->domain,
- sig->selector,
- (sig->canon_headers == PDKIM_CANON_SIMPLE)?"simple":"relaxed",
- (sig->canon_body == PDKIM_CANON_SIMPLE)?"simple":"relaxed",
- (sig->algo == PDKIM_ALGO_RSA_SHA256)?"rsa-sha256":"rsa-sha1"
- ),
- ((sig->identity != NULL)?
- string_sprintf("i=%s ", sig->identity)
- :
- US""
- ),
- ((sig->created > 0)?
- string_sprintf("t=%lu ", sig->created)
- :
- US""
- ),
- ((sig->expires > 0)?
- string_sprintf("x=%lu ", sig->expires)
- :
- US""
- ),
- ((sig->bodylength > -1)?
- string_sprintf("l=%lu ", sig->bodylength)
- :
- US""
- )
- );
-
- switch(sig->verify_status) {
- case PDKIM_VERIFY_NONE:
- logmsg = string_append(logmsg, &size, &ptr, 1, "[not verified]");
+dkim_collect_input = FALSE;
+
+/* Finish DKIM operation and fetch link to signatures chain */
+
+if (pdkim_feed_finish(dkim_verify_ctx, &dkim_signatures) != PDKIM_OK)
+ return;
+
+for (sig = dkim_signatures; sig; sig = sig->next)
+ {
+ int size = 0;
+ int ptr = 0;
+
+ /* Log a line for each signature */
+
+ uschar *logmsg = string_append(NULL, &size, &ptr, 5,
+ string_sprintf("d=%s s=%s c=%s/%s a=%s b=%d ",
+ sig->domain,
+ sig->selector,
+ sig->canon_headers == PDKIM_CANON_SIMPLE ? "simple" : "relaxed",
+ sig->canon_body == PDKIM_CANON_SIMPLE ? "simple" : "relaxed",
+ sig->algo == PDKIM_ALGO_RSA_SHA256 ? "rsa-sha256" : "rsa-sha1",
+ sig->sigdata_len * 8
+ ),
+
+ sig->identity ? string_sprintf("i=%s ", sig->identity) : US"",
+ sig->created > 0 ? string_sprintf("t=%lu ", sig->created) : US"",
+ sig->expires > 0 ? string_sprintf("x=%lu ", sig->expires) : US"",
+ sig->bodylength > -1 ? string_sprintf("l=%lu ", sig->bodylength) : US""
+ );
+
+ switch (sig->verify_status)
+ {
+ case PDKIM_VERIFY_NONE:
+ logmsg = string_append(logmsg, &size, &ptr, 1, "[not verified]");
break;
- case PDKIM_VERIFY_INVALID:
- logmsg = string_append(logmsg, &size, &ptr, 1, "[invalid - ");
- switch (sig->verify_ext_status) {
- case PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE:
- logmsg = string_append(logmsg, &size, &ptr, 1, "public key record (currently?) unavailable]");
- break;
- case PDKIM_VERIFY_INVALID_BUFFER_SIZE:
- logmsg = string_append(logmsg, &size, &ptr, 1, "overlong public key record]");
- break;
- case PDKIM_VERIFY_INVALID_PUBKEY_PARSING:
- logmsg = string_append(logmsg, &size, &ptr, 1, "syntax error in public key record]");
- break;
- default:
- logmsg = string_append(logmsg, &size, &ptr, 1, "unspecified problem]");
- }
+
+ case PDKIM_VERIFY_INVALID:
+ logmsg = string_append(logmsg, &size, &ptr, 1, "[invalid - ");
+ switch (sig->verify_ext_status)
+ {
+ case PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE:
+ logmsg = string_append(logmsg, &size, &ptr, 1,
+ "public key record (currently?) unavailable]");
+ break;
+
+ case PDKIM_VERIFY_INVALID_BUFFER_SIZE:
+ logmsg = string_append(logmsg, &size, &ptr, 1,
+ "overlong public key record]");
+ break;
+
+ case PDKIM_VERIFY_INVALID_PUBKEY_PARSING:
+ logmsg = string_append(logmsg, &size, &ptr, 1,
+ "syntax error in public key record]");
+ break;
+
+ default:
+ logmsg = string_append(logmsg, &size, &ptr, 1,
+ "unspecified problem]");
+ }
break;
- case PDKIM_VERIFY_FAIL:
- logmsg = string_append(logmsg, &size, &ptr, 1, "[verification failed - ");
- switch (sig->verify_ext_status) {
- case PDKIM_VERIFY_FAIL_BODY:
- logmsg = string_append(logmsg, &size, &ptr, 1, "body hash mismatch (body probably modified in transit)]");
- break;
- case PDKIM_VERIFY_FAIL_MESSAGE:
- logmsg = string_append(logmsg, &size, &ptr, 1, "signature did not verify (headers probably modified in transit)]");
- break;
- default:
- logmsg = string_append(logmsg, &size, &ptr, 1, "unspecified reason]");
- }
+
+ case PDKIM_VERIFY_FAIL:
+ logmsg =
+ string_append(logmsg, &size, &ptr, 1, "[verification failed - ");
+ switch (sig->verify_ext_status)
+ {
+ case PDKIM_VERIFY_FAIL_BODY:
+ logmsg = string_append(logmsg, &size, &ptr, 1,
+ "body hash mismatch (body probably modified in transit)]");
+ break;
+
+ case PDKIM_VERIFY_FAIL_MESSAGE:
+ logmsg = string_append(logmsg, &size, &ptr, 1,
+ "signature did not verify (headers probably modified in transit)]");
+ break;
+
+ default:
+ logmsg = string_append(logmsg, &size, &ptr, 1, "unspecified reason]");
+ }
break;
- case PDKIM_VERIFY_PASS:
- logmsg = string_append(logmsg, &size, &ptr, 1, "[verification succeeded]");
+
+ case PDKIM_VERIFY_PASS:
+ logmsg =
+ string_append(logmsg, &size, &ptr, 1, "[verification succeeded]");
break;
}
- logmsg[ptr] = '\0';
- log_write(0, LOG_MAIN, "DKIM: %s", logmsg);
+ logmsg[ptr] = '\0';
+ log_write(0, LOG_MAIN, "DKIM: %s", logmsg);
+
+ /* Build a colon-separated list of signing domains (and identities, if present) in dkim_signers */
+
+ dkim_signers = string_append(dkim_signers,
+ &dkim_signers_size,
+ &dkim_signers_ptr, 2, sig->domain, ":");
- /* Build a colon-separated list of signing domains (and identities, if present) in dkim_signers */
+ if (sig->identity)
dkim_signers = string_append(dkim_signers,
- &dkim_signers_size,
- &dkim_signers_ptr,
- 2,
- sig->domain,
- ":"
- );
-
- if (sig->identity != NULL) {
- dkim_signers = string_append(dkim_signers,
- &dkim_signers_size,
- &dkim_signers_ptr,
- 2,
- sig->identity,
- ":"
- );
- }
+ &dkim_signers_size,
+ &dkim_signers_ptr, 2, sig->identity, ":");
- /* Process next signature */
- sig = sig->next;
+ /* Process next signature */
}
- /* NULL-terminate and chop the last colon from the domain list */
- if (dkim_signers != NULL) {
- dkim_signers[dkim_signers_ptr] = '\0';
- if (Ustrlen(dkim_signers) > 0)
- dkim_signers[Ustrlen(dkim_signers)-1] = '\0';
+/* NULL-terminate and chop the last colon from the domain list */
+
+if (dkim_signers)
+ {
+ dkim_signers[dkim_signers_ptr] = '\0';
+ if (Ustrlen(dkim_signers) > 0)
+ dkim_signers[Ustrlen(dkim_signers) - 1] = '\0';
}
}
-void dkim_exim_acl_setup(uschar *id) {
- pdkim_signature *sig = dkim_signatures;
- dkim_cur_sig = NULL;
- dkim_cur_signer = id;
- if (dkim_disable_verify ||
- !id || !dkim_verify_ctx) return;
- /* Find signature to run ACL on */
- while (sig != NULL) {
- uschar *cmp_val = NULL;
- if (Ustrchr(id,'@') != NULL) cmp_val = (uschar *)sig->identity;
- else cmp_val = (uschar *)sig->domain;
- if (cmp_val && (strcmpic(cmp_val,id) == 0)) {
- dkim_cur_sig = sig;
- /* The "dkim_domain" and "dkim_selector" expansion variables have
- related globals, since they are used in the signing code too.
- Instead of inventing separate names for verification, we set
- them here. This is easy since a domain and selector is guaranteed
- to be in a signature. The other dkim_* expansion items are
- dynamically fetched from dkim_cur_sig at expansion time (see
- function below). */
- dkim_signing_domain = (uschar *)sig->domain;
- dkim_signing_selector = (uschar *)sig->selector;
- return;
+void
+dkim_exim_acl_setup(uschar * id)
+{
+pdkim_signature * sig;
+uschar * cmp_val;
+
+dkim_cur_sig = NULL;
+dkim_cur_signer = id;
+
+if (dkim_disable_verify || !id || !dkim_verify_ctx)
+ return;
+
+/* Find signature to run ACL on */
+
+for (sig = dkim_signatures; sig; sig = sig->next)
+ if ( (cmp_val = Ustrchr(id, '@') != NULL ? US sig->identity : US sig->domain)
+ && strcmpic(cmp_val, id) == 0
+ )
+ {
+ dkim_cur_sig = sig;
+
+ /* The "dkim_domain" and "dkim_selector" expansion variables have
+ related globals, since they are used in the signing code too.
+ Instead of inventing separate names for verification, we set
+ them here. This is easy since a domain and selector is guaranteed
+ to be in a signature. The other dkim_* expansion items are
+ dynamically fetched from dkim_cur_sig at expansion time (see
+ function below). */
+
+ dkim_signing_domain = US sig->domain;
+ dkim_signing_selector = US sig->selector;
+ dkim_key_length = sig->sigdata_len * 8;
+ return;
}
- sig = sig->next;
- }
}
-uschar *dkim_exim_expand_query(int what) {
+static uschar *
+dkim_exim_expand_defaults(int what)
+{
+switch (what)
+ {
+ case DKIM_ALGO: return US"";
+ case DKIM_BODYLENGTH: return US"9999999999999";
+ case DKIM_CANON_BODY: return US"";
+ case DKIM_CANON_HEADERS: return US"";
+ case DKIM_COPIEDHEADERS: return US"";
+ case DKIM_CREATED: return US"0";
+ case DKIM_EXPIRES: return US"9999999999999";
+ case DKIM_HEADERNAMES: return US"";
+ case DKIM_IDENTITY: return US"";
+ case DKIM_KEY_GRANULARITY: return US"*";
+ case DKIM_KEY_SRVTYPE: return US"*";
+ case DKIM_KEY_NOTES: return US"";
+ case DKIM_KEY_TESTING: return US"0";
+ case DKIM_NOSUBDOMAINS: return US"0";
+ case DKIM_VERIFY_STATUS: return US"none";
+ case DKIM_VERIFY_REASON: return US"";
+ default: return US"";
+ }
+}
- if (!dkim_verify_ctx ||
- dkim_disable_verify ||
- !dkim_cur_sig) return dkim_exim_expand_defaults(what);
- switch(what) {
- case DKIM_ALGO:
- switch(dkim_cur_sig->algo) {
- case PDKIM_ALGO_RSA_SHA1:
- return US"rsa-sha1";
- case PDKIM_ALGO_RSA_SHA256:
- default:
- return US"rsa-sha256";
+uschar *
+dkim_exim_expand_query(int what)
+{
+if (!dkim_verify_ctx || dkim_disable_verify || !dkim_cur_sig)
+ return dkim_exim_expand_defaults(what);
+
+switch (what)
+ {
+ case DKIM_ALGO:
+ switch (dkim_cur_sig->algo)
+ {
+ case PDKIM_ALGO_RSA_SHA1: return US"rsa-sha1";
+ case PDKIM_ALGO_RSA_SHA256:
+ default: return US"rsa-sha256";
}
- case DKIM_BODYLENGTH:
- return (dkim_cur_sig->bodylength >= 0)?
- (uschar *)string_sprintf(OFF_T_FMT,(LONGLONG_T)dkim_cur_sig->bodylength)
- :dkim_exim_expand_defaults(what);
- case DKIM_CANON_BODY:
- switch(dkim_cur_sig->canon_body) {
- case PDKIM_CANON_RELAXED:
- return US"relaxed";
- case PDKIM_CANON_SIMPLE:
- default:
- return US"simple";
- }
- case DKIM_CANON_HEADERS:
- switch(dkim_cur_sig->canon_headers) {
- case PDKIM_CANON_RELAXED:
- return US"relaxed";
- case PDKIM_CANON_SIMPLE:
- default:
- return US"simple";
+
+ case DKIM_BODYLENGTH:
+ return dkim_cur_sig->bodylength >= 0
+ ? string_sprintf(OFF_T_FMT, (LONGLONG_T) dkim_cur_sig->bodylength)
+ : dkim_exim_expand_defaults(what);
+
+ case DKIM_CANON_BODY:
+ switch (dkim_cur_sig->canon_body)
+ {
+ case PDKIM_CANON_RELAXED: return US"relaxed";
+ case PDKIM_CANON_SIMPLE:
+ default: return US"simple";
}
- case DKIM_COPIEDHEADERS:
- return dkim_cur_sig->copiedheaders?
- (uschar *)(dkim_cur_sig->copiedheaders)
- :dkim_exim_expand_defaults(what);
- case DKIM_CREATED:
- return (dkim_cur_sig->created > 0)?
- (uschar *)string_sprintf("%llu",dkim_cur_sig->created)
- :dkim_exim_expand_defaults(what);
- case DKIM_EXPIRES:
- return (dkim_cur_sig->expires > 0)?
- (uschar *)string_sprintf("%llu",dkim_cur_sig->expires)
- :dkim_exim_expand_defaults(what);
- case DKIM_HEADERNAMES:
- return dkim_cur_sig->headernames?
- (uschar *)(dkim_cur_sig->headernames)
- :dkim_exim_expand_defaults(what);
- case DKIM_IDENTITY:
- return dkim_cur_sig->identity?
- (uschar *)(dkim_cur_sig->identity)
- :dkim_exim_expand_defaults(what);
- case DKIM_KEY_GRANULARITY:
- return dkim_cur_sig->pubkey?
- (dkim_cur_sig->pubkey->granularity?
- (uschar *)(dkim_cur_sig->pubkey->granularity)
- :dkim_exim_expand_defaults(what)
- )
- :dkim_exim_expand_defaults(what);
- case DKIM_KEY_SRVTYPE:
- return dkim_cur_sig->pubkey?
- (dkim_cur_sig->pubkey->srvtype?
- (uschar *)(dkim_cur_sig->pubkey->srvtype)
- :dkim_exim_expand_defaults(what)
- )
- :dkim_exim_expand_defaults(what);
- case DKIM_KEY_NOTES:
- return dkim_cur_sig->pubkey?
- (dkim_cur_sig->pubkey->notes?
- (uschar *)(dkim_cur_sig->pubkey->notes)
- :dkim_exim_expand_defaults(what)
- )
- :dkim_exim_expand_defaults(what);
- case DKIM_KEY_TESTING:
- return dkim_cur_sig->pubkey?
- (dkim_cur_sig->pubkey->testing?
- US"1"
- :dkim_exim_expand_defaults(what)
- )
- :dkim_exim_expand_defaults(what);
- case DKIM_NOSUBDOMAINS:
- return dkim_cur_sig->pubkey?
- (dkim_cur_sig->pubkey->no_subdomaining?
- US"1"
- :dkim_exim_expand_defaults(what)
- )
- :dkim_exim_expand_defaults(what);
- case DKIM_VERIFY_STATUS:
- switch(dkim_cur_sig->verify_status) {
- case PDKIM_VERIFY_INVALID:
- return US"invalid";
- case PDKIM_VERIFY_FAIL:
- return US"fail";
- case PDKIM_VERIFY_PASS:
- return US"pass";
- case PDKIM_VERIFY_NONE:
- default:
- return US"none";
+
+ case DKIM_CANON_HEADERS:
+ switch (dkim_cur_sig->canon_headers)
+ {
+ case PDKIM_CANON_RELAXED: return US"relaxed";
+ case PDKIM_CANON_SIMPLE:
+ default: return US"simple";
+ }
+
+ case DKIM_COPIEDHEADERS:
+ return dkim_cur_sig->copiedheaders
+ ? US dkim_cur_sig->copiedheaders : dkim_exim_expand_defaults(what);
+
+ case DKIM_CREATED:
+ return dkim_cur_sig->created > 0
+ ? string_sprintf("%llu", dkim_cur_sig->created)
+ : dkim_exim_expand_defaults(what);
+
+ case DKIM_EXPIRES:
+ return dkim_cur_sig->expires > 0
+ ? string_sprintf("%llu", dkim_cur_sig->expires)
+ : dkim_exim_expand_defaults(what);
+
+ case DKIM_HEADERNAMES:
+ return dkim_cur_sig->headernames
+ ? US dkim_cur_sig->headernames : dkim_exim_expand_defaults(what);
+
+ case DKIM_IDENTITY:
+ return dkim_cur_sig->identity
+ ? US dkim_cur_sig->identity : dkim_exim_expand_defaults(what);
+
+ case DKIM_KEY_GRANULARITY:
+ return dkim_cur_sig->pubkey
+ ? dkim_cur_sig->pubkey->granularity
+ ? US dkim_cur_sig->pubkey->granularity
+ : dkim_exim_expand_defaults(what)
+ : dkim_exim_expand_defaults(what);
+
+ case DKIM_KEY_SRVTYPE:
+ return dkim_cur_sig->pubkey
+ ? dkim_cur_sig->pubkey->srvtype
+ ? US dkim_cur_sig->pubkey->srvtype
+ : dkim_exim_expand_defaults(what)
+ : dkim_exim_expand_defaults(what);
+
+ case DKIM_KEY_NOTES:
+ return dkim_cur_sig->pubkey
+ ? dkim_cur_sig->pubkey->notes
+ ? US dkim_cur_sig->pubkey->notes
+ : dkim_exim_expand_defaults(what)
+ : dkim_exim_expand_defaults(what);
+
+ case DKIM_KEY_TESTING:
+ return dkim_cur_sig->pubkey
+ ? dkim_cur_sig->pubkey->testing
+ ? US"1"
+ : dkim_exim_expand_defaults(what)
+ : dkim_exim_expand_defaults(what);
+
+ case DKIM_NOSUBDOMAINS:
+ return dkim_cur_sig->pubkey
+ ? dkim_cur_sig->pubkey->no_subdomaining
+ ? US"1"
+ : dkim_exim_expand_defaults(what)
+ : dkim_exim_expand_defaults(what);
+
+ case DKIM_VERIFY_STATUS:
+ switch (dkim_cur_sig->verify_status)
+ {
+ case PDKIM_VERIFY_INVALID: return US"invalid";
+ case PDKIM_VERIFY_FAIL: return US"fail";
+ case PDKIM_VERIFY_PASS: return US"pass";
+ case PDKIM_VERIFY_NONE:
+ default: return US"none";
}
- case DKIM_VERIFY_REASON:
- switch (dkim_cur_sig->verify_ext_status) {
- case PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE:
- return US"pubkey_unavailable";
- case PDKIM_VERIFY_INVALID_PUBKEY_PARSING:
- return US"pubkey_syntax";
- case PDKIM_VERIFY_FAIL_BODY:
- return US"bodyhash_mismatch";
- case PDKIM_VERIFY_FAIL_MESSAGE:
- return US"signature_incorrect";
+
+ case DKIM_VERIFY_REASON:
+ switch (dkim_cur_sig->verify_ext_status)
+ {
+ case PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE:
+ return US"pubkey_unavailable";
+ case PDKIM_VERIFY_INVALID_PUBKEY_PARSING: return US"pubkey_syntax";
+ case PDKIM_VERIFY_FAIL_BODY: return US"bodyhash_mismatch";
+ case PDKIM_VERIFY_FAIL_MESSAGE: return US"signature_incorrect";
}
- default:
- return US"";
+
+ default:
+ return US"";
}
}
-uschar *dkim_exim_expand_defaults(int what) {
- switch(what) {
- case DKIM_ALGO: return US"";
- case DKIM_BODYLENGTH: return US"9999999999999";
- case DKIM_CANON_BODY: return US"";
- case DKIM_CANON_HEADERS: return US"";
- case DKIM_COPIEDHEADERS: return US"";
- case DKIM_CREATED: return US"0";
- case DKIM_EXPIRES: return US"9999999999999";
- case DKIM_HEADERNAMES: return US"";
- case DKIM_IDENTITY: return US"";
- case DKIM_KEY_GRANULARITY: return US"*";
- case DKIM_KEY_SRVTYPE: return US"*";
- case DKIM_KEY_NOTES: return US"";
- case DKIM_KEY_TESTING: return US"0";
- case DKIM_NOSUBDOMAINS: return US"0";
- case DKIM_VERIFY_STATUS: return US"none";
- case DKIM_VERIFY_REASON: return US"";
- default: return US"";
+uschar *
+dkim_exim_sign(int dkim_fd, uschar * dkim_private_key,
+ const uschar * dkim_domain, uschar * dkim_selector,
+ uschar * dkim_canon, uschar * dkim_sign_headers)
+{
+int sep = 0;
+uschar *seen_items = NULL;
+int seen_items_size = 0;
+int seen_items_offset = 0;
+uschar itembuf[256];
+uschar *dkim_canon_expanded;
+uschar *dkim_sign_headers_expanded;
+uschar *dkim_private_key_expanded;
+pdkim_ctx *ctx = NULL;
+uschar *rc = NULL;
+uschar *sigbuf = NULL;
+int sigsize = 0;
+int sigptr = 0;
+pdkim_signature *signature;
+int pdkim_canon;
+int pdkim_rc;
+int sread;
+char buf[4096];
+int save_errno = 0;
+int old_pool = store_pool;
+
+store_pool = POOL_MAIN;
+
+if (!(dkim_domain = expand_cstring(dkim_domain)))
+ {
+ /* expansion error, do not send message. */
+ log_write(0, LOG_MAIN | LOG_PANIC, "failed to expand "
+ "dkim_domain: %s", expand_string_message);
+ rc = NULL;
+ goto CLEANUP;
}
-}
+/* Set $dkim_domain expansion variable to each unique domain in list. */
+
+while ((dkim_signing_domain = string_nextinlist(&dkim_domain, &sep,
+ itembuf, sizeof(itembuf))))
+ {
+ if (!dkim_signing_domain || dkim_signing_domain[0] == '\0')
+ continue;
+
+ /* Only sign once for each domain, no matter how often it
+ appears in the expanded list. */
+
+ if (seen_items)
+ {
+ const uschar *seen_items_list = seen_items;
+ if (match_isinlist(dkim_signing_domain,
+ &seen_items_list, 0, NULL, NULL, MCL_STRING, TRUE,
+ NULL) == OK)
+ continue;
+
+ seen_items =
+ string_append(seen_items, &seen_items_size, &seen_items_offset, 1, ":");
+ }
+
+ seen_items =
+ string_append(seen_items, &seen_items_size, &seen_items_offset, 1,
+ dkim_signing_domain);
+ seen_items[seen_items_offset] = '\0';
+
+ /* Set up $dkim_selector expansion variable. */
-uschar *dkim_exim_sign(int dkim_fd,
- uschar *dkim_private_key,
- uschar *dkim_domain,
- uschar *dkim_selector,
- uschar *dkim_canon,
- uschar *dkim_sign_headers) {
- int sep = 0;
- uschar *seen_items = NULL;
- int seen_items_size = 0;
- int seen_items_offset = 0;
- uschar itembuf[256];
- uschar *dkim_canon_expanded;
- uschar *dkim_sign_headers_expanded;
- uschar *dkim_private_key_expanded;
- pdkim_ctx *ctx = NULL;
- uschar *rc = NULL;
- uschar *sigbuf = NULL;
- int sigsize = 0;
- int sigptr = 0;
- pdkim_signature *signature;
- int pdkim_canon;
- int pdkim_rc;
- int sread;
- char buf[4096];
- int save_errno = 0;
- int old_pool = store_pool;
-
- store_pool = POOL_MAIN;
-
- dkim_domain = expand_string(dkim_domain);
- if (dkim_domain == NULL) {
+ if (!(dkim_signing_selector = expand_string(dkim_selector)))
+ {
+ log_write(0, LOG_MAIN | LOG_PANIC, "failed to expand "
+ "dkim_selector: %s", expand_string_message);
+ rc = NULL;
+ goto CLEANUP;
+ }
+
+ /* Get canonicalization to use */
+
+ dkim_canon_expanded = dkim_canon ? expand_string(dkim_canon) : US"relaxed";
+ if (!dkim_canon_expanded)
+ {
/* expansion error, do not send message. */
- log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand "
- "dkim_domain: %s", expand_string_message);
+ log_write(0, LOG_MAIN | LOG_PANIC, "failed to expand "
+ "dkim_canon: %s", expand_string_message);
rc = NULL;
goto CLEANUP;
- }
+ }
- /* Set $dkim_domain expansion variable to each unique domain in list. */
- while ((dkim_signing_domain = string_nextinlist(&dkim_domain, &sep,
- itembuf,
- sizeof(itembuf))) != NULL) {
- if (!dkim_signing_domain || (dkim_signing_domain[0] == '\0')) continue;
- /* Only sign once for each domain, no matter how often it
- appears in the expanded list. */
- if (seen_items != NULL) {
- uschar *seen_items_list = seen_items;
- if (match_isinlist(dkim_signing_domain,
- &seen_items_list,0,NULL,NULL,MCL_STRING,TRUE,NULL) == OK)
- continue;
- seen_items = string_append(seen_items,&seen_items_size,&seen_items_offset,1,":");
+ if (Ustrcmp(dkim_canon_expanded, "relaxed") == 0)
+ pdkim_canon = PDKIM_CANON_RELAXED;
+ else if (Ustrcmp(dkim_canon_expanded, "simple") == 0)
+ pdkim_canon = PDKIM_CANON_SIMPLE;
+ else
+ {
+ log_write(0, LOG_MAIN,
+ "DKIM: unknown canonicalization method '%s', defaulting to 'relaxed'.\n",
+ dkim_canon_expanded);
+ pdkim_canon = PDKIM_CANON_RELAXED;
}
- seen_items = string_append(seen_items,&seen_items_size,&seen_items_offset,1,dkim_signing_domain);
- seen_items[seen_items_offset] = '\0';
-
- /* Set up $dkim_selector expansion variable. */
- dkim_signing_selector = expand_string(dkim_selector);
- if (dkim_signing_selector == NULL) {
- log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand "
- "dkim_selector: %s", expand_string_message);
+
+ dkim_sign_headers_expanded = NULL;
+ if (dkim_sign_headers)
+ if (!(dkim_sign_headers_expanded = expand_string(dkim_sign_headers)))
+ {
+ log_write(0, LOG_MAIN | LOG_PANIC, "failed to expand "
+ "dkim_sign_headers: %s", expand_string_message);
rc = NULL;
goto CLEANUP;
+ }
+ /* else pass NULL, which means default header list */
+
+ /* Get private key to use. */
+
+ if (!(dkim_private_key_expanded = expand_string(dkim_private_key)))
+ {
+ log_write(0, LOG_MAIN | LOG_PANIC, "failed to expand "
+ "dkim_private_key: %s", expand_string_message);
+ rc = NULL;
+ goto CLEANUP;
}
- /* Get canonicalization to use */
- dkim_canon_expanded = expand_string(dkim_canon?dkim_canon:US"relaxed");
- if (dkim_canon_expanded == NULL) {
- /* expansion error, do not send message. */
- log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand "
- "dkim_canon: %s", expand_string_message);
+ if ( Ustrlen(dkim_private_key_expanded) == 0
+ || Ustrcmp(dkim_private_key_expanded, "0") == 0
+ || Ustrcmp(dkim_private_key_expanded, "false") == 0
+ )
+ continue; /* don't sign, but no error */
+
+ if (dkim_private_key_expanded[0] == '/')
+ {
+ int privkey_fd = 0;
+
+ /* Looks like a filename, load the private key. */
+
+ memset(big_buffer, 0, big_buffer_size);
+ privkey_fd = open(CS dkim_private_key_expanded, O_RDONLY);
+ if (privkey_fd < 0)
+ {
+ log_write(0, LOG_MAIN | LOG_PANIC, "unable to open "
+ "private key file for reading: %s",
+ dkim_private_key_expanded);
rc = NULL;
goto CLEANUP;
- }
- if (Ustrcmp(dkim_canon_expanded, "relaxed") == 0)
- pdkim_canon = PDKIM_CANON_RELAXED;
- else if (Ustrcmp(dkim_canon_expanded, "simple") == 0)
- pdkim_canon = PDKIM_CANON_SIMPLE;
- else {
- log_write(0, LOG_MAIN, "DKIM: unknown canonicalization method '%s', defaulting to 'relaxed'.\n",dkim_canon_expanded);
- pdkim_canon = PDKIM_CANON_RELAXED;
- }
-
- if (dkim_sign_headers) {
- dkim_sign_headers_expanded = expand_string(dkim_sign_headers);
- if (dkim_sign_headers_expanded == NULL) {
- log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand "
- "dkim_sign_headers: %s", expand_string_message);
- rc = NULL;
- goto CLEANUP;
}
- }
- else {
- /* pass NULL, which means default header list */
- dkim_sign_headers_expanded = NULL;
- }
- /* Get private key to use. */
- dkim_private_key_expanded = expand_string(dkim_private_key);
- if (dkim_private_key_expanded == NULL) {
- log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand "
- "dkim_private_key: %s", expand_string_message);
+ if (read(privkey_fd, big_buffer, big_buffer_size - 2) < 0)
+ {
+ log_write(0, LOG_MAIN|LOG_PANIC, "unable to read private key file: %s",
+ dkim_private_key_expanded);
rc = NULL;
goto CLEANUP;
- }
- if ( (Ustrlen(dkim_private_key_expanded) == 0) ||
- (Ustrcmp(dkim_private_key_expanded,"0") == 0) ||
- (Ustrcmp(dkim_private_key_expanded,"false") == 0) ) {
- /* don't sign, but no error */
- continue;
- }
-
- if (dkim_private_key_expanded[0] == '/') {
- int privkey_fd = 0;
- /* Looks like a filename, load the private key. */
- memset(big_buffer,0,big_buffer_size);
- privkey_fd = open(CS dkim_private_key_expanded,O_RDONLY);
- if (privkey_fd < 0) {
- log_write(0, LOG_MAIN|LOG_PANIC, "unable to open "
- "private key file for reading: %s", dkim_private_key_expanded);
- rc = NULL;
- goto CLEANUP;
- }
- if (read(privkey_fd,big_buffer,(big_buffer_size-2)) < 0) {
- log_write(0, LOG_MAIN|LOG_PANIC, "unable to read private key file: %s",
- dkim_private_key_expanded);
- rc = NULL;
- goto CLEANUP;
}
- (void)close(privkey_fd);
- dkim_private_key_expanded = big_buffer;
- }
- ctx = pdkim_init_sign(PDKIM_INPUT_SMTP,
- (char *)dkim_signing_domain,
- (char *)dkim_signing_selector,
- (char *)dkim_private_key_expanded
- );
-
- pdkim_set_debug_stream(ctx,debug_file);
-
- pdkim_set_optional(ctx,
- (char *)dkim_sign_headers_expanded,
- NULL,
- pdkim_canon,
- pdkim_canon,
- -1,
- PDKIM_ALGO_RSA_SHA256,
- 0,
- 0);
-
- lseek(dkim_fd, 0, SEEK_SET);
- while((sread = read(dkim_fd,&buf,4096)) > 0) {
- if (pdkim_feed(ctx,buf,sread) != PDKIM_OK) {
- rc = NULL;
- goto CLEANUP;
- }
+ (void) close(privkey_fd);
+ dkim_private_key_expanded = big_buffer;
}
- /* Handle failed read above. */
- if (sread == -1) {
- debug_printf("DKIM: Error reading -K file.\n");
- save_errno = errno;
+
+ ctx = pdkim_init_sign( (char *) dkim_signing_domain,
+ (char *) dkim_signing_selector,
+ (char *) dkim_private_key_expanded);
+ pdkim_set_optional(ctx,
+ (char *) dkim_sign_headers_expanded,
+ NULL,
+ pdkim_canon,
+ pdkim_canon, -1, PDKIM_ALGO_RSA_SHA256, 0, 0);
+
+ lseek(dkim_fd, 0, SEEK_SET);
+
+ while ((sread = read(dkim_fd, &buf, 4096)) > 0)
+ if (pdkim_feed(ctx, buf, sread) != PDKIM_OK)
+ {
rc = NULL;
goto CLEANUP;
+ }
+
+ /* Handle failed read above. */
+ if (sread == -1)
+ {
+ debug_printf("DKIM: Error reading -K file.\n");
+ save_errno = errno;
+ rc = NULL;
+ goto CLEANUP;
}
- pdkim_rc = pdkim_feed_finish(ctx,&signature);
- if (pdkim_rc != PDKIM_OK) {
- log_write(0, LOG_MAIN|LOG_PANIC, "DKIM: signing failed (RC %d)", pdkim_rc);
- rc = NULL;
- goto CLEANUP;
+ if ((pdkim_rc = pdkim_feed_finish(ctx, &signature)) != PDKIM_OK)
+ {
+ log_write(0, LOG_MAIN|LOG_PANIC, "DKIM: signing failed (RC %d)", pdkim_rc);
+ rc = NULL;
+ goto CLEANUP;
}
- sigbuf = string_append(sigbuf, &sigsize, &sigptr, 2,
- US signature->signature_header,
- US"\r\n");
+ sigbuf = string_append(sigbuf, &sigsize, &sigptr, 2,
+ US signature->signature_header, US"\r\n");
- pdkim_free_ctx(ctx);
- ctx = NULL;
+ pdkim_free_ctx(ctx);
+ ctx = NULL;
}
- if (sigbuf != NULL) {
- sigbuf[sigptr] = '\0';
- rc = sigbuf;
- } else
- rc = US"";
-
- CLEANUP:
- if (ctx != NULL)
- pdkim_free_ctx(ctx);
- store_pool = old_pool;
- errno = save_errno;
- return rc;
+if (sigbuf)
+ {
+ sigbuf[sigptr] = '\0';
+ rc = sigbuf;
+ }
+else
+ rc = US"";
+
+CLEANUP:
+if (ctx)
+ pdkim_free_ctx(ctx);
+store_pool = old_pool;
+errno = save_errno;
+return rc;
}
#endif
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge, 1995 - 2007 */
+/* Copyright (c) University of Cambridge, 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
-uschar *dkim_exim_sign(int,uschar *,uschar *,uschar *,uschar *,uschar *);
+uschar *dkim_exim_sign(int, uschar *, const uschar *, uschar *, uschar *, uschar *);
void dkim_exim_verify_init(void);
void dkim_exim_verify_feed(uschar *, int);
void dkim_exim_verify_finish(void);
void dkim_exim_acl_setup(uschar *);
uschar *dkim_exim_expand_query(int);
-uschar *dkim_exim_expand_defaults(int);
#define DKIM_ALGO 1
#define DKIM_BODYLENGTH 2
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Functions for interfacing with the DNS. */
#include "exim.h"
-/* Function declaration needed for mutual recursion when A6 records
-are supported. */
-
-#if HAVE_IPV6
-#ifdef SUPPORT_A6
-static void dns_complete_a6(dns_address ***, dns_answer *, dns_record *,
- int, uschar *);
-#endif
-#endif
-
/*************************************************
* Fake DNS resolver *
also return a code specifying that the name should be passed on.
Background: the original test suite required a real nameserver to carry the
-test zones, whereas the new test suit has the fake server for portability. This
+test zones, whereas the new test suite has the fake server for portability. This
code supports both.
Arguments:
*/
static int
-fakens_search(uschar *domain, int type, uschar *answerptr, int size)
+fakens_search(const uschar *domain, int type, uschar *answerptr, int size)
{
int len = Ustrlen(domain);
int asize = size; /* Locally modified */
-uschar *endname;
uschar name[256];
uschar utilname[256];
uschar *aptr = answerptr; /* Locally modified */
if (domain[len - 1] == '.') len--;
Ustrncpy(name, domain, len);
name[len] = 0;
-endname = name + len;
-
-/* This code, for forcing TRY_AGAIN and NO_RECOVERY, is here so that it works
-for the old test suite that uses a real nameserver. When the old test suite is
-eventually abandoned, this code could be moved into the fakens utility. */
-
-if (len >= 14 && Ustrcmp(endname - 14, "test.again.dns") == 0)
- {
- int delay = Uatoi(name); /* digits at the start of the name */
- DEBUG(D_dns) debug_printf("Return from DNS lookup of %s (%s) faked for testing\n",
- name, dns_text_type(type));
- if (delay > 0)
- {
- DEBUG(D_dns) debug_printf("delaying %d seconds\n", delay);
- sleep(delay);
- }
- h_errno = TRY_AGAIN;
- return -1;
- }
-
-if (len >= 13 && Ustrcmp(endname - 13, "test.fail.dns") == 0)
- {
- DEBUG(D_dns) debug_printf("Return from DNS lookup of %s (%s) faked for testing\n",
- name, dns_text_type(type));
- h_errno = NO_RECOVERY;
- return -1;
- }
/* Look for the fakens utility, and if it exists, call it. */
-(void)string_format(utilname, sizeof(utilname), "%s/../bin/fakens",
- spool_directory);
+(void)string_format(utilname, sizeof(utilname), "%s/bin/fakens",
+ config_main_directory);
if (stat(CS utilname, &statbuf) >= 0)
{
int infd, outfd, rc;
uschar *argv[5];
- DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) using fakens\n",
- name, dns_text_type(type));
+ DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) using fakens\n", name, dns_text_type(type));
argv[0] = utilname;
- argv[1] = spool_directory;
+ argv[1] = config_main_directory;
argv[2] = name;
argv[3] = dns_text_type(type);
argv[4] = NULL;
asize -= rc; /* may need to be passed on to res_search(). */
}
+ /* If we ran out of output buffer before exhausting the return,
+ carry on reading and counting it. */
+
+ if (asize == 0)
+ while ((rc = read(outfd, name, sizeof(name))) > 0)
+ len += rc;
+
if (rc < 0)
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "read from fakens failed: %s",
strerror(errno));
DEBUG(D_dns) debug_printf("fakens returned PASS_ON\n");
}
}
+else
+ {
+ DEBUG(D_dns) debug_printf("fakens (%s) not found\n", utilname);
+ }
/* fakens utility not found, or it returned "pass on" */
*/
void
-dns_build_reverse(uschar *string, uschar *buffer)
+dns_build_reverse(const uschar *string, uschar *buffer)
{
-uschar *p = string + Ustrlen(string);
+const uschar *p = string + Ustrlen(string);
uschar *pp = buffer;
/* Handle IPv4 address */
int i;
for (i = 0; i < 4; i++)
{
- uschar *ppp = p;
+ const uschar *ppp = p;
while (ppp > string && ppp[-1] != '.') ppp--;
Ustrncpy(pp, ppp, p - ppp);
pp += p - ppp;
dnss->aptr += namelen;
GETSHORT(dnss->srr.type, dnss->aptr); /* Record type */
-dnss->aptr += 6; /* Don't want class or TTL */
+dnss->aptr += 2; /* Don't want class */
+GETLONG(dnss->srr.ttl, dnss->aptr); /* TTL */
GETSHORT(dnss->srr.size, dnss->aptr); /* Size of data portion */
dnss->srr.data = dnss->aptr; /* The record's data follows */
dnss->aptr += dnss->srr.size; /* Advance to next RR */
}
+/* Extract the AUTHORITY information from the answer. If the
+answer isn't authoritive (AA not set), we do not extract anything.
+
+The AUTHORITIVE section contains NS records if
+the name in question was found, it contains a SOA record
+otherwise. (This is just from experience and some tests, is there
+some spec?)
+
+We've cycle through the AUTHORITY section, since it may contain
+other records (e.g. NSEC3) too. */
+
+static const uschar *
+dns_extract_auth_name(const dns_answer * dnsa) /* FIXME: const dns_answer */
+{
+dns_scan dnss;
+dns_record * rr;
+HEADER * h = (HEADER *) dnsa->answer;
+
+if (!h->nscount || !h->aa) return NULL;
+for (rr = dns_next_rr((dns_answer*) dnsa, &dnss, RESET_AUTHORITY);
+ rr;
+ rr = dns_next_rr((dns_answer*) dnsa, &dnss, RESET_NEXT))
+ if (rr->type == (h->ancount ? T_NS : T_SOA)) return rr->name;
+return NULL;
+}
+
+
/*************************************************
/* We do not perform DNSSEC work ourselves; if the administrator has installed
a verifying resolver which sets AD as appropriate, though, we'll use that.
-(AD = Authentic Data)
+(AD = Authentic Data, AA = Authoritive Answer)
Argument: pointer to dns answer block
Returns: bool indicating presence of AD bit
*/
BOOL
-dns_is_secure(dns_answer *dnsa)
+dns_is_secure(const dns_answer * dnsa)
{
#ifdef DISABLE_DNSSEC
DEBUG(D_dns)
debug_printf("DNSSEC support disabled at build-time; dns_is_secure() false\n");
return FALSE;
#else
-HEADER *h = (HEADER *)dnsa->answer;
-return h->ad ? TRUE : FALSE;
+HEADER * h = (HEADER *) dnsa->answer;
+const uschar * auth_name;
+const uschar * trusted;
+
+if (h->ad) return TRUE;
+
+/* If the resolver we ask is authoritive for the domain in question, it
+* may not set the AD but the AA bit. If we explicitly trust
+* the resolver for that domain (via a domainlist in dns_trust_aa),
+* we return TRUE to indicate a secure answer.
+*/
+
+if ( !h->aa
+ || !dns_trust_aa
+ || !(trusted = expand_string(dns_trust_aa))
+ || !*trusted
+ || !(auth_name = dns_extract_auth_name(dnsa))
+ || OK != match_isinlist(auth_name, &trusted, 0, NULL, NULL,
+ MCL_DOMAIN, TRUE, NULL)
+ )
+ return FALSE;
+
+DEBUG(D_dns) debug_printf("DNS faked the AD bit "
+ "(got AA and matched with dns_trust_aa (%s in %s))\n",
+ auth_name, dns_trust_aa);
+
+return TRUE;
#endif
}
static void
dns_set_insecure(dns_answer * dnsa)
{
+#ifndef DISABLE_DNSSEC
HEADER * h = (HEADER *)dnsa->answer;
h->ad = 0;
+#endif
}
+/************************************************
+ * Check whether the AA bit is set *
+ * We need this to warn if we requested AD *
+ * from an authoritive server *
+ ************************************************/
+BOOL
+dns_is_aa(const dns_answer *dnsa)
+{
+#ifdef DISABLE_DNSSEC
+return FALSE;
+#else
+return ((HEADER*)dnsa->answer)->aa;
+#endif
+}
*/
static int
-dns_return(uschar *name, int type, int rc)
+dns_return(const uschar * name, int type, int rc)
{
res_state resp = os_get_dns_resolver_res();
tree_node *node = store_get_perm(sizeof(tree_node) + 290);
sprintf(CS node->name, "%.255s-%s-%lx", name, dns_text_type(type),
- resp->options);
+ (unsigned long) resp->options);
node->data.val = rc;
(void)tree_insertnode(&tree_dns_fails, node);
return rc;
}
-
-
/*************************************************
* Do basic DNS lookup *
*************************************************/
*/
int
-dns_basic_lookup(dns_answer *dnsa, uschar *name, int type)
+dns_basic_lookup(dns_answer *dnsa, const uschar *name, int type)
{
#ifndef STAND_ALONE
int rc = -1;
-uschar *save;
+const uschar *save_domain;
#endif
res_state resp = os_get_dns_resolver_res();
caching for successful lookups. */
sprintf(CS node_name, "%.255s-%s-%lx", name, dns_text_type(type),
- resp->options);
+ (unsigned long) resp->options);
previous = tree_search(tree_dns_fails, node_name);
if (previous != NULL)
{
return previous->data.val;
}
+#ifdef SUPPORT_I18N
+/* Convert all names to a-label form before doing lookup */
+ {
+ uschar * alabel;
+ uschar * errstr = NULL;
+ DEBUG(D_dns) if (string_is_utf8(name))
+ debug_printf("convert utf8 '%s' to alabel for for lookup\n", name);
+ if ((alabel = string_domain_utf8_to_alabel(name, &errstr)), errstr)
+ {
+ DEBUG(D_dns)
+ debug_printf("DNS name '%s' utf8 conversion to alabel failed: %s\n", name,
+ errstr);
+ host_find_failed_syntax = TRUE;
+ return DNS_NOMATCH;
+ }
+ name = alabel;
+ }
+#endif
+
/* If configured, check the hygene of the name passed to lookup. Otherwise,
although DNS lookups may give REFUSED at the lower level, some resolvers
turn this into TRY_AGAIN, which is silly. Give a NOMATCH return, since such
if (check_dns_names_pattern[0] != 0 && type != T_PTR && type != T_TXT)
{
- uschar *checkname = name;
+ const uschar *checkname = name;
int ovector[3*(EXPAND_MAXN+1)];
dns_pattern_init();
while (*checkname++ != '.');
}
- if (pcre_exec(regex_check_dns_names, NULL, CS checkname, Ustrlen(checkname),
+ if (pcre_exec(regex_check_dns_names, NULL, CCS checkname, Ustrlen(checkname),
0, PCRE_EOPT, ovector, sizeof(ovector)/sizeof(int)) < 0)
{
DEBUG(D_dns)
nameservers are also believed to do this. It is, of course, contrary to the
specification of the DNS, so we lock it out. */
-if ((
- #ifdef SUPPORT_A6
- type == T_A6 ||
- #endif
- type == T_A || type == T_AAAA) &&
- string_is_ip_address(name, NULL) != 0)
+if ((type == T_A || type == T_AAAA) && string_is_ip_address(name, NULL) != 0)
return DNS_NOMATCH;
/* If we are running in the test harness, instead of calling the normal resolver
(res_search), we call fakens_search(), which recognizes certain special
domains, and interfaces to a fake nameserver for certain special zones. */
-if (running_in_test_harness)
- dnsa->answerlen = fakens_search(name, type, dnsa->answer, MAXPACKET);
-else
- dnsa->answerlen = res_search(CS name, C_IN, type, dnsa->answer, MAXPACKET);
+dnsa->answerlen = running_in_test_harness
+ ? fakens_search(name, type, dnsa->answer, MAXPACKET)
+ : res_search(CCS name, C_IN, type, dnsa->answer, MAXPACKET);
if (dnsa->answerlen > MAXPACKET)
{
name, dns_text_type(type));
/* Cut this out for various test programs */
- #ifndef STAND_ALONE
- save = deliver_domain;
- deliver_domain = name; /* set $domain */
- rc = match_isinlist(name, &dns_again_means_nonexist, 0, NULL, NULL,
+#ifndef STAND_ALONE
+ save_domain = deliver_domain;
+ deliver_domain = string_copy(name); /* set $domain */
+ rc = match_isinlist(name, (const uschar **)&dns_again_means_nonexist, 0, NULL, NULL,
MCL_DOMAIN, TRUE, NULL);
- deliver_domain = save;
+ deliver_domain = save_domain;
if (rc != OK)
{
DEBUG(D_dns) debug_printf("returning DNS_AGAIN\n");
"DNS_NOMATCH\n", name);
return dns_return(name, type, DNS_NOMATCH);
- #else /* For stand-alone tests */
+#else /* For stand-alone tests */
return dns_return(name, type, DNS_AGAIN);
- #endif
+#endif
case NO_RECOVERY:
DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave NO_RECOVERY\n"
If fully_qualified_name is not NULL, set it to point to the full name
returned by the resolver, if this is different to what it is given, unless
the returned name starts with "*" as some nameservers seem to be returning
-wildcards in this form.
+wildcards in this form. In international mode "different" means "alabel
+forms are different".
Arguments:
dnsa pointer to dns_answer structure
*/
int
-dns_lookup(dns_answer *dnsa, uschar *name, int type, uschar **fully_qualified_name)
+dns_lookup(dns_answer *dnsa, const uschar *name, int type,
+ const uschar **fully_qualified_name)
{
int i;
const uschar *orig_name = name;
cname_rr.data = type_rr.data = NULL;
for (rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS);
- rr != NULL;
+ rr;
rr = dns_next_rr(dnsa, &dnss, RESET_NEXT))
{
if (rr->type == type)
if (i == 0 && fully_qualified_name != NULL)
{
- if (cname_rr.data != NULL)
- {
- if (Ustrcmp(cname_rr.name, *fully_qualified_name) != 0 &&
- cname_rr.name[0] != '*')
- *fully_qualified_name = string_copy_dnsdomain(cname_rr.name);
- }
- else if (type_rr.data != NULL)
- {
- if (Ustrcmp(type_rr.name, *fully_qualified_name) != 0 &&
- type_rr.name[0] != '*')
- *fully_qualified_name = string_copy_dnsdomain(type_rr.name);
- }
+ uschar * rr_name = cname_rr.data ? cname_rr.name
+ : type_rr.data ? type_rr.name : NULL;
+ if ( rr_name
+ && Ustrcmp(rr_name, *fully_qualified_name) != 0
+ && rr_name[0] != '*'
+#ifdef SUPPORT_I18N
+ && ( !string_is_utf8(*fully_qualified_name)
+ || Ustrcmp(rr_name,
+ string_domain_utf8_to_alabel(*fully_qualified_name, NULL)) != 0
+ )
+#endif
+ )
+ *fully_qualified_name = string_copy_dnsdomain(rr_name);
}
/* If any data records of the correct type were found, we are done. */
if (cname_rr.data == NULL) return DNS_FAIL;
datalen = dn_expand(dnsa->answer, dnsa->answer + dnsa->answerlen,
- cname_rr.data, (DN_EXPAND_ARG4_TYPE)data, 256);
+ cname_rr.data, (DN_EXPAND_ARG4_TYPE)data, sizeof(data));
if (datalen < 0) return DNS_FAIL;
name = data;
* Do a DNS lookup and handle virtual types *
************************************************/
-/* This function handles some invented "lookup types" that synthesize feature
+/* This function handles some invented "lookup types" that synthesize features
not available in the basic types. The special types all have negative values.
Positive type values are passed straight on to dns_lookup().
*/
int
-dns_special_lookup(dns_answer *dnsa, uschar *name, int type,
- uschar **fully_qualified_name)
+dns_special_lookup(dns_answer *dnsa, const uschar *name, int type,
+ const uschar **fully_qualified_name)
{
-if (type >= 0) return dns_lookup(dnsa, name, type, fully_qualified_name);
-
-/* The "mx hosts only" type doesn't require any special action here */
-
-if (type == T_MXH) return dns_lookup(dnsa, name, T_MX, fully_qualified_name);
-
-/* Find nameservers for the domain or the nearest enclosing zone, excluding the
-root servers. */
-
-if (type == T_ZNS)
+switch (type)
{
- uschar *d = name;
- while (d != 0)
+ /* The "mx hosts only" type doesn't require any special action here */
+ case T_MXH:
+ return dns_lookup(dnsa, name, T_MX, fully_qualified_name);
+
+ /* Find nameservers for the domain or the nearest enclosing zone, excluding
+ the root servers. */
+ case T_ZNS:
+ type = T_NS;
+ /* FALLTHROUGH */
+ case T_SOA:
{
- int rc = dns_lookup(dnsa, d, T_NS, fully_qualified_name);
- if (rc != DNS_NOMATCH && rc != DNS_NODATA) return rc;
- while (*d != 0 && *d != '.') d++;
- if (*d++ == 0) break;
+ const uschar *d = name;
+ while (d != 0)
+ {
+ int rc = dns_lookup(dnsa, d, type, fully_qualified_name);
+ if (rc != DNS_NOMATCH && rc != DNS_NODATA) return rc;
+ while (*d != 0 && *d != '.') d++;
+ if (*d++ == 0) break;
+ }
+ return DNS_NOMATCH;
}
- return DNS_NOMATCH;
- }
-
-/* Try to look up the Client SMTP Authorization SRV record for the name. If
-there isn't one, search from the top downwards for a CSA record in a parent
-domain, which might be making assertions about subdomains. If we find a record
-we set fully_qualified_name to whichever lookup succeeded, so that the caller
-can tell whether to look at the explicit authorization field or the subdomain
-assertion field. */
-
-if (type == T_CSA)
- {
- uschar *srvname, *namesuff, *tld, *p;
- int priority, weight, port;
- int limit, rc, i;
- BOOL ipv6;
- dns_record *rr;
- dns_scan dnss;
-
- DEBUG(D_dns) debug_printf("CSA lookup of %s\n", name);
- srvname = string_sprintf("_client._smtp.%s", name);
- rc = dns_lookup(dnsa, srvname, T_SRV, NULL);
- if (rc == DNS_SUCCEED || rc == DNS_AGAIN)
+ /* Try to look up the Client SMTP Authorization SRV record for the name. If
+ there isn't one, search from the top downwards for a CSA record in a parent
+ domain, which might be making assertions about subdomains. If we find a record
+ we set fully_qualified_name to whichever lookup succeeded, so that the caller
+ can tell whether to look at the explicit authorization field or the subdomain
+ assertion field. */
+ case T_CSA:
{
- if (rc == DNS_SUCCEED) *fully_qualified_name = name;
- return rc;
- }
-
- /* Search for CSA subdomain assertion SRV records from the top downwards,
- starting with the 2nd level domain. This order maximizes cache-friendliness.
- We skip the top level domains to avoid loading their nameservers and because
- we know they'll never have CSA SRV records. */
-
- namesuff = Ustrrchr(name, '.');
- if (namesuff == NULL) return DNS_NOMATCH;
- tld = namesuff + 1;
- ipv6 = FALSE;
- limit = dns_csa_search_limit;
+ uschar *srvname, *namesuff, *tld, *p;
+ int priority, weight, port;
+ int limit, rc, i;
+ BOOL ipv6;
+ dns_record *rr;
+ dns_scan dnss;
- /* Use more appropriate search parameters if we are in the reverse DNS. */
+ DEBUG(D_dns) debug_printf("CSA lookup of %s\n", name);
- if (strcmpic(namesuff, US".arpa") == 0)
- {
- if (namesuff - 8 > name && strcmpic(namesuff - 8, US".in-addr.arpa") == 0)
- {
- namesuff -= 8;
- tld = namesuff + 1;
- limit = 3;
- }
- else if (namesuff - 4 > name && strcmpic(namesuff - 4, US".ip6.arpa") == 0)
+ srvname = string_sprintf("_client._smtp.%s", name);
+ rc = dns_lookup(dnsa, srvname, T_SRV, NULL);
+ if (rc == DNS_SUCCEED || rc == DNS_AGAIN)
{
- namesuff -= 4;
- tld = namesuff + 1;
- ipv6 = TRUE;
- limit = 3;
+ if (rc == DNS_SUCCEED) *fully_qualified_name = string_copy(name);
+ return rc;
}
- }
-
- DEBUG(D_dns) debug_printf("CSA TLD %s\n", tld);
-
- /* Do not perform the search if the top level or 2nd level domains do not
- exist. This is quite common, and when it occurs all the search queries would
- go to the root or TLD name servers, which is not friendly. So we check the
- AUTHORITY section; if it contains the root's SOA record or the TLD's SOA then
- the TLD or the 2LD (respectively) doesn't exist and we can skip the search.
- If the TLD and the 2LD exist but the explicit CSA record lookup failed, then
- the AUTHORITY SOA will be the 2LD's or a subdomain thereof. */
-
- if (rc == DNS_NOMATCH)
- {
- /* This is really gross. The successful return value from res_search() is
- the packet length, which is stored in dnsa->answerlen. If we get a
- negative DNS reply then res_search() returns -1, which causes the bounds
- checks for name decompression to fail when it is treated as a packet
- length, which in turn causes the authority search to fail. The correct
- packet length has been lost inside libresolv, so we have to guess a
- replacement value. (The only way to fix this properly would be to
- re-implement res_search() and res_query() so that they don't muddle their
- success and packet length return values.) For added safety we only reset
- the packet length if the packet header looks plausible. */
-
- HEADER *h = (HEADER *)dnsa->answer;
- if (h->qr == 1 && h->opcode == QUERY && h->tc == 0
- && (h->rcode == NOERROR || h->rcode == NXDOMAIN)
- && ntohs(h->qdcount) == 1 && ntohs(h->ancount) == 0
- && ntohs(h->nscount) >= 1)
- dnsa->answerlen = MAXPACKET;
-
- for (rr = dns_next_rr(dnsa, &dnss, RESET_AUTHORITY);
- rr != NULL;
- rr = dns_next_rr(dnsa, &dnss, RESET_NEXT))
- if (rr->type != T_SOA) continue;
- else if (strcmpic(rr->name, US"") == 0 ||
- strcmpic(rr->name, tld) == 0) return DNS_NOMATCH;
- else break;
- }
- for (i = 0; i < limit; i++)
- {
- if (ipv6)
+ /* Search for CSA subdomain assertion SRV records from the top downwards,
+ starting with the 2nd level domain. This order maximizes cache-friendliness.
+ We skip the top level domains to avoid loading their nameservers and because
+ we know they'll never have CSA SRV records. */
+
+ namesuff = Ustrrchr(name, '.');
+ if (namesuff == NULL) return DNS_NOMATCH;
+ tld = namesuff + 1;
+ ipv6 = FALSE;
+ limit = dns_csa_search_limit;
+
+ /* Use more appropriate search parameters if we are in the reverse DNS. */
+
+ if (strcmpic(namesuff, US".arpa") == 0)
+ if (namesuff - 8 > name && strcmpic(namesuff - 8, US".in-addr.arpa") == 0)
+ {
+ namesuff -= 8;
+ tld = namesuff + 1;
+ limit = 3;
+ }
+ else if (namesuff - 4 > name && strcmpic(namesuff - 4, US".ip6.arpa") == 0)
+ {
+ namesuff -= 4;
+ tld = namesuff + 1;
+ ipv6 = TRUE;
+ limit = 3;
+ }
+
+ DEBUG(D_dns) debug_printf("CSA TLD %s\n", tld);
+
+ /* Do not perform the search if the top level or 2nd level domains do not
+ exist. This is quite common, and when it occurs all the search queries would
+ go to the root or TLD name servers, which is not friendly. So we check the
+ AUTHORITY section; if it contains the root's SOA record or the TLD's SOA then
+ the TLD or the 2LD (respectively) doesn't exist and we can skip the search.
+ If the TLD and the 2LD exist but the explicit CSA record lookup failed, then
+ the AUTHORITY SOA will be the 2LD's or a subdomain thereof. */
+
+ if (rc == DNS_NOMATCH)
{
- /* Scan through the IPv6 reverse DNS in chunks of 16 bits worth of IP
- address, i.e. 4 hex chars and 4 dots, i.e. 8 chars. */
- namesuff -= 8;
- if (namesuff <= name) return DNS_NOMATCH;
+ /* This is really gross. The successful return value from res_search() is
+ the packet length, which is stored in dnsa->answerlen. If we get a
+ negative DNS reply then res_search() returns -1, which causes the bounds
+ checks for name decompression to fail when it is treated as a packet
+ length, which in turn causes the authority search to fail. The correct
+ packet length has been lost inside libresolv, so we have to guess a
+ replacement value. (The only way to fix this properly would be to
+ re-implement res_search() and res_query() so that they don't muddle their
+ success and packet length return values.) For added safety we only reset
+ the packet length if the packet header looks plausible. */
+
+ HEADER *h = (HEADER *)dnsa->answer;
+ if (h->qr == 1 && h->opcode == QUERY && h->tc == 0
+ && (h->rcode == NOERROR || h->rcode == NXDOMAIN)
+ && ntohs(h->qdcount) == 1 && ntohs(h->ancount) == 0
+ && ntohs(h->nscount) >= 1)
+ dnsa->answerlen = MAXPACKET;
+
+ for (rr = dns_next_rr(dnsa, &dnss, RESET_AUTHORITY);
+ rr;
+ rr = dns_next_rr(dnsa, &dnss, RESET_NEXT)
+ )
+ if (rr->type != T_SOA) continue;
+ else if (strcmpic(rr->name, US"") == 0 ||
+ strcmpic(rr->name, tld) == 0) return DNS_NOMATCH;
+ else break;
}
- else
- /* Find the start of the preceding domain name label. */
- do
- if (--namesuff <= name) return DNS_NOMATCH;
- while (*namesuff != '.');
-
- DEBUG(D_dns) debug_printf("CSA parent search at %s\n", namesuff + 1);
-
- srvname = string_sprintf("_client._smtp.%s", namesuff + 1);
- rc = dns_lookup(dnsa, srvname, T_SRV, NULL);
- if (rc == DNS_AGAIN) return rc;
- if (rc != DNS_SUCCEED) continue;
- /* Check that the SRV record we have found is worth returning. We don't
- just return the first one we find, because some lower level SRV record
- might make stricter assertions than its parent domain. */
-
- for (rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS);
- rr != NULL;
- rr = dns_next_rr(dnsa, &dnss, RESET_NEXT))
+ for (i = 0; i < limit; i++)
{
- if (rr->type != T_SRV) continue;
-
- /* Extract the numerical SRV fields (p is incremented) */
- p = rr->data;
- GETSHORT(priority, p);
- GETSHORT(weight, p);
- GETSHORT(port, p);
-
- /* Check the CSA version number */
- if (priority != 1) continue;
-
- /* If it's making an interesting assertion, return this response. */
- if (port & 1)
- {
- *fully_qualified_name = namesuff + 1;
- return DNS_SUCCEED;
- }
+ if (ipv6)
+ {
+ /* Scan through the IPv6 reverse DNS in chunks of 16 bits worth of IP
+ address, i.e. 4 hex chars and 4 dots, i.e. 8 chars. */
+ namesuff -= 8;
+ if (namesuff <= name) return DNS_NOMATCH;
+ }
+ else
+ /* Find the start of the preceding domain name label. */
+ do
+ if (--namesuff <= name) return DNS_NOMATCH;
+ while (*namesuff != '.');
+
+ DEBUG(D_dns) debug_printf("CSA parent search at %s\n", namesuff + 1);
+
+ srvname = string_sprintf("_client._smtp.%s", namesuff + 1);
+ rc = dns_lookup(dnsa, srvname, T_SRV, NULL);
+ if (rc == DNS_AGAIN) return rc;
+ if (rc != DNS_SUCCEED) continue;
+
+ /* Check that the SRV record we have found is worth returning. We don't
+ just return the first one we find, because some lower level SRV record
+ might make stricter assertions than its parent domain. */
+
+ for (rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS);
+ rr;
+ rr = dns_next_rr(dnsa, &dnss, RESET_NEXT))
+ {
+ if (rr->type != T_SRV) continue;
+
+ /* Extract the numerical SRV fields (p is incremented) */
+ p = rr->data;
+ GETSHORT(priority, p);
+ GETSHORT(weight, p); weight = weight; /* compiler quietening */
+ GETSHORT(port, p);
+
+ /* Check the CSA version number */
+ if (priority != 1) continue;
+
+ /* If it's making an interesting assertion, return this response. */
+ if (port & 1)
+ {
+ *fully_qualified_name = namesuff + 1;
+ return DNS_SUCCEED;
+ }
+ }
}
+ return DNS_NOMATCH;
}
- return DNS_NOMATCH;
+
+ default:
+ if (type >= 0)
+ return dns_lookup(dnsa, name, type, fully_qualified_name);
}
/* Control should never reach here */
-/* Support for A6 records has been commented out since they were demoted to
-experimental status at IETF 51. */
-
-#if HAVE_IPV6 && defined(SUPPORT_A6)
-
-/*************************************************
-* Search DNS block for prefix RRs *
-*************************************************/
-
-/* Called from dns_complete_a6() to search an additional section or a main
-answer section for required prefix records to complete an IPv6 address obtained
-from an A6 record. For each prefix record, a recursive call to dns_complete_a6
-is made, with a new copy of the address so far.
-
-Arguments:
- dnsa the DNS answer block
- which RESET_ADDITIONAL or RESET_ANSWERS
- name name of prefix record
- yptrptr pointer to the pointer that points to where to hang the next
- dns_address structure
- bits number of bits we have already got
- bitvec the bits we have already got
-
-Returns: TRUE if any records were found
-*/
-
-static BOOL
-dns_find_prefix(dns_answer *dnsa, int which, uschar *name, dns_address
- ***yptrptr, int bits, uschar *bitvec)
-{
-BOOL yield = FALSE;
-dns_record *rr;
-dns_scan dnss;
-
-for (rr = dns_next_rr(dnsa, &dnss, which);
- rr != NULL;
- rr = dns_next_rr(dnsa, &dnss, RESET_NEXT))
- {
- uschar cbitvec[16];
- if (rr->type != T_A6 || strcmpic(rr->name, name) != 0) continue;
- yield = TRUE;
- memcpy(cbitvec, bitvec, sizeof(cbitvec));
- dns_complete_a6(yptrptr, dnsa, rr, bits, cbitvec);
- }
-
-return yield;
-}
-
-
-
-/*************************************************
-* Follow chains of A6 records *
-*************************************************/
-
-/* A6 records may be incomplete, with pointers to other records containing more
-bits of the address. There can be a tree structure, leading to a number of
-addresses originating from a single initial A6 record.
-
-Arguments:
- yptrptr pointer to the pointer that points to where to hang the next
- dns_address structure
- dnsa the current DNS answer block
- rr the RR we have at present
- bits number of bits we have already got
- bitvec the bits we have already got
-
-Returns: nothing
-*/
-
-static void
-dns_complete_a6(dns_address ***yptrptr, dns_answer *dnsa, dns_record *rr,
- int bits, uschar *bitvec)
-{
-static uschar bitmask[] = { 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80 };
-uschar *p = (uschar *)(rr->data);
-int prefix_len, suffix_len;
-int i, j, k;
-uschar *chainptr;
-uschar chain[264];
-dns_answer cdnsa;
-
-/* The prefix length is the first byte. It defines the prefix which is missing
-from the data in this record as a number of bits. Zero means this is the end of
-a chain. The suffix is the data in this record; only sufficient bytes to hold
-it are supplied. There may be zero bytes. We have to ignore trailing bits that
-we have already obtained from earlier RRs in the chain. */
-
-prefix_len = *p++; /* bits */
-suffix_len = (128 - prefix_len + 7)/8; /* bytes */
-
-/* If the prefix in this record is greater than the prefix in the previous
-record in the chain, we have to ignore the record (RFC 2874). */
-
-if (prefix_len > 128 - bits) return;
-
-/* In this little loop, the number of bits up to and including the current byte
-is held in k. If we have none of the bits in this byte, we can just or it into
-the current data. If we have all of the bits in this byte, we skip it.
-Otherwise, some masking has to be done. */
-
-for (i = suffix_len - 1, j = 15, k = 8; i >= 0; i--)
- {
- int required = k - bits;
- if (required >= 8) bitvec[j] |= p[i];
- else if (required > 0) bitvec[j] |= p[i] & bitmask[required];
- j--; /* I tried putting these in the "for" statement, but gcc muttered */
- k += 8; /* about computed values not being used. */
- }
-
-/* If the prefix_length is zero, we are at the end of a chain. Build a
-dns_address item with the current data, hang it onto the end of the chain,
-adjust the hanging pointer, and we are done. */
-
-if (prefix_len == 0)
- {
- dns_address *new = store_get(sizeof(dns_address) + 50);
- inet_ntop(AF_INET6, bitvec, CS new->address, 50);
- new->next = NULL;
- **yptrptr = new;
- *yptrptr = &(new->next);
- return;
- }
-
-/* Prefix length is not zero. Reset the number of bits that we have collected
-so far, and extract the chain name. */
-
-bits = 128 - prefix_len;
-p += suffix_len;
-
-chainptr = chain;
-while ((i = *p++) != 0)
- {
- if (chainptr != chain) *chainptr++ = '.';
- memcpy(chainptr, p, i);
- chainptr += i;
- p += i;
- }
-*chainptr = 0;
-chainptr = chain;
-
-/* Now scan the current DNS response record to see if the additional section
-contains the records we want. This processing can be cut out for testing
-purposes. */
-
-if (dns_find_prefix(dnsa, RESET_ADDITIONAL, chainptr, yptrptr, bits, bitvec))
- return;
-
-/* No chain records were found in the current DNS response block. Do a new DNS
-lookup to try to find these records. This opens up the possibility of DNS
-failures. We ignore them at this point; if all branches of the tree fail, there
-will be no addresses at the end. */
-
-if (dns_lookup(&cdnsa, chainptr, T_A6, NULL) == DNS_SUCCEED)
- (void)dns_find_prefix(&cdnsa, RESET_ANSWERS, chainptr, yptrptr, bits, bitvec);
-}
-#endif /* HAVE_IPV6 && defined(SUPPORT_A6) */
-
-
/*************************************************
* Get address(es) from DNS record *
*************************************************/
-/* The record type is either T_A for an IPv4 address or T_AAAA (or T_A6 when
-supported) for an IPv6 address. In the A6 case, there may be several addresses,
-generated by following chains. A recursive function does all the hard work. A6
-records now look like passing into history, so the code is only included when
-explicitly asked for.
+/* The record type is either T_A for an IPv4 address or T_AAAA for an IPv6 address.
Argument:
dnsa the DNS answer block
rr the RR
-Returns: pointer a chain of dns_address items
+Returns: pointer to a chain of dns_address items; NULL when the dnsa was overrun
*/
dns_address *
dns_address_from_rr(dns_answer *dnsa, dns_record *rr)
{
-dns_address *yield = NULL;
-
-#if HAVE_IPV6 && defined(SUPPORT_A6)
-dns_address **yieldptr = &yield;
-uschar bitvec[16];
-#else
-dnsa = dnsa; /* Stop picky compilers warning */
-#endif
+dns_address * yield = NULL;
+uschar * dnsa_lim = dnsa->answer + dnsa->answerlen;
if (rr->type == T_A)
{
- uschar *p = (uschar *)(rr->data);
- yield = store_get(sizeof(dns_address) + 20);
- (void)sprintf(CS yield->address, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
- yield->next = NULL;
+ uschar *p = US rr->data;
+ if (p + 4 <= dnsa_lim)
+ {
+ yield = store_get(sizeof(dns_address) + 20);
+ (void)sprintf(CS yield->address, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+ yield->next = NULL;
+ }
}
#if HAVE_IPV6
-#ifdef SUPPORT_A6
-else if (rr->type == T_A6)
- {
- memset(bitvec, 0, sizeof(bitvec));
- dns_complete_a6(&yieldptr, dnsa, rr, 0, bitvec);
- }
-#endif /* SUPPORT_A6 */
-
else
{
- yield = store_get(sizeof(dns_address) + 50);
- inet_ntop(AF_INET6, (uschar *)(rr->data), CS yield->address, 50);
- yield->next = NULL;
+ if (rr->data + 16 <= dnsa_lim)
+ {
+ struct in6_addr in6;
+ int i;
+ for (i = 0; i < 16; i++) in6.s6_addr[i] = rr->data[i];
+ yield = store_get(sizeof(dns_address) + 50);
+ inet_ntop(AF_INET6, &in6, CS yield->address, 50);
+ yield->next = NULL;
+ }
}
#endif /* HAVE_IPV6 */
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
#include "auths/spa.h"
#endif
+#ifdef AUTH_TLS
+#include "auths/tls.h"
+#endif
+
auth_info auths_available[] = {
/* Checking by an expansion condition on plain text */
},
#endif
+#ifdef AUTH_TLS
+ {
+ US"tls", /* lookup name */
+ auth_tls_options,
+ &auth_tls_options_count,
+ &auth_tls_option_defaults,
+ sizeof(auth_tls_options_block),
+ auth_tls_init, /* init function */
+ auth_tls_server, /* server function */
+ NULL, /* client function */
+ NULL /* diagnostic function */
+ },
+#endif
+
{ US"", NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL }
};
#ifdef EXPERIMENTAL_SPF
extern lookup_module_info spf_lookup_module_info;
#endif
-#ifdef EXPERIMENTAL_REDIS
-extern lookup_module_info redis_lookup_module_info;
-#endif
#if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
extern lookup_module_info pgsql_lookup_module_info;
#endif
#if defined(LOOKUP_PASSWD) && LOOKUP_PASSWD!=2
extern lookup_module_info passwd_lookup_module_info;
#endif
+#if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
+extern lookup_module_info redis_lookup_module_info;
+#endif
#if defined(LOOKUP_ORACLE) && LOOKUP_ORACLE!=2
extern lookup_module_info oracle_lookup_module_info;
#endif
addlookupmodule(NULL, &pgsql_lookup_module_info);
#endif
-#ifdef EXPERIMENTAL_REDIS
+#if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
addlookupmodule(NULL, &redis_lookup_module_info);
#endif
/* This function is called when a host is listed for serialization of
connections. It is also called when ETRN is listed for serialization. We open
the misc database and look for a record, which implies an existing connection
-or ETRN run. If not found, create one and return TRUE.
+or ETRN run. If increasing the count would take us past the given limit
+value return FALSE. If not, bump it and return TRUE. If not found, create
+one with value 1 and return TRUE.
Arguments:
key string on which to serialize
+ lim parallelism limit
Returns: TRUE if OK to proceed; FALSE otherwise
*/
BOOL
-enq_start(uschar *key)
+enq_start(uschar *key, unsigned lim)
{
dbdata_serialize *serial_record;
dbdata_serialize new_record;
to create if it can't open a read/write file. It expects only O_RDWR or
O_RDONLY as its argument. */
-dbm_file = dbfn_open(US"misc", O_RDWR, &dbblock, TRUE);
-if (dbm_file == NULL) return FALSE;
+if (!(dbm_file = dbfn_open(US"misc", O_RDWR, &dbblock, TRUE)))
+ return FALSE;
/* See if there is a record for this host or queue run; if there is, we cannot
proceed with the connection unless the record is very old. */
serial_record = dbfn_read(dbm_file, key);
-if (serial_record != NULL && time(NULL) - serial_record->time_stamp < 6*60*60)
+if (serial_record && time(NULL) - serial_record->time_stamp < 6*60*60)
{
- dbfn_close(dbm_file);
- DEBUG(D_transport) debug_printf("outstanding serialization record for %s\n",
- key);
- return FALSE;
+ if (serial_record->count >= lim)
+ {
+ dbfn_close(dbm_file);
+ DEBUG(D_transport) debug_printf("outstanding serialization record for %s\n",
+ key);
+ return FALSE;
+ }
+ new_record.count = serial_record->count + 1;
}
+else
+ new_record.count = 1;
-/* We can proceed - insert a new record or update the old one. At present
-the count field is not used; just set it to 1. */
+/* We can proceed - insert a new record or update the old one. */
-new_record.count = 1;
+DEBUG(D_transport) debug_printf("write serialization record for %s val %d\n",
+ key, new_record.count);
dbfn_write(dbm_file, key, &new_record, (int)sizeof(dbdata_serialize));
dbfn_close(dbm_file);
return TRUE;
{
open_db dbblock;
open_db *dbm_file;
+dbdata_serialize *serial_record;
DEBUG(D_transport) debug_printf("end serialized: %s\n", key);
-dbm_file = dbfn_open(US"misc", O_RDWR, &dbblock, TRUE);
-if (dbm_file == NULL) return;
-dbfn_delete(dbm_file, key);
+if ( !(dbm_file = dbfn_open(US"misc", O_RDWR, &dbblock, TRUE))
+ || !(serial_record = dbfn_read(dbm_file, key))
+ )
+ return;
+if (--serial_record->count > 0)
+ {
+ DEBUG(D_transport) debug_printf("write serialization record for %s val %d\n",
+ key, serial_record->count);
+ dbfn_write(dbm_file, key, serial_record, (int)sizeof(dbdata_serialize));
+ }
+else
+ {
+ DEBUG(D_transport) debug_printf("remove serialization record for %s\n", key);
+ dbfn_delete(dbm_file, key);
+ }
dbfn_close(dbm_file);
}
if [ $keep -gt 99 ]; then first=001; else first=01; fi
+# Grab our pid ro avoid race in file creation
+ourpid=$$
+
if [ -f $mainlog ]; then
$mv $mainlog $mainlog.$first
$chown $user:$group $mainlog.$first
- $touch $mainlog
- $chown $user:$group $mainlog
- $chmod 640 $mainlog
+ $touch $mainlog.$ourpid
+ $chown $user:$group $mainlog.$ourpid
+ $chmod 640 $mainlog.$ourpid
+ $mv $mainlog.$ourpid $mainlog
fi
if [ -f $rejectlog ]; then
$mv $rejectlog $rejectlog.$first
$chown $user:$group $rejectlog.$first
- $touch $rejectlog
- $chown $user:$group $rejectlog
- $chmod 640 $rejectlog
+ $touch $rejectlog.$ourpid
+ $chown $user:$group $rejectlog.$ourpid
+ $chmod 640 $rejectlog.$ourpid
+ $mv $rejectlog.$ourpid $rejectlog
fi
if [ -f $paniclog ]; then
$mv $paniclog $paniclog.$first
$chown $user:$group $paniclog.$first
- $touch $paniclog
- $chown $user:$group $paniclog
- $chmod 640 $paniclog
+ $touch $paniclog.$ourpid
+ $chown $user:$group $paniclog.$ourpid
+ $chmod 640 $paniclog.$ourpid
+ $mv $paniclog.$ourpid $paniclog
fi
# Now scan the (0)02 and later files, compressing where necessary, and
use strict;
-# Copyright (c) 2007-2014 University of Cambridge.
+# Copyright (c) 2007-2015 University of Cambridge.
# See the file NOTICE for conditions of use and distribution.
# Except when they appear in comments, the following placeholders in this
foreach (@ARGV)
{
my $filename = $_;
- if ($filename =~ /\.(?:COMPRESS_SUFFIX)$/o)
+ if (-x 'ZCAT_COMMAND' && $filename =~ /\.(?:COMPRESS_SUFFIX)$/o)
{
open(LOG, "ZCAT_COMMAND $filename |") ||
die "Unable to zcat $filename: $!\n";
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
*/
BOOL
-regex_match_and_setup(const pcre *re, uschar *subject, int options, int setup)
+regex_match_and_setup(const pcre *re, const uschar *subject, int options, int setup)
{
int ovector[3*(EXPAND_MAXN+1)];
-int n = pcre_exec(re, NULL, CS subject, Ustrlen(subject), 0,
+uschar * s = string_copy(subject); /* de-constifying */
+int n = pcre_exec(re, NULL, CS s, Ustrlen(s), 0,
PCRE_EOPT | options, ovector, sizeof(ovector)/sizeof(int));
BOOL yield = n >= 0;
if (n == 0) n = EXPAND_MAXN + 1;
expand_nmax = (setup < 0)? 0 : setup + 1;
for (nn = (setup < 0)? 0 : 2; nn < n*2; nn += 2)
{
- expand_nstring[expand_nmax] = subject + ovector[nn];
+ expand_nstring[expand_nmax] = s + ovector[nn];
expand_nlength[expand_nmax++] = ovector[nn+1] - ovector[nn];
}
expand_nmax--;
if (fd < 0) return;
-{int dummy = write(fd, process_info, process_info_len); dummy = dummy; }
+(void)write(fd, process_info, process_info_len);
(void)close(fd);
}
{
if (!running_in_test_harness)
{
- debug_printf("tick check: %lu.%06lu %lu.%06lu\n",
+ debug_printf("tick check: " TIME_T_FMT ".%06lu " TIME_T_FMT ".%06lu\n",
then_tv->tv_sec, (long) then_tv->tv_usec,
now_tv.tv_sec, (long) now_tv.tv_usec);
- debug_printf("waiting %lu.%06lu\n", itval.it_value.tv_sec,
- (long) itval.it_value.tv_usec);
+ debug_printf("waiting " TIME_T_FMT ".%06lu\n",
+ itval.it_value.tv_sec, (long) itval.it_value.tv_usec);
}
}
#ifdef WITH_CONTENT_SCAN
fprintf(f, " Content_Scanning");
#endif
+#ifdef WITH_OLD_DEMIME
+ fprintf(f, " Old_Demime");
+#endif
#ifndef DISABLE_DKIM
fprintf(f, " DKIM");
#endif
-#ifdef WITH_OLD_DEMIME
- fprintf(f, " Old_Demime");
+#ifndef DISABLE_DNSSEC
+ fprintf(f, " DNSSEC");
#endif
-#ifndef DISABLE_PRDR
- fprintf(f, " PRDR");
+#ifndef DISABLE_EVENT
+ fprintf(f, " Event");
+#endif
+#ifdef SUPPORT_I18N
+ fprintf(f, " I18N");
#endif
#ifndef DISABLE_OCSP
fprintf(f, " OCSP");
#endif
+#ifndef DISABLE_PRDR
+ fprintf(f, " PRDR");
+#endif
+#ifdef SUPPORT_PROXY
+ fprintf(f, " PROXY");
+#endif
+#ifdef SUPPORT_SOCKS
+ fprintf(f, " SOCKS");
+#endif
#ifdef EXPERIMENTAL_SPF
fprintf(f, " Experimental_SPF");
#endif
#ifdef EXPERIMENTAL_DMARC
fprintf(f, " Experimental_DMARC");
#endif
-#ifdef EXPERIMENTAL_PROXY
- fprintf(f, " Experimental_Proxy");
-#endif
-#ifdef EXPERIMENTAL_EVENT
- fprintf(f, " Experimental_Event");
-#endif
-#ifdef EXPERIMENTAL_REDIS
- fprintf(f, " Experimental_Redis");
+#ifdef EXPERIMENTAL_DSN_INFO
+ fprintf(f, " Experimental_DSN_info");
#endif
fprintf(f, "\n");
#if defined(LOOKUP_PGSQL) && LOOKUP_PGSQL!=2
fprintf(f, " pgsql");
#endif
+#if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
+ fprintf(f, " redis");
+#endif
#if defined(LOOKUP_SQLITE) && LOOKUP_SQLITE!=2
fprintf(f, " sqlite");
#endif
#ifdef AUTH_SPA
fprintf(f, " spa");
#endif
+#ifdef AUTH_TLS
+ fprintf(f, " tls");
+#endif
fprintf(f, "\n");
fprintf(f, "Routers:");
#ifdef SUPPORT_TLS
tls_version_report(f);
#endif
+#ifdef SUPPORT_I18N
+ utf8_version_report(f);
+#endif
- for (authi = auths_available; *authi->driver_name != '\0'; ++authi) {
- if (authi->version_report) {
+ for (authi = auths_available; *authi->driver_name != '\0'; ++authi)
+ if (authi->version_report)
(*authi->version_report)(f);
- }
- }
/* PCRE_PRERELEASE is either defined and empty or a bare sequence of
characters; unless it's an ancient version of PCRE in which case it
init_lookup_list();
for (i = 0; i < lookup_list_count; i++)
- {
if (lookup_list[i]->version_report)
lookup_list[i]->version_report(f);
- }
#ifdef WHITELIST_D_MACROS
fprintf(f, "WHITELIST_D_MACROS: \"%s\"\n", WHITELIST_D_MACROS);
BOOL deliver_give_up = FALSE;
BOOL list_queue = FALSE;
BOOL list_options = FALSE;
+BOOL list_config = FALSE;
BOOL local_queue_only;
BOOL more = TRUE;
BOOL one_msg_action = FALSE;
}
#endif
-/* In the Cygwin environment, some initialization needs doing. It is fudged
-in by means of this macro. */
+/* In the Cygwin environment, some initialization used to need doing.
+It was fudged in by means of this macro; now no longer but we'll leave
+it in case of others. */
#ifdef OS_INIT
OS_INIT
exit(EXIT_FAILURE);
}
+/* Initialize the default log options. */
+
+bits_set(log_selector, log_selector_size, log_default);
+
/* Set log_stderr to stderr, provided that stderr exists. This gets reset to
NULL when the daemon is run and the file is closed. We have to use this
indirection, because some systems don't allow writing to the variable "stderr".
regex_must_compile(US"^[A-Za-z0-9_/.-]*$", FALSE, TRUE);
#endif
+for (i = 0; i < REGEX_VARS; i++) regex_vars[i] = NULL;
+
/* If the program is called as "mailq" treat it as equivalent to "exim -bp";
this seems to be a generally accepted convention, since one finds symbolic
else if (Ustrcmp(argrest, "P") == 0)
{
- list_options = TRUE;
- debug_selector |= D_v;
- debug_file = stderr;
+ /* -bP config: we need to setup here, because later,
+ * when list_options is checked, the config is read already */
+ if (argv[i+1] && Ustrcmp(argv[i+1], "config") == 0)
+ {
+ list_config = TRUE;
+ readconf_save_config(version_string);
+ }
+ else
+ {
+ list_options = TRUE;
+ debug_selector |= D_v;
+ debug_file = stderr;
+ }
}
/* -brt: Test retry configuration lookup */
if (nr_configs)
{
int sep = 0;
- uschar *list = argrest;
+ const uschar *list = argrest;
uschar *filename;
while (trusted_config && (filename = string_nextinlist(&list,
&sep, big_buffer, big_buffer_size)) != NULL)
argrest++;
}
if (*argrest != 0)
- decode_bits(&selector, NULL, D_memory, 0, argrest, debug_options,
- debug_options_count, US"debug", 0);
+ decode_bits(&selector, 1, debug_notall, argrest,
+ debug_options, debug_options_count, US"debug", 0);
debug_selector = selector;
}
break;
case 'f':
{
- int start, end;
+ int dummy_start, dummy_end;
uschar *errmess;
if (*argrest == 0)
{
{ badarg = TRUE; break; }
}
if (*argrest == 0)
- {
sender_address = string_sprintf(""); /* Ensure writeable memory */
- }
else
{
uschar *temp = argrest + Ustrlen(argrest) - 1;
if (temp >= argrest && *temp == '.') f_end_dot = TRUE;
allow_domain_literals = TRUE;
strip_trailing_dot = TRUE;
- sender_address = parse_extract_address(argrest, &errmess, &start, &end,
- &sender_address_domain, TRUE);
+#ifdef SUPPORT_I18N
+ allow_utf8_domains = TRUE;
+#endif
+ sender_address = parse_extract_address(argrest, &errmess,
+ &dummy_start, &dummy_end, &sender_address_domain, TRUE);
+#ifdef SUPPORT_I18N
+ message_smtputf8 = string_is_utf8(sender_address);
+ allow_utf8_domains = FALSE;
+#endif
allow_domain_literals = FALSE;
strip_trailing_dot = FALSE;
if (sender_address == NULL)
This needs to happen before we read the main configuration. */
init_lookup_list();
+#ifdef SUPPORT_I18N
+if (running_in_test_harness) smtputf8_advertise_hosts = NULL;
+#endif
+
/* Read the main runtime configuration data; this gives up if there
is a failure. It leaves the configuration file open so that the subsequent
configuration data for delivery can be read if needed. */
/* Handle the decoding of logging options. */
-decode_bits(&log_write_selector, &log_extra_selector, 0, 0,
+decode_bits(log_selector, log_selector_size, log_notall,
log_selector_string, log_options, log_options_count, US"log", 0);
DEBUG(D_any)
{
+ int i;
debug_printf("configuration file is %s\n", config_main_filename);
- debug_printf("log selectors = %08x %08x\n", log_write_selector,
- log_extra_selector);
+ debug_printf("log selectors =");
+ for (i = 0; i < log_selector_size; i++)
+ debug_printf(" %08x", log_selector[i]);
+ debug_printf("\n");
}
/* If domain literals are not allowed, check the sender address that was
Don't attempt it if logging is disabled, or if listing variables or if
verifying/testing addresses or expansions. */
-if (((debug_selector & D_any) != 0 || (log_extra_selector & LX_arguments) != 0)
+if (((debug_selector & D_any) != 0 || LOGGING(arguments))
&& really_exim && !list_options && !checking)
{
int i;
for (i = 0; i < argc; i++)
{
int len = Ustrlen(argv[i]);
- uschar *printing;
+ const uschar *printing;
uschar *quote;
if (p + len + 8 >= big_buffer + big_buffer_size)
{
printing = string_printing(argv[i]);
if (printing[0] == 0) quote = US"\""; else
{
- uschar *pp = printing;
+ const uschar *pp = printing;
quote = US"";
while (*pp != 0) if (isspace(*pp++)) { quote = US"\""; break; }
}
while (*p) p++;
}
- if ((log_extra_selector & LX_arguments) != 0)
+ if (LOGGING(arguments))
log_write(0, LOG_MAIN, "%s", big_buffer);
else
debug_printf("%s\n", big_buffer);
exim_exit(EXIT_SUCCESS);
}
+if (list_config)
+ {
+ set_process_info("listing config");
+ readconf_print(US"config", NULL, FALSE);
+ exim_exit(EXIT_SUCCESS);
+ }
+
/* Handle a request to deliver one or more messages that are already on the
queue. Values of msg_action other than MSG_DELIVER and MSG_LOAD are dealt with
"**** This is not for real!\n\n",
sender_host_address);
+ memset(sender_host_cache, 0, sizeof(sender_host_cache));
if (verify_check_host(&hosts_connection_nolog) == OK)
- log_write_selector &= ~L_smtp_connection;
+ BIT_CLEAR(log_selector, log_selector_size, Li_smtp_connection);
log_write(L_smtp_connection, LOG_MAIN, "%s", smtp_get_connection_info());
/* NOTE: We do *not* call smtp_log_no_mail() if smtp_start_session() fails,
deliver_drop_privilege = TRUE;
queue_smtp = FALSE;
queue_smtp_domains = NULL;
+#ifdef SUPPORT_I18N
+ message_utf8_downconvert = -1; /* convert-if-needed */
+#endif
}
{
smtp_in = stdin;
smtp_out = stdout;
+ memset(sender_host_cache, 0, sizeof(sender_host_cache));
if (verify_check_host(&hosts_connection_nolog) == OK)
- log_write_selector &= ~L_smtp_connection;
+ BIT_CLEAR(log_selector, log_selector_size, Li_smtp_connection);
log_write(L_smtp_connection, LOG_MAIN, "%s", smtp_get_connection_info());
if (!smtp_start_session())
{
if (recipients_max > 0 && ++rcount > recipients_max &&
!extract_recipients)
- {
if (error_handling == ERRORS_STDERR)
{
fprintf(stderr, "exim: too many recipients\n");
moan_to_sender(ERRMESS_TOOMANYRECIP, NULL, NULL, stdin, TRUE)?
errors_sender_rc : EXIT_FAILURE;
}
- }
+#ifdef SUPPORT_I18N
+ {
+ BOOL b = allow_utf8_domains;
+ allow_utf8_domains = TRUE;
+#endif
recipient =
parse_extract_address(s, &errmess, &start, &end, &domain, FALSE);
+#ifdef SUPPORT_I18N
+ if (string_is_utf8(recipient))
+ message_smtputf8 = TRUE;
+ else
+ allow_utf8_domains = b;
+ }
+#endif
if (domain == 0 && !allow_unqualified_recipient)
{
recipient = NULL;
return_path = string_copy(sender_address);
}
else
- {
printf("Return-path = %s\n", (return_path[0] == 0)? US"<>" : return_path);
- }
printf("Sender = %s\n", (sender_address[0] == 0)? US"<>" : sender_address);
receive_add_recipient(
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
here. */
#ifndef ICONV_ARG2_TYPE
-# define ICONV_ARG2_TYPE const char **
+# define ICONV_ARG2_TYPE char **
#endif
/* One OS uses a different type for the 5th argument of getsockopt */
#endif
#endif
+/* DANE w/o DNSSEC is useless */
+#if defined(EXPERIMENTAL_DANE) && defined(DISABLE_DNSSEC)
+ #undef DISABLE_DNSSEC
+#endif
+
/* End of exim.h */
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
*/
int
-string_interpret_escape(uschar **pp)
+string_interpret_escape(const uschar **pp)
{
int ch;
-uschar *p = *pp;
+const uschar *p = *pp;
ch = *(++p);
if (isdigit(ch) && ch != '8' && ch != '9')
{
keystart = t;
while (*s != 0 && *s != '\"')
{
- if (*s == '\\') *t++ = string_interpret_escape(&s);
+ if (*s == '\\') *t++ = string_interpret_escape((const uschar **)&s);
else *t++ = *s;
s++;
}
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
*/
void *
-dbfn_read_with_length(open_db *dbblock, uschar *key, int *length)
+dbfn_read_with_length(open_db *dbblock, const uschar *key, int *length)
{
void *yield;
EXIM_DATUM key_datum, result_datum;
+int klen = Ustrlen(key) + 1;
+uschar * key_copy = store_get(klen);
+
+memcpy(key_copy, key, klen);
EXIM_DATUM_INIT(key_datum); /* Some DBM libraries require the datum */
EXIM_DATUM_INIT(result_datum); /* to be cleared before use. */
-EXIM_DATUM_DATA(key_datum) = CS key;
-EXIM_DATUM_SIZE(key_datum) = Ustrlen(key) + 1;
+EXIM_DATUM_DATA(key_datum) = CS key_copy;
+EXIM_DATUM_SIZE(key_datum) = klen;
if (!EXIM_DBGET(dbblock->dbptr, key_datum, result_datum)) return NULL;
*/
int
-dbfn_write(open_db *dbblock, uschar *key, void *ptr, int length)
+dbfn_write(open_db *dbblock, const uschar *key, void *ptr, int length)
{
EXIM_DATUM key_datum, value_datum;
dbdata_generic *gptr = (dbdata_generic *)ptr;
+int klen = Ustrlen(key) + 1;
+uschar * key_copy = store_get(klen);
+
+memcpy(key_copy, key, klen);
gptr->time_stamp = time(NULL);
EXIM_DATUM_INIT(key_datum); /* Some DBM libraries require the datum */
EXIM_DATUM_INIT(value_datum); /* to be cleared before use. */
-EXIM_DATUM_DATA(key_datum) = CS key;
-EXIM_DATUM_SIZE(key_datum) = Ustrlen(key) + 1;
+EXIM_DATUM_DATA(key_datum) = CS key_copy;
+EXIM_DATUM_SIZE(key_datum) = klen;
EXIM_DATUM_DATA(value_datum) = CS ptr;
EXIM_DATUM_SIZE(value_datum) = length;
return EXIM_DBPUT(dbblock->dbptr, key_datum, value_datum);
*/
int
-dbfn_delete(open_db *dbblock, uschar *key)
+dbfn_delete(open_db *dbblock, const uschar *key)
{
+int klen = Ustrlen(key) + 1;
+uschar * key_copy = store_get(klen);
+
+memcpy(key_copy, key, klen);
EXIM_DATUM key_datum;
EXIM_DATUM_INIT(key_datum); /* Some DBM libraries require clearing */
-EXIM_DATUM_DATA(key_datum) = CS key;
-EXIM_DATUM_SIZE(key_datum) = Ustrlen(key) + 1;
+EXIM_DATUM_DATA(key_datum) = CS key_copy;
+EXIM_DATUM_SIZE(key_datum) = klen;
return EXIM_DBDEL(dbblock->dbptr, key_datum);
}
printf("\n");
}
- /* Old-style domain record, without separate timestamps. This code can
- eventually be thrown away, say in 5 years' time (it's now Feb 2003). */
-
- else
- {
- printf("%s %s callout=%s postmaster=%s random=%s\n",
- print_time(((dbdata_generic *)value)->time_stamp),
- keybuffer,
- print_cache(callout->result),
- print_cache(callout->postmaster_result),
- print_cache(callout->random_result));
- }
-
break;
case type_ratelimit:
# The build process concatenates on the front of this various settings from
# os-specific files and from the user's configuration file.
-# Copyright (c) 2004 - 2012 University of Cambridge.
+# Copyright (c) 2004 - 2015 University of Cambridge.
# See the file NOTICE for conditions of use and distribution.
# Except when they appear in comments, the following placeholders in this
# If log_file_path is "syslog" then logging is only to syslog, and the monitor
# is unable to display a log tail unless EXIMON_LOG_FILE_PATH is set to tell
-# it where the log data is. Otherwise, remove any occurrences of
-# "syslog:" or ":syslog" (spaces allowed in various places) and look at the
-# remainder of the entry. If it's null, the default is "mainlog" in the
-# "log" directory in the spool directory. Otherwise, set the name from the
-# given path.
+# it where the log data is. If log_file_path is unset (i.e. empty) the default
+# is "mainlog" in the "log" directory in the spool directory. Otherwise,
+# remove any occurrences of "syslog:" or ":syslog" (spaces allowed in various
+# places) and look at the remainder of the entry. If it's null, check whether
+# LOG_FILE_NAME was set a compile time and contains a path. Otherwise fall
+# back to the default path.
if [ "$EXIMON_LOG_FILE_PATH" != "" ] ; then
LOG_FILE_NAME="$EXIMON_LOG_FILE_PATH"
echo MAIL.INFO syslog messages into a separate file, you can point eximon at
echo that file with the EXIMON_LOG_FILE_PATH environment variable.
echo \*\*\*
+elif [ "$LOG_FILE_PATH" = "" ] ; then
+ LOG_FILE_NAME=$SPOOL_DIRECTORY/log/mainlog
else
LOG_FILE_NAME=`echo $LOG_FILE_PATH | \
sed -e 's/ *: *syslog *: */:/' \
-e 's/^ *syslog *: *//' \
-e 's/%s/main/'`
if [ "$LOG_FILE_NAME" = "" ] ; then
- LOG_FILE_NAME=$SPOOL_DIRECTORY/log/mainlog
+ COMPILETIMEDEFAULT=`$EXIM_PATH -C /dev/null -bP log_file_path | \
+ sed -e 's/.*=[ ]*//' \
+ -e 's/ *: *syslog *: */:/' \
+ -e 's/ *: *syslog *$//' \
+ -e 's/^ *syslog *: *//' \
+ -e 's/%s/main/'`
+ if [ "$COMPILETIMEDEFAULT" != "" ] ; then
+ LOG_FILE_NAME="$COMPILETIMEDEFAULT"
+ else
+ LOG_FILE_NAME=$SPOOL_DIRECTORY/log/mainlog
+ fi
fi
fi
};
getopts('hf:r:y:o:s:C:zxlibRca',\%opt);
+if ($ARGV[0]) { &help; exit;}
if ($opt{h}) { &help; exit;}
if ($opt{a}) { $eargs = '-bp'; }
if ($opt{C} && -e $opt{C} && -f $opt{C} && -R $opt{C}) { $eargs .= ' -C '.$opt{C}; }
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Recursively called function */
-static uschar *expand_string_internal(uschar *, BOOL, uschar **, BOOL, BOOL, BOOL *);
-static int_eximarith_t expanded_string_integer(uschar *, BOOL);
+static uschar *expand_string_internal(const uschar *, BOOL, const uschar **, BOOL, BOOL, BOOL *);
+static int_eximarith_t expanded_string_integer(const uschar *, BOOL);
#ifdef STAND_ALONE
#ifndef SUPPORT_CRYPTEQ
-#ifndef nelements
-# define nelements(arr) (sizeof(arr) / sizeof(*arr))
-#endif
-
/*************************************************
* Local statics and tables *
*************************************************/
US"acl",
US"certextract",
US"dlfunc",
+ US"env",
US"extract",
US"filter",
US"hash",
US"hmac",
US"if",
+#ifdef SUPPORT_I18N
+ US"imapfolder",
+#endif
US"length",
US"listextract",
US"lookup",
EITEM_ACL,
EITEM_CERTEXTRACT,
EITEM_DLFUNC,
+ EITEM_ENV,
EITEM_EXTRACT,
EITEM_FILTER,
EITEM_HASH,
EITEM_HMAC,
EITEM_IF,
+#ifdef SUPPORT_I18N
+ EITEM_IMAPFOLDER,
+#endif
EITEM_LENGTH,
EITEM_LISTEXTRACT,
EITEM_LOOKUP,
US"quote_local_part",
US"reverse_ip",
US"time_eval",
- US"time_interval"};
+ US"time_interval"
+#ifdef SUPPORT_I18N
+ ,US"utf8_domain_from_alabel",
+ US"utf8_domain_to_alabel",
+ US"utf8_localpart_from_alabel",
+ US"utf8_localpart_to_alabel"
+#endif
+ };
enum {
EOP_FROM_UTF8,
EOP_QUOTE_LOCAL_PART,
EOP_REVERSE_IP,
EOP_TIME_EVAL,
- EOP_TIME_INTERVAL };
+ EOP_TIME_INTERVAL
+#ifdef SUPPORT_I18N
+ ,EOP_UTF8_DOMAIN_FROM_ALABEL,
+ EOP_UTF8_DOMAIN_TO_ALABEL,
+ EOP_UTF8_LOCALPART_FROM_ALABEL,
+ EOP_UTF8_LOCALPART_TO_ALABEL
+#endif
+ };
static uschar *op_table_main[] = {
US"address",
US"hash",
US"hex2b64",
US"hexquote",
+ US"ipv6denorm",
+ US"ipv6norm",
US"l",
US"lc",
US"length",
US"utf8clean" };
enum {
- EOP_ADDRESS = sizeof(op_table_underscore)/sizeof(uschar *),
+ EOP_ADDRESS = nelem(op_table_underscore),
EOP_ADDRESSES,
EOP_BASE62,
EOP_BASE62D,
EOP_HASH,
EOP_HEX2B64,
EOP_HEXQUOTE,
+ EOP_IPV6DENORM,
+ EOP_IPV6NORM,
EOP_L,
EOP_LC,
EOP_LENGTH,
{ "bounce_return_size_limit", vtype_int, &bounce_return_size_limit },
{ "caller_gid", vtype_gid, &real_gid },
{ "caller_uid", vtype_uid, &real_uid },
+ { "callout_address", vtype_stringptr, &callout_address },
{ "compile_date", vtype_stringptr, &version_date },
{ "compile_number", vtype_stringptr, &version_cnumber },
{ "config_dir", vtype_stringptr, &config_main_directory },
{ "dkim_headernames", vtype_dkim, (void *)DKIM_HEADERNAMES },
{ "dkim_identity", vtype_dkim, (void *)DKIM_IDENTITY },
{ "dkim_key_granularity",vtype_dkim, (void *)DKIM_KEY_GRANULARITY },
+ { "dkim_key_length", vtype_int, &dkim_key_length },
{ "dkim_key_nosubdomains",vtype_dkim, (void *)DKIM_NOSUBDOMAINS },
{ "dkim_key_notes", vtype_dkim, (void *)DKIM_KEY_NOTES },
{ "dkim_key_srvtype", vtype_dkim, (void *)DKIM_KEY_SRVTYPE },
{ "dnslist_value", vtype_stringptr, &dnslist_value },
{ "domain", vtype_stringptr, &deliver_domain },
{ "domain_data", vtype_stringptr, &deliver_domain_data },
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
{ "event_data", vtype_stringptr, &event_data },
/*XXX want to use generic vars for as many of these as possible*/
{ "message_id", vtype_stringptr, &message_id },
{ "message_linecount", vtype_int, &message_linecount },
{ "message_size", vtype_int, &message_size },
+#ifdef SUPPORT_I18N
+ { "message_smtputf8", vtype_bool, &message_smtputf8 },
+#endif
#ifdef WITH_CONTENT_SCAN
{ "mime_anomaly_level", vtype_int, &mime_anomaly_level },
{ "mime_anomaly_text", vtype_stringptr, &mime_anomaly_text },
{ "parent_domain", vtype_stringptr, &deliver_domain_parent },
{ "parent_local_part", vtype_stringptr, &deliver_localpart_parent },
{ "pid", vtype_pid, NULL },
+#ifndef DISABLE_PRDR
+ { "prdr_requested", vtype_bool, &prdr_requested },
+#endif
{ "primary_hostname", vtype_stringptr, &primary_hostname },
-#ifdef EXPERIMENTAL_PROXY
- { "proxy_host_address", vtype_stringptr, &proxy_host_address },
- { "proxy_host_port", vtype_int, &proxy_host_port },
+#if defined(SUPPORT_PROXY) || defined(SUPPORT_SOCKS)
+ { "proxy_external_address",vtype_stringptr, &proxy_external_address },
+ { "proxy_external_port", vtype_int, &proxy_external_port },
+ { "proxy_local_address", vtype_stringptr, &proxy_local_address },
+ { "proxy_local_port", vtype_int, &proxy_local_port },
{ "proxy_session", vtype_bool, &proxy_session },
- { "proxy_target_address",vtype_stringptr, &proxy_target_address },
- { "proxy_target_port", vtype_int, &proxy_target_port },
#endif
{ "prvscheck_address", vtype_stringptr, &prvscheck_address },
{ "prvscheck_keynum", vtype_stringptr, &prvscheck_keynum },
{ "sender_address_local_part", vtype_localpart, &sender_address },
{ "sender_data", vtype_stringptr, &sender_data },
{ "sender_fullhost", vtype_stringptr, &sender_fullhost },
+ { "sender_helo_dnssec", vtype_bool, &sender_helo_dnssec },
{ "sender_helo_name", vtype_stringptr, &sender_helo_name },
{ "sender_host_address", vtype_stringptr, &sender_host_address },
{ "sender_host_authenticated",vtype_stringptr, &sender_host_authenticated },
{ "sn8", vtype_filter_int, &filter_sn[8] },
{ "sn9", vtype_filter_int, &filter_sn[9] },
#ifdef WITH_CONTENT_SCAN
+ { "spam_action", vtype_stringptr, &spam_action },
{ "spam_bar", vtype_stringptr, &spam_bar },
{ "spam_report", vtype_stringptr, &spam_report },
{ "spam_score", vtype_stringptr, &spam_score },
{ "warnmsg_recipients", vtype_stringptr, &warnmsg_recipients }
};
-static int var_table_size = sizeof(var_table)/sizeof(var_entry);
+static int var_table_size = nelem(var_table);
static uschar var_buffer[256];
static BOOL malformed_header;
Ustrchr() yields non-NULL if the character is zero (which is not something
I expected). */
-static uschar *
-read_name(uschar *name, int max, uschar *s, uschar *extras)
+static const uschar *
+read_name(uschar *name, int max, const uschar *s, uschar *extras)
{
int ptr = 0;
while (*s != 0 && (isalnum(*s) || Ustrchr(extras, *s) != NULL))
Returns: a pointer to the first character after the header name
*/
-static uschar *
-read_header_name(uschar *name, int max, uschar *s)
+static const uschar *
+read_header_name(uschar *name, int max, const uschar *s)
{
int prelen = Ustrchr(name, '_') - name + 1;
int ptr = Ustrlen(name) - prelen;
return s;
}
+static const uschar *
+read_cnumber(int *n, const uschar *s)
+{
+*n = 0;
+while (isdigit(*s)) *n = *n * 10 + (*s++ - '0');
+return s;
+}
+
/*************************************************
*/
static uschar *
-expand_getkeyed(uschar *key, uschar *s)
+expand_getkeyed(uschar *key, const uschar *s)
{
int length = Ustrlen(key);
while (isspace(*s)) s++;
{
int dkeylength;
uschar *data;
- uschar *dkey = s;
+ const uschar *dkey = s;
while (*s != 0 && *s != '=' && !isspace(*s)) s++;
dkeylength = s - dkey;
static uschar *
-expand_getlistele(int field, uschar * list)
+expand_getlistele(int field, const uschar * list)
{
-uschar * tlist= list;
+const uschar * tlist= list;
int sep= 0;
uschar dummy;
if (!(vp = find_var_ent(certvar)))
{
- expand_string_message =
+ expand_string_message =
string_sprintf("no variable named \"%s\"", certvar);
return NULL; /* Unknown variable name */
}
want to do that in future */
if (vp->type != vtype_cert)
{
- expand_string_message =
+ expand_string_message =
string_sprintf("\"%s\" is not a certificate", certvar);
return NULL; /* Unknown variable name */
}
return tls_cert_ext_by_oid(*(void **)vp->value, field, 0);
for(cp = certfields;
- cp < certfields + nelements(certfields);
+ cp < certfields + nelem(certfields);
cp++)
if (Ustrncmp(cp->name, field, cp->namelen) == 0)
{
return (*cp->getfn)( *(void **)vp->value, modifier );
}
-expand_string_message =
+expand_string_message =
string_sprintf("bad field selector \"%s\" for certextract", field);
return NULL;
}
while (*s != 0)
{
- if (i == 0) i = sizeof(prime)/sizeof(int) - 1;
+ if (i == 0) i = nelem(prime) - 1;
total += prime[i--] * (unsigned int)(*s++);
}
uschar *endptr;
int n = Ustrtoul(name + 4, &endptr, 10);
if (*endptr == 0 && n != 0 && n <= AUTH_VARS)
- return (auth_vars[n-1] == NULL)? US"" : auth_vars[n-1];
+ return !auth_vars[n-1] ? US"" : auth_vars[n-1];
+ }
+else if (Ustrncmp(name, "regex", 5) == 0)
+ {
+ uschar *endptr;
+ int n = Ustrtoul(name + 5, &endptr, 10);
+ if (*endptr == 0 && n != 0 && n <= REGEX_VARS)
+ return !regex_vars[n-1] ? US"" : regex_vars[n-1];
}
/* For all other variables, search the table */
*/
static int
-read_subs(uschar **sub, int n, int m, uschar **sptr, BOOL skipping,
+read_subs(uschar **sub, int n, int m, const uschar **sptr, BOOL skipping,
BOOL check_end, uschar *name, BOOL *resetok)
{
int i;
-uschar *s = *sptr;
+const uschar *s = *sptr;
while (isspace(*s)) s++;
for (i = 0; i < n; i++)
eval_acl(uschar ** sub, int nsub, uschar ** user_msgp)
{
int i;
-uschar *tmp;
int sav_narg = acl_narg;
int ret;
+uschar * dummy_logmsg;
extern int acl_where;
-if(--nsub > sizeof(acl_arg)/sizeof(*acl_arg)) nsub = sizeof(acl_arg)/sizeof(*acl_arg);
+if(--nsub > nelem(acl_arg)) nsub = nelem(acl_arg);
for (i = 0; i < nsub && sub[i+1]; i++)
{
- tmp = acl_arg[i];
+ uschar * tmp = acl_arg[i];
acl_arg[i] = sub[i+1]; /* place callers args in the globals */
sub[i+1] = tmp; /* stash the old args using our caller's storage */
}
acl_narg>0 ? acl_arg[0] : US"<none>",
acl_narg>1 ? " +more" : "");
-ret = acl_eval(acl_where, sub[0], user_msgp, &tmp);
+ret = acl_eval(acl_where, sub[0], user_msgp, &dummy_logmsg);
for (i = 0; i < nsub; i++)
acl_arg[i] = sub[i+1]; /* restore old args */
NULL after an error
*/
-static uschar *
-eval_condition(uschar *s, BOOL *resetok, BOOL *yield)
+static const uschar *
+eval_condition(const uschar *s, BOOL *resetok, BOOL *yield)
{
BOOL testfor = TRUE;
BOOL tempcond, combined_cond;
int_eximarith_t num[2];
struct stat statbuf;
uschar name[256];
-uschar *sub[10];
+const uschar *sub[10];
const pcre *re;
const uschar *rerror;
/* Find which condition we are dealing with, and switch on it */
-cond_type = chop_match(name, cond_table, sizeof(cond_table)/sizeof(uschar *));
+cond_type = chop_match(name, cond_table, nelem(cond_table));
switch(cond_type)
{
/* def: tests for a non-empty variable, or for the existence of a header. If
case ECOND_ACL:
/* ${if acl {{name}{arg1}{arg2}...} {yes}{no}} */
{
+ uschar *sub[10];
uschar *user_msg;
BOOL cond = FALSE;
int size = 0;
while (isspace(*s)) s++;
if (*s++ != '{') goto COND_FAILED_CURLY_START; /*}*/
- switch(read_subs(sub, sizeof(sub)/sizeof(*sub), 1,
+ switch(read_subs(sub, nelem(sub), 1,
&s, yield == NULL, TRUE, US"acl", resetok))
{
case 1: expand_string_message = US"too few arguments or bracketing "
}
*resetok = FALSE;
- if (yield != NULL) switch(eval_acl(sub, sizeof(sub)/sizeof(*sub), &user_msg))
+ if (yield != NULL) switch(eval_acl(sub, nelem(sub), &user_msg))
{
case OK:
cond = TRUE;
in their own set of braces. */
case ECOND_SASLAUTHD:
- #ifndef CYRUS_SASLAUTHD_SOCKET
- goto COND_FAILED_NOT_COMPILED;
- #else
- while (isspace(*s)) s++;
- if (*s++ != '{') goto COND_FAILED_CURLY_START; /* }-for-text-editors */
- switch(read_subs(sub, 4, 2, &s, yield == NULL, TRUE, US"saslauthd", resetok))
- {
- case 1: expand_string_message = US"too few arguments or bracketing "
- "error for saslauthd";
- case 2:
- case 3: return NULL;
- }
- if (sub[2] == NULL) sub[3] = NULL; /* realm if no service */
- if (yield != NULL)
+#ifndef CYRUS_SASLAUTHD_SOCKET
+ goto COND_FAILED_NOT_COMPILED;
+#else
{
- int rc;
- rc = auth_call_saslauthd(sub[0], sub[1], sub[2], sub[3],
- &expand_string_message);
- if (rc == ERROR || rc == DEFER) return NULL;
- *yield = (rc == OK) == testfor;
+ uschar *sub[4];
+ while (isspace(*s)) s++;
+ if (*s++ != '{') goto COND_FAILED_CURLY_START; /* }-for-text-editors */
+ switch(read_subs(sub, nelem(sub), 2, &s, yield == NULL, TRUE, US"saslauthd",
+ resetok))
+ {
+ case 1: expand_string_message = US"too few arguments or bracketing "
+ "error for saslauthd";
+ case 2:
+ case 3: return NULL;
+ }
+ if (sub[2] == NULL) sub[3] = NULL; /* realm if no service */
+ if (yield != NULL)
+ {
+ int rc = auth_call_saslauthd(sub[0], sub[1], sub[2], sub[3],
+ &expand_string_message);
+ if (rc == ERROR || rc == DEFER) return NULL;
+ *yield = (rc == OK) == testfor;
+ }
+ return s;
}
- return s;
- #endif /* CYRUS_SASLAUTHD_SOCKET */
+#endif /* CYRUS_SASLAUTHD_SOCKET */
/* symbolic operators for numeric and string comparison, and a number of
case ECOND_INLIST:
case ECOND_INLISTI:
{
+ const uschar * list = sub[1];
int sep = 0;
uschar *save_iterate_item = iterate_item;
int (*compare)(const uschar *, const uschar *);
DEBUG(D_expand) debug_printf("condition: %s\n", name);
tempcond = FALSE;
- if (cond_type == ECOND_INLISTI)
- compare = strcmpic;
- else
- compare = (int (*)(const uschar *, const uschar *)) strcmp;
+ compare = cond_type == ECOND_INLISTI
+ ? strcmpic : (int (*)(const uschar *, const uschar *)) strcmp;
- while ((iterate_item = string_nextinlist(&sub[1], &sep, NULL, 0)) != NULL)
+ while ((iterate_item = string_nextinlist(&list, &sep, NULL, 0)))
if (compare(sub[0], iterate_item) == 0)
{
tempcond = TRUE;
case ECOND_FORALL:
case ECOND_FORANY:
{
+ const uschar * list;
int sep = 0;
uschar *save_iterate_item = iterate_item;
}
if (yield != NULL) *yield = !testfor;
- while ((iterate_item = string_nextinlist(&sub[0], &sep, NULL, 0)) != NULL)
+ list = sub[0];
+ while ((iterate_item = string_nextinlist(&list, &sep, NULL, 0)) != NULL)
{
DEBUG(D_expand) debug_printf("%s: $item = \"%s\"\n", name, iterate_item);
if (!eval_condition(sub[1], resetok, &tempcond))
*/
static int
-process_yesno(BOOL skipping, BOOL yes, uschar *save_lookup, uschar **sptr,
+process_yesno(BOOL skipping, BOOL yes, uschar *save_lookup, const uschar **sptr,
uschar **yieldptr, int *sizeptr, int *ptrptr, uschar *type, BOOL *resetok)
{
int rc = 0;
-uschar *s = *sptr; /* Local value */
+const uschar *s = *sptr; /* Local value */
uschar *sub1, *sub2;
/* If there are no following strings, we substitute the contents of $value for
else if (*s != '}')
{
uschar name[256];
- s = read_name(name, sizeof(name), s, US"_");
+ /* deconst cast ok here as source is s anyway */
+ s = US read_name(name, sizeof(name), s, US"_");
if (Ustrcmp(name, "fail") == 0)
{
if (!yes && !skipping)
*/
static uschar *
-expand_string_internal(uschar *string, BOOL ket_ends, uschar **left,
+expand_string_internal(const uschar *string, BOOL ket_ends, const uschar **left,
BOOL skipping, BOOL honour_dollar, BOOL *resetok_p)
{
int ptr = 0;
int size = Ustrlen(string)+ 64;
int item_type;
uschar *yield = store_get(size);
-uschar *s = string;
+const uschar *s = string;
uschar *save_expand_nstring[EXPAND_MAXN+1];
int save_expand_nlength[EXPAND_MAXN+1];
BOOL resetok = TRUE;
if (s[1] == 'N')
{
- uschar *t = s + 2;
+ const uschar * t = s + 2;
for (s = t; *s != 0; s++) if (*s == '\\' && s[1] == 'N') break;
yield = string_cat(yield, &size, &ptr, t, s - t);
if (*s != 0) s += 2;
if (isdigit(*s))
{
int n;
- s = read_number(&n, s);
+ s = read_cnumber(&n, s);
if (n >= 0 && n <= expand_nmax)
yield = string_cat(yield, &size, &ptr, expand_nstring[n],
expand_nlength[n]);
if (isdigit((*(++s))))
{
int n;
- s = read_number(&n, s); /*{*/
+ s = read_cnumber(&n, s); /*{*/
if (*s++ != '}')
{ /*{*/
expand_string_message = US"} expected after number";
OK. */
s = read_name(name, sizeof(name), s, US"_-");
- item_type = chop_match(name, item_table, sizeof(item_table)/sizeof(uschar *));
+ item_type = chop_match(name, item_table, nelem(item_table));
switch(item_type)
{
uschar *sub[10]; /* name + arg1-arg9 (which must match number of acl_arg[]) */
uschar *user_msg;
- switch(read_subs(sub, 10, 1, &s, skipping, TRUE, US"acl", &resetok))
+ switch(read_subs(sub, nelem(sub), 1, &s, skipping, TRUE, US"acl",
+ &resetok))
{
case 1: goto EXPAND_FAILED_CURLY;
case 2:
if (skipping) continue;
resetok = FALSE;
- switch(eval_acl(sub, sizeof(sub)/sizeof(*sub), &user_msg))
+ switch(eval_acl(sub, nelem(sub), &user_msg))
{
case OK:
case FAIL:
case EITEM_IF:
{
BOOL cond = FALSE;
- uschar *next_s;
+ const uschar *next_s;
int save_expand_nmax =
save_expand_strings(save_expand_nstring, save_expand_nlength);
continue;
}
+#ifdef SUPPORT_I18N
+ case EITEM_IMAPFOLDER:
+ { /* ${imapfolder {name}{sep]{specials}} */
+ uschar *sub_arg[3];
+ uschar *encoded;
+
+ switch(read_subs(sub_arg, nelem(sub_arg), 1, &s, skipping, TRUE, name,
+ &resetok))
+ {
+ case 1: goto EXPAND_FAILED_CURLY;
+ case 2:
+ case 3: goto EXPAND_FAILED;
+ }
+
+ if (sub_arg[1] == NULL) /* One argument */
+ {
+ sub_arg[1] = US"/"; /* default separator */
+ sub_arg[2] = NULL;
+ }
+ else if (Ustrlen(sub_arg[1]) != 1)
+ {
+ expand_string_message =
+ string_sprintf(
+ "IMAP folder separator must be one character, found \"%s\"",
+ sub_arg[1]);
+ goto EXPAND_FAILED;
+ }
+
+ if (!(encoded = imap_utf7_encode(sub_arg[0], headers_charset,
+ sub_arg[1][0], sub_arg[2], &expand_string_message)))
+ goto EXPAND_FAILED;
+ if (!skipping)
+ yield = string_cat(yield, &size, &ptr, encoded, Ustrlen(encoded));
+ continue;
+ }
+#endif
+
/* Handle database lookups unless locked out. If "skipping" is TRUE, we are
expanding an internal string that isn't actually going to be used. All we
need to do is check the syntax, so don't do a lookup at all. Preserve the
int stype, partial, affixlen, starflags;
int expand_setup = 0;
int nameptr = 0;
- uschar *key, *filename, *affix;
+ uschar *key, *filename;
+ const uschar *affix;
uschar *save_lookup_value = lookup_value;
int save_expand_nmax =
save_expand_strings(save_expand_nstring, save_expand_nlength);
{
FILE *f;
uschar *arg;
- uschar **argv;
+ const uschar **argv;
pid_t pid;
int fd_in, fd_out;
int lsize = 0;
/* Create the child process, making it a group leader. */
- pid = child_open(argv, NULL, 0077, &fd_in, &fd_out, TRUE);
+ pid = child_open(USS argv, NULL, 0077, &fd_in, &fd_out, TRUE);
if (pid < 0)
{
{
int ovector[3*(EXPAND_MAXN+1)];
int n = pcre_exec(re, NULL, CS subject, slen, moffset + moffsetextra,
- PCRE_EOPT | emptyopt, ovector, sizeof(ovector)/sizeof(int));
+ PCRE_EOPT | emptyopt, ovector, nelem(ovector));
int nn;
uschar *insert;
int sep = 0;
int save_ptr = ptr;
uschar outsep[2] = { '\0', '\0' };
- uschar *list, *expr, *temp;
+ const uschar *list, *expr, *temp;
uschar *save_iterate_item = iterate_item;
uschar *save_lookup_value = lookup_value;
if (item_type == EITEM_REDUCE)
{
+ uschar * t;
while (isspace(*s)) s++;
if (*s++ != '{') goto EXPAND_FAILED_CURLY;
- temp = expand_string_internal(s, TRUE, &s, skipping, TRUE, &resetok);
- if (temp == NULL) goto EXPAND_FAILED;
- lookup_value = temp;
+ t = expand_string_internal(s, TRUE, &s, skipping, TRUE, &resetok);
+ if (!t) goto EXPAND_FAILED;
+ lookup_value = t;
if (*s++ != '}') goto EXPAND_FAILED_CURLY;
}
if (temp != NULL) s = temp;
}
else
- {
temp = expand_string_internal(s, TRUE, &s, TRUE, TRUE, &resetok);
- }
if (temp == NULL)
{
else
{
- temp = expand_string_internal(expr, TRUE, NULL, skipping, TRUE, &resetok);
+ uschar * t = expand_string_internal(expr, TRUE, NULL, skipping, TRUE, &resetok);
+ temp = t;
if (temp == NULL)
{
iterate_item = save_iterate_item;
}
if (item_type == EITEM_REDUCE)
{
- lookup_value = temp; /* Update the value of $value */
+ lookup_value = t; /* Update the value of $value */
continue; /* and continue the iteration */
}
}
case EITEM_SORT:
{
int sep = 0;
- uschar *srclist, *cmp, *xtract;
+ const uschar *srclist, *cmp, *xtract;
uschar *srcitem;
- uschar *dstlist = NULL;
- uschar *dstkeylist = NULL;
+ const uschar *dstlist = NULL, *dstkeylist = NULL;
uschar * tmp;
uschar *save_iterate_item = iterate_item;
#define EXPAND_DLFUNC_MAX_ARGS 8
case EITEM_DLFUNC:
- #ifndef EXPAND_DLFUNC
- expand_string_message = US"\"${dlfunc\" encountered, but this facility " /*}*/
- "is not included in this binary";
- goto EXPAND_FAILED;
+#ifndef EXPAND_DLFUNC
+ expand_string_message = US"\"${dlfunc\" encountered, but this facility " /*}*/
+ "is not included in this binary";
+ goto EXPAND_FAILED;
- #else /* EXPAND_DLFUNC */
+#else /* EXPAND_DLFUNC */
{
tree_node *t;
exim_dlfunc_t *func;
goto EXPAND_FAILED;
}
}
- #endif /* EXPAND_DLFUNC */
+#endif /* EXPAND_DLFUNC */
+
+ case EITEM_ENV: /* ${env {name} {val_if_found} {val_if_unfound}} */
+ {
+ uschar * key;
+ uschar *save_lookup_value = lookup_value;
+
+ while (isspace(*s)) s++;
+ if (*s != '{') /*}*/
+ goto EXPAND_FAILED;
+
+ key = expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok);
+ if (!key) goto EXPAND_FAILED; /*{*/
+ if (*s++ != '}') goto EXPAND_FAILED_CURLY;
+
+ lookup_value = US getenv(CS key);
+
+ switch(process_yesno(
+ skipping, /* were previously skipping */
+ lookup_value != NULL, /* success/failure indicator */
+ save_lookup_value, /* value to reset for string2 */
+ &s, /* input pointer */
+ &yield, /* output pointer */
+ &size, /* output size */
+ &ptr, /* output current point */
+ US"env", /* condition type */
+ &resetok))
+ {
+ case 1: goto EXPAND_FAILED; /* when all is well, the */
+ case 2: goto EXPAND_FAILED_CURLY; /* returned value is 0 */
+ }
+ continue;
+ }
} /* EITEM_* switch */
/* Control reaches here if the name is not recognized as one of the more
the arguments and then scan the main table. */
if ((c = chop_match(name, op_table_underscore,
- sizeof(op_table_underscore)/sizeof(uschar *))) < 0)
+ nelem(op_table_underscore))) < 0)
{
arg = Ustrchr(name, '_');
if (arg != NULL) *arg = 0;
- c = chop_match(name, op_table_main,
- sizeof(op_table_main)/sizeof(uschar *));
- if (c >= 0) c += sizeof(op_table_underscore)/sizeof(uschar *);
+ c = chop_match(name, op_table_main, nelem(op_table_main));
+ if (c >= 0) c += nelem(op_table_underscore);
if (arg != NULL) *arg++ = '_'; /* Put back for error messages */
}
case EOP_SHA256:
if (s[1] == '$')
{
- uschar * s1 = s;
+ const uschar * s1 = s;
sub = expand_string_internal(s+2, TRUE, &s1, skipping,
FALSE, &resetok);
if (!sub) goto EXPAND_FAILED; /*{*/
uschar * cp;
uschar buffer[256];
- while (string_nextinlist(&sub, &sep, buffer, sizeof(buffer)) != NULL) cnt++;
+ while (string_nextinlist(CUSS &sub, &sep, buffer, sizeof(buffer)) != NULL) cnt++;
cp = string_sprintf("%d", cnt);
yield = string_cat(yield, &size, &ptr, cp, Ustrlen(cp));
continue;
case EOP_LISTNAMED:
{
tree_node *t = NULL;
- uschar * list;
+ const uschar * list;
int sep = 0;
uschar * item;
uschar * suffix = US"";
continue;
}
+ case EOP_IPV6NORM:
+ case EOP_IPV6DENORM:
+ {
+ int type = string_is_ip_address(sub, NULL);
+ int binary[4];
+ uschar buffer[44];
+
+ switch (type)
+ {
+ case 6:
+ (void) host_aton(sub, binary);
+ break;
+
+ case 4: /* convert to IPv4-mapped IPv6 */
+ binary[0] = binary[1] = 0;
+ binary[2] = 0x0000ffff;
+ (void) host_aton(sub, binary+3);
+ break;
+
+ case 0:
+ expand_string_message =
+ string_sprintf("\"%s\" is not an IP address", sub);
+ goto EXPAND_FAILED;
+ }
+
+ yield = string_cat(yield, &size, &ptr, buffer,
+ c == EOP_IPV6NORM
+ ? ipv6_nmtoa(binary, buffer)
+ : host_nmtoa(4, binary, -1, buffer, ':')
+ );
+ continue;
+ }
+
case EOP_ADDRESS:
case EOP_LOCAL_PART:
case EOP_DOMAIN:
case EOP_RFC2047:
{
uschar buffer[2048];
- uschar *string = parse_quote_2047(sub, Ustrlen(sub), headers_charset,
+ const uschar *string = parse_quote_2047(sub, Ustrlen(sub), headers_charset,
buffer, sizeof(buffer), FALSE);
yield = string_cat(yield, &size, &ptr, string, Ustrlen(string));
continue;
}
/* replace illegal UTF-8 sequences by replacement character */
-
+
#define UTF8_REPLACEMENT_CHAR US"?"
case EOP_UTF8CLEAN:
int bytes_left = 0;
long codepoint = -1;
uschar seq_buff[4]; /* accumulate utf-8 here */
-
+
while (*sub != 0)
{
int complete = 0;
if (bytes_left)
{
if ((c & 0xc0) != 0x80)
- {
/* wrong continuation byte; invalidate all bytes */
complete = 1; /* error */
- }
else
{
codepoint = (codepoint << 6) | (c & 0x3f);
seq_buff[index++] = c;
if (--bytes_left == 0) /* codepoint complete */
- {
if(codepoint > 0x10FFFF) /* is it too large? */
complete = -1; /* error (RFC3629 limit) */
else
yield = string_cat(yield, &size, &ptr, seq_buff, seq_len);
index = 0;
}
- }
}
}
else /* no bytes left: new sequence */
yield = string_cat(yield, &size, &ptr, UTF8_REPLACEMENT_CHAR, 1);
}
if ((complete == 1) && ((c & 0x80) == 0))
- { /* ASCII character follows incomplete sequence */
+ /* ASCII character follows incomplete sequence */
yield = string_cat(yield, &size, &ptr, &c, 1);
- }
}
continue;
}
+#ifdef SUPPORT_I18N
+ case EOP_UTF8_DOMAIN_TO_ALABEL:
+ {
+ uschar * error = NULL;
+ uschar * s = string_domain_utf8_to_alabel(sub, &error);
+ if (error)
+ {
+ expand_string_message = string_sprintf(
+ "error converting utf8 (%s) to alabel: %s",
+ string_printing(sub), error);
+ goto EXPAND_FAILED;
+ }
+ yield = string_cat(yield, &size, &ptr, s, Ustrlen(s));
+ continue;
+ }
+
+ case EOP_UTF8_DOMAIN_FROM_ALABEL:
+ {
+ uschar * error = NULL;
+ uschar * s = string_domain_alabel_to_utf8(sub, &error);
+ if (error)
+ {
+ expand_string_message = string_sprintf(
+ "error converting alabel (%s) to utf8: %s",
+ string_printing(sub), error);
+ goto EXPAND_FAILED;
+ }
+ yield = string_cat(yield, &size, &ptr, s, Ustrlen(s));
+ continue;
+ }
+
+ case EOP_UTF8_LOCALPART_TO_ALABEL:
+ {
+ uschar * error = NULL;
+ uschar * s = string_localpart_utf8_to_alabel(sub, &error);
+ if (error)
+ {
+ expand_string_message = string_sprintf(
+ "error converting utf8 (%s) to alabel: %s",
+ string_printing(sub), error);
+ goto EXPAND_FAILED;
+ }
+ yield = string_cat(yield, &size, &ptr, s, Ustrlen(s));
+ DEBUG(D_expand) debug_printf("yield: '%s'\n", yield);
+ continue;
+ }
+
+ case EOP_UTF8_LOCALPART_FROM_ALABEL:
+ {
+ uschar * error = NULL;
+ uschar * s = string_localpart_alabel_to_utf8(sub, &error);
+ if (error)
+ {
+ expand_string_message = string_sprintf(
+ "error converting alabel (%s) to utf8: %s",
+ string_printing(sub), error);
+ goto EXPAND_FAILED;
+ }
+ yield = string_cat(yield, &size, &ptr, s, Ustrlen(s));
+ continue;
+ }
+#endif /* EXPERIMENTAL_INTERNATIONAL */
+
/* escape turns all non-printing characters into escape sequences. */
case EOP_ESCAPE:
{
- uschar *t = string_printing(sub);
+ const uschar *t = string_printing(sub);
yield = string_cat(yield, &size, &ptr, t, Ustrlen(t));
continue;
}
+const uschar *
+expand_cstring(const uschar *string)
+{
+search_find_defer = FALSE;
+malformed_header = FALSE;
+return (Ustrpbrk(string, "$\\") == NULL)? string :
+ expand_string_internal(string, FALSE, NULL, FALSE, TRUE, NULL);
+}
+
+
+
/*************************************************
* Expand and copy *
*************************************************/
/* Now and again we want to expand a string and be sure that the result is in a
new bit of store. This function does that.
+Since we know it has been copied, the de-const cast is safe.
Argument: the string to be expanded
Returns: the expanded string, always in a new bit of store, or NULL
*/
uschar *
-expand_string_copy(uschar *string)
+expand_string_copy(const uschar *string)
{
-uschar *yield = expand_string(string);
+const uschar *yield = expand_cstring(string);
if (yield == string) yield = string_copy(string);
-return yield;
+return US yield;
}
*/
static int_eximarith_t
-expanded_string_integer(uschar *s, BOOL isplus)
+expanded_string_integer(const uschar *s, BOOL isplus)
{
int_eximarith_t value;
uschar *msg = US"invalid integer \"%s\"";
{
int ovector[3*(EXPAND_MAXN+1)];
int n = pcre_exec(re, NULL, subject, Ustrlen(subject), 0, PCRE_EOPT|options,
- ovector, sizeof(ovector)/sizeof(int));
+ ovector, nelem(ovector));
BOOL yield = n >= 0;
if (n == 0) n = EXPAND_MAXN + 1;
if (yield)
if (Ustrspn(argv[i], "abcdefghijklmnopqrtsuvwxyz0123456789-.:/") ==
Ustrlen(argv[i]))
{
- #ifdef LOOKUP_LDAP
+#ifdef LOOKUP_LDAP
eldap_default_servers = argv[i];
- #endif
- #ifdef LOOKUP_MYSQL
+#endif
+#ifdef LOOKUP_MYSQL
mysql_servers = argv[i];
- #endif
- #ifdef LOOKUP_PGSQL
+#endif
+#ifdef LOOKUP_PGSQL
pgsql_servers = argv[i];
- #endif
- #ifdef EXPERIMENTAL_REDIS
+#endif
+#ifdef LOOKUP_REDIS
redis_servers = argv[i];
- #endif
+#endif
}
- #ifdef EXIM_PERL
+#ifdef EXIM_PERL
else opt_perl_startup = argv[i];
- #endif
+#endif
}
printf("Testing string expansion: debug_level = %d\n\n", debug_level);
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
}
}
- *bp++ = string_interpret_escape(&ptr);
+ *bp++ = string_interpret_escape(CUSS &ptr);
}
}
set in a system filter and to the local address in user filters. */
addr = deliver_make_addr(expargs[0], TRUE); /* TRUE => copy s */
- addr->p.errors_address = (s == NULL)?
+ addr->prop.errors_address = (s == NULL)?
s : string_copy(s); /* Default is NULL */
if (commands->noerror) setflag(addr, af_ignore_error);
addr->next = *generated;
{
int sep = 0;
uschar *ss;
- uschar *list = s;
+ const uschar *list = s;
uschar buffer[128];
while ((ss = string_nextinlist(&list, &sep, buffer, sizeof(buffer)))
!= NULL)
DEFERFREEZEFAIL:
fmsg = expargs[0];
if (Ustrlen(fmsg) > 1024) Ustrcpy(fmsg + 1000, " ... (truncated)");
- fmsg = string_printing(fmsg);
+ fmsg = US string_printing(fmsg);
*error_pointer = fmsg;
if (filter_test != FTEST_NONE)
case testprint_command:
if (filter_test != FTEST_NONE || (debug_selector & D_filter) != 0)
{
- uschar *s = string_printing(expargs[0]);
+ const uschar *s = string_printing(expargs[0]);
if (filter_test == FTEST_NONE)
debug_printf("Filter: testprint: %s\n", s);
else
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
extern int tls_client_start(int, host_item *, address_item *,
transport_instance *
-#ifdef EXPERIMENTAL_DANE
+# ifdef EXPERIMENTAL_DANE
, dns_answer *
-#endif
+# endif
);
extern void tls_close(BOOL, BOOL);
extern int tls_export_cert(uschar *, size_t, void *);
extern int tls_feof(void);
extern int tls_ferror(void);
-extern void tls_free_cert(void *);
+extern void tls_free_cert(void **);
extern int tls_getc(void);
extern int tls_import_cert(const uschar *, void **);
extern int tls_read(BOOL, uschar *, size_t);
# ifndef USE_GNUTLS
extern BOOL tls_openssl_options_parse(uschar *, long *);
# endif
-extern uschar * tls_field_from_dn(uschar *, uschar *);
-extern BOOL tls_is_name_for_cert(uschar *, void *);
+extern uschar * tls_field_from_dn(uschar *, const uschar *);
+extern BOOL tls_is_name_for_cert(const uschar *, void *);
# ifdef EXPERIMENTAL_DANE
-extern int tlsa_lookup(host_item *, dns_answer *, BOOL, BOOL *);
+extern int tlsa_lookup(const host_item *, dns_answer *, BOOL, BOOL *);
# endif
#endif /*SUPPORT_TLS*/
extern void acl_var_write(uschar *, uschar *, void *);
extern uschar *auth_b64encode(uschar *, int);
extern int auth_b64decode(uschar *, uschar **);
-extern int auth_call_pam(uschar *, uschar **);
+extern int auth_call_pam(const uschar *, uschar **);
extern int auth_call_pwcheck(uschar *, uschar **);
-extern int auth_call_radius(uschar *, uschar **);
-extern int auth_call_saslauthd(uschar *, uschar *, uschar *, uschar *,
- uschar **);
+extern int auth_call_radius(const uschar *, uschar **);
+extern int auth_call_saslauthd(const uschar *, const uschar *,
+ const uschar *, const uschar *, uschar **);
extern int auth_check_serv_cond(auth_instance *);
extern int auth_check_some_cond(auth_instance *, uschar *, uschar *, int);
extern uschar *auth_xtextencode(uschar *, int);
extern int auth_xtextdecode(uschar *, uschar **);
+extern void bits_clear(unsigned int *, size_t, int *);
+extern void bits_set(unsigned int *, size_t, int *);
+
extern void cancel_cutthrough_connection(const char *);
-extern int check_host(void *, uschar *, uschar **, uschar **);
+extern int check_host(void *, const uschar *, const uschar **, uschar **);
extern uschar **child_exec_exim(int, BOOL, int *, BOOL, int, ...);
-extern pid_t child_open_uid(uschar **, uschar **, int, uid_t *, gid_t *,
- int *, int *, uschar *, BOOL);
+extern pid_t child_open_uid(const uschar **, const uschar **, int,
+ uid_t *, gid_t *, int *, int *, uschar *, BOOL);
extern uschar *cutthrough_finaldot(void);
extern BOOL cutthrough_flush_send(void);
extern BOOL cutthrough_headers_send(void);
#endif
extern void debug_logging_activate(uschar *, uschar *);
-extern void debug_print_argv(uschar **);
+extern void debug_print_argv(const uschar **);
extern void debug_print_ids(uschar *);
extern void debug_print_string(uschar *);
extern void debug_print_tree(tree_node *);
extern void debug_vprintf(const char *, va_list);
-extern void decode_bits(unsigned int *, unsigned int *,
- int, int, uschar *, bit_table *, int, uschar *, int);
+extern void decode_bits(unsigned int *, size_t, int *,
+ uschar *, bit_table *, int, uschar *, int);
extern address_item *deliver_make_addr(uschar *, BOOL);
extern void deliver_init(void);
extern void delivery_log(int, address_item *, int, uschar *);
extern void deliver_set_expansions(address_item *);
extern int deliver_split_address(address_item *);
extern void deliver_succeeded(address_item *);
+
+extern uschar *deliver_get_sender_address (uschar *id);
+
#ifdef WITH_OLD_DEMIME
extern int demime(uschar **);
#endif
int, uschar *, uschar *, uschar *, uschar *, uschar *, uschar *);
#endif
extern dns_address *dns_address_from_rr(dns_answer *, dns_record *);
-extern int dns_basic_lookup(dns_answer *, uschar *, int);
-extern void dns_build_reverse(uschar *, uschar *);
+extern int dns_basic_lookup(dns_answer *, const uschar *, int);
+extern void dns_build_reverse(const uschar *, uschar *);
extern void dns_init(BOOL, BOOL, BOOL);
-extern BOOL dns_is_secure(dns_answer *);
-extern int dns_lookup(dns_answer *, uschar *, int, uschar **);
+extern BOOL dns_is_aa(const dns_answer *);
+extern BOOL dns_is_secure(const dns_answer *);
+extern int dns_lookup(dns_answer *, const uschar *, int, const uschar **);
extern void dns_pattern_init(void);
-extern int dns_special_lookup(dns_answer *, uschar *, int, uschar **);
+extern int dns_special_lookup(dns_answer *, const uschar *, int, const uschar **);
extern dns_record *dns_next_rr(dns_answer *, dns_scan *, int);
extern uschar *dns_text_type(int);
extern void dscp_list_to_stream(FILE *);
extern BOOL dscp_lookup(const uschar *, int, int *, int *, int *);
extern void enq_end(uschar *);
-extern BOOL enq_start(uschar *);
-#ifdef EXPERIMENTAL_EVENT
-extern uschar *event_raise(uschar *, uschar *, uschar *);
+extern BOOL enq_start(uschar *, unsigned);
+#ifndef DISABLE_EVENT
+extern uschar *event_raise(uschar *, const uschar *, uschar *);
+extern void msg_event_raise(const uschar *, const address_item *);
#endif
extern void exim_exit(int);
extern void exim_nullstd(void);
uschar *mtype, uschar *mname, unsigned dgb_opt, uschar *oname, BOOL bvalue,
uschar *svalue, BOOL *rvalue);
extern BOOL expand_check_condition(uschar *, uschar *, uschar *);
-extern uschar *expand_string(uschar *);
-extern uschar *expand_string_copy(uschar *);
+extern uschar *expand_string(uschar *); /* public, cannot make const */
+extern const uschar *expand_cstring(const uschar *); /* ... so use this one */
+extern uschar *expand_string_copy(const uschar *);
extern int_eximarith_t expand_string_integer(uschar *, BOOL);
extern void modify_variable(uschar *, void *);
extern BOOL header_match(uschar *, BOOL, BOOL, string_item *, int, ...);
extern int host_address_extract_port(uschar *);
extern uschar *host_and_ident(BOOL);
-extern int host_aton(uschar *, int *);
-extern void host_build_hostlist(host_item **, uschar *, BOOL);
-extern ip_address_item *host_build_ifacelist(uschar *, uschar *);
+extern int host_aton(const uschar *, int *);
+extern void host_build_hostlist(host_item **, const uschar *, BOOL);
+extern ip_address_item *host_build_ifacelist(const uschar *, uschar *);
extern void host_build_log_info(void);
extern void host_build_sender_fullhost(void);
-extern BOOL host_find_byname(host_item *, uschar *, int, uschar **, BOOL);
-extern int host_find_bydns(host_item *, uschar *, int, uschar *, uschar *,
- uschar *, uschar *, uschar *, uschar **, BOOL *);
+extern BOOL host_find_byname(host_item *, const uschar *, int,
+ const uschar **, BOOL);
+extern int host_find_bydns(host_item *, const uschar *, int, uschar *, uschar *,
+ uschar *, const dnssec_domains *, const uschar **, BOOL *);
extern ip_address_item *host_find_interfaces(void);
-extern BOOL host_is_in_net(uschar *, uschar *, int);
+extern BOOL host_is_in_net(const uschar *, const uschar *, int);
extern BOOL host_is_tls_on_connect_port(int);
extern int host_item_get_port(host_item *);
extern void host_mask(int, int *, int);
extern uschar *host_ntoa(int, const void *, uschar *, int *);
extern int host_scan_for_local_hosts(host_item *, host_item **, BOOL *);
+extern uschar *imap_utf7_encode(uschar *, const uschar *,
+ uschar, uschar *, uschar **);
+
extern void invert_address(uschar *, uschar *);
+extern int ip_addr(void *, int, const uschar *, int);
extern int ip_bind(int, int, uschar *, int);
extern int ip_connect(int, int, const uschar *, int, int);
extern int ip_connectedsocket(int, const uschar *, int, int,
int, host_item *, uschar **);
extern int ip_get_address_family(int);
-extern void ip_keepalive(int, uschar *, BOOL);
+extern void ip_keepalive(int, const uschar *, BOOL);
extern int ip_recv(int, uschar *, int, int);
extern int ip_socket(int, int);
+extern int ip_tcpsocket(const uschar *, uschar **, int);
+extern int ip_unixsocket(const uschar *, uschar **);
+extern int ip_streamsocket(const uschar *, uschar **, int);
+
+extern int ipv6_nmtoa(int *, uschar *);
+
extern uschar *local_part_quote(uschar *);
extern int log_create(uschar *);
extern int log_create_as_exim(uschar *);
extern int malware_in_file(uschar *);
extern void malware_init(void);
#endif
-extern int match_address_list(uschar *, BOOL, BOOL, uschar **,
- unsigned int *, int, int, uschar **);
-extern int match_check_list(uschar **, int, tree_node **, unsigned int **,
- int(*)(void *, uschar *, uschar **, uschar **), void *, int,
- uschar *, uschar **);
-extern int match_isinlist(uschar *, uschar **, int, tree_node **,
- unsigned int *, int, BOOL, uschar **);
-extern int match_check_string(uschar *, uschar *, int, BOOL, BOOL, BOOL,
- uschar **);
+extern int match_address_list(const uschar *, BOOL, BOOL, const uschar **,
+ unsigned int *, int, int, const uschar **);
+extern int match_check_list(const uschar **, int, tree_node **, unsigned int **,
+ int(*)(void *, const uschar *, const uschar **, uschar **), void *, int,
+ const uschar *, const uschar **);
+extern int match_isinlist(const uschar *, const uschar **, int, tree_node **,
+ unsigned int *, int, BOOL, const uschar **);
+extern int match_check_string(const uschar *, const uschar *, int, BOOL, BOOL, BOOL,
+ const uschar **);
extern void md5_end(md5 *, const uschar *, int, uschar *);
extern void md5_mid(md5 *, const uschar *);
extern void md5_start(md5 *);
struct mime_boundary_context;
extern int mime_acl_check(uschar *acl, FILE *f,
struct mime_boundary_context *, uschar **, uschar **);
-extern int mime_decode(uschar **);
-extern int mime_regex(uschar **);
+extern int mime_decode(const uschar **);
+extern int mime_regex(const uschar **);
#endif
extern uschar *moan_check_errorcopy(uschar *);
extern BOOL moan_skipped_syntax_errors(uschar *, error_block *, uschar *,
extern uschar *parse_extract_address(uschar *, uschar **, int *, int *, int *,
BOOL);
extern int parse_forward_list(uschar *, int, address_item **, uschar **,
- uschar *, uschar *, error_block **);
+ const uschar *, uschar *, error_block **);
extern uschar *parse_find_address_end(uschar *, BOOL);
extern uschar *parse_find_at(uschar *);
-extern uschar *parse_fix_phrase(uschar *, int, uschar *, int);
+extern const uschar *parse_fix_phrase(const uschar *, int, uschar *, int);
extern uschar *parse_message_id(uschar *, uschar **, uschar **);
-extern uschar *parse_quote_2047(uschar *, int, uschar *, uschar *, int, BOOL);
+extern const uschar *parse_quote_2047(const uschar *, int, uschar *, uschar *, int, BOOL);
extern uschar *parse_date_time(uschar *str, time_t *t);
extern int vaguely_random_number(int);
#ifdef SUPPORT_TLS
extern uschar *readconf_printtime(int);
extern uschar *readconf_readname(uschar *, int, uschar *);
extern int readconf_readtime(const uschar *, int, BOOL);
-extern void readconf_rest();
-extern uschar *readconf_retry_error(uschar *, uschar *, int *, int *);
+extern void readconf_rest(void);
+extern uschar *readconf_retry_error(const uschar *, const uschar *, int *, int *);
+extern void readconf_save_config(const uschar *);
extern void read_message_body(BOOL);
extern void receive_bomb_out(uschar *, uschar *);
extern BOOL receive_check_fs(int);
extern int receive_statvfs(BOOL, int *);
extern void receive_swallow_smtp(void);
#ifdef WITH_CONTENT_SCAN
-extern int regex(uschar **);
+extern int regex(const uschar **);
#endif
-extern BOOL regex_match_and_setup(const pcre *, uschar *, int, int);
+extern BOOL regex_match_and_setup(const pcre *, const uschar *, int, int);
extern const pcre *regex_must_compile(const uschar *, BOOL, BOOL);
extern void retry_add_item(address_item *, uschar *, int);
-extern BOOL retry_check_address(uschar *, host_item *, uschar *, BOOL,
+extern BOOL retry_check_address(const uschar *, host_item *, uschar *, BOOL,
uschar **, uschar **);
-extern retry_config *retry_find_config(uschar *, uschar *, int, int);
-extern BOOL retry_ultimate_address_timeout(uschar *, uschar *,
+extern retry_config *retry_find_config(const uschar *, const uschar *, int, int);
+extern BOOL retry_ultimate_address_timeout(uschar *, const uschar *,
dbdata_retry *, time_t);
extern void retry_update(address_item **, address_item **, address_item **);
extern uschar *rewrite_address(uschar *, BOOL, BOOL, rewrite_rule *, int);
extern uschar *rewrite_address_qualify(uschar *, BOOL);
-extern header_line *rewrite_header(header_line *, uschar *, uschar *,
+extern header_line *rewrite_header(header_line *,
+ const uschar *, const uschar *,
rewrite_rule *, int, BOOL);
extern uschar *rewrite_one(uschar *, int, BOOL *, BOOL, uschar *,
rewrite_rule *);
uschar **);
extern int route_address(address_item *, address_item **, address_item **,
address_item **, address_item **, int);
-extern int route_check_prefix(uschar *, uschar *);
-extern int route_check_suffix(uschar *, uschar *);
+extern int route_check_prefix(const uschar *, const uschar *);
+extern int route_check_suffix(const uschar *, const uschar *);
extern BOOL route_findgroup(uschar *, gid_t *);
-extern BOOL route_finduser(uschar *, struct passwd **, uid_t *);
+extern BOOL route_finduser(const uschar *, struct passwd **, uid_t *);
extern BOOL route_find_expanded_group(uschar *, uschar *, uschar *, gid_t *,
uschar **);
extern BOOL route_find_expanded_user(uschar *, uschar *, uschar *,
extern void route_init(void);
extern void route_tidyup(void);
-extern uschar *search_find(void *, uschar *, uschar *, int, uschar *, int,
+extern uschar *search_find(void *, uschar *, uschar *, int, const uschar *, int,
int, int *);
-extern int search_findtype(uschar *, int);
-extern int search_findtype_partial(uschar *, int *, uschar **, int *,
+extern int search_findtype(const uschar *, int);
+extern int search_findtype_partial(const uschar *, int *, const uschar **, int *,
int *);
extern void *search_open(uschar *, int, int, uid_t *, gid_t *);
extern void search_tidyup(void);
extern void sigalrm_handler(int);
extern BOOL smtp_buffered(void);
extern void smtp_closedown(uschar *);
-extern int smtp_connect(host_item *, int, int, uschar *, int, BOOL, const uschar *
-#ifdef EXPERIMENTAL_EVENT
- , uschar *
-#endif
- );
+extern int smtp_connect(host_item *, int, int, uschar *, int,
+ transport_instance *);
+extern int smtp_sock_connect(host_item *, int, int, uschar *,
+ transport_instance * tb, int);
extern int smtp_feof(void);
extern int smtp_ferror(void);
extern uschar *smtp_get_connection_info(void);
-extern BOOL smtp_get_interface(uschar *, int, address_item *, BOOL *,
+extern BOOL smtp_get_interface(uschar *, int, address_item *,
uschar **, uschar *);
extern BOOL smtp_get_port(uschar *, address_item *, int *, uschar *);
extern int smtp_getc(void);
extern BOOL smtp_verify_helo(void);
extern int smtp_write_command(smtp_outblock *, BOOL, const char *, ...) PRINTF_FUNCTION(3,4);
#ifdef WITH_CONTENT_SCAN
-extern int spam(uschar **);
+extern int spam(const uschar **);
extern FILE *spool_mbox(unsigned long *, const uschar *);
#endif
extern BOOL spool_move_message(uschar *, uschar *, uschar *, uschar *);
extern int stdin_ungetc(int);
extern uschar *string_append(uschar *, int *, int *, int, ...);
extern uschar *string_append_listele(uschar *, uschar, const uschar *);
+extern uschar *string_append_listele_n(uschar *, uschar, const uschar *, unsigned);
extern uschar *string_base62(unsigned long int);
extern uschar *string_cat(uschar *, int *, int *, const uschar *, int);
extern uschar *string_copy_dnsdomain(uschar *);
-extern uschar *string_copy_malloc(uschar *);
-extern uschar *string_copylc(uschar *);
+extern uschar *string_copy_malloc(const uschar *);
+extern uschar *string_copylc(const uschar *);
extern uschar *string_copynlc(uschar *, int);
-extern uschar *string_dequote(uschar **);
+extern uschar *string_dequote(const uschar **);
extern BOOL string_format(uschar *, int, const char *, ...) ALMOST_PRINTF(3,4);
extern uschar *string_format_size(int, uschar *);
-extern int string_interpret_escape(uschar **);
+extern int string_interpret_escape(const uschar **);
extern int string_is_ip_address(const uschar *, int *);
+#ifdef SUPPORT_I18N
+extern BOOL string_is_utf8(const uschar *);
+#endif
extern uschar *string_log_address(address_item *, BOOL, BOOL);
-extern uschar *string_nextinlist(uschar **, int *, uschar *, int);
+extern uschar *string_nextinlist(const uschar **, int *, uschar *, int);
extern uschar *string_open_failed(int, const char *, ...) PRINTF_FUNCTION(2,3);
-extern uschar *string_printing2(uschar *, BOOL);
+extern const uschar *string_printing2(const uschar *, BOOL);
extern uschar *string_split_message(uschar *);
extern uschar *string_unprinting(uschar *);
+#ifdef SUPPORT_I18N
+extern uschar *string_address_utf8_to_alabel(const uschar *, uschar **);
+extern uschar *string_domain_alabel_to_utf8(const uschar *, uschar **);
+extern uschar *string_domain_utf8_to_alabel(const uschar *, uschar **);
+extern uschar *string_localpart_alabel_to_utf8(const uschar *, uschar **);
+extern uschar *string_localpart_utf8_to_alabel(const uschar *, uschar **);
+#endif
extern BOOL string_vformat(uschar *, int, const char *, va_list);
extern int strcmpic(const uschar *, const uschar *);
extern int strncmpic(const uschar *, const uschar *, int);
extern uschar *tod_stamp(int);
extern void tls_modify_variables(tls_support *);
-extern BOOL transport_check_waiting(uschar *, uschar *, int, uschar *,
- BOOL *);
+extern BOOL transport_check_waiting(const uschar *, const uschar *, int, uschar *,
+ BOOL *, oicf, void*);
extern void transport_init(void);
-extern BOOL transport_pass_socket(uschar *, uschar *, uschar *, uschar *,
+extern BOOL transport_pass_socket(const uschar *, const uschar *, const uschar *, uschar *,
int);
extern uschar *transport_rcpt_address(address_item *, BOOL);
-extern BOOL transport_set_up_command(uschar ***, uschar *, BOOL, int,
- address_item *, uschar *, uschar **);
+extern BOOL transport_set_up_command(const uschar ***, uschar *,
+ BOOL, int, address_item *, uschar *, uschar **);
extern void transport_update_waiting(host_item *, uschar *);
extern BOOL transport_write_block(int, uschar *, int);
extern BOOL transport_write_string(int, const char *, ...);
extern void tree_add_nonrecipient(uschar *);
extern void tree_add_unusable(host_item *);
extern int tree_insertnode(tree_node **, tree_node *);
-extern tree_node *tree_search(tree_node *, uschar *);
+extern tree_node *tree_search(tree_node *, const uschar *);
extern void tree_write(tree_node *, FILE *);
extern void tree_walk(tree_node *, void (*)(uschar*, uschar*, void*), void *);
#ifdef WITH_CONTENT_SCAN
extern void unspool_mbox(void);
#endif
+#ifdef SUPPORT_I18N
+extern void utf8_version_report(FILE *);
+#endif
extern int verify_address(address_item *, FILE *, int, int, int, int,
uschar *, uschar *, BOOL *);
-extern int verify_check_dnsbl(uschar **);
+extern int verify_check_dnsbl(int, const uschar **, uschar **);
extern int verify_check_header_address(uschar **, uschar **, int, int, int,
uschar *, uschar *, int, int *);
extern int verify_check_headers(uschar **);
extern int verify_check_host(uschar **);
extern int verify_check_notblind(void);
extern int verify_check_given_host(uschar **, host_item *);
-extern int verify_check_this_host(uschar **, unsigned int *, uschar*,
- uschar *, uschar **);
+extern int verify_check_this_host(const uschar **, unsigned int *,
+ const uschar*, const uschar *, const uschar **);
extern address_item *verify_checked_sender(uschar *);
extern void verify_get_ident(int);
extern BOOL verify_sender(int *, uschar **);
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* All the global variables are defined together in this one module, so
uschar *pgsql_servers = NULL;
#endif
-#ifdef EXPERIMENTAL_REDIS
+#ifdef LOOKUP_REDIS
uschar *redis_servers = NULL;
#endif
uschar *gnutls_require_proto = NULL;
uschar *openssl_options = NULL;
const pcre *regex_STARTTLS = NULL;
-uschar *tls_advertise_hosts = NULL; /* This is deliberate */
+uschar *tls_advertise_hosts = US"*";
uschar *tls_certificate = NULL;
uschar *tls_crl = NULL;
/* This default matches NSS DH_MAX_P_BITS value at current time (2012), because
bit-count as "NORMAL" (2432) and Thunderbird dropping connection. */
int tls_dh_max_bits = 2236;
uschar *tls_dhparam = NULL;
-#ifndef DISABLE_OCSP
+uschar *tls_eccurve = US"prime256v1";
+# ifndef DISABLE_OCSP
uschar *tls_ocsp_file = NULL;
-#endif
+# endif
BOOL tls_offered = FALSE;
uschar *tls_privatekey = NULL;
BOOL tls_remember_esmtp = FALSE;
uschar *tls_try_verify_hosts = NULL;
uschar *tls_verify_certificates= US"system";
uschar *tls_verify_hosts = NULL;
+#else /*!SUPPORT_TLS*/
+uschar *tls_advertise_hosts = NULL;
#endif
#ifndef DISABLE_PRDR
const pcre *regex_PRDR = NULL;
#endif
+#ifdef SUPPORT_I18N
+const pcre *regex_UTF8 = NULL;
+#endif
+
/* Input-reading functions for messages, so we can use special ones for
incoming TCP/IP. The defaults use stdin. We never need these for any
stand-alone tests. */
when verifying one address while routing/verifying another. We have to have
the size explicit, because it is referenced from more than one module. */
-uschar **address_expansions[ADDRESS_EXPANSIONS_COUNT] = {
- &deliver_address_data,
- &deliver_domain,
- &deliver_domain_data,
- &deliver_domain_orig,
- &deliver_domain_parent,
- &deliver_localpart,
- &deliver_localpart_data,
- &deliver_localpart_orig,
- &deliver_localpart_parent,
- &deliver_localpart_prefix,
- &deliver_localpart_suffix,
- (uschar **)(&deliver_recipients),
- &deliver_host,
- &deliver_home,
- &address_file,
- &address_pipe,
- &self_hostname,
+const uschar **address_expansions[ADDRESS_EXPANSIONS_COUNT] = {
+ CUSS &deliver_address_data,
+ CUSS &deliver_domain,
+ CUSS &deliver_domain_data,
+ CUSS &deliver_domain_orig,
+ CUSS &deliver_domain_parent,
+ CUSS &deliver_localpart,
+ CUSS &deliver_localpart_data,
+ CUSS &deliver_localpart_orig,
+ CUSS &deliver_localpart_parent,
+ CUSS &deliver_localpart_prefix,
+ CUSS &deliver_localpart_suffix,
+ CUSS (uschar **)(&deliver_recipients),
+ CUSS &deliver_host,
+ CUSS &deliver_home,
+ CUSS &address_file,
+ CUSS &address_pipe,
+ CUSS &self_hostname,
NULL };
int address_expansions_count = sizeof(address_expansions)/sizeof(uschar **);
NULL, /* return_filename */
NULL, /* self_hostname */
NULL, /* shadow_message */
- #ifdef SUPPORT_TLS
+#ifdef SUPPORT_TLS
NULL, /* cipher */
NULL, /* ourcert */
NULL, /* peercert */
NULL, /* peerdn */
OCSP_NOT_REQ, /* ocsp */
- #endif
+#endif
+#ifdef EXPERIMENTAL_DSN_INFO
+ NULL, /* smtp_greeting */
+ NULL, /* helo_response */
+#endif
NULL, /* authenticator */
NULL, /* auth_id */
NULL, /* auth_sndr */
NULL, /* remove_headers */
#ifdef EXPERIMENTAL_SRS
NULL, /* srs_sender */
+#endif
+#ifdef SUPPORT_I18N
+ FALSE, /* utf8 */
#endif
}
};
uschar *bounce_sender_authentication = NULL;
int bsmtp_transaction_linecount = 0;
+uschar *callout_address = NULL;
int callout_cache_domain_positive_expire = 7*24*60*60;
int callout_cache_domain_negative_expire = 3*60*60;
int callout_cache_positive_expire = 24*60*60;
uschar *continue_transport = NULL;
uschar *csa_status = NULL;
-BOOL cutthrough_delivery = FALSE;
-int cutthrough_fd = -1;
+cut_t cutthrough = {
+ FALSE, /* delivery: when to attempt */
+ -1, /* fd: open connection */
+ 0, /* nrcpt: number of addresses */
+};
BOOL daemon_listen = FALSE;
uschar *daemon_smtp_port = US"smtp";
BOOL debug_daemon = FALSE;
int debug_fd = -1;
FILE *debug_file = NULL;
-bit_table debug_options[] = {
- { US"acl", D_acl },
- { US"all", D_all },
- { US"auth", D_auth },
- { US"deliver", D_deliver },
- { US"dns", D_dns },
- { US"dnsbl", D_dnsbl },
- { US"exec", D_exec },
- { US"expand", D_expand },
- { US"filter", D_filter },
- { US"hints_lookup", D_hints_lookup },
- { US"host_lookup", D_host_lookup },
- { US"ident", D_ident },
- { US"interface", D_interface },
- { US"lists", D_lists },
- { US"load", D_load },
- { US"local_scan", D_local_scan },
- { US"lookup", D_lookup },
- { US"memory", D_memory },
- { US"pid", D_pid },
- { US"process_info", D_process_info },
- { US"queue_run", D_queue_run },
- { US"receive", D_receive },
- { US"resolver", D_resolver },
- { US"retry", D_retry },
- { US"rewrite", D_rewrite },
- { US"route", D_route },
- { US"timestamp", D_timestamp },
- { US"tls", D_tls },
- { US"transport", D_transport },
- { US"uid", D_uid },
- { US"verify", D_verify }
+int debug_notall[] = {
+ Di_memory,
+ -1
+};
+bit_table debug_options[] = { /* must be in alphabetical order */
+ BIT_TABLE(D, acl),
+ BIT_TABLE(D, all),
+ BIT_TABLE(D, auth),
+ BIT_TABLE(D, deliver),
+ BIT_TABLE(D, dns),
+ BIT_TABLE(D, dnsbl),
+ BIT_TABLE(D, exec),
+ BIT_TABLE(D, expand),
+ BIT_TABLE(D, filter),
+ BIT_TABLE(D, hints_lookup),
+ BIT_TABLE(D, host_lookup),
+ BIT_TABLE(D, ident),
+ BIT_TABLE(D, interface),
+ BIT_TABLE(D, lists),
+ BIT_TABLE(D, load),
+ BIT_TABLE(D, local_scan),
+ BIT_TABLE(D, lookup),
+ BIT_TABLE(D, memory),
+ BIT_TABLE(D, pid),
+ BIT_TABLE(D, process_info),
+ BIT_TABLE(D, queue_run),
+ BIT_TABLE(D, receive),
+ BIT_TABLE(D, resolver),
+ BIT_TABLE(D, retry),
+ BIT_TABLE(D, rewrite),
+ BIT_TABLE(D, route),
+ BIT_TABLE(D, timestamp),
+ BIT_TABLE(D, tls),
+ BIT_TABLE(D, transport),
+ BIT_TABLE(D, uid),
+ BIT_TABLE(D, verify),
};
-int debug_options_count = sizeof(debug_options)/sizeof(bit_table);
+int debug_options_count = nelem(debug_options);
+
unsigned int debug_selector = 0;
int delay_warning[DELAY_WARNING_SIZE] = { DELAY_WARNING_SIZE, 1, 24*60*60 };
uschar *delay_warning_condition=
BOOL delivery_date_remove = TRUE;
uschar *deliver_address_data = NULL;
int deliver_datafile = -1;
-uschar *deliver_domain = NULL;
+const uschar *deliver_domain = NULL;
uschar *deliver_domain_data = NULL;
-uschar *deliver_domain_orig = NULL;
-uschar *deliver_domain_parent = NULL;
+const uschar *deliver_domain_orig = NULL;
+const uschar *deliver_domain_parent = NULL;
BOOL deliver_drop_privilege = FALSE;
BOOL deliver_firsttime = FALSE;
BOOL deliver_force = FALSE;
BOOL deliver_freeze = FALSE;
time_t deliver_frozen_at = 0;
uschar *deliver_home = NULL;
-uschar *deliver_host = NULL;
-uschar *deliver_host_address = NULL;
+const uschar *deliver_host = NULL;
+const uschar *deliver_host_address = NULL;
int deliver_host_port = 0;
uschar *deliver_in_buffer = NULL;
ino_t deliver_inode = 0;
BOOL disable_logging = FALSE;
#ifndef DISABLE_DKIM
+BOOL dkim_collect_input = FALSE;
uschar *dkim_cur_signer = NULL;
+BOOL dkim_disable_verify = FALSE;
+int dkim_key_length = 0;
uschar *dkim_signers = NULL;
uschar *dkim_signing_domain = NULL;
uschar *dkim_signing_selector = NULL;
uschar *dkim_verify_signers = US"$dkim_signers";
-BOOL dkim_collect_input = FALSE;
-BOOL dkim_disable_verify = FALSE;
#endif
#ifdef EXPERIMENTAL_DMARC
BOOL dmarc_has_been_checked = FALSE;
int dns_retrans = 0;
int dns_retry = 0;
int dns_dnssec_ok = -1; /* <0 = not coerced */
+uschar *dns_trust_aa = NULL;
int dns_use_edns0 = -1; /* <0 = not coerced */
uschar *dnslist_domain = NULL;
uschar *dnslist_matched = NULL;
int error_handling = ERRORS_SENDER;
uschar *errors_reply_to = NULL;
int errors_sender_rc = EXIT_FAILURE;
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
uschar *event_action = NULL; /* expansion for delivery events */
uschar *event_data = NULL; /* auxilary data variable for event */
int event_defer_errno = 0;
-uschar *event_name = NULL; /* event name variable */
+const uschar *event_name = NULL; /* event name variable */
#endif
tree_node *localpartlist_anchor= NULL;
int localpartlist_count = 0;
uschar *log_buffer = NULL;
-unsigned int log_extra_selector = LX_default;
+
+int log_default[] = { /* for initializing log_selector */
+ Li_acl_warn_skipped,
+ Li_connection_reject,
+ Li_delay_delivery,
+ Li_dnslist_defer,
+ Li_etrn,
+ Li_host_lookup_failed,
+ Li_lost_incoming_connection,
+ Li_outgoing_interface, /* see d_log_interface in deliver.c */
+ Li_queue_run,
+ Li_rejected_header,
+ Li_retry_defer,
+ Li_sender_verify_fail,
+ Li_size_reject,
+ Li_skip_delivery,
+ Li_smtp_confirmation,
+ Li_tls_certificate_verified,
+ Li_tls_cipher,
+ -1
+};
+
uschar *log_file_path = US LOG_FILE_PATH
"\0<--------------Space to patch log_file_path->";
-/* Those log options with L_xxx identifiers have values less than 0x800000 and
-are the ones that get put into log_write_selector. They can be used in calls to
-log_write() to test for the bit. The options with LX_xxx identifiers have
-values greater than 0x80000000 and are put into log_extra_selector (without the
-top bit). They are never used in calls to log_write(), but are tested
-independently. This separation became necessary when the number of log
-selectors was getting close to filling a 32-bit word. */
-
-/* Note that this list must be in alphabetical order. */
-
-bit_table log_options[] = {
- { US"8bitmime", LX_8bitmime },
- { US"acl_warn_skipped", LX_acl_warn_skipped },
- { US"address_rewrite", L_address_rewrite },
- { US"all", L_all },
- { US"all_parents", L_all_parents },
- { US"arguments", LX_arguments },
- { US"connection_reject", L_connection_reject },
- { US"delay_delivery", L_delay_delivery },
- { US"deliver_time", LX_deliver_time },
- { US"delivery_size", LX_delivery_size },
- { US"dnslist_defer", L_dnslist_defer },
- { US"etrn", L_etrn },
- { US"host_lookup_failed", L_host_lookup_failed },
- { US"ident_timeout", LX_ident_timeout },
- { US"incoming_interface", LX_incoming_interface },
- { US"incoming_port", LX_incoming_port },
- { US"lost_incoming_connection", L_lost_incoming_connection },
- { US"outgoing_port", LX_outgoing_port },
- { US"pid", LX_pid },
-#ifdef EXPERIMENTAL_PROXY
- { US"proxy", LX_proxy },
+int log_notall[] = {
+ -1
+};
+bit_table log_options[] = { /* must be in alphabetical order */
+ BIT_TABLE(L, 8bitmime),
+ BIT_TABLE(L, acl_warn_skipped),
+ BIT_TABLE(L, address_rewrite),
+ BIT_TABLE(L, all),
+ BIT_TABLE(L, all_parents),
+ BIT_TABLE(L, arguments),
+ BIT_TABLE(L, connection_reject),
+ BIT_TABLE(L, delay_delivery),
+ BIT_TABLE(L, deliver_time),
+ BIT_TABLE(L, delivery_size),
+ BIT_TABLE(L, dnslist_defer),
+ BIT_TABLE(L, etrn),
+ BIT_TABLE(L, host_lookup_failed),
+ BIT_TABLE(L, ident_timeout),
+ BIT_TABLE(L, incoming_interface),
+ BIT_TABLE(L, incoming_port),
+ BIT_TABLE(L, lost_incoming_connection),
+ BIT_TABLE(L, outgoing_interface),
+ BIT_TABLE(L, outgoing_port),
+ BIT_TABLE(L, pid),
+#if defined(SUPPORT_PROXY) || defined (SUPPORT_SOCKS)
+ BIT_TABLE(L, proxy),
#endif
- { US"queue_run", L_queue_run },
- { US"queue_time", LX_queue_time },
- { US"queue_time_overall", LX_queue_time_overall },
- { US"received_recipients", LX_received_recipients },
- { US"received_sender", LX_received_sender },
- { US"rejected_header", LX_rejected_header },
- { US"rejected_headers", LX_rejected_header },
- { US"retry_defer", L_retry_defer },
- { US"return_path_on_delivery", LX_return_path_on_delivery },
- { US"sender_on_delivery", LX_sender_on_delivery },
- { US"sender_verify_fail", LX_sender_verify_fail },
- { US"size_reject", L_size_reject },
- { US"skip_delivery", L_skip_delivery },
- { US"smtp_confirmation", LX_smtp_confirmation },
- { US"smtp_connection", L_smtp_connection },
- { US"smtp_incomplete_transaction", L_smtp_incomplete_transaction },
- { US"smtp_mailauth", LX_smtp_mailauth },
- { US"smtp_no_mail", LX_smtp_no_mail },
- { US"smtp_protocol_error", L_smtp_protocol_error },
- { US"smtp_syntax_error", L_smtp_syntax_error },
- { US"subject", LX_subject },
- { US"tls_certificate_verified", LX_tls_certificate_verified },
- { US"tls_cipher", LX_tls_cipher },
- { US"tls_peerdn", LX_tls_peerdn },
- { US"tls_sni", LX_tls_sni },
- { US"unknown_in_list", LX_unknown_in_list }
+ BIT_TABLE(L, queue_run),
+ BIT_TABLE(L, queue_time),
+ BIT_TABLE(L, queue_time_overall),
+ BIT_TABLE(L, received_recipients),
+ BIT_TABLE(L, received_sender),
+ BIT_TABLE(L, rejected_header),
+ { US"rejected_headers", Li_rejected_header },
+ BIT_TABLE(L, retry_defer),
+ BIT_TABLE(L, return_path_on_delivery),
+ BIT_TABLE(L, sender_on_delivery),
+ BIT_TABLE(L, sender_verify_fail),
+ BIT_TABLE(L, size_reject),
+ BIT_TABLE(L, skip_delivery),
+ BIT_TABLE(L, smtp_confirmation),
+ BIT_TABLE(L, smtp_connection),
+ BIT_TABLE(L, smtp_incomplete_transaction),
+ BIT_TABLE(L, smtp_mailauth),
+ BIT_TABLE(L, smtp_no_mail),
+ BIT_TABLE(L, smtp_protocol_error),
+ BIT_TABLE(L, smtp_syntax_error),
+ BIT_TABLE(L, subject),
+ BIT_TABLE(L, tls_certificate_verified),
+ BIT_TABLE(L, tls_cipher),
+ BIT_TABLE(L, tls_peerdn),
+ BIT_TABLE(L, tls_sni),
+ BIT_TABLE(L, unknown_in_list),
};
+int log_options_count = nelem(log_options);
-int log_options_count = sizeof(log_options)/sizeof(bit_table);
int log_reject_target = 0;
+unsigned int log_selector[log_selector_size]; /* initialized in main() */
uschar *log_selector_string = NULL;
FILE *log_stderr = NULL;
BOOL log_testing_mode = FALSE;
BOOL log_timezone = FALSE;
-unsigned int log_write_selector= L_default;
uschar *login_sender_address = NULL;
uschar *lookup_dnssec_authenticated = NULL;
int lookup_open_max = 25;
BOOL message_logs = TRUE;
int message_size = 0;
uschar *message_size_limit = US"50M";
+#ifdef SUPPORT_I18N
+BOOL message_smtputf8 = FALSE;
+int message_utf8_downconvert = 0; /* -1 ifneeded; 0 never; 1 always */
+#endif
uschar message_subdir[2] = { 0, 0 };
uschar *message_reference = NULL;
uschar *process_log_path = NULL;
BOOL prod_requires_admin = TRUE;
-#ifdef EXPERIMENTAL_PROXY
-uschar *proxy_host_address = US"";
-int proxy_host_port = 0;
-uschar *proxy_required_hosts = US"";
+#if defined(SUPPORT_PROXY) || defined(SUPPORT_SOCKS)
+uschar *hosts_proxy = US"";
+uschar *proxy_external_address = US"";
+int proxy_external_port = 0;
+uschar *proxy_local_address = US"";
+int proxy_local_port = 0;
BOOL proxy_session = FALSE;
BOOL proxy_session_failed = FALSE;
-uschar *proxy_target_address = US"";
-int proxy_target_port = 0;
#endif
uschar *prvscheck_address = NULL;
uschar *prvscheck_result = NULL;
-uschar *qualify_domain_recipient = NULL;
+const uschar *qualify_domain_recipient = NULL;
uschar *qualify_domain_sender = NULL;
BOOL queue_2stage = FALSE;
uschar *queue_domains = NULL;
const pcre *regex_IGNOREQUOTA = NULL;
const pcre *regex_PIPELINING = NULL;
const pcre *regex_SIZE = NULL;
-const pcre *regex_smtp_code = NULL;
const pcre *regex_ismsgid = NULL;
+const pcre *regex_smtp_code = NULL;
+uschar *regex_vars[REGEX_VARS];
#ifdef WHITELIST_D_MACROS
const pcre *regex_whitelisted_macro = NULL;
#endif
NULL, /* fallback_hostlist */
NULL, /* transport instance */
NULL, /* pass_router */
- NULL /* redirect_router */
+ NULL, /* redirect_router */
+
+ { NULL, NULL }, /* dnssec_domains {require,request} */
};
uschar *router_name = NULL;
uschar *sender_data = NULL;
unsigned int sender_domain_cache[(MAX_NAMED_LIST * 2)/32];
uschar *sender_fullhost = NULL;
+BOOL sender_helo_dnssec = FALSE;
uschar *sender_helo_name = NULL;
uschar **sender_host_aliases = &no_aliases;
uschar *sender_host_address = NULL;
int sending_port = -1;
SIGNAL_BOOL sigalrm_seen = FALSE;
uschar **sighup_argv = NULL;
+int slow_lookup_log = 0; /* millisecs, zero disables */
int smtp_accept_count = 0;
BOOL smtp_accept_keepalive = TRUE;
int smtp_accept_max = 20;
int smtp_rlr_threshold = INT_MAX;
BOOL smtp_use_pipelining = FALSE;
BOOL smtp_use_size = FALSE;
+#ifdef SUPPORT_I18N
+uschar *smtputf8_advertise_hosts = US"*"; /* overridden under test-harness */
+#endif
#ifdef WITH_CONTENT_SCAN
uschar *spamd_address = US"127.0.0.1 783";
uschar *spam_bar = NULL;
uschar *spam_report = NULL;
+uschar *spam_action = NULL;
uschar *spam_score = NULL;
uschar *spam_score_int = NULL;
#endif
NULL, /* remove_headers */
NULL, /* return_path */
NULL, /* debug_string */
+ NULL, /* max_parallel */
NULL, /* message_size_limit */
NULL, /* headers_rewrite */
NULL, /* rewrite_rules */
FALSE, /* log_defer_output */
TRUE_UNSET /* retry_use_local_part: BOOL, but set neither
1 nor 0 so can detect unset */
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
,NULL /* event_action */
#endif
};
int transport_count;
uschar *transport_name = NULL;
int transport_newlines;
-uschar **transport_filter_argv = NULL;
+const uschar **transport_filter_argv = NULL;
int transport_filter_timeout;
BOOL transport_filter_timed_out = FALSE;
int transport_write_timeout= 0;
uschar *verify_mode = NULL;
uschar *version_copyright =
- US"Copyright (c) University of Cambridge, 1995 - 2014\n"
- "(c) The Exim Maintainers and contributors in ACKNOWLEDGMENTS file, 2007 - 2014";
+ US"Copyright (c) University of Cambridge, 1995 - 2015\n"
+ "(c) The Exim Maintainers and contributors in ACKNOWLEDGMENTS file, 2007 - 2015";
uschar *version_date = US"?";
uschar *version_cnumber = US"????";
uschar *version_string = US"?";
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Almost all the global variables are defined together in this one header, so
extern uschar *pgsql_servers; /* List of servers and connect info */
#endif
-#ifdef EXPERIMENTAL_REDIS
+#ifdef LOOKUP_REDIS
extern uschar *redis_servers; /* List of servers and connect info */
#endif
extern uschar *gnutls_require_proto; /* So some can be avoided */
extern uschar *openssl_options; /* OpenSSL compatibility options */
extern const pcre *regex_STARTTLS; /* For recognizing STARTTLS settings */
-extern uschar *tls_advertise_hosts; /* host for which TLS is advertised */
extern uschar *tls_certificate; /* Certificate file */
extern uschar *tls_channelbinding_b64; /* string of base64 channel binding */
extern uschar *tls_crl; /* CRL File */
extern int tls_dh_max_bits; /* don't accept higher lib suggestions */
extern uschar *tls_dhparam; /* DH param file */
-#ifndef DISABLE_OCSP
+extern uschar *tls_eccurve; /* EC curve */
+# ifndef DISABLE_OCSP
extern uschar *tls_ocsp_file; /* OCSP stapling proof file */
-#endif
+# endif
extern BOOL tls_offered; /* Server offered TLS */
extern uschar *tls_privatekey; /* Private key file */
extern BOOL tls_remember_esmtp; /* For YAEB */
extern uschar *tls_verify_certificates;/* Path for certificates to check */
extern uschar *tls_verify_hosts; /* Mandatory client verification */
#endif
+extern uschar *tls_advertise_hosts; /* host for which TLS is advertised */
extern uschar *dsn_envid; /* DSN envid string */
extern int dsn_ret; /* DSN ret type*/
the size of this vector set explicitly, because it is referenced from more than
one module. */
-extern uschar **address_expansions[ADDRESS_EXPANSIONS_COUNT];
+extern const uschar **address_expansions[ADDRESS_EXPANSIONS_COUNT];
/* General global variables */
extern uschar *bounce_sender_authentication; /* AUTH address for bounces */
extern int bsmtp_transaction_linecount; /* Start of last transaction */
+extern uschar *callout_address; /* Address used for a malware/spamd/verify etc. callout */
extern int callout_cache_domain_positive_expire; /* Time for positive domain callout cache records to expire */
extern int callout_cache_domain_negative_expire; /* Time for negative domain callout cache records to expire */
extern int callout_cache_positive_expire; /* Time for positive callout cache records to expire */
extern uschar *continue_transport; /* Transport for continued delivery */
extern uschar *csa_status; /* Client SMTP Authorization result */
-extern BOOL cutthrough_delivery; /* Deliver in foreground */
-extern int cutthrough_fd; /* Connection for ditto */
+
+typedef struct {
+ BOOL delivery; /* When to attempt */
+ int fd; /* Open connection */
+ int nrcpt; /* Count of addresses */
+ uschar * interface; /* (address of) */
+ host_item host; /* Host used */
+ address_item addr; /* (Chain of) addresses */
+} cut_t;
+extern cut_t cutthrough; /* Deliver-concurrently */
extern BOOL daemon_listen; /* True if listening required */
extern uschar *daemon_smtp_port; /* Can be a list of ports */
extern BOOL debug_daemon; /* Debug the daemon process only */
extern int debug_fd; /* The fd for debug_file */
extern FILE *debug_file; /* Where to write debugging info */
+extern int debug_notall[]; /* Debug options excluded from +all */
extern bit_table debug_options[]; /* Table of debug options */
extern int debug_options_count; /* Size of table */
extern int delay_warning[]; /* Times between warnings */
extern uschar *deliver_address_data; /* Arbitrary data for an address */
extern int deliver_datafile; /* FD for data part of message */
-extern uschar *deliver_domain; /* The local domain for delivery */
+extern const uschar *deliver_domain; /* The local domain for delivery */
extern uschar *deliver_domain_data; /* From domain lookup */
-extern uschar *deliver_domain_orig; /* The original local domain for delivery */
-extern uschar *deliver_domain_parent; /* The parent domain for delivery */
+extern const uschar *deliver_domain_orig; /* The original local domain for delivery */
+extern const uschar *deliver_domain_parent; /* The parent domain for delivery */
extern BOOL deliver_drop_privilege; /* TRUE for unprivileged delivery */
extern BOOL deliver_firsttime; /* True for first delivery attempt */
extern BOOL deliver_force; /* TRUE if delivery was forced */
extern BOOL deliver_freeze; /* TRUE if delivery is frozen */
extern time_t deliver_frozen_at; /* Time of freezing */
extern uschar *deliver_home; /* Home directory for pipes */
-extern uschar *deliver_host; /* (First) host for routed local deliveries */
+extern const uschar *deliver_host; /* (First) host for routed local deliveries */
/* Remote host for filter */
-extern uschar *deliver_host_address; /* Address for remote delivery filter */
+extern const uschar *deliver_host_address; /* Address for remote delivery filter */
extern int deliver_host_port; /* Address for remote delivery filter */
extern uschar *deliver_in_buffer; /* Buffer for copying file */
extern ino_t deliver_inode; /* Inode for appendfile */
extern BOOL disable_logging; /* Disables log writing when TRUE */
#ifndef DISABLE_DKIM
+extern BOOL dkim_collect_input; /* Runtime flag that tracks wether SMTP input is fed to DKIM validation */
extern uschar *dkim_cur_signer; /* Expansion variable, holds the current "signer" domain or identity during a acl_smtp_dkim run */
+extern BOOL dkim_disable_verify; /* Set via ACL control statement. When set, DKIM verification is disabled for the current message */
+extern int dkim_key_length; /* Expansion variable, length of signing key in bits */
extern uschar *dkim_signers; /* Expansion variable, holds colon-separated list of domains and identities that have signed a message */
extern uschar *dkim_signing_domain; /* Expansion variable, domain used for signing a message. */
extern uschar *dkim_signing_selector; /* Expansion variable, selector used for signing a message. */
extern uschar *dkim_verify_signers; /* Colon-separated list of domains for each of which we call the DKIM ACL */
-extern BOOL dkim_collect_input; /* Runtime flag that tracks wether SMTP input is fed to DKIM validation */
-extern BOOL dkim_disable_verify; /* Set via ACL control statement. When set, DKIM verification is disabled for the current message */
#endif
#ifdef EXPERIMENTAL_DMARC
extern BOOL dmarc_has_been_checked; /* Global variable to check if test has been called yet */
extern int dns_retrans; /* Retransmission time setting */
extern int dns_retry; /* Number of retries */
extern int dns_dnssec_ok; /* When constructing DNS query, set DO flag */
+extern uschar *dns_trust_aa; /* DNSSEC trust AA as AD */
extern int dns_use_edns0; /* Coerce EDNS0 support on/off in resolver. */
extern uschar *dnslist_domain; /* DNS (black) list domain */
extern uschar *dnslist_matched; /* DNS (black) list matched key */
extern uschar *errors_reply_to; /* Reply-to for error messages */
extern int errors_sender_rc; /* Return after message to sender*/
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
extern uschar *event_action; /* expansion for delivery events */
extern uschar *event_data; /* event data */
extern int event_defer_errno; /* error number set when a remote delivery is deferred with a host error */
-extern uschar *event_name; /* event classification */
+extern const uschar *event_name; /* event classification */
#endif
extern gid_t exim_gid; /* To be used with exim_uid */
extern tree_node *localpartlist_anchor;/* Tree of defined localpart lists */
extern int localpartlist_count; /* Number defined */
extern uschar *log_buffer; /* For constructing log entries */
-extern unsigned int log_extra_selector;/* Bit map of logging options other than used by log_write() */
+extern int log_default[]; /* Initialization list for log_selector */
extern uschar *log_file_path; /* If unset, use default */
+extern int log_notall[]; /* Log options excluded from +all */
extern bit_table log_options[]; /* Table of options */
extern int log_options_count; /* Size of table */
extern int log_reject_target; /* Target log for ACL rejections */
+extern unsigned int log_selector[]; /* Bit map of logging options */
extern uschar *log_selector_string; /* As supplied in the config */
extern FILE *log_stderr; /* Copy of stderr for log use, or NULL */
extern BOOL log_testing_mode; /* TRUE in various testing modes */
extern BOOL log_timezone; /* TRUE to include the timezone in log lines */
-extern unsigned int log_write_selector;/* Bit map of logging options for log_write() */
extern uschar *login_sender_address; /* The actual sender address */
extern lookup_info **lookup_list; /* Array of pointers to available lookups */
extern int lookup_list_count; /* Number of entries in the list */
extern BOOL message_logs; /* TRUE to write message logs */
extern int message_size; /* Size of message */
extern uschar *message_size_limit; /* As it says */
+#ifdef SUPPORT_I18N
+extern BOOL message_smtputf8; /* Internationalized mail handling */
+extern int message_utf8_downconvert; /* convert from utf8 */
+const extern pcre *regex_UTF8; /* For recognizing SMTPUTF8 settings */
+#endif
extern uschar message_subdir[]; /* Subdirectory for messages */
extern uschar *message_reference; /* Reference for error messages */
extern uschar *process_log_path; /* Alternate path */
extern BOOL prod_requires_admin; /* TRUE if prodding requires admin */
-#ifdef EXPERIMENTAL_PROXY
-extern uschar *proxy_host_address; /* IP of host being proxied */
-extern int proxy_host_port; /* Port of host being proxied */
-extern uschar *proxy_required_hosts; /* Hostlist which (require) use proxy protocol */
+#if defined(SUPPORT_PROXY) || defined(SUPPORT_SOCKS)
+extern uschar *hosts_proxy; /* Hostlist which (require) use proxy protocol */
+extern uschar *proxy_external_address; /* IP of remote interface of proxy */
+extern int proxy_external_port; /* Port on remote interface of proxy */
+extern uschar *proxy_local_address; /* IP of local interface of proxy */
+extern int proxy_local_port; /* Port on local interface of proxy */
extern BOOL proxy_session; /* TRUE if receiving mail from valid proxy */
extern BOOL proxy_session_failed; /* TRUE if required proxy negotiation failed */
-extern uschar *proxy_target_address; /* IP of proxy server inbound */
-extern int proxy_target_port; /* Port of proxy server inbound */
#endif
extern uschar *prvscheck_address; /* Set during prvscheck expansion item */
extern uschar *prvscheck_keynum; /* Set during prvscheck expansion item */
extern uschar *prvscheck_result; /* Set during prvscheck expansion item */
-extern uschar *qualify_domain_recipient; /* Domain to qualify recipients with */
+extern const uschar *qualify_domain_recipient; /* Domain to qualify recipients with */
extern uschar *qualify_domain_sender; /* Domain to qualify senders with */
extern BOOL queue_2stage; /* Run queue in 2-stage manner */
extern uschar *queue_domains; /* Queue these domains */
extern const pcre *regex_IGNOREQUOTA; /* For recognizing IGNOREQUOTA (LMTP) */
extern const pcre *regex_PIPELINING; /* For recognizing PIPELINING */
extern const pcre *regex_SIZE; /* For recognizing SIZE settings */
-extern const pcre *regex_smtp_code; /* For recognizing SMTP codes */
extern const pcre *regex_ismsgid; /* Compiled r.e. for message it */
+extern const pcre *regex_smtp_code; /* For recognizing SMTP codes */
+extern uschar *regex_vars[]; /* $regexN variables */
#ifdef WHITELIST_D_MACROS
extern const pcre *regex_whitelisted_macro; /* For -D macro values */
#endif
extern uschar *sender_data; /* lookup result for senders */
extern unsigned int sender_domain_cache[(MAX_NAMED_LIST * 2)/32]; /* Cache bits for sender domain */
extern uschar *sender_fullhost; /* Sender host name + address */
+extern BOOL sender_helo_dnssec; /* True if HELO verify used DNS and was DNSSEC */
extern uschar *sender_helo_name; /* Host name from HELO/EHLO */
extern uschar **sender_host_aliases; /* Points to list of alias names */
extern unsigned int sender_host_cache[(MAX_NAMED_LIST * 2)/32]; /* Cache bits for incoming host */
extern int sending_port; /* Port of outgoing interface */
extern SIGNAL_BOOL sigalrm_seen; /* Flag for sigalrm_handler */
extern uschar **sighup_argv; /* Args for re-execing after SIGHUP */
+extern int slow_lookup_log; /* Log DNS lookups taking loger than N millisecs */
extern int smtp_accept_count; /* Count of connections */
extern BOOL smtp_accept_keepalive; /* Set keepalive on incoming */
extern int smtp_accept_max; /* Max SMTP connections */
extern int smtp_rlr_threshold; /* Threshold for RCPT rate limit */
extern BOOL smtp_use_pipelining; /* Global for passed connections */
extern BOOL smtp_use_size; /* Global for passed connections */
+#ifdef SUPPORT_I18N
+extern uschar *smtputf8_advertise_hosts; /* ingress control */
+#endif
#ifdef WITH_CONTENT_SCAN
extern uschar *spamd_address; /* address for the spamassassin daemon */
extern uschar *spam_bar; /* the spam "bar" (textual representation of spam_score) */
extern uschar *spam_report; /* the spamd report (multiline) */
+extern uschar *spam_action; /* the spamd recommended-action */
extern uschar *spam_score; /* the spam score (float) */
extern uschar *spam_score_int; /* spam_score * 10 (int) */
#endif
extern uschar *transport_name; /* Name of transport last started */
extern int transport_count; /* Count of bytes transported */
extern int transport_newlines; /* Accurate count of number of newline chars transported */
-extern uschar **transport_filter_argv; /* For on-the-fly filtering */
+extern const uschar **transport_filter_argv; /* For on-the-fly filtering */
extern int transport_filter_timeout; /* Timeout for same */
extern BOOL transport_filter_timed_out; /* True if it did */
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2012 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Functions for finding hosts, either by gethostbyname(), gethostbyaddr(), or
return (unsigned int)(random_seed >> 16) % limit;
}
+/*************************************************
+* Wrappers for logging lookup times *
+*************************************************/
+
+/* When the 'slow_lookup_log' variable is enabled, these wrappers will
+write to the log file all (potential) dns lookups that take more than
+slow_lookup_log milliseconds
+*/
+
+static void
+log_long_lookup(const uschar * type, const uschar * data, unsigned long msec)
+{
+log_write(0, LOG_MAIN, "Long %s lookup for '%s': %lu msec",
+ type, data, msec);
+}
+
+
+/* returns the current system epoch time in milliseconds. */
+static unsigned long
+get_time_in_ms()
+{
+struct timeval tmp_time;
+unsigned long seconds, microseconds;
+
+gettimeofday(&tmp_time, NULL);
+seconds = (unsigned long) tmp_time.tv_sec;
+microseconds = (unsigned long) tmp_time.tv_usec;
+return seconds*1000 + microseconds/1000;
+}
+
+
+static int
+dns_lookup_timerwrap(dns_answer *dnsa, const uschar *name, int type,
+ const uschar **fully_qualified_name)
+{
+int retval;
+unsigned long time_msec;
+
+if (!slow_lookup_log)
+ return dns_lookup(dnsa, name, type, fully_qualified_name);
+
+time_msec = get_time_in_ms();
+retval = dns_lookup(dnsa, name, type, fully_qualified_name);
+if ((time_msec = get_time_in_ms() - time_msec) > slow_lookup_log)
+ log_long_lookup(US"name", name, time_msec);
+return retval;
+}
/*************************************************
*************************************************/
/* This function is called instead of gethostbyname(), gethostbyname2(), or
-getipnodebyname() when running in the test harness. It recognizes the name
-"manyhome.test.ex" and generates a humungous number of IP addresses. It also
+getipnodebyname() when running in the test harness. . It also
recognizes an unqualified "localhost" and forces it to the appropriate loopback
address. IP addresses are treated as literals. For other names, it uses the DNS
to find the host name. In the test harness, this means it will access only the
*/
static struct hostent *
-host_fake_gethostbyname(uschar *name, int af, int *error_num)
+host_fake_gethostbyname(const uschar *name, int af, int *error_num)
{
#if HAVE_IPV6
int alen = (af == AF_INET)? sizeof(struct in_addr):sizeof(struct in6_addr);
#endif
int ipa;
-uschar *lname = name;
+const uschar *lname = name;
uschar *adds;
uschar **alist;
struct hostent *yield;
debug_printf("using host_fake_gethostbyname for %s (%s)\n", name,
(af == AF_INET)? "IPv4" : "IPv6");
-/* Handle the name that needs a vast number of IP addresses */
-
-if (Ustrcmp(name, "manyhome.test.ex") == 0 && af == AF_INET)
- {
- int i, j;
- yield = store_get(sizeof(struct hostent));
- alist = store_get(2049 * sizeof(char *));
- adds = store_get(2048 * alen);
- yield->h_name = CS name;
- yield->h_aliases = NULL;
- yield->h_addrtype = af;
- yield->h_length = alen;
- yield->h_addr_list = CSS alist;
- for (i = 104; i <= 111; i++)
- {
- for (j = 0; j <= 255; j++)
- {
- *alist++ = adds;
- *adds++ = 10;
- *adds++ = 250;
- *adds++ = i;
- *adds++ = j;
- }
- }
- *alist = NULL;
- return yield;
- }
-
/* Handle unqualified "localhost" */
if (Ustrcmp(name, "localhost") == 0)
else
{
int type = (af == AF_INET)? T_A:T_AAAA;
- int rc = dns_lookup(&dnsa, lname, type, NULL);
+ int rc = dns_lookup_timerwrap(&dnsa, lname, type, NULL);
int count = 0;
lookup_dnssec_authenticated = NULL;
}
for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
- rr != NULL;
+ rr;
rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
- {
- if (rr->type == type) count++;
- }
+ if (rr->type == type)
+ count++;
yield = store_get(sizeof(struct hostent));
alist = store_get((count + 1) * sizeof(char **));
yield->h_addr_list = CSS alist;
for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
- rr != NULL;
+ rr;
rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
{
int i, n;
int x[4];
dns_address *da;
if (rr->type != type) continue;
- da = dns_address_from_rr(&dnsa, rr);
+ if (!(da = dns_address_from_rr(&dnsa, rr))) break;
*alist++ = adds;
n = host_aton(da->address, x);
for (i = 0; i < n; i++)
*/
void
-host_build_hostlist(host_item **anchor, uschar *list, BOOL randomize)
+host_build_hostlist(host_item **anchor, const uschar *list, BOOL randomize)
{
int sep = 0;
int fake_mx = MX_NONE; /* This value is actually -1 */
uschar *name;
-uschar buffer[1024];
if (list == NULL) return;
if (randomize) fake_mx--; /* Start at -2 for randomizing */
*anchor = NULL;
-while ((name = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
+while ((name = string_nextinlist(&list, &sep, NULL, 0)) != NULL)
{
host_item *h;
}
h = store_get(sizeof(host_item));
- h->name = string_copy(name);
+ h->name = name;
h->address = NULL;
h->port = PORT_NONE;
h->mx = fake_mx;
int
host_item_get_port(host_item *h)
{
-uschar *p;
+const uschar *p;
int port, x;
int len = Ustrlen(h->name);
domain. Sigh. */
address = string_sprintf("[%s]:%d", sender_host_address, sender_host_port);
-if ((log_extra_selector & LX_incoming_port) == 0 || sender_host_port <= 0)
+if (!LOGGING(incoming_port) || sender_host_port <= 0)
*(Ustrrchr(address, ':')) = 0;
/* If there's no EHLO/HELO data, we can't show it. */
{
uschar *flag = useflag? US"H=" : US"";
uschar *iface = US"";
- if ((log_extra_selector & LX_incoming_interface) != 0 &&
- interface_address != NULL)
+ if (LOGGING(incoming_interface) && interface_address != NULL)
iface = string_sprintf(" I=[%s]:%d", interface_address, interface_port);
if (sender_ident == NULL)
(void)string_format(big_buffer, big_buffer_size, "%s%s%s",
*/
ip_address_item *
-host_build_ifacelist(uschar *list, uschar *name)
+host_build_ifacelist(const uschar *list, uschar *name)
{
int sep = 0;
uschar *s;
if (local_interface_data == NULL)
{
void *reset_item = store_get(0);
- ip_address_item *dlist = host_build_ifacelist(local_interfaces,
+ ip_address_item *dlist = host_build_ifacelist(CUS local_interfaces,
US"local_interfaces");
- ip_address_item *xlist = host_build_ifacelist(extra_local_interfaces,
+ ip_address_item *xlist = host_build_ifacelist(CUS extra_local_interfaces,
US"extra_local_interfaces");
ip_address_item *ipa;
*/
int
-host_aton(uschar *address, int *bin)
+host_aton(const uschar *address, int *bin)
{
int x[4];
int v4offset = 0;
if (Ustrchr(address, ':') != NULL)
{
- uschar *p = address;
- uschar *component[8];
+ const uschar *p = address;
+ const uschar *component[8];
BOOL ipv4_ends = FALSE;
int ci = 0;
int nulloffset = 0;
{
j = binary[0];
for (i = 24; i >= 0; i -= 8)
- {
- sprintf(CS tt, "%d.", (j >> i) & 255);
- while (*tt) tt++;
- }
+ tt += sprintf(CS tt, "%d.", (j >> i) & 255);
}
else
- {
for (i = 0; i < 4; i++)
{
j = binary[i];
- sprintf(CS tt, "%04x%c%04x%c", (j >> 16) & 0xffff, sep, j & 0xffff, sep);
- while (*tt) tt++;
+ tt += sprintf(CS tt, "%04x%c%04x%c", (j >> 16) & 0xffff, sep, j & 0xffff, sep);
}
- }
tt--; /* lose final separator */
}
+/* Like host_nmtoa() but: ipv6-only, canonical output, no mask
+
+Arguments:
+ binary points to the ints
+ buffer big enough to hold the result
+
+Returns: the number of characters placed in buffer, not counting
+ the final nul.
+*/
+
+int
+ipv6_nmtoa(int * binary, uschar * buffer)
+{
+int i, j, k;
+uschar * c = buffer;
+uschar * d = NULL; /* shut insufficiently "clever" compiler up */
+
+for (i = 0; i < 4; i++)
+ { /* expand to text */
+ j = binary[i];
+ c += sprintf(CS c, "%x:%x:", (j >> 16) & 0xffff, j & 0xffff);
+ }
+
+for (c = buffer, k = -1, i = 0; i < 8; i++)
+ { /* find longest 0-group sequence */
+ if (*c == '0') /* must be "0:" */
+ {
+ uschar * s = c;
+ j = i;
+ while (c[2] == '0') i++, c += 2;
+ if (i-j > k)
+ {
+ k = i-j; /* length of sequence */
+ d = s; /* start of sequence */
+ }
+ }
+ while (*++c != ':') ;
+ c++;
+ }
+
+c[-1] = '\0'; /* drop trailing colon */
+
+/* debug_printf("%s: D k %d <%s> <%s>\n", __FUNCTION__, k, d, d + 2*(k+1)); */
+if (k >= 0)
+ { /* collapse */
+ c = d + 2*(k+1);
+ if (d == buffer) c--; /* need extra colon */
+ *d++ = ':'; /* 1st 0 */
+ while ((*d++ = *c++)) ;
+ }
+else
+ d = c;
+
+return d - buffer;
+}
+
+
/*************************************************
* Check port for tls_on_connect *
{
int sep = 0;
uschar buffer[32];
-uschar *list = tls_in.on_connect_ports;
+const uschar *list = tls_in.on_connect_ports;
uschar *s;
uschar *end;
*/
BOOL
-host_is_in_net(uschar *host, uschar *net, int maskoffset)
+host_is_in_net(const uschar *host, const uschar *net, int maskoffset)
{
int i;
int address[4];
if (hosts_treat_as_local != NULL)
{
int rc;
- uschar *save = deliver_domain;
+ const uschar *save = deliver_domain;
deliver_domain = h->name; /* set $domain */
- rc = match_isinlist(string_copylc(h->name), &hosts_treat_as_local, 0,
+ rc = match_isinlist(string_copylc(h->name), CUSS &hosts_treat_as_local, 0,
&domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL);
deliver_domain = save;
if (rc == OK) goto FOUND_LOCAL;
uschar *s, *t;
struct hostent *hosts;
struct in_addr addr;
+unsigned long time_msec;
+
+if (slow_lookup_log) time_msec = get_time_in_ms();
/* Lookup on IPv6 system */
hosts = gethostbyaddr(CS(&addr), sizeof(addr), AF_INET);
#endif
+if ( slow_lookup_log
+ && (time_msec = get_time_in_ms() - time_msec) > slow_lookup_log
+ )
+ log_long_lookup(US"name", sender_host_address, time_msec);
+
/* Failed to look up the host. */
if (hosts == NULL)
uschar **aliases;
uschar buffer[256];
uschar *ordername;
-uschar *list = host_lookup_order;
+const uschar *list = host_lookup_order;
dns_record *rr;
dns_answer dnsa;
dns_scan dnss;
/* Do lookups directly in the DNS or via gethostbyaddr() (or equivalent), in
the order specified by the host_lookup_order option. */
-while ((ordername = string_nextinlist(&list, &sep, buffer, sizeof(buffer)))
- != NULL)
+while ((ordername = string_nextinlist(&list, &sep, buffer, sizeof(buffer))))
{
if (strcmpic(ordername, US"bydns") == 0)
{
dns_init(FALSE, FALSE, FALSE); /* dnssec ctrl by dns_dnssec_ok glbl */
dns_build_reverse(sender_host_address, buffer);
- rc = dns_lookup(&dnsa, buffer, T_PTR, NULL);
+ rc = dns_lookup_timerwrap(&dnsa, buffer, T_PTR, NULL);
/* The first record we come across is used for the name; others are
considered to be aliases. We have to scan twice, in order to find out the
int count = 0;
int old_pool = store_pool;
- /* Ideally we'd check DNSSEC both forward and reverse, but we use the
- gethost* routines for forward, so can't do that unless/until we rewrite. */
sender_host_dnssec = dns_is_secure(&dnsa);
DEBUG(D_dns)
debug_printf("Reverse DNS security status: %s\n",
store_pool = POOL_PERM; /* Save names in permanent storage */
for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
- rr != NULL;
+ rr;
rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
- {
- if (rr->type == T_PTR) count++;
- }
+ if (rr->type == T_PTR)
+ count++;
/* Get store for the list of aliases. For compatibility with
gethostbyaddr, we make an empty list if there are none. */
/* Re-scan and extract the names */
for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
- rr != NULL;
+ rr;
rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
{
uschar *s = NULL;
"empty name: treated as non-existent host name\n");
continue;
}
- if (sender_host_name == NULL) sender_host_name = s;
- else *aptr++ = s;
+ if (!sender_host_name) sender_host_name = s;
+ else *aptr++ = s;
while (*s != 0) { *s = tolower(*s); s++; }
}
int rc;
BOOL ok = FALSE;
host_item h;
+ dnssec_domains d;
+
h.next = NULL;
h.name = hname;
h.mx = MX_NONE;
h.address = NULL;
+ d.request = sender_host_dnssec ? US"*" : NULL;;
+ d.require = NULL;
- /* When called with the last argument FALSE, host_find_byname() won't return
- HOST_FOUND_LOCAL. If the incoming address is an IPv4 address expressed in
- IPv6 format, we must compare the IPv4 part to any IPv4 addresses. */
-
- if ((rc = host_find_byname(&h, NULL, 0, NULL, FALSE)) == HOST_FOUND)
+ if ( (rc = host_find_bydns(&h, NULL, HOST_FIND_BY_A,
+ NULL, NULL, NULL, &d, NULL, NULL)) == HOST_FOUND
+ || rc == HOST_FOUND_LOCAL
+ )
{
host_item *hh;
HDEBUG(D_host_lookup) debug_printf("checking addresses for %s\n", hname);
+
+ /* If the forward lookup was not secure we cancel the is-secure variable */
+
+ DEBUG(D_dns) debug_printf("Forward DNS security status: %s\n",
+ h.dnssec == DS_YES ? "DNSSEC verified (AD)" : "unverified");
+ if (h.dnssec != DS_YES) sender_host_dnssec = FALSE;
+
for (hh = &h; hh != NULL; hh = hh->next)
- {
if (host_is_in_net(hh->address, sender_host_address, 0))
{
HDEBUG(D_host_lookup) debug_printf(" %s OK\n", hh->address);
break;
}
else
- {
HDEBUG(D_host_lookup) debug_printf(" %s\n", hh->address);
- }
- }
+
if (!ok) HDEBUG(D_host_lookup)
debug_printf("no IP address for %s matched %s\n", hname,
sender_host_address);
return DEFER;
}
else
- {
HDEBUG(D_host_lookup) debug_printf("no IP addresses found for %s\n", hname);
- }
/* If this name is no good, and it's the sender name, set it null pro tem;
if it's an alias, just remove it from the list. */
*/
int
-host_find_byname(host_item *host, uschar *ignore_target_hosts, int flags,
- uschar **fully_qualified_name, BOOL local_host_check)
+host_find_byname(host_item *host, const uschar *ignore_target_hosts, int flags,
+ const uschar **fully_qualified_name, BOOL local_host_check)
{
int i, yield, times;
uschar **addrlist;
int af;
#endif
-/* If we are in the test harness, a name ending in .test.again.dns always
-forces a temporary error response, unless the name is in
-dns_again_means_nonexist. */
-
-if (running_in_test_harness)
- {
- uschar *endname = host->name + Ustrlen(host->name);
- if (Ustrcmp(endname - 14, "test.again.dns") == 0) goto RETURN_AGAIN;
- }
-
/* Make sure DNS options are set as required. This appears to be necessary in
some circumstances when the get..byname() function actually calls the DNS. */
dns_init((flags & HOST_FIND_QUALIFY_SINGLE) != 0,
(flags & HOST_FIND_SEARCH_PARENTS) != 0,
- FALSE); /*XXX dnssec? */
+ FALSE); /* Cannot retrieve dnssec status so do not request */
/* In an IPv6 world, unless IPv6 has been disabled, we need to scan for both
kinds of address, so go round the loop twice. Note that we have ensured that
#else
if (disable_ipv6 ||
(dns_ipv4_lookup != NULL &&
- match_isinlist(host->name, &dns_ipv4_lookup, 0, NULL, NULL, MCL_DOMAIN,
- TRUE, NULL) == OK))
+ match_isinlist(host->name, CUSS &dns_ipv4_lookup, 0, NULL, NULL,
+ MCL_DOMAIN, TRUE, NULL) == OK))
#endif
{ af = AF_INET; times = 1; }
BOOL ipv4_addr;
int error_num = 0;
struct hostent *hostdata;
+ unsigned long time_msec = 0; /* compiler quietening */
#ifdef STAND_ALONE
printf("Looking up: %s\n", host->name);
#endif
+ if (slow_lookup_log) time_msec = get_time_in_ms();
+
#if HAVE_IPV6
if (running_in_test_harness)
hostdata = host_fake_gethostbyname(host->name, af, &error_num);
}
#endif /* HAVE_IPV6 */
+ if ( slow_lookup_log
+ && (time_msec = get_time_in_ms() - time_msec) > slow_lookup_log)
+ log_long_lookup(US"name", host->name, time_msec);
+
if (hostdata == NULL)
{
uschar *error;
switch (error_num)
{
case HOST_NOT_FOUND: error = US"HOST_NOT_FOUND"; break;
- case TRY_AGAIN: error = US"TRY_AGAIN"; break;
- case NO_RECOVERY: error = US"NO_RECOVERY"; break;
- case NO_DATA: error = US"NO_DATA"; break;
+ case TRY_AGAIN: error = US"TRY_AGAIN"; break;
+ case NO_RECOVERY: error = US"NO_RECOVERY"; break;
+ case NO_DATA: error = US"NO_DATA"; break;
#if NO_DATA != NO_ADDRESS
- case NO_ADDRESS: error = US"NO_ADDRESS"; break;
+ case NO_ADDRESS: error = US"NO_ADDRESS"; break;
#endif
default: error = US"?"; break;
}
HDEBUG(D_host_lookup)
{
- host_item *h;
+ const host_item *h;
if (fully_qualified_name != NULL)
debug_printf("fully qualified name = %s\n", *fully_qualified_name);
debug_printf("%s looked up these IP addresses:\n",
{
#ifndef STAND_ALONE
int rc;
- uschar *save = deliver_domain;
+ const uschar *save = deliver_domain;
deliver_domain = host->name; /* set $domain */
- rc = match_isinlist(host->name, &dns_again_means_nonexist, 0, NULL, NULL,
+ rc = match_isinlist(host->name, CUSS &dns_again_means_nonexist, 0, NULL, NULL,
MCL_DOMAIN, TRUE, NULL);
deliver_domain = save;
if (rc == OK)
fully_qualified_name if not NULL, return fully qualified name here if
the contents are different (i.e. it must be preset
to something)
- dnnssec_require if TRUE check the DNS result AD bit
+ dnssec_request if TRUE request the AD bit
+ dnssec_require if TRUE require the AD bit
Returns: HOST_FIND_FAILED couldn't find A record
HOST_FIND_AGAIN try again later
static int
set_address_from_dns(host_item *host, host_item **lastptr,
- uschar *ignore_target_hosts, BOOL allow_ip, uschar **fully_qualified_name,
+ const uschar *ignore_target_hosts, BOOL allow_ip,
+ const uschar **fully_qualified_name,
BOOL dnssec_request, BOOL dnssec_require)
{
dns_record *rr;
return HOST_FOUND;
}
-/* On an IPv6 system, unless IPv6 is disabled, go round the loop up to three
-times, looking for A6 and AAAA records the first two times. However, unless
+/* On an IPv6 system, unless IPv6 is disabled, go round the loop up to twice,
+looking for AAAA records the first time. However, unless
doing standalone testing, we force an IPv4 lookup if the domain matches
-dns_ipv4_lookup is set. Since A6 records look like being abandoned, support
-them only if explicitly configured to do so. On an IPv4 system, go round the
+dns_ipv4_lookup is set. On an IPv4 system, go round the
loop once only, looking only for A records. */
#if HAVE_IPV6
#ifndef STAND_ALONE
if (disable_ipv6 || (dns_ipv4_lookup != NULL &&
- match_isinlist(host->name, &dns_ipv4_lookup, 0, NULL, NULL, MCL_DOMAIN,
- TRUE, NULL) == OK))
+ match_isinlist(host->name, CUSS &dns_ipv4_lookup, 0, NULL, NULL,
+ MCL_DOMAIN, TRUE, NULL) == OK))
i = 0; /* look up A records only */
else
#endif /* STAND_ALONE */
- #ifdef SUPPORT_A6
- i = 2; /* look up A6 and AAAA and A records */
- #else
i = 1; /* look up AAAA and A records */
- #endif /* SUPPORT_A6 */
/* The IPv4 world */
for (; i >= 0; i--)
{
- static int types[] = { T_A, T_AAAA, T_A6 };
+ static int types[] = { T_A, T_AAAA };
int type = types[i];
int randoffset = (i == 0)? 500 : 0; /* Ensures v6 sorts before v4 */
dns_answer dnsa;
dns_scan dnss;
- int rc = dns_lookup(&dnsa, host->name, type, fully_qualified_name);
+ int rc = dns_lookup_timerwrap(&dnsa, host->name, type, fully_qualified_name);
lookup_dnssec_authenticated = !dnssec_request ? NULL
: dns_is_secure(&dnsa) ? US"yes" : US"no";
- /* We want to return HOST_FIND_AGAIN if one of the A, A6, or AAAA lookups
+ DEBUG(D_dns)
+ if ( (dnssec_request || dnssec_require)
+ && !dns_is_secure(&dnsa)
+ && dns_is_aa(&dnsa)
+ )
+ debug_printf("DNS lookup of %.256s (A/AAAA) requested AD, but got AA\n", host->name);
+
+ /* We want to return HOST_FIND_AGAIN if one of the A or AAAA lookups
fails or times out, but not if another one succeeds. (In the early
IPv6 days there are name servers that always fail on AAAA, but are happy
to give out an A record. We want to proceed with that A record.) */
{
if (i == 0) /* Just tried for an A record, i.e. end of loop */
{
- if (host->address != NULL) return HOST_FOUND; /* A6 or AAAA was found */
+ if (host->address != NULL) return HOST_FOUND; /* AAAA was found */
if (rc == DNS_AGAIN || rc == DNS_FAIL || v6_find_again)
return HOST_FIND_AGAIN;
return HOST_FIND_FAILED; /* DNS_NOMATCH or DNS_NODATA */
}
- /* Tried for an A6 or AAAA record: remember if this was a temporary
+ /* Tried for an AAAA record: remember if this was a temporary
error, and look for the next record type. */
if (rc != DNS_NOMATCH && rc != DNS_NODATA) v6_find_again = TRUE;
{
log_write(L_host_lookup_failed, LOG_MAIN,
"dnssec fail on %s for %.256s",
- i>1 ? "A6" : i>0 ? "AAAA" : "A", host->name);
+ i>0 ? "AAAA" : "A", host->name);
continue;
}
if (host->dnssec == DS_YES) /* set in host_find_bydns() */
/* Lookup succeeded: fill in the given host item with the first non-ignored
address found; create additional items for any others. A single A6 record
- may generate more than one address. */
+ may generate more than one address. The lookup had a chance to update the
+ fqdn; we do not want any later times round the loop to do so. */
+
+ fully_qualified_name = NULL;
for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
- rr != NULL;
+ rr;
rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
{
if (rr->type == type)
{
- /* dns_address *da = dns_address_from_rr(&dnsa, rr); */
-
- dns_address *da;
- da = dns_address_from_rr(&dnsa, rr);
+ dns_address *da = dns_address_from_rr(&dnsa, rr);
DEBUG(D_host_lookup)
- {
- if (da == NULL)
- debug_printf("no addresses extracted from A6 RR for %s\n",
+ if (!da) debug_printf("no addresses extracted from A6 RR for %s\n",
host->name);
- }
/* This loop runs only once for A and AAAA records, but may run
several times for an A6 record that generated multiple addresses. */
- for (; da != NULL; da = da->next)
+ for (; da; da = da->next)
{
#ifndef STAND_ALONE
if (ignore_target_hosts != NULL &&
}
}
-/* Control gets here only if the third lookup (the A record) succeeded.
+/* Control gets here only if the econdookup (the A record) succeeded.
However, the address may not be filled in if it was ignored. */
-return (host->address == NULL)? HOST_IGNORED : HOST_FOUND;
+return host->address ? HOST_FOUND : HOST_IGNORED;
}
srv_service when SRV used, the service name
srv_fail_domains DNS errors for these domains => assume nonexist
mx_fail_domains DNS errors for these domains => assume nonexist
- dnssec_request_domains => make dnssec request
- dnssec_require_domains => ditto and nonexist failures
+ dnssec_d.request => make dnssec request: domainlist
+ dnssec_d.require => ditto and nonexist failures
fully_qualified_name if not NULL, return fully-qualified name
removed set TRUE if local host was removed from the list
*/
int
-host_find_bydns(host_item *host, uschar *ignore_target_hosts, int whichrrs,
+host_find_bydns(host_item *host, const uschar *ignore_target_hosts, int whichrrs,
uschar *srv_service, uschar *srv_fail_domains, uschar *mx_fail_domains,
- uschar *dnssec_request_domains, uschar *dnssec_require_domains,
- uschar **fully_qualified_name, BOOL *removed)
+ const dnssec_domains *dnssec_d,
+ const uschar **fully_qualified_name, BOOL *removed)
{
host_item *h, *last;
dns_record *rr;
int yield;
dns_answer dnsa;
dns_scan dnss;
-BOOL dnssec_require = match_isinlist(host->name, &dnssec_require_domains,
+BOOL dnssec_require = dnssec_d
+ && match_isinlist(host->name, CUSS &dnssec_d->require,
0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) == OK;
BOOL dnssec_request = dnssec_require
- || match_isinlist(host->name, &dnssec_request_domains,
- 0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) == OK;
+ || ( dnssec_d
+ && match_isinlist(host->name, CUSS &dnssec_d->request,
+ 0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) == OK);
dnssec_status_t dnssec;
/* Set the default fully qualified name to the incoming name, initialize the
if (fully_qualified_name != NULL) *fully_qualified_name = host->name;
dns_init((whichrrs & HOST_FIND_QUALIFY_SINGLE) != 0,
(whichrrs & HOST_FIND_SEARCH_PARENTS) != 0,
- dnssec_request
- );
+ dnssec_request);
host_find_failed_syntax = FALSE;
/* First, if requested, look for SRV records. The service name is given; we
-assume TCP progocol. DNS domain names are constrained to a maximum of 256
+assume TCP protocol. DNS domain names are constrained to a maximum of 256
characters, so the code below should be safe. */
if ((whichrrs & HOST_FIND_BY_SRV) != 0)
dnssec = DS_UNK;
lookup_dnssec_authenticated = NULL;
- rc = dns_lookup(&dnsa, buffer, ind_type, &temp_fully_qualified_name);
+ rc = dns_lookup_timerwrap(&dnsa, buffer, ind_type, CUSS &temp_fully_qualified_name);
+
+ DEBUG(D_dns)
+ if ((dnssec_request || dnssec_require)
+ & !dns_is_secure(&dnsa)
+ & dns_is_aa(&dnsa))
+ debug_printf("DNS lookup of %.256s (SRV) requested AD, but got AA\n", host->name);
if (dnssec_request)
{
if (rc == DNS_FAIL || rc == DNS_AGAIN)
{
#ifndef STAND_ALONE
- if (match_isinlist(host->name, &srv_fail_domains, 0, NULL, NULL, MCL_DOMAIN,
- TRUE, NULL) != OK)
+ if (match_isinlist(host->name, CUSS &srv_fail_domains, 0, NULL, NULL,
+ MCL_DOMAIN, TRUE, NULL) != OK)
#endif
{ yield = HOST_FIND_AGAIN; goto out; }
DEBUG(D_host_lookup) debug_printf("DNS_%s treated as DNS_NODATA "
ind_type = T_MX;
dnssec = DS_UNK;
lookup_dnssec_authenticated = NULL;
- rc = dns_lookup(&dnsa, host->name, ind_type, fully_qualified_name);
+ rc = dns_lookup_timerwrap(&dnsa, host->name, ind_type, fully_qualified_name);
+
+ DEBUG(D_dns)
+ if ((dnssec_request || dnssec_require)
+ & !dns_is_secure(&dnsa)
+ & dns_is_aa(&dnsa))
+ debug_printf("DNS lookup of %.256s (MX) requested AD, but got AA\n", host->name);
if (dnssec_request)
{
if (dns_is_secure(&dnsa))
- {
+ {
DEBUG(D_host_lookup) debug_printf("%s MX DNSSEC\n", host->name);
dnssec = DS_YES; lookup_dnssec_authenticated = US"yes";
}
case DNS_FAIL:
case DNS_AGAIN:
#ifndef STAND_ALONE
- if (match_isinlist(host->name, &mx_fail_domains, 0, NULL, NULL, MCL_DOMAIN,
- TRUE, NULL) != OK)
+ if (match_isinlist(host->name, CUSS &mx_fail_domains, 0, NULL, NULL,
+ MCL_DOMAIN, TRUE, NULL) != OK)
#endif
{ yield = HOST_FIND_AGAIN; goto out; }
DEBUG(D_host_lookup) debug_printf("DNS_%s treated as DNS_NODATA "
return yield;
}
-
-
-
/*************************************************
**************************************************
* Stand-alone test program *
else
{
int flags = whichrrs;
+ dnssec_domains d;
h.name = buffer;
h.next = NULL;
if (qualify_single) flags |= HOST_FIND_QUALIFY_SINGLE;
if (search_parents) flags |= HOST_FIND_SEARCH_PARENTS;
+ d.request = request_dnssec ? &h.name : NULL;
+ d.require = require_dnssec ? &h.name : NULL;
+
rc = byname
? host_find_byname(&h, NULL, flags, &fully_qualified_name, TRUE)
: host_find_bydns(&h, NULL, flags, US"smtp", NULL, NULL,
- request_dnssec ? &h.name : NULL,
- require_dnssec ? &h.name : NULL,
- &fully_qualified_name, NULL);
+ &d, &fully_qualified_name, NULL);
if (rc == HOST_FIND_FAILED) printf("Failed\n");
else if (rc == HOST_FIND_AGAIN) printf("Again\n");
--- /dev/null
+#include "exim.h"
+
+#ifdef SUPPORT_I18N
+
+uschar *
+imap_utf7_encode(uschar *string, const uschar *charset, uschar sep,
+ uschar *specials, uschar **error)
+{
+static uschar encode_base64[64] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";
+int ptr = 0;
+int size = 0;
+size_t slen;
+uschar *sptr, *yield = NULL;
+int i = 0, j; /* compiler quietening */
+uschar c = 0; /* compiler quietening */
+BOOL base64mode = FALSE;
+BOOL lastsep = FALSE;
+uschar utf16buf[256];
+uschar *utf16ptr;
+uschar *s;
+uschar outbuf[256];
+uschar *outptr = outbuf;
+#if HAVE_ICONV
+iconv_t icd;
+#endif
+
+if (!specials) specials = US"";
+
+/* Pass over the string. If it consists entirely of "normal" characters
+ (possibly with leading seps), return it as is. */
+for (s = string; *s; s++)
+ {
+ if (s == string && *s == sep)
+ string++;
+ if ( *s >= 0x7f
+ || *s < 0x20
+ || strchr("./&", *s)
+ || *s == sep
+ || Ustrchr(specials, *s)
+ )
+ break;
+ }
+
+if (!*s)
+ return string;
+
+sptr = string;
+slen = Ustrlen(string);
+
+#if HAVE_ICONV
+if ((icd = iconv_open("UTF-16BE", CCS charset)) == (iconv_t)-1)
+ {
+ *error = string_sprintf(
+ "imapfolder: iconv_open(\"UTF-16BE\", \"%s\") failed: %s%s",
+ charset, strerror(errno),
+ errno == EINVAL ? " (maybe unsupported conversion)" : "");
+ return NULL;
+ }
+#endif
+
+while (slen > 0)
+ {
+#if HAVE_ICONV
+ size_t left = sizeof(utf16buf);
+ utf16ptr = utf16buf;
+
+ if ( iconv(icd, (ICONV_ARG2_TYPE)&sptr, &slen, CSS &utf16ptr, &left)
+ == (size_t)-1
+ && errno != E2BIG
+ )
+ {
+ *error = string_sprintf("imapfolder: iconv() failed to convert from %s: %s",
+ charset, strerror(errno));
+ iconv_close(icd);
+ return NULL;
+ }
+#else
+ for (utf16ptr = utf16buf;
+ slen > 0 && (utf16ptr - utf16buf) < sizeof(utf16buf);
+ utf16ptr += 2, slen--, sptr++)
+ {
+ *utf16ptr = *sptr;
+ *(utf16ptr+1) = '\0';
+ }
+#endif
+
+ s = utf16buf;
+ while (s < utf16ptr)
+ {
+ /* Now encode utf16buf as modified UTF-7 */
+ if ( s[0] != 0
+ || s[1] >= 0x7f
+ || s[1] < 0x20
+ || (Ustrchr(specials, s[1]) && s[1] != sep)
+ )
+ {
+ lastsep = FALSE;
+ /* Encode as modified BASE64 */
+ if (!base64mode)
+ {
+ *outptr++ = '&';
+ base64mode = TRUE;
+ i = 0;
+ }
+
+ for (j = 0; j < 2; j++, s++) switch (i++)
+ {
+ case 0:
+ /* Top 6 bits of the first octet */
+ *outptr++ = encode_base64[(*s >> 2) & 0x3F];
+ c = (*s & 0x03); break;
+ case 1:
+ /* Bottom 2 bits of the first octet, and top 4 bits of the second */
+ *outptr++ = encode_base64[(c << 4) | ((*s >> 4) & 0x0F)];
+ c = (*s & 0x0F); break;
+ case 2:
+ /* Bottom 4 bits of the second octet and top 2 bits of the third */
+ *outptr++ = encode_base64[(c << 2) | ((*s >> 6) & 0x03)];
+ /* Bottom 6 bits of the third octet */
+ *outptr++ = encode_base64[*s & 0x3F];
+ i = 0;
+ }
+ }
+
+ else if ( (s[1] != '.' && s[1] != '/')
+ || s[1] == sep
+ )
+ {
+ /* Encode as self (almost) */
+ if (base64mode)
+ {
+ switch (i)
+ {
+ case 1:
+ /* Remaining bottom 2 bits of the last octet */
+ *outptr++ = encode_base64[c << 4];
+ break;
+ case 2:
+ /* Remaining bottom 4 bits of the last octet */
+ *outptr++ = encode_base64[c << 2];
+ }
+ *outptr++ = '-';
+ base64mode = FALSE;
+ }
+
+ if (*++s == sep)
+ {
+ if (!lastsep)
+ {
+ *outptr++ = '.';
+ lastsep = TRUE;
+ }
+ }
+ else
+ {
+ *outptr++ = *s;
+ if (*s == '&')
+ *outptr++ = '-';
+ lastsep = FALSE;
+ }
+
+ s++;
+ }
+ else
+ {
+ *error = string_sprintf("imapfolder: illegal character '%c'", s[1]);
+ if (yield) store_reset(yield);
+ return NULL;
+ }
+
+ if (outptr > outbuf + sizeof(outbuf) - 3)
+ {
+ yield = string_cat(yield, &size, &ptr, outbuf, outptr - outbuf);
+ outptr = outbuf;
+ }
+
+ }
+ } /* End of input string */
+
+if (base64mode)
+ {
+ switch (i)
+ {
+ case 1:
+ /* Remaining bottom 2 bits of the last octet */
+ *outptr++ = encode_base64[c << 4];
+ break;
+ case 2:
+ /* Remaining bottom 4 bits of the last octet */
+ *outptr++ = encode_base64[c << 2];
+ }
+ *outptr++ = '-';
+ }
+
+#if HAVE_ICONV
+iconv_close(icd);
+#endif
+
+yield = string_cat(yield, &size, &ptr, outbuf, outptr - outbuf);
+if (yield[ptr-1] == '.')
+ ptr--;
+yield[ptr] = '\0';
+
+return yield;
+}
+
+#endif /* whole file */
+/* vi: aw ai sw=2
+*/
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Functions for doing things with sockets. With the advent of IPv6 this has
* Bind socket to interface and port *
*************************************************/
-/* This function binds a socket to a local interface address and port. For a
-wildcard IPv6 bind, the address is ":".
-
-Arguments:
- sock the socket
- af AF_INET or AF_INET6 - the socket type
- address the IP address, in text form
- port the IP port (host order)
-
-Returns: the result of bind()
-*/
-
int
-ip_bind(int sock, int af, uschar *address, int port)
+ip_addr(void * sin_, int af, const uschar * address, int port)
{
-int s_len;
-union sockaddr_46 sin;
-memset(&sin, 0, sizeof(sin));
+union sockaddr_46 * sin = sin_;
+memset(sin, 0, sizeof(*sin));
/* Setup code when using an IPv6 socket. The wildcard address is ":", to
ensure an IPv6 socket is used. */
{
if (address[0] == ':' && address[1] == 0)
{
- sin.v6.sin6_family = AF_INET6;
- sin.v6.sin6_addr = in6addr_any;
+ sin->v6.sin6_family = AF_INET6;
+ sin->v6.sin6_addr = in6addr_any;
}
else
- {
- ip_addrinfo(address, &sin.v6); /* Panic-dies on error */
- }
- sin.v6.sin6_port = htons(port);
- s_len = sizeof(sin.v6);
+ ip_addrinfo(address, &sin->v6); /* Panic-dies on error */
+ sin->v6.sin6_port = htons(port);
+ return sizeof(sin->v6);
}
else
#else /* HAVE_IPv6 */
/* Setup code when using IPv4 socket. The wildcard address is "". */
{
- sin.v4.sin_family = AF_INET;
- sin.v4.sin_port = htons(port);
- s_len = sizeof(sin.v4);
- if (address[0] == 0)
- sin.v4.sin_addr.s_addr = (S_ADDR_TYPE)INADDR_ANY;
- else
- sin.v4.sin_addr.s_addr = (S_ADDR_TYPE)inet_addr(CS address);
+ sin->v4.sin_family = AF_INET;
+ sin->v4.sin_port = htons(port);
+ sin->v4.sin_addr.s_addr = address[0] == 0
+ ? (S_ADDR_TYPE)INADDR_ANY
+ : (S_ADDR_TYPE)inet_addr(CS address);
+ return sizeof(sin->v4);
}
+}
+
-/* Now we can call the bind() function */
+/* This function binds a socket to a local interface address and port. For a
+wildcard IPv6 bind, the address is ":".
+
+Arguments:
+ sock the socket
+ af AF_INET or AF_INET6 - the socket type
+ address the IP address, in text form
+ port the IP port (host order)
+
+Returns: the result of bind()
+*/
+
+int
+ip_bind(int sock, int af, uschar *address, int port)
+{
+union sockaddr_46 sin;
+int s_len = ip_addr(&sin, af, address, port);
return bind(sock, (struct sockaddr *)&sin, s_len);
}
can't think of any other way of doing this. It converts a connection refused
into a timeout if the timeout is set to 999999. */
-if (running_in_test_harness)
+if (running_in_test_harness && save_errno == ECONNREFUSED && timeout == 999999)
{
- if (save_errno == ECONNREFUSED && timeout == 999999)
- {
- rc = -1;
- save_errno = EINTR;
- sigalrm_seen = TRUE;
- }
+ rc = -1;
+ save_errno = EINTR;
+ sigalrm_seen = TRUE;
}
/* Success */
-if (rc >= 0) return 0;
+if (rc >= 0)
+ {
+ callout_address = string_sprintf("[%s]:%d", address, port);
+ return 0;
+ }
/* A failure whose error code is "Interrupted system call" is in fact
an externally applied timeout if the signal handler has been run. */
-errno = (save_errno == EINTR && sigalrm_seen)? ETIMEDOUT : save_errno;
+errno = save_errno == EINTR && sigalrm_seen ? ETIMEDOUT : save_errno;
return -1;
}
else
{
shost.name = string_copy(hostname);
- if (host_find_byname(&shost, NULL, HOST_FIND_QUALIFY_SINGLE, NULL,
- FALSE) != HOST_FOUND)
+ if (host_find_byname(&shost, NULL, HOST_FIND_QUALIFY_SINGLE,
+ NULL, FALSE) != HOST_FOUND)
{
*errstr = string_sprintf("no IP address found for host %s", shost.name);
return -1;
{
if (fd != fd6) close(fd6);
if (fd != fd4) close(fd4);
- if (connhost) {
+ if (connhost)
+ {
h->port = port;
*connhost = *h;
connhost->next = NULL;
}
+int
+ip_tcpsocket(const uschar * hostport, uschar ** errstr, int tmo)
+{
+int scan;
+uschar hostname[256];
+unsigned int portlow, porthigh;
+
+/* extract host and port part */
+scan = sscanf(CS hostport, "%255s %u-%u", hostname, &portlow, &porthigh);
+if (scan != 3)
+ {
+ if (scan != 2)
+ {
+ *errstr = string_sprintf("invalid socket '%s'", hostport);
+ return -1;
+ }
+ porthigh = portlow;
+ }
+
+return ip_connectedsocket(SOCK_STREAM, hostname, portlow, porthigh,
+ tmo, NULL, errstr);
+}
+
+int
+ip_unixsocket(const uschar * path, uschar ** errstr)
+{
+int sock;
+struct sockaddr_un server;
+
+if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
+ {
+ *errstr = US"can't open UNIX socket.";
+ return -1;
+ }
+
+server.sun_family = AF_UNIX;
+Ustrncpy(server.sun_path, path, sizeof(server.sun_path)-1);
+server.sun_path[sizeof(server.sun_path)-1] = '\0';
+if (connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0)
+ {
+ int err = errno;
+ (void)close(sock);
+ *errstr = string_sprintf("unable to connect to UNIX socket (%s): %s",
+ path, strerror(err));
+ return -1;
+ }
+callout_address = string_copy(path);
+return sock;
+}
+
+int
+ip_streamsocket(const uschar * spec, uschar ** errstr, int tmo)
+{
+return *spec == '/'
+ ? ip_unixsocket(spec, errstr) : ip_tcpsocket(spec, errstr, tmo);
+}
+
/*************************************************
* Set keepalive on a socket *
*************************************************/
*/
void
-ip_keepalive(int sock, uschar *address, BOOL torf)
+ip_keepalive(int sock, const uschar *address, BOOL torf)
{
int fodder = 1;
if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
fd_ready(int fd, int timeout)
{
fd_set select_inset;
-struct timeval tv;
time_t start_recv = time(NULL);
+int time_left = timeout;
int rc;
-if (timeout <= 0)
+if (time_left <= 0)
{
errno = ETIMEDOUT;
return FALSE;
}
/* Wait until the socket is ready */
-for (;;)
+do
{
+ struct timeval tv = { time_left, 0 };
FD_ZERO (&select_inset);
FD_SET (fd, &select_inset);
- tv.tv_sec = timeout;
- tv.tv_usec = 0;
/*DEBUG(D_transport) debug_printf("waiting for data on fd\n");*/
rc = select(fd + 1, (SELECT_ARG2_TYPE *)&select_inset, NULL, NULL, &tv);
Aug 2004: Somebody set up a cron job that ran exiwhat every 2 minutes, making
the interrupt not at all rare. Since the timeout is typically more than 2
minutes, the effect was to block the timeout completely. To prevent this
- happening again, we do an explicit time test. */
+ happening again, we do an explicit time test and adjust the timeout
+ accordingly */
if (rc < 0 && errno == EINTR)
{
DEBUG(D_transport) debug_printf("EINTR while waiting for socket data\n");
- if (time(NULL) - start_recv < timeout) continue;
- DEBUG(D_transport) debug_printf("total wait time exceeds timeout\n");
- }
- /* Handle a timeout, and treat any other select error as a timeout, including
- an EINTR when we have been in this loop for longer than timeout. */
+ /* Watch out, 'continue' jumps to the condition, not to the loops top */
+ time_left = timeout - (time(NULL) - start_recv);
+ if (time_left > 0) continue;
+ }
if (rc <= 0)
{
return FALSE;
}
- /* If the socket is ready, break out of the loop. */
-
- if (FD_ISSET(fd, &select_inset)) break;
+ /* Checking the FD_ISSET is not enough, if we're interrupted, the
+ select_inset may still contain the 'input'. */
}
+while (rc < 0 || !FD_ISSET(fd, &select_inset));
return TRUE;
}
return TRUE;
}
else if (c > 0)
- {
first = middle + 1;
- }
else
- {
last = middle;
- }
}
return FALSE;
}
/* End of ip.c */
+/* vi: aw ai sw=2
+*/
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2012 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* This file is the header that is the only Exim header to be included in the
each time a new feature is added (in a way that doesn't break backward
compatibility). */
-#define LOCAL_SCAN_ABI_VERSION_MAJOR 1
-#define LOCAL_SCAN_ABI_VERSION_MINOR 1
+#define LOCAL_SCAN_ABI_VERSION_MAJOR 2
+#define LOCAL_SCAN_ABI_VERSION_MINOR 0
#define LOCAL_SCAN_ABI_VERSION \
LOCAL_SCAN_ABI_VERSION_MAJOR.LOCAL_SCAN_ABI_VERSION_MINOR
extern void smtp_printf(const char *, ...) PRINTF_FUNCTION(1,2);
extern void smtp_vprintf(const char *, va_list);
extern uschar *string_copy(const uschar *);
-extern uschar *string_copyn(uschar *, int);
+extern uschar *string_copyn(const uschar *, int);
extern uschar *string_sprintf(const char *, ...) ALMOST_PRINTF(1,2);
/* End of local_scan.h */
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Functions for writing log files. The code for maintaining datestamped
}
+
+static void
+set_file_path(void)
+{
+int sep = ':'; /* Fixed separator - outside use */
+uschar *t;
+const uschar *tt = US LOG_FILE_PATH;
+while ((t = string_nextinlist(&tt, &sep, log_buffer, LOG_BUFFER_SIZE)))
+ {
+ if (Ustrcmp(t, "syslog") == 0 || t[0] == 0) continue;
+ file_path = string_copy(t);
+ break;
+ }
+}
+
+
+
/*************************************************
* Write message to log file *
*************************************************/
Arguments:
selector write to main log or LOG_INFO only if this value is zero, or if
- its bit is set in log_write_selector
+ its bit is set in log_selector[0]
flags each bit indicates some independent action:
LOG_SENDER add raw sender to the message
LOG_RECIPIENTS add raw recipients list to message
/* If nothing has been set, don't waste effort... the default values for the
statics are file_path="" and logging_mode = LOG_MODE_FILE. */
- if (log_file_path[0] != 0)
+ if (*log_file_path)
{
int sep = ':'; /* Fixed separator - outside use */
uschar *s;
- uschar *ss = log_file_path;
+ const uschar *ss = log_file_path;
logging_mode = 0;
- while ((s = string_nextinlist(&ss,&sep,log_buffer,LOG_BUFFER_SIZE)) != NULL)
+ while ((s = string_nextinlist(&ss, &sep, log_buffer, LOG_BUFFER_SIZE)))
{
if (Ustrcmp(s, "syslog") == 0)
logging_mode |= LOG_MODE_SYSLOG;
/* If a non-empty path is given, use it */
- if (s[0] != 0)
- {
+ if (*s)
file_path = string_copy(s);
- }
/* If the path is empty, we want to use the first non-empty, non-
syslog item in LOG_FILE_PATH, if there is one, since the value of
use the ultimate default in the spool directory. */
else
- {
- uschar *t;
- uschar *tt = US LOG_FILE_PATH;
- while ((t = string_nextinlist(&tt,&sep,log_buffer,LOG_BUFFER_SIZE))
- != NULL)
- {
- if (Ustrcmp(t, "syslog") == 0 || t[0] == 0) continue;
- file_path = string_copy(t);
- break;
- }
- } /* Empty item in log_file_path */
+ set_file_path(); /* Empty item in log_file_path */
} /* First non-syslog item in log_file_path */
} /* Scan of log_file_path */
}
should work since we have now set up the routing. */
if (multiple)
- {
log_write(0, LOG_MAIN|LOG_PANIC,
"More than one path given in log_file_path: using %s", file_path);
- }
}
/* If debugging, show all log entries, but don't show headers. Do it all
Ustrcpy(ptr, "LOG:");
ptr += 4;
- /* Show the options that were passed into the call. These are those whose
- flag values do not have the 0x80000000 bit in them. Note that this
- automatically exclude the "all" setting. */
+ /* Show the selector that was passed into the call. */
for (i = 0; i < log_options_count; i++)
{
- unsigned int bit = log_options[i].bit;
- if ((bit & 0x80000000) != 0) continue;
- if ((selector & bit) != 0)
+ unsigned int bitnum = log_options[i].bit;
+ if (bitnum < BITWORDSIZE && selector == BIT(bitnum))
{
*ptr++ = ' ';
Ustrcpy(ptr, log_options[i].name);
sprintf(CS ptr, "%s ", tod_stamp(tod_log));
while(*ptr) ptr++;
-if ((log_extra_selector & LX_pid) != 0)
+if (LOGGING(pid))
{
sprintf(CS ptr, "[%d] ", (int)getpid());
while (*ptr) ptr++;
if (!really_exim || log_testing_mode)
{
if (debug_selector == 0 && log_stderr != NULL &&
- (selector == 0 || (selector & log_write_selector) != 0))
+ (selector == 0 || (selector & log_selector[0]) != 0))
{
if (host_checking)
fprintf(log_stderr, "LOG: %s", CS(log_buffer + 20)); /* no timestamp */
if so, re-open. */
if ((flags & LOG_MAIN) != 0 &&
- (selector == 0 || (selector & log_write_selector) != 0))
+ (selector == 0 || (selector & log_selector[0]) != 0))
{
if ((logging_mode & LOG_MODE_SYSLOG) != 0 &&
(syslog_duplication || (flags & (LOG_REJECT|LOG_PANIC)) == 0))
{
header_line *h;
- if (header_list != NULL && (log_extra_selector & LX_rejected_header) != 0)
+ if (header_list != NULL && LOGGING(rejected_header))
{
if (recipients_count > 0)
{
+/*************************************************
+* Multi-bit set or clear *
+*************************************************/
+
+/* These functions take a list of bit indexes (terminated by -1) and
+clear or set the corresponding bits in the selector.
+
+Arguments:
+ selector address of the bit string
+ selsize number of words in the bit string
+ bits list of bits to set
+*/
+
+void
+bits_clear(unsigned int *selector, size_t selsize, int *bits)
+{
+for(; *bits != -1; ++bits)
+ BIT_CLEAR(selector, selsize, *bits);
+}
+
+void
+bits_set(unsigned int *selector, size_t selsize, int *bits)
+{
+for(; *bits != -1; ++bits)
+ BIT_SET(selector, selsize, *bits);
+}
+
+
+
/*************************************************
* Decode bit settings for log/debug *
*************************************************/
intended for user use. It's an easy way for Exim to pass the debug settings
when it is re-exec'ed.
-The log options are held in two unsigned ints (because there became too many
-for one). The top bit in the table means "put in 2nd selector". This does not
-yet apply to debug options, so the "=" facility sets only the first selector.
-
-The "all" selector, which must be equal to 0xffffffff, is recognized specially.
-It sets all the bits in both selectors. However, there is a facility for then
-unsetting certain bits, because we want to turn off "memory" in the debug case.
+The option table is a list of names and bit indexes. The index -1
+means "set all bits, except for those listed in notall". The notall
+list is terminated by -1.
The action taken for bad values varies depending upon why we're here.
For log messages, or if the debugging is triggered from config, then we write
we treat it as an unknown option: error message to stderr and die.
Arguments:
- selector1 address of the first bit string
- selector2 address of the second bit string, or NULL
- notall1 bits to exclude from "all" for selector1
- notall2 bits to exclude from "all" for selector2
+ selector address of the bit string
+ selsize number of words in the bit string
+ notall list of bits to exclude from "all"
string the configured string
options the table of option names
count size of table
*/
void
-decode_bits(unsigned int *selector1, unsigned int *selector2, int notall1,
- int notall2, uschar *string, bit_table *options, int count, uschar *which,
- int flags)
+decode_bits(unsigned int *selector, size_t selsize, int *notall,
+ uschar *string, bit_table *options, int count, uschar *which, int flags)
{
uschar *errmsg;
if (string == NULL) return;
if (*string == '=')
{
char *end; /* Not uschar */
- *selector1 = strtoul(CS string+1, &end, 0);
+ memset(selector, 0, sizeof(*selector)*selsize);
+ *selector = strtoul(CS string+1, &end, 0);
if (*end == 0) return;
errmsg = string_sprintf("malformed numeric %s_selector setting: %s", which,
string);
if (middle->name[len] != 0) c = -1; else
{
unsigned int bit = middle->bit;
- unsigned int *selector;
-
- /* The value with all bits set means "force all bits in both selectors"
- in the case where two are being handled. However, the top bit in the
- second selector is never set. When setting, some bits can be excluded.
- */
-
- if (bit == 0xffffffff)
- {
- if (adding)
- {
- *selector1 = 0xffffffff ^ notall1;
- if (selector2 != NULL) *selector2 = 0x7fffffff ^ notall2;
- }
- else
- {
- *selector1 = 0;
- if (selector2 != NULL) *selector2 = 0;
- }
- }
-
- /* Otherwise, the 0x80000000 bit means "this value, without the top
- bit, belongs in the second selector". */
- else
- {
- if ((bit & 0x80000000) != 0)
- {
- selector = selector2;
- bit &= 0x7fffffff;
- }
- else selector = selector1;
- if (adding) *selector |= bit; else *selector &= ~bit;
- }
+ if (bit == -1)
+ {
+ if (adding)
+ {
+ memset(selector, -1, sizeof(*selector)*selsize);
+ bits_clear(selector, selsize, notall);
+ }
+ else
+ memset(selector, 0, sizeof(*selector)*selsize);
+ }
+ else if (adding)
+ BIT_SET(selector, selsize, bit);
+ else
+ BIT_CLEAR(selector, selsize, bit);
+
break; /* Out of loop to match selector name */
}
}
debug_selector = D_default;
if (opts)
- {
- decode_bits(&debug_selector, NULL, D_memory, 0, opts,
+ decode_bits(&debug_selector, 1, debug_notall, opts,
debug_options, debug_options_count, US"debug", DEBUG_FROM_CONFIG);
- }
+
+/* When activating from a transport process we may never have logged at all
+resulting in certain setup not having been done. Hack this for now so we
+do not segfault; note that nondefault log locations will not work */
+
+if (!*file_path) set_file_path();
open_log(&fd, lt_debug, tag_name);
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
int (*find)( /* find function */
void *, /* handle */
uschar *, /* file name or NULL */
- uschar *, /* key or query */
+ const uschar *, /* key or query */
int, /* length of key or query */
uschar **, /* for returning answer */
uschar **, /* for error message */
- BOOL *); /* to request cache cleanup */
+ uint *); /* cache TTL, sconds */
void (*close)( /* close function */
void *); /* handle */
void (*tidy)(void); /* tidy function */
} lookup_info;
/* This magic number is used by the following lookup_module_info structure
- for checking API compatibility. It's equivalent to the string"LMM2" */
-#define LOOKUP_MODULE_INFO_MAGIC 0x4c4d4d32
+ for checking API compatibility. It used to be equivalent to the string"LMM3" */
+#define LOOKUP_MODULE_INFO_MAGIC 0x4c4d4933
/* Version 2 adds: version_report */
+/* Version 3 change: non/cache becomes TTL in seconds */
typedef struct lookup_module_info {
uint magic;
uschar **errmsg where to put an error message on failure;
this is initially set to "", and should be left
as that for a standard "entry not found" error
- BOOL *do_cache the lookup should set this to FALSE when it changes data.
- This is TRUE by default. When set to FALSE the cache tree
+ uint *do_cache the lookup should set this to 0 when it changes data.
+ This is MAXINT by default. When set to 0 the cache tree
of the current search handle will be cleaned and the
current result will NOT be cached. Currently the mysql
and pgsql lookups use this when UPDATE/INSERT queries are
executed.
+ If set to a nonzero number of seconds, the cached value
+ becomes unusable after this time. Currently the dnsdb
+ lookup uses this to support the TTL value.
Even though the key is zero-terminated, the length is passed because in the
common case it has been computed already and is often needed.
* Changed over to using unsigned chars
* Makes use of lf_check_file() for file checking
* --------------------------------------------------------------
+ * Modified by The Exim Maintainers 2015:
+ * const propagation
+ * --------------------------------------------------------------
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
static int
cdb_find(void *handle,
uschar *filename,
- uschar *keystring,
+ const uschar *keystring,
int key_len,
uschar **result,
uschar **errmsg,
- BOOL *do_cache)
+ uint *do_cache)
{
struct cdb_state * cdbp = handle;
uint32 item_key_len,
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2012 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
#include "../exim.h"
the keylength in order to include the terminating zero. */
static int
-dbmdb_find(void *handle, uschar *filename, uschar *keystring, int length,
- uschar **result, uschar **errmsg, BOOL *do_cache)
+dbmdb_find(void *handle, uschar *filename, const uschar *keystring, int length,
+ uschar **result, uschar **errmsg, uint *do_cache)
{
EXIM_DB *d = (EXIM_DB *)handle;
EXIM_DATUM key, data;
/* See local README for interface description */
int
-static dbmnz_find(void *handle, uschar *filename, uschar *keystring, int length,
- uschar **result, uschar **errmsg, BOOL *do_cache)
+static dbmnz_find(void *handle, uschar *filename, const uschar *keystring, int length,
+ uschar **result, uschar **errmsg, uint *do_cache)
{
return dbmdb_find(handle, filename, keystring, length-1, result, errmsg,
do_cache);
*/
static int
-dbmjz_find(void *handle, uschar *filename, uschar *keystring, int length,
- uschar **result, uschar **errmsg, BOOL *do_cache)
+dbmjz_find(void *handle, uschar *filename, const uschar *keystring, int length,
+ uschar **result, uschar **errmsg, uint *do_cache)
{
uschar *key_item, *key_buffer, *key_p;
-uschar *key_elems = keystring;
+const uschar *key_elems = keystring;
int buflen, bufleft, key_item_len, sep = 0;
/* To a first approximation, the size of the lookup key needs to be about,
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
#include "../exim.h"
#if HAVE_IPV6
"a+",
"aaaa",
- #ifdef SUPPORT_A6
- "a6",
- #endif
#endif
"cname",
"csa",
"mxh",
"ns",
"ptr",
+ "soa",
"spf",
"srv",
"tlsa",
#if HAVE_IPV6
T_ADDRESSES, /* Private type for AAAA + A */
T_AAAA,
- #ifdef SUPPORT_A6
- T_A6,
- #endif
#endif
T_CNAME,
T_CSA, /* Private type for "Client SMTP Authorization". */
T_MXH, /* Private type for "MX hostnames" */
T_NS,
T_PTR,
+ T_SOA,
T_SPF,
T_SRV,
T_TLSA,
is output. Similarly for "SPF" records, but the default for joining multiple
items in one SPF record is the empty string, for direct concatenation.
-(c) If the next sequence of characters is 'defer_FOO' followed by a comma,
-the defer behaviour is set to FOO. The possible behaviours are: 'strict', where
-any defer causes the whole lookup to defer; 'lax', where a defer causes the
-whole lookup to defer only if none of the DNS queries succeeds; and 'never',
-where all defers are as if the lookup failed. The default is 'lax'.
+(c) Options, all comma-terminated, in any order. Any unrecognised option
+terminates option processing. Recognised options are:
-(d) Another optional comma-sep field: 'dnssec_FOO', with 'strict', 'lax'
-and 'never' (default); can appear before or after (c). The meanings are
+- 'defer_FOO': set the defer behaviour to FOO. The possible behaviours are:
+'strict', where any defer causes the whole lookup to defer; 'lax', where a defer
+causes the whole lookup to defer only if none of the DNS queries succeeds; and
+'never', where all defers are as if the lookup failed. The default is 'lax'.
+
+- 'dnssec_FOO', with 'strict', 'lax' and 'never' (default). The meanings are
require, try and don't-try dnssec respectively.
-(e) If the next sequence of characters is a sequence of letters and digits
+- 'retrans_VAL', set the timeout value. VAL is an Exim time specification
+(eg "5s"). The default is set by the main configuration option 'dns_retrans'.
+
+- 'retry_VAL', set the retry count on timeouts. VAL is an integer. The
+default is set by the main configuration option "dns_retry".
+
+(d) If the next sequence of characters is a sequence of letters and digits
followed by '=', it is interpreted as the name of the DNS record type. The
default is "TXT".
-(f) Then there follows list of domain names. This is a generalized Exim list,
+(e) Then there follows list of domain names. This is a generalized Exim list,
which may start with '<' in order to set a specific separator. The default
separator, as always, is colon. */
static int
-dnsdb_find(void *handle, uschar *filename, uschar *keystring, int length,
- uschar **result, uschar **errmsg, BOOL *do_cache)
+dnsdb_find(void *handle, uschar *filename, const uschar *keystring, int length,
+ uschar **result, uschar **errmsg, uint *do_cache)
{
int rc;
int size = 256;
int sep = 0;
int defer_mode = PASS;
int dnssec_mode = OK;
+int save_retrans = dns_retrans;
+int save_retry = dns_retry;
int type;
int failrc = FAIL;
-uschar *outsep = US"\n";
-uschar *outsep2 = NULL;
+const uschar *outsep = CUS"\n";
+const uschar *outsep2 = NULL;
uschar *equals, *domain, *found;
-uschar buffer[256];
/* Because we're the working in the search pool, we try to reclaim as much
store as possible later, so we preallocate the result here */
/* Check for a modifier keyword. */
-while ( strncmpic(keystring, US"defer_", 6) == 0
- || strncmpic(keystring, US"dnssec_", 7) == 0
- )
+for (;;)
{
if (strncmpic(keystring, US"defer_", 6) == 0)
{
keystring += 6;
if (strncmpic(keystring, US"strict", 6) == 0)
- {
- defer_mode = DEFER;
- keystring += 6;
- }
+ { defer_mode = DEFER; keystring += 6; }
else if (strncmpic(keystring, US"lax", 3) == 0)
- {
- defer_mode = PASS;
- keystring += 3;
- }
+ { defer_mode = PASS; keystring += 3; }
else if (strncmpic(keystring, US"never", 5) == 0)
- {
- defer_mode = OK;
- keystring += 5;
- }
+ { defer_mode = OK; keystring += 5; }
else
{
*errmsg = US"unsupported dnsdb defer behaviour";
return DEFER;
}
}
- else
+ else if (strncmpic(keystring, US"dnssec_", 7) == 0)
{
keystring += 7;
if (strncmpic(keystring, US"strict", 6) == 0)
- {
- dnssec_mode = DEFER;
- keystring += 6;
- }
+ { dnssec_mode = DEFER; keystring += 6; }
else if (strncmpic(keystring, US"lax", 3) == 0)
+ { dnssec_mode = PASS; keystring += 3; }
+ else if (strncmpic(keystring, US"never", 5) == 0)
+ { dnssec_mode = OK; keystring += 5; }
+ else
{
- dnssec_mode = PASS;
- keystring += 3;
+ *errmsg = US"unsupported dnsdb dnssec behaviour";
+ return DEFER;
}
- else if (strncmpic(keystring, US"never", 5) == 0)
+ }
+ else if (strncmpic(keystring, US"retrans_", 8) == 0)
+ {
+ int timeout_sec;
+ if ((timeout_sec = readconf_readtime(keystring += 8, ',', FALSE)) <= 0)
{
- dnssec_mode = OK;
- keystring += 5;
+ *errmsg = US"unsupported dnsdb timeout value";
+ return DEFER;
}
- else
+ dns_retrans = timeout_sec;
+ while (*keystring != ',') keystring++;
+ }
+ else if (strncmpic(keystring, US"retry_", 6) == 0)
+ {
+ int retries;
+ if ((retries = (int)strtol(CCS keystring + 6, CSS &keystring, 0)) < 0)
{
- *errmsg = US"unsupported dnsdb dnssec behaviour";
+ *errmsg = US"unsupported dnsdb retry count";
return DEFER;
}
+ dns_retry = retries;
}
+ else
+ break;
+
while (isspace(*keystring)) keystring++;
if (*keystring++ != ',')
{
/* Now scan the list and do a lookup for each item */
-while ((domain = string_nextinlist(&keystring, &sep, buffer, sizeof(buffer)))
- != NULL)
+while ((domain = string_nextinlist(&keystring, &sep, NULL, 0)))
{
uschar rbuffer[256];
int searchtype = (type == T_CSA)? T_SRV : /* record type we want */
#if HAVE_IPV6
if (type == T_ADDRESSES) /* NB cannot happen unless HAVE_IPV6 */
{
- if (searchtype == T_ADDRESSES)
-# if defined(SUPPORT_A6)
- searchtype = T_A6;
-# else
- searchtype = T_AAAA;
-# endif
- else if (searchtype == T_A6) searchtype = T_AAAA;
+ if (searchtype == T_ADDRESSES) searchtype = T_AAAA;
else if (searchtype == T_AAAA) searchtype = T_A;
- rc = dns_special_lookup(&dnsa, domain, searchtype, &found);
+ rc = dns_special_lookup(&dnsa, domain, searchtype, CUSS &found);
}
else
#endif
- rc = dns_special_lookup(&dnsa, domain, type, &found);
+ rc = dns_special_lookup(&dnsa, domain, type, CUSS &found);
lookup_dnssec_authenticated = dnssec_mode==OK ? NULL
: dns_is_secure(&dnsa) ? US"yes" : US"no";
{
if (defer_mode == DEFER)
{
+ dns_retrans = save_retrans;
+ dns_retry = save_retry;
dns_init(FALSE, FALSE, FALSE); /* clr dnssec bit */
return DEFER; /* always defer */
}
{
if (rr->type != searchtype) continue;
- /* There may be several addresses from an A6 record. Put the configured
- separator between them, just as for between several records. However, A6
- support is not normally configured these days. */
+ if (*do_cache > rr->ttl)
+ *do_cache = rr->ttl;
- if (type == T_A ||
- #ifdef SUPPORT_A6
- type == T_A6 ||
- #endif
- type == T_AAAA ||
- type == T_ADDRESSES)
+ if (type == T_A || type == T_AAAA || type == T_ADDRESSES)
{
dns_address *da;
- for (da = dns_address_from_rr(&dnsa, rr); da != NULL; da = da->next)
+ for (da = dns_address_from_rr(&dnsa, rr); da; da = da->next)
{
if (ptr != 0) yield = string_cat(yield, &size, &ptr, outsep, 1);
yield = string_cat(yield, &size, &ptr, da->address,
uint16_t i, payload_length;
uschar s[MAX_TLSA_EXPANDED_SIZE];
uschar * sp = s;
- uschar *p = (uschar *)(rr->data);
+ uschar * p = US rr->data;
usage = *p++;
selector = *p++;
for (i=0;
i < payload_length && sp-s < (MAX_TLSA_EXPANDED_SIZE - 4);
i++)
- {
sp += sprintf(CS sp, "%02x", (unsigned char)p[i]);
- }
+
yield = string_cat(yield, &size, &ptr, s, Ustrlen(s));
}
- else /* T_CNAME, T_CSA, T_MX, T_MXH, T_NS, T_PTR, T_SRV */
+ else /* T_CNAME, T_CSA, T_MX, T_MXH, T_NS, T_PTR, T_SOA, T_SRV */
{
int priority, weight, port;
uschar s[264];
- uschar *p = (uschar *)(rr->data);
-
- if (type == T_MXH)
- {
- /* mxh ignores the priority number and includes only the hostnames */
- GETSHORT(priority, p);
- }
- else if (type == T_MX)
- {
- GETSHORT(priority, p);
- sprintf(CS s, "%d%c", priority, *outsep2);
- yield = string_cat(yield, &size, &ptr, s, Ustrlen(s));
- }
- else if (type == T_SRV)
- {
- GETSHORT(priority, p);
- GETSHORT(weight, p);
- GETSHORT(port, p);
- sprintf(CS s, "%d%c%d%c%d%c", priority, *outsep2,
- weight, *outsep2, port, *outsep2);
- yield = string_cat(yield, &size, &ptr, s, Ustrlen(s));
- }
- else if (type == T_CSA)
- {
- /* See acl_verify_csa() for more comments about CSA. */
-
- GETSHORT(priority, p);
- GETSHORT(weight, p);
- GETSHORT(port, p);
-
- if (priority != 1) continue; /* CSA version must be 1 */
-
- /* If the CSA record we found is not the one we asked for, analyse
- the subdomain assertions in the port field, else analyse the direct
- authorization status in the weight field. */
-
- if (found != domain)
- {
- if (port & 1) *s = 'X'; /* explicit authorization required */
- else *s = '?'; /* no subdomain assertions here */
- }
- else
- {
- if (weight < 2) *s = 'N'; /* not authorized */
- else if (weight == 2) *s = 'Y'; /* authorized */
- else if (weight == 3) *s = '?'; /* unauthorizable */
- else continue; /* invalid */
- }
-
- s[1] = ' ';
- yield = string_cat(yield, &size, &ptr, s, 2);
- }
+ uschar * p = US rr->data;
+
+ switch (type)
+ {
+ case T_MXH:
+ /* mxh ignores the priority number and includes only the hostnames */
+ GETSHORT(priority, p);
+ break;
+
+ case T_MX:
+ GETSHORT(priority, p);
+ sprintf(CS s, "%d%c", priority, *outsep2);
+ yield = string_cat(yield, &size, &ptr, s, Ustrlen(s));
+ break;
+
+ case T_SRV:
+ GETSHORT(priority, p);
+ GETSHORT(weight, p);
+ GETSHORT(port, p);
+ sprintf(CS s, "%d%c%d%c%d%c", priority, *outsep2,
+ weight, *outsep2, port, *outsep2);
+ yield = string_cat(yield, &size, &ptr, s, Ustrlen(s));
+ break;
+
+ case T_CSA:
+ /* See acl_verify_csa() for more comments about CSA. */
+ GETSHORT(priority, p);
+ GETSHORT(weight, p);
+ GETSHORT(port, p);
+
+ if (priority != 1) continue; /* CSA version must be 1 */
+
+ /* If the CSA record we found is not the one we asked for, analyse
+ the subdomain assertions in the port field, else analyse the direct
+ authorization status in the weight field. */
+
+ if (Ustrcmp(found, domain) != 0)
+ {
+ if (port & 1) *s = 'X'; /* explicit authorization required */
+ else *s = '?'; /* no subdomain assertions here */
+ }
+ else
+ {
+ if (weight < 2) *s = 'N'; /* not authorized */
+ else if (weight == 2) *s = 'Y'; /* authorized */
+ else if (weight == 3) *s = '?'; /* unauthorizable */
+ else continue; /* invalid */
+ }
+
+ s[1] = ' ';
+ yield = string_cat(yield, &size, &ptr, s, 2);
+ break;
+
+ default:
+ break;
+ }
/* GETSHORT() has advanced the pointer to the target domain. */
rc = dn_expand(dnsa.answer, dnsa.answer + dnsa.answerlen, p,
- (DN_EXPAND_ARG4_TYPE)(s), sizeof(s));
+ (DN_EXPAND_ARG4_TYPE)s, sizeof(s));
/* If an overlong response was received, the data will have been
truncated and dn_expand may fail. */
break;
}
else yield = string_cat(yield, &size, &ptr, s, Ustrlen(s));
+
+ if (type == T_SOA && outsep2 != NULL)
+ {
+ unsigned long serial, refresh, retry, expire, minimum;
+
+ p += rc;
+ yield = string_cat(yield, &size, &ptr, outsep2, 1);
+
+ rc = dn_expand(dnsa.answer, dnsa.answer + dnsa.answerlen, p,
+ (DN_EXPAND_ARG4_TYPE)s, sizeof(s));
+ if (rc < 0)
+ {
+ log_write(0, LOG_MAIN, "responsible-mailbox truncated: type=%s "
+ "domain=%s", dns_text_type(type), domain);
+ break;
+ }
+ else yield = string_cat(yield, &size, &ptr, s, Ustrlen(s));
+
+ p += rc;
+ GETLONG(serial, p); GETLONG(refresh, p);
+ GETLONG(retry, p); GETLONG(expire, p); GETLONG(minimum, p);
+ sprintf(CS s, "%c%lu%c%lu%c%lu%c%lu%c%lu",
+ *outsep2, serial, *outsep2, refresh,
+ *outsep2, retry, *outsep2, expire, *outsep2, minimum);
+ yield = string_cat(yield, &size, &ptr, s, Ustrlen(s));
+ }
}
} /* Loop for list of returned records */
/* If ptr == 0 we have not found anything. Otherwise, insert the terminating
zero and return the result. */
+dns_retrans = save_retrans;
+dns_retry = save_retry;
dns_init(FALSE, FALSE, FALSE); /* clear the dnssec bit for getaddrbyname */
if (ptr == 0) return failrc;
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* The idea for this code came from Matthew Byng-Maddick, but his original has
for us. */
int
-static dsearch_find(void *handle, uschar *dirname, uschar *keystring, int length,
- uschar **result, uschar **errmsg, BOOL *do_cache)
+static dsearch_find(void *handle, uschar *dirname, const uschar *keystring, int length,
+ uschar **result, uschar **errmsg, uint *do_cache)
{
struct stat statbuf;
int save_errno;
static int
ibase_find(void *handle, uschar * filename, uschar * query, int length,
- uschar ** result, uschar ** errmsg, BOOL *do_cache)
+ uschar ** result, uschar ** errmsg, uint *do_cache)
{
int sep = 0;
uschar *server;
#ifdef DYNLOOKUP
#define ibase_lookup_module_info _lookup_module_info
#endif
-
+
static lookup_info *_lookup_list[] = { &_lookup_info };
lookup_module_info ibase_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 1 };
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Many thanks to Stuart Lynne for contributing the original code for this
*/
static int
-perform_ldap_search(uschar *ldap_url, uschar *server, int s_port, int search_type,
- uschar **res, uschar **errmsg, BOOL *defer_break, uschar *user, uschar *password,
- int sizelimit, int timelimit, int tcplimit, int dereference, void *referrals)
+perform_ldap_search(const uschar *ldap_url, uschar *server, int s_port,
+ int search_type, uschar **res, uschar **errmsg, BOOL *defer_break,
+ uschar *user, uschar *password, int sizelimit, int timelimit, int tcplimit,
+ int dereference, void *referrals)
{
LDAPURLDesc *ludp = NULL;
LDAPMessage *result = NULL;
uschar *error2 = NULL; /* error message from the server */
uschar *matched = NULL; /* partially matched DN */
-int attr_count = 0;
+int attrs_requested = 0;
int error_yield = DEFER;
int msgid;
int rc, ldap_rc, ldap_parse_rc;
/* Count the attributes; we need this later to tell us how to format results */
for (attrp = USS ludp->lud_attrs; attrp != NULL && *attrp != NULL; attrp++)
- attr_count++;
+ attrs_requested++;
/* See if we can find a cached connection to this host. The port is not
relevant for ldapi. The host name pointer is set to NULL if no host was given
LDAP_RES_SEARCH_ENTRY)
{
LDAPMessage *e;
+ int valuecount; /* We can see an attr spread across several
+ entries. If B is derived from A and we request
+ A and the directory contains both, A and B,
+ then we get two entries, one for A and one for B.
+ Here we just count the values per entry */
- DEBUG(D_lookup) debug_printf("ldap_result loop\n");
+ DEBUG(D_lookup) debug_printf("LDAP result loop\n");
- for(e = ldap_first_entry(lcp->ld, result);
+ for(e = ldap_first_entry(lcp->ld, result), valuecount = 0;
e != NULL;
e = ldap_next_entry(lcp->ld, e))
{
/* Otherwise, loop through the entry, grabbing attribute values. If there's
only one attribute being retrieved, no attribute name is given, and the
- result is not quoted. Multiple values are separated by (comma, space).
+ result is not quoted. Multiple values are separated by (comma).
If more than one attribute is being retrieved, the data is given as a
- sequence of name=value pairs, with the value always in quotes. If there are
- multiple values, they are given within the quotes, comma separated. */
+ sequence of name=value pairs, separated by (space), with the value always in quotes.
+ If there are multiple values, they are given within the quotes, comma separated. */
else for (attr = US ldap_first_attribute(lcp->ld, e, &ber);
attr != NULL;
attr = US ldap_next_attribute(lcp->ld, e, ber))
{
+ DEBUG(D_lookup) debug_printf("LDAP attr loop\n");
+
+ /* In case of attrs_requested == 1 we just count the values, in all other cases
+ (0, >1) we count the values per attribute */
+ if (attrs_requested != 1) valuecount = 0;
+
if (attr[0] != 0)
{
/* Get array of values for this attribute. */
if ((firstval = values = USS ldap_get_values(lcp->ld, e, CS attr))
!= NULL)
{
- if (attr_count != 1)
+
+ if (attrs_requested != 1)
{
if (insert_space)
data = string_cat(data, &size, &ptr, US" ", 1);
{
uschar *value = *values;
int len = Ustrlen(value);
+ ++valuecount;
+
+ DEBUG(D_lookup) debug_printf("LDAP value loop %s:%s\n", attr, value);
- DEBUG(D_lookup) debug_printf("LDAP attr loop %s:%s\n", attr, value);
+ /* In case we requested one attribute only but got several times
+ into that attr loop, we need to append the additional values.
+ (This may happen if you derive attributeTypes B and C from A and
+ then query for A.) In all other cases we detect the different
+ attribute and append only every non first value. */
- /* In case we requested one attribute only but got
- * several times into that attr loop, we need to append
- * the additional values. (This may happen if you derive
- * attributeTypes B and C from A and then query for A.)
- * In all other cases we detect the different attribute
- * and append only every non first value. */
- if ((attr_count == 1 && data) || (values != firstval))
+ if (data && valuecount > 1)
data = string_cat(data, &size, &ptr, US",", 1);
/* For multiple attributes, the data is in quotes. We must escape
internal quotes, backslashes, newlines, and must double commas. */
- if (attr_count != 1)
+ if (attrs_requested != 1)
{
int j;
for (j = 0; j < len; j++)
/* Closing quote at the end of the data for a named attribute. */
- if (attr_count != 1)
+ if (attrs_requested != 1)
data = string_cat(data, &size, &ptr, US"\"", 1);
/* Free the values */
*/
static int
-control_ldap_search(uschar *ldap_url, int search_type, uschar **res,
+control_ldap_search(const uschar *ldap_url, int search_type, uschar **res,
uschar **errmsg)
{
BOOL defer_break = FALSE;
int sep = 0;
int dereference = LDAP_DEREF_NEVER;
void* referrals = LDAP_OPT_ON;
-uschar *url = ldap_url;
-uschar *p;
+const uschar *url = ldap_url;
+const uschar *p;
uschar *user = NULL;
uschar *password = NULL;
uschar *local_servers = NULL;
-uschar *server, *list;
+uschar *server;
+const uschar *list;
uschar buffer[512];
while (isspace(*url)) url++;
while (strncmpic(url, US"ldap", 4) != 0)
{
- uschar *name = url;
+ const uschar *name = url;
while (*url != 0 && *url != '=') url++;
if (*url == '=')
{
The handle and filename arguments are not used. */
static int
-eldap_find(void *handle, uschar *filename, uschar *ldap_url, int length,
- uschar **result, uschar **errmsg, BOOL *do_cache)
+eldap_find(void *handle, uschar *filename, const uschar *ldap_url, int length,
+ uschar **result, uschar **errmsg, uint *do_cache)
{
/* Keep picky compilers happy */
do_cache = do_cache;
}
static int
-eldapm_find(void *handle, uschar *filename, uschar *ldap_url, int length,
- uschar **result, uschar **errmsg, BOOL *do_cache)
+eldapm_find(void *handle, uschar *filename, const uschar *ldap_url, int length,
+ uschar **result, uschar **errmsg, uint *do_cache)
{
/* Keep picky compilers happy */
do_cache = do_cache;
}
static int
-eldapdn_find(void *handle, uschar *filename, uschar *ldap_url, int length,
- uschar **result, uschar **errmsg, BOOL *do_cache)
+eldapdn_find(void *handle, uschar *filename, const uschar *ldap_url, int length,
+ uschar **result, uschar **errmsg, uint *do_cache)
{
/* Keep picky compilers happy */
do_cache = do_cache;
}
int
-eldapauth_find(void *handle, uschar *filename, uschar *ldap_url, int length,
- uschar **result, uschar **errmsg, BOOL *do_cache)
+eldapauth_find(void *handle, uschar *filename, const uschar *ldap_url, int length,
+ uschar **result, uschar **errmsg, uint *do_cache)
{
/* Keep picky compilers happy */
do_cache = do_cache;
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Header for eldapauth_find */
-extern int eldapauth_find(void *, uschar *, uschar *, int, uschar **,
+extern int eldapauth_find(void *, uschar *, const uschar *, int, uschar **,
uschar **, BOOL *);
/* End of lookups/ldap.h */
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Header for the functions that are shared by the lookups */
extern int lf_check_file(int, uschar *, int, int, uid_t *, gid_t *,
const char *, uschar **);
extern uschar *lf_quote(uschar *, uschar *, int, uschar *, int *, int *);
-extern int lf_sqlperform(uschar *, uschar *, uschar *, uschar *, uschar **,
- uschar **, BOOL *, int(*)(uschar *, uschar *, uschar **,
- uschar **, BOOL *, BOOL *));
+extern int lf_sqlperform(const uschar *, const uschar *, const uschar *,
+ const uschar *, uschar **,
+ uschar **, uint *, int(*)(const uschar *, uschar *, uschar **,
+ uschar **, BOOL *, uint *));
/* End of lf_functions.h */
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
query the query
result where to pass back the result
errmsg where to pass back an error message
- do_cache to be set FALSE if data is changed
+ do_cache to be set zero if data is changed
func the lookup function to call
Returns: the return from the lookup function, or DEFER
*/
int
-lf_sqlperform(uschar *name, uschar *optionname, uschar *optserverlist,
- uschar *query, uschar **result, uschar **errmsg, BOOL *do_cache,
- int(*fn)(uschar *, uschar *, uschar **, uschar **, BOOL *, BOOL *))
+lf_sqlperform(const uschar *name, const uschar *optionname,
+ const uschar *optserverlist, const uschar *query,
+ uschar **result, uschar **errmsg, uint *do_cache,
+ int(*fn)(const uschar *, uschar *, uschar **, uschar **, BOOL *, uint *))
{
int sep, rc;
uschar *server;
-uschar *serverlist;
+const uschar *serverlist;
uschar buffer[512];
BOOL defer_break = FALSE;
else
{
int qsep;
- uschar *s, *ss;
- uschar *qserverlist;
+ const uschar *s, *ss;
+ const uschar *qserverlist;
uschar *qserver;
uschar qbuffer[512];
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
#include "../exim.h"
but people do occasionally do weird things. */
static int
-internal_lsearch_find(void *handle, uschar *filename, uschar *keystring,
+internal_lsearch_find(void *handle, uschar *filename, const uschar *keystring,
int length, uschar **result, uschar **errmsg, int type)
{
FILE *f = (FILE *)handle;
uschar *t = s++;
while (*s != 0 && *s != '\"')
{
- if (*s == '\\') *t++ = string_interpret_escape(&s);
+ if (*s == '\\') *t++ = string_interpret_escape(CUSS &s);
else *t++ = *s;
s++;
}
{
int rc;
int save = buffer[linekeylength];
- uschar *list = buffer;
+ const uschar *list = buffer;
buffer[linekeylength] = 0;
rc = match_isinlist(keystring,
&list,
/* See local README for interface description */
static int
-lsearch_find(void *handle, uschar *filename, uschar *keystring, int length,
- uschar **result, uschar **errmsg, BOOL *do_cache)
+lsearch_find(void *handle, uschar *filename, const uschar *keystring, int length,
+ uschar **result, uschar **errmsg, uint *do_cache)
{
do_cache = do_cache; /* Keep picky compilers happy */
return internal_lsearch_find(handle, filename, keystring, length, result,
/* See local README for interface description */
static int
-wildlsearch_find(void *handle, uschar *filename, uschar *keystring, int length,
- uschar **result, uschar **errmsg, BOOL *do_cache)
+wildlsearch_find(void *handle, uschar *filename, const uschar *keystring, int length,
+ uschar **result, uschar **errmsg, uint *do_cache)
{
do_cache = do_cache; /* Keep picky compilers happy */
return internal_lsearch_find(handle, filename, keystring, length, result,
/* See local README for interface description */
static int
-nwildlsearch_find(void *handle, uschar *filename, uschar *keystring, int length,
- uschar **result, uschar **errmsg, BOOL *do_cache)
+nwildlsearch_find(void *handle, uschar *filename, const uschar *keystring, int length,
+ uschar **result, uschar **errmsg, uint *do_cache)
{
do_cache = do_cache; /* Keep picky compilers happy */
return internal_lsearch_find(handle, filename, keystring, length, result,
/* See local README for interface description */
static int
-iplsearch_find(void *handle, uschar *filename, uschar *keystring, int length,
- uschar **result, uschar **errmsg, BOOL *do_cache)
+iplsearch_find(void *handle, uschar *filename, const uschar *keystring, int length,
+ uschar **result, uschar **errmsg, uint *do_cache)
{
do_cache = do_cache; /* Keep picky compilers happy */
if ((length == 1 && keystring[0] == '*') ||
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Thanks to Paul Kelly for contributing the original code for these
resultptr where to store the result
errmsg where to point an error message
defer_break TRUE if no more servers are to be tried after DEFER
- do_cache set false if data is changed
+ do_cache set zero if data is changed
The server string is of the form "host/dbname/user/password". The host can be
host:port. This string is in a nextinlist temporary buffer, so can be
*/
static int
-perform_mysql_search(uschar *query, uschar *server, uschar **resultptr,
- uschar **errmsg, BOOL *defer_break, BOOL *do_cache)
+perform_mysql_search(const uschar *query, uschar *server, uschar **resultptr,
+ uschar **errmsg, BOOL *defer_break, uint *do_cache)
{
MYSQL *mysql_handle = NULL; /* Keep compilers happy */
MYSQL_RES *mysql_result = NULL;
/* See if we have a cached connection to the server */
-for (cn = mysql_connections; cn != NULL; cn = cn->next)
- {
+for (cn = mysql_connections; cn; cn = cn->next)
if (Ustrcmp(cn->server, server_copy) == 0)
{
mysql_handle = cn->handle;
break;
}
- }
/* If no cached connection, we must set one up. Mysql allows for a host name
and port to be specified. It also allows the name of a Unix socket to be used.
Unfortunately, this contains slashes, but its use is expected to be rare, so
the rather cumbersome syntax shouldn't inconvenience too many people. We use
-this: host:port(socket) where all the parts are optional. */
+this: host:port(socket)[group] where all the parts are optional.
+The "group" parameter specifies an option group from a MySQL option file. */
-if (cn == NULL)
+if (!cn)
{
uschar *p;
uschar *socket = NULL;
int port = 0;
+ uschar *group = US"exim";
+
+ if ((p = Ustrchr(sdata[0], '[')))
+ {
+ *p++ = 0;
+ group = p;
+ while (*p && *p != ']') p++;
+ *p = 0;
+ }
- if ((p = Ustrchr(sdata[0], '(')) != NULL)
+ if ((p = Ustrchr(sdata[0], '(')))
{
*p++ = 0;
socket = p;
- while (*p != 0 && *p != ')') p++;
+ while (*p && *p != ')') p++;
*p = 0;
}
- if ((p = Ustrchr(sdata[0], ':')) != NULL)
+ if ((p = Ustrchr(sdata[0], ':')))
{
*p++ = 0;
port = Uatoi(p);
}
- if (Ustrchr(sdata[0], '/') != NULL)
+ if (Ustrchr(sdata[0], '/'))
{
*errmsg = string_sprintf("unexpected slash in MySQL server hostname: %s",
sdata[0]);
mysql_handle = store_get(sizeof(MYSQL));
mysql_init(mysql_handle);
+ mysql_options(mysql_handle, MYSQL_READ_DEFAULT_GROUP, CS group);
if (mysql_real_connect(mysql_handle,
/* host user passwd database */
CS sdata[0], CS sdata[2], CS sdata[3], CS sdata[1],
was expected (this is all explained clearly in the MySQL manual). In this case,
we return the number of rows affected by the command. In this event, we do NOT
want to cache the result; also the whole cache for the handle must be cleaned
-up. Setting do_cache FALSE requests this. */
+up. Setting do_cache zero requests this. */
if ((mysql_result = mysql_use_result(mysql_handle)) == NULL)
{
{
DEBUG(D_lookup) debug_printf("MYSQL: query was not one that returns data\n");
result = string_sprintf("%d", mysql_affected_rows(mysql_handle));
- *do_cache = FALSE;
+ *do_cache = 0;
goto MYSQL_EXIT;
}
*errmsg = string_sprintf("MYSQL: lookup result failed: %s\n",
shared with other SQL lookups. */
static int
-mysql_find(void *handle, uschar *filename, uschar *query, int length,
- uschar **result, uschar **errmsg, BOOL *do_cache)
+mysql_find(void *handle, uschar *filename, const uschar *query, int length,
+ uschar **result, uschar **errmsg, uint *do_cache)
{
return lf_sqlperform(US"MySQL", US"mysql_servers", mysql_servers, query,
result, errmsg, do_cache, perform_mysql_search);
static int
nis_find(void *handle, uschar *filename, uschar *keystring, int length,
- uschar **result, uschar **errmsg, BOOL *do_cache)
+ uschar **result, uschar **errmsg, uint *do_cache)
{
int rc;
uschar *nis_data;
static int
nis0_find(void *handle, uschar *filename, uschar *keystring, int length,
- uschar **result, uschar **errmsg, BOOL *do_cache)
+ uschar **result, uschar **errmsg, uint *do_cache)
{
int rc;
uschar *nis_data;
static int
nisplus_find(void *handle, uschar *filename, uschar *query, int length,
- uschar **result, uschar **errmsg, BOOL *do_cache)
+ uschar **result, uschar **errmsg, uint *do_cache)
{
int i;
int ssize = 0;
static int
oracle_find(void *handle, uschar *filename, uschar *query, int length,
- uschar **result, uschar **errmsg, BOOL *do_cache)
+ uschar **result, uschar **errmsg, uint *do_cache)
{
int sep = 0;
uschar *server;
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
#include "../exim.h"
/* See local README for interface description */
static int
-passwd_find(void *handle, uschar *filename, uschar *keystring, int length,
- uschar **result, uschar **errmsg, BOOL *do_cache)
+passwd_find(void *handle, uschar *filename, const uschar *keystring, int length,
+ uschar **result, uschar **errmsg, uint *do_cache)
{
struct passwd *pw;
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Thanks to Petr Cech for contributing the original code for these
*/
static int
-perform_pgsql_search(uschar *query, uschar *server, uschar **resultptr,
- uschar **errmsg, BOOL *defer_break, BOOL *do_cache)
+perform_pgsql_search(const uschar *query, uschar *server, uschar **resultptr,
+ uschar **errmsg, BOOL *defer_break, uint *do_cache)
{
PGconn *pg_conn = NULL;
PGresult *pg_result = NULL;
/* The command was successful but did not return any data since it was
* not SELECT but either an INSERT, UPDATE or DELETE statement. Tell the
* high level code to not cache this query, and clean the current cache for
- * this handle by setting *do_cache FALSE. */
+ * this handle by setting *do_cache zero. */
result = string_copy(US PQcmdTuples(pg_result));
offset = Ustrlen(result);
- *do_cache = FALSE;
+ *do_cache = 0;
DEBUG(D_lookup) debug_printf("PGSQL: command does not return any data "
"but was successful. Rows affected: %s\n", result);
shared with other SQL lookups. */
static int
-pgsql_find(void *handle, uschar *filename, uschar *query, int length,
- uschar **result, uschar **errmsg, BOOL *do_cache)
+pgsql_find(void *handle, uschar *filename, const uschar *query, int length,
+ uschar **result, uschar **errmsg, uint *do_cache)
{
return lf_sqlperform(US"PostgreSQL", US"pgsql_servers", pgsql_servers, query,
result, errmsg, do_cache, perform_pgsql_search);
/* The characters that always need to be quoted (with backslash) are newline,
tab, carriage return, backspace, backslash itself, and the quote characters.
-Percent and underscore are only special in contexts where they can be wild
-cards, and this isn't usually the case for data inserted from messages, since
-that isn't likely to be treated as a pattern of any kind. However, pgsql seems
-to allow escaping "on spec". If you use something like "where id="ab\%cd" it
-does treat the string as "ab%cd". So we can safely quote percent and
-underscore. [This is different to MySQL, where you can't do this.]
The original code quoted single quotes as \' which is documented as valid in
the O'Reilly book "Practical PostgreSQL" (first edition) as an alternative to
if (opt != NULL) return NULL; /* No options recognized */
while ((c = *t++) != 0)
- if (Ustrchr("\n\t\r\b\'\"\\%_", c) != NULL) count++;
+ if (Ustrchr("\n\t\r\b\'\"\\", c) != NULL) count++;
if (count == 0) return s;
t = quoted = store_get(Ustrlen(s) + count + 1);
*t++ = '\'';
*t++ = '\'';
}
- else if (Ustrchr("\n\t\r\b\"\\%_", c) != NULL)
+ else if (Ustrchr("\n\t\r\b\"\\", c) != NULL)
{
*t++ = '\\';
switch(c)
#include "../exim.h"
-#ifdef EXPERIMENTAL_REDIS
+#ifdef LOOKUP_REDIS
#include "lf_functions.h"
#include <hiredis/hiredis.h>
+#ifndef nele
+# define nele(arr) (sizeof(arr) / sizeof(*arr))
+#endif
+
/* Structure and anchor for caching connections. */
typedef struct redis_connection {
- struct redis_connection *next;
- uschar *server;
- redisContext *handle;
+ struct redis_connection *next;
+ uschar *server;
+ redisContext *handle;
} redis_connection;
static redis_connection *redis_connections = NULL;
+
static void *
redis_open(uschar *filename, uschar **errmsg)
{
- return (void *)(1);
+return (void *)(1);
}
+
void
redis_tidy(void)
{
- redis_connection *cn;
-
- /*
- * XXX: Not sure how often this is called!
- * Guess its called after every lookup which probably would mean to just
- * not use the _tidy() function at all and leave with exim exiting to
- * GC connections!
- */
- while ((cn = redis_connections) != NULL) {
- redis_connections = cn->next;
- DEBUG(D_lookup) debug_printf("close REDIS connection: %s\n", cn->server);
- redisFree(cn->handle);
- }
+redis_connection *cn;
+
+/* XXX: Not sure how often this is called!
+ Guess its called after every lookup which probably would mean to just
+ not use the _tidy() function at all and leave with exim exiting to
+ GC connections! */
+
+while ((cn = redis_connections))
+ {
+ redis_connections = cn->next;
+ DEBUG(D_lookup) debug_printf("close REDIS connection: %s\n", cn->server);
+ redisFree(cn->handle);
+ }
}
+
/* This function is called from the find entry point to do the search for a
- * single server.
- *
- * Arguments:
- * query the query string
- * server the server string
- * resultptr where to store the result
- * errmsg where to point an error message
- * defer_break TRUE if no more servers are to be tried after DEFER
- * do_cache set false if data is changed
- *
- * The server string is of the form "host/dbnumber/password". The host can be
- * host:port. This string is in a nextinlist temporary buffer, so can be
- * overwritten.
- *
- * Returns: OK, FAIL, or DEFER
- */
+single server.
+
+ Arguments:
+ query the query string
+ server the server string
+ resultptr where to store the result
+ errmsg where to point an error message
+ defer_break TRUE if no more servers are to be tried after DEFER
+ do_cache set false if data is changed
+
+ The server string is of the form "host/dbnumber/password". The host can be
+ host:port. This string is in a nextinlist temporary buffer, so can be
+ overwritten.
+
+ Returns: OK, FAIL, or DEFER
+*/
+
static int
-perform_redis_search(uschar *command, uschar *server, uschar **resultptr,
- uschar **errmsg, BOOL *defer_break, BOOL *do_cache)
+perform_redis_search(const uschar *command, uschar *server, uschar **resultptr,
+ uschar **errmsg, BOOL *defer_break, uint *do_cache)
{
- redisContext *redis_handle = NULL; /* Keep compilers happy */
- redisReply *redis_reply = NULL;
- redisReply *entry = NULL;
- redisReply *tentry = NULL;
- redis_connection *cn;
- int ssize = 0;
- int offset = 0;
- int yield = DEFER;
- int i, j;
- uschar *result = NULL;
- uschar *server_copy = NULL;
- uschar *tmp, *ttmp;
- uschar *sdata[3];
-
- /*
- * Disaggregate the parameters from the server argument.
- * The order is host:port(socket)
- * We can write to the string, since it is in a nextinlist temporary buffer.
- * This copy is also used for debugging output.
- */
- memset(sdata, 0, sizeof(sdata)) /* Set all to NULL */;
- for (i = 2; i > 0; i--) {
- uschar *pp = Ustrrchr(server, '/');
- if (pp == NULL) {
- *errmsg = string_sprintf("incomplete Redis server data: %s", (i == 2) ? server : server_copy);
- *defer_break = TRUE;
- return DEFER;
- }
- *pp++ = 0;
- sdata[i] = pp;
- if (i == 2) server_copy = string_copy(server); /* sans password */
- }
- sdata[0] = server; /* What's left at the start */
-
- /* If the database or password is an empty string, set it NULL */
- if (sdata[1][0] == 0) sdata[1] = NULL;
- if (sdata[2][0] == 0) sdata[2] = NULL;
-
- /* See if we have a cached connection to the server */
- for (cn = redis_connections; cn != NULL; cn = cn->next) {
- if (Ustrcmp(cn->server, server_copy) == 0) {
- redis_handle = cn->handle;
- break;
- }
- }
-
- if (cn == NULL) {
- uschar *p;
- uschar *socket = NULL;
- int port = 0;
- /* int redis_err = REDIS_OK; */
-
- if ((p = Ustrchr(sdata[0], '(')) != NULL) {
- *p++ = 0;
- socket = p;
- while (*p != 0 && *p != ')')
- p++;
- *p = 0;
- }
-
- if ((p = Ustrchr(sdata[0], ':')) != NULL) {
- *p++ = 0;
- port = Uatoi(p);
- } else {
- port = Uatoi("6379");
- }
-
- if (Ustrchr(server, '/') != NULL) {
- *errmsg = string_sprintf("unexpected slash in Redis server hostname: %s", sdata[0]);
- *defer_break = TRUE;
- return DEFER;
- }
-
- DEBUG(D_lookup)
- debug_printf("REDIS new connection: host=%s port=%d socket=%s database=%s\n", sdata[0], port, socket, sdata[1]);
-
- /* Get store for a new handle, initialize it, and connect to the server */
- /* XXX: Use timeouts ? */
- if (socket != NULL)
- redis_handle = redisConnectUnix(CCS socket);
- else
- redis_handle = redisConnect(CCS server, port);
- if (redis_handle == NULL) {
- *errmsg = string_sprintf("REDIS connection failed");
- *defer_break = FALSE;
- goto REDIS_EXIT;
- }
-
- /* Add the connection to the cache */
- cn = store_get(sizeof(redis_connection));
- cn->server = server_copy;
- cn->handle = redis_handle;
- cn->next = redis_connections;
- redis_connections = cn;
- } else {
- DEBUG(D_lookup)
- debug_printf("REDIS using cached connection for %s\n", server_copy);
- }
-
- /* Authenticate if there is a password */
- if(sdata[2] != NULL) {
- if ((redis_reply = redisCommand(redis_handle, "AUTH %s", sdata[2])) == NULL) {
- *errmsg = string_sprintf("REDIS Authentication failed: %s\n", redis_handle->errstr);
- *defer_break = FALSE;
- goto REDIS_EXIT;
- }
- }
-
- /* Select the database if there is a dbnumber passed */
- if(sdata[1] != NULL) {
- if ((redis_reply = redisCommand(redis_handle, "SELECT %s", sdata[1])) == NULL) {
- *errmsg = string_sprintf("REDIS: Selecting database=%s failed: %s\n", sdata[1], redis_handle->errstr);
- *defer_break = FALSE;
- goto REDIS_EXIT;
- } else {
- DEBUG(D_lookup) debug_printf("REDIS: Selecting database=%s\n", sdata[1]);
- }
- }
-
- /* Run the command */
- if ((redis_reply = redisCommand(redis_handle, CS command)) == NULL) {
- *errmsg = string_sprintf("REDIS: query failed: %s\n", redis_handle->errstr);
- *defer_break = FALSE;
- goto REDIS_EXIT;
- }
-
- switch (redis_reply->type) {
- case REDIS_REPLY_ERROR:
- *errmsg = string_sprintf("REDIS: lookup result failed: %s\n", redis_reply->str);
- *defer_break = FALSE;
- *do_cache = FALSE;
- goto REDIS_EXIT;
- /* NOTREACHED */
-
- break;
- case REDIS_REPLY_NIL:
- DEBUG(D_lookup) debug_printf("REDIS: query was not one that returned any data\n");
- result = string_sprintf("");
- *do_cache = FALSE;
- goto REDIS_EXIT;
- /* NOTREACHED */
-
- break;
- case REDIS_REPLY_INTEGER:
- ttmp = (redis_reply->integer != 0) ? US"true" : US"false";
- result = string_cat(result, &ssize, &offset, US ttmp, Ustrlen(ttmp));
- break;
- case REDIS_REPLY_STRING:
- case REDIS_REPLY_STATUS:
- result = string_cat(result, &ssize, &offset, US redis_reply->str, redis_reply->len);
- break;
- case REDIS_REPLY_ARRAY:
-
- /* NOTE: For now support 1 nested array result. If needed a limitless result can be parsed */
- for (i = 0; i < redis_reply->elements; i++) {
- entry = redis_reply->element[i];
-
- if (result != NULL)
- result = string_cat(result, &ssize, &offset, US"\n", 1);
-
- switch (entry->type) {
- case REDIS_REPLY_INTEGER:
- tmp = string_sprintf("%d", entry->integer);
- result = string_cat(result, &ssize, &offset, US tmp, Ustrlen(tmp));
- break;
- case REDIS_REPLY_STRING:
- result = string_cat(result, &ssize, &offset, US entry->str, entry->len);
- break;
- case REDIS_REPLY_ARRAY:
- for (j = 0; j < entry->elements; j++) {
- tentry = entry->element[j];
-
- if (result != NULL)
- result = string_cat(result, &ssize, &offset, US"\n", 1);
-
- switch (tentry->type) {
- case REDIS_REPLY_INTEGER:
- ttmp = string_sprintf("%d", tentry->integer);
- result = string_cat(result, &ssize, &offset, US ttmp, Ustrlen(ttmp));
- break;
- case REDIS_REPLY_STRING:
- result = string_cat(result, &ssize, &offset, US tentry->str, tentry->len);
- break;
- case REDIS_REPLY_ARRAY:
- DEBUG(D_lookup) debug_printf("REDIS: result has nesting of arrays which is not supported. Ignoring!\n");
- break;
- default:
- DEBUG(D_lookup) debug_printf("REDIS: result has unsupported type. Ignoring!\n");
- break;
- }
- }
- break;
- default:
- DEBUG(D_lookup) debug_printf("REDIS: query returned unsupported type\n");
- break;
- }
- }
- break;
- }
-
-
- if (result == NULL) {
- yield = FAIL;
- *errmsg = US"REDIS: no data found";
- } else {
- result[offset] = 0;
- store_reset(result + offset + 1);
- }
-
- REDIS_EXIT:
- /* Free store for any result that was got; don't close the connection, as it is cached. */
- if (redis_reply != NULL)
- freeReplyObject(redis_reply);
-
- /* Non-NULL result indicates a sucessful result */
- if (result != NULL) {
- *resultptr = result;
- return OK;
- } else {
- DEBUG(D_lookup) debug_printf("%s\n", *errmsg);
- /* NOTE: Required to close connection since it needs to be reopened */
- return yield; /* FAIL or DEFER */
- }
+redisContext *redis_handle = NULL; /* Keep compilers happy */
+redisReply *redis_reply = NULL;
+redisReply *entry = NULL;
+redisReply *tentry = NULL;
+redis_connection *cn;
+int ssize = 0;
+int offset = 0;
+int yield = DEFER;
+int i, j;
+uschar *result = NULL;
+uschar *server_copy = NULL;
+uschar *tmp, *ttmp;
+uschar *sdata[3];
+
+/* Disaggregate the parameters from the server argument.
+The order is host:port(socket)
+We can write to the string, since it is in a nextinlist temporary buffer.
+This copy is also used for debugging output. */
+
+memset(sdata, 0, sizeof(sdata)) /* Set all to NULL */;
+for (i = 2; i > 0; i--)
+ {
+ uschar *pp = Ustrrchr(server, '/');
+
+ if (!pp)
+ {
+ *errmsg = string_sprintf("incomplete Redis server data: %s",
+ i == 2 ? server : server_copy);
+ *defer_break = TRUE;
+ return DEFER;
+ }
+ *pp++ = 0;
+ sdata[i] = pp;
+ if (i == 2) server_copy = string_copy(server); /* sans password */
+ }
+sdata[0] = server; /* What's left at the start */
+
+/* If the database or password is an empty string, set it NULL */
+if (sdata[1][0] == 0) sdata[1] = NULL;
+if (sdata[2][0] == 0) sdata[2] = NULL;
+
+/* See if we have a cached connection to the server */
+
+for (cn = redis_connections; cn; cn = cn->next)
+ if (Ustrcmp(cn->server, server_copy) == 0)
+ {
+ redis_handle = cn->handle;
+ break;
+ }
+
+if (!cn)
+ {
+ uschar *p;
+ uschar *socket = NULL;
+ int port = 0;
+ /* int redis_err = REDIS_OK; */
+
+ if ((p = Ustrchr(sdata[0], '(')))
+ {
+ *p++ = 0;
+ socket = p;
+ while (*p != 0 && *p != ')') p++;
+ *p = 0;
+ }
+
+ if ((p = Ustrchr(sdata[0], ':')))
+ {
+ *p++ = 0;
+ port = Uatoi(p);
+ }
+ else
+ port = Uatoi("6379");
+
+ if (Ustrchr(server, '/'))
+ {
+ *errmsg = string_sprintf("unexpected slash in Redis server hostname: %s",
+ sdata[0]);
+ *defer_break = TRUE;
+ return DEFER;
+ }
+
+ DEBUG(D_lookup)
+ debug_printf("REDIS new connection: host=%s port=%d socket=%s database=%s\n",
+ sdata[0], port, socket, sdata[1]);
+
+ /* Get store for a new handle, initialize it, and connect to the server */
+ /* XXX: Use timeouts ? */
+ redis_handle =
+ socket ? redisConnectUnix(CCS socket) : redisConnect(CCS server, port);
+ if (!redis_handle)
+ {
+ *errmsg = string_sprintf("REDIS connection failed");
+ *defer_break = FALSE;
+ goto REDIS_EXIT;
+ }
+
+ /* Add the connection to the cache */
+ cn = store_get(sizeof(redis_connection));
+ cn->server = server_copy;
+ cn->handle = redis_handle;
+ cn->next = redis_connections;
+ redis_connections = cn;
+ }
+else
+ {
+ DEBUG(D_lookup)
+ debug_printf("REDIS using cached connection for %s\n", server_copy);
+}
+
+/* Authenticate if there is a password */
+if(sdata[2])
+ if (!(redis_reply = redisCommand(redis_handle, "AUTH %s", sdata[2])))
+ {
+ *errmsg = string_sprintf("REDIS Authentication failed: %s\n", redis_handle->errstr);
+ *defer_break = FALSE;
+ goto REDIS_EXIT;
+ }
+
+/* Select the database if there is a dbnumber passed */
+if(sdata[1])
+ {
+ if (!(redis_reply = redisCommand(redis_handle, "SELECT %s", sdata[1])))
+ {
+ *errmsg = string_sprintf("REDIS: Selecting database=%s failed: %s\n", sdata[1], redis_handle->errstr);
+ *defer_break = FALSE;
+ goto REDIS_EXIT;
+ }
+ DEBUG(D_lookup) debug_printf("REDIS: Selecting database=%s\n", sdata[1]);
+ }
+
+/* split string on whitespace into argv */
+ {
+ uschar * argv[32];
+ int i;
+ const uschar * s = command;
+ int siz, ptr;
+ uschar c;
+
+ while (isspace(*s)) s++;
+
+ for (i = 0; *s && i < nele(argv); i++)
+ {
+ for (argv[i] = NULL, siz = ptr = 0; (c = *s) && !isspace(c); s++)
+ if (c != '\\' || *++s) /* backslash protects next char */
+ argv[i] = string_cat(argv[i], &siz, &ptr, s, 1);
+ *(argv[i]+ptr) = '\0';
+ DEBUG(D_lookup) debug_printf("REDIS: argv[%d] '%s'\n", i, argv[i]);
+ while (isspace(*s)) s++;
+ }
+
+ /* Run the command. We use the argv form rather than plain as that parses
+ into args by whitespace yet has no escaping mechanism. */
+
+ redis_reply = redisCommandArgv(redis_handle, i, (const char **) argv, NULL);
+ if (!redis_reply)
+ {
+ *errmsg = string_sprintf("REDIS: query failed: %s\n", redis_handle->errstr);
+ *defer_break = FALSE;
+ goto REDIS_EXIT;
+ }
+ }
+
+switch (redis_reply->type)
+ {
+ case REDIS_REPLY_ERROR:
+ *errmsg = string_sprintf("REDIS: lookup result failed: %s\n", redis_reply->str);
+ *defer_break = FALSE;
+ *do_cache = 0;
+ goto REDIS_EXIT;
+ /* NOTREACHED */
+
+ case REDIS_REPLY_NIL:
+ DEBUG(D_lookup)
+ debug_printf("REDIS: query was not one that returned any data\n");
+ result = string_sprintf("");
+ *do_cache = 0;
+ goto REDIS_EXIT;
+ /* NOTREACHED */
+
+ case REDIS_REPLY_INTEGER:
+ ttmp = (redis_reply->integer != 0) ? US"true" : US"false";
+ result = string_cat(result, &ssize, &offset, US ttmp, Ustrlen(ttmp));
+ break;
+
+ case REDIS_REPLY_STRING:
+ case REDIS_REPLY_STATUS:
+ result = string_cat(result, &ssize, &offset,
+ US redis_reply->str, redis_reply->len);
+ break;
+
+ case REDIS_REPLY_ARRAY:
+
+ /* NOTE: For now support 1 nested array result. If needed a limitless
+ result can be parsed */
+
+ for (i = 0; i < redis_reply->elements; i++)
+ {
+ entry = redis_reply->element[i];
+
+ if (result)
+ result = string_cat(result, &ssize, &offset, US"\n", 1);
+
+ switch (entry->type)
+ {
+ case REDIS_REPLY_INTEGER:
+ tmp = string_sprintf("%d", entry->integer);
+ result = string_cat(result, &ssize, &offset, US tmp, Ustrlen(tmp));
+ break;
+ case REDIS_REPLY_STRING:
+ result = string_cat(result, &ssize, &offset,
+ US entry->str, entry->len);
+ break;
+ case REDIS_REPLY_ARRAY:
+ for (j = 0; j < entry->elements; j++)
+ {
+ tentry = entry->element[j];
+
+ if (result)
+ result = string_cat(result, &ssize, &offset, US"\n", 1);
+
+ switch (tentry->type)
+ {
+ case REDIS_REPLY_INTEGER:
+ ttmp = string_sprintf("%d", tentry->integer);
+ result = string_cat(result, &ssize, &offset,
+ US ttmp, Ustrlen(ttmp));
+ break;
+ case REDIS_REPLY_STRING:
+ result = string_cat(result, &ssize, &offset,
+ US tentry->str, tentry->len);
+ break;
+ case REDIS_REPLY_ARRAY:
+ DEBUG(D_lookup)
+ debug_printf("REDIS: result has nesting of arrays which"
+ " is not supported. Ignoring!\n");
+ break;
+ default:
+ DEBUG(D_lookup) debug_printf(
+ "REDIS: result has unsupported type. Ignoring!\n");
+ break;
+ }
+ }
+ break;
+ default:
+ DEBUG(D_lookup) debug_printf("REDIS: query returned unsupported type\n");
+ break;
+ }
+ }
+ break;
+ }
+
+
+if (result)
+ {
+ result[offset] = 0;
+ store_reset(result + offset + 1);
+ }
+else
+ {
+ yield = FAIL;
+ *errmsg = US"REDIS: no data found";
+ }
+
+REDIS_EXIT:
+
+/* Free store for any result that was got; don't close the connection,
+as it is cached. */
+
+if (redis_reply) freeReplyObject(redis_reply);
+
+/* Non-NULL result indicates a sucessful result */
+
+if (result)
+ {
+ *resultptr = result;
+ return OK;
+ }
+else
+ {
+ DEBUG(D_lookup) debug_printf("%s\n", *errmsg);
+ /* NOTE: Required to close connection since it needs to be reopened */
+ return yield; /* FAIL or DEFER */
+ }
}
+
+
/*************************************************
* Find entry point *
*************************************************/
*/
static int
-redis_find(void *handle __attribute__((unused)), uschar *filename __attribute__((unused)),
- uschar *command, int length, uschar **result, uschar **errmsg, BOOL *do_cache)
+redis_find(void *handle __attribute__((unused)),
+ uschar *filename __attribute__((unused)),
+ const uschar *command, int length, uschar **result, uschar **errmsg,
+ uint *do_cache)
{
- return lf_sqlperform(US"Redis", US"redis_servers", redis_servers, command,
- result, errmsg, do_cache, perform_redis_search);
+return lf_sqlperform(US"Redis", US"redis_servers", redis_servers, command,
+ result, errmsg, do_cache, perform_redis_search);
}
+
+
+/*************************************************
+* Quote entry point *
+*************************************************/
+
+/* Prefix any whitespace, or backslash, with a backslash.
+This is not a Redis thing but instead to let the argv splitting
+we do to split on whitespace, yet provide means for getting
+whitespace into an argument.
+
+Arguments:
+ s the string to be quoted
+ opt additional option text or NULL if none
+
+Returns: the processed string or NULL for a bad option
+*/
+
+static uschar *
+redis_quote(uschar *s, uschar *opt)
+{
+register int c;
+int count = 0;
+uschar *t = s;
+uschar *quoted;
+
+if (opt) return NULL; /* No options recognized */
+
+while ((c = *t++) != 0)
+ if (isspace(c) || c == '\\') count++;
+
+if (count == 0) return s;
+t = quoted = store_get(Ustrlen(s) + count + 1);
+
+while ((c = *s++) != 0)
+ {
+ if (isspace(c) || c == '\\') *t++ = '\\';
+ *t++ = c;
+ }
+
+*t = 0;
+return quoted;
+}
+
+
/*************************************************
* Version reporting entry point *
*************************************************/
void
redis_version_report(FILE *f)
{
- fprintf(f, "Library version: REDIS: Compile: %d [%d]\n",
+fprintf(f, "Library version: REDIS: Compile: %d [%d]\n",
HIREDIS_MAJOR, HIREDIS_MINOR);
#ifdef DYNLOOKUP
- fprintf(f, " Exim version %s\n", EXIM_VERSION_STR);
+fprintf(f, " Exim version %s\n", EXIM_VERSION_STR);
#endif
}
+
+
/* These are the lookup_info blocks for this driver */
static lookup_info redis_lookup_info = {
US"redis", /* lookup name */
redis_find, /* find function */
NULL, /* no close function */
redis_tidy, /* tidy function */
- NULL, /* quoting function */
+ redis_quote, /* quoting function */
redis_version_report /* version reporting */
};
#ifdef DYNLOOKUP
-#define redis_lookup_module_info _lookup_module_info
+# define redis_lookup_module_info _lookup_module_info
#endif /* DYNLOOKUP */
static lookup_info *_lookup_list[] = { &redis_lookup_info };
lookup_module_info redis_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 1 };
-#endif /* EXPERIMENTAL_REDIS */
+#endif /* LOOKUP_REDIS */
/* End of lookups/redis.c */
#include <spf2/spf_dns_resolv.h>
#include <spf2/spf_dns_cache.h>
-static void *spf_open(uschar *filename, uschar **errmsg) {
+static void *
+spf_open(uschar *filename, uschar **errmsg)
+{
SPF_server_t *spf_server = NULL;
spf_server = SPF_server_new(SPF_DNS_CACHE, 0);
if (spf_server == NULL) {
return (void *) spf_server;
}
-static void spf_close(void *handle) {
+static void
+spf_close(void *handle)
+{
SPF_server_t *spf_server = handle;
if (spf_server) SPF_server_free(spf_server);
}
-static int spf_find(void *handle, uschar *filename, uschar *keystring, int key_len,
- uschar **result, uschar **errmsg, BOOL *do_cache) {
+static int
+spf_find(void *handle, uschar *filename, uschar *keystring, int key_len,
+ uschar **result, uschar **errmsg, uint *do_cache)
+{
SPF_server_t *spf_server = handle;
SPF_request_t *spf_request = NULL;
SPF_response_t *spf_response = NULL;
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
#include "../exim.h"
static int
-sqlite_find(void *handle, uschar *filename, uschar *query, int length,
- uschar **result, uschar **errmsg, BOOL *do_cache)
+sqlite_find(void *handle, uschar *filename, const uschar *query, int length,
+ uschar **result, uschar **errmsg, uint *do_cache)
{
int ret;
struct strbuf res = { NULL, 0, 0 };
return FAIL;
}
-if (res.string == NULL) *do_cache = FALSE;
+if (res.string == NULL) *do_cache = 0;
*result = res.string;
return OK;
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
#include "../exim.h"
/* See local README for interface description. */
static int
-testdb_find(void *handle, uschar *filename, uschar *query, int length,
- uschar **result, uschar **errmsg, BOOL *do_cache)
+testdb_find(void *handle, uschar *filename, const uschar *query, int length,
+ uschar **result, uschar **errmsg, uint *do_cache)
{
handle = handle; /* Keep picky compilers happy */
filename = filename;
return DEFER;
}
-if (Ustrcmp(query, "nocache") == 0) *do_cache = FALSE;
+if (Ustrcmp(query, "nocache") == 0) *do_cache = 0;
*result = string_copy(query);
return OK;
static int
whoson_find(void *handle, uschar *filename, uschar *query, int length,
- uschar **result, uschar **errmsg, BOOL *do_cache)
+ uschar **result, uschar **errmsg, uint *do_cache)
{
uschar buffer[80];
handle = handle; /* Keep picky compilers happy */
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Support functions for calling from local_scan(). These are mostly just
int
lss_match_domain(uschar *domain, uschar *list)
{
-return match_isinlist(domain, &list, 0, &domainlist_anchor, NULL, MCL_DOMAIN,
+return match_isinlist(CUS domain, CUSS &list, 0, &domainlist_anchor, NULL, MCL_DOMAIN,
TRUE, NULL);
}
int
lss_match_local_part(uschar *local_part, uschar *list, BOOL caseless)
{
-return match_isinlist(local_part, &list, 0, &localpartlist_anchor, NULL,
+return match_isinlist(CUS local_part, CUSS &list, 0, &localpartlist_anchor, NULL,
MCL_LOCALPART, caseless, NULL);
}
int
lss_match_address(uschar *address, uschar *list, BOOL caseless)
{
-return match_address_list(address, caseless, TRUE, &list, NULL, -1, 0, NULL);
+return match_address_list(CUS address, caseless, TRUE, CUSS &list, NULL, -1, 0, NULL);
}
int
lss_match_host(uschar *host_name, uschar *host_address, uschar *list)
{
-return verify_check_this_host(&list, NULL, host_name, host_address, NULL);
+return verify_check_this_host(CUSS &list, NULL, host_name, host_address, NULL);
}
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
#define mac_string(s) # s
#define mac_expanded_string(s) mac_string(s)
+/* Number of elements of an array */
+#define nelem(arr) (sizeof(arr) / sizeof(*arr))
+
/* When running in the test harness, the load average is fudged. */
#define DEBUG(x) if ((debug_selector & (x)) != 0)
#define HDEBUG(x) if (host_checking || (debug_selector & (x)) != 0)
+#define PTR_CHK(ptr) \
+do { \
+if ((void *)ptr > (void *)store_get(0)) \
+ debug_printf("BUG: ptr '%s' beyond arena at %s:%d\n", \
+ mac_expanded_string(ptr), __FUNCTION__, __LINE__); \
+} while(0)
+
/* The default From: text for DSNs */
#define DEFAULT_DSN_FROM "Mail Delivery System <Mailer-Daemon@$qualify_domain>"
as long as the maximum path length. */
#if defined PATH_MAX && PATH_MAX > 16384
-#define BIG_BUFFER_SIZE PATH_MAX
+# define BIG_BUFFER_SIZE PATH_MAX
#elif defined MAXPATHLEN && MAXPATHLEN > 16384
-#define BIG_BUFFER_SIZE MAXPATHLEN
+# define BIG_BUFFER_SIZE MAXPATHLEN
#else
-#define BIG_BUFFER_SIZE 16384
+# define BIG_BUFFER_SIZE 16384
#endif
-/* header size of pipe content
+/* header size of pipe content
currently: char id, char subid, char[5] length */
#define PIPE_HEADER_SIZE 7
/* Wait this long before determining that a Proxy Protocol configured
host isn't speaking the protocol, and so is disallowed. Can be moved to
runtime configuration if per site settings become needed. */
-#ifdef EXPERIMENTAL_PROXY
+#ifdef SUPPORT_PROXY
#define PROXY_NEGOTIATION_TIMEOUT_SEC 3
#define PROXY_NEGOTIATION_TIMEOUT_USEC 0
#endif
#define END_SIZE 4 /* Reading ended because message too big */
#define END_WERROR 5 /* Write error while reading the message */
-/* Options bits for debugging; D_v and D_local_scan are also in local_scan.h */
-
-#define D_v 0x00000001
-#define D_local_scan 0x00000002
-
-#define D_acl 0x00000004
-#define D_auth 0x00000008
-#define D_deliver 0x00000010
-#define D_dns 0x00000020
-#define D_dnsbl 0x00000040
-#define D_exec 0x00000080
-#define D_expand 0x00000100
-#define D_filter 0x00000200
-#define D_hints_lookup 0x00000400
-#define D_host_lookup 0x00000800
-#define D_ident 0x00001000
-#define D_interface 0x00002000
-#define D_lists 0x00004000
-#define D_load 0x00008000
-#define D_lookup 0x00010000
-#define D_memory 0x00020000
-#define D_pid 0x00040000
-#define D_process_info 0x00080000
-#define D_queue_run 0x00100000
-#define D_receive 0x00200000
-#define D_resolver 0x00400000
-#define D_retry 0x00800000
-#define D_rewrite 0x01000000
-#define D_route 0x02000000
-#define D_timestamp 0x04000000
-#define D_tls 0x08000000
-#define D_transport 0x10000000
-#define D_uid 0x20000000
-#define D_verify 0x40000000
-
-/* The D_all value must always have all bits set, as it is recognized specially
-by the function that decodes debug and log selectors. This is to enable it to
-set all the bits in a multi-word selector. Debug doesn't use this yet, but we
-are getting close. In fact, we want to omit "memory" for -d+all, but can't
-handle this here. It is fudged externally. */
+/* Bit masks for debug and log selectors */
+
+/* Assume words are 32 bits wide. Tiny waste of space on 64 bit
+platforms, but this ensures bit vectors always work the same way. */
+#define BITWORDSIZE 32
+
+/* This macro is for single-word bit vectors: the debug selector,
+and the first word of the log selector. */
+#define BIT(n) (1 << (n))
+
+/* And these are for multi-word vectors. */
+#define BITWORD(n) ( (n) / BITWORDSIZE)
+#define BITMASK(n) (1 << (n) % BITWORDSIZE)
+
+#define BIT_CLEAR(s,z,n) ((s)[BITWORD(n)] &= ~BITMASK(n))
+#define BIT_SET(s,z,n) ((s)[BITWORD(n)] |= BITMASK(n))
+#define BIT_TEST(s,z,n) (((s)[BITWORD(n)] & BITMASK(n)) != 0)
+
+/* Used in globals.c for initializing bit_table structures. T will be either
+D or L correspondong to the debug and log selector bits declared below. */
+
+#define BIT_TABLE(T,name) { US #name, T##i_##name }
+
+/* IOTA allows us to keep an implicit sequential count, like a simple enum,
+but we can have sequentially numbered identifiers which are not declared
+sequentially. We use this for more compact declarations of bit indexes and
+masks, alternating between sequential bit index and corresponding mask. */
+
+#define IOTA(iota) (__LINE__ - iota)
+#define IOTA_INIT(zero) (__LINE__ - zero + 1)
+
+/* Options bits for debugging. DEBUG_BIT() declares both a bit index and the
+corresponding mask. Di_all is a special value recognized by decode_bits().
+
+Exim's code assumes in a number of places that the debug_selector is one
+word, and this is exposed in the local_scan ABI. The D_v and D_local_scan bit
+masks are part of the local_scan API so are #defined in local_scan.h */
+
+#define DEBUG_BIT(name) Di_##name = IOTA(Di_iota), D_##name = BIT(Di_##name)
+
+enum {
+ Di_all = -1,
+ Di_v = 0,
+ Di_local_scan = 1,
+
+ Di_iota = IOTA_INIT(2),
+ DEBUG_BIT(acl),
+ DEBUG_BIT(auth),
+ DEBUG_BIT(deliver),
+ DEBUG_BIT(dns),
+ DEBUG_BIT(dnsbl),
+ DEBUG_BIT(exec),
+ DEBUG_BIT(expand),
+ DEBUG_BIT(filter),
+ DEBUG_BIT(hints_lookup),
+ DEBUG_BIT(host_lookup),
+ DEBUG_BIT(ident),
+ DEBUG_BIT(interface),
+ DEBUG_BIT(lists),
+ DEBUG_BIT(load),
+ DEBUG_BIT(lookup),
+ DEBUG_BIT(memory),
+ DEBUG_BIT(pid),
+ DEBUG_BIT(process_info),
+ DEBUG_BIT(queue_run),
+ DEBUG_BIT(receive),
+ DEBUG_BIT(resolver),
+ DEBUG_BIT(retry),
+ DEBUG_BIT(rewrite),
+ DEBUG_BIT(route),
+ DEBUG_BIT(timestamp),
+ DEBUG_BIT(tls),
+ DEBUG_BIT(transport),
+ DEBUG_BIT(uid),
+ DEBUG_BIT(verify),
+};
+
+/* Multi-bit debug masks */
#define D_all 0xffffffff
D_timestamp | \
D_resolver))
-/* Options bits for logging. Those that will end up in log_write_selector have
-values < 0x80000000. They can be used in calls to log_write(). The others have
-values > 0x80000000 and are put into log_extra_selector (without the top bit).
-These are only ever tested independently. "All" is a magic value that is used
-only in the name table to set all options in both bit maps. */
-
-/* The L_all value must always have all bits set, as it is recognized specially
-by the function that decodes debug and log selectors. This is to enable it to
-set all the bits in a multi-word selector. */
-
-#define L_all 0xffffffff
-
-#define L_address_rewrite 0x00000001
-#define L_all_parents 0x00000002
-#define L_connection_reject 0x00000004
-#define L_delay_delivery 0x00000008
-#define L_dnslist_defer 0x00000010
-#define L_etrn 0x00000020
-#define L_host_lookup_failed 0x00000040
-#define L_lost_incoming_connection 0x00000080
-#define L_queue_run 0x00000100
-#define L_retry_defer 0x00000200
-#define L_size_reject 0x00000400
-#define L_skip_delivery 0x00000800
-#define L_smtp_connection 0x00001000
-#define L_smtp_incomplete_transaction 0x00002000
-#define L_smtp_protocol_error 0x00004000
-#define L_smtp_syntax_error 0x00008000
-
-#define LX_acl_warn_skipped 0x80000001
-#define LX_arguments 0x80000002
-#define LX_deliver_time 0x80000004
-#define LX_delivery_size 0x80000008
-#define LX_ident_timeout 0x80000010
-#define LX_incoming_interface 0x80000020
-#define LX_incoming_port 0x80000040
-#define LX_outgoing_port 0x80000080
-#define LX_pid 0x80000100
-#define LX_queue_time 0x80000200
-#define LX_queue_time_overall 0x80000400
-#define LX_received_sender 0x80000800
-#define LX_received_recipients 0x80001000
-#define LX_rejected_header 0x80002000
-#define LX_return_path_on_delivery 0x80004000
-#define LX_sender_on_delivery 0x80008000
-#define LX_sender_verify_fail 0x80010000
-#define LX_smtp_confirmation 0x80020000
-#define LX_smtp_no_mail 0x80040000
-#define LX_subject 0x80080000
-#define LX_tls_certificate_verified 0x80100000
-#define LX_tls_cipher 0x80200000
-#define LX_tls_peerdn 0x80400000
-#define LX_tls_sni 0x80800000
-#define LX_unknown_in_list 0x81000000
-#define LX_8bitmime 0x82000000
-#define LX_smtp_mailauth 0x84000000
-#define LX_proxy 0x88000000
-
-#define L_default (L_connection_reject | \
- L_delay_delivery | \
- L_dnslist_defer | \
- L_etrn | \
- L_host_lookup_failed | \
- L_lost_incoming_connection | \
- L_queue_run | \
- L_retry_defer | \
- L_size_reject | \
- L_skip_delivery)
-
-#define LX_default ((LX_acl_warn_skipped | \
- LX_rejected_header | \
- LX_sender_verify_fail | \
- LX_smtp_confirmation | \
- LX_tls_certificate_verified| \
- LX_tls_cipher) & 0x7fffffff)
+/* Options bits for logging. Those that have values < BITWORDSIZE can be used
+in calls to log_write(). The others are put into later words in log_selector
+and are only ever tested independently, so they do not need bit mask
+declarations. The Li_all value is recognized specially by decode_bits(). */
+
+#define LOG_BIT(name) Li_##name = IOTA(Li_iota), L_##name = BIT(Li_##name)
+
+enum {
+ Li_all = -1,
+
+ Li_iota = IOTA_INIT(0),
+ LOG_BIT(address_rewrite),
+ LOG_BIT(all_parents),
+ LOG_BIT(connection_reject),
+ LOG_BIT(delay_delivery),
+ LOG_BIT(dnslist_defer),
+ LOG_BIT(etrn),
+ LOG_BIT(host_lookup_failed),
+ LOG_BIT(lost_incoming_connection),
+ LOG_BIT(queue_run),
+ LOG_BIT(retry_defer),
+ LOG_BIT(size_reject),
+ LOG_BIT(skip_delivery),
+ LOG_BIT(smtp_connection),
+ LOG_BIT(smtp_incomplete_transaction),
+ LOG_BIT(smtp_protocol_error),
+ LOG_BIT(smtp_syntax_error),
+
+ Li_acl_warn_skipped = BITWORDSIZE,
+ Li_arguments,
+ Li_deliver_time,
+ Li_delivery_size,
+ Li_ident_timeout,
+ Li_incoming_interface,
+ Li_incoming_port,
+ Li_outgoing_port,
+ Li_pid,
+ Li_queue_time,
+ Li_queue_time_overall,
+ Li_received_sender,
+ Li_received_recipients,
+ Li_rejected_header,
+ Li_return_path_on_delivery,
+ Li_sender_on_delivery,
+ Li_sender_verify_fail,
+ Li_smtp_confirmation,
+ Li_smtp_no_mail,
+ Li_subject,
+ Li_tls_certificate_verified,
+ Li_tls_cipher,
+ Li_tls_peerdn,
+ Li_tls_sni,
+ Li_unknown_in_list,
+ Li_8bitmime,
+ Li_smtp_mailauth,
+ Li_proxy,
+ Li_outgoing_interface,
+
+ log_selector_size = BITWORD(Li_outgoing_interface) + 1
+};
+
+#define LOGGING(opt) BIT_TEST(log_selector, log_selector_size, Li_##opt)
/* Private error numbers for delivery failures, set negative so as not
to conflict with system errno values. */
#define ERRNO_UIDFAIL (-29) /* Failed to get uid */
#define ERRNO_BADTRANSPORT (-30) /* Unset or non-existent transport */
#define ERRNO_MBXLENGTH (-31) /* MBX length mismatch */
-#define ERRNO_UNKNOWNHOST (-32) /* Lookup failed in smtp transport */
+#define ERRNO_UNKNOWNHOST (-32) /* Lookup failed routing or in smtp tpt */
#define ERRNO_FORMATUNKNOWN (-33) /* Can't match format in appendfile */
#define ERRNO_BADCREATE (-34) /* Creation outside home in appendfile */
#define ERRNO_LISTDEFER (-35) /* Can't check a list; lookup defer */
#define ERRNO_MAIL4XX (-45) /* MAIL gave 4xx error */
#define ERRNO_DATA4XX (-46) /* DATA gave 4xx error */
#define ERRNO_PROXYFAIL (-47) /* Negotiation failed for proxy configured host */
-#define ERRNO_AUTHPROB (-48) /* Autheticator "other" failure */
+#define ERRNO_AUTHPROB (-48) /* Authenticator "other" failure */
+
+#ifdef SUPPORT_I18N
+# define ERRNO_UTF8_FWD (-49) /* target not supporting SMTPUTF8 */
+#endif
/* These must be last, so all retry deferments can easily be identified */
#define ERRNO_HRETRY (-53) /* Not time for any remote host */
#define ERRNO_LOCAL_ONLY (-54) /* Local-only delivery */
#define ERRNO_QUEUE_DOMAIN (-55) /* Domain in queue_domains */
+#define ERRNO_TRETRY (-56) /* Transport concurrency limit */
/* Special actions to take after failure or deferment. */
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) Tom Kistner <tom@duncanthrax.net> 2003-2014 */
+/* Copyright (c) Tom Kistner <tom@duncanthrax.net> 2003 - 2015 */
/* License: GPL */
/* Code for calling virus (malware) scanners. Called from acl.c. */
/* The maximum number of clamd servers that are supported in the configuration */
#define MAX_CLAMD_SERVERS 32
#define MAX_CLAMD_SERVERS_S "32"
-/* Maximum length of the hostname that can be specified in the clamd address list */
-#define MAX_CLAMD_ADDRESS_LENGTH 64
-#define MAX_CLAMD_ADDRESS_LENGTH_S "64"
-typedef struct clamd_address_container {
- uschar tcp_addr[MAX_CLAMD_ADDRESS_LENGTH+1];
- unsigned int tcp_port;
-} clamd_address_container;
+typedef struct clamd_address {
+ uschar * hostspec;
+ unsigned tcp_port;
+ unsigned retry;
+} clamd_address;
#ifndef nelements
# define nelements(arr) (sizeof(arr) / sizeof(arr[0]))
static inline int
malware_errlog_defer(const uschar * str)
{
- log_write(0, LOG_MAIN|LOG_PANIC, "malware acl condition: %s", str);
- return DEFER;
+log_write(0, LOG_MAIN|LOG_PANIC, "malware acl condition: %s", str);
+return DEFER;
}
static int
-m_errlog_defer(struct scan * scanent, const uschar * str)
+m_errlog_defer(struct scan * scanent, const uschar * hostport,
+ const uschar * str)
{
- return malware_errlog_defer(string_sprintf("%s: %s", scanent->name, str));
+return malware_errlog_defer(string_sprintf("%s %s : %s",
+ scanent->name, hostport ? hostport : CUS"", str));
}
static int
-m_errlog_defer_3(struct scan * scanent, const uschar * str,
- int fd_to_close)
+m_errlog_defer_3(struct scan * scanent, const uschar * hostport,
+ const uschar * str, int fd_to_close)
{
- (void) close(fd_to_close);
- return m_errlog_defer(scanent, str);
+(void) close(fd_to_close);
+return m_errlog_defer(scanent, hostport, str);
}
/*************************************************/
m_tcpsocket(const uschar * hostname, unsigned int port,
host_item * host, uschar ** errstr)
{
- return ip_connectedsocket(SOCK_STREAM, hostname, port, port, 5, host, errstr);
-}
-
-static int
-m_tcpsocket_fromdef(const uschar * hostport, uschar ** errstr)
-{
- int scan;
- uschar hostname[256];
- unsigned int portlow, porthigh;
-
- /* extract host and port part */
- scan = sscanf(CS hostport, "%255s %u-%u", hostname, &portlow, &porthigh);
- if ( scan != 3 ) {
- if ( scan != 2 ) {
- *errstr = string_sprintf("invalid socket '%s'", hostport);
- return -1;
- }
- porthigh = portlow;
- }
-
- return ip_connectedsocket(SOCK_STREAM, hostname, portlow, porthigh,
- 5, NULL, errstr);
-}
-
-static int
-m_unixsocket(const uschar * path, uschar ** errstr)
-{
- int sock;
- struct sockaddr_un server;
-
- if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
- *errstr = US"can't open UNIX socket.";
- return -1;
- }
-
- server.sun_family = AF_UNIX;
- Ustrncpy(server.sun_path, path, sizeof(server.sun_path)-1);
- server.sun_path[sizeof(server.sun_path)-1] = '\0';
- if (connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0) {
- int err = errno;
- (void)close(sock);
- *errstr = string_sprintf("unable to connect to UNIX socket (%s): %s",
- path, strerror(err));
- return -1;
- }
- return sock;
-}
-
-static inline int
-m_streamsocket(const uschar * spec, uschar ** errstr)
-{
- return *spec == '/'
- ? m_unixsocket(spec, errstr) : m_tcpsocket_fromdef(spec, errstr);
+return ip_connectedsocket(SOCK_STREAM, hostname, port, port, 5, host, errstr);
}
static int
m_sock_send(int sock, uschar * buf, int cnt, uschar ** errstr)
{
- if (send(sock, buf, cnt, 0) < 0) {
- int err = errno;
- (void)close(sock);
- *errstr = string_sprintf("unable to send to socket (%s): %s",
- buf, strerror(err));
- return -1;
- }
- return sock;
+if (send(sock, buf, cnt, 0) < 0)
+ {
+ int err = errno;
+ (void)close(sock);
+ *errstr = string_sprintf("unable to send to socket (%s): %s",
+ buf, strerror(err));
+ return -1;
+ }
+return sock;
}
static const pcre *
m_pcre_compile(const uschar * re, uschar ** errstr)
{
- const uschar * rerror;
- int roffset;
- const pcre * cre;
-
- cre = pcre_compile(CS re, PCRE_COPT, (const char **)&rerror, &roffset, NULL);
- if (!cre)
- *errstr= string_sprintf("regular expression error in '%s': %s at offset %d",
- re, rerror, roffset);
- return cre;
+const uschar * rerror;
+int roffset;
+const pcre * cre;
+
+cre = pcre_compile(CS re, PCRE_COPT, (const char **)&rerror, &roffset, NULL);
+if (!cre)
+ *errstr= string_sprintf("regular expression error in '%s': %s at offset %d",
+ re, rerror, roffset);
+return cre;
}
uschar *
m_pcre_exec(const pcre * cre, uschar * text)
{
- int ovector[10*3];
- int i = pcre_exec(cre, NULL, CS text, Ustrlen(text), 0, 0,
- ovector, nelements(ovector));
- uschar * substr = NULL;
- if (i >= 2) /* Got it */
- pcre_get_substring(CS text, ovector, i, 1, (const char **) &substr);
- return substr;
+int ovector[10*3];
+int i = pcre_exec(cre, NULL, CS text, Ustrlen(text), 0, 0,
+ ovector, nelements(ovector));
+uschar * substr = NULL;
+if (i >= 2) /* Got it */
+ pcre_get_substring(CS text, ovector, i, 1, (const char **) &substr);
+return substr;
}
static const pcre *
-m_pcre_nextinlist(uschar ** list, int * sep, char * listerr, uschar ** errstr)
+m_pcre_nextinlist(const uschar ** list, int * sep,
+ char * listerr, uschar ** errstr)
{
- const uschar * list_ele;
- const pcre * cre = NULL;
+const uschar * list_ele;
+const pcre * cre = NULL;
- if (!(list_ele = string_nextinlist(list, sep, NULL, 0)))
- *errstr = US listerr;
- else
- cre = m_pcre_compile(CUS list_ele, errstr);
- return cre;
+if (!(list_ele = string_nextinlist(list, sep, NULL, 0)))
+ *errstr = US listerr;
+else
+ cre = m_pcre_compile(CUS list_ele, errstr);
+return cre;
}
/*
case 'A': /* ERR */
if ((p = strchr (line, '\n')) != NULL)
*p = '\0';
- return m_errlog_defer(scanent,
+ return m_errlog_defer(scanent, NULL,
string_sprintf("scanner failed: %s", line));
default: /* VIR */
return OK;
}
}
- return m_errlog_defer(scanent,
+ return m_errlog_defer(scanent, NULL,
string_sprintf("malformed reply received: %s", line));
}
}
return mksd_parse_line (scanent, CS av_buffer);
}
+
+static int
+clamd_option(clamd_address * cd, const uschar * optstr, int * subsep)
+{
+uschar * s;
+
+cd->retry = 0;
+while ((s = string_nextinlist(&optstr, subsep, NULL, 0)))
+ if (Ustrncmp(s, "retry=", 6) == 0)
+ {
+ int sec = readconf_readtime((s += 6), '\0', FALSE);
+ if (sec < 0)
+ return FAIL;
+ cd->retry = sec;
+ }
+ else
+ return FAIL;
+return OK;
+}
+
/*************************************************
* Scan content for malware *
*************************************************/
int timeout, BOOL faking)
{
int sep = 0;
-uschar *av_scanner_work = av_scanner;
+const uschar *av_scanner_work = av_scanner;
uschar *scanner_name;
unsigned long mbox_size;
FILE *mbox_file;
if (!timeout) timeout = MALWARE_TIMEOUT;
tmo = time(NULL) + timeout;
- for (scanent = m_scans; ; scanent++) {
+ for (scanent = m_scans; ; scanent++)
+ {
if (!scanent->name)
return malware_errlog_defer(string_sprintf("unknown scanner type '%s'",
scanner_name));
break;
switch(scanent->conn)
{
- case MC_TCP: sock = m_tcpsocket_fromdef(scanner_options, &errstr); break;
- case MC_UNIX: sock = m_unixsocket(scanner_options, &errstr); break;
- case MC_STRM: sock = m_streamsocket(scanner_options, &errstr); break;
+ case MC_TCP: sock = ip_tcpsocket(scanner_options, &errstr, 5); break;
+ case MC_UNIX: sock = ip_unixsocket(scanner_options, &errstr); break;
+ case MC_STRM: sock = ip_streamsocket(scanner_options, &errstr, 5); break;
default: /* compiler quietening */ break;
}
if (sock < 0)
- return m_errlog_defer(scanent, errstr);
+ return m_errlog_defer(scanent, CUS callout_address, errstr);
break;
}
DEBUG(D_acl) debug_printf("Malware scan: %s tmo %s\n", scanner_name, readconf_printtime(timeout));
/* send scan request */
if (m_sock_send(sock, scanrequest, Ustrlen(scanrequest)+1, &errstr) < 0)
- return m_errlog_defer(scanent, errstr);
+ return m_errlog_defer(scanent, CUS callout_address, errstr);
while ((len = recv_line(sock, buf, sizeof(buf), tmo)) >= 0)
if (len > 0)
{
/* calc file size */
if ((drweb_fd = open(CCS eml_filename, O_RDONLY)) == -1)
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, NULL,
string_sprintf("can't open spool file %s: %s",
eml_filename, strerror(errno)),
sock);
{
int err = errno;
(void)close(drweb_fd);
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, NULL,
string_sprintf("can't seek spool file %s: %s",
eml_filename, strerror(err)),
sock);
if ((off_t)fsize_uint != fsize)
{
(void)close(drweb_fd);
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, NULL,
string_sprintf("seeking spool file %s, size overflow",
eml_filename),
sock);
(send(sock, &drweb_slen, sizeof(drweb_slen), 0) < 0))
{
(void)close(drweb_fd);
- return m_errlog_defer_3(scanent, string_sprintf(
+ return m_errlog_defer_3(scanent, CUS callout_address, string_sprintf(
"unable to send commands to socket (%s)", scanner_options),
sock);
}
if (!(drweb_fbuf = (uschar *) malloc (fsize_uint)))
{
(void)close(drweb_fd);
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, NULL,
string_sprintf("unable to allocate memory %u for file (%s)",
fsize_uint, eml_filename),
sock);
int err = errno;
(void)close(drweb_fd);
free(drweb_fbuf);
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, NULL,
string_sprintf("can't read spool file %s: %s",
eml_filename, strerror(err)),
sock);
if (send(sock, drweb_fbuf, fsize, 0) < 0)
{
free(drweb_fbuf);
- return m_errlog_defer_3(scanent, string_sprintf(
+ return m_errlog_defer_3(scanent, CUS callout_address, string_sprintf(
"unable to send file body to socket (%s)", scanner_options),
sock);
}
(send(sock, &drweb_slen, sizeof(drweb_slen), 0) < 0) ||
(send(sock, eml_filename, Ustrlen(eml_filename), 0) < 0) ||
(send(sock, &drweb_fin, sizeof(drweb_fin), 0) < 0))
- return m_errlog_defer_3(scanent, string_sprintf(
+ return m_errlog_defer_3(scanent, CUS callout_address, string_sprintf(
"unable to send commands to socket (%s)", scanner_options),
sock);
}
/* wait for result */
if (!recv_len(sock, &drweb_rc, sizeof(drweb_rc), tmo))
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, CUS callout_address,
US"unable to read return code", sock);
drweb_rc = ntohl(drweb_rc);
if (!recv_len(sock, &drweb_vnum, sizeof(drweb_vnum), tmo))
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, CUS callout_address,
US"unable to read the number of viruses", sock);
drweb_vnum = ntohl(drweb_vnum);
int size = 0, off = 0, ovector[10*3];
/* read the size of report */
if (!recv_len(sock, &drweb_slen, sizeof(drweb_slen), tmo))
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, CUS callout_address,
US"cannot read report size", sock);
drweb_slen = ntohl(drweb_slen);
tmpbuf = store_get(drweb_slen);
/* read report body */
if (!recv_len(sock, tmpbuf, drweb_slen, tmo))
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, CUS callout_address,
US"cannot read report string", sock);
tmpbuf[drweb_slen] = '\0';
* DERR_CRC_ERROR, DERR_READSOCKET, DERR_WRITE_ERR
* and others are ignored */
if (drweb_s)
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, CUS callout_address,
string_sprintf("drweb daemon retcode 0x%x (%s)", drweb_rc, drweb_s),
sock);
recv_line(sock, buf, sizeof(buf), tmo);
if (buf[0] != '2') /* aveserver is having problems */
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, CUS callout_address,
string_sprintf("unavailable (Responded: %s).",
((buf[0] != 0) ? buf : (uschar *)"nothing") ),
sock);
DEBUG(D_acl) debug_printf("Malware scan: issuing %s %s\n",
scanner_name, buf);
if (m_sock_send(sock, buf, Ustrlen(buf), &errstr) < 0)
- return m_errlog_defer(scanent, errstr);
+ return m_errlog_defer(scanent, CUS callout_address, errstr);
malware_name = NULL;
result = 0;
break;
if (buf[0] == '5') /* aveserver is having problems */
{
- result = m_errlog_defer(scanent,
+ result = m_errlog_defer(scanent, CUS callout_address,
string_sprintf("unable to scan file %s (Responded: %s).",
eml_filename, buf));
break;
}
if (m_sock_send(sock, US"quit\r\n", 6, &errstr) < 0)
- return m_errlog_defer(scanent, errstr);
+ return m_errlog_defer(scanent, CUS callout_address, errstr);
/* read aveserver's greeting and see if it is ready (2xx greeting) */
buf[0] = 0;
recv_line(sock, buf, sizeof(buf), tmo);
if (buf[0] != '2') /* aveserver is having problems */
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, CUS callout_address,
string_sprintf("unable to quit dialogue (Responded: %s).",
((buf[0] != 0) ? buf : (uschar *)"nothing") ),
sock);
{
if (m_sock_send(sock, cmdopt[i], Ustrlen(cmdopt[i]), &errstr) < 0)
- return m_errlog_defer(scanent, errstr);
+ return m_errlog_defer(scanent, CUS callout_address, errstr);
bread = ip_recv(sock, av_buffer, sizeof(av_buffer), tmo-time(NULL));
if (bread > 0) av_buffer[bread]='\0';
if (bread < 0)
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, CUS callout_address,
string_sprintf("unable to read answer %d (%s)", i, strerror(errno)),
sock);
for (j = 0; j < bread; j++)
file_name = string_sprintf("SCAN\t%s\n", eml_filename);
if (m_sock_send(sock, file_name, Ustrlen(file_name), &errstr) < 0)
- return m_errlog_defer(scanent, errstr);
+ return m_errlog_defer(scanent, CUS callout_address, errstr);
/* set up match */
/* todo also SUSPICION\t */
for (;;)
{
- errno = ETIME;
+ errno = ETIMEDOUT;
i = av_buffer+sizeof(av_buffer)-p;
if ((bread= ip_recv(sock, p, i-1, tmo-time(NULL))) < 0)
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, CUS callout_address,
string_sprintf("unable to read result (%s)", strerror(errno)),
sock);
- for (p[bread] = '\0'; q = strchr(p, '\n'); p = q+1)
+ for (p[bread] = '\0'; (q = Ustrchr(p, '\n')); p = q+1)
{
*q = '\0';
uschar tmpbuf[1024];
uschar * scanrequest;
int kav_rc;
- unsigned long kav_reportlen, bread;
+ unsigned long kav_reportlen;
+ int bread;
const pcre *kav_re;
uschar *p;
/* send scan request */
if (m_sock_send(sock, scanrequest, Ustrlen(scanrequest)+1, &errstr) < 0)
- return m_errlog_defer(scanent, errstr);
+ return m_errlog_defer(scanent, CUS callout_address, errstr);
/* wait for result */
if (!recv_len(sock, tmpbuf, 2, tmo))
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, CUS callout_address,
US"unable to read 2 bytes from socket.", sock);
/* get errorcode from one nibble */
switch(kav_rc)
{
case 5: case 6: /* improper kavdaemon configuration */
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, CUS callout_address,
US"please reconfigure kavdaemon to NOT disinfect or remove infected files.",
sock);
case 1:
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, CUS callout_address,
US"reported 'scanning not completed' (code 1).", sock);
case 7:
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, CUS callout_address,
US"reported 'kavdaemon damaged' (code 7).", sock);
}
{
/* read report size */
if (!recv_len(sock, &kav_reportlen, 4, tmo))
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, CUS callout_address,
US"cannot read report size", sock);
/* it's possible that avp returns av_buffer[1] == 1 but the
uschar *p;
if (!cmdline_scanner)
- return m_errlog_defer(scanent, errstr);
+ return m_errlog_defer(scanent, NULL, errstr);
/* find scanner output trigger */
cmdline_trigger_re = m_pcre_nextinlist(&av_scanner_work, &sep,
"missing trigger specification", &errstr);
if (!cmdline_trigger_re)
- return m_errlog_defer(scanent, errstr);
+ return m_errlog_defer(scanent, NULL, errstr);
/* find scanner name regex */
cmdline_regex_re = m_pcre_nextinlist(&av_scanner_work, &sep,
"missing virus name regex specification", &errstr);
if (!cmdline_regex_re)
- return m_errlog_defer(scanent, errstr);
+ return m_errlog_defer(scanent, NULL, errstr);
/* prepare scanner call; despite the naming, file_name holds a directory
name which is documented as the value given to %s. */
{
int err = errno;
signal(SIGCHLD,eximsigchld); signal(SIGPIPE,eximsigpipe);
- return m_errlog_defer(scanent,
+ return m_errlog_defer(scanent, NULL,
string_sprintf("call (%s) failed: %s.", commandline, strerror(err)));
}
scanner_fd = fileno(scanner_out);
int err = errno;
(void) pclose(scanner_out);
signal(SIGCHLD,eximsigchld); signal(SIGPIPE,eximsigpipe);
- return m_errlog_defer(scanent, string_sprintf(
+ return m_errlog_defer(scanent, NULL, string_sprintf(
"opening scanner output file (%s) failed: %s.",
file_name, strerror(err)));
}
sizeof(linebuffer), tmo)))
{
if (rcnt < 0)
+ {
+ int err = errno;
if (rcnt == -1)
break;
- else
- {
- int err = errno;
- (void) pclose(scanner_out);
- signal(SIGCHLD,eximsigchld); signal(SIGPIPE,eximsigpipe);
- return m_errlog_defer(scanent, string_sprintf(
- "unable to read from scanner (%s): %s",
- commandline, strerror(err)));
- }
+ (void) pclose(scanner_out);
+ signal(SIGCHLD,eximsigchld); signal(SIGPIPE,eximsigpipe);
+ return m_errlog_defer(scanent, NULL, string_sprintf(
+ "unable to read from scanner (%s): %s",
+ commandline, strerror(err)));
+ }
if (Ustrlen(linebuffer) > fwrite(linebuffer, 1, Ustrlen(linebuffer), scanner_record))
{
/* short write */
(void) pclose(scanner_out);
signal(SIGCHLD,eximsigchld); signal(SIGPIPE,eximsigpipe);
- return m_errlog_defer(scanent, string_sprintf(
+ return m_errlog_defer(scanent, NULL, string_sprintf(
"short write on scanner output file (%s).", file_name));
}
putc('\n', scanner_record);
sep = pclose(scanner_out);
signal(SIGCHLD,eximsigchld); signal(SIGPIPE,eximsigpipe);
if (sep != 0)
- return m_errlog_defer(scanent,
+ return m_errlog_defer(scanent, NULL,
sep == -1
? string_sprintf("running scanner failed: %s", strerror(sep))
: string_sprintf("scanner returned error code: %d", sep));
if ( write(sock, file_name, Ustrlen(file_name)) < 0
|| write(sock, "\n", 1) != 1
)
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, CUS callout_address,
string_sprintf("unable to write to UNIX socket (%s)", scanner_options),
sock);
/* wait for result */
memset(av_buffer, 0, sizeof(av_buffer));
if ((bread = ip_recv(sock, av_buffer, sizeof(av_buffer), tmo-time(NULL))) <= 0)
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, CUS callout_address,
string_sprintf("unable to read from UNIX socket (%s)", scanner_options),
sock);
malware_name = string_copy(&av_buffer[2]);
}
else if (!strncmp(CS av_buffer, "-1", 2))
- return m_errlog_defer_3(scanent, US"scanner reported error", sock);
+ return m_errlog_defer_3(scanent, CUS callout_address,
+ US"scanner reported error", sock);
else /* all ok, no virus */
malware_name = NULL;
* WITH_OLD_CLAMAV_STREAM is defined.
* See Exim bug 926 for details. */
- uschar *p, *vname, *result_tag, *response_end;
+ uschar *p, *vname, *result_tag;
int bread=0;
uschar * file_name;
uschar av_buffer[1024];
off_t fsize;
unsigned int fsize_uint;
BOOL use_scan_command = FALSE;
- clamd_address_container * clamd_address_vector[MAX_CLAMD_SERVERS];
- int current_server;
+ clamd_address * cv[MAX_CLAMD_SERVERS];
int num_servers = 0;
#ifdef WITH_OLD_CLAMAV_STREAM
unsigned int port;
uint32_t send_size, send_final_zeroblock;
#endif
+ /*XXX if unixdomain socket, only one server supported. Needs fixing;
+ there's no reason we should not mix local and remote servers */
+
if (*scanner_options == '/')
+ {
+ clamd_address * cd;
+ const uschar * sublist;
+ int subsep = ' ';
+
/* Local file; so we def want to use_scan_command and don't want to try
* passing IP/port combinations */
use_scan_command = TRUE;
+ cd = (clamd_address *) store_get(sizeof(clamd_address));
+
+ /* extract socket-path part */
+ sublist = scanner_options;
+ cd->hostspec = string_nextinlist(&sublist, &subsep, NULL, 0);
+
+ /* parse options */
+ if (clamd_option(cd, sublist, &subsep) != OK)
+ return m_errlog_defer(scanent, NULL,
+ string_sprintf("bad option '%s'", scanner_options));
+ cv[0] = cd;
+ }
else
{
- const uschar *address = scanner_options;
- uschar address_buffer[MAX_CLAMD_ADDRESS_LENGTH + 20];
-
/* Go through the rest of the list of host/port and construct an array
* of servers to try. The first one is the bit we just passed from
* scanner_options so process that first and then scan the remainder of
* the address buffer */
do
{
- clamd_address_container *this_clamd;
+ clamd_address * cd;
+ const uschar * sublist;
+ int subsep = ' ';
+ uschar * s;
/* The 'local' option means use the SCAN command over the network
* socket (ie common file storage in use) */
- if (strcmpic(address,US"local") == 0)
+ /*XXX we could accept this also as a local option? */
+ if (strcmpic(scanner_options, US"local") == 0)
{
use_scan_command = TRUE;
continue;
}
- /* XXX: If unsuccessful we should free this memory */
- this_clamd =
- (clamd_address_container *)store_get(sizeof(clamd_address_container));
+ cd = (clamd_address *) store_get(sizeof(clamd_address));
/* extract host and port part */
- if( sscanf(CS address, "%" MAX_CLAMD_ADDRESS_LENGTH_S "s %u",
- this_clamd->tcp_addr, &(this_clamd->tcp_port)) != 2 )
+ sublist = scanner_options;
+ if (!(cd->hostspec = string_nextinlist(&sublist, &subsep, NULL, 0)))
+ {
+ (void) m_errlog_defer(scanent, NULL,
+ string_sprintf("missing address: '%s'", scanner_options));
+ continue;
+ }
+ if (!(s = string_nextinlist(&sublist, &subsep, NULL, 0)))
+ {
+ (void) m_errlog_defer(scanent, NULL,
+ string_sprintf("missing port: '%s'", scanner_options));
+ continue;
+ }
+ cd->tcp_port = atoi(CS s);
+
+ /* parse options */
+ /*XXX should these options be common over scanner types? */
+ if (clamd_option(cd, sublist, &subsep) != OK)
{
- (void) m_errlog_defer(scanent,
- string_sprintf("invalid address '%s'", address));
+ return m_errlog_defer(scanent, NULL,
+ string_sprintf("bad option '%s'", scanner_options));
continue;
}
- clamd_address_vector[num_servers] = this_clamd;
- num_servers++;
+ cv[num_servers++] = cd;
if (num_servers >= MAX_CLAMD_SERVERS)
{
- (void) m_errlog_defer(scanent,
+ (void) m_errlog_defer(scanent, NULL,
US"More than " MAX_CLAMD_SERVERS_S " clamd servers "
"specified; only using the first " MAX_CLAMD_SERVERS_S );
break;
}
- } while ((address = string_nextinlist(&av_scanner_work, &sep,
- address_buffer,
- sizeof(address_buffer))) != NULL);
+ } while ((scanner_options = string_nextinlist(&av_scanner_work, &sep,
+ NULL, 0)));
/* check if we have at least one server */
if (!num_servers)
- return m_errlog_defer(scanent,
+ return m_errlog_defer(scanent, NULL,
US"no useable server addresses in malware configuration option.");
}
/* See the discussion of response formats below to see why we really
don't like colons in filenames when passing filenames to ClamAV. */
if (use_scan_command && Ustrchr(eml_filename, ':'))
- return m_errlog_defer(scanent,
+ return m_errlog_defer(scanent, NULL,
string_sprintf("local/SCAN mode incompatible with" \
" : in path to email filename [%s]", eml_filename));
while (num_servers > 0)
{
- int i;
- /* Randomly pick a server to start with */
- current_server = random_number( num_servers );
+ int i = random_number( num_servers );
+ clamd_address * cd = cv[i];
- DEBUG(D_acl)
- debug_printf("trying server name %s, port %u\n",
- clamd_address_vector[current_server]->tcp_addr,
- clamd_address_vector[current_server]->tcp_port);
+ DEBUG(D_acl) debug_printf("trying server name %s, port %u\n",
+ cd->hostspec, cd->tcp_port);
/* Lookup the host. This is to ensure that we connect to the same IP
* on both connections (as one host could resolve to multiple ips) */
- sock= m_tcpsocket(clamd_address_vector[current_server]->tcp_addr,
- clamd_address_vector[current_server]->tcp_port,
- &connhost, &errstr);
- if (sock >= 0)
+ for (;;)
{
- /* Connection successfully established with a server */
- hostname = clamd_address_vector[current_server]->tcp_addr;
- break;
+ sock= m_tcpsocket(cd->hostspec, cd->tcp_port, &connhost, &errstr);
+ if (sock >= 0)
+ {
+ /* Connection successfully established with a server */
+ hostname = cd->hostspec;
+ break;
+ }
+ if (cd->retry <= 0) break;
+ while (cd->retry > 0) cd->retry = sleep(cd->retry);
}
+ if (sock >= 0)
+ break;
- (void) m_errlog_defer(scanent, errstr);
+ (void) m_errlog_defer(scanent, CUS callout_address, errstr);
/* Remove the server from the list. XXX We should free the memory */
num_servers--;
- for (i = current_server; i < num_servers; i++)
- clamd_address_vector[i] = clamd_address_vector[i+1];
+ for (; i < num_servers; i++)
+ cv[i] = cv[i+1];
}
if (num_servers == 0)
- return m_errlog_defer(scanent, US"all servers failed");
+ return m_errlog_defer(scanent, NULL, US"all servers failed");
}
else
- {
- if ((sock = m_unixsocket(scanner_options, &errstr)) < 0)
- return m_errlog_defer(scanent, errstr);
- }
+ for (;;)
+ {
+ if ((sock = ip_unixsocket(cv[0]->hostspec, &errstr)) >= 0)
+ {
+ hostname = cv[0]->hostspec;
+ break;
+ }
+ if (cv[0]->retry <= 0)
+ return m_errlog_defer(scanent, CUS callout_address, errstr);
+ while (cv[0]->retry > 0) cv[0]->retry = sleep(cv[0]->retry);
+ }
/* have socket in variable "sock"; command to use is semi-independent of
* the socket protocol. We use SCAN if is local (either Unix/local
/* Pass the string to ClamAV (7 = "STREAM\n") */
if (m_sock_send(sock, US"STREAM\n", 7, &errstr) < 0)
- return m_errlog_defer(scanent, errstr);
+ return m_errlog_defer(scanent, CUS callout_address, errstr);
memset(av_buffer2, 0, sizeof(av_buffer2));
bread = ip_recv(sock, av_buffer2, sizeof(av_buffer2), tmo-time(NULL));
if (bread < 0)
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, CUS callout_address,
string_sprintf("unable to read PORT from socket (%s)",
strerror(errno)),
sock);
if (bread == sizeof(av_buffer2))
- return m_errlog_defer_3(scanent, "buffer too small", sock);
+ return m_errlog_defer_3(scanent, CUS callout_address,
+ "buffer too small", sock);
if (!(*av_buffer2))
- return m_errlog_defer_3(scanent, "ClamAV returned null", sock);
+ return m_errlog_defer_3(scanent, CUS callout_address,
+ "ClamAV returned null", sock);
av_buffer2[bread] = '\0';
if( sscanf(CS av_buffer2, "PORT %u\n", &port) != 1 )
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, CUS callout_address,
string_sprintf("Expected port information from clamd, got '%s'",
av_buffer2),
sock);
sockData = m_tcpsocket(connhost.address, port, NULL, &errstr);
if (sockData < 0)
- return m_errlog_defer_3(scanent, errstr, sock);
+ return m_errlog_defer_3(scanent, CUS callout_address, errstr, sock);
# define CLOSE_SOCKDATA (void)close(sockData)
#else /* WITH_OLD_CLAMAV_STREAM not defined */
/* Pass the string to ClamAV (10 = "zINSTREAM\0") */
if (send(sock, "zINSTREAM", 10, 0) < 0)
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, CUS hostname,
string_sprintf("unable to send zINSTREAM to socket (%s)",
strerror(errno)),
sock);
{
int err = errno;
CLOSE_SOCKDATA;
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, NULL,
string_sprintf("can't open spool file %s: %s",
eml_filename, strerror(err)),
sock);
{
int err = errno;
CLOSE_SOCKDATA; (void)close(clam_fd);
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, NULL,
string_sprintf("can't seek spool file %s: %s",
eml_filename, strerror(err)),
sock);
if ((off_t)fsize_uint != fsize)
{
CLOSE_SOCKDATA; (void)close(clam_fd);
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, NULL,
string_sprintf("seeking spool file %s, size overflow",
eml_filename),
sock);
if (!(clamav_fbuf = (uschar *) malloc (fsize_uint)))
{
CLOSE_SOCKDATA; (void)close(clam_fd);
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, NULL,
string_sprintf("unable to allocate memory %u for file (%s)",
fsize_uint, eml_filename),
sock);
{
int err = errno;
free(clamav_fbuf); CLOSE_SOCKDATA; (void)close(clam_fd);
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, NULL,
string_sprintf("can't read spool file %s: %s",
eml_filename, strerror(err)),
sock);
if (send(sockData, clamav_fbuf, fsize_uint, 0) < 0)
{
free(clamav_fbuf); CLOSE_SOCKDATA;
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, NULL,
string_sprintf("unable to send file body to socket (%s:%u)",
hostname, port),
sock);
(send(sock, &send_final_zeroblock, sizeof(send_final_zeroblock), 0) < 0))
{
free(clamav_fbuf);
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, NULL,
string_sprintf("unable to send file body to socket (%s)", hostname),
sock);
}
scanner_name, scanner_options);
if (send(sock, file_name, Ustrlen(file_name), 0) < 0)
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, CUS callout_address,
string_sprintf("unable to write to socket (%s)", strerror(errno)),
sock);
sock = -1;
if (bread <= 0)
- return m_errlog_defer(scanent,
+ return m_errlog_defer(scanent, CUS callout_address,
string_sprintf("unable to read from socket (%s)",
errno == 0 ? "EOF" : strerror(errno)));
if (bread == sizeof(av_buffer))
- return m_errlog_defer(scanent, US"buffer too small");
+ return m_errlog_defer(scanent, CUS callout_address,
+ US"buffer too small");
/* We're now assured of a NULL at the end of av_buffer */
/* Check the result. ClamAV returns one of two result formats.
passing a filename to clamd). */
if (!(*av_buffer))
- return m_errlog_defer(scanent, US"ClamAV returned null");
+ return m_errlog_defer(scanent, CUS callout_address,
+ US"ClamAV returned null");
/* strip newline at the end (won't be present for zINSTREAM)
(also any trailing whitespace, which shouldn't exist, but we depend upon
while (isspace(*--p) && (p > av_buffer))
*p = '\0';
if (*p) ++p;
- response_end = p;
/* colon in returned output? */
- if((p = Ustrchr(av_buffer,':')) == NULL)
- return m_errlog_defer(scanent, string_sprintf(
+ if(!(p = Ustrchr(av_buffer,':')))
+ return m_errlog_defer(scanent, CUS callout_address, string_sprintf(
"ClamAV returned malformed result (missing colon): %s",
av_buffer));
}
else if (Ustrcmp(result_tag, "ERROR") == 0)
- return m_errlog_defer(scanent,
+ return m_errlog_defer(scanent, CUS callout_address,
string_sprintf("ClamAV returned: %s", av_buffer));
else if (Ustrcmp(result_tag, "OK") == 0)
}
else
- return m_errlog_defer(scanent,
+ return m_errlog_defer(scanent, CUS callout_address,
string_sprintf("unparseable response from ClamAV: {%s}", av_buffer));
break;
uschar * s = Ustrchr(sockline_scanner, '%');
if (s++)
if ((*s != 's' && *s != '%') || Ustrchr(s+1, '%'))
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, NULL,
US"unsafe sock scanner call spec", sock);
}
else
sockline_trig_re = m_pcre_nextinlist(&av_scanner_work, &sep,
"missing trigger specification", &errstr);
if (!sockline_trig_re)
- return m_errlog_defer_3(scanent, errstr, sock);
+ return m_errlog_defer_3(scanent, NULL, errstr, sock);
/* find virus name regex */
sockline_name_re = m_pcre_nextinlist(&av_scanner_work, &sep,
"missing virus name regex specification", &errstr);
if (!sockline_name_re)
- return m_errlog_defer_3(scanent, errstr, sock);
+ return m_errlog_defer_3(scanent, NULL, errstr, sock);
/* prepare scanner call - security depends on expansions check above */
commandline = string_sprintf("%s/scan/%s/%s.eml", spool_directory, message_id, message_id);
/* Pass the command string to the socket */
if (m_sock_send(sock, commandline, Ustrlen(commandline), &errstr) < 0)
- return m_errlog_defer(scanent, errstr);
+ return m_errlog_defer(scanent, CUS callout_address, errstr);
/* Read the result */
bread = ip_recv(sock, av_buffer, sizeof(av_buffer), tmo-time(NULL));
if (bread <= 0)
- return m_errlog_defer_3(scanent,
+ return m_errlog_defer_3(scanent, CUS callout_address,
string_sprintf("unable to read from socket (%s)", strerror(errno)),
sock);
if (bread == sizeof(av_buffer))
- return m_errlog_defer_3(scanent, US"buffer too small", sock);
+ return m_errlog_defer_3(scanent, CUS callout_address,
+ US"buffer too small", sock);
av_buffer[bread] = '\0';
linebuffer = string_copy(av_buffer);
|| mksd_maxproc < 1
|| mksd_maxproc > 32
)
- return m_errlog_defer(scanent,
+ return m_errlog_defer(scanent, CUS callout_address,
string_sprintf("invalid option '%s'", scanner_options));
}
- if((sock = m_unixsocket(US "/var/run/mksd/socket", &errstr)) < 0)
- return m_errlog_defer(scanent, errstr);
+ if((sock = ip_unixsocket(US "/var/run/mksd/socket", &errstr)) < 0)
+ return m_errlog_defer(scanent, CUS callout_address, errstr);
malware_name = NULL;
)
{
int slen = Ustrlen(buf);
- if (slen >= 1)
+ if (slen >= 1)
{
DEBUG(D_acl) debug_printf("got from avast: %s\n", buf);
switch (avast_stage)
if (send(sock, scanrequest, len, 0) < 0)
{
scanrequest[len-1] = '\0';
- return m_errlog_defer_3(scanent, string_sprintf(
+ return m_errlog_defer_3(scanent, CUS callout_address, string_sprintf(
"unable to send request '%s' to socket (%s): %s",
scanrequest, scanner_options, strerror(errno)), sock);
}
if ((malware_name = m_pcre_exec(ava_re_virus, buf)))
{ /* remove backslash in front of [whitespace|backslash] */
uschar * p, * p0;
- for (p = malware_name; *p; ++p)
+ for (p = malware_name; *p; ++p)
if (*p == '\\' && (isspace(p[1]) || p[1] == '\\'))
for (p0 = p; *p0; ++p0) *p0 = p0[1];
-
+
avast_stage = AVA_DONE;
goto endloop;
}
- if (Ustrncmp(buf, "200 SCAN OK", 11) == 0)
+ if (Ustrncmp(buf, "200 SCAN OK", 11) == 0)
{ /* we're done finally */
if (send(sock, "QUIT\n", 5, 0) < 0) /* courtesy */
- return m_errlog_defer_3(scanent, string_sprintf(
+ return m_errlog_defer_3(scanent, CUS callout_address,
+ string_sprintf(
"unable to send quit request to socket (%s): %s",
scanner_options, strerror(errno)),
sock);
/* here for any unexpected response from the scanner */
goto endloop;
+
+ case AVA_DONE: log_write(0, LOG_PANIC, "%s:%d:%s: should not happen",
+ __FILE__, __LINE__, __FUNCTION__);
}
}
}
switch(avast_stage)
{
- case AVA_HELO:
+ case AVA_HELO:
case AVA_OPT:
- case AVA_RSP: return m_errlog_defer_3(scanent,
+ case AVA_RSP: return m_errlog_defer_3(scanent, CUS callout_address,
nread >= 0
? string_sprintf(
"invalid response from scanner: '%s'", buf)
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Functions for matching strings */
strings, domains, and local parts. */
typedef struct check_string_block {
- uschar *origsubject; /* caseful; keep these two first, in */
- uschar *subject; /* step with the block below */
+ const uschar *origsubject; /* caseful; keep these two first, in */
+ const uschar *subject; /* step with the block below */
int expand_setup;
BOOL use_partial;
BOOL caseless;
addresses. */
typedef struct check_address_block {
- uschar *origaddress; /* caseful; keep these two first, in */
+ const uschar *origaddress; /* caseful; keep these two first, in */
uschar *address; /* step with the block above */
int expand_setup;
BOOL caseless;
*/
static int
-check_string(void *arg, uschar *pattern, uschar **valueptr, uschar **error)
+check_string(void *arg, const uschar *pattern, const uschar **valueptr, uschar **error)
{
-check_string_block *cb = (check_string_block *)arg;
+const check_string_block *cb = arg;
int search_type, partial, affixlen, starflags;
int expand_setup = cb->expand_setup;
-uschar *affix;
+const uschar *affix;
uschar *s;
uschar *filename = NULL;
uschar *keyquery, *result, *semicolon;
it works if the pattern uses (?-i) to turn off case-independence, overriding
"caseless". */
-s = (pattern[0] == '^')? cb->origsubject : cb->subject;
+s = string_copy(pattern[0] == '^' ? cb->origsubject : cb->subject);
/* If required to set up $0, initialize the data but don't turn on by setting
expand_nmax until the match is assured. */
{
const pcre *re = regex_must_compile(pattern, cb->caseless, FALSE);
return ((expand_setup < 0)?
- pcre_exec(re, NULL, CS s, Ustrlen(s), 0, PCRE_EOPT, NULL, 0) >= 0
+ pcre_exec(re, NULL, CCS s, Ustrlen(s), 0, PCRE_EOPT, NULL, 0) >= 0
:
regex_match_and_setup(re, s, 0, expand_setup)
)?
BOOL prim = FALSE;
BOOL secy = FALSE;
BOOL removed = FALSE;
- uschar *ss = pattern + 4;
- uschar *ignore_target_hosts = NULL;
+ const uschar *ss = pattern + 4;
+ const uschar *ignore_target_hosts = NULL;
if (strncmpic(ss, US"any", 3) == 0) ss += 3;
else if (strncmpic(ss, US"primary", 7) == 0)
NULL, /* service name not relevant */
NULL, /* srv_fail_domains not relevant */
NULL, /* mx_fail_domains not relevant */
- NULL, /* no dnssec request XXX ? */
- NULL, /* no dnssec require XXX ? */
+ NULL, /* no dnssec request/require XXX ? */
NULL, /* no feedback FQDN */
&removed); /* feedback if local removed */
*/
int
-match_check_string(uschar *s, uschar *pattern, int expand_setup,
- BOOL use_partial, BOOL caseless, BOOL at_is_special, uschar **valueptr)
+match_check_string(const uschar *s, const uschar *pattern, int expand_setup,
+ BOOL use_partial, BOOL caseless, BOOL at_is_special, const uschar **valueptr)
{
check_string_block cb;
cb.origsubject = s;
type MCL_STRING, MCL_DOMAIN, MCL_HOST, MCL_ADDRESS, or MCL_LOCALPART
*/
-static uschar *
+static const uschar *
get_check_key(void *arg, int type)
{
switch(type)
*/
int
-match_check_list(uschar **listptr, int sep, tree_node **anchorptr,
- unsigned int **cache_ptr, int (*func)(void *,uschar *,uschar **,uschar **),
- void *arg, int type, uschar *name, uschar **valueptr)
+match_check_list(const uschar **listptr, int sep, tree_node **anchorptr,
+ unsigned int **cache_ptr, int (*func)(void *,const uschar *,const uschar **,uschar **),
+ void *arg, int type, const uschar *name, const uschar **valueptr)
{
int yield = OK;
unsigned int *original_cache_bits = *cache_ptr;
BOOL ignore_unknown = FALSE;
BOOL include_defer = FALSE;
BOOL ignore_defer = FALSE;
-uschar *list;
+const uschar *list;
uschar *sss;
uschar *ot = NULL;
uschar buffer[1024];
if (type == MCL_DOMAIN && deliver_domain == NULL)
{
check_string_block *cb = (check_string_block *)arg;
- deliver_domain = cb->subject;
- list = expand_string(*listptr);
+ deliver_domain = string_copy(cb->subject);
+ list = expand_cstring(*listptr);
deliver_domain = NULL;
}
- else list = expand_string(*listptr);
+ else list = expand_cstring(*listptr);
if (list == NULL)
{
cached = US" - cached";
if (valueptr != NULL)
{
- uschar *key = get_check_key(arg, type);
+ const uschar *key = get_check_key(arg, type);
namedlist_cacheblock *p;
for (p = nb->cache_data; p != NULL; p = p->next)
{
case DEFER:
if (error == NULL)
- error = string_sprintf("DNS lookup of %s deferred", ss);
+ error = string_sprintf("DNS lookup of \"%s\" deferred", ss);
if (ignore_defer)
{
HDEBUG(D_lists) debug_printf("%s: item ignored by +ignore_defer\n",
log_write(0, LOG_MAIN, "%s: accepted by +include_defer", error);
return OK;
}
+ if (!search_error_message) search_error_message = error;
goto DEFER_RETURN;
/* The ERROR return occurs when checking hosts, when either a forward
include_unknown? "yes":"no", error);
if (!include_unknown)
{
- if ((log_extra_selector & LX_unknown_in_list) != 0)
+ if (LOGGING(unknown_in_list))
log_write(0, LOG_MAIN, "list matching forced to fail: %s", error);
return FAIL;
}
(void)fclose(f);
if (!include_unknown)
{
- if ((log_extra_selector & LX_unknown_in_list) != 0)
+ if (LOGGING(unknown_in_list))
log_write(0, LOG_MAIN, "list matching forced to fail: %s", error);
return FAIL;
}
*/
int
-match_isinlist(uschar *s, uschar **listptr, int sep, tree_node **anchorptr,
- unsigned int *cache_bits, int type, BOOL caseless, uschar **valueptr)
+match_isinlist(const uschar *s, const uschar **listptr, int sep,
+ tree_node **anchorptr,
+ unsigned int *cache_bits, int type, BOOL caseless, const uschar **valueptr)
{
unsigned int *local_cache_bits = cache_bits;
check_string_block cb;
*/
static int
-check_address(void *arg, uschar *pattern, uschar **valueptr, uschar **error)
+check_address(void *arg, const uschar *pattern, const uschar **valueptr, uschar **error)
{
check_address_block *cb = (check_address_block *)arg;
check_string_block csb;
int rc;
int expand_inc = 0;
unsigned int *null = NULL;
-uschar *listptr;
+const uschar *listptr;
uschar *subject = cb->address;
-uschar *s, *pdomain, *sdomain;
+const uschar *s;
+uschar *pdomain, *sdomain;
error = error; /* Keep clever compilers from complaining */
if (pattern[0] == '@' && pattern[1] == '@')
{
int watchdog = 50;
- uschar *list, *key, *ss;
+ const uschar *key;
+ uschar *list, *ss;
uschar buffer[1024];
if (sdomain == subject + 1 && *subject == '*') return FAIL;
int sep = 0;
if ((rc = match_check_string(key, pattern + 2, -1, TRUE, FALSE, FALSE,
- &list)) != OK) return rc;
+ CUSS &list)) != OK) return rc;
/* Check for chaining from the last item; set up the next key if one
is found. */
/* Look up the local parts provided by the list; negation is permitted.
If a local part has to begin with !, a regex can be used. */
- while ((ss = string_nextinlist(&list, &sep, buffer, sizeof(buffer)))
- != NULL)
+ while ((ss = string_nextinlist(CUSS &list, &sep, buffer, sizeof(buffer))))
{
int local_yield;
*/
int
-match_address_list(uschar *address, BOOL caseless, BOOL expand,
- uschar **listptr, unsigned int *cache_bits, int expand_setup, int sep,
- uschar **valueptr)
+match_address_list(const uschar *address, BOOL caseless, BOOL expand,
+ const uschar **listptr, unsigned int *cache_bits, int expand_setup, int sep,
+ const uschar **valueptr)
{
uschar *p;
check_address_block ab;
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- 2. The origin of this software must not be misrepresented; you must
- not claim that you wrote the original software. If you use this
- software in a product, an acknowledgment in the product
+ 2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
3. Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software.
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
+ 4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
the terms of the GNU General Public License, version 2. See the
COPYING file in the source distribution for details.
- ----------------------------------------------------------------
+ ----------------------------------------------------------------
*/
#include "valgrind.h"
-/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
+/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
This enum comprises an ABI exported by Valgrind to programs
which use client requests. DO NOT CHANGE THE ORDER OF THESE
ENTRIES, NOR DELETE ANY -- add new ones at the end. */
typedef
- enum {
+ enum {
VG_USERREQ__MAKE_MEM_NOACCESS = VG_USERREQ_TOOL_BASE('M','C'),
VG_USERREQ__MAKE_MEM_UNDEFINED,
VG_USERREQ__MAKE_MEM_DEFINED,
VG_USERREQ__COUNT_LEAK_BLOCKS,
/* This is just for memcheck's internal use - don't use it */
- _VG_USERREQ__MEMCHECK_RECORD_OVERLAP_ERROR
+ _VG_USERREQ__MEMCHECK_RECORD_OVERLAP_ERROR
= VG_USERREQ_TOOL_BASE('M','C') + 256
} Vg_MemCheckClientRequest;
VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \
VG_USERREQ__MAKE_MEM_NOACCESS, \
(_qzz_addr), (_qzz_len), 0, 0, 0)
-
+
/* Similarly, mark memory at _qzz_addr as addressable but undefined
for _qzz_len bytes. */
#define VALGRIND_MAKE_MEM_UNDEFINED(_qzz_addr,_qzz_len) \
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) Tom Kistner <tom@duncanthrax.net> 2004 */
+/* Copyright (c) Tom Kistner <tom@duncanthrax.net> 2004, 2015 */
/* License: GPL */
#include "exim.h"
give info on detected "problems" in MIME
encodings. Those are defined in mime.h. */
-void
+static void
mime_set_anomaly(int level, const char *text)
{
mime_anomaly_level = level;
0-255 - char to write
*/
-uschar *
+static uschar *
mime_decode_qp_char(uschar *qp_p, int *c)
{
uschar *initial_pos = qp_p;
}
-FILE *
+static FILE *
mime_get_decode_file(uschar *pname, uschar *fname)
{
FILE *f = NULL;
int
-mime_decode(uschar **listptr)
+mime_decode(const uschar **listptr)
{
int sep = 0;
-uschar *list = *listptr;
+const uschar *list = *listptr;
uschar *option;
uschar option_buffer[1024];
uschar decode_path[1024];
return OK;
}
-int
+
+static int
mime_get_header(FILE *f, uschar *header)
{
int c = EOF;
}
+static void
+mime_vars_reset(void)
+{
+mime_anomaly_level = 0;
+mime_anomaly_text = NULL;
+mime_boundary = NULL;
+mime_charset = NULL;
+mime_decoded_filename = NULL;
+mime_filename = NULL;
+mime_content_description = NULL;
+mime_content_disposition = NULL;
+mime_content_id = NULL;
+mime_content_transfer_encoding = NULL;
+mime_content_type = NULL;
+mime_is_multipart = 0;
+mime_content_size = 0;
+}
+
+
+/* Grab a parameter value, dealing with quoting.
+
+Arguments:
+ str Input string. Updated on return to point to terminating ; or NUL
+
+Return:
+ Allocated string with parameter value
+*/
+static uschar *
+mime_param_val(uschar ** sp)
+{
+uschar * s = *sp;
+uschar * val = NULL;
+int size = 0, ptr = 0;
+
+/* debug_printf(" considering paramval '%s'\n", s); */
+
+while (*s && *s != ';') /* ; terminates */
+ if (*s == '"')
+ {
+ s++; /* skip opening " */
+ while (*s && *s != '"') /* " protects ; */
+ val = string_cat(val, &size, &ptr, s++, 1);
+ if (*s) s++; /* skip closing " */
+ }
+ else
+ val = string_cat(val, &size, &ptr, s++, 1);
+if (val) val[ptr] = '\0';
+*sp = s;
+return val;
+}
+
+static uschar *
+mime_next_semicolon(uschar * s)
+{
+while (*s && *s != ';') /* ; terminates */
+ if (*s == '"')
+ {
+ s++; /* skip opening " */
+ while (*s && *s != '"') /* " protects ; */
+ s++;
+ if (*s) s++; /* skip closing " */
+ }
+ else
+ s++;
+return s;
+}
+
+
+static uschar *
+rfc2231_to_2047(const uschar * fname, const uschar * charset, int * len)
+{
+int size = 0, ptr = 0;
+uschar * val = string_cat(NULL, &size, &ptr, US"=?", 2);
+uschar c;
+
+if (charset)
+ val = string_cat(val, &size, &ptr, charset, Ustrlen(charset));
+val = string_cat(val, &size, &ptr, US"?Q?", 3);
+
+while ((c = *fname))
+ if (c == '%' && isxdigit(fname[1]) && isxdigit(fname[2]))
+ {
+ val = string_cat(val, &size, &ptr, US"=", 1);
+ val = string_cat(val, &size, &ptr, ++fname, 2);
+ fname += 2;
+ }
+ else
+ val = string_cat(val, &size, &ptr, fname++, 1);
+
+val = string_cat(val, &size, &ptr, US"?=", 2);
+val[*len = ptr] = '\0';
+return val;
+}
+
+
int
mime_acl_check(uschar *acl, FILE *f, struct mime_boundary_context *context,
- uschar **user_msgptr, uschar **log_msgptr)
+ uschar **user_msgptr, uschar **log_msgptr)
{
int rc = OK;
-uschar *header = NULL;
+uschar * header = NULL;
struct mime_boundary_context nested_context;
/* reserve a line buffer to work in */
-if (!(header = (uschar *)malloc(MIME_MAX_HEADER_SIZE+1)))
- {
- log_write(0, LOG_PANIC,
- "MIME ACL: can't allocate %d bytes of memory.", MIME_MAX_HEADER_SIZE+1);
- return DEFER;
- }
+header = store_get(MIME_MAX_HEADER_SIZE+1);
/* Not actually used at the moment, but will be vital to fixing
* some RFC 2046 nonconformance later... */
while(1)
{
/* reset all per-part mime variables */
- mime_anomaly_level = 0;
- mime_anomaly_text = NULL;
- mime_boundary = NULL;
- mime_charset = NULL;
- mime_decoded_filename = NULL;
- mime_filename = NULL;
- mime_content_description = NULL;
- mime_content_disposition = NULL;
- mime_content_id = NULL;
- mime_content_transfer_encoding = NULL;
- mime_content_type = NULL;
- mime_is_multipart = 0;
- mime_content_size = 0;
-
- /*
- If boundary is null, we assume that *f is positioned on the start of headers (for example,
- at the very beginning of a message.
- If a boundary is given, we must first advance to it to reach the start of the next header
- block.
- */
+ mime_vars_reset();
+
+ /* If boundary is null, we assume that *f is positioned on the start of
+ headers (for example, at the very beginning of a message. If a boundary is
+ given, we must first advance to it to reach the start of the next header
+ block. */
/* NOTE -- there's an error here -- RFC2046 specifically says to
* check for outer boundaries. This code doesn't do that, and
* (I have moved partway towards adding support, however, by adding
* a "parent" field to my new boundary-context structure.)
*/
- if (context != NULL)
+ if (context) for (;;)
{
- while(fgets(CS header, MIME_MAX_HEADER_SIZE, f) != NULL)
+ if (!fgets(CS header, MIME_MAX_HEADER_SIZE, f))
{
- /* boundary line must start with 2 dashes */
- if (Ustrncmp(header,"--",2) == 0)
- {
- if (Ustrncmp((header+2),context->boundary,Ustrlen(context->boundary)) == 0)
- {
- /* found boundary */
- if (Ustrncmp((header+2+Ustrlen(context->boundary)),"--",2) == 0)
- {
- /* END boundary found */
- debug_printf("End boundary found %s\n", context->boundary);
- return rc;
- }
- else
- debug_printf("Next part with boundary %s\n", context->boundary);
+ /* Hit EOF or read error. Ugh. */
+ DEBUG(D_acl) debug_printf("MIME: Hit EOF ...\n");
+ return rc;
+ }
- /* can't use break here */
- goto DECODE_HEADERS;
- }
+ /* boundary line must start with 2 dashes */
+ if ( Ustrncmp(header, "--", 2) == 0
+ && Ustrncmp(header+2, context->boundary, Ustrlen(context->boundary)) == 0
+ )
+ { /* found boundary */
+ if (Ustrncmp((header+2+Ustrlen(context->boundary)), "--", 2) == 0)
+ {
+ /* END boundary found */
+ DEBUG(D_acl) debug_printf("MIME: End boundary found %s\n",
+ context->boundary);
+ return rc;
}
+
+ DEBUG(D_acl) debug_printf("MIME: Next part with boundary %s\n",
+ context->boundary);
+ break;
}
- /* Hit EOF or read error. Ugh. */
- debug_printf("Hit EOF ...\n");
- return rc;
}
-DECODE_HEADERS:
/* parse headers, set up expansion variables */
- while (mime_get_header(f,header))
+ while (mime_get_header(f, header))
{
- int i;
- /* loop through header list */
- for (i = 0; i < mime_header_list_size; i++)
+ struct mime_header * mh;
+
+ /* look for interesting headers */
+ for (mh = mime_header_list;
+ mh < mime_header_list + mime_header_list_size;
+ mh++) if (strncmpic(mh->name, header, mh->namelen) == 0)
{
- uschar *header_value = NULL;
- int header_value_len = 0;
+ uschar * p = header + mh->namelen;
+ uschar * q;
+
+ /* grab the value (normalize to lower case)
+ and copy to its corresponding expansion variable */
+
+ for (q = p; *q != ';' && *q; q++) ;
+ *mh->value = string_copynlc(p, q-p);
+ DEBUG(D_acl) debug_printf("MIME: found %s header, value is '%s'\n",
+ mh->name, *mh->value);
+
+ if (*(p = q)) p++; /* jump past the ; */
- /* found an interesting header? */
- if (strncmpic(mime_header_list[i].name,header,mime_header_list[i].namelen) == 0)
{
- uschar *p = header + mime_header_list[i].namelen;
- /* yes, grab the value (normalize to lower case)
- and copy to its corresponding expansion variable */
- while(*p != ';')
- {
- *p = tolower(*p);
- p++;
- }
- header_value_len = (p - (header + mime_header_list[i].namelen));
- header_value = (uschar *)malloc(header_value_len+1);
- memset(header_value,0,header_value_len+1);
- p = header + mime_header_list[i].namelen;
- Ustrncpy(header_value, p, header_value_len);
- debug_printf("Found %s MIME header, value is '%s'\n", mime_header_list[i].name, header_value);
- *((uschar **)(mime_header_list[i].value)) = header_value;
-
- /* make p point to the next character after the closing ';' */
- p += (header_value_len+1);
-
- /* grab all param=value tags on the remaining line, check if they are interesting */
-NEXT_PARAM_SEARCH:
- while (*p != 0)
+ uschar * mime_fname = NULL;
+ uschar * mime_fname_rfc2231 = NULL;
+ uschar * mime_filename_charset = NULL;
+ BOOL decoding_failed = FALSE;
+
+ /* grab all param=value tags on the remaining line,
+ check if they are interesting */
+
+ while (*p)
{
mime_parameter * mp;
- for (mp = mime_parameter_list;
- mp < &mime_parameter_list[mime_parameter_list_size];
- mp++)
- {
- uschar *param_value = NULL;
- int param_value_len = 0;
-
- /* found an interesting parameter? */
- if (strncmpic(mp->name, p, mp->namelen) == 0)
+
+ DEBUG(D_acl) debug_printf("MIME: considering paramlist '%s'\n", p);
+
+ if ( !mime_filename
+ && strncmpic(CUS"content-disposition:", header, 20) == 0
+ && strncmpic(CUS"filename*", p, 9) == 0
+ )
+ { /* RFC 2231 filename */
+ uschar * q;
+
+ /* find value of the filename */
+ p += 9;
+ while(*p != '=' && *p) p++;
+ if (*p) p++; /* p is filename or NUL */
+ q = mime_param_val(&p); /* p now trailing ; or NUL */
+
+ if (q && *q)
{
- uschar *q = p + mp->namelen;
- int size = 0;
- int ptr = 0;
+ uschar * temp_string, * err_msg;
+ int slen;
+
+ /* build up an un-decoded filename over successive
+ filename*= parameters (for use when 2047 decode fails) */
- /* yes, grab the value and copy to its corresponding expansion variable */
- while(*q && *q != ';') /* ; terminates */
+ mime_fname_rfc2231 = string_sprintf("%#s%s",
+ mime_fname_rfc2231, q);
+
+ if (!decoding_failed)
{
- if (*q == '"')
+ int size;
+ if (!mime_filename_charset)
{
- q++; /* skip leading " */
- while(*q && *q != '"') /* which protects ; */
- param_value = string_cat(param_value, &size, &ptr, q++, 1);
- if (*q) q++; /* skip trailing " */
+ uschar * s = q;
+
+ /* look for a ' in the "filename" */
+ while(*s != '\'' && *s) s++; /* s is 1st ' or NUL */
+
+ if ((size = s-q) > 0)
+ mime_filename_charset = string_copyn(q, size);
+
+ if (*(p = s)) p++;
+ while(*p == '\'') p++; /* p is after 2nd ' */
}
else
- param_value = string_cat(param_value, &size, &ptr, q++, 1);
- }
- if (param_value)
- {
- param_value[ptr++] = '\0';
- param_value_len = ptr;
-
- param_value = rfc2047_decode(param_value,
- check_rfc2047_length, NULL, 32, ¶m_value_len, &q);
- debug_printf("Found %s MIME parameter in %s header, "
- "value is '%s'\n", mp->name, mime_header_list[i].name,
- param_value);
+ p = q;
+
+ DEBUG(D_acl) debug_printf("MIME: charset %s fname '%s'\n",
+ mime_filename_charset ? mime_filename_charset : US"<NULL>", p);
+
+ temp_string = rfc2231_to_2047(p, mime_filename_charset, &slen);
+ DEBUG(D_acl) debug_printf("MIME: 2047-name %s\n", temp_string);
+
+ temp_string = rfc2047_decode(temp_string, FALSE, NULL, ' ',
+ NULL, &err_msg);
+ DEBUG(D_acl) debug_printf("MIME: plain-name %s\n", temp_string);
+
+ size = Ustrlen(temp_string);
+
+ if (size == slen)
+ decoding_failed = TRUE;
+ else
+ /* build up a decoded filename over successive
+ filename*= parameters */
+
+ mime_filename = mime_fname = mime_fname
+ ? string_sprintf("%s%s", mime_fname, temp_string)
+ : temp_string;
}
- *mp->value = param_value;
- p += (mp->namelen + param_value_len + 1);
- goto NEXT_PARAM_SEARCH;
+ }
}
- }
+
+ else
+ /* look for interesting parameters */
+ for (mp = mime_parameter_list;
+ mp < mime_parameter_list + nelem(mime_parameter_list);
+ mp++
+ ) if (strncmpic(mp->name, p, mp->namelen) == 0)
+ {
+ uschar * q;
+ uschar * dummy_errstr;
+
+ /* grab the value and copy to its expansion variable */
+ p += mp->namelen;
+ q = mime_param_val(&p); /* p now trailing ; or NUL */
+
+ *mp->value = q && *q
+ ? rfc2047_decode(q, check_rfc2047_length, NULL, 32, NULL,
+ &dummy_errstr)
+ : NULL;
+ DEBUG(D_acl) debug_printf(
+ "MIME: found %s parameter in %s header, value '%s'\n",
+ mp->name, mh->name, *mp->value);
+
+ break; /* done matching param names */
+ }
+
+
/* There is something, but not one of our interesting parameters.
- Advance to the next semicolon */
- while(*p != ';') p++;
- p++;
+ Advance past the next semicolon */
+ p = mime_next_semicolon(p);
+ if (*p) p++;
+ } /* param scan on line */
+
+ if (strncmpic(CUS"content-disposition:", header, 20) == 0)
+ {
+ if (decoding_failed) mime_filename = mime_fname_rfc2231;
+
+ DEBUG(D_acl) debug_printf(
+ "MIME: found %s parameter in %s header, value is '%s'\n",
+ "filename", mh->name, mime_filename);
+ }
}
}
}
- }
/* set additional flag variables (easier access) */
- if ( (mime_content_type != NULL) &&
- (Ustrncmp(mime_content_type,"multipart",9) == 0) )
+ if ( mime_content_type
+ && Ustrncmp(mime_content_type,"multipart",9) == 0
+ )
mime_is_multipart = 1;
/* Make a copy of the boundary pointer.
(nested_context.boundary != NULL) &&
(Ustrncmp(mime_content_type,"multipart",9) == 0) )
{
- debug_printf("Entering multipart recursion, boundary '%s'\n", nested_context.boundary);
+ DEBUG(D_acl)
+ debug_printf("MIME: Entering multipart recursion, boundary '%s'\n",
+ nested_context.boundary);
nested_context.context =
context && context->context == MBC_ATTACHMENT
else if ( (mime_content_type != NULL) &&
(Ustrncmp(mime_content_type,"message/rfc822",14) == 0) )
{
- uschar *rfc822name = NULL;
+ const uschar *rfc822name = NULL;
uschar filename[2048];
int file_nr = 0;
int result = 0;
{
log_write(0, LOG_MAIN,
"mime_regex acl condition warning - could not decode RFC822 MIME part to file.");
- return DEFER;
+ rc = DEFER;
+ goto out;
}
mime_decoded_filename = NULL;
}
NO_RFC822:
/* If the boundary of this instance is NULL, we are finished here */
- if (context == NULL) break;
+ if (!context) break;
if (context->context == MBC_COVERLETTER_ONESHOT)
context->context = MBC_ATTACHMENT;
}
+out:
+mime_vars_reset();
return rc;
}
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) Tom Kistner <tom@duncanthrax.net> 2004 */
+/* Copyright (c) Tom Kistner <tom@duncanthrax.net> 2004, 2015 */
/* License: GPL */
#ifdef WITH_CONTENT_SCAN
};
typedef struct mime_header {
- uschar *name;
- int namelen;
- void *value;
+ uschar * name;
+ int namelen;
+ uschar ** value;
} mime_header;
static mime_header mime_header_list[] = {
- { US"content-type:", 13, &mime_content_type },
- { US"content-disposition:", 20, &mime_content_disposition },
+ { US"content-type:", 13, &mime_content_type },
+ { US"content-disposition:", 20, &mime_content_disposition },
{ US"content-transfer-encoding:", 26, &mime_content_transfer_encoding },
- { US"content-id:", 11, &mime_content_id },
- { US"content-description:", 20 , &mime_content_description }
+ { US"content-id:", 11, &mime_content_id },
+ { US"content-description:", 20, &mime_content_description }
};
static int mime_header_list_size = sizeof(mime_header_list)/sizeof(mime_header);
static mime_parameter mime_parameter_list[] = {
{ US"name=", 5, &mime_filename },
{ US"filename=", 9, &mime_filename },
- { US"charset=", 8, &mime_charset },
+ { US"charset=", 8, &mime_charset },
{ US"boundary=", 9, &mime_boundary }
};
-static int mime_parameter_list_size = sizeof(mime_parameter_list)/sizeof(mime_parameter);
-
/* MIME Anomaly list */
#define MIME_ANOMALY_BROKEN_BASE64 2, "Broken BASE64 encoding detected"
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Functions for sending messages to sender or to mailmaster. */
moan_check_errorcopy(uschar *recipient)
{
uschar *item, *localpart, *domain;
-uschar *listptr = errors_copy;
+const uschar *listptr = errors_copy;
uschar *yield = NULL;
uschar buffer[256];
int sep = 0;
while ((item = string_nextinlist(&listptr, &sep, buffer, sizeof(buffer)))
!= NULL)
{
- uschar *newaddress = item;
- uschar *pattern = string_dequote(&newaddress);
+ const uschar *newaddress = item;
+ const uschar *pattern = string_dequote(&newaddress);
/* If no new address found, just skip this item. */
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2012 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
#define US (unsigned char *)
#define CUS (const unsigned char *)
#define USS (unsigned char **)
+#define CUSS (const unsigned char **)
/* The C library string functions expect "char *" arguments. Use macros to
avoid having to write a cast each time. We do this for string and file
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Functions for parsing addresses */
{
s = read_local_part(s, t, errorptr, FALSE);
if (*errorptr == NULL)
- {
if (*s != term)
- {
if (*s != '@')
*errorptr = string_sprintf("\"@\" or \".\" expected after \"%s\"", t);
else
*domainptr = t;
s = read_domain(s, t, errorptr);
}
- }
- }
return s;
}
return NULL;
}
-return (uschar *)yield;
+return yield;
/* Use goto (via the macro FAILED) to get to here from a variety of places.
We might have an empty address in a group - the caller can choose to ignore
the introduction
*/
-uschar *
-parse_quote_2047(uschar *string, int len, uschar *charset, uschar *buffer,
+const uschar *
+parse_quote_2047(const uschar *string, int len, uschar *charset, uschar *buffer,
int buffer_size, BOOL fold)
{
-uschar *s = string;
+const uschar *s = string;
uschar *p, *t;
int hlen;
BOOL coded = FALSE;
{
*t++ = '_';
first_byte = FALSE;
- }
+ }
else
{
sprintf(CS t, "=%02X", ch);
Returns: the fixed RFC822 phrase
*/
-uschar *
-parse_fix_phrase(uschar *phrase, int len, uschar *buffer, int buffer_size)
+const uschar *
+parse_fix_phrase(const uschar *phrase, int len, uschar *buffer, int buffer_size)
{
int ch, i;
BOOL quoted = FALSE;
-uschar *s, *t, *end, *yield;
+const uschar *s, *end;
+uschar *t, *yield;
while (len > 0 && isspace(*phrase)) { phrase++; len--; }
if (len > buffer_size/4) return US"Name too long";
else if (ch == '(')
{
- uschar *ss = s; /* uschar after '(' */
+ const uschar *ss = s; /* uschar after '(' */
int level = 1;
while(ss < end)
{
int
parse_forward_list(uschar *s, int options, address_item **anchor,
- uschar **error, uschar *incoming_domain, uschar *directory,
+ uschar **error, const uschar *incoming_domain, uschar *directory,
error_block **syntax_errors)
{
int count = 0;
# Make file for building the pdkim library.
-OBJ = base64.o bignum.o pdkim.o rsa.o sha1.o sha2.o
+OBJ = base64.o bignum.o pdkim.o rsa.o sha1.o sha2.o part-x509parse.o pdkim-rsa.o
pdkim.a: $(OBJ)
@$(RM_COMMAND) -f pdkim.a
.SUFFIXES: .o .c
.c.o:; @echo "$(CC) $*.c"
- $(FE)$(CC) -c $(CFLAGS) $(INCLUDE) $*.c
+ $(FE)$(CC) -c $(CFLAGS) $(INCLUDE) -I. $*.c
base64.o: $(HDRS) base64.c
bignum.o: $(HDRS) bignum.c
-pdkim.o: $(HDRS) pdkim.c
+part-x509parse.o: $(HDRS) part-x509parse.c
+pdkim.o: $(HDRS) pdkim.h pdkim-rsa.h pdkim.c
+pdkim-rsa.o: $(HDRS) polarssl/private-x509parse_c.h polarssl/base64.h \
+ pdkim-rsa.h pdkim-rsa.c
rsa.o: $(HDRS) rsa.c
sha1.o: $(HDRS) sha1.c
sha2.o: $(HDRS) sha2.c
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include "base64.h"
+#include "polarssl/config.h"
+
+#if defined(POLARSSL_BASE64_C)
+
+#include "polarssl/base64.h"
static const unsigned char base64_enc_map[64] =
{
for( i = j = n = 0; i < slen; i++ )
{
+ unsigned char c = src[i];
+
if( ( slen - i ) >= 2 &&
- src[i] == '\r' && src[i + 1] == '\n' )
+ c == '\r' && src[i + 1] == '\n' )
continue;
- if( src[i] == '\n' )
+ if( c == '\n' || c == ' ' || c == '\t' )
continue;
- if( src[i] == '=' && ++j > 2 )
+ if( c == '=' && ++j > 2 )
return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
- if( src[i] > 127 || base64_dec_map[src[i]] == 127 )
+ if( c > 127 || base64_dec_map[src[i]] == 127 )
return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
- if( base64_dec_map[src[i]] < 64 && j != 0 )
+ if( base64_dec_map[c] < 64 && j != 0 )
return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
n++;
for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
{
- if( *src == '\r' || *src == '\n' )
+ unsigned char c = *src;
+
+ if( c == '\r' || c == '\n' || c == ' ' || c == '\t' )
continue;
- j -= ( base64_dec_map[*src] == 64 );
- x = (x << 6) | ( base64_dec_map[*src] & 0x3F );
+ j -= ( base64_dec_map[c] == 64 );
+ x = (x << 6) | ( base64_dec_map[c] & 0x3F );
if( ++n == 4 )
{
return( 0 );
}
+
+#if defined(POLARSSL_SELF_TEST)
+
+#include <string.h>
+#include <stdio.h>
+
+static const unsigned char base64_test_dec[64] =
+{
+ 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
+ 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
+ 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
+ 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
+ 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
+ 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
+ 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
+ 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
+};
+
+static const unsigned char base64_test_enc[] =
+ "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
+ "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
+
+/*
+ * Checkup routine
+ */
+int base64_self_test( int verbose )
+{
+ int len;
+ unsigned char *src, buffer[128];
+
+ if( verbose != 0 )
+ printf( " Base64 encoding test: " );
+
+ len = sizeof( buffer );
+ src = (unsigned char *) base64_test_dec;
+
+ if( base64_encode( buffer, &len, src, 64 ) != 0 ||
+ memcmp( base64_test_enc, buffer, 88 ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n Base64 decoding test: " );
+
+ len = sizeof( buffer );
+ src = (unsigned char *) base64_test_enc;
+
+ if( base64_decode( buffer, &len, src, 88 ) != 0 ||
+ memcmp( base64_test_dec, buffer, 64 ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n\n" );
+
+ return( 0 );
+}
+
+#endif
+
+#endif
+++ /dev/null
-/**
- * \file base64.h
- *
- * Copyright (C) 2006-2010, Brainspark B.V.
- *
- * This file is part of PolarSSL (http://www.polarssl.org)
- * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
- *
- * 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef POLARSSL_BASE64_H
-#define POLARSSL_BASE64_H
-
-#define POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL 0x0010
-#define POLARSSL_ERR_BASE64_INVALID_CHARACTER 0x0012
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \brief Encode a buffer into base64 format
- *
- * \param dst destination buffer
- * \param dlen size of the buffer
- * \param src source buffer
- * \param slen amount of data to be encoded
- *
- * \return 0 if successful, or POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL.
- * *dlen is always updated to reflect the amount
- * of data that has (or would have) been written.
- *
- * \note Call this function with *dlen = 0 to obtain the
- * required buffer size in *dlen
- */
-int base64_encode( unsigned char *dst, int *dlen,
- const unsigned char *src, int slen );
-
-/**
- * \brief Decode a base64-formatted buffer
- *
- * \param dst destination buffer
- * \param dlen size of the buffer
- * \param src source buffer
- * \param slen amount of data to be decoded
- *
- * \return 0 if successful, POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL, or
- * POLARSSL_ERR_BASE64_INVALID_DATA if the input data is not
- * correct. *dlen is always updated to reflect the amount
- * of data that has (or would have) been written.
- *
- * \note Call this function with *dlen = 0 to obtain the
- * required buffer size in *dlen
- */
-int base64_decode( unsigned char *dst, int *dlen,
- const unsigned char *src, int slen );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* base64.h */
* http://math.libtomcrypt.com/files/tommath.pdf
*/
-#include "bignum.h"
-#include "bn_mul.h"
+#include "polarssl/config.h"
+
+#if defined(POLARSSL_BIGNUM_C)
+
+#include "polarssl/bignum.h"
+#include "polarssl/bn_mul.h"
#include <string.h>
#include <stdlib.h>
}
#endif
+
+#if defined(POLARSSL_SELF_TEST)
+
+#define GCD_PAIR_COUNT 3
+
+static const int gcd_pairs[GCD_PAIR_COUNT][3] =
+{
+ { 693, 609, 21 },
+ { 1764, 868, 28 },
+ { 768454923, 542167814, 1 }
+};
+
+/*
+ * Checkup routine
+ */
+int mpi_self_test( int verbose )
+{
+ int ret, i;
+ mpi A, E, N, X, Y, U, V;
+
+ mpi_init( &A, &E, &N, &X, &Y, &U, &V, NULL );
+
+ MPI_CHK( mpi_read_string( &A, 16,
+ "EFE021C2645FD1DC586E69184AF4A31E" \
+ "D5F53E93B5F123FA41680867BA110131" \
+ "944FE7952E2517337780CB0DB80E61AA" \
+ "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
+
+ MPI_CHK( mpi_read_string( &E, 16,
+ "B2E7EFD37075B9F03FF989C7C5051C20" \
+ "34D2A323810251127E7BF8625A4F49A5" \
+ "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
+ "5B5C25763222FEFCCFC38B832366C29E" ) );
+
+ MPI_CHK( mpi_read_string( &N, 16,
+ "0066A198186C18C10B2F5ED9B522752A" \
+ "9830B69916E535C8F047518A889A43A5" \
+ "94B6BED27A168D31D4A52F88925AA8F5" ) );
+
+ MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
+
+ MPI_CHK( mpi_read_string( &U, 16,
+ "602AB7ECA597A3D6B56FF9829A5E8B85" \
+ "9E857EA95A03512E2BAE7391688D264A" \
+ "A5663B0341DB9CCFD2C4C5F421FEC814" \
+ "8001B72E848A38CAE1C65F78E56ABDEF" \
+ "E12D3C039B8A02D6BE593F0BBBDA56F1" \
+ "ECF677152EF804370C1A305CAF3B5BF1" \
+ "30879B56C61DE584A0F53A2447A51E" ) );
+
+ if( verbose != 0 )
+ printf( " MPI test #1 (mul_mpi): " );
+
+ if( mpi_cmp_mpi( &X, &U ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n" );
+
+ MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );
+
+ MPI_CHK( mpi_read_string( &U, 16,
+ "256567336059E52CAE22925474705F39A94" ) );
+
+ MPI_CHK( mpi_read_string( &V, 16,
+ "6613F26162223DF488E9CD48CC132C7A" \
+ "0AC93C701B001B092E4E5B9F73BCD27B" \
+ "9EE50D0657C77F374E903CDFA4C642" ) );
+
+ if( verbose != 0 )
+ printf( " MPI test #2 (div_mpi): " );
+
+ if( mpi_cmp_mpi( &X, &U ) != 0 ||
+ mpi_cmp_mpi( &Y, &V ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n" );
+
+ MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );
+
+ MPI_CHK( mpi_read_string( &U, 16,
+ "36E139AEA55215609D2816998ED020BB" \
+ "BD96C37890F65171D948E9BC7CBAA4D9" \
+ "325D24D6A3C12710F10A09FA08AB87" ) );
+
+ if( verbose != 0 )
+ printf( " MPI test #3 (exp_mod): " );
+
+ if( mpi_cmp_mpi( &X, &U ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n" );
+
+ MPI_CHK( mpi_inv_mod( &X, &A, &N ) );
+
+ MPI_CHK( mpi_read_string( &U, 16,
+ "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
+ "C3DBA76456363A10869622EAC2DD84EC" \
+ "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
+
+ if( verbose != 0 )
+ printf( " MPI test #4 (inv_mod): " );
+
+ if( mpi_cmp_mpi( &X, &U ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n" );
+
+ if( verbose != 0 )
+ printf( " MPI test #5 (simple gcd): " );
+
+ for ( i = 0; i < GCD_PAIR_COUNT; i++)
+ {
+ MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
+ MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
+
+ MPI_CHK( mpi_gcd( &A, &X, &Y ) );
+
+ if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed at %d\n", i );
+
+ return( 1 );
+ }
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n" );
+
+cleanup:
+
+ if( ret != 0 && verbose != 0 )
+ printf( "Unexpected error, return code = %08X\n", ret );
+
+ mpi_free( &V, &U, &Y, &X, &N, &E, &A, NULL );
+
+ if( verbose != 0 )
+ printf( "\n" );
+
+ return( ret );
+}
+
+#endif
+
+#endif
+++ /dev/null
-/**
- * \file bignum.h
- *
- * Copyright (C) 2006-2010, Brainspark B.V.
- *
- * This file is part of PolarSSL (http://www.polarssl.org)
- * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
- *
- * 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef POLARSSL_BIGNUM_H
-#define POLARSSL_BIGNUM_H
-
-#include <stdio.h>
-
-#define POLARSSL_ERR_MPI_FILE_IO_ERROR 0x0002
-#define POLARSSL_ERR_MPI_BAD_INPUT_DATA 0x0004
-#define POLARSSL_ERR_MPI_INVALID_CHARACTER 0x0006
-#define POLARSSL_ERR_MPI_BUFFER_TOO_SMALL 0x0008
-#define POLARSSL_ERR_MPI_NEGATIVE_VALUE 0x000A
-#define POLARSSL_ERR_MPI_DIVISION_BY_ZERO 0x000C
-#define POLARSSL_ERR_MPI_NOT_ACCEPTABLE 0x000E
-
-#define MPI_CHK(f) if( ( ret = f ) != 0 ) goto cleanup
-
-/*
- * Define the base integer type, architecture-wise
- */
-#if defined(POLARSSL_HAVE_INT8)
-typedef unsigned char t_int;
-typedef unsigned short t_dbl;
-#else
-#if defined(POLARSSL_HAVE_INT16)
-typedef unsigned short t_int;
-typedef unsigned long t_dbl;
-#else
- typedef unsigned long t_int;
- #if defined(_MSC_VER) && defined(_M_IX86)
- typedef unsigned __int64 t_dbl;
- #else
- #if defined(__amd64__) || defined(__x86_64__) || \
- defined(__ppc64__) || defined(__powerpc64__) || \
- defined(__ia64__) || defined(__alpha__)
- typedef unsigned int t_dbl __attribute__((mode(TI)));
- #else
- #if defined(POLARSSL_HAVE_LONGLONG)
- typedef unsigned long long t_dbl;
- #endif
- #endif
- #endif
-#endif
-#endif
-
-/**
- * \brief MPI structure
- */
-typedef struct
-{
- int s; /*!< integer sign */
- int n; /*!< total # of limbs */
- t_int *p; /*!< pointer to limbs */
-}
-mpi;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \brief Initialize one or more mpi
- */
-void mpi_init( mpi *X, ... );
-
-/**
- * \brief Unallocate one or more mpi
- */
-void mpi_free( mpi *X, ... );
-
-/**
- * \brief Enlarge to the specified number of limbs
- *
- * \param X MPI to grow
- * \param nblimbs The target number of limbs
- *
- * \return 0 if successful,
- * 1 if memory allocation failed
- */
-int mpi_grow( mpi *X, int nblimbs );
-
-/**
- * \brief Copy the contents of Y into X
- *
- * \param X Destination MPI
- * \param Y Source MPI
- *
- * \return 0 if successful,
- * 1 if memory allocation failed
- */
-int mpi_copy( mpi *X, const mpi *Y );
-
-/**
- * \brief Swap the contents of X and Y
- *
- * \param X First MPI value
- * \param Y Second MPI value
- */
-void mpi_swap( mpi *X, mpi *Y );
-
-/**
- * \brief Set value from integer
- *
- * \param X MPI to set
- * \param z Value to use
- *
- * \return 0 if successful,
- * 1 if memory allocation failed
- */
-int mpi_lset( mpi *X, int z );
-
-/**
- * \brief Return the number of least significant bits
- *
- * \param X MPI to use
- */
-int mpi_lsb( const mpi *X );
-
-/**
- * \brief Return the number of most significant bits
- *
- * \param X MPI to use
- */
-int mpi_msb( const mpi *X );
-
-/**
- * \brief Return the total size in bytes
- *
- * \param X MPI to use
- */
-int mpi_size( const mpi *X );
-
-/**
- * \brief Import from an ASCII string
- *
- * \param X Destination MPI
- * \param radix Input numeric base
- * \param s Null-terminated string buffer
- *
- * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
- */
-int mpi_read_string( mpi *X, int radix, const char *s );
-
-/**
- * \brief Export into an ASCII string
- *
- * \param X Source MPI
- * \param radix Output numeric base
- * \param s String buffer
- * \param slen String buffer size
- *
- * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code.
- * *slen is always updated to reflect the amount
- * of data that has (or would have) been written.
- *
- * \note Call this function with *slen = 0 to obtain the
- * minimum required buffer size in *slen.
- */
-int mpi_write_string( const mpi *X, int radix, char *s, int *slen );
-
-/**
- * \brief Read X from an opened file
- *
- * \param X Destination MPI
- * \param radix Input numeric base
- * \param fin Input file handle
- *
- * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
- */
-int mpi_read_file( mpi *X, int radix, FILE *fin );
-
-/**
- * \brief Write X into an opened file, or stdout if fout is NULL
- *
- * \param p Prefix, can be NULL
- * \param X Source MPI
- * \param radix Output numeric base
- * \param fout Output file handle (can be NULL)
- *
- * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
- *
- * \note Set fout == NULL to print X on the console.
- */
-int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout );
-
-/**
- * \brief Import X from unsigned binary data, big endian
- *
- * \param X Destination MPI
- * \param buf Input buffer
- * \param buflen Input buffer size
- *
- * \return 0 if successful,
- * 1 if memory allocation failed
- */
-int mpi_read_binary( mpi *X, const unsigned char *buf, int buflen );
-
-/**
- * \brief Export X into unsigned binary data, big endian
- *
- * \param X Source MPI
- * \param buf Output buffer
- * \param buflen Output buffer size
- *
- * \return 0 if successful,
- * POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough
- */
-int mpi_write_binary( const mpi *X, unsigned char *buf, int buflen );
-
-/**
- * \brief Left-shift: X <<= count
- *
- * \param X MPI to shift
- * \param count Amount to shift
- *
- * \return 0 if successful,
- * 1 if memory allocation failed
- */
-int mpi_shift_l( mpi *X, int count );
-
-/**
- * \brief Right-shift: X >>= count
- *
- * \param X MPI to shift
- * \param count Amount to shift
- *
- * \return 0 if successful,
- * 1 if memory allocation failed
- */
-int mpi_shift_r( mpi *X, int count );
-
-/**
- * \brief Compare unsigned values
- *
- * \param X Left-hand MPI
- * \param Y Right-hand MPI
- *
- * \return 1 if |X| is greater than |Y|,
- * -1 if |X| is lesser than |Y| or
- * 0 if |X| is equal to |Y|
- */
-int mpi_cmp_abs( const mpi *X, const mpi *Y );
-
-/**
- * \brief Compare signed values
- *
- * \param X Left-hand MPI
- * \param Y Right-hand MPI
- *
- * \return 1 if X is greater than Y,
- * -1 if X is lesser than Y or
- * 0 if X is equal to Y
- */
-int mpi_cmp_mpi( const mpi *X, const mpi *Y );
-
-/**
- * \brief Compare signed values
- *
- * \param X Left-hand MPI
- * \param z The integer value to compare to
- *
- * \return 1 if X is greater than z,
- * -1 if X is lesser than z or
- * 0 if X is equal to z
- */
-int mpi_cmp_int( const mpi *X, int z );
-
-/**
- * \brief Unsigned addition: X = |A| + |B|
- *
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param B Right-hand MPI
- *
- * \return 0 if successful,
- * 1 if memory allocation failed
- */
-int mpi_add_abs( mpi *X, const mpi *A, const mpi *B );
-
-/**
- * \brief Unsigned substraction: X = |A| - |B|
- *
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param B Right-hand MPI
- *
- * \return 0 if successful,
- * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B is greater than A
- */
-int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B );
-
-/**
- * \brief Signed addition: X = A + B
- *
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param B Right-hand MPI
- *
- * \return 0 if successful,
- * 1 if memory allocation failed
- */
-int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B );
-
-/**
- * \brief Signed substraction: X = A - B
- *
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param B Right-hand MPI
- *
- * \return 0 if successful,
- * 1 if memory allocation failed
- */
-int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B );
-
-/**
- * \brief Signed addition: X = A + b
- *
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param b The integer value to add
- *
- * \return 0 if successful,
- * 1 if memory allocation failed
- */
-int mpi_add_int( mpi *X, const mpi *A, int b );
-
-/**
- * \brief Signed substraction: X = A - b
- *
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param b The integer value to subtract
- *
- * \return 0 if successful,
- * 1 if memory allocation failed
- */
-int mpi_sub_int( mpi *X, const mpi *A, int b );
-
-/**
- * \brief Baseline multiplication: X = A * B
- *
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param B Right-hand MPI
- *
- * \return 0 if successful,
- * 1 if memory allocation failed
- */
-int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B );
-
-/**
- * \brief Baseline multiplication: X = A * b
- * Note: b is an unsigned integer type, thus
- * Negative values of b are ignored.
- *
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param b The integer value to multiply with
- *
- * \return 0 if successful,
- * 1 if memory allocation failed
- */
-int mpi_mul_int( mpi *X, const mpi *A, t_int b );
-
-/**
- * \brief Division by mpi: A = Q * B + R
- *
- * \param Q Destination MPI for the quotient
- * \param R Destination MPI for the rest value
- * \param A Left-hand MPI
- * \param B Right-hand MPI
- *
- * \return 0 if successful,
- * 1 if memory allocation failed,
- * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0
- *
- * \note Either Q or R can be NULL.
- */
-int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B );
-
-/**
- * \brief Division by int: A = Q * b + R
- *
- * \param Q Destination MPI for the quotient
- * \param R Destination MPI for the rest value
- * \param A Left-hand MPI
- * \param b Integer to divide by
- *
- * \return 0 if successful,
- * 1 if memory allocation failed,
- * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
- *
- * \note Either Q or R can be NULL.
- */
-int mpi_div_int( mpi *Q, mpi *R, const mpi *A, int b );
-
-/**
- * \brief Modulo: R = A mod B
- *
- * \param R Destination MPI for the rest value
- * \param A Left-hand MPI
- * \param B Right-hand MPI
- *
- * \return 0 if successful,
- * 1 if memory allocation failed,
- * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0,
- * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B < 0
- */
-int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B );
-
-/**
- * \brief Modulo: r = A mod b
- *
- * \param r Destination t_int
- * \param A Left-hand MPI
- * \param b Integer to divide by
- *
- * \return 0 if successful,
- * 1 if memory allocation failed,
- * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0,
- * POLARSSL_ERR_MPI_NEGATIVE_VALUE if b < 0
- */
-int mpi_mod_int( t_int *r, const mpi *A, int b );
-
-/**
- * \brief Sliding-window exponentiation: X = A^E mod N
- *
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param E Exponent MPI
- * \param N Modular MPI
- * \param _RR Speed-up MPI used for recalculations
- *
- * \return 0 if successful,
- * 1 if memory allocation failed,
- * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or even
- *
- * \note _RR is used to avoid re-computing R*R mod N across
- * multiple calls, which speeds up things a bit. It can
- * be set to NULL if the extra performance is unneeded.
- */
-int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR );
-
-/**
- * \brief Greatest common divisor: G = gcd(A, B)
- *
- * \param G Destination MPI
- * \param A Left-hand MPI
- * \param B Right-hand MPI
- *
- * \return 0 if successful,
- * 1 if memory allocation failed
- */
-int mpi_gcd( mpi *G, const mpi *A, const mpi *B );
-
-/**
- * \brief Modular inverse: X = A^-1 mod N
- *
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param N Right-hand MPI
- *
- * \return 0 if successful,
- * 1 if memory allocation failed,
- * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or nil
- POLARSSL_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N
- */
-int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N );
-
-/**
- * \brief Miller-Rabin primality test
- *
- * \param X MPI to check
- * \param f_rng RNG function
- * \param p_rng RNG parameter
- *
- * \return 0 if successful (probably prime),
- * 1 if memory allocation failed,
- * POLARSSL_ERR_MPI_NOT_ACCEPTABLE if X is not prime
- */
-int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng );
-
-/**
- * \brief Prime number generation
- *
- * \param X Destination MPI
- * \param nbits Required size of X in bits
- * \param dh_flag If 1, then (X-1)/2 will be prime too
- * \param f_rng RNG function
- * \param p_rng RNG parameter
- *
- * \return 0 if successful (probably prime),
- * 1 if memory allocation failed,
- * POLARSSL_ERR_MPI_BAD_INPUT_DATA if nbits is < 3
- */
-int mpi_gen_prime( mpi *X, int nbits, int dh_flag,
- int (*f_rng)(void *), void *p_rng );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* bignum.h */
+++ /dev/null
-/**
- * \file bn_mul.h
- *
- * Copyright (C) 2006-2010, Brainspark B.V.
- *
- * This file is part of PolarSSL (http://www.polarssl.org)
- * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
- *
- * 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-/*
- * Multiply source vector [s] with b, add result
- * to destination vector [d] and set carry c.
- *
- * Currently supports:
- *
- * . IA-32 (386+) . AMD64 / EM64T
- * . IA-32 (SSE2) . Motorola 68000
- * . PowerPC, 32-bit . MicroBlaze
- * . PowerPC, 64-bit . TriCore
- * . SPARC v8 . ARM v3+
- * . Alpha . MIPS32
- * . C, longlong . C, generic
- */
-
-#ifndef POLARSSL_BN_MUL_H
-#define POLARSSL_BN_MUL_H
-
-#if defined(POLARSSL_HAVE_ASM)
-
-#if defined(__GNUC__)
-#if defined(__i386__)
-
-#define MULADDC_INIT \
- asm( " \
- movl %%ebx, %0; \
- movl %5, %%esi; \
- movl %6, %%edi; \
- movl %7, %%ecx; \
- movl %8, %%ebx; \
- "
-
-#define MULADDC_CORE \
- " \
- lodsl; \
- mull %%ebx; \
- addl %%ecx, %%eax; \
- adcl $0, %%edx; \
- addl (%%edi), %%eax; \
- adcl $0, %%edx; \
- movl %%edx, %%ecx; \
- stosl; \
- "
-
-#if defined(POLARSSL_HAVE_SSE2)
-
-#define MULADDC_HUIT \
- " \
- movd %%ecx, %%mm1; \
- movd %%ebx, %%mm0; \
- movd (%%edi), %%mm3; \
- paddq %%mm3, %%mm1; \
- movd (%%esi), %%mm2; \
- pmuludq %%mm0, %%mm2; \
- movd 4(%%esi), %%mm4; \
- pmuludq %%mm0, %%mm4; \
- movd 8(%%esi), %%mm6; \
- pmuludq %%mm0, %%mm6; \
- movd 12(%%esi), %%mm7; \
- pmuludq %%mm0, %%mm7; \
- paddq %%mm2, %%mm1; \
- movd 4(%%edi), %%mm3; \
- paddq %%mm4, %%mm3; \
- movd 8(%%edi), %%mm5; \
- paddq %%mm6, %%mm5; \
- movd 12(%%edi), %%mm4; \
- paddq %%mm4, %%mm7; \
- movd %%mm1, (%%edi); \
- movd 16(%%esi), %%mm2; \
- pmuludq %%mm0, %%mm2; \
- psrlq $32, %%mm1; \
- movd 20(%%esi), %%mm4; \
- pmuludq %%mm0, %%mm4; \
- paddq %%mm3, %%mm1; \
- movd 24(%%esi), %%mm6; \
- pmuludq %%mm0, %%mm6; \
- movd %%mm1, 4(%%edi); \
- psrlq $32, %%mm1; \
- movd 28(%%esi), %%mm3; \
- pmuludq %%mm0, %%mm3; \
- paddq %%mm5, %%mm1; \
- movd 16(%%edi), %%mm5; \
- paddq %%mm5, %%mm2; \
- movd %%mm1, 8(%%edi); \
- psrlq $32, %%mm1; \
- paddq %%mm7, %%mm1; \
- movd 20(%%edi), %%mm5; \
- paddq %%mm5, %%mm4; \
- movd %%mm1, 12(%%edi); \
- psrlq $32, %%mm1; \
- paddq %%mm2, %%mm1; \
- movd 24(%%edi), %%mm5; \
- paddq %%mm5, %%mm6; \
- movd %%mm1, 16(%%edi); \
- psrlq $32, %%mm1; \
- paddq %%mm4, %%mm1; \
- movd 28(%%edi), %%mm5; \
- paddq %%mm5, %%mm3; \
- movd %%mm1, 20(%%edi); \
- psrlq $32, %%mm1; \
- paddq %%mm6, %%mm1; \
- movd %%mm1, 24(%%edi); \
- psrlq $32, %%mm1; \
- paddq %%mm3, %%mm1; \
- movd %%mm1, 28(%%edi); \
- addl $32, %%edi; \
- addl $32, %%esi; \
- psrlq $32, %%mm1; \
- movd %%mm1, %%ecx; \
- "
-
-#define MULADDC_STOP \
- " \
- emms; \
- movl %4, %%ebx; \
- movl %%ecx, %1; \
- movl %%edi, %2; \
- movl %%esi, %3; \
- " \
- : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
- : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
- : "eax", "ecx", "edx", "esi", "edi" \
- );
-
-#else
-
-#define MULADDC_STOP \
- " \
- movl %4, %%ebx; \
- movl %%ecx, %1; \
- movl %%edi, %2; \
- movl %%esi, %3; \
- " \
- : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
- : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
- : "eax", "ecx", "edx", "esi", "edi" \
- );
-#endif /* SSE2 */
-#endif /* i386 */
-
-#if defined(__amd64__) || defined (__x86_64__)
-
-#define MULADDC_INIT \
- asm( "movq %0, %%rsi " :: "m" (s)); \
- asm( "movq %0, %%rdi " :: "m" (d)); \
- asm( "movq %0, %%rcx " :: "m" (c)); \
- asm( "movq %0, %%rbx " :: "m" (b)); \
- asm( "xorq %r8, %r8 " );
-
-#define MULADDC_CORE \
- asm( "movq (%rsi),%rax " ); \
- asm( "mulq %rbx " ); \
- asm( "addq $8, %rsi " ); \
- asm( "addq %rcx, %rax " ); \
- asm( "movq %r8, %rcx " ); \
- asm( "adcq $0, %rdx " ); \
- asm( "nop " ); \
- asm( "addq %rax, (%rdi) " ); \
- asm( "adcq %rdx, %rcx " ); \
- asm( "addq $8, %rdi " );
-
-#define MULADDC_STOP \
- asm( "movq %%rcx, %0 " : "=m" (c)); \
- asm( "movq %%rdi, %0 " : "=m" (d)); \
- asm( "movq %%rsi, %0 " : "=m" (s) :: \
- "rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8" );
-
-#endif /* AMD64 */
-
-#if defined(__mc68020__) || defined(__mcpu32__)
-
-#define MULADDC_INIT \
- asm( "movl %0, %%a2 " :: "m" (s)); \
- asm( "movl %0, %%a3 " :: "m" (d)); \
- asm( "movl %0, %%d3 " :: "m" (c)); \
- asm( "movl %0, %%d2 " :: "m" (b)); \
- asm( "moveq #0, %d0 " );
-
-#define MULADDC_CORE \
- asm( "movel %a2@+, %d1 " ); \
- asm( "mulul %d2, %d4:%d1 " ); \
- asm( "addl %d3, %d1 " ); \
- asm( "addxl %d0, %d4 " ); \
- asm( "moveq #0, %d3 " ); \
- asm( "addl %d1, %a3@+ " ); \
- asm( "addxl %d4, %d3 " );
-
-#define MULADDC_STOP \
- asm( "movl %%d3, %0 " : "=m" (c)); \
- asm( "movl %%a3, %0 " : "=m" (d)); \
- asm( "movl %%a2, %0 " : "=m" (s) :: \
- "d0", "d1", "d2", "d3", "d4", "a2", "a3" );
-
-#define MULADDC_HUIT \
- asm( "movel %a2@+, %d1 " ); \
- asm( "mulul %d2, %d4:%d1 " ); \
- asm( "addxl %d3, %d1 " ); \
- asm( "addxl %d0, %d4 " ); \
- asm( "addl %d1, %a3@+ " ); \
- asm( "movel %a2@+, %d1 " ); \
- asm( "mulul %d2, %d3:%d1 " ); \
- asm( "addxl %d4, %d1 " ); \
- asm( "addxl %d0, %d3 " ); \
- asm( "addl %d1, %a3@+ " ); \
- asm( "movel %a2@+, %d1 " ); \
- asm( "mulul %d2, %d4:%d1 " ); \
- asm( "addxl %d3, %d1 " ); \
- asm( "addxl %d0, %d4 " ); \
- asm( "addl %d1, %a3@+ " ); \
- asm( "movel %a2@+, %d1 " ); \
- asm( "mulul %d2, %d3:%d1 " ); \
- asm( "addxl %d4, %d1 " ); \
- asm( "addxl %d0, %d3 " ); \
- asm( "addl %d1, %a3@+ " ); \
- asm( "movel %a2@+, %d1 " ); \
- asm( "mulul %d2, %d4:%d1 " ); \
- asm( "addxl %d3, %d1 " ); \
- asm( "addxl %d0, %d4 " ); \
- asm( "addl %d1, %a3@+ " ); \
- asm( "movel %a2@+, %d1 " ); \
- asm( "mulul %d2, %d3:%d1 " ); \
- asm( "addxl %d4, %d1 " ); \
- asm( "addxl %d0, %d3 " ); \
- asm( "addl %d1, %a3@+ " ); \
- asm( "movel %a2@+, %d1 " ); \
- asm( "mulul %d2, %d4:%d1 " ); \
- asm( "addxl %d3, %d1 " ); \
- asm( "addxl %d0, %d4 " ); \
- asm( "addl %d1, %a3@+ " ); \
- asm( "movel %a2@+, %d1 " ); \
- asm( "mulul %d2, %d3:%d1 " ); \
- asm( "addxl %d4, %d1 " ); \
- asm( "addxl %d0, %d3 " ); \
- asm( "addl %d1, %a3@+ " ); \
- asm( "addxl %d0, %d3 " );
-
-#endif /* MC68000 */
-
-#if defined(__powerpc__) || defined(__ppc__)
-#if defined(__powerpc64__) || defined(__ppc64__)
-
-#if defined(__MACH__) && defined(__APPLE__)
-
-#define MULADDC_INIT \
- asm( "ld r3, %0 " :: "m" (s)); \
- asm( "ld r4, %0 " :: "m" (d)); \
- asm( "ld r5, %0 " :: "m" (c)); \
- asm( "ld r6, %0 " :: "m" (b)); \
- asm( "addi r3, r3, -8 " ); \
- asm( "addi r4, r4, -8 " ); \
- asm( "addic r5, r5, 0 " );
-
-#define MULADDC_CORE \
- asm( "ldu r7, 8(r3) " ); \
- asm( "mulld r8, r7, r6 " ); \
- asm( "mulhdu r9, r7, r6 " ); \
- asm( "adde r8, r8, r5 " ); \
- asm( "ld r7, 8(r4) " ); \
- asm( "addze r5, r9 " ); \
- asm( "addc r8, r8, r7 " ); \
- asm( "stdu r8, 8(r4) " );
-
-#define MULADDC_STOP \
- asm( "addze r5, r5 " ); \
- asm( "addi r4, r4, 8 " ); \
- asm( "addi r3, r3, 8 " ); \
- asm( "std r5, %0 " : "=m" (c)); \
- asm( "std r4, %0 " : "=m" (d)); \
- asm( "std r3, %0 " : "=m" (s) :: \
- "r3", "r4", "r5", "r6", "r7", "r8", "r9" );
-
-#else
-
-#define MULADDC_INIT \
- asm( "ld %%r3, %0 " :: "m" (s)); \
- asm( "ld %%r4, %0 " :: "m" (d)); \
- asm( "ld %%r5, %0 " :: "m" (c)); \
- asm( "ld %%r6, %0 " :: "m" (b)); \
- asm( "addi %r3, %r3, -8 " ); \
- asm( "addi %r4, %r4, -8 " ); \
- asm( "addic %r5, %r5, 0 " );
-
-#define MULADDC_CORE \
- asm( "ldu %r7, 8(%r3) " ); \
- asm( "mulld %r8, %r7, %r6 " ); \
- asm( "mulhdu %r9, %r7, %r6 " ); \
- asm( "adde %r8, %r8, %r5 " ); \
- asm( "ld %r7, 8(%r4) " ); \
- asm( "addze %r5, %r9 " ); \
- asm( "addc %r8, %r8, %r7 " ); \
- asm( "stdu %r8, 8(%r4) " );
-
-#define MULADDC_STOP \
- asm( "addze %r5, %r5 " ); \
- asm( "addi %r4, %r4, 8 " ); \
- asm( "addi %r3, %r3, 8 " ); \
- asm( "std %%r5, %0 " : "=m" (c)); \
- asm( "std %%r4, %0 " : "=m" (d)); \
- asm( "std %%r3, %0 " : "=m" (s) :: \
- "r3", "r4", "r5", "r6", "r7", "r8", "r9" );
-
-#endif
-
-#else /* PPC32 */
-
-#if defined(__MACH__) && defined(__APPLE__)
-
-#define MULADDC_INIT \
- asm( "lwz r3, %0 " :: "m" (s)); \
- asm( "lwz r4, %0 " :: "m" (d)); \
- asm( "lwz r5, %0 " :: "m" (c)); \
- asm( "lwz r6, %0 " :: "m" (b)); \
- asm( "addi r3, r3, -4 " ); \
- asm( "addi r4, r4, -4 " ); \
- asm( "addic r5, r5, 0 " );
-
-#define MULADDC_CORE \
- asm( "lwzu r7, 4(r3) " ); \
- asm( "mullw r8, r7, r6 " ); \
- asm( "mulhwu r9, r7, r6 " ); \
- asm( "adde r8, r8, r5 " ); \
- asm( "lwz r7, 4(r4) " ); \
- asm( "addze r5, r9 " ); \
- asm( "addc r8, r8, r7 " ); \
- asm( "stwu r8, 4(r4) " );
-
-#define MULADDC_STOP \
- asm( "addze r5, r5 " ); \
- asm( "addi r4, r4, 4 " ); \
- asm( "addi r3, r3, 4 " ); \
- asm( "stw r5, %0 " : "=m" (c)); \
- asm( "stw r4, %0 " : "=m" (d)); \
- asm( "stw r3, %0 " : "=m" (s) :: \
- "r3", "r4", "r5", "r6", "r7", "r8", "r9" );
-
-#else
-
-#define MULADDC_INIT \
- asm( "lwz %%r3, %0 " :: "m" (s)); \
- asm( "lwz %%r4, %0 " :: "m" (d)); \
- asm( "lwz %%r5, %0 " :: "m" (c)); \
- asm( "lwz %%r6, %0 " :: "m" (b)); \
- asm( "addi %r3, %r3, -4 " ); \
- asm( "addi %r4, %r4, -4 " ); \
- asm( "addic %r5, %r5, 0 " );
-
-#define MULADDC_CORE \
- asm( "lwzu %r7, 4(%r3) " ); \
- asm( "mullw %r8, %r7, %r6 " ); \
- asm( "mulhwu %r9, %r7, %r6 " ); \
- asm( "adde %r8, %r8, %r5 " ); \
- asm( "lwz %r7, 4(%r4) " ); \
- asm( "addze %r5, %r9 " ); \
- asm( "addc %r8, %r8, %r7 " ); \
- asm( "stwu %r8, 4(%r4) " );
-
-#define MULADDC_STOP \
- asm( "addze %r5, %r5 " ); \
- asm( "addi %r4, %r4, 4 " ); \
- asm( "addi %r3, %r3, 4 " ); \
- asm( "stw %%r5, %0 " : "=m" (c)); \
- asm( "stw %%r4, %0 " : "=m" (d)); \
- asm( "stw %%r3, %0 " : "=m" (s) :: \
- "r3", "r4", "r5", "r6", "r7", "r8", "r9" );
-
-#endif
-
-#endif /* PPC32 */
-#endif /* PPC64 */
-
-#if defined(__sparc__)
-
-#define MULADDC_INIT \
- asm( "ld %0, %%o0 " :: "m" (s)); \
- asm( "ld %0, %%o1 " :: "m" (d)); \
- asm( "ld %0, %%o2 " :: "m" (c)); \
- asm( "ld %0, %%o3 " :: "m" (b));
-
-#define MULADDC_CORE \
- asm( "ld [%o0], %o4 " ); \
- asm( "inc 4, %o0 " ); \
- asm( "ld [%o1], %o5 " ); \
- asm( "umul %o3, %o4, %o4 " ); \
- asm( "addcc %o4, %o2, %o4 " ); \
- asm( "rd %y, %g1 " ); \
- asm( "addx %g1, 0, %g1 " ); \
- asm( "addcc %o4, %o5, %o4 " ); \
- asm( "st %o4, [%o1] " ); \
- asm( "addx %g1, 0, %o2 " ); \
- asm( "inc 4, %o1 " );
-
-#define MULADDC_STOP \
- asm( "st %%o2, %0 " : "=m" (c)); \
- asm( "st %%o1, %0 " : "=m" (d)); \
- asm( "st %%o0, %0 " : "=m" (s) :: \
- "g1", "o0", "o1", "o2", "o3", "o4", "o5" );
-
-#endif /* SPARCv8 */
-
-#if defined(__microblaze__) || defined(microblaze)
-
-#define MULADDC_INIT \
- asm( "lwi r3, %0 " :: "m" (s)); \
- asm( "lwi r4, %0 " :: "m" (d)); \
- asm( "lwi r5, %0 " :: "m" (c)); \
- asm( "lwi r6, %0 " :: "m" (b)); \
- asm( "andi r7, r6, 0xffff" ); \
- asm( "bsrli r6, r6, 16 " );
-
-#define MULADDC_CORE \
- asm( "lhui r8, r3, 0 " ); \
- asm( "addi r3, r3, 2 " ); \
- asm( "lhui r9, r3, 0 " ); \
- asm( "addi r3, r3, 2 " ); \
- asm( "mul r10, r9, r6 " ); \
- asm( "mul r11, r8, r7 " ); \
- asm( "mul r12, r9, r7 " ); \
- asm( "mul r13, r8, r6 " ); \
- asm( "bsrli r8, r10, 16 " ); \
- asm( "bsrli r9, r11, 16 " ); \
- asm( "add r13, r13, r8 " ); \
- asm( "add r13, r13, r9 " ); \
- asm( "bslli r10, r10, 16 " ); \
- asm( "bslli r11, r11, 16 " ); \
- asm( "add r12, r12, r10 " ); \
- asm( "addc r13, r13, r0 " ); \
- asm( "add r12, r12, r11 " ); \
- asm( "addc r13, r13, r0 " ); \
- asm( "lwi r10, r4, 0 " ); \
- asm( "add r12, r12, r10 " ); \
- asm( "addc r13, r13, r0 " ); \
- asm( "add r12, r12, r5 " ); \
- asm( "addc r5, r13, r0 " ); \
- asm( "swi r12, r4, 0 " ); \
- asm( "addi r4, r4, 4 " );
-
-#define MULADDC_STOP \
- asm( "swi r5, %0 " : "=m" (c)); \
- asm( "swi r4, %0 " : "=m" (d)); \
- asm( "swi r3, %0 " : "=m" (s) :: \
- "r3", "r4" , "r5" , "r6" , "r7" , "r8" , \
- "r9", "r10", "r11", "r12", "r13" );
-
-#endif /* MicroBlaze */
-
-#if defined(__tricore__)
-
-#define MULADDC_INIT \
- asm( "ld.a %%a2, %0 " :: "m" (s)); \
- asm( "ld.a %%a3, %0 " :: "m" (d)); \
- asm( "ld.w %%d4, %0 " :: "m" (c)); \
- asm( "ld.w %%d1, %0 " :: "m" (b)); \
- asm( "xor %d5, %d5 " );
-
-#define MULADDC_CORE \
- asm( "ld.w %d0, [%a2+] " ); \
- asm( "madd.u %e2, %e4, %d0, %d1 " ); \
- asm( "ld.w %d0, [%a3] " ); \
- asm( "addx %d2, %d2, %d0 " ); \
- asm( "addc %d3, %d3, 0 " ); \
- asm( "mov %d4, %d3 " ); \
- asm( "st.w [%a3+], %d2 " );
-
-#define MULADDC_STOP \
- asm( "st.w %0, %%d4 " : "=m" (c)); \
- asm( "st.a %0, %%a3 " : "=m" (d)); \
- asm( "st.a %0, %%a2 " : "=m" (s) :: \
- "d0", "d1", "e2", "d4", "a2", "a3" );
-
-#endif /* TriCore */
-
-#if defined(__arm__)
-
-#define MULADDC_INIT \
- asm( "ldr r0, %0 " :: "m" (s)); \
- asm( "ldr r1, %0 " :: "m" (d)); \
- asm( "ldr r2, %0 " :: "m" (c)); \
- asm( "ldr r3, %0 " :: "m" (b));
-
-#define MULADDC_CORE \
- asm( "ldr r4, [r0], #4 " ); \
- asm( "mov r5, #0 " ); \
- asm( "ldr r6, [r1] " ); \
- asm( "umlal r2, r5, r3, r4 " ); \
- asm( "adds r7, r6, r2 " ); \
- asm( "adc r2, r5, #0 " ); \
- asm( "str r7, [r1], #4 " );
-
-#define MULADDC_STOP \
- asm( "str r2, %0 " : "=m" (c)); \
- asm( "str r1, %0 " : "=m" (d)); \
- asm( "str r0, %0 " : "=m" (s) :: \
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" );
-
-#endif /* ARMv3 */
-
-#if defined(__alpha__)
-
-#define MULADDC_INIT \
- asm( "ldq $1, %0 " :: "m" (s)); \
- asm( "ldq $2, %0 " :: "m" (d)); \
- asm( "ldq $3, %0 " :: "m" (c)); \
- asm( "ldq $4, %0 " :: "m" (b));
-
-#define MULADDC_CORE \
- asm( "ldq $6, 0($1) " ); \
- asm( "addq $1, 8, $1 " ); \
- asm( "mulq $6, $4, $7 " ); \
- asm( "umulh $6, $4, $6 " ); \
- asm( "addq $7, $3, $7 " ); \
- asm( "cmpult $7, $3, $3 " ); \
- asm( "ldq $5, 0($2) " ); \
- asm( "addq $7, $5, $7 " ); \
- asm( "cmpult $7, $5, $5 " ); \
- asm( "stq $7, 0($2) " ); \
- asm( "addq $2, 8, $2 " ); \
- asm( "addq $6, $3, $3 " ); \
- asm( "addq $5, $3, $3 " );
-
-#define MULADDC_STOP \
- asm( "stq $3, %0 " : "=m" (c)); \
- asm( "stq $2, %0 " : "=m" (d)); \
- asm( "stq $1, %0 " : "=m" (s) :: \
- "$1", "$2", "$3", "$4", "$5", "$6", "$7" );
-
-#endif /* Alpha */
-
-#if defined(__mips__)
-
-#define MULADDC_INIT \
- asm( "lw $10, %0 " :: "m" (s)); \
- asm( "lw $11, %0 " :: "m" (d)); \
- asm( "lw $12, %0 " :: "m" (c)); \
- asm( "lw $13, %0 " :: "m" (b));
-
-#define MULADDC_CORE \
- asm( "lw $14, 0($10) " ); \
- asm( "multu $13, $14 " ); \
- asm( "addi $10, $10, 4 " ); \
- asm( "mflo $14 " ); \
- asm( "mfhi $9 " ); \
- asm( "addu $14, $12, $14 " ); \
- asm( "lw $15, 0($11) " ); \
- asm( "sltu $12, $14, $12 " ); \
- asm( "addu $15, $14, $15 " ); \
- asm( "sltu $14, $15, $14 " ); \
- asm( "addu $12, $12, $9 " ); \
- asm( "sw $15, 0($11) " ); \
- asm( "addu $12, $12, $14 " ); \
- asm( "addi $11, $11, 4 " );
-
-#define MULADDC_STOP \
- asm( "sw $12, %0 " : "=m" (c)); \
- asm( "sw $11, %0 " : "=m" (d)); \
- asm( "sw $10, %0 " : "=m" (s) :: \
- "$9", "$10", "$11", "$12", "$13", "$14", "$15" );
-
-#endif /* MIPS */
-#endif /* GNUC */
-
-#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
-
-#define MULADDC_INIT \
- __asm mov esi, s \
- __asm mov edi, d \
- __asm mov ecx, c \
- __asm mov ebx, b
-
-#define MULADDC_CORE \
- __asm lodsd \
- __asm mul ebx \
- __asm add eax, ecx \
- __asm adc edx, 0 \
- __asm add eax, [edi] \
- __asm adc edx, 0 \
- __asm mov ecx, edx \
- __asm stosd
-
-#if defined(POLARSSL_HAVE_SSE2)
-
-#define EMIT __asm _emit
-
-#define MULADDC_HUIT \
- EMIT 0x0F EMIT 0x6E EMIT 0xC9 \
- EMIT 0x0F EMIT 0x6E EMIT 0xC3 \
- EMIT 0x0F EMIT 0x6E EMIT 0x1F \
- EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
- EMIT 0x0F EMIT 0x6E EMIT 0x16 \
- EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
- EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \
- EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
- EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \
- EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
- EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \
- EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \
- EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
- EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \
- EMIT 0x0F EMIT 0xD4 EMIT 0xDC \
- EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \
- EMIT 0x0F EMIT 0xD4 EMIT 0xEE \
- EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \
- EMIT 0x0F EMIT 0xD4 EMIT 0xFC \
- EMIT 0x0F EMIT 0x7E EMIT 0x0F \
- EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \
- EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
- EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
- EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \
- EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
- EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
- EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \
- EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
- EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \
- EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
- EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \
- EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \
- EMIT 0x0F EMIT 0xD4 EMIT 0xCD \
- EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \
- EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \
- EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \
- EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
- EMIT 0x0F EMIT 0xD4 EMIT 0xCF \
- EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \
- EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \
- EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \
- EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
- EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
- EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \
- EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \
- EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \
- EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
- EMIT 0x0F EMIT 0xD4 EMIT 0xCC \
- EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \
- EMIT 0x0F EMIT 0xD4 EMIT 0xDD \
- EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \
- EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
- EMIT 0x0F EMIT 0xD4 EMIT 0xCE \
- EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \
- EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
- EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
- EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \
- EMIT 0x83 EMIT 0xC7 EMIT 0x20 \
- EMIT 0x83 EMIT 0xC6 EMIT 0x20 \
- EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
- EMIT 0x0F EMIT 0x7E EMIT 0xC9
-
-#define MULADDC_STOP \
- EMIT 0x0F EMIT 0x77 \
- __asm mov c, ecx \
- __asm mov d, edi \
- __asm mov s, esi \
-
-#else
-
-#define MULADDC_STOP \
- __asm mov c, ecx \
- __asm mov d, edi \
- __asm mov s, esi \
-
-#endif /* SSE2 */
-#endif /* MSVC */
-
-#endif /* POLARSSL_HAVE_ASM */
-
-#if !defined(MULADDC_CORE)
-#if defined(POLARSSL_HAVE_LONGLONG)
-
-#define MULADDC_INIT \
-{ \
- t_dbl r; \
- t_int r0, r1;
-
-#define MULADDC_CORE \
- r = *(s++) * (t_dbl) b; \
- r0 = r; \
- r1 = r >> biL; \
- r0 += c; r1 += (r0 < c); \
- r0 += *d; r1 += (r0 < *d); \
- c = r1; *(d++) = r0;
-
-#define MULADDC_STOP \
-}
-
-#else
-#define MULADDC_INIT \
-{ \
- t_int s0, s1, b0, b1; \
- t_int r0, r1, rx, ry; \
- b0 = ( b << biH ) >> biH; \
- b1 = ( b >> biH );
-
-#define MULADDC_CORE \
- s0 = ( *s << biH ) >> biH; \
- s1 = ( *s >> biH ); s++; \
- rx = s0 * b1; r0 = s0 * b0; \
- ry = s1 * b0; r1 = s1 * b1; \
- r1 += ( rx >> biH ); \
- r1 += ( ry >> biH ); \
- rx <<= biH; ry <<= biH; \
- r0 += rx; r1 += (r0 < rx); \
- r0 += ry; r1 += (r0 < ry); \
- r0 += c; r1 += (r0 < c); \
- r0 += *d; r1 += (r0 < *d); \
- c = r1; *(d++) = r0;
-
-#define MULADDC_STOP \
-}
-
-#endif /* C (generic) */
-#endif /* C (longlong) */
-
-#endif /* bn_mul.h */
--- /dev/null
+#define POLARSSL_BASE64_C
+
+
+
--- /dev/null
+#include "polarssl/bignum.h"
+#include "polarssl/part-x509.h"
+#include "polarssl/private-x509parse_c.h"
+
+#ifndef POLARSSL_PRIVATE_X509_PARSE_C_H
+#define POLARSSL_PRIVATE_X509_PARSE_C_H
+/* *************** begin copy from x509parse.c ********************/
+/*
+ * X.509 certificate and private key decoding
+ *
+ * Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+/*
+ * The ITU-T X.509 standard defines a certificat format for PKI.
+ *
+ * http://www.ietf.org/rfc/rfc2459.txt
+ * http://www.ietf.org/rfc/rfc3279.txt
+ *
+ * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
+ *
+ * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
+ * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
+ */
+
+
+/*
+ * ASN.1 DER decoding routines
+ */
+static int asn1_get_len( unsigned char **p,
+ const unsigned char *end,
+ int *len )
+{
+ if( ( end - *p ) < 1 )
+ return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
+
+ if( ( **p & 0x80 ) == 0 )
+ *len = *(*p)++;
+ else
+ {
+ switch( **p & 0x7F )
+ {
+ case 1:
+ if( ( end - *p ) < 2 )
+ return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
+
+ *len = (*p)[1];
+ (*p) += 2;
+ break;
+
+ case 2:
+ if( ( end - *p ) < 3 )
+ return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
+
+ *len = ( (*p)[1] << 8 ) | (*p)[2];
+ (*p) += 3;
+ break;
+
+ default:
+ return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
+ break;
+ }
+ }
+
+ if( *len > (int) ( end - *p ) )
+ return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
+
+ return( 0 );
+}
+
+/* This function is not exported by PolarSSL 0.14.2
+ * static */
+int asn1_get_tag( unsigned char **p,
+ const unsigned char *end,
+ int *len, int tag )
+{
+ if( ( end - *p ) < 1 )
+ return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
+
+ if( **p != tag )
+ return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
+
+ (*p)++;
+
+ return( asn1_get_len( p, end, len ) );
+}
+
+/* This function is not exported by PolarSSL 0.14.2
+ * static */
+int asn1_get_int( unsigned char **p,
+ const unsigned char *end,
+ int *val )
+{
+ int ret, len;
+
+ if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
+ return( ret );
+
+ if( len > (int) sizeof( int ) || ( **p & 0x80 ) != 0 )
+ return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
+
+ *val = 0;
+
+ while( len-- > 0 )
+ {
+ *val = ( *val << 8 ) | **p;
+ (*p)++;
+ }
+
+ return( 0 );
+}
+
+/* This function is not exported by PolarSSL 0.14.2
+ * static */
+int asn1_get_mpi( unsigned char **p,
+ const unsigned char *end,
+ mpi *X )
+{
+ int ret, len;
+
+ if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
+ return( ret );
+
+ ret = mpi_read_binary( X, *p, len );
+
+ *p += len;
+
+ return( ret );
+}
+/* *************** end copy from x509parse.c ********************/
+#endif /* private-x509parse_c.h */
--- /dev/null
+#include "pdkim-rsa.h"
+#include "polarssl/base64.h"
+#include <stdlib.h>
+#include <string.h>
+#include "polarssl/private-x509parse_c.h"
+
+/* PDKIM code (not copied from polarssl) */
+/*
+ * Parse a public RSA key
+
+OpenSSL RSA public key ASN1 container
+ 0:d=0 hl=3 l= 159 cons: SEQUENCE
+ 3:d=1 hl=2 l= 13 cons: SEQUENCE
+ 5:d=2 hl=2 l= 9 prim: OBJECT:rsaEncryption
+ 16:d=2 hl=2 l= 0 prim: NULL
+ 18:d=1 hl=3 l= 141 prim: BIT STRING:RSAPublicKey (below)
+
+RSAPublicKey ASN1 container
+ 0:d=0 hl=3 l= 137 cons: SEQUENCE
+ 3:d=1 hl=3 l= 129 prim: INTEGER:Public modulus
+135:d=1 hl=2 l= 3 prim: INTEGER:Public exponent
+*/
+
+int rsa_parse_public_key( rsa_context *rsa, unsigned char *buf, int buflen )
+{
+ unsigned char *p, *end;
+ int ret, len;
+
+ p = buf;
+ end = buf+buflen;
+
+ if( ( ret = asn1_get_tag( &p, end, &len,
+ ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) {
+ return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
+ }
+
+ if( ( ret = asn1_get_tag( &p, end, &len,
+ ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) == 0 ) {
+ /* Skip over embedded rsaEncryption Object */
+ p+=len;
+
+ /* The RSAPublicKey ASN1 container is wrapped in a BIT STRING */
+ if( ( ret = asn1_get_tag( &p, end, &len,
+ ASN1_BIT_STRING ) ) != 0 ) {
+ return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
+ }
+
+ /* Limit range to that BIT STRING */
+ end = p + len;
+ p++;
+
+ if( ( ret = asn1_get_tag( &p, end, &len,
+ ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) {
+ return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
+ }
+ }
+
+ if ( ( ( ret = asn1_get_mpi( &p, end, &(rsa->N) ) ) == 0 ) &&
+ ( ( ret = asn1_get_mpi( &p, end, &(rsa->E) ) ) == 0 ) ) {
+ rsa->len = mpi_size( &rsa->N );
+ return 0;
+ }
+
+ return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
+}
+
+/*
+ * Parse a private RSA key
+ */
+int rsa_parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
+ unsigned char *pwd, int pwdlen )
+{
+ int ret, len, enc;
+ unsigned char *s1, *s2;
+ unsigned char *p, *end;
+
+ s1 = (unsigned char *) strstr( (char *) buf,
+ "-----BEGIN RSA PRIVATE KEY-----" );
+
+ if( s1 != NULL )
+ {
+ s2 = (unsigned char *) strstr( (char *) buf,
+ "-----END RSA PRIVATE KEY-----" );
+
+ if( s2 == NULL || s2 <= s1 )
+ return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
+
+ s1 += 31;
+ if( *s1 == '\r' ) s1++;
+ if( *s1 == '\n' ) s1++;
+ else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
+
+ enc = 0;
+
+ if( memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
+ {
+ return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
+ }
+
+ len = 0;
+ ret = base64_decode( NULL, &len, s1, s2 - s1 );
+
+ if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
+ return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
+
+ if( ( buf = (unsigned char *) malloc( len ) ) == NULL )
+ return( 1 );
+
+ if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 )
+ {
+ free( buf );
+ return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
+ }
+
+ buflen = len;
+
+ if( enc != 0 )
+ {
+ return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
+ }
+ }
+
+ memset( rsa, 0, sizeof( rsa_context ) );
+
+ p = buf;
+ end = buf + buflen;
+
+ /*
+ * RSAPrivateKey ::= SEQUENCE {
+ * version Version,
+ * modulus INTEGER, -- n
+ * publicExponent INTEGER, -- e
+ * privateExponent INTEGER, -- d
+ * prime1 INTEGER, -- p
+ * prime2 INTEGER, -- q
+ * exponent1 INTEGER, -- d mod (p-1)
+ * exponent2 INTEGER, -- d mod (q-1)
+ * coefficient INTEGER, -- (inverse of q) mod p
+ * otherPrimeInfos OtherPrimeInfos OPTIONAL
+ * }
+ */
+ if( ( ret = asn1_get_tag( &p, end, &len,
+ ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
+ {
+ if( s1 != NULL )
+ free( buf );
+
+ rsa_free( rsa );
+ return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
+ }
+
+ end = p + len;
+
+ if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
+ {
+ if( s1 != NULL )
+ free( buf );
+
+ rsa_free( rsa );
+ return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
+ }
+
+ if( rsa->ver != 0 )
+ {
+ if( s1 != NULL )
+ free( buf );
+
+ rsa_free( rsa );
+ return( ret | POLARSSL_ERR_X509_KEY_INVALID_VERSION );
+ }
+
+ if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
+ ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
+ ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
+ ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
+ ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
+ ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
+ ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
+ ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
+ {
+ if( s1 != NULL )
+ free( buf );
+
+ rsa_free( rsa );
+ return( ret | POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
+ }
+
+ rsa->len = mpi_size( &rsa->N );
+
+ if( p != end )
+ {
+ if( s1 != NULL )
+ free( buf );
+
+ rsa_free( rsa );
+ return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT |
+ POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
+ }
+
+ if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
+ {
+ if( s1 != NULL )
+ free( buf );
+
+ rsa_free( rsa );
+ return( ret );
+ }
+
+ if( s1 != NULL )
+ free( buf );
+
+ return( 0 );
+}
--- /dev/null
+#include "polarssl/part-x509.h"
+#include "polarssl/rsa.h"
+
+/* PDKIM declarations (not part of polarssl) */
+int rsa_parse_public_key( rsa_context *rsa, unsigned char *buf, int buflen );
+int rsa_parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
+ unsigned char *pwd, int pwdlen );
+
/*
* PDKIM - a RFC4871 (DKIM) implementation
*
- * Copyright (C) 2009 - 2012 Tom Kistner <tom@duncanthrax.net>
+ * Copyright (C) 2009 - 2015 Tom Kistner <tom@duncanthrax.net>
*
* http://duncanthrax.net/pdkim/
*
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-
+#include "../exim.h"
#include "pdkim.h"
+#include "pdkim-rsa.h"
-#include "sha1.h"
-#include "sha2.h"
-#include "rsa.h"
-#include "base64.h"
+#include "polarssl/sha1.h"
+#include "polarssl/sha2.h"
+#include "polarssl/rsa.h"
+#include "polarssl/base64.h"
#define PDKIM_SIGNATURE_VERSION "1"
#define PDKIM_PUB_RECORD_VERSION "DKIM1"
/* -------------------------------------------------------------------------- */
/* Print debugging functions */
-#ifdef PDKIM_DEBUG
-void pdkim_quoteprint(FILE *stream, const char *data, int len, int lf) {
- int i;
- const unsigned char *p = (const unsigned char *)data;
-
- for (i=0;i<len;i++) {
- const int c = p[i];
- switch (c) {
- case ' ' : fprintf(stream,"{SP}"); break;
- case '\t': fprintf(stream,"{TB}"); break;
- case '\r': fprintf(stream,"{CR}"); break;
- case '\n': fprintf(stream,"{LF}"); break;
- case '{' : fprintf(stream,"{BO}"); break;
- case '}' : fprintf(stream,"{BC}"); break;
- default:
- if ( (c < 32) || (c > 127) )
- fprintf(stream,"{%02x}",c);
- else
- fputc(c,stream);
+void
+pdkim_quoteprint(const char *data, int len, int lf)
+{
+int i;
+const unsigned char *p = (const unsigned char *)data;
+
+for (i = 0; i < len; i++)
+ {
+ const int c = p[i];
+ switch (c)
+ {
+ case ' ' : debug_printf("{SP}"); break;
+ case '\t': debug_printf("{TB}"); break;
+ case '\r': debug_printf("{CR}"); break;
+ case '\n': debug_printf("{LF}"); break;
+ case '{' : debug_printf("{BO}"); break;
+ case '}' : debug_printf("{BC}"); break;
+ default:
+ if ( (c < 32) || (c > 127) )
+ debug_printf("{%02x}", c);
+ else
+ debug_printf("%c", c);
break;
}
}
- if (lf)
- fputc('\n',stream);
+if (lf)
+ debug_printf("\n");
}
-void pdkim_hexprint(FILE *stream, const char *data, int len, int lf) {
- int i;
- const unsigned char *p = (const unsigned char *)data;
- for (i=0;i<len;i++) {
- const int c = p[i];
- fprintf(stream,"%02x",c);
- }
- if (lf)
- fputc('\n',stream);
+void
+pdkim_hexprint(const char *data, int len, int lf)
+{
+int i;
+const unsigned char *p = (const unsigned char *)data;
+
+for (i = 0 ; i < len; i++)
+ debug_printf("%02x", p[i]);
+if (lf)
+ debug_printf("\n");
}
-#endif
/* -------------------------------------------------------------------------- */
/* Simple string list implementation for convinience */
-pdkim_stringlist *pdkim_append_stringlist(pdkim_stringlist *base, char *str) {
- pdkim_stringlist *new_entry = malloc(sizeof(pdkim_stringlist));
- if (new_entry == NULL) return NULL;
- memset(new_entry,0,sizeof(pdkim_stringlist));
- new_entry->value = strdup(str);
- if (new_entry->value == NULL) return NULL;
- if (base != NULL) {
- pdkim_stringlist *last = base;
- while (last->next != NULL) { last = last->next; }
- last->next = new_entry;
- return base;
- }
- else return new_entry;
-}
-pdkim_stringlist *pdkim_prepend_stringlist(pdkim_stringlist *base, char *str) {
- pdkim_stringlist *new_entry = malloc(sizeof(pdkim_stringlist));
- if (new_entry == NULL) return NULL;
- memset(new_entry,0,sizeof(pdkim_stringlist));
- new_entry->value = strdup(str);
- if (new_entry->value == NULL) return NULL;
- if (base != NULL) {
- new_entry->next = base;
+pdkim_stringlist *
+pdkim_append_stringlist(pdkim_stringlist *base, char *str)
+{
+pdkim_stringlist *new_entry = malloc(sizeof(pdkim_stringlist));
+
+if (!new_entry) return NULL;
+memset(new_entry, 0, sizeof(pdkim_stringlist));
+if (!(new_entry->value = strdup(str))) return NULL;
+if (base)
+ {
+ pdkim_stringlist *last = base;
+ while (last->next != NULL) { last = last->next; }
+ last->next = new_entry;
+ return base;
}
+else
return new_entry;
}
+pdkim_stringlist *
+pdkim_prepend_stringlist(pdkim_stringlist *base, char *str)
+{
+pdkim_stringlist *new_entry = malloc(sizeof(pdkim_stringlist));
+
+if (!new_entry) return NULL;
+memset(new_entry, 0, sizeof(pdkim_stringlist));
+if (!(new_entry->value = strdup(str))) return NULL;
+if (base)
+ new_entry->next = base;
+return new_entry;
+}
+
/* -------------------------------------------------------------------------- */
/* A small "growing string" implementation to escape malloc/realloc hell */
-pdkim_str *pdkim_strnew (const char *cstr) {
- unsigned int len = cstr?strlen(cstr):0;
- pdkim_str *p = malloc(sizeof(pdkim_str));
- if (p == NULL) return NULL;
- memset(p,0,sizeof(pdkim_str));
- p->str = malloc(len+1);
- if (p->str == NULL) {
- free(p);
- return NULL;
+
+pdkim_str *
+pdkim_strnew (const char *cstr)
+{
+unsigned int len = cstr ? strlen(cstr) : 0;
+pdkim_str *p = malloc(sizeof(pdkim_str));
+
+if (!p) return NULL;
+memset(p, 0, sizeof(pdkim_str));
+if (!(p->str = malloc(len+1)))
+ {
+ free(p);
+ return NULL;
}
- p->allocated=(len+1);
- p->len=len;
- if (cstr) strcpy(p->str,cstr);
- else p->str[p->len] = '\0';
- return p;
+p->allocated = len+1;
+p->len = len;
+if (cstr)
+ strcpy(p->str, cstr);
+else
+ p->str[p->len] = '\0';
+return p;
}
-char *pdkim_strncat(pdkim_str *str, const char *data, int len) {
- if ((str->allocated - str->len) < (len+1)) {
- /* Extend the buffer */
- int num_frags = ((len+1)/PDKIM_STR_ALLOC_FRAG)+1;
- char *n = realloc(str->str,
- (str->allocated+(num_frags*PDKIM_STR_ALLOC_FRAG)));
- if (n == NULL) return NULL;
- str->str = n;
- str->allocated += (num_frags*PDKIM_STR_ALLOC_FRAG);
+
+char *
+pdkim_strncat(pdkim_str *str, const char *data, int len)
+{
+if ((str->allocated - str->len) < (len+1))
+ {
+ /* Extend the buffer */
+ int num_frags = ((len+1)/PDKIM_STR_ALLOC_FRAG)+1;
+ char *n = realloc(str->str,
+ (str->allocated+(num_frags*PDKIM_STR_ALLOC_FRAG)));
+ if (n == NULL) return NULL;
+ str->str = n;
+ str->allocated += (num_frags*PDKIM_STR_ALLOC_FRAG);
}
- strncpy(&(str->str[str->len]),data,len);
- str->len+=len;
- str->str[str->len] = '\0';
- return str->str;
+strncpy(&(str->str[str->len]), data, len);
+str->len += len;
+str->str[str->len] = '\0';
+return str->str;
}
-char *pdkim_strcat(pdkim_str *str, const char *cstr) {
- return pdkim_strncat(str, cstr, strlen(cstr));
+
+char *
+pdkim_strcat(pdkim_str *str, const char *cstr)
+{
+return pdkim_strncat(str, cstr, strlen(cstr));
}
-char *pdkim_numcat(pdkim_str *str, unsigned long num) {
- char minibuf[20];
- snprintf(minibuf,20,"%lu",num);
- return pdkim_strcat(str,minibuf);
+
+char *
+pdkim_numcat(pdkim_str *str, unsigned long num)
+{
+char minibuf[20];
+snprintf(minibuf, 20, "%lu", num);
+return pdkim_strcat(str, minibuf);
}
-char *pdkim_strtrim(pdkim_str *str) {
- char *p = str->str;
- char *q = str->str;
- while ( (*p != '\0') && ((*p == '\t') || (*p == ' ')) ) p++;
- while (*p != '\0') {*q = *p; q++; p++;}
+
+char *
+pdkim_strtrim(pdkim_str *str)
+{
+char *p = str->str;
+char *q = str->str;
+while ( (*p != '\0') && ((*p == '\t') || (*p == ' ')) ) p++;
+while (*p != '\0') {*q = *p; q++; p++;}
+*q = '\0';
+while ( (q != str->str) && ( (*q == '\0') || (*q == '\t') || (*q == ' ') ) )
+ {
*q = '\0';
- while ( (q != str->str) && ( (*q == '\0') || (*q == '\t') || (*q == ' ') ) ) {
- *q = '\0';
- q--;
+ q--;
}
- str->len = strlen(str->str);
- return str->str;
+str->len = strlen(str->str);
+return str->str;
}
-char *pdkim_strclear(pdkim_str *str) {
- str->str[0] = '\0';
- str->len = 0;
- return str->str;
+
+char *
+pdkim_strclear(pdkim_str *str)
+{
+str->str[0] = '\0';
+str->len = 0;
+return str->str;
}
-void pdkim_strfree(pdkim_str *str) {
- if (str == NULL) return;
- if (str->str != NULL) free(str->str);
- free(str);
+
+void
+pdkim_strfree(pdkim_str *str)
+{
+if (!str) return;
+if (str->str) free(str->str);
+free(str);
}
/* -------------------------------------------------------------------------- */
-void pdkim_free_pubkey(pdkim_pubkey *pub) {
- if (pub) {
- if (pub->version != NULL) free(pub->version);
- if (pub->granularity != NULL) free(pub->granularity);
- if (pub->hashes != NULL) free(pub->hashes);
- if (pub->keytype != NULL) free(pub->keytype);
- if (pub->srvtype != NULL) free(pub->srvtype);
- if (pub->notes != NULL) free(pub->notes);
- if (pub->key != NULL) free(pub->key);
- free(pub);
+
+void
+pdkim_free_pubkey(pdkim_pubkey *pub)
+{
+if (pub)
+ {
+ if (pub->version ) free(pub->version);
+ if (pub->granularity) free(pub->granularity);
+ if (pub->hashes ) free(pub->hashes);
+ if (pub->keytype ) free(pub->keytype);
+ if (pub->srvtype ) free(pub->srvtype);
+ if (pub->notes ) free(pub->notes);
+ if (pub->key ) free(pub->key);
+ free(pub);
}
}
/* -------------------------------------------------------------------------- */
-void pdkim_free_sig(pdkim_signature *sig) {
- if (sig) {
- pdkim_signature *next = (pdkim_signature *)sig->next;
-
- pdkim_stringlist *e = sig->headers;
- while(e != NULL) {
- pdkim_stringlist *c = e;
- if (e->value != NULL) free(e->value);
- e = e->next;
- free(c);
+
+void
+pdkim_free_sig(pdkim_signature *sig)
+{
+if (sig)
+ {
+ pdkim_signature *next = (pdkim_signature *)sig->next;
+
+ pdkim_stringlist *e = sig->headers;
+ while(e)
+ {
+ pdkim_stringlist *c = e;
+ if (e->value) free(e->value);
+ e = e->next;
+ free(c);
}
- if (sig->sigdata != NULL) free(sig->sigdata);
- if (sig->bodyhash != NULL) free(sig->bodyhash);
- if (sig->selector != NULL) free(sig->selector);
- if (sig->domain != NULL) free(sig->domain);
- if (sig->identity != NULL) free(sig->identity);
- if (sig->headernames != NULL) free(sig->headernames);
- if (sig->copiedheaders != NULL) free(sig->copiedheaders);
- if (sig->rsa_privkey != NULL) free(sig->rsa_privkey);
- if (sig->sign_headers != NULL) free(sig->sign_headers);
- if (sig->signature_header != NULL) free(sig->signature_header);
- if (sig->sha1_body != NULL) free(sig->sha1_body);
- if (sig->sha2_body != NULL) free(sig->sha2_body);
-
- if (sig->pubkey != NULL) pdkim_free_pubkey(sig->pubkey);
-
- free(sig);
- if (next != NULL) pdkim_free_sig(next);
+ if (sig->sigdata ) free(sig->sigdata);
+ if (sig->bodyhash ) free(sig->bodyhash);
+ if (sig->selector ) free(sig->selector);
+ if (sig->domain ) free(sig->domain);
+ if (sig->identity ) free(sig->identity);
+ if (sig->headernames ) free(sig->headernames);
+ if (sig->copiedheaders ) free(sig->copiedheaders);
+ if (sig->rsa_privkey ) free(sig->rsa_privkey);
+ if (sig->sign_headers ) free(sig->sign_headers);
+ if (sig->signature_header) free(sig->signature_header);
+ if (sig->sha1_body ) free(sig->sha1_body);
+ if (sig->sha2_body ) free(sig->sha2_body);
+
+ if (sig->pubkey) pdkim_free_pubkey(sig->pubkey);
+
+ free(sig);
+ if (next) pdkim_free_sig(next);
}
}
/* -------------------------------------------------------------------------- */
-DLLEXPORT void pdkim_free_ctx(pdkim_ctx *ctx) {
- if (ctx) {
- pdkim_stringlist *e = ctx->headers;
- while(e != NULL) {
- pdkim_stringlist *c = e;
- if (e->value != NULL) free(e->value);
- e = e->next;
- free(c);
+
+DLLEXPORT void
+pdkim_free_ctx(pdkim_ctx *ctx)
+{
+if (ctx)
+ {
+ pdkim_stringlist *e = ctx->headers;
+ while(e)
+ {
+ pdkim_stringlist *c = e;
+ if (e->value) free(e->value);
+ e = e->next;
+ free(c);
}
- pdkim_free_sig(ctx->sig);
- pdkim_strfree(ctx->cur_header);
- free(ctx);
+ pdkim_free_sig(ctx->sig);
+ pdkim_strfree(ctx->cur_header);
+ free(ctx);
}
}
the passed colon-separated "list", starting at entry
"start". Returns the position of the header name in
the list. */
-int header_name_match(const char *header,
- char *tick,
- int do_tick) {
- char *hname;
- char *lcopy;
- char *p;
- char *q;
- int rc = PDKIM_FAIL;
-
- /* Get header name */
- char *hcolon = strchr(header,':');
- if (hcolon == NULL) return rc; /* This isn't a header */
- hname = malloc((hcolon-header)+1);
- if (hname == NULL) return PDKIM_ERR_OOM;
- memset(hname,0,(hcolon-header)+1);
- strncpy(hname,header,(hcolon-header));
-
- /* Copy tick-off list locally, so we can punch zeroes into it */
- lcopy = strdup(tick);
- if (lcopy == NULL) {
- free(hname);
- return PDKIM_ERR_OOM;
- }
- p = lcopy;
- q = strchr(p,':');
- while (q != NULL) {
- *q = '\0';
-
- if (strcasecmp(p,hname) == 0) {
- rc = PDKIM_OK;
- /* Invalidate header name instance in tick-off list */
- if (do_tick) tick[p-lcopy] = '_';
- goto BAIL;
- }
- p = q+1;
- q = strchr(p,':');
+int
+header_name_match(const char *header,
+ char *tick,
+ int do_tick)
+{
+char *hname;
+char *lcopy;
+char *p;
+char *q;
+int rc = PDKIM_FAIL;
+
+/* Get header name */
+char *hcolon = strchr(header, ':');
+
+if (!hcolon) return rc; /* This isn't a header */
+
+if (!(hname = malloc((hcolon-header)+1)))
+ return PDKIM_ERR_OOM;
+memset(hname, 0, (hcolon-header)+1);
+strncpy(hname, header, (hcolon-header));
+
+/* Copy tick-off list locally, so we can punch zeroes into it */
+if (!(lcopy = strdup(tick)))
+ {
+ free(hname);
+ return PDKIM_ERR_OOM;
}
+p = lcopy;
+q = strchr(p, ':');
+while (q)
+ {
+ *q = '\0';
- if (strcasecmp(p,hname) == 0) {
+ if (strcasecmp(p, hname) == 0)
+ {
rc = PDKIM_OK;
/* Invalidate header name instance in tick-off list */
if (do_tick) tick[p-lcopy] = '_';
+ goto BAIL;
+ }
+
+ p = q+1;
+ q = strchr(p, ':');
}
- BAIL:
- free(hname);
- free(lcopy);
- return rc;
+if (strcasecmp(p, hname) == 0)
+ {
+ rc = PDKIM_OK;
+ /* Invalidate header name instance in tick-off list */
+ if (do_tick) tick[p-lcopy] = '_';
+ }
+
+BAIL:
+free(hname);
+free(lcopy);
+return rc;
}
/* -------------------------------------------------------------------------- */
/* Performs "relaxed" canonicalization of a header. The returned pointer needs
to be free()d. */
-char *pdkim_relax_header (char *header, int crlf) {
- int past_field_name = 0;
- int seen_wsp = 0;
- char *p = header;
- char *q;
- char *relaxed = malloc(strlen(header)+3);
- if (relaxed == NULL) return NULL;
- q = relaxed;
- while (*p != '\0') {
- int c = *p;
- /* Ignore CR & LF */
- if ( (c == '\r') || (c == '\n') ) {
- p++;
+
+char *
+pdkim_relax_header (char *header, int crlf)
+{
+BOOL past_field_name = FALSE;
+BOOL seen_wsp = FALSE;
+char *p;
+char *q;
+char *relaxed = malloc(strlen(header)+3);
+
+if (!relaxed) return NULL;
+
+q = relaxed;
+for (p = header; *p != '\0'; p++)
+ {
+ int c = *p;
+ /* Ignore CR & LF */
+ if (c == '\r' || c == '\n')
+ continue;
+ if (c == '\t' || c == ' ')
+ {
+ if (seen_wsp)
continue;
+ c = ' '; /* Turns WSP into SP */
+ seen_wsp = TRUE;
}
- if ( (c == '\t') || (c == ' ') ) {
- c = ' '; /* Turns WSP into SP */
- if (seen_wsp) {
- p++;
- continue;
- }
- else seen_wsp = 1;
- }
- else {
- if ( (!past_field_name) && (c == ':') ) {
- if (seen_wsp) q--; /* This removes WSP before the colon */
- seen_wsp = 1; /* This removes WSP after the colon */
- past_field_name = 1;
+ else
+ if (!past_field_name && c == ':')
+ {
+ if (seen_wsp) q--; /* This removes WSP before the colon */
+ seen_wsp = TRUE; /* This removes WSP after the colon */
+ past_field_name = TRUE;
}
- else seen_wsp = 0;
- }
- /* Lowercase header name */
- if (!past_field_name) c = tolower(c);
- *q = c;
- p++;
- q++;
+ else
+ seen_wsp = FALSE;
+
+ /* Lowercase header name */
+ if (!past_field_name) c = tolower(c);
+ *q++ = c;
}
- if ((q>relaxed) && (*(q-1) == ' ')) q--; /* Squash eventual trailing SP */
- *q = '\0';
- if (crlf) strcat(relaxed,"\r\n");
- return relaxed;
+
+if (q > relaxed && q[-1] == ' ') q--; /* Squash eventual trailing SP */
+*q = '\0';
+
+if (crlf) strcat(relaxed, "\r\n");
+return relaxed;
}
/* -------------------------------------------------------------------------- */
#define PDKIM_QP_ERROR_DECODE -1
-char *pdkim_decode_qp_char(char *qp_p, int *c) {
- char *initial_pos = qp_p;
-
- /* Advance one char */
- qp_p++;
-
- /* Check for two hex digits and decode them */
- if (isxdigit(*qp_p) && isxdigit(qp_p[1])) {
- /* Do hex conversion */
- if (isdigit(*qp_p)) {*c = *qp_p - '0';}
- else {*c = toupper(*qp_p) - 'A' + 10;}
- *c <<= 4;
- if (isdigit(qp_p[1])) {*c |= qp_p[1] - '0';}
- else {*c |= toupper(qp_p[1]) - 'A' + 10;}
- return qp_p + 2;
+
+static char *
+pdkim_decode_qp_char(char *qp_p, int *c)
+{
+char *initial_pos = qp_p;
+
+/* Advance one char */
+qp_p++;
+
+/* Check for two hex digits and decode them */
+if (isxdigit(*qp_p) && isxdigit(qp_p[1]))
+ {
+ /* Do hex conversion */
+ *c = (isdigit(*qp_p) ? *qp_p - '0' : toupper(*qp_p) - 'A' + 10) << 4;
+ *c |= isdigit(qp_p[1]) ? qp_p[1] - '0' : toupper(qp_p[1]) - 'A' + 10;
+ return qp_p + 2;
}
- /* Illegal char here */
- *c = PDKIM_QP_ERROR_DECODE;
- return initial_pos;
+/* Illegal char here */
+*c = PDKIM_QP_ERROR_DECODE;
+return initial_pos;
}
/* -------------------------------------------------------------------------- */
-char *pdkim_decode_qp(char *str) {
- int nchar = 0;
- char *q;
- char *p = str;
- char *n = malloc(strlen(p)+1);
- if (n == NULL) return NULL;
- *n = '\0';
- q = n;
- while (*p != '\0') {
- if (*p == '=') {
- p = pdkim_decode_qp_char(p,&nchar);
- if (nchar >= 0) {
- *q = nchar;
- q++;
- continue;
+
+char *
+pdkim_decode_qp(char *str)
+{
+int nchar = 0;
+char *q;
+char *p = str;
+char *n = malloc(strlen(p)+1);
+
+if (!n) return NULL;
+
+*n = '\0';
+q = n;
+while (*p != '\0')
+ {
+ if (*p == '=')
+ {
+ p = pdkim_decode_qp_char(p, &nchar);
+ if (nchar >= 0)
+ {
+ *q++ = nchar;
+ continue;
}
}
- else {
- *q = *p;
- q++;
- }
- p++;
+ else
+ *q++ = *p;
+ p++;
}
- *q = '\0';
- return n;
+*q = '\0';
+return n;
}
/* -------------------------------------------------------------------------- */
-char *pdkim_decode_base64(char *str, int *num_decoded) {
- int dlen = 0;
- char *res;
-
- base64_decode(NULL, &dlen, (unsigned char *)str, strlen(str));
- res = malloc(dlen+1);
- if (res == NULL) return NULL;
- if (base64_decode((unsigned char *)res,&dlen,(unsigned char *)str,strlen(str)) != 0) {
- free(res);
- return NULL;
+
+char *
+pdkim_decode_base64(char *str, int *num_decoded)
+{
+int dlen = 0;
+char *res;
+
+base64_decode(NULL, &dlen, (unsigned char *)str, strlen(str));
+
+if (!(res = malloc(dlen+1)))
+ return NULL;
+if (base64_decode((unsigned char *)res, &dlen, (unsigned char *)str, strlen(str)) != 0)
+ {
+ free(res);
+ return NULL;
}
- if (num_decoded != NULL) *num_decoded = dlen;
- return res;
+
+if (num_decoded) *num_decoded = dlen;
+return res;
}
+
/* -------------------------------------------------------------------------- */
-char *pdkim_encode_base64(char *str, int num) {
- int dlen = 0;
- char *res;
-
- base64_encode(NULL, &dlen, (unsigned char *)str, num);
- res = malloc(dlen+1);
- if (res == NULL) return NULL;
- if (base64_encode((unsigned char *)res,&dlen,(unsigned char *)str,num) != 0) {
- free(res);
- return NULL;
+
+char *
+pdkim_encode_base64(char *str, int num)
+{
+int dlen = 0;
+char *res;
+
+base64_encode(NULL, &dlen, (unsigned char *)str, num);
+
+if (!(res = malloc(dlen+1)))
+ return NULL;
+if (base64_encode((unsigned char *)res, &dlen, (unsigned char *)str, num) != 0)
+ {
+ free(res);
+ return NULL;
}
- return res;
+return res;
}
#define PDKIM_HDR_LIMBO 0
#define PDKIM_HDR_TAG 1
#define PDKIM_HDR_VALUE 2
-pdkim_signature *pdkim_parse_sig_header(pdkim_ctx *ctx, char *raw_hdr) {
- pdkim_signature *sig ;
- char *p,*q;
- pdkim_str *cur_tag = NULL;
- pdkim_str *cur_val = NULL;
- int past_hname = 0;
- int in_b_val = 0;
- int where = PDKIM_HDR_LIMBO;
- int i;
-
- sig = malloc(sizeof(pdkim_signature));
- if (sig == NULL) return NULL;
- memset(sig,0,sizeof(pdkim_signature));
- sig->bodylength = -1;
-
- sig->rawsig_no_b_val = malloc(strlen(raw_hdr)+1);
- if (sig->rawsig_no_b_val == NULL) {
- free(sig);
- return NULL;
+
+pdkim_signature *
+pdkim_parse_sig_header(pdkim_ctx *ctx, char *raw_hdr)
+{
+pdkim_signature *sig ;
+char *p, *q;
+pdkim_str *cur_tag = NULL;
+pdkim_str *cur_val = NULL;
+BOOL past_hname = FALSE;
+BOOL in_b_val = FALSE;
+int where = PDKIM_HDR_LIMBO;
+int i;
+
+if (!(sig = malloc(sizeof(pdkim_signature)))) return NULL;
+memset(sig, 0, sizeof(pdkim_signature));
+sig->bodylength = -1;
+
+if (!(sig->rawsig_no_b_val = malloc(strlen(raw_hdr)+1)))
+ {
+ free(sig);
+ return NULL;
}
- p = raw_hdr;
- q = sig->rawsig_no_b_val;
+q = sig->rawsig_no_b_val;
- while (1) {
+for (p = raw_hdr; ; p++)
+ {
+ char c = *p;
- /* Ignore FWS */
- if ( (*p == '\r') || (*p == '\n') )
- goto NEXT_CHAR;
+ /* Ignore FWS */
+ if (c == '\r' || c == '\n')
+ goto NEXT_CHAR;
- /* Fast-forward through header name */
- if (!past_hname) {
- if (*p == ':') past_hname = 1;
- goto NEXT_CHAR;
+ /* Fast-forward through header name */
+ if (!past_hname)
+ {
+ if (c == ':') past_hname = TRUE;
+ goto NEXT_CHAR;
}
- if (where == PDKIM_HDR_LIMBO) {
- /* In limbo, just wait for a tag-char to appear */
- if (!((*p >= 'a') && (*p <= 'z')))
- goto NEXT_CHAR;
+ if (where == PDKIM_HDR_LIMBO)
+ {
+ /* In limbo, just wait for a tag-char to appear */
+ if (!(c >= 'a' && c <= 'z'))
+ goto NEXT_CHAR;
- where = PDKIM_HDR_TAG;
+ where = PDKIM_HDR_TAG;
}
- if (where == PDKIM_HDR_TAG) {
- if (cur_tag == NULL)
- cur_tag = pdkim_strnew(NULL);
-
- if ((*p >= 'a') && (*p <= 'z'))
- pdkim_strncat(cur_tag,p,1);
-
- if (*p == '=') {
- if (strcmp(cur_tag->str,"b") == 0) {
- *q = '='; q++;
- in_b_val = 1;
- }
- where = PDKIM_HDR_VALUE;
- goto NEXT_CHAR;
+ if (where == PDKIM_HDR_TAG)
+ {
+ if (!cur_tag)
+ cur_tag = pdkim_strnew(NULL);
+
+ if (c >= 'a' && c <= 'z')
+ pdkim_strncat(cur_tag, p, 1);
+
+ if (c == '=')
+ {
+ if (strcmp(cur_tag->str, "b") == 0)
+ {
+ *q = '='; q++;
+ in_b_val = TRUE;
+ }
+ where = PDKIM_HDR_VALUE;
+ goto NEXT_CHAR;
}
}
- if (where == PDKIM_HDR_VALUE) {
- if (cur_val == NULL)
- cur_val = pdkim_strnew(NULL);
-
- if ( (*p == '\r') || (*p == '\n') || (*p == ' ') || (*p == '\t') )
- goto NEXT_CHAR;
-
- if ( (*p == ';') || (*p == '\0') ) {
- if (cur_tag->len > 0) {
- pdkim_strtrim(cur_val);
- #ifdef PDKIM_DEBUG
- if (ctx->debug_stream)
- fprintf(ctx->debug_stream, "%s=%s\n", cur_tag->str, cur_val->str);
- #endif
- switch (cur_tag->str[0]) {
- case 'b':
- switch (cur_tag->str[1]) {
- case 'h':
- sig->bodyhash = pdkim_decode_base64(cur_val->str,&(sig->bodyhash_len));
- break;
- default:
- sig->sigdata = pdkim_decode_base64(cur_val->str,&(sig->sigdata_len));
- break;
- }
- break;
- case 'v':
- if (strcmp(cur_val->str,PDKIM_SIGNATURE_VERSION) == 0) {
- /* We only support version 1, and that is currently the
- only version there is. */
- sig->version = 1;
- }
- break;
- case 'a':
- i = 0;
- while (pdkim_algos[i] != NULL) {
- if (strcmp(cur_val->str,pdkim_algos[i]) == 0 ) {
- sig->algo = i;
- break;
- }
- i++;
- }
- break;
- case 'c':
- i = 0;
- while (pdkim_combined_canons[i].str != NULL) {
- if (strcmp(cur_val->str,pdkim_combined_canons[i].str) == 0 ) {
- sig->canon_headers = pdkim_combined_canons[i].canon_headers;
- sig->canon_body = pdkim_combined_canons[i].canon_body;
- break;
- }
- i++;
- }
- break;
- case 'q':
- i = 0;
- while (pdkim_querymethods[i] != NULL) {
- if (strcmp(cur_val->str,pdkim_querymethods[i]) == 0 ) {
- sig->querymethod = i;
- break;
- }
- i++;
- }
- break;
- case 's':
- sig->selector = strdup(cur_val->str);
- break;
- case 'd':
- sig->domain = strdup(cur_val->str);
- break;
- case 'i':
- sig->identity = pdkim_decode_qp(cur_val->str);
- break;
- case 't':
- sig->created = strtoul(cur_val->str,NULL,10);
- break;
- case 'x':
- sig->expires = strtoul(cur_val->str,NULL,10);
- break;
- case 'l':
- sig->bodylength = strtol(cur_val->str,NULL,10);
- break;
- case 'h':
- sig->headernames = strdup(cur_val->str);
- break;
- case 'z':
- sig->copiedheaders = pdkim_decode_qp(cur_val->str);
- break;
- default:
- #ifdef PDKIM_DEBUG
- if (ctx->debug_stream)
- fprintf(ctx->debug_stream, "Unknown tag encountered\n");
- #endif
- break;
- }
- }
- pdkim_strclear(cur_tag);
- pdkim_strclear(cur_val);
- in_b_val = 0;
- where = PDKIM_HDR_LIMBO;
- goto NEXT_CHAR;
- }
- else pdkim_strncat(cur_val,p,1);
- }
+ if (where == PDKIM_HDR_VALUE)
+ {
+ if (!cur_val)
+ cur_val = pdkim_strnew(NULL);
- NEXT_CHAR:
- if (*p == '\0') break;
+ if (c == '\r' || c == '\n' || c == ' ' || c == '\t')
+ goto NEXT_CHAR;
- if (!in_b_val) {
- *q = *p;
- q++;
+ if (c == ';' || c == '\0')
+ {
+ if (cur_tag->len > 0)
+ {
+ pdkim_strtrim(cur_val);
+
+ DEBUG(D_acl) debug_printf(" %s=%s\n", cur_tag->str, cur_val->str);
+
+ switch (cur_tag->str[0])
+ {
+ case 'b':
+ if (cur_tag->str[1] == 'h')
+ sig->bodyhash = pdkim_decode_base64(cur_val->str,
+ &sig->bodyhash_len);
+ else
+ sig->sigdata = pdkim_decode_base64(cur_val->str,
+ &sig->sigdata_len);
+ break;
+ case 'v':
+ /* We only support version 1, and that is currently the
+ only version there is. */
+ if (strcmp(cur_val->str, PDKIM_SIGNATURE_VERSION) == 0)
+ sig->version = 1;
+ break;
+ case 'a':
+ for (i = 0; pdkim_algos[i]; i++)
+ if (strcmp(cur_val->str, pdkim_algos[i]) == 0)
+ {
+ sig->algo = i;
+ break;
+ }
+ break;
+ case 'c':
+ for (i = 0; pdkim_combined_canons[i].str; i++)
+ if (strcmp(cur_val->str, pdkim_combined_canons[i].str) == 0)
+ {
+ sig->canon_headers = pdkim_combined_canons[i].canon_headers;
+ sig->canon_body = pdkim_combined_canons[i].canon_body;
+ break;
+ }
+ break;
+ case 'q':
+ for (i = 0; pdkim_querymethods[i]; i++)
+ if (strcmp(cur_val->str, pdkim_querymethods[i]) == 0)
+ {
+ sig->querymethod = i;
+ break;
+ }
+ break;
+ case 's':
+ sig->selector = strdup(cur_val->str); break;
+ case 'd':
+ sig->domain = strdup(cur_val->str); break;
+ case 'i':
+ sig->identity = pdkim_decode_qp(cur_val->str); break;
+ case 't':
+ sig->created = strtoul(cur_val->str, NULL, 10); break;
+ case 'x':
+ sig->expires = strtoul(cur_val->str, NULL, 10); break;
+ case 'l':
+ sig->bodylength = strtol(cur_val->str, NULL, 10); break;
+ case 'h':
+ sig->headernames = strdup(cur_val->str); break;
+ case 'z':
+ sig->copiedheaders = pdkim_decode_qp(cur_val->str); break;
+ default:
+ DEBUG(D_acl) debug_printf(" Unknown tag encountered\n");
+ break;
+ }
+ }
+ pdkim_strclear(cur_tag);
+ pdkim_strclear(cur_val);
+ in_b_val = FALSE;
+ where = PDKIM_HDR_LIMBO;
+ }
+ else
+ pdkim_strncat(cur_val, p, 1);
}
- p++;
- }
- /* Make sure the most important bits are there. */
- if (!(sig->domain && (*(sig->domain) != '\0') &&
- sig->selector && (*(sig->selector) != '\0') &&
- sig->headernames && (*(sig->headernames) != '\0') &&
- sig->bodyhash &&
- sig->sigdata &&
- sig->version)) {
- pdkim_free_sig(sig);
- return NULL;
- }
+NEXT_CHAR:
+ if (c == '\0')
+ break;
- *q = '\0';
- /* Chomp raw header. The final newline must not be added to the signature. */
- q--;
- while( (q > sig->rawsig_no_b_val) && ((*q == '\r') || (*q == '\n')) ) {
- *q = '\0'; q--;
+ if (!in_b_val)
+ *q++ = c;
}
- #ifdef PDKIM_DEBUG
- if (ctx->debug_stream) {
- fprintf(ctx->debug_stream,
- "PDKIM >> Raw signature w/o b= tag value >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
- pdkim_quoteprint(ctx->debug_stream,
- sig->rawsig_no_b_val,
- strlen(sig->rawsig_no_b_val), 1);
- fprintf(ctx->debug_stream,
- "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
+/* Make sure the most important bits are there. */
+if (!(sig->domain && (*(sig->domain) != '\0') &&
+ sig->selector && (*(sig->selector) != '\0') &&
+ sig->headernames && (*(sig->headernames) != '\0') &&
+ sig->bodyhash &&
+ sig->sigdata &&
+ sig->version))
+ {
+ pdkim_free_sig(sig);
+ return NULL;
}
- #endif
- sig->sha1_body = malloc(sizeof(sha1_context));
- if (sig->sha1_body == NULL) {
- pdkim_free_sig(sig);
- return NULL;
+*q = '\0';
+/* Chomp raw header. The final newline must not be added to the signature. */
+q--;
+while (q > sig->rawsig_no_b_val && (*q == '\r' || *q == '\n'))
+ *q = '\0'; q--; /*XXX questionable code layout; possible bug */
+
+DEBUG(D_acl)
+ {
+ debug_printf(
+ "PDKIM >> Raw signature w/o b= tag value >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
+ pdkim_quoteprint(sig->rawsig_no_b_val, strlen(sig->rawsig_no_b_val), 1);
+ debug_printf(
+ "PDKIM >> Sig size: %4d bits\n", sig->sigdata_len*8);
+ debug_printf(
+ "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
}
- sig->sha2_body = malloc(sizeof(sha2_context));
- if (sig->sha2_body == NULL) {
- pdkim_free_sig(sig);
- return NULL;
+
+if ( !(sig->sha1_body = malloc(sizeof(sha1_context)))
+ || !(sig->sha2_body = malloc(sizeof(sha2_context)))
+ )
+ {
+ pdkim_free_sig(sig);
+ return NULL;
}
- sha1_starts(sig->sha1_body);
- sha2_starts(sig->sha2_body,0);
+sha1_starts(sig->sha1_body);
+sha2_starts(sig->sha2_body, 0);
- return sig;
+return sig;
}
/* -------------------------------------------------------------------------- */
-pdkim_pubkey *pdkim_parse_pubkey_record(pdkim_ctx *ctx, char *raw_record) {
- pdkim_pubkey *pub ;
- char *p;
- pdkim_str *cur_tag = NULL;
- pdkim_str *cur_val = NULL;
- int where = PDKIM_HDR_LIMBO;
-
- pub = malloc(sizeof(pdkim_pubkey));
- if (pub == NULL) return NULL;
- memset(pub,0,sizeof(pdkim_pubkey));
- p = raw_record;
-
- while (1) {
-
- /* Ignore FWS */
- if ( (*p == '\r') || (*p == '\n') )
+pdkim_pubkey *
+pdkim_parse_pubkey_record(pdkim_ctx *ctx, char *raw_record)
+{
+pdkim_pubkey *pub;
+char *p;
+pdkim_str *cur_tag = NULL;
+pdkim_str *cur_val = NULL;
+int where = PDKIM_HDR_LIMBO;
+
+if (!(pub = malloc(sizeof(pdkim_pubkey)))) return NULL;
+memset(pub, 0, sizeof(pdkim_pubkey));
+
+for (p = raw_record; ; p++)
+ {
+ char c = *p;
+
+ /* Ignore FWS */
+ if (c == '\r' || c == '\n')
+ goto NEXT_CHAR;
+
+ if (where == PDKIM_HDR_LIMBO)
+ {
+ /* In limbo, just wait for a tag-char to appear */
+ if (!(c >= 'a' && c <= 'z'))
goto NEXT_CHAR;
- if (where == PDKIM_HDR_LIMBO) {
- /* In limbo, just wait for a tag-char to appear */
- if (!((*p >= 'a') && (*p <= 'z')))
- goto NEXT_CHAR;
-
- where = PDKIM_HDR_TAG;
+ where = PDKIM_HDR_TAG;
}
- if (where == PDKIM_HDR_TAG) {
- if (cur_tag == NULL)
- cur_tag = pdkim_strnew(NULL);
+ if (where == PDKIM_HDR_TAG)
+ {
+ if (!cur_tag)
+ cur_tag = pdkim_strnew(NULL);
- if ((*p >= 'a') && (*p <= 'z'))
- pdkim_strncat(cur_tag,p,1);
+ if (c >= 'a' && c <= 'z')
+ pdkim_strncat(cur_tag, p, 1);
- if (*p == '=') {
- where = PDKIM_HDR_VALUE;
- goto NEXT_CHAR;
+ if (c == '=')
+ {
+ where = PDKIM_HDR_VALUE;
+ goto NEXT_CHAR;
}
}
- if (where == PDKIM_HDR_VALUE) {
- if (cur_val == NULL)
- cur_val = pdkim_strnew(NULL);
-
- if ( (*p == '\r') || (*p == '\n') )
- goto NEXT_CHAR;
-
- if ( (*p == ';') || (*p == '\0') ) {
- if (cur_tag->len > 0) {
- pdkim_strtrim(cur_val);
- #ifdef PDKIM_DEBUG
- if (ctx->debug_stream)
- fprintf(ctx->debug_stream, "%s=%s\n", cur_tag->str, cur_val->str);
- #endif
- switch (cur_tag->str[0]) {
- case 'v':
- /* This tag isn't evaluated because:
- - We only support version DKIM1.
- - Which is the default for this value (set below)
- - Other versions are currently not specified. */
- break;
- case 'h':
- pub->hashes = strdup(cur_val->str);
- break;
- case 'g':
- pub->granularity = strdup(cur_val->str);
- break;
- case 'n':
- pub->notes = pdkim_decode_qp(cur_val->str);
- break;
- case 'p':
- pub->key = pdkim_decode_base64(cur_val->str,&(pub->key_len));
- break;
- case 'k':
- pub->hashes = strdup(cur_val->str);
- break;
- case 's':
- pub->srvtype = strdup(cur_val->str);
- break;
- case 't':
- if (strchr(cur_val->str,'y') != NULL) pub->testing = 1;
- if (strchr(cur_val->str,'s') != NULL) pub->no_subdomaining = 1;
- break;
- default:
- #ifdef PDKIM_DEBUG
- if (ctx->debug_stream)
- fprintf(ctx->debug_stream, "Unknown tag encountered\n");
- #endif
- break;
- }
- }
- pdkim_strclear(cur_tag);
- pdkim_strclear(cur_val);
- where = PDKIM_HDR_LIMBO;
- goto NEXT_CHAR;
+ if (where == PDKIM_HDR_VALUE)
+ {
+ if (!cur_val)
+ cur_val = pdkim_strnew(NULL);
+
+ if (c == '\r' || c == '\n')
+ goto NEXT_CHAR;
+
+ if (c == ';' || c == '\0')
+ {
+ if (cur_tag->len > 0)
+ {
+ pdkim_strtrim(cur_val);
+ DEBUG(D_acl) debug_printf(" %s=%s\n", cur_tag->str, cur_val->str);
+
+ switch (cur_tag->str[0])
+ {
+ case 'v':
+ /* This tag isn't evaluated because:
+ - We only support version DKIM1.
+ - Which is the default for this value (set below)
+ - Other versions are currently not specified. */
+ break;
+ case 'h':
+ pub->hashes = strdup(cur_val->str); break;
+ case 'g':
+ pub->granularity = strdup(cur_val->str); break;
+ case 'n':
+ pub->notes = pdkim_decode_qp(cur_val->str); break;
+ case 'p':
+ pub->key = pdkim_decode_base64(cur_val->str, &(pub->key_len)); break;
+ case 'k':
+ pub->hashes = strdup(cur_val->str); break;
+ case 's':
+ pub->srvtype = strdup(cur_val->str); break;
+ case 't':
+ if (strchr(cur_val->str, 'y') != NULL) pub->testing = 1;
+ if (strchr(cur_val->str, 's') != NULL) pub->no_subdomaining = 1;
+ break;
+ default:
+ DEBUG(D_acl) debug_printf(" Unknown tag encountered\n");
+ break;
+ }
+ }
+ pdkim_strclear(cur_tag);
+ pdkim_strclear(cur_val);
+ where = PDKIM_HDR_LIMBO;
}
- else pdkim_strncat(cur_val,p,1);
+ else
+ pdkim_strncat(cur_val, p, 1);
}
- NEXT_CHAR:
- if (*p == '\0') break;
- p++;
+NEXT_CHAR:
+ if (c == '\0') break;
}
- /* Set fallback defaults */
- if (pub->version == NULL) pub->version = strdup(PDKIM_PUB_RECORD_VERSION);
- if (pub->granularity == NULL) pub->granularity = strdup("*");
- if (pub->keytype == NULL) pub->keytype = strdup("rsa");
- if (pub->srvtype == NULL) pub->srvtype = strdup("*");
-
- /* p= is required */
- if (pub->key == NULL) {
- pdkim_free_pubkey(pub);
- return NULL;
- }
+/* Set fallback defaults */
+if (!pub->version ) pub->version = strdup(PDKIM_PUB_RECORD_VERSION);
+if (!pub->granularity) pub->granularity = strdup("*");
+if (!pub->keytype ) pub->keytype = strdup("rsa");
+if (!pub->srvtype ) pub->srvtype = strdup("*");
+/* p= is required */
+if (pub->key)
return pub;
+
+pdkim_free_pubkey(pub);
+return NULL;
}
/* -------------------------------------------------------------------------- */
-int pdkim_update_bodyhash(pdkim_ctx *ctx, const char *data, int len) {
- pdkim_signature *sig = ctx->sig;
- /* Cache relaxed version of data */
- char *relaxed_data = NULL;
- int relaxed_len = 0;
-
- /* Traverse all signatures, updating their hashes. */
- while (sig != NULL) {
- /* Defaults to simple canon (no further treatment necessary) */
- const char *canon_data = data;
- int canon_len = len;
-
- if (sig->canon_body == PDKIM_CANON_RELAXED) {
- /* Relax the line if not done already */
- if (relaxed_data == NULL) {
- int seen_wsp = 0;
- const char *p = data;
- int q = 0;
- relaxed_data = malloc(len+1);
- if (relaxed_data == NULL) return PDKIM_ERR_OOM;
- while (*p != '\0') {
- char c = *p;
- if (c == '\r') {
- if ( (q > 0) && (relaxed_data[q-1] == ' ') ) q--;
- }
- else if ( (c == '\t') || (c == ' ') ) {
- c = ' '; /* Turns WSP into SP */
- if (seen_wsp) {
- p++;
- continue;
- }
- else seen_wsp = 1;
- }
- else seen_wsp = 0;
- relaxed_data[q++] = c;
- p++;
- }
- relaxed_data[q] = '\0';
- relaxed_len = q;
+
+int
+pdkim_update_bodyhash(pdkim_ctx *ctx, const char *data, int len)
+{
+pdkim_signature *sig = ctx->sig;
+/* Cache relaxed version of data */
+char *relaxed_data = NULL;
+int relaxed_len = 0;
+
+/* Traverse all signatures, updating their hashes. */
+while (sig)
+ {
+ /* Defaults to simple canon (no further treatment necessary) */
+ const char *canon_data = data;
+ int canon_len = len;
+
+ if (sig->canon_body == PDKIM_CANON_RELAXED)
+ {
+ /* Relax the line if not done already */
+ if (!relaxed_data)
+ {
+ BOOL seen_wsp = FALSE;
+ const char *p;
+ int q = 0;
+
+ if (!(relaxed_data = malloc(len+1)))
+ return PDKIM_ERR_OOM;
+
+ for (p = data; *p; p++)
+ {
+ char c = *p;
+ if (c == '\r')
+ {
+ if (q > 0 && relaxed_data[q-1] == ' ')
+ q--;
+ }
+ else if (c == '\t' || c == ' ')
+ {
+ c = ' '; /* Turns WSP into SP */
+ if (seen_wsp)
+ continue;
+ seen_wsp = TRUE;
+ }
+ else
+ seen_wsp = FALSE;
+ relaxed_data[q++] = c;
+ }
+ relaxed_data[q] = '\0';
+ relaxed_len = q;
}
- canon_data = relaxed_data;
- canon_len = relaxed_len;
+ canon_data = relaxed_data;
+ canon_len = relaxed_len;
}
- /* Make sure we don't exceed the to-be-signed body length */
- if ((sig->bodylength >= 0) &&
- ((sig->signed_body_bytes+(unsigned long)canon_len) > sig->bodylength))
- canon_len = (sig->bodylength - sig->signed_body_bytes);
+ /* Make sure we don't exceed the to-be-signed body length */
+ if ( sig->bodylength >= 0
+ && sig->signed_body_bytes + (unsigned long)canon_len > sig->bodylength
+ )
+ canon_len = sig->bodylength - sig->signed_body_bytes;
- if (canon_len > 0) {
- if (sig->algo == PDKIM_ALGO_RSA_SHA1)
- sha1_update(sig->sha1_body,(unsigned char *)canon_data,canon_len);
- else
- sha2_update(sig->sha2_body,(unsigned char *)canon_data,canon_len);
- sig->signed_body_bytes += canon_len;
-#ifdef PDKIM_DEBUG
- if (ctx->debug_stream!=NULL)
- pdkim_quoteprint(ctx->debug_stream,canon_data,canon_len,0);
-#endif
+ if (canon_len > 0)
+ {
+ if (sig->algo == PDKIM_ALGO_RSA_SHA1)
+ sha1_update(sig->sha1_body, (unsigned char *)canon_data, canon_len);
+ else
+ sha2_update(sig->sha2_body, (unsigned char *)canon_data, canon_len);
+
+ sig->signed_body_bytes += canon_len;
+ DEBUG(D_acl) pdkim_quoteprint(canon_data, canon_len, 1);
}
- sig = sig->next;
+ sig = sig->next;
}
- if (relaxed_data != NULL) free(relaxed_data);
- return PDKIM_OK;
+if (relaxed_data) free(relaxed_data);
+return PDKIM_OK;
}
/* -------------------------------------------------------------------------- */
-int pdkim_finish_bodyhash(pdkim_ctx *ctx) {
- pdkim_signature *sig = ctx->sig;
- /* Traverse all signatures */
- while (sig != NULL) {
-
- /* Finish hashes */
- unsigned char bh[32]; /* SHA-256 = 32 Bytes, SHA-1 = 20 Bytes */
- if (sig->algo == PDKIM_ALGO_RSA_SHA1)
- sha1_finish(sig->sha1_body,bh);
- else
- sha2_finish(sig->sha2_body,bh);
-
- #ifdef PDKIM_DEBUG
- if (ctx->debug_stream) {
- fprintf(ctx->debug_stream, "PDKIM [%s] Body bytes hashed: %lu\n",
- sig->domain, sig->signed_body_bytes);
- fprintf(ctx->debug_stream, "PDKIM [%s] bh computed: ", sig->domain);
- pdkim_hexprint(ctx->debug_stream, (char *)bh,
- (sig->algo == PDKIM_ALGO_RSA_SHA1)?20:32,1);
+int
+pdkim_finish_bodyhash(pdkim_ctx *ctx)
+{
+pdkim_signature *sig = ctx->sig;
+
+/* Traverse all signatures */
+while (sig)
+ { /* Finish hashes */
+ unsigned char bh[32]; /* SHA-256 = 32 Bytes, SHA-1 = 20 Bytes */
+
+ if (sig->algo == PDKIM_ALGO_RSA_SHA1)
+ sha1_finish(sig->sha1_body, bh);
+ else
+ sha2_finish(sig->sha2_body, bh);
+
+ DEBUG(D_acl)
+ {
+ debug_printf("PDKIM [%s] Body bytes hashed: %lu\n"
+ "PDKIM [%s] bh computed: ",
+ sig->domain, sig->signed_body_bytes, sig->domain);
+ pdkim_hexprint((char *)bh, sig->algo == PDKIM_ALGO_RSA_SHA1 ? 20 : 32, 1);
}
- #endif
-
- /* SIGNING -------------------------------------------------------------- */
- if (ctx->mode == PDKIM_MODE_SIGN) {
- sig->bodyhash_len = (sig->algo == PDKIM_ALGO_RSA_SHA1)?20:32;
- sig->bodyhash = malloc(sig->bodyhash_len);
- if (sig->bodyhash == NULL) return PDKIM_ERR_OOM;
- memcpy(sig->bodyhash,bh,sig->bodyhash_len);
-
- /* If bodylength limit is set, and we have received less bytes
- than the requested amount, effectively remove the limit tag. */
- if (sig->signed_body_bytes < sig->bodylength) sig->bodylength = -1;
+
+ /* SIGNING -------------------------------------------------------------- */
+ if (ctx->mode == PDKIM_MODE_SIGN)
+ {
+ sig->bodyhash_len = (sig->algo == PDKIM_ALGO_RSA_SHA1)?20:32;
+
+ if (!(sig->bodyhash = malloc(sig->bodyhash_len)))
+ return PDKIM_ERR_OOM;
+ memcpy(sig->bodyhash, bh, sig->bodyhash_len);
+
+ /* If bodylength limit is set, and we have received less bytes
+ than the requested amount, effectively remove the limit tag. */
+ if (sig->signed_body_bytes < sig->bodylength)
+ sig->bodylength = -1;
}
- /* VERIFICATION --------------------------------------------------------- */
- else {
- /* Compare bodyhash */
- if (memcmp(bh,sig->bodyhash,
- (sig->algo == PDKIM_ALGO_RSA_SHA1)?20:32) == 0) {
- #ifdef PDKIM_DEBUG
- if (ctx->debug_stream)
- fprintf(ctx->debug_stream, "PDKIM [%s] Body hash verified OK\n",
- sig->domain);
- #endif
+
+ /* VERIFICATION --------------------------------------------------------- */
+ else
+ {
+ /* Compare bodyhash */
+ if (memcmp(bh, sig->bodyhash,
+ (sig->algo == PDKIM_ALGO_RSA_SHA1)?20:32) == 0)
+ {
+ DEBUG(D_acl) debug_printf("PDKIM [%s] Body hash verified OK\n", sig->domain);
}
- else {
- #ifdef PDKIM_DEBUG
- if (ctx->debug_stream) {
- fprintf(ctx->debug_stream, "PDKIM [%s] Body hash did NOT verify\n",
- sig->domain);
- fprintf(ctx->debug_stream, "PDKIM [%s] bh signature: ", sig->domain);
- pdkim_hexprint(ctx->debug_stream, sig->bodyhash,
- (sig->algo == PDKIM_ALGO_RSA_SHA1)?20:32,1);
- }
- #endif
- sig->verify_status = PDKIM_VERIFY_FAIL;
- sig->verify_ext_status = PDKIM_VERIFY_FAIL_BODY;
+ else
+ {
+ DEBUG(D_acl)
+ {
+ debug_printf("PDKIM [%s] bh signature: ", sig->domain);
+ pdkim_hexprint(sig->bodyhash,
+ sig->algo == PDKIM_ALGO_RSA_SHA1 ? 20 : 32, 1);
+ debug_printf("PDKIM [%s] Body hash did NOT verify\n", sig->domain);
+ }
+ sig->verify_status = PDKIM_VERIFY_FAIL;
+ sig->verify_ext_status = PDKIM_VERIFY_FAIL_BODY;
}
}
- sig = sig->next;
+ sig = sig->next;
}
- return PDKIM_OK;
+return PDKIM_OK;
}
/* -------------------------------------------------------------------------- */
/* Callback from pdkim_feed below for processing complete body lines */
-int pdkim_bodyline_complete(pdkim_ctx *ctx) {
- char *p = ctx->linebuf;
- int n = ctx->linebuf_offset;
- /* Ignore extra data if we've seen the end-of-data marker */
- if (ctx->seen_eod) goto BAIL;
+static int
+pdkim_bodyline_complete(pdkim_ctx *ctx)
+{
+char *p = ctx->linebuf;
+int n = ctx->linebuf_offset;
+pdkim_signature *sig = ctx->sig; /*XXX assumes only one sig */
+
+/* Ignore extra data if we've seen the end-of-data marker */
+if (ctx->seen_eod) goto BAIL;
+
+/* We've always got one extra byte to stuff a zero ... */
+ctx->linebuf[ctx->linebuf_offset] = '\0';
+
+/* Terminate on EOD marker */
+if (memcmp(p, ".\r\n", 3) == 0)
+ {
+ /* In simple body mode, if any empty lines were buffered,
+ replace with one. rfc 4871 3.4.3 */
+ /*XXX checking the signed-body-bytes is a gross hack; I think
+ it indicates that all linebreaks should be buffered, including
+ the one terminating a text line */
+ if ( sig && sig->canon_body == PDKIM_CANON_SIMPLE
+ && sig->signed_body_bytes == 0
+ && ctx->num_buffered_crlf > 0
+ )
+ pdkim_update_bodyhash(ctx, "\r\n", 2);
+
+ ctx->seen_eod = TRUE;
+ goto BAIL;
+ }
+/* Unstuff dots */
+if (memcmp(p, "..", 2) == 0)
+ {
+ p++;
+ n--;
+ }
- /* We've always got one extra byte to stuff a zero ... */
- ctx->linebuf[(ctx->linebuf_offset)] = '\0';
+/* Empty lines need to be buffered until we find a non-empty line */
+if (memcmp(p, "\r\n", 2) == 0)
+ {
+ ctx->num_buffered_crlf++;
+ goto BAIL;
+ }
- if (ctx->input_mode == PDKIM_INPUT_SMTP) {
- /* Terminate on EOD marker */
- if (memcmp(p,".\r\n",3) == 0) {
- ctx->seen_eod = 1;
- goto BAIL;
- }
- /* Unstuff dots */
- if (memcmp(p,"..",2) == 0) {
- p++;
- n--;
+if (sig && sig->canon_body == PDKIM_CANON_RELAXED)
+ {
+ /* Lines with just spaces need to be buffered too */
+ char *check = p;
+ while (memcmp(check, "\r\n", 2) != 0)
+ {
+ char c = *check;
+
+ if (c != '\t' && c != ' ')
+ goto PROCESS;
+ check++;
}
- }
- /* Empty lines need to be buffered until we find a non-empty line */
- if (memcmp(p,"\r\n",2) == 0) {
- ctx->num_buffered_crlf++;
- goto BAIL;
- }
+ ctx->num_buffered_crlf++;
+ goto BAIL;
+}
- /* At this point, we have a non-empty line, so release the buffered ones. */
- while (ctx->num_buffered_crlf) {
- pdkim_update_bodyhash(ctx,"\r\n",2);
- ctx->num_buffered_crlf--;
+PROCESS:
+/* At this point, we have a non-empty line, so release the buffered ones. */
+while (ctx->num_buffered_crlf)
+ {
+ pdkim_update_bodyhash(ctx, "\r\n", 2);
+ ctx->num_buffered_crlf--;
}
- pdkim_update_bodyhash(ctx,p,n);
+pdkim_update_bodyhash(ctx, p, n);
- BAIL:
- ctx->linebuf_offset = 0;
- return PDKIM_OK;
+BAIL:
+ctx->linebuf_offset = 0;
+return PDKIM_OK;
}
/* -------------------------------------------------------------------------- */
/* Callback from pdkim_feed below for processing complete headers */
#define DKIM_SIGNATURE_HEADERNAME "DKIM-Signature:"
-int pdkim_header_complete(pdkim_ctx *ctx) {
- pdkim_signature *sig = ctx->sig;
-
- /* Special case: The last header can have an extra \r appended */
- if ( (ctx->cur_header->len > 1) &&
- (ctx->cur_header->str[(ctx->cur_header->len)-1] == '\r') ) {
- ctx->cur_header->str[(ctx->cur_header->len)-1] = '\0';
- ctx->cur_header->len--;
+
+int
+pdkim_header_complete(pdkim_ctx *ctx)
+{
+/* Special case: The last header can have an extra \r appended */
+if ( (ctx->cur_header->len > 1) &&
+ (ctx->cur_header->str[(ctx->cur_header->len)-1] == '\r') )
+ {
+ ctx->cur_header->str[(ctx->cur_header->len)-1] = '\0';
+ ctx->cur_header->len--;
}
- ctx->num_headers++;
- if (ctx->num_headers > PDKIM_MAX_HEADERS) goto BAIL;
+ctx->num_headers++;
+if (ctx->num_headers > PDKIM_MAX_HEADERS) goto BAIL;
- /* SIGNING -------------------------------------------------------------- */
- if (ctx->mode == PDKIM_MODE_SIGN) {
- /* Traverse all signatures */
- while (sig != NULL) {
- pdkim_stringlist *list;
+/* SIGNING -------------------------------------------------------------- */
+if (ctx->mode == PDKIM_MODE_SIGN)
+ {
+ pdkim_signature *sig;
- if (header_name_match(ctx->cur_header->str,
- sig->sign_headers?
- sig->sign_headers:
- PDKIM_DEFAULT_SIGN_HEADERS, 0) != PDKIM_OK) goto NEXT_SIG;
+ for (sig = ctx->sig; sig; sig = sig->next) /* Traverse all signatures */
+ if (header_name_match(ctx->cur_header->str,
+ sig->sign_headers?
+ sig->sign_headers:
+ PDKIM_DEFAULT_SIGN_HEADERS, 0) == PDKIM_OK)
+ {
+ pdkim_stringlist *list;
/* Add header to the signed headers list (in reverse order) */
- list = pdkim_prepend_stringlist(sig->headers,
- ctx->cur_header->str);
- if (list == NULL) return PDKIM_ERR_OOM;
+ if (!(list = pdkim_prepend_stringlist(sig->headers,
+ ctx->cur_header->str)))
+ return PDKIM_ERR_OOM;
sig->headers = list;
-
- NEXT_SIG:
- sig = sig->next;
- }
+ }
}
- /* DKIM-Signature: headers are added to the verification list */
- if (ctx->mode == PDKIM_MODE_VERIFY) {
- if (strncasecmp(ctx->cur_header->str,
- DKIM_SIGNATURE_HEADERNAME,
- strlen(DKIM_SIGNATURE_HEADERNAME)) == 0) {
- pdkim_signature *new_sig;
- /* Create and chain new signature block */
- #ifdef PDKIM_DEBUG
- if (ctx->debug_stream)
- fprintf(ctx->debug_stream,
- "PDKIM >> Found sig, trying to parse >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
- #endif
- new_sig = pdkim_parse_sig_header(ctx, ctx->cur_header->str);
- if (new_sig != NULL) {
- pdkim_signature *last_sig = ctx->sig;
- if (last_sig == NULL) {
- ctx->sig = new_sig;
- }
- else {
- while (last_sig->next != NULL) { last_sig = last_sig->next; }
- last_sig->next = new_sig;
- }
- }
- else {
- #ifdef PDKIM_DEBUG
- if (ctx->debug_stream) {
- fprintf(ctx->debug_stream,"Error while parsing signature header\n");
- fprintf(ctx->debug_stream,
- "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
- }
- #endif
+/* VERIFICATION ----------------------------------------------------------- */
+/* DKIM-Signature: headers are added to the verification list */
+if (ctx->mode == PDKIM_MODE_VERIFY)
+ {
+ if (strncasecmp(ctx->cur_header->str,
+ DKIM_SIGNATURE_HEADERNAME,
+ strlen(DKIM_SIGNATURE_HEADERNAME)) == 0)
+ {
+ pdkim_signature *new_sig;
+
+ /* Create and chain new signature block */
+ DEBUG(D_acl) debug_printf(
+ "PDKIM >> Found sig, trying to parse >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
+
+ if ((new_sig = pdkim_parse_sig_header(ctx, ctx->cur_header->str)))
+ {
+ pdkim_signature *last_sig = ctx->sig;
+ if (!last_sig)
+ ctx->sig = new_sig;
+ else
+ {
+ while (last_sig->next) last_sig = last_sig->next;
+ last_sig->next = new_sig;
+ }
}
+ else
+ DEBUG(D_acl) debug_printf(
+ "Error while parsing signature header\n"
+ "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
}
- /* every other header is stored for signature verification */
- else {
- pdkim_stringlist *list;
- list = pdkim_prepend_stringlist(ctx->headers,
- ctx->cur_header->str);
- if (list == NULL) return PDKIM_ERR_OOM;
- ctx->headers = list;
+ /* every other header is stored for signature verification */
+ else
+ {
+ pdkim_stringlist *list;
+
+ if (!(list = pdkim_prepend_stringlist(ctx->headers, ctx->cur_header->str)))
+ return PDKIM_ERR_OOM;
+ ctx->headers = list;
}
}
- BAIL:
- pdkim_strclear(ctx->cur_header); /* Re-use existing pdkim_str */
- return PDKIM_OK;
+BAIL:
+pdkim_strclear(ctx->cur_header); /* Re-use existing pdkim_str */
+return PDKIM_OK;
}
/* -------------------------------------------------------------------------- */
#define HEADER_BUFFER_FRAG_SIZE 256
-DLLEXPORT int pdkim_feed (pdkim_ctx *ctx,
- char *data,
- int len) {
- int p;
- for (p=0;p<len;p++) {
- char c = data[p];
- if (ctx->past_headers) {
- /* Processing body byte */
- ctx->linebuf[(ctx->linebuf_offset)++] = c;
- if (c == '\n') {
- int rc = pdkim_bodyline_complete(ctx); /* End of line */
- if (rc != PDKIM_OK) return rc;
+
+DLLEXPORT int
+pdkim_feed (pdkim_ctx *ctx, char *data, int len)
+{
+int p;
+
+for (p = 0; p<len; p++)
+ {
+ char c = data[p];
+
+ if (ctx->past_headers)
+ {
+ /* Processing body byte */
+ ctx->linebuf[ctx->linebuf_offset++] = c;
+ if (c == '\n')
+ {
+ int rc = pdkim_bodyline_complete(ctx); /* End of line */
+ if (rc != PDKIM_OK) return rc;
}
- if (ctx->linebuf_offset == (PDKIM_MAX_BODY_LINE_LEN-1))
- return PDKIM_ERR_LONG_LINE;
+ if (ctx->linebuf_offset == (PDKIM_MAX_BODY_LINE_LEN-1))
+ return PDKIM_ERR_LONG_LINE;
}
- else {
- /* Processing header byte */
- if (c != '\r') {
- if (c == '\n') {
- if (ctx->seen_lf) {
- int rc = pdkim_header_complete(ctx); /* Seen last header line */
- if (rc != PDKIM_OK) return rc;
- ctx->past_headers = 1;
- ctx->seen_lf = 0;
-#ifdef PDKIM_DEBUG
- if (ctx->debug_stream)
- fprintf(ctx->debug_stream,
- "PDKIM >> Hashed body data, canonicalized >>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
-#endif
- continue;
- }
- else ctx->seen_lf = 1;
- }
- else if (ctx->seen_lf) {
- if (! ((c == '\t') || (c == ' '))) {
- int rc = pdkim_header_complete(ctx); /* End of header */
- if (rc != PDKIM_OK) return rc;
- }
- ctx->seen_lf = 0;
- }
- }
- if (ctx->cur_header == NULL) {
- ctx->cur_header = pdkim_strnew(NULL);
- if (ctx->cur_header == NULL) return PDKIM_ERR_OOM;
+ else
+ {
+ /* Processing header byte */
+ if (c != '\r')
+ {
+ if (c == '\n')
+ {
+ if (ctx->seen_lf)
+ {
+ int rc = pdkim_header_complete(ctx); /* Seen last header line */
+ if (rc != PDKIM_OK) return rc;
+
+ ctx->past_headers = TRUE;
+ ctx->seen_lf = 0;
+ DEBUG(D_acl) debug_printf(
+ "PDKIM >> Hashed body data, canonicalized >>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
+ continue;
+ }
+ else
+ ctx->seen_lf = TRUE;
+ }
+ else if (ctx->seen_lf)
+ {
+ if (!(c == '\t' || c == ' '))
+ {
+ int rc = pdkim_header_complete(ctx); /* End of header */
+ if (rc != PDKIM_OK) return rc;
+ }
+ ctx->seen_lf = FALSE;
+ }
}
- if (ctx->cur_header->len < PDKIM_MAX_HEADER_LEN)
- if (pdkim_strncat(ctx->cur_header,&data[p],1) == NULL)
- return PDKIM_ERR_OOM;
+
+ if (!ctx->cur_header)
+ if (!(ctx->cur_header = pdkim_strnew(NULL)))
+ return PDKIM_ERR_OOM;
+
+ if (ctx->cur_header->len < PDKIM_MAX_HEADER_LEN)
+ if (!pdkim_strncat(ctx->cur_header, &data[p], 1))
+ return PDKIM_ERR_OOM;
}
}
- return PDKIM_OK;
+return PDKIM_OK;
}
+/*
+ * RFC 5322 specifies that header line length SHOULD be no more than 78
+ * lets make it so!
+ * pdkim_headcat
+ * returns char*
+ *
+ * col: this int holds and receives column number (octets since last '\n')
+ * str: partial string to append to
+ * pad: padding, split line or space after before or after eg: ";"
+ * intro: - must join to payload eg "h=", usually the tag name
+ * payload: eg base64 data - long data can be split arbitrarily.
+ *
+ * this code doesn't fold the header in some of the places that RFC4871
+ * allows: As per RFC5322(2.2.3) it only folds before or after tag-value
+ * pairs and inside long values. it also always spaces or breaks after the
+ * "pad"
+ *
+ * no guarantees are made for output given out-of range input. like tag
+ * names loinger than 78, or bogus col. Input is assumed to be free of line breaks.
+ */
-/* -------------------------------------------------------------------------- */
-char *pdkim_create_header(pdkim_signature *sig, int final) {
- char *rc = NULL;
- char *base64_bh = NULL;
- char *base64_b = NULL;
- pdkim_str *hdr = pdkim_strnew("DKIM-Signature: v="PDKIM_SIGNATURE_VERSION);
- if (hdr == NULL) return NULL;
-
- base64_bh = pdkim_encode_base64(sig->bodyhash, sig->bodyhash_len);
- if (base64_bh == NULL) goto BAIL;
-
- /* Required and static bits */
- if (
- pdkim_strcat(hdr,"; a=") &&
- pdkim_strcat(hdr,pdkim_algos[sig->algo]) &&
- pdkim_strcat(hdr,"; q=") &&
- pdkim_strcat(hdr,pdkim_querymethods[sig->querymethod]) &&
- pdkim_strcat(hdr,"; c=") &&
- pdkim_strcat(hdr,pdkim_canons[sig->canon_headers]) &&
- pdkim_strcat(hdr,"/") &&
- pdkim_strcat(hdr,pdkim_canons[sig->canon_body]) &&
- pdkim_strcat(hdr,"; d=") &&
- pdkim_strcat(hdr,sig->domain) &&
- pdkim_strcat(hdr,"; s=") &&
- pdkim_strcat(hdr,sig->selector) &&
- pdkim_strcat(hdr,";\r\n\th=") &&
- pdkim_strcat(hdr,sig->headernames) &&
- pdkim_strcat(hdr,"; bh=") &&
- pdkim_strcat(hdr,base64_bh) &&
- pdkim_strcat(hdr,";\r\n\t")
- ) {
- /* Optional bits */
- if (sig->identity != NULL) {
- if (!( pdkim_strcat(hdr,"i=") &&
- pdkim_strcat(hdr,sig->identity) &&
- pdkim_strcat(hdr,";") ) ) {
- goto BAIL;
- }
- }
- if (sig->created > 0) {
- if (!( pdkim_strcat(hdr,"t=") &&
- pdkim_numcat(hdr,sig->created) &&
- pdkim_strcat(hdr,";") ) ) {
- goto BAIL;
- }
- }
- if (sig->expires > 0) {
- if (!( pdkim_strcat(hdr,"x=") &&
- pdkim_numcat(hdr,sig->expires) &&
- pdkim_strcat(hdr,";") ) ) {
- goto BAIL;
- }
+static char *
+pdkim_headcat(int *col, pdkim_str *str, const char * pad,
+ const char *intro, const char *payload)
+{
+size_t l;
+
+if (pad)
+ {
+ l = strlen(pad);
+ if (*col + l > 78)
+ {
+ pdkim_strcat(str, "\r\n\t");
+ *col = 1;
}
- if (sig->bodylength >= 0) {
- if (!( pdkim_strcat(hdr,"l=") &&
- pdkim_numcat(hdr,sig->bodylength) &&
- pdkim_strcat(hdr,";") ) ) {
- goto BAIL;
- }
- }
- /* Extra linebreak */
- if (hdr->str[(hdr->len)-1] == ';') {
- if (!pdkim_strcat(hdr," \r\n\t")) goto BAIL;
+ pdkim_strncat(str, pad, l);
+ *col += l;
+ }
+
+l = (pad?1:0) + (intro?strlen(intro):0);
+
+if (*col + l > 78)
+ { /*can't fit intro - start a new line to make room.*/
+ pdkim_strcat(str, "\r\n\t");
+ *col = 1;
+ l = intro?strlen(intro):0;
+ }
+
+l += payload ? strlen(payload):0 ;
+
+while (l>77)
+ { /* this fragment will not fit on a single line */
+ if (pad)
+ {
+ pdkim_strcat(str, " ");
+ *col += 1;
+ pad = NULL; /* only want this once */
+ l--;
}
- /* Preliminary or final version? */
- if (final) {
- base64_b = pdkim_encode_base64(sig->sigdata, sig->sigdata_len);
- if (base64_b == NULL) goto BAIL;
- if (
- pdkim_strcat(hdr,"b=") &&
- pdkim_strcat(hdr,base64_b) &&
- pdkim_strcat(hdr,";")
- ) goto DONE;
+
+ if (intro)
+ {
+ size_t sl = strlen(intro);
+
+ pdkim_strncat(str, intro, sl);
+ *col += sl;
+ l -= sl;
+ intro = NULL; /* only want this once */
}
- else {
- if (pdkim_strcat(hdr,"b=;")) goto DONE;
+
+ if (payload)
+ {
+ size_t sl = strlen(payload);
+ size_t chomp = *col+sl < 77 ? sl : 78-*col;
+
+ pdkim_strncat(str, payload, chomp);
+ *col += chomp;
+ payload += chomp;
+ l -= chomp-1;
}
- goto BAIL;
+ /* the while precondition tells us it didn't fit. */
+ pdkim_strcat(str, "\r\n\t");
+ *col = 1;
+ }
+
+if (*col + l > 78)
+ {
+ pdkim_strcat(str, "\r\n\t");
+ *col = 1;
+ pad = NULL;
}
- DONE:
- rc = strdup(hdr->str);
+if (pad)
+ {
+ pdkim_strcat(str, " ");
+ *col += 1;
+ pad = NULL;
+ }
+
+if (intro)
+ {
+ size_t sl = strlen(intro);
+
+ pdkim_strncat(str, intro, sl);
+ *col += sl;
+ l -= sl;
+ intro = NULL;
+ }
- BAIL:
- pdkim_strfree(hdr);
- if (base64_bh != NULL) free(base64_bh);
- if (base64_b != NULL) free(base64_b);
- return rc;
+if (payload)
+ {
+ size_t sl = strlen(payload);
+
+ pdkim_strncat(str, payload, sl);
+ *col += sl;
+ }
+
+return str->str;
}
/* -------------------------------------------------------------------------- */
-DLLEXPORT int pdkim_feed_finish(pdkim_ctx *ctx, pdkim_signature **return_signatures) {
- pdkim_signature *sig = ctx->sig;
- pdkim_str *headernames = NULL; /* Collected signed header names */
-
- /* Check if we must still flush a (partial) header. If that is the
- case, the message has no body, and we must compute a body hash
- out of '<CR><LF>' */
- if (ctx->cur_header && ctx->cur_header->len) {
- int rc = pdkim_header_complete(ctx);
- if (rc != PDKIM_OK) return rc;
- pdkim_update_bodyhash(ctx,"\r\n",2);
+
+char *
+pdkim_create_header(pdkim_signature *sig, int final)
+{
+char *rc = NULL;
+char *base64_bh = NULL;
+char *base64_b = NULL;
+int col = 0;
+pdkim_str *hdr;
+pdkim_str *canon_all;
+
+if (!(hdr = pdkim_strnew("DKIM-Signature: v="PDKIM_SIGNATURE_VERSION)))
+ return NULL;
+
+if (!(canon_all = pdkim_strnew(pdkim_canons[sig->canon_headers])))
+ goto BAIL;
+
+if (!(base64_bh = pdkim_encode_base64(sig->bodyhash, sig->bodyhash_len)))
+ goto BAIL;
+
+col = strlen(hdr->str);
+
+/* Required and static bits */
+if ( pdkim_headcat(&col, hdr, ";", "a=", pdkim_algos[sig->algo])
+ && pdkim_headcat(&col, hdr, ";", "q=", pdkim_querymethods[sig->querymethod])
+ && pdkim_strcat(canon_all, "/")
+ && pdkim_strcat(canon_all, pdkim_canons[sig->canon_body])
+ && pdkim_headcat(&col, hdr, ";", "c=", canon_all->str)
+ && pdkim_headcat(&col, hdr, ";", "d=", sig->domain)
+ && pdkim_headcat(&col, hdr, ";", "s=", sig->selector)
+ )
+ {
+ /* list of eader names can be split between items. */
+ {
+ char *n = strdup(sig->headernames);
+ char *f = n;
+ char *i = "h=";
+ char *s = ";";
+
+ if (!n) goto BAIL;
+ while (*n)
+ {
+ char *c = strchr(n, ':');
+
+ if (c) *c ='\0';
+
+ if (!i)
+ if (!pdkim_headcat(&col, hdr, NULL, NULL, ":"))
+ {
+ free(f);
+ goto BAIL;
+ }
+
+ if (!pdkim_headcat(&col, hdr, s, i, n))
+ {
+ free(f);
+ goto BAIL;
+ }
+
+ if (!c)
+ break;
+
+ n = c+1;
+ s = NULL;
+ i = NULL;
+ }
+ free(f);
+ }
+
+ if(!pdkim_headcat(&col, hdr, ";", "bh=", base64_bh))
+ goto BAIL;
+
+ /* Optional bits */
+ if (sig->identity)
+ if(!pdkim_headcat(&col, hdr, ";", "i=", sig->identity))
+ goto BAIL;
+
+ if (sig->created > 0)
+ {
+ char minibuf[20];
+
+ snprintf(minibuf, 20, "%lu", sig->created);
+ if(!pdkim_headcat(&col, hdr, ";", "t=", minibuf))
+ goto BAIL;
}
- else {
- /* For non-smtp input, check if there's an unfinished line in the
- body line buffer. If that is the case, we must add a CRLF to the
- hash to properly terminate the message. */
- if ((ctx->input_mode == PDKIM_INPUT_NORMAL) && ctx->linebuf_offset) {
- pdkim_update_bodyhash(ctx, ctx->linebuf, ctx->linebuf_offset);
- pdkim_update_bodyhash(ctx,"\r\n",2);
+
+ if (sig->expires > 0)
+ {
+ char minibuf[20];
+
+ snprintf(minibuf, 20, "%lu", sig->expires);
+ if(!pdkim_headcat(&col, hdr, ";", "x=", minibuf))
+ goto BAIL;
}
- #ifdef PDKIM_DEBUG
- if (ctx->debug_stream)
- fprintf(ctx->debug_stream,
- "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
- #endif
+
+ if (sig->bodylength >= 0)
+ {
+ char minibuf[20];
+
+ snprintf(minibuf, 20, "%lu", sig->bodylength);
+ if(!pdkim_headcat(&col, hdr, ";", "l=", minibuf))
+ goto BAIL;
+ }
+
+ /* Preliminary or final version? */
+ if (final)
+ {
+ if (!(base64_b = pdkim_encode_base64(sig->sigdata, sig->sigdata_len)))
+ goto BAIL;
+ if (!pdkim_headcat(&col, hdr, ";", "b=", base64_b))
+ goto BAIL;
}
+ else
+ if(!pdkim_headcat(&col, hdr, ";", "b=", ""))
+ goto BAIL;
- /* Build (and/or evaluate) body hash */
- if (pdkim_finish_bodyhash(ctx) != PDKIM_OK) return PDKIM_ERR_OOM;
+ /* add trailing semicolon: I'm not sure if this is actually needed */
+ if (!pdkim_headcat(&col, hdr, NULL, ";", ""))
+ goto BAIL;
+ }
- /* SIGNING -------------------------------------------------------------- */
- if (ctx->mode == PDKIM_MODE_SIGN) {
- headernames = pdkim_strnew(NULL);
- if (headernames == NULL) return PDKIM_ERR_OOM;
+rc = strdup(hdr->str);
+
+BAIL:
+pdkim_strfree(hdr);
+if (canon_all) pdkim_strfree(canon_all);
+if (base64_bh) free(base64_bh);
+if (base64_b ) free(base64_b);
+return rc;
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+DLLEXPORT int
+pdkim_feed_finish(pdkim_ctx *ctx, pdkim_signature **return_signatures)
+{
+pdkim_signature *sig = ctx->sig;
+pdkim_str *headernames = NULL; /* Collected signed header names */
+
+/* Check if we must still flush a (partial) header. If that is the
+ case, the message has no body, and we must compute a body hash
+ out of '<CR><LF>' */
+if (ctx->cur_header && ctx->cur_header->len)
+ {
+ int rc = pdkim_header_complete(ctx);
+ if (rc != PDKIM_OK) return rc;
+ pdkim_update_bodyhash(ctx, "\r\n", 2);
}
- /* ---------------------------------------------------------------------- */
+else
+ DEBUG(D_acl) debug_printf(
+ "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
- while (sig != NULL) {
- sha1_context sha1_headers;
- sha2_context sha2_headers;
- char *sig_hdr;
- char headerhash[32];
+/* Build (and/or evaluate) body hash */
+if (pdkim_finish_bodyhash(ctx) != PDKIM_OK)
+ return PDKIM_ERR_OOM;
- if (sig->algo == PDKIM_ALGO_RSA_SHA1)
- sha1_starts(&sha1_headers);
- else
- sha2_starts(&sha2_headers,0);
-
- #ifdef PDKIM_DEBUG
- if (ctx->debug_stream)
- fprintf(ctx->debug_stream,
- "PDKIM >> Hashed header data, canonicalized, in sequence >>>>>>>>>>>>>>\n");
- #endif
-
- /* SIGNING ---------------------------------------------------------------- */
- /* When signing, walk through our header list and add them to the hash. As we
- go, construct a list of the header's names to use for the h= parameter. */
- if (ctx->mode == PDKIM_MODE_SIGN) {
- pdkim_stringlist *p = sig->headers;
- while (p != NULL) {
- char *rh = NULL;
- /* Collect header names (Note: colon presence is guaranteed here) */
- char *q = strchr(p->value,':');
- if (pdkim_strncat(headernames, p->value,
- (q-(p->value))+((p->next==NULL)?0:1)) == NULL)
- return PDKIM_ERR_OOM;
-
- if (sig->canon_headers == PDKIM_CANON_RELAXED)
- rh = pdkim_relax_header(p->value,1); /* cook header for relaxed canon */
- else
- rh = strdup(p->value); /* just copy it for simple canon */
-
- if (rh == NULL) return PDKIM_ERR_OOM;
-
- /* Feed header to the hash algorithm */
- if (sig->algo == PDKIM_ALGO_RSA_SHA1)
- sha1_update(&(sha1_headers),(unsigned char *)rh,strlen(rh));
- else
- sha2_update(&(sha2_headers),(unsigned char *)rh,strlen(rh));
- #ifdef PDKIM_DEBUG
- if (ctx->debug_stream)
- pdkim_quoteprint(ctx->debug_stream, rh, strlen(rh), 1);
- #endif
- free(rh);
- p = p->next;
+/* SIGNING -------------------------------------------------------------- */
+if (ctx->mode == PDKIM_MODE_SIGN)
+ if (!(headernames = pdkim_strnew(NULL)))
+ return PDKIM_ERR_OOM;
+/* ---------------------------------------------------------------------- */
+
+while (sig)
+ {
+ sha1_context sha1_headers;
+ sha2_context sha2_headers;
+ char *sig_hdr;
+ char headerhash[32];
+
+ if (sig->algo == PDKIM_ALGO_RSA_SHA1)
+ sha1_starts(&sha1_headers);
+ else
+ sha2_starts(&sha2_headers, 0);
+
+ DEBUG(D_acl) debug_printf(
+ "PDKIM >> Hashed header data, canonicalized, in sequence >>>>>>>>>>>>>>\n");
+
+ /* SIGNING ---------------------------------------------------------------- */
+ /* When signing, walk through our header list and add them to the hash. As we
+ go, construct a list of the header's names to use for the h= parameter. */
+
+ if (ctx->mode == PDKIM_MODE_SIGN)
+ {
+ pdkim_stringlist *p;
+
+ for (p = sig->headers; p; p = p->next)
+ {
+ char *rh = NULL;
+ /* Collect header names (Note: colon presence is guaranteed here) */
+ char *q = strchr(p->value, ':');
+
+ if (!(pdkim_strncat(headernames, p->value,
+ (q-(p->value)) + (p->next ? 1 : 0))))
+ return PDKIM_ERR_OOM;
+
+ rh = sig->canon_headers == PDKIM_CANON_RELAXED
+ ? pdkim_relax_header(p->value, 1) /* cook header for relaxed canon */
+ : strdup(p->value); /* just copy it for simple canon */
+ if (!rh)
+ return PDKIM_ERR_OOM;
+
+ /* Feed header to the hash algorithm */
+ if (sig->algo == PDKIM_ALGO_RSA_SHA1)
+ sha1_update(&(sha1_headers), (unsigned char *)rh, strlen(rh));
+ else
+ sha2_update(&(sha2_headers), (unsigned char *)rh, strlen(rh));
+
+ DEBUG(D_acl) pdkim_quoteprint(rh, strlen(rh), 1);
+ free(rh);
}
}
- /* VERIFICATION ----------------------------------------------------------- */
- /* When verifying, walk through the header name list in the h= parameter and
- add the headers to the hash in that order. */
- else {
- char *b = strdup(sig->headernames);
- char *p = b;
- char *q = NULL;
- pdkim_stringlist *hdrs = ctx->headers;
-
- if (b == NULL) return PDKIM_ERR_OOM;
-
- /* clear tags */
- while (hdrs != NULL) {
- hdrs->tag = 0;
- hdrs = hdrs->next;
- }
- while(1) {
- hdrs = ctx->headers;
- q = strchr(p,':');
- if (q != NULL) *q = '\0';
- while (hdrs != NULL) {
- if ( (hdrs->tag == 0) &&
- (strncasecmp(hdrs->value,p,strlen(p)) == 0) &&
- ((hdrs->value)[strlen(p)] == ':') ) {
- char *rh = NULL;
- if (sig->canon_headers == PDKIM_CANON_RELAXED)
- rh = pdkim_relax_header(hdrs->value,1); /* cook header for relaxed canon */
- else
- rh = strdup(hdrs->value); /* just copy it for simple canon */
- if (rh == NULL) return PDKIM_ERR_OOM;
- /* Feed header to the hash algorithm */
- if (sig->algo == PDKIM_ALGO_RSA_SHA1)
- sha1_update(&(sha1_headers),(unsigned char *)rh,strlen(rh));
- else
- sha2_update(&(sha2_headers),(unsigned char *)rh,strlen(rh));
- #ifdef PDKIM_DEBUG
- if (ctx->debug_stream)
- pdkim_quoteprint(ctx->debug_stream, rh, strlen(rh), 1);
- #endif
- free(rh);
- hdrs->tag = 1;
- break;
- }
- hdrs = hdrs->next;
- }
- if (q == NULL) break;
- p = q+1;
+ /* VERIFICATION ----------------------------------------------------------- */
+ /* When verifying, walk through the header name list in the h= parameter and
+ add the headers to the hash in that order. */
+ else
+ {
+ char *b = strdup(sig->headernames);
+ char *p = b;
+ char *q = NULL;
+ pdkim_stringlist *hdrs;
+
+ if (!b) return PDKIM_ERR_OOM;
+
+ /* clear tags */
+ for (hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
+ hdrs->tag = 0;
+
+ while(1)
+ {
+ if ((q = strchr(p, ':')))
+ *q = '\0';
+
+ for (hdrs = ctx->headers; hdrs; hdrs = hdrs->next)
+ if ( hdrs->tag == 0
+ && strncasecmp(hdrs->value, p, strlen(p)) == 0
+ && (hdrs->value)[strlen(p)] == ':'
+ )
+ {
+ char *rh;
+
+ rh = sig->canon_headers == PDKIM_CANON_RELAXED
+ ? pdkim_relax_header(hdrs->value, 1) /* cook header for relaxed canon */
+ : strdup(hdrs->value); /* just copy it for simple canon */
+ if (!rh)
+ return PDKIM_ERR_OOM;
+
+ /* Feed header to the hash algorithm */
+ if (sig->algo == PDKIM_ALGO_RSA_SHA1)
+ sha1_update(&sha1_headers, (unsigned char *)rh, strlen(rh));
+ else
+ sha2_update(&sha2_headers, (unsigned char *)rh, strlen(rh));
+
+ DEBUG(D_acl) pdkim_quoteprint(rh, strlen(rh), 1);
+ free(rh);
+ hdrs->tag = 1;
+ break;
+ }
+
+ if (!q) break;
+ p = q+1;
}
- free(b);
+ free(b);
}
- #ifdef PDKIM_DEBUG
- if (ctx->debug_stream)
- fprintf(ctx->debug_stream,
- "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
- #endif
+ DEBUG(D_acl) debug_printf(
+ "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
- /* SIGNING ---------------------------------------------------------------- */
- if (ctx->mode == PDKIM_MODE_SIGN) {
- /* Copy headernames to signature struct */
- sig->headernames = strdup(headernames->str);
- pdkim_strfree(headernames);
+ /* SIGNING ---------------------------------------------------------------- */
+ if (ctx->mode == PDKIM_MODE_SIGN)
+ {
+ /* Copy headernames to signature struct */
+ sig->headernames = strdup(headernames->str);
+ pdkim_strfree(headernames);
- /* Create signature header with b= omitted */
- sig_hdr = pdkim_create_header(ctx->sig,0);
- }
- /* VERIFICATION ----------------------------------------------------------- */
- else {
- sig_hdr = strdup(sig->rawsig_no_b_val);
+ /* Create signature header with b= omitted */
+ sig_hdr = pdkim_create_header(ctx->sig, 0);
}
- /* ------------------------------------------------------------------------ */
- if (sig_hdr == NULL) return PDKIM_ERR_OOM;
+ /* VERIFICATION ----------------------------------------------------------- */
+ else
+ sig_hdr = strdup(sig->rawsig_no_b_val);
+ /* ------------------------------------------------------------------------ */
- /* Relax header if necessary */
- if (sig->canon_headers == PDKIM_CANON_RELAXED) {
- char *relaxed_hdr = pdkim_relax_header(sig_hdr,0);
- free(sig_hdr);
- if (relaxed_hdr == NULL) return PDKIM_ERR_OOM;
- sig_hdr = relaxed_hdr;
+ if (!sig_hdr)
+ return PDKIM_ERR_OOM;
+
+ /* Relax header if necessary */
+ if (sig->canon_headers == PDKIM_CANON_RELAXED)
+ {
+ char *relaxed_hdr = pdkim_relax_header(sig_hdr, 0);
+
+ free(sig_hdr);
+ if (!relaxed_hdr)
+ return PDKIM_ERR_OOM;
+ sig_hdr = relaxed_hdr;
}
- #ifdef PDKIM_DEBUG
- if (ctx->debug_stream) {
- fprintf(ctx->debug_stream,
- "PDKIM >> Signed DKIM-Signature header, canonicalized >>>>>>>>>>>>>>>>>\n");
- pdkim_quoteprint(ctx->debug_stream, sig_hdr, strlen(sig_hdr), 1);
- fprintf(ctx->debug_stream,
- "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
+ DEBUG(D_acl)
+ {
+ debug_printf(
+ "PDKIM >> Signed DKIM-Signature header, canonicalized >>>>>>>>>>>>>>>>>\n");
+ pdkim_quoteprint(sig_hdr, strlen(sig_hdr), 1);
+ debug_printf(
+ "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
}
- #endif
-
- /* Finalize header hash */
- if (sig->algo == PDKIM_ALGO_RSA_SHA1) {
- sha1_update(&(sha1_headers),(unsigned char *)sig_hdr,strlen(sig_hdr));
- sha1_finish(&(sha1_headers),(unsigned char *)headerhash);
- #ifdef PDKIM_DEBUG
- if (ctx->debug_stream) {
- fprintf(ctx->debug_stream, "PDKIM [%s] hh computed: ", sig->domain);
- pdkim_hexprint(ctx->debug_stream, headerhash, 20, 1);
+
+ /* Finalize header hash */
+ if (sig->algo == PDKIM_ALGO_RSA_SHA1)
+ {
+ sha1_update(&sha1_headers, (unsigned char *)sig_hdr, strlen(sig_hdr));
+ sha1_finish(&sha1_headers, (unsigned char *)headerhash);
+
+ DEBUG(D_acl)
+ {
+ debug_printf( "PDKIM [%s] hh computed: ", sig->domain);
+ pdkim_hexprint(headerhash, 20, 1);
}
- #endif
}
- else {
- sha2_update(&(sha2_headers),(unsigned char *)sig_hdr,strlen(sig_hdr));
- sha2_finish(&(sha2_headers),(unsigned char *)headerhash);
- #ifdef PDKIM_DEBUG
- if (ctx->debug_stream) {
- fprintf(ctx->debug_stream, "PDKIM [%s] hh computed: ", sig->domain);
- pdkim_hexprint(ctx->debug_stream, headerhash, 32, 1);
+ else
+ {
+ sha2_update(&sha2_headers, (unsigned char *)sig_hdr, strlen(sig_hdr));
+ sha2_finish(&sha2_headers, (unsigned char *)headerhash);
+
+ DEBUG(D_acl)
+ {
+ debug_printf("PDKIM [%s] hh computed: ", sig->domain);
+ pdkim_hexprint(headerhash, 32, 1);
}
- #endif
}
- free(sig_hdr);
+ free(sig_hdr);
- /* SIGNING ---------------------------------------------------------------- */
- if (ctx->mode == PDKIM_MODE_SIGN) {
- rsa_context rsa;
+ /* SIGNING ---------------------------------------------------------------- */
+ if (ctx->mode == PDKIM_MODE_SIGN)
+ {
+ rsa_context rsa;
- rsa_init(&rsa,RSA_PKCS_V15,0);
+ rsa_init(&rsa, RSA_PKCS_V15, 0);
- /* Perform private key operation */
- if (rsa_parse_key(&rsa, (unsigned char *)sig->rsa_privkey,
- strlen(sig->rsa_privkey), NULL, 0) != 0) {
- return PDKIM_ERR_RSA_PRIVKEY;
- }
+ /* Perform private key operation */
+ if (rsa_parse_key(&rsa, (unsigned char *)sig->rsa_privkey,
+ strlen(sig->rsa_privkey), NULL, 0) != 0)
+ return PDKIM_ERR_RSA_PRIVKEY;
- sig->sigdata_len = mpi_size(&(rsa.N));
- sig->sigdata = malloc(sig->sigdata_len);
- if (sig->sigdata == NULL) return PDKIM_ERR_OOM;
-
- if (rsa_pkcs1_sign( &rsa, RSA_PRIVATE,
- ((sig->algo == PDKIM_ALGO_RSA_SHA1)?
- SIG_RSA_SHA1:SIG_RSA_SHA256),
- 0,
- (unsigned char *)headerhash,
- (unsigned char *)sig->sigdata ) != 0) {
- return PDKIM_ERR_RSA_SIGNING;
- }
+ sig->sigdata_len = mpi_size(&(rsa.N));
+ if (!(sig->sigdata = malloc(sig->sigdata_len)))
+ return PDKIM_ERR_OOM;
+
+ if (rsa_pkcs1_sign( &rsa, RSA_PRIVATE,
+ ((sig->algo == PDKIM_ALGO_RSA_SHA1)?
+ SIG_RSA_SHA1:SIG_RSA_SHA256),
+ 0,
+ (unsigned char *)headerhash,
+ (unsigned char *)sig->sigdata ) != 0)
+ return PDKIM_ERR_RSA_SIGNING;
- rsa_free(&rsa);
+ rsa_free(&rsa);
- #ifdef PDKIM_DEBUG
- if (ctx->debug_stream) {
- fprintf(ctx->debug_stream, "PDKIM [%s] b computed: ",
- sig->domain);
- pdkim_hexprint(ctx->debug_stream, sig->sigdata, sig->sigdata_len, 1);
+ DEBUG(D_acl)
+ {
+ debug_printf( "PDKIM [%s] b computed: ", sig->domain);
+ pdkim_hexprint(sig->sigdata, sig->sigdata_len, 1);
}
- #endif
- sig->signature_header = pdkim_create_header(ctx->sig,1);
- if (sig->signature_header == NULL) return PDKIM_ERR_OOM;
+ if (!(sig->signature_header = pdkim_create_header(ctx->sig, 1)))
+ return PDKIM_ERR_OOM;
}
- /* VERIFICATION ----------------------------------------------------------- */
- else {
- rsa_context rsa;
- char *dns_txt_name, *dns_txt_reply;
-
- rsa_init(&rsa,RSA_PKCS_V15,0);
-
- dns_txt_name = malloc(PDKIM_DNS_TXT_MAX_NAMELEN);
- if (dns_txt_name == NULL) return PDKIM_ERR_OOM;
- dns_txt_reply = malloc(PDKIM_DNS_TXT_MAX_RECLEN);
- if (dns_txt_reply == NULL) {
- free(dns_txt_name);
- return PDKIM_ERR_OOM;
- }
- memset(dns_txt_reply,0,PDKIM_DNS_TXT_MAX_RECLEN);
- memset(dns_txt_name ,0,PDKIM_DNS_TXT_MAX_NAMELEN);
-
- if (snprintf(dns_txt_name,PDKIM_DNS_TXT_MAX_NAMELEN,
- "%s._domainkey.%s.",
- sig->selector,sig->domain) >= PDKIM_DNS_TXT_MAX_NAMELEN) {
- sig->verify_status = PDKIM_VERIFY_INVALID;
- sig->verify_ext_status = PDKIM_VERIFY_INVALID_BUFFER_SIZE;
- goto NEXT_VERIFY;
- }
- if ((ctx->dns_txt_callback(dns_txt_name, dns_txt_reply) != PDKIM_OK) ||
- (dns_txt_reply[0] == '\0')) {
- sig->verify_status = PDKIM_VERIFY_INVALID;
- sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE;
- goto NEXT_VERIFY;
+ /* VERIFICATION ----------------------------------------------------------- */
+ else
+ {
+ rsa_context rsa;
+ char *dns_txt_name, *dns_txt_reply;
+
+ rsa_init(&rsa, RSA_PKCS_V15, 0);
+
+ if (!(dns_txt_name = malloc(PDKIM_DNS_TXT_MAX_NAMELEN)))
+ return PDKIM_ERR_OOM;
+
+ if (!(dns_txt_reply = malloc(PDKIM_DNS_TXT_MAX_RECLEN)))
+ {
+ free(dns_txt_name);
+ return PDKIM_ERR_OOM;
}
- #ifdef PDKIM_DEBUG
- if (ctx->debug_stream) {
- fprintf(ctx->debug_stream,
- "PDKIM >> Parsing public key record >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
- fprintf(ctx->debug_stream,"Raw record: ");
- pdkim_quoteprint(ctx->debug_stream, dns_txt_reply, strlen(dns_txt_reply), 1);
+ memset(dns_txt_reply, 0, PDKIM_DNS_TXT_MAX_RECLEN);
+ memset(dns_txt_name , 0, PDKIM_DNS_TXT_MAX_NAMELEN);
+
+ if (snprintf(dns_txt_name, PDKIM_DNS_TXT_MAX_NAMELEN,
+ "%s._domainkey.%s.",
+ sig->selector, sig->domain) >= PDKIM_DNS_TXT_MAX_NAMELEN)
+ {
+ sig->verify_status = PDKIM_VERIFY_INVALID;
+ sig->verify_ext_status = PDKIM_VERIFY_INVALID_BUFFER_SIZE;
+ goto NEXT_VERIFY;
}
- #endif
-
- sig->pubkey = pdkim_parse_pubkey_record(ctx,dns_txt_reply);
- if (sig->pubkey == NULL) {
- sig->verify_status = PDKIM_VERIFY_INVALID;
- sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_PARSING;
- #ifdef PDKIM_DEBUG
- if (ctx->debug_stream) {
- fprintf(ctx->debug_stream,"Error while parsing public key record\n");
- fprintf(ctx->debug_stream,
- "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
- }
- #endif
- goto NEXT_VERIFY;
+
+ if ( ctx->dns_txt_callback(dns_txt_name, dns_txt_reply) != PDKIM_OK
+ || dns_txt_reply[0] == '\0')
+ {
+ sig->verify_status = PDKIM_VERIFY_INVALID;
+ sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE;
+ goto NEXT_VERIFY;
}
- #ifdef PDKIM_DEBUG
- if (ctx->debug_stream) {
- fprintf(ctx->debug_stream,
- "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
+ DEBUG(D_acl)
+ {
+ debug_printf(
+ "PDKIM >> Parsing public key record >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"
+ " Raw record: ");
+ pdkim_quoteprint(dns_txt_reply, strlen(dns_txt_reply), 1);
}
- #endif
-
- if (rsa_parse_public_key(&rsa,
- (unsigned char *)sig->pubkey->key,
- sig->pubkey->key_len) != 0) {
- sig->verify_status = PDKIM_VERIFY_INVALID;
- sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_PARSING;
- goto NEXT_VERIFY;
+
+ if (!(sig->pubkey = pdkim_parse_pubkey_record(ctx, dns_txt_reply)))
+ {
+ sig->verify_status = PDKIM_VERIFY_INVALID;
+ sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_PARSING;
+
+ DEBUG(D_acl) debug_printf(
+ " Error while parsing public key record\n"
+ "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
+ goto NEXT_VERIFY;
}
- /* Check the signature */
- if (rsa_pkcs1_verify(&rsa,
- RSA_PUBLIC,
- ((sig->algo == PDKIM_ALGO_RSA_SHA1)?
- SIG_RSA_SHA1:SIG_RSA_SHA256),
- 0,
- (unsigned char *)headerhash,
- (unsigned char *)sig->sigdata) != 0) {
- sig->verify_status = PDKIM_VERIFY_FAIL;
- sig->verify_ext_status = PDKIM_VERIFY_FAIL_MESSAGE;
- goto NEXT_VERIFY;
+ DEBUG(D_acl) debug_printf(
+ "PDKIM <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
+
+ if (rsa_parse_public_key(&rsa,
+ (unsigned char *)sig->pubkey->key,
+ sig->pubkey->key_len) != 0)
+ {
+ sig->verify_status = PDKIM_VERIFY_INVALID;
+ sig->verify_ext_status = PDKIM_VERIFY_INVALID_PUBKEY_PARSING;
+ goto NEXT_VERIFY;
}
- /* We have a winner! (if bodydhash was correct earlier) */
- if (sig->verify_status == PDKIM_VERIFY_NONE) {
- sig->verify_status = PDKIM_VERIFY_PASS;
+ /* Check the signature */
+ if (rsa_pkcs1_verify(&rsa,
+ RSA_PUBLIC,
+ ((sig->algo == PDKIM_ALGO_RSA_SHA1)?
+ SIG_RSA_SHA1:SIG_RSA_SHA256),
+ 0,
+ (unsigned char *)headerhash,
+ (unsigned char *)sig->sigdata) != 0)
+ {
+ sig->verify_status = PDKIM_VERIFY_FAIL;
+ sig->verify_ext_status = PDKIM_VERIFY_FAIL_MESSAGE;
+ goto NEXT_VERIFY;
}
- NEXT_VERIFY:
-
- #ifdef PDKIM_DEBUG
- if (ctx->debug_stream) {
- fprintf(ctx->debug_stream, "PDKIM [%s] signature status: %s",
- sig->domain, pdkim_verify_status_str(sig->verify_status));
- if (sig->verify_ext_status > 0) {
- fprintf(ctx->debug_stream, " (%s)\n",
- pdkim_verify_ext_status_str(sig->verify_ext_status));
- }
- else {
- fprintf(ctx->debug_stream, "\n");
- }
+ /* We have a winner! (if bodydhash was correct earlier) */
+ if (sig->verify_status == PDKIM_VERIFY_NONE)
+ sig->verify_status = PDKIM_VERIFY_PASS;
+
+NEXT_VERIFY:
+
+ DEBUG(D_acl)
+ {
+ debug_printf("PDKIM [%s] signature status: %s",
+ sig->domain, pdkim_verify_status_str(sig->verify_status));
+ if (sig->verify_ext_status > 0)
+ debug_printf(" (%s)\n",
+ pdkim_verify_ext_status_str(sig->verify_ext_status));
+ else
+ debug_printf("\n");
}
- #endif
- rsa_free(&rsa);
- free(dns_txt_name);
- free(dns_txt_reply);
+ rsa_free(&rsa);
+ free(dns_txt_name);
+ free(dns_txt_reply);
}
- sig = sig->next;
+ sig = sig->next;
}
- /* If requested, set return pointer to signature(s) */
- if (return_signatures != NULL) {
- *return_signatures = ctx->sig;
- }
+/* If requested, set return pointer to signature(s) */
+if (return_signatures)
+ *return_signatures = ctx->sig;
- return PDKIM_OK;
+return PDKIM_OK;
}
/* -------------------------------------------------------------------------- */
-DLLEXPORT pdkim_ctx *pdkim_init_verify(int input_mode,
- int(*dns_txt_callback)(char *, char *)
- ) {
- pdkim_ctx *ctx = malloc(sizeof(pdkim_ctx));
- if (ctx == NULL) return NULL;
- memset(ctx,0,sizeof(pdkim_ctx));
-
- ctx->linebuf = malloc(PDKIM_MAX_BODY_LINE_LEN);
- if (ctx->linebuf == NULL) {
- free(ctx);
- return NULL;
+
+DLLEXPORT pdkim_ctx *
+pdkim_init_verify(int(*dns_txt_callback)(char *, char *))
+{
+pdkim_ctx *ctx = malloc(sizeof(pdkim_ctx));
+
+if (!ctx)
+ return NULL;
+memset(ctx, 0, sizeof(pdkim_ctx));
+
+if (!(ctx->linebuf = malloc(PDKIM_MAX_BODY_LINE_LEN)))
+ {
+ free(ctx);
+ return NULL;
}
- ctx->mode = PDKIM_MODE_VERIFY;
- ctx->input_mode = input_mode;
- ctx->dns_txt_callback = dns_txt_callback;
+ctx->mode = PDKIM_MODE_VERIFY;
+ctx->dns_txt_callback = dns_txt_callback;
- return ctx;
+return ctx;
}
/* -------------------------------------------------------------------------- */
-DLLEXPORT pdkim_ctx *pdkim_init_sign(int input_mode,
- char *domain,
- char *selector,
- char *rsa_privkey) {
- pdkim_ctx *ctx;
- pdkim_signature *sig;
- if (!domain || !selector || !rsa_privkey) return NULL;
+DLLEXPORT pdkim_ctx *
+pdkim_init_sign(char *domain, char *selector, char *rsa_privkey)
+{
+pdkim_ctx *ctx;
+pdkim_signature *sig;
- ctx = malloc(sizeof(pdkim_ctx));
- if (ctx == NULL) return NULL;
- memset(ctx,0,sizeof(pdkim_ctx));
+if (!domain || !selector || !rsa_privkey)
+ return NULL;
- ctx->linebuf = malloc(PDKIM_MAX_BODY_LINE_LEN);
- if (ctx->linebuf == NULL) {
- free(ctx);
- return NULL;
+if (!(ctx = malloc(sizeof(pdkim_ctx))))
+ return NULL;
+memset(ctx, 0, sizeof(pdkim_ctx));
+
+if (!(ctx->linebuf = malloc(PDKIM_MAX_BODY_LINE_LEN)))
+ {
+ free(ctx);
+ return NULL;
}
- sig = malloc(sizeof(pdkim_signature));
- if (sig == NULL) {
- free(ctx->linebuf);
- free(ctx);
- return NULL;
+if (!(sig = malloc(sizeof(pdkim_signature))))
+ {
+ free(ctx->linebuf);
+ free(ctx);
+ return NULL;
}
- memset(sig,0,sizeof(pdkim_signature));
- sig->bodylength = -1;
+memset(sig, 0, sizeof(pdkim_signature));
- ctx->mode = PDKIM_MODE_SIGN;
- ctx->input_mode = input_mode;
- ctx->sig = sig;
+sig->bodylength = -1;
- ctx->sig->domain = strdup(domain);
- ctx->sig->selector = strdup(selector);
- ctx->sig->rsa_privkey = strdup(rsa_privkey);
+ctx->mode = PDKIM_MODE_SIGN;
+ctx->sig = sig;
- if (!ctx->sig->domain || !ctx->sig->selector || !ctx->sig->rsa_privkey) {
- pdkim_free_ctx(ctx);
- return NULL;
- }
+ctx->sig->domain = strdup(domain);
+ctx->sig->selector = strdup(selector);
+ctx->sig->rsa_privkey = strdup(rsa_privkey);
- ctx->sig->sha1_body = malloc(sizeof(sha1_context));
- if (ctx->sig->sha1_body == NULL) {
- pdkim_free_ctx(ctx);
- return NULL;
- }
- sha1_starts(ctx->sig->sha1_body);
+if (!ctx->sig->domain || !ctx->sig->selector || !ctx->sig->rsa_privkey)
+ goto BAIL;
- ctx->sig->sha2_body = malloc(sizeof(sha2_context));
- if (ctx->sig->sha2_body == NULL) {
- pdkim_free_ctx(ctx);
- return NULL;
- }
- sha2_starts(ctx->sig->sha2_body,0);
+if (!(ctx->sig->sha1_body = malloc(sizeof(sha1_context))))
+ goto BAIL;
+sha1_starts(ctx->sig->sha1_body);
- return ctx;
-}
+if (!(ctx->sig->sha2_body = malloc(sizeof(sha2_context))))
+ goto BAIL;
+sha2_starts(ctx->sig->sha2_body, 0);
-#ifdef PDKIM_DEBUG
-/* -------------------------------------------------------------------------- */
-DLLEXPORT void pdkim_set_debug_stream(pdkim_ctx *ctx,
- FILE *debug_stream) {
- ctx->debug_stream = debug_stream;
+return ctx;
+
+BAIL:
+ pdkim_free_ctx(ctx);
+ return NULL;
}
-#endif
/* -------------------------------------------------------------------------- */
-DLLEXPORT int pdkim_set_optional(pdkim_ctx *ctx,
+
+DLLEXPORT int
+pdkim_set_optional(pdkim_ctx *ctx,
char *sign_headers,
char *identity,
int canon_headers,
long bodylength,
int algo,
unsigned long created,
- unsigned long expires) {
+ unsigned long expires)
+{
- if (identity != NULL) {
- ctx->sig->identity = strdup(identity);
- if (ctx->sig->identity == NULL) return PDKIM_ERR_OOM;
- }
+if (identity)
+ if (!(ctx->sig->identity = strdup(identity)))
+ return PDKIM_ERR_OOM;
- if (sign_headers != NULL) {
- ctx->sig->sign_headers = strdup(sign_headers);
- if (ctx->sig->sign_headers == NULL) return PDKIM_ERR_OOM;
- }
+if (sign_headers)
+ if (!(ctx->sig->sign_headers = strdup(sign_headers)))
+ return PDKIM_ERR_OOM;
- ctx->sig->canon_headers = canon_headers;
- ctx->sig->canon_body = canon_body;
- ctx->sig->bodylength = bodylength;
- ctx->sig->algo = algo;
- ctx->sig->created = created;
- ctx->sig->expires = expires;
+ctx->sig->canon_headers = canon_headers;
+ctx->sig->canon_body = canon_body;
+ctx->sig->bodylength = bodylength;
+ctx->sig->algo = algo;
+ctx->sig->created = created;
+ctx->sig->expires = expires;
- return PDKIM_OK;
+return PDKIM_OK;
}
+
+
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-/* -------------------------------------------------------------------------- */
-/* Debugging. This can also be enabled/disabled at run-time. I recommend to
- leave it defined. */
-#define PDKIM_DEBUG
-
/* -------------------------------------------------------------------------- */
/* Length of the preallocated buffer for the "answer" from the dns/txt
callback function. This should match the maximum RDLENGTH from DNS. */
/* Context to keep state between all operations. */
#define PDKIM_MODE_SIGN 0
#define PDKIM_MODE_VERIFY 1
-#define PDKIM_INPUT_NORMAL 0
-#define PDKIM_INPUT_SMTP 1
typedef struct pdkim_ctx {
/* PDKIM_MODE_VERIFY or PDKIM_MODE_SIGN */
int mode;
- /* PDKIM_INPUT_SMTP or PDKIM_INPUT_NORMAL */
- int input_mode;
-
/* One (signing) or several chained (verification) signatures */
pdkim_signature *sig;
pdkim_str *cur_header;
char *linebuf;
int linebuf_offset;
- int seen_lf;
- int seen_eod;
- int past_headers;
+ BOOL seen_lf;
+ BOOL seen_eod;
+ BOOL past_headers;
int num_buffered_crlf;
int num_headers;
pdkim_stringlist *headers; /* Raw headers for verification */
-
-#ifdef PDKIM_DEBUG
- /* A FILE pointer. When not NULL, debug output will be generated
- and sent to this stream */
- FILE *debug_stream;
-#endif
-
} pdkim_ctx;
#endif
DLLEXPORT
-pdkim_ctx *pdkim_init_sign (int, char *, char *, char *);
+pdkim_ctx *pdkim_init_sign (char *, char *, char *);
DLLEXPORT
-pdkim_ctx *pdkim_init_verify (int, int(*)(char *, char *));
+pdkim_ctx *pdkim_init_verify (int(*)(char *, char *));
DLLEXPORT
int pdkim_set_optional (pdkim_ctx *, char *, char *,int, int,
DLLEXPORT
void pdkim_free_ctx (pdkim_ctx *);
-#ifdef PDKIM_DEBUG
-DLLEXPORT
-void pdkim_set_debug_stream(pdkim_ctx *, FILE *);
-#endif
-
#ifdef __cplusplus
}
#endif
--- /dev/null
+/**
+ * \file base64.h
+ *
+ * Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef POLARSSL_BASE64_H
+#define POLARSSL_BASE64_H
+
+#define POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL 0x0010
+#define POLARSSL_ERR_BASE64_INVALID_CHARACTER 0x0012
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Encode a buffer into base64 format
+ *
+ * \param dst destination buffer
+ * \param dlen size of the buffer
+ * \param src source buffer
+ * \param slen amount of data to be encoded
+ *
+ * \return 0 if successful, or POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL.
+ * *dlen is always updated to reflect the amount
+ * of data that has (or would have) been written.
+ *
+ * \note Call this function with *dlen = 0 to obtain the
+ * required buffer size in *dlen
+ */
+int base64_encode( unsigned char *dst, int *dlen,
+ const unsigned char *src, int slen );
+
+/**
+ * \brief Decode a base64-formatted buffer
+ *
+ * \param dst destination buffer
+ * \param dlen size of the buffer
+ * \param src source buffer
+ * \param slen amount of data to be decoded
+ *
+ * \return 0 if successful, POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL, or
+ * POLARSSL_ERR_BASE64_INVALID_DATA if the input data is not
+ * correct. *dlen is always updated to reflect the amount
+ * of data that has (or would have) been written.
+ *
+ * \note Call this function with *dlen = 0 to obtain the
+ * required buffer size in *dlen
+ */
+int base64_decode( unsigned char *dst, int *dlen,
+ const unsigned char *src, int slen );
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ */
+int base64_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* base64.h */
--- /dev/null
+/**
+ * \file bignum.h
+ *
+ * Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef POLARSSL_BIGNUM_H
+#define POLARSSL_BIGNUM_H
+
+#include <stdio.h>
+
+#define POLARSSL_ERR_MPI_FILE_IO_ERROR 0x0002
+#define POLARSSL_ERR_MPI_BAD_INPUT_DATA 0x0004
+#define POLARSSL_ERR_MPI_INVALID_CHARACTER 0x0006
+#define POLARSSL_ERR_MPI_BUFFER_TOO_SMALL 0x0008
+#define POLARSSL_ERR_MPI_NEGATIVE_VALUE 0x000A
+#define POLARSSL_ERR_MPI_DIVISION_BY_ZERO 0x000C
+#define POLARSSL_ERR_MPI_NOT_ACCEPTABLE 0x000E
+
+#define MPI_CHK(f) if( ( ret = f ) != 0 ) goto cleanup
+
+/*
+ * Define the base integer type, architecture-wise
+ */
+#if defined(POLARSSL_HAVE_INT8)
+typedef unsigned char t_int;
+typedef unsigned short t_dbl;
+#else
+#if defined(POLARSSL_HAVE_INT16)
+typedef unsigned short t_int;
+typedef unsigned long t_dbl;
+#else
+ typedef unsigned long t_int;
+ #if defined(_MSC_VER) && defined(_M_IX86)
+ typedef unsigned __int64 t_dbl;
+ #else
+ #if defined(__amd64__) || defined(__x86_64__) || \
+ defined(__ppc64__) || defined(__powerpc64__) || \
+ defined(__ia64__) || defined(__alpha__)
+ typedef unsigned int t_dbl __attribute__((mode(TI)));
+ #else
+ #if defined(POLARSSL_HAVE_LONGLONG)
+ typedef unsigned long long t_dbl;
+ #endif
+ #endif
+ #endif
+#endif
+#endif
+
+/**
+ * \brief MPI structure
+ */
+typedef struct
+{
+ int s; /*!< integer sign */
+ int n; /*!< total # of limbs */
+ t_int *p; /*!< pointer to limbs */
+}
+mpi;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Initialize one or more mpi
+ */
+void mpi_init( mpi *X, ... );
+
+/**
+ * \brief Unallocate one or more mpi
+ */
+void mpi_free( mpi *X, ... );
+
+/**
+ * \brief Enlarge to the specified number of limbs
+ *
+ * \param X MPI to grow
+ * \param nblimbs The target number of limbs
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_grow( mpi *X, int nblimbs );
+
+/**
+ * \brief Copy the contents of Y into X
+ *
+ * \param X Destination MPI
+ * \param Y Source MPI
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_copy( mpi *X, const mpi *Y );
+
+/**
+ * \brief Swap the contents of X and Y
+ *
+ * \param X First MPI value
+ * \param Y Second MPI value
+ */
+void mpi_swap( mpi *X, mpi *Y );
+
+/**
+ * \brief Set value from integer
+ *
+ * \param X MPI to set
+ * \param z Value to use
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_lset( mpi *X, int z );
+
+/**
+ * \brief Return the number of least significant bits
+ *
+ * \param X MPI to use
+ */
+int mpi_lsb( const mpi *X );
+
+/**
+ * \brief Return the number of most significant bits
+ *
+ * \param X MPI to use
+ */
+int mpi_msb( const mpi *X );
+
+/**
+ * \brief Return the total size in bytes
+ *
+ * \param X MPI to use
+ */
+int mpi_size( const mpi *X );
+
+/**
+ * \brief Import from an ASCII string
+ *
+ * \param X Destination MPI
+ * \param radix Input numeric base
+ * \param s Null-terminated string buffer
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
+ */
+int mpi_read_string( mpi *X, int radix, const char *s );
+
+/**
+ * \brief Export into an ASCII string
+ *
+ * \param X Source MPI
+ * \param radix Output numeric base
+ * \param s String buffer
+ * \param slen String buffer size
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code.
+ * *slen is always updated to reflect the amount
+ * of data that has (or would have) been written.
+ *
+ * \note Call this function with *slen = 0 to obtain the
+ * minimum required buffer size in *slen.
+ */
+int mpi_write_string( const mpi *X, int radix, char *s, int *slen );
+
+/**
+ * \brief Read X from an opened file
+ *
+ * \param X Destination MPI
+ * \param radix Input numeric base
+ * \param fin Input file handle
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
+ */
+int mpi_read_file( mpi *X, int radix, FILE *fin );
+
+/**
+ * \brief Write X into an opened file, or stdout if fout is NULL
+ *
+ * \param p Prefix, can be NULL
+ * \param X Source MPI
+ * \param radix Output numeric base
+ * \param fout Output file handle (can be NULL)
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
+ *
+ * \note Set fout == NULL to print X on the console.
+ */
+int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout );
+
+/**
+ * \brief Import X from unsigned binary data, big endian
+ *
+ * \param X Destination MPI
+ * \param buf Input buffer
+ * \param buflen Input buffer size
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_read_binary( mpi *X, const unsigned char *buf, int buflen );
+
+/**
+ * \brief Export X into unsigned binary data, big endian
+ *
+ * \param X Source MPI
+ * \param buf Output buffer
+ * \param buflen Output buffer size
+ *
+ * \return 0 if successful,
+ * POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough
+ */
+int mpi_write_binary( const mpi *X, unsigned char *buf, int buflen );
+
+/**
+ * \brief Left-shift: X <<= count
+ *
+ * \param X MPI to shift
+ * \param count Amount to shift
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_shift_l( mpi *X, int count );
+
+/**
+ * \brief Right-shift: X >>= count
+ *
+ * \param X MPI to shift
+ * \param count Amount to shift
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_shift_r( mpi *X, int count );
+
+/**
+ * \brief Compare unsigned values
+ *
+ * \param X Left-hand MPI
+ * \param Y Right-hand MPI
+ *
+ * \return 1 if |X| is greater than |Y|,
+ * -1 if |X| is lesser than |Y| or
+ * 0 if |X| is equal to |Y|
+ */
+int mpi_cmp_abs( const mpi *X, const mpi *Y );
+
+/**
+ * \brief Compare signed values
+ *
+ * \param X Left-hand MPI
+ * \param Y Right-hand MPI
+ *
+ * \return 1 if X is greater than Y,
+ * -1 if X is lesser than Y or
+ * 0 if X is equal to Y
+ */
+int mpi_cmp_mpi( const mpi *X, const mpi *Y );
+
+/**
+ * \brief Compare signed values
+ *
+ * \param X Left-hand MPI
+ * \param z The integer value to compare to
+ *
+ * \return 1 if X is greater than z,
+ * -1 if X is lesser than z or
+ * 0 if X is equal to z
+ */
+int mpi_cmp_int( const mpi *X, int z );
+
+/**
+ * \brief Unsigned addition: X = |A| + |B|
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param B Right-hand MPI
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_add_abs( mpi *X, const mpi *A, const mpi *B );
+
+/**
+ * \brief Unsigned substraction: X = |A| - |B|
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param B Right-hand MPI
+ *
+ * \return 0 if successful,
+ * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B is greater than A
+ */
+int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B );
+
+/**
+ * \brief Signed addition: X = A + B
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param B Right-hand MPI
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B );
+
+/**
+ * \brief Signed substraction: X = A - B
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param B Right-hand MPI
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B );
+
+/**
+ * \brief Signed addition: X = A + b
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param b The integer value to add
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_add_int( mpi *X, const mpi *A, int b );
+
+/**
+ * \brief Signed substraction: X = A - b
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param b The integer value to subtract
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_sub_int( mpi *X, const mpi *A, int b );
+
+/**
+ * \brief Baseline multiplication: X = A * B
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param B Right-hand MPI
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B );
+
+/**
+ * \brief Baseline multiplication: X = A * b
+ * Note: b is an unsigned integer type, thus
+ * Negative values of b are ignored.
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param b The integer value to multiply with
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_mul_int( mpi *X, const mpi *A, t_int b );
+
+/**
+ * \brief Division by mpi: A = Q * B + R
+ *
+ * \param Q Destination MPI for the quotient
+ * \param R Destination MPI for the rest value
+ * \param A Left-hand MPI
+ * \param B Right-hand MPI
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed,
+ * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0
+ *
+ * \note Either Q or R can be NULL.
+ */
+int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B );
+
+/**
+ * \brief Division by int: A = Q * b + R
+ *
+ * \param Q Destination MPI for the quotient
+ * \param R Destination MPI for the rest value
+ * \param A Left-hand MPI
+ * \param b Integer to divide by
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed,
+ * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
+ *
+ * \note Either Q or R can be NULL.
+ */
+int mpi_div_int( mpi *Q, mpi *R, const mpi *A, int b );
+
+/**
+ * \brief Modulo: R = A mod B
+ *
+ * \param R Destination MPI for the rest value
+ * \param A Left-hand MPI
+ * \param B Right-hand MPI
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed,
+ * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0,
+ * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B < 0
+ */
+int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B );
+
+/**
+ * \brief Modulo: r = A mod b
+ *
+ * \param r Destination t_int
+ * \param A Left-hand MPI
+ * \param b Integer to divide by
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed,
+ * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0,
+ * POLARSSL_ERR_MPI_NEGATIVE_VALUE if b < 0
+ */
+int mpi_mod_int( t_int *r, const mpi *A, int b );
+
+/**
+ * \brief Sliding-window exponentiation: X = A^E mod N
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param E Exponent MPI
+ * \param N Modular MPI
+ * \param _RR Speed-up MPI used for recalculations
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed,
+ * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or even
+ *
+ * \note _RR is used to avoid re-computing R*R mod N across
+ * multiple calls, which speeds up things a bit. It can
+ * be set to NULL if the extra performance is unneeded.
+ */
+int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR );
+
+/**
+ * \brief Greatest common divisor: G = gcd(A, B)
+ *
+ * \param G Destination MPI
+ * \param A Left-hand MPI
+ * \param B Right-hand MPI
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_gcd( mpi *G, const mpi *A, const mpi *B );
+
+/**
+ * \brief Modular inverse: X = A^-1 mod N
+ *
+ * \param X Destination MPI
+ * \param A Left-hand MPI
+ * \param N Right-hand MPI
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed,
+ * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or nil
+ POLARSSL_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N
+ */
+int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N );
+
+/**
+ * \brief Miller-Rabin primality test
+ *
+ * \param X MPI to check
+ * \param f_rng RNG function
+ * \param p_rng RNG parameter
+ *
+ * \return 0 if successful (probably prime),
+ * 1 if memory allocation failed,
+ * POLARSSL_ERR_MPI_NOT_ACCEPTABLE if X is not prime
+ */
+int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng );
+
+/**
+ * \brief Prime number generation
+ *
+ * \param X Destination MPI
+ * \param nbits Required size of X in bits
+ * \param dh_flag If 1, then (X-1)/2 will be prime too
+ * \param f_rng RNG function
+ * \param p_rng RNG parameter
+ *
+ * \return 0 if successful (probably prime),
+ * 1 if memory allocation failed,
+ * POLARSSL_ERR_MPI_BAD_INPUT_DATA if nbits is < 3
+ */
+int mpi_gen_prime( mpi *X, int nbits, int dh_flag,
+ int (*f_rng)(void *), void *p_rng );
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ */
+int mpi_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* bignum.h */
--- /dev/null
+/**
+ * \file bn_mul.h
+ *
+ * Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+/*
+ * Multiply source vector [s] with b, add result
+ * to destination vector [d] and set carry c.
+ *
+ * Currently supports:
+ *
+ * . IA-32 (386+) . AMD64 / EM64T
+ * . IA-32 (SSE2) . Motorola 68000
+ * . PowerPC, 32-bit . MicroBlaze
+ * . PowerPC, 64-bit . TriCore
+ * . SPARC v8 . ARM v3+
+ * . Alpha . MIPS32
+ * . C, longlong . C, generic
+ */
+#ifndef POLARSSL_BN_MUL_H
+#define POLARSSL_BN_MUL_H
+
+#include "polarssl/config.h"
+
+#if defined(POLARSSL_HAVE_ASM)
+
+#if defined(__GNUC__)
+#if defined(__i386__)
+
+#define MULADDC_INIT \
+ asm( " \
+ movl %%ebx, %0; \
+ movl %5, %%esi; \
+ movl %6, %%edi; \
+ movl %7, %%ecx; \
+ movl %8, %%ebx; \
+ "
+
+#define MULADDC_CORE \
+ " \
+ lodsl; \
+ mull %%ebx; \
+ addl %%ecx, %%eax; \
+ adcl $0, %%edx; \
+ addl (%%edi), %%eax; \
+ adcl $0, %%edx; \
+ movl %%edx, %%ecx; \
+ stosl; \
+ "
+
+#if defined(POLARSSL_HAVE_SSE2)
+
+#define MULADDC_HUIT \
+ " \
+ movd %%ecx, %%mm1; \
+ movd %%ebx, %%mm0; \
+ movd (%%edi), %%mm3; \
+ paddq %%mm3, %%mm1; \
+ movd (%%esi), %%mm2; \
+ pmuludq %%mm0, %%mm2; \
+ movd 4(%%esi), %%mm4; \
+ pmuludq %%mm0, %%mm4; \
+ movd 8(%%esi), %%mm6; \
+ pmuludq %%mm0, %%mm6; \
+ movd 12(%%esi), %%mm7; \
+ pmuludq %%mm0, %%mm7; \
+ paddq %%mm2, %%mm1; \
+ movd 4(%%edi), %%mm3; \
+ paddq %%mm4, %%mm3; \
+ movd 8(%%edi), %%mm5; \
+ paddq %%mm6, %%mm5; \
+ movd 12(%%edi), %%mm4; \
+ paddq %%mm4, %%mm7; \
+ movd %%mm1, (%%edi); \
+ movd 16(%%esi), %%mm2; \
+ pmuludq %%mm0, %%mm2; \
+ psrlq $32, %%mm1; \
+ movd 20(%%esi), %%mm4; \
+ pmuludq %%mm0, %%mm4; \
+ paddq %%mm3, %%mm1; \
+ movd 24(%%esi), %%mm6; \
+ pmuludq %%mm0, %%mm6; \
+ movd %%mm1, 4(%%edi); \
+ psrlq $32, %%mm1; \
+ movd 28(%%esi), %%mm3; \
+ pmuludq %%mm0, %%mm3; \
+ paddq %%mm5, %%mm1; \
+ movd 16(%%edi), %%mm5; \
+ paddq %%mm5, %%mm2; \
+ movd %%mm1, 8(%%edi); \
+ psrlq $32, %%mm1; \
+ paddq %%mm7, %%mm1; \
+ movd 20(%%edi), %%mm5; \
+ paddq %%mm5, %%mm4; \
+ movd %%mm1, 12(%%edi); \
+ psrlq $32, %%mm1; \
+ paddq %%mm2, %%mm1; \
+ movd 24(%%edi), %%mm5; \
+ paddq %%mm5, %%mm6; \
+ movd %%mm1, 16(%%edi); \
+ psrlq $32, %%mm1; \
+ paddq %%mm4, %%mm1; \
+ movd 28(%%edi), %%mm5; \
+ paddq %%mm5, %%mm3; \
+ movd %%mm1, 20(%%edi); \
+ psrlq $32, %%mm1; \
+ paddq %%mm6, %%mm1; \
+ movd %%mm1, 24(%%edi); \
+ psrlq $32, %%mm1; \
+ paddq %%mm3, %%mm1; \
+ movd %%mm1, 28(%%edi); \
+ addl $32, %%edi; \
+ addl $32, %%esi; \
+ psrlq $32, %%mm1; \
+ movd %%mm1, %%ecx; \
+ "
+
+#define MULADDC_STOP \
+ " \
+ emms; \
+ movl %4, %%ebx; \
+ movl %%ecx, %1; \
+ movl %%edi, %2; \
+ movl %%esi, %3; \
+ " \
+ : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
+ : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
+ : "eax", "ecx", "edx", "esi", "edi" \
+ );
+
+#else
+
+#define MULADDC_STOP \
+ " \
+ movl %4, %%ebx; \
+ movl %%ecx, %1; \
+ movl %%edi, %2; \
+ movl %%esi, %3; \
+ " \
+ : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
+ : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
+ : "eax", "ecx", "edx", "esi", "edi" \
+ );
+#endif /* SSE2 */
+#endif /* i386 */
+
+#if defined(__amd64__) || defined (__x86_64__)
+
+#define MULADDC_INIT \
+ asm( "movq %0, %%rsi " :: "m" (s)); \
+ asm( "movq %0, %%rdi " :: "m" (d)); \
+ asm( "movq %0, %%rcx " :: "m" (c)); \
+ asm( "movq %0, %%rbx " :: "m" (b)); \
+ asm( "xorq %r8, %r8 " );
+
+#define MULADDC_CORE \
+ asm( "movq (%rsi),%rax " ); \
+ asm( "mulq %rbx " ); \
+ asm( "addq $8, %rsi " ); \
+ asm( "addq %rcx, %rax " ); \
+ asm( "movq %r8, %rcx " ); \
+ asm( "adcq $0, %rdx " ); \
+ asm( "nop " ); \
+ asm( "addq %rax, (%rdi) " ); \
+ asm( "adcq %rdx, %rcx " ); \
+ asm( "addq $8, %rdi " );
+
+#define MULADDC_STOP \
+ asm( "movq %%rcx, %0 " : "=m" (c)); \
+ asm( "movq %%rdi, %0 " : "=m" (d)); \
+ asm( "movq %%rsi, %0 " : "=m" (s) :: \
+ "rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8" );
+
+#endif /* AMD64 */
+
+#if defined(__mc68020__) || defined(__mcpu32__)
+
+#define MULADDC_INIT \
+ asm( "movl %0, %%a2 " :: "m" (s)); \
+ asm( "movl %0, %%a3 " :: "m" (d)); \
+ asm( "movl %0, %%d3 " :: "m" (c)); \
+ asm( "movl %0, %%d2 " :: "m" (b)); \
+ asm( "moveq #0, %d0 " );
+
+#define MULADDC_CORE \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d4:%d1 " ); \
+ asm( "addl %d3, %d1 " ); \
+ asm( "addxl %d0, %d4 " ); \
+ asm( "moveq #0, %d3 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "addxl %d4, %d3 " );
+
+#define MULADDC_STOP \
+ asm( "movl %%d3, %0 " : "=m" (c)); \
+ asm( "movl %%a3, %0 " : "=m" (d)); \
+ asm( "movl %%a2, %0 " : "=m" (s) :: \
+ "d0", "d1", "d2", "d3", "d4", "a2", "a3" );
+
+#define MULADDC_HUIT \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d4:%d1 " ); \
+ asm( "addxl %d3, %d1 " ); \
+ asm( "addxl %d0, %d4 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d3:%d1 " ); \
+ asm( "addxl %d4, %d1 " ); \
+ asm( "addxl %d0, %d3 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d4:%d1 " ); \
+ asm( "addxl %d3, %d1 " ); \
+ asm( "addxl %d0, %d4 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d3:%d1 " ); \
+ asm( "addxl %d4, %d1 " ); \
+ asm( "addxl %d0, %d3 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d4:%d1 " ); \
+ asm( "addxl %d3, %d1 " ); \
+ asm( "addxl %d0, %d4 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d3:%d1 " ); \
+ asm( "addxl %d4, %d1 " ); \
+ asm( "addxl %d0, %d3 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d4:%d1 " ); \
+ asm( "addxl %d3, %d1 " ); \
+ asm( "addxl %d0, %d4 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d3:%d1 " ); \
+ asm( "addxl %d4, %d1 " ); \
+ asm( "addxl %d0, %d3 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "addxl %d0, %d3 " );
+
+#endif /* MC68000 */
+
+#if defined(__powerpc__) || defined(__ppc__)
+#if defined(__powerpc64__) || defined(__ppc64__)
+
+#if defined(__MACH__) && defined(__APPLE__)
+
+#define MULADDC_INIT \
+ asm( "ld r3, %0 " :: "m" (s)); \
+ asm( "ld r4, %0 " :: "m" (d)); \
+ asm( "ld r5, %0 " :: "m" (c)); \
+ asm( "ld r6, %0 " :: "m" (b)); \
+ asm( "addi r3, r3, -8 " ); \
+ asm( "addi r4, r4, -8 " ); \
+ asm( "addic r5, r5, 0 " );
+
+#define MULADDC_CORE \
+ asm( "ldu r7, 8(r3) " ); \
+ asm( "mulld r8, r7, r6 " ); \
+ asm( "mulhdu r9, r7, r6 " ); \
+ asm( "adde r8, r8, r5 " ); \
+ asm( "ld r7, 8(r4) " ); \
+ asm( "addze r5, r9 " ); \
+ asm( "addc r8, r8, r7 " ); \
+ asm( "stdu r8, 8(r4) " );
+
+#define MULADDC_STOP \
+ asm( "addze r5, r5 " ); \
+ asm( "addi r4, r4, 8 " ); \
+ asm( "addi r3, r3, 8 " ); \
+ asm( "std r5, %0 " : "=m" (c)); \
+ asm( "std r4, %0 " : "=m" (d)); \
+ asm( "std r3, %0 " : "=m" (s) :: \
+ "r3", "r4", "r5", "r6", "r7", "r8", "r9" );
+
+#else
+
+#define MULADDC_INIT \
+ asm( "ld %%r3, %0 " :: "m" (s)); \
+ asm( "ld %%r4, %0 " :: "m" (d)); \
+ asm( "ld %%r5, %0 " :: "m" (c)); \
+ asm( "ld %%r6, %0 " :: "m" (b)); \
+ asm( "addi %r3, %r3, -8 " ); \
+ asm( "addi %r4, %r4, -8 " ); \
+ asm( "addic %r5, %r5, 0 " );
+
+#define MULADDC_CORE \
+ asm( "ldu %r7, 8(%r3) " ); \
+ asm( "mulld %r8, %r7, %r6 " ); \
+ asm( "mulhdu %r9, %r7, %r6 " ); \
+ asm( "adde %r8, %r8, %r5 " ); \
+ asm( "ld %r7, 8(%r4) " ); \
+ asm( "addze %r5, %r9 " ); \
+ asm( "addc %r8, %r8, %r7 " ); \
+ asm( "stdu %r8, 8(%r4) " );
+
+#define MULADDC_STOP \
+ asm( "addze %r5, %r5 " ); \
+ asm( "addi %r4, %r4, 8 " ); \
+ asm( "addi %r3, %r3, 8 " ); \
+ asm( "std %%r5, %0 " : "=m" (c)); \
+ asm( "std %%r4, %0 " : "=m" (d)); \
+ asm( "std %%r3, %0 " : "=m" (s) :: \
+ "r3", "r4", "r5", "r6", "r7", "r8", "r9" );
+
+#endif
+
+#else /* PPC32 */
+
+#if defined(__MACH__) && defined(__APPLE__)
+
+#define MULADDC_INIT \
+ asm( "lwz r3, %0 " :: "m" (s)); \
+ asm( "lwz r4, %0 " :: "m" (d)); \
+ asm( "lwz r5, %0 " :: "m" (c)); \
+ asm( "lwz r6, %0 " :: "m" (b)); \
+ asm( "addi r3, r3, -4 " ); \
+ asm( "addi r4, r4, -4 " ); \
+ asm( "addic r5, r5, 0 " );
+
+#define MULADDC_CORE \
+ asm( "lwzu r7, 4(r3) " ); \
+ asm( "mullw r8, r7, r6 " ); \
+ asm( "mulhwu r9, r7, r6 " ); \
+ asm( "adde r8, r8, r5 " ); \
+ asm( "lwz r7, 4(r4) " ); \
+ asm( "addze r5, r9 " ); \
+ asm( "addc r8, r8, r7 " ); \
+ asm( "stwu r8, 4(r4) " );
+
+#define MULADDC_STOP \
+ asm( "addze r5, r5 " ); \
+ asm( "addi r4, r4, 4 " ); \
+ asm( "addi r3, r3, 4 " ); \
+ asm( "stw r5, %0 " : "=m" (c)); \
+ asm( "stw r4, %0 " : "=m" (d)); \
+ asm( "stw r3, %0 " : "=m" (s) :: \
+ "r3", "r4", "r5", "r6", "r7", "r8", "r9" );
+
+#else
+
+#define MULADDC_INIT \
+ asm( "lwz %%r3, %0 " :: "m" (s)); \
+ asm( "lwz %%r4, %0 " :: "m" (d)); \
+ asm( "lwz %%r5, %0 " :: "m" (c)); \
+ asm( "lwz %%r6, %0 " :: "m" (b)); \
+ asm( "addi %r3, %r3, -4 " ); \
+ asm( "addi %r4, %r4, -4 " ); \
+ asm( "addic %r5, %r5, 0 " );
+
+#define MULADDC_CORE \
+ asm( "lwzu %r7, 4(%r3) " ); \
+ asm( "mullw %r8, %r7, %r6 " ); \
+ asm( "mulhwu %r9, %r7, %r6 " ); \
+ asm( "adde %r8, %r8, %r5 " ); \
+ asm( "lwz %r7, 4(%r4) " ); \
+ asm( "addze %r5, %r9 " ); \
+ asm( "addc %r8, %r8, %r7 " ); \
+ asm( "stwu %r8, 4(%r4) " );
+
+#define MULADDC_STOP \
+ asm( "addze %r5, %r5 " ); \
+ asm( "addi %r4, %r4, 4 " ); \
+ asm( "addi %r3, %r3, 4 " ); \
+ asm( "stw %%r5, %0 " : "=m" (c)); \
+ asm( "stw %%r4, %0 " : "=m" (d)); \
+ asm( "stw %%r3, %0 " : "=m" (s) :: \
+ "r3", "r4", "r5", "r6", "r7", "r8", "r9" );
+
+#endif
+
+#endif /* PPC32 */
+#endif /* PPC64 */
+
+#if defined(__sparc__)
+
+#define MULADDC_INIT \
+ asm( "ld %0, %%o0 " :: "m" (s)); \
+ asm( "ld %0, %%o1 " :: "m" (d)); \
+ asm( "ld %0, %%o2 " :: "m" (c)); \
+ asm( "ld %0, %%o3 " :: "m" (b));
+
+#define MULADDC_CORE \
+ asm( "ld [%o0], %o4 " ); \
+ asm( "inc 4, %o0 " ); \
+ asm( "ld [%o1], %o5 " ); \
+ asm( "umul %o3, %o4, %o4 " ); \
+ asm( "addcc %o4, %o2, %o4 " ); \
+ asm( "rd %y, %g1 " ); \
+ asm( "addx %g1, 0, %g1 " ); \
+ asm( "addcc %o4, %o5, %o4 " ); \
+ asm( "st %o4, [%o1] " ); \
+ asm( "addx %g1, 0, %o2 " ); \
+ asm( "inc 4, %o1 " );
+
+#define MULADDC_STOP \
+ asm( "st %%o2, %0 " : "=m" (c)); \
+ asm( "st %%o1, %0 " : "=m" (d)); \
+ asm( "st %%o0, %0 " : "=m" (s) :: \
+ "g1", "o0", "o1", "o2", "o3", "o4", "o5" );
+
+#endif /* SPARCv8 */
+
+#if defined(__microblaze__) || defined(microblaze)
+
+#define MULADDC_INIT \
+ asm( "lwi r3, %0 " :: "m" (s)); \
+ asm( "lwi r4, %0 " :: "m" (d)); \
+ asm( "lwi r5, %0 " :: "m" (c)); \
+ asm( "lwi r6, %0 " :: "m" (b)); \
+ asm( "andi r7, r6, 0xffff" ); \
+ asm( "bsrli r6, r6, 16 " );
+
+#define MULADDC_CORE \
+ asm( "lhui r8, r3, 0 " ); \
+ asm( "addi r3, r3, 2 " ); \
+ asm( "lhui r9, r3, 0 " ); \
+ asm( "addi r3, r3, 2 " ); \
+ asm( "mul r10, r9, r6 " ); \
+ asm( "mul r11, r8, r7 " ); \
+ asm( "mul r12, r9, r7 " ); \
+ asm( "mul r13, r8, r6 " ); \
+ asm( "bsrli r8, r10, 16 " ); \
+ asm( "bsrli r9, r11, 16 " ); \
+ asm( "add r13, r13, r8 " ); \
+ asm( "add r13, r13, r9 " ); \
+ asm( "bslli r10, r10, 16 " ); \
+ asm( "bslli r11, r11, 16 " ); \
+ asm( "add r12, r12, r10 " ); \
+ asm( "addc r13, r13, r0 " ); \
+ asm( "add r12, r12, r11 " ); \
+ asm( "addc r13, r13, r0 " ); \
+ asm( "lwi r10, r4, 0 " ); \
+ asm( "add r12, r12, r10 " ); \
+ asm( "addc r13, r13, r0 " ); \
+ asm( "add r12, r12, r5 " ); \
+ asm( "addc r5, r13, r0 " ); \
+ asm( "swi r12, r4, 0 " ); \
+ asm( "addi r4, r4, 4 " );
+
+#define MULADDC_STOP \
+ asm( "swi r5, %0 " : "=m" (c)); \
+ asm( "swi r4, %0 " : "=m" (d)); \
+ asm( "swi r3, %0 " : "=m" (s) :: \
+ "r3", "r4" , "r5" , "r6" , "r7" , "r8" , \
+ "r9", "r10", "r11", "r12", "r13" );
+
+#endif /* MicroBlaze */
+
+#if defined(__tricore__)
+
+#define MULADDC_INIT \
+ asm( "ld.a %%a2, %0 " :: "m" (s)); \
+ asm( "ld.a %%a3, %0 " :: "m" (d)); \
+ asm( "ld.w %%d4, %0 " :: "m" (c)); \
+ asm( "ld.w %%d1, %0 " :: "m" (b)); \
+ asm( "xor %d5, %d5 " );
+
+#define MULADDC_CORE \
+ asm( "ld.w %d0, [%a2+] " ); \
+ asm( "madd.u %e2, %e4, %d0, %d1 " ); \
+ asm( "ld.w %d0, [%a3] " ); \
+ asm( "addx %d2, %d2, %d0 " ); \
+ asm( "addc %d3, %d3, 0 " ); \
+ asm( "mov %d4, %d3 " ); \
+ asm( "st.w [%a3+], %d2 " );
+
+#define MULADDC_STOP \
+ asm( "st.w %0, %%d4 " : "=m" (c)); \
+ asm( "st.a %0, %%a3 " : "=m" (d)); \
+ asm( "st.a %0, %%a2 " : "=m" (s) :: \
+ "d0", "d1", "e2", "d4", "a2", "a3" );
+
+#endif /* TriCore */
+
+#if defined(__arm__)
+
+#define MULADDC_INIT \
+ asm( "ldr r0, %0 " :: "m" (s)); \
+ asm( "ldr r1, %0 " :: "m" (d)); \
+ asm( "ldr r2, %0 " :: "m" (c)); \
+ asm( "ldr r3, %0 " :: "m" (b));
+
+#define MULADDC_CORE \
+ asm( "ldr r4, [r0], #4 " ); \
+ asm( "mov r5, #0 " ); \
+ asm( "ldr r6, [r1] " ); \
+ asm( "umlal r2, r5, r3, r4 " ); \
+ asm( "adds r7, r6, r2 " ); \
+ asm( "adc r2, r5, #0 " ); \
+ asm( "str r7, [r1], #4 " );
+
+#define MULADDC_STOP \
+ asm( "str r2, %0 " : "=m" (c)); \
+ asm( "str r1, %0 " : "=m" (d)); \
+ asm( "str r0, %0 " : "=m" (s) :: \
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" );
+
+#endif /* ARMv3 */
+
+#if defined(__alpha__)
+
+#define MULADDC_INIT \
+ asm( "ldq $1, %0 " :: "m" (s)); \
+ asm( "ldq $2, %0 " :: "m" (d)); \
+ asm( "ldq $3, %0 " :: "m" (c)); \
+ asm( "ldq $4, %0 " :: "m" (b));
+
+#define MULADDC_CORE \
+ asm( "ldq $6, 0($1) " ); \
+ asm( "addq $1, 8, $1 " ); \
+ asm( "mulq $6, $4, $7 " ); \
+ asm( "umulh $6, $4, $6 " ); \
+ asm( "addq $7, $3, $7 " ); \
+ asm( "cmpult $7, $3, $3 " ); \
+ asm( "ldq $5, 0($2) " ); \
+ asm( "addq $7, $5, $7 " ); \
+ asm( "cmpult $7, $5, $5 " ); \
+ asm( "stq $7, 0($2) " ); \
+ asm( "addq $2, 8, $2 " ); \
+ asm( "addq $6, $3, $3 " ); \
+ asm( "addq $5, $3, $3 " );
+
+#define MULADDC_STOP \
+ asm( "stq $3, %0 " : "=m" (c)); \
+ asm( "stq $2, %0 " : "=m" (d)); \
+ asm( "stq $1, %0 " : "=m" (s) :: \
+ "$1", "$2", "$3", "$4", "$5", "$6", "$7" );
+
+#endif /* Alpha */
+
+#if defined(__mips__)
+
+#define MULADDC_INIT \
+ asm( "lw $10, %0 " :: "m" (s)); \
+ asm( "lw $11, %0 " :: "m" (d)); \
+ asm( "lw $12, %0 " :: "m" (c)); \
+ asm( "lw $13, %0 " :: "m" (b));
+
+#define MULADDC_CORE \
+ asm( "lw $14, 0($10) " ); \
+ asm( "multu $13, $14 " ); \
+ asm( "addi $10, $10, 4 " ); \
+ asm( "mflo $14 " ); \
+ asm( "mfhi $9 " ); \
+ asm( "addu $14, $12, $14 " ); \
+ asm( "lw $15, 0($11) " ); \
+ asm( "sltu $12, $14, $12 " ); \
+ asm( "addu $15, $14, $15 " ); \
+ asm( "sltu $14, $15, $14 " ); \
+ asm( "addu $12, $12, $9 " ); \
+ asm( "sw $15, 0($11) " ); \
+ asm( "addu $12, $12, $14 " ); \
+ asm( "addi $11, $11, 4 " );
+
+#define MULADDC_STOP \
+ asm( "sw $12, %0 " : "=m" (c)); \
+ asm( "sw $11, %0 " : "=m" (d)); \
+ asm( "sw $10, %0 " : "=m" (s) :: \
+ "$9", "$10", "$11", "$12", "$13", "$14", "$15" );
+
+#endif /* MIPS */
+#endif /* GNUC */
+
+#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
+
+#define MULADDC_INIT \
+ __asm mov esi, s \
+ __asm mov edi, d \
+ __asm mov ecx, c \
+ __asm mov ebx, b
+
+#define MULADDC_CORE \
+ __asm lodsd \
+ __asm mul ebx \
+ __asm add eax, ecx \
+ __asm adc edx, 0 \
+ __asm add eax, [edi] \
+ __asm adc edx, 0 \
+ __asm mov ecx, edx \
+ __asm stosd
+
+#if defined(POLARSSL_HAVE_SSE2)
+
+#define EMIT __asm _emit
+
+#define MULADDC_HUIT \
+ EMIT 0x0F EMIT 0x6E EMIT 0xC9 \
+ EMIT 0x0F EMIT 0x6E EMIT 0xC3 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x1F \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
+ EMIT 0x0F EMIT 0x6E EMIT 0x16 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
+ EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xDC \
+ EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xEE \
+ EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xFC \
+ EMIT 0x0F EMIT 0x7E EMIT 0x0F \
+ EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
+ EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCD \
+ EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCF \
+ EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
+ EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCC \
+ EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xDD \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCE \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \
+ EMIT 0x83 EMIT 0xC7 EMIT 0x20 \
+ EMIT 0x83 EMIT 0xC6 EMIT 0x20 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0x7E EMIT 0xC9
+
+#define MULADDC_STOP \
+ EMIT 0x0F EMIT 0x77 \
+ __asm mov c, ecx \
+ __asm mov d, edi \
+ __asm mov s, esi \
+
+#else
+
+#define MULADDC_STOP \
+ __asm mov c, ecx \
+ __asm mov d, edi \
+ __asm mov s, esi \
+
+#endif /* SSE2 */
+#endif /* MSVC */
+
+#endif /* POLARSSL_HAVE_ASM */
+
+#if !defined(MULADDC_CORE)
+#if defined(POLARSSL_HAVE_LONGLONG)
+
+#define MULADDC_INIT \
+{ \
+ t_dbl r; \
+ t_int r0, r1;
+
+#define MULADDC_CORE \
+ r = *(s++) * (t_dbl) b; \
+ r0 = r; \
+ r1 = r >> biL; \
+ r0 += c; r1 += (r0 < c); \
+ r0 += *d; r1 += (r0 < *d); \
+ c = r1; *(d++) = r0;
+
+#define MULADDC_STOP \
+}
+
+#else
+#define MULADDC_INIT \
+{ \
+ t_int s0, s1, b0, b1; \
+ t_int r0, r1, rx, ry; \
+ b0 = ( b << biH ) >> biH; \
+ b1 = ( b >> biH );
+
+#define MULADDC_CORE \
+ s0 = ( *s << biH ) >> biH; \
+ s1 = ( *s >> biH ); s++; \
+ rx = s0 * b1; r0 = s0 * b0; \
+ ry = s1 * b0; r1 = s1 * b1; \
+ r1 += ( rx >> biH ); \
+ r1 += ( ry >> biH ); \
+ rx <<= biH; ry <<= biH; \
+ r0 += rx; r1 += (r0 < rx); \
+ r0 += ry; r1 += (r0 < ry); \
+ r0 += c; r1 += (r0 < c); \
+ r0 += *d; r1 += (r0 < *d); \
+ c = r1; *(d++) = r0;
+
+#define MULADDC_STOP \
+}
+
+#endif /* C (generic) */
+#endif /* C (longlong) */
+
+#endif /* bn_mul.h */
+/**
+ * \file bn_mul.h
+ *
+ * Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+/*
+ * Multiply source vector [s] with b, add result
+ * to destination vector [d] and set carry c.
+ *
+ * Currently supports:
+ *
+ * . IA-32 (386+) . AMD64 / EM64T
+ * . IA-32 (SSE2) . Motorola 68000
+ * . PowerPC, 32-bit . MicroBlaze
+ * . PowerPC, 64-bit . TriCore
+ * . SPARC v8 . ARM v3+
+ * . Alpha . MIPS32
+ * . C, longlong . C, generic
+ */
+#ifndef POLARSSL_BN_MUL_H
+#define POLARSSL_BN_MUL_H
+
+#include "polarssl/config.h"
+
+#if defined(POLARSSL_HAVE_ASM)
+
+#if defined(__GNUC__)
+#if defined(__i386__)
+
+#define MULADDC_INIT \
+ asm( " \
+ movl %%ebx, %0; \
+ movl %5, %%esi; \
+ movl %6, %%edi; \
+ movl %7, %%ecx; \
+ movl %8, %%ebx; \
+ "
+
+#define MULADDC_CORE \
+ " \
+ lodsl; \
+ mull %%ebx; \
+ addl %%ecx, %%eax; \
+ adcl $0, %%edx; \
+ addl (%%edi), %%eax; \
+ adcl $0, %%edx; \
+ movl %%edx, %%ecx; \
+ stosl; \
+ "
+
+#if defined(POLARSSL_HAVE_SSE2)
+
+#define MULADDC_HUIT \
+ " \
+ movd %%ecx, %%mm1; \
+ movd %%ebx, %%mm0; \
+ movd (%%edi), %%mm3; \
+ paddq %%mm3, %%mm1; \
+ movd (%%esi), %%mm2; \
+ pmuludq %%mm0, %%mm2; \
+ movd 4(%%esi), %%mm4; \
+ pmuludq %%mm0, %%mm4; \
+ movd 8(%%esi), %%mm6; \
+ pmuludq %%mm0, %%mm6; \
+ movd 12(%%esi), %%mm7; \
+ pmuludq %%mm0, %%mm7; \
+ paddq %%mm2, %%mm1; \
+ movd 4(%%edi), %%mm3; \
+ paddq %%mm4, %%mm3; \
+ movd 8(%%edi), %%mm5; \
+ paddq %%mm6, %%mm5; \
+ movd 12(%%edi), %%mm4; \
+ paddq %%mm4, %%mm7; \
+ movd %%mm1, (%%edi); \
+ movd 16(%%esi), %%mm2; \
+ pmuludq %%mm0, %%mm2; \
+ psrlq $32, %%mm1; \
+ movd 20(%%esi), %%mm4; \
+ pmuludq %%mm0, %%mm4; \
+ paddq %%mm3, %%mm1; \
+ movd 24(%%esi), %%mm6; \
+ pmuludq %%mm0, %%mm6; \
+ movd %%mm1, 4(%%edi); \
+ psrlq $32, %%mm1; \
+ movd 28(%%esi), %%mm3; \
+ pmuludq %%mm0, %%mm3; \
+ paddq %%mm5, %%mm1; \
+ movd 16(%%edi), %%mm5; \
+ paddq %%mm5, %%mm2; \
+ movd %%mm1, 8(%%edi); \
+ psrlq $32, %%mm1; \
+ paddq %%mm7, %%mm1; \
+ movd 20(%%edi), %%mm5; \
+ paddq %%mm5, %%mm4; \
+ movd %%mm1, 12(%%edi); \
+ psrlq $32, %%mm1; \
+ paddq %%mm2, %%mm1; \
+ movd 24(%%edi), %%mm5; \
+ paddq %%mm5, %%mm6; \
+ movd %%mm1, 16(%%edi); \
+ psrlq $32, %%mm1; \
+ paddq %%mm4, %%mm1; \
+ movd 28(%%edi), %%mm5; \
+ paddq %%mm5, %%mm3; \
+ movd %%mm1, 20(%%edi); \
+ psrlq $32, %%mm1; \
+ paddq %%mm6, %%mm1; \
+ movd %%mm1, 24(%%edi); \
+ psrlq $32, %%mm1; \
+ paddq %%mm3, %%mm1; \
+ movd %%mm1, 28(%%edi); \
+ addl $32, %%edi; \
+ addl $32, %%esi; \
+ psrlq $32, %%mm1; \
+ movd %%mm1, %%ecx; \
+ "
+
+#define MULADDC_STOP \
+ " \
+ emms; \
+ movl %4, %%ebx; \
+ movl %%ecx, %1; \
+ movl %%edi, %2; \
+ movl %%esi, %3; \
+ " \
+ : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
+ : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
+ : "eax", "ecx", "edx", "esi", "edi" \
+ );
+
+#else
+
+#define MULADDC_STOP \
+ " \
+ movl %4, %%ebx; \
+ movl %%ecx, %1; \
+ movl %%edi, %2; \
+ movl %%esi, %3; \
+ " \
+ : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
+ : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
+ : "eax", "ecx", "edx", "esi", "edi" \
+ );
+#endif /* SSE2 */
+#endif /* i386 */
+
+#if defined(__amd64__) || defined (__x86_64__)
+
+#define MULADDC_INIT \
+ asm( "movq %0, %%rsi " :: "m" (s)); \
+ asm( "movq %0, %%rdi " :: "m" (d)); \
+ asm( "movq %0, %%rcx " :: "m" (c)); \
+ asm( "movq %0, %%rbx " :: "m" (b)); \
+ asm( "xorq %r8, %r8 " );
+
+#define MULADDC_CORE \
+ asm( "movq (%rsi),%rax " ); \
+ asm( "mulq %rbx " ); \
+ asm( "addq $8, %rsi " ); \
+ asm( "addq %rcx, %rax " ); \
+ asm( "movq %r8, %rcx " ); \
+ asm( "adcq $0, %rdx " ); \
+ asm( "nop " ); \
+ asm( "addq %rax, (%rdi) " ); \
+ asm( "adcq %rdx, %rcx " ); \
+ asm( "addq $8, %rdi " );
+
+#define MULADDC_STOP \
+ asm( "movq %%rcx, %0 " : "=m" (c)); \
+ asm( "movq %%rdi, %0 " : "=m" (d)); \
+ asm( "movq %%rsi, %0 " : "=m" (s) :: \
+ "rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8" );
+
+#endif /* AMD64 */
+
+#if defined(__mc68020__) || defined(__mcpu32__)
+
+#define MULADDC_INIT \
+ asm( "movl %0, %%a2 " :: "m" (s)); \
+ asm( "movl %0, %%a3 " :: "m" (d)); \
+ asm( "movl %0, %%d3 " :: "m" (c)); \
+ asm( "movl %0, %%d2 " :: "m" (b)); \
+ asm( "moveq #0, %d0 " );
+
+#define MULADDC_CORE \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d4:%d1 " ); \
+ asm( "addl %d3, %d1 " ); \
+ asm( "addxl %d0, %d4 " ); \
+ asm( "moveq #0, %d3 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "addxl %d4, %d3 " );
+
+#define MULADDC_STOP \
+ asm( "movl %%d3, %0 " : "=m" (c)); \
+ asm( "movl %%a3, %0 " : "=m" (d)); \
+ asm( "movl %%a2, %0 " : "=m" (s) :: \
+ "d0", "d1", "d2", "d3", "d4", "a2", "a3" );
+
+#define MULADDC_HUIT \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d4:%d1 " ); \
+ asm( "addxl %d3, %d1 " ); \
+ asm( "addxl %d0, %d4 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d3:%d1 " ); \
+ asm( "addxl %d4, %d1 " ); \
+ asm( "addxl %d0, %d3 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d4:%d1 " ); \
+ asm( "addxl %d3, %d1 " ); \
+ asm( "addxl %d0, %d4 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d3:%d1 " ); \
+ asm( "addxl %d4, %d1 " ); \
+ asm( "addxl %d0, %d3 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d4:%d1 " ); \
+ asm( "addxl %d3, %d1 " ); \
+ asm( "addxl %d0, %d4 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d3:%d1 " ); \
+ asm( "addxl %d4, %d1 " ); \
+ asm( "addxl %d0, %d3 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d4:%d1 " ); \
+ asm( "addxl %d3, %d1 " ); \
+ asm( "addxl %d0, %d4 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d3:%d1 " ); \
+ asm( "addxl %d4, %d1 " ); \
+ asm( "addxl %d0, %d3 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "addxl %d0, %d3 " );
+
+#endif /* MC68000 */
+
+#if defined(__powerpc__) || defined(__ppc__)
+#if defined(__powerpc64__) || defined(__ppc64__)
+
+#if defined(__MACH__) && defined(__APPLE__)
+
+#define MULADDC_INIT \
+ asm( "ld r3, %0 " :: "m" (s)); \
+ asm( "ld r4, %0 " :: "m" (d)); \
+ asm( "ld r5, %0 " :: "m" (c)); \
+ asm( "ld r6, %0 " :: "m" (b)); \
+ asm( "addi r3, r3, -8 " ); \
+ asm( "addi r4, r4, -8 " ); \
+ asm( "addic r5, r5, 0 " );
+
+#define MULADDC_CORE \
+ asm( "ldu r7, 8(r3) " ); \
+ asm( "mulld r8, r7, r6 " ); \
+ asm( "mulhdu r9, r7, r6 " ); \
+ asm( "adde r8, r8, r5 " ); \
+ asm( "ld r7, 8(r4) " ); \
+ asm( "addze r5, r9 " ); \
+ asm( "addc r8, r8, r7 " ); \
+ asm( "stdu r8, 8(r4) " );
+
+#define MULADDC_STOP \
+ asm( "addze r5, r5 " ); \
+ asm( "addi r4, r4, 8 " ); \
+ asm( "addi r3, r3, 8 " ); \
+ asm( "std r5, %0 " : "=m" (c)); \
+ asm( "std r4, %0 " : "=m" (d)); \
+ asm( "std r3, %0 " : "=m" (s) :: \
+ "r3", "r4", "r5", "r6", "r7", "r8", "r9" );
+
+#else
+
+#define MULADDC_INIT \
+ asm( "ld %%r3, %0 " :: "m" (s)); \
+ asm( "ld %%r4, %0 " :: "m" (d)); \
+ asm( "ld %%r5, %0 " :: "m" (c)); \
+ asm( "ld %%r6, %0 " :: "m" (b)); \
+ asm( "addi %r3, %r3, -8 " ); \
+ asm( "addi %r4, %r4, -8 " ); \
+ asm( "addic %r5, %r5, 0 " );
+
+#define MULADDC_CORE \
+ asm( "ldu %r7, 8(%r3) " ); \
+ asm( "mulld %r8, %r7, %r6 " ); \
+ asm( "mulhdu %r9, %r7, %r6 " ); \
+ asm( "adde %r8, %r8, %r5 " ); \
+ asm( "ld %r7, 8(%r4) " ); \
+ asm( "addze %r5, %r9 " ); \
+ asm( "addc %r8, %r8, %r7 " ); \
+ asm( "stdu %r8, 8(%r4) " );
+
+#define MULADDC_STOP \
+ asm( "addze %r5, %r5 " ); \
+ asm( "addi %r4, %r4, 8 " ); \
+ asm( "addi %r3, %r3, 8 " ); \
+ asm( "std %%r5, %0 " : "=m" (c)); \
+ asm( "std %%r4, %0 " : "=m" (d)); \
+ asm( "std %%r3, %0 " : "=m" (s) :: \
+ "r3", "r4", "r5", "r6", "r7", "r8", "r9" );
+
+#endif
+
+#else /* PPC32 */
+
+#if defined(__MACH__) && defined(__APPLE__)
+
+#define MULADDC_INIT \
+ asm( "lwz r3, %0 " :: "m" (s)); \
+ asm( "lwz r4, %0 " :: "m" (d)); \
+ asm( "lwz r5, %0 " :: "m" (c)); \
+ asm( "lwz r6, %0 " :: "m" (b)); \
+ asm( "addi r3, r3, -4 " ); \
+ asm( "addi r4, r4, -4 " ); \
+ asm( "addic r5, r5, 0 " );
+
+#define MULADDC_CORE \
+ asm( "lwzu r7, 4(r3) " ); \
+ asm( "mullw r8, r7, r6 " ); \
+ asm( "mulhwu r9, r7, r6 " ); \
+ asm( "adde r8, r8, r5 " ); \
+ asm( "lwz r7, 4(r4) " ); \
+ asm( "addze r5, r9 " ); \
+ asm( "addc r8, r8, r7 " ); \
+ asm( "stwu r8, 4(r4) " );
+
+#define MULADDC_STOP \
+ asm( "addze r5, r5 " ); \
+ asm( "addi r4, r4, 4 " ); \
+ asm( "addi r3, r3, 4 " ); \
+ asm( "stw r5, %0 " : "=m" (c)); \
+ asm( "stw r4, %0 " : "=m" (d)); \
+ asm( "stw r3, %0 " : "=m" (s) :: \
+ "r3", "r4", "r5", "r6", "r7", "r8", "r9" );
+
+#else
+
+#define MULADDC_INIT \
+ asm( "lwz %%r3, %0 " :: "m" (s)); \
+ asm( "lwz %%r4, %0 " :: "m" (d)); \
+ asm( "lwz %%r5, %0 " :: "m" (c)); \
+ asm( "lwz %%r6, %0 " :: "m" (b)); \
+ asm( "addi %r3, %r3, -4 " ); \
+ asm( "addi %r4, %r4, -4 " ); \
+ asm( "addic %r5, %r5, 0 " );
+
+#define MULADDC_CORE \
+ asm( "lwzu %r7, 4(%r3) " ); \
+ asm( "mullw %r8, %r7, %r6 " ); \
+ asm( "mulhwu %r9, %r7, %r6 " ); \
+ asm( "adde %r8, %r8, %r5 " ); \
+ asm( "lwz %r7, 4(%r4) " ); \
+ asm( "addze %r5, %r9 " ); \
+ asm( "addc %r8, %r8, %r7 " ); \
+ asm( "stwu %r8, 4(%r4) " );
+
+#define MULADDC_STOP \
+ asm( "addze %r5, %r5 " ); \
+ asm( "addi %r4, %r4, 4 " ); \
+ asm( "addi %r3, %r3, 4 " ); \
+ asm( "stw %%r5, %0 " : "=m" (c)); \
+ asm( "stw %%r4, %0 " : "=m" (d)); \
+ asm( "stw %%r3, %0 " : "=m" (s) :: \
+ "r3", "r4", "r5", "r6", "r7", "r8", "r9" );
+
+#endif
+
+#endif /* PPC32 */
+#endif /* PPC64 */
+
+#if defined(__sparc__)
+
+#define MULADDC_INIT \
+ asm( "ld %0, %%o0 " :: "m" (s)); \
+ asm( "ld %0, %%o1 " :: "m" (d)); \
+ asm( "ld %0, %%o2 " :: "m" (c)); \
+ asm( "ld %0, %%o3 " :: "m" (b));
+
+#define MULADDC_CORE \
+ asm( "ld [%o0], %o4 " ); \
+ asm( "inc 4, %o0 " ); \
+ asm( "ld [%o1], %o5 " ); \
+ asm( "umul %o3, %o4, %o4 " ); \
+ asm( "addcc %o4, %o2, %o4 " ); \
+ asm( "rd %y, %g1 " ); \
+ asm( "addx %g1, 0, %g1 " ); \
+ asm( "addcc %o4, %o5, %o4 " ); \
+ asm( "st %o4, [%o1] " ); \
+ asm( "addx %g1, 0, %o2 " ); \
+ asm( "inc 4, %o1 " );
+
+#define MULADDC_STOP \
+ asm( "st %%o2, %0 " : "=m" (c)); \
+ asm( "st %%o1, %0 " : "=m" (d)); \
+ asm( "st %%o0, %0 " : "=m" (s) :: \
+ "g1", "o0", "o1", "o2", "o3", "o4", "o5" );
+
+#endif /* SPARCv8 */
+
+#if defined(__microblaze__) || defined(microblaze)
+
+#define MULADDC_INIT \
+ asm( "lwi r3, %0 " :: "m" (s)); \
+ asm( "lwi r4, %0 " :: "m" (d)); \
+ asm( "lwi r5, %0 " :: "m" (c)); \
+ asm( "lwi r6, %0 " :: "m" (b)); \
+ asm( "andi r7, r6, 0xffff" ); \
+ asm( "bsrli r6, r6, 16 " );
+
+#define MULADDC_CORE \
+ asm( "lhui r8, r3, 0 " ); \
+ asm( "addi r3, r3, 2 " ); \
+ asm( "lhui r9, r3, 0 " ); \
+ asm( "addi r3, r3, 2 " ); \
+ asm( "mul r10, r9, r6 " ); \
+ asm( "mul r11, r8, r7 " ); \
+ asm( "mul r12, r9, r7 " ); \
+ asm( "mul r13, r8, r6 " ); \
+ asm( "bsrli r8, r10, 16 " ); \
+ asm( "bsrli r9, r11, 16 " ); \
+ asm( "add r13, r13, r8 " ); \
+ asm( "add r13, r13, r9 " ); \
+ asm( "bslli r10, r10, 16 " ); \
+ asm( "bslli r11, r11, 16 " ); \
+ asm( "add r12, r12, r10 " ); \
+ asm( "addc r13, r13, r0 " ); \
+ asm( "add r12, r12, r11 " ); \
+ asm( "addc r13, r13, r0 " ); \
+ asm( "lwi r10, r4, 0 " ); \
+ asm( "add r12, r12, r10 " ); \
+ asm( "addc r13, r13, r0 " ); \
+ asm( "add r12, r12, r5 " ); \
+ asm( "addc r5, r13, r0 " ); \
+ asm( "swi r12, r4, 0 " ); \
+ asm( "addi r4, r4, 4 " );
+
+#define MULADDC_STOP \
+ asm( "swi r5, %0 " : "=m" (c)); \
+ asm( "swi r4, %0 " : "=m" (d)); \
+ asm( "swi r3, %0 " : "=m" (s) :: \
+ "r3", "r4" , "r5" , "r6" , "r7" , "r8" , \
+ "r9", "r10", "r11", "r12", "r13" );
+
+#endif /* MicroBlaze */
+
+#if defined(__tricore__)
+
+#define MULADDC_INIT \
+ asm( "ld.a %%a2, %0 " :: "m" (s)); \
+ asm( "ld.a %%a3, %0 " :: "m" (d)); \
+ asm( "ld.w %%d4, %0 " :: "m" (c)); \
+ asm( "ld.w %%d1, %0 " :: "m" (b)); \
+ asm( "xor %d5, %d5 " );
+
+#define MULADDC_CORE \
+ asm( "ld.w %d0, [%a2+] " ); \
+ asm( "madd.u %e2, %e4, %d0, %d1 " ); \
+ asm( "ld.w %d0, [%a3] " ); \
+ asm( "addx %d2, %d2, %d0 " ); \
+ asm( "addc %d3, %d3, 0 " ); \
+ asm( "mov %d4, %d3 " ); \
+ asm( "st.w [%a3+], %d2 " );
+
+#define MULADDC_STOP \
+ asm( "st.w %0, %%d4 " : "=m" (c)); \
+ asm( "st.a %0, %%a3 " : "=m" (d)); \
+ asm( "st.a %0, %%a2 " : "=m" (s) :: \
+ "d0", "d1", "e2", "d4", "a2", "a3" );
+
+#endif /* TriCore */
+
+#if defined(__arm__)
+
+#define MULADDC_INIT \
+ asm( "ldr r0, %0 " :: "m" (s)); \
+ asm( "ldr r1, %0 " :: "m" (d)); \
+ asm( "ldr r2, %0 " :: "m" (c)); \
+ asm( "ldr r3, %0 " :: "m" (b));
+
+#define MULADDC_CORE \
+ asm( "ldr r4, [r0], #4 " ); \
+ asm( "mov r5, #0 " ); \
+ asm( "ldr r6, [r1] " ); \
+ asm( "umlal r2, r5, r3, r4 " ); \
+ asm( "adds r7, r6, r2 " ); \
+ asm( "adc r2, r5, #0 " ); \
+ asm( "str r7, [r1], #4 " );
+
+#define MULADDC_STOP \
+ asm( "str r2, %0 " : "=m" (c)); \
+ asm( "str r1, %0 " : "=m" (d)); \
+ asm( "str r0, %0 " : "=m" (s) :: \
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" );
+
+#endif /* ARMv3 */
+
+#if defined(__alpha__)
+
+#define MULADDC_INIT \
+ asm( "ldq $1, %0 " :: "m" (s)); \
+ asm( "ldq $2, %0 " :: "m" (d)); \
+ asm( "ldq $3, %0 " :: "m" (c)); \
+ asm( "ldq $4, %0 " :: "m" (b));
+
+#define MULADDC_CORE \
+ asm( "ldq $6, 0($1) " ); \
+ asm( "addq $1, 8, $1 " ); \
+ asm( "mulq $6, $4, $7 " ); \
+ asm( "umulh $6, $4, $6 " ); \
+ asm( "addq $7, $3, $7 " ); \
+ asm( "cmpult $7, $3, $3 " ); \
+ asm( "ldq $5, 0($2) " ); \
+ asm( "addq $7, $5, $7 " ); \
+ asm( "cmpult $7, $5, $5 " ); \
+ asm( "stq $7, 0($2) " ); \
+ asm( "addq $2, 8, $2 " ); \
+ asm( "addq $6, $3, $3 " ); \
+ asm( "addq $5, $3, $3 " );
+
+#define MULADDC_STOP \
+ asm( "stq $3, %0 " : "=m" (c)); \
+ asm( "stq $2, %0 " : "=m" (d)); \
+ asm( "stq $1, %0 " : "=m" (s) :: \
+ "$1", "$2", "$3", "$4", "$5", "$6", "$7" );
+
+#endif /* Alpha */
+
+#if defined(__mips__)
+
+#define MULADDC_INIT \
+ asm( "lw $10, %0 " :: "m" (s)); \
+ asm( "lw $11, %0 " :: "m" (d)); \
+ asm( "lw $12, %0 " :: "m" (c)); \
+ asm( "lw $13, %0 " :: "m" (b));
+
+#define MULADDC_CORE \
+ asm( "lw $14, 0($10) " ); \
+ asm( "multu $13, $14 " ); \
+ asm( "addi $10, $10, 4 " ); \
+ asm( "mflo $14 " ); \
+ asm( "mfhi $9 " ); \
+ asm( "addu $14, $12, $14 " ); \
+ asm( "lw $15, 0($11) " ); \
+ asm( "sltu $12, $14, $12 " ); \
+ asm( "addu $15, $14, $15 " ); \
+ asm( "sltu $14, $15, $14 " ); \
+ asm( "addu $12, $12, $9 " ); \
+ asm( "sw $15, 0($11) " ); \
+ asm( "addu $12, $12, $14 " ); \
+ asm( "addi $11, $11, 4 " );
+
+#define MULADDC_STOP \
+ asm( "sw $12, %0 " : "=m" (c)); \
+ asm( "sw $11, %0 " : "=m" (d)); \
+ asm( "sw $10, %0 " : "=m" (s) :: \
+ "$9", "$10", "$11", "$12", "$13", "$14", "$15" );
+
+#endif /* MIPS */
+#endif /* GNUC */
+
+#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
+
+#define MULADDC_INIT \
+ __asm mov esi, s \
+ __asm mov edi, d \
+ __asm mov ecx, c \
+ __asm mov ebx, b
+
+#define MULADDC_CORE \
+ __asm lodsd \
+ __asm mul ebx \
+ __asm add eax, ecx \
+ __asm adc edx, 0 \
+ __asm add eax, [edi] \
+ __asm adc edx, 0 \
+ __asm mov ecx, edx \
+ __asm stosd
+
+#if defined(POLARSSL_HAVE_SSE2)
+
+#define EMIT __asm _emit
+
+#define MULADDC_HUIT \
+ EMIT 0x0F EMIT 0x6E EMIT 0xC9 \
+ EMIT 0x0F EMIT 0x6E EMIT 0xC3 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x1F \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
+ EMIT 0x0F EMIT 0x6E EMIT 0x16 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
+ EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xDC \
+ EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xEE \
+ EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xFC \
+ EMIT 0x0F EMIT 0x7E EMIT 0x0F \
+ EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
+ EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCD \
+ EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCF \
+ EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
+ EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCC \
+ EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xDD \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCE \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \
+ EMIT 0x83 EMIT 0xC7 EMIT 0x20 \
+ EMIT 0x83 EMIT 0xC6 EMIT 0x20 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0x7E EMIT 0xC9
+
+#define MULADDC_STOP \
+ EMIT 0x0F EMIT 0x77 \
+ __asm mov c, ecx \
+ __asm mov d, edi \
+ __asm mov s, esi \
+
+#else
+
+#define MULADDC_STOP \
+ __asm mov c, ecx \
+ __asm mov d, edi \
+ __asm mov s, esi \
+
+#endif /* SSE2 */
+#endif /* MSVC */
+
+#endif /* POLARSSL_HAVE_ASM */
+
+#if !defined(MULADDC_CORE)
+#if defined(POLARSSL_HAVE_LONGLONG)
+
+#define MULADDC_INIT \
+{ \
+ t_dbl r; \
+ t_int r0, r1;
+
+#define MULADDC_CORE \
+ r = *(s++) * (t_dbl) b; \
+ r0 = r; \
+ r1 = r >> biL; \
+ r0 += c; r1 += (r0 < c); \
+ r0 += *d; r1 += (r0 < *d); \
+ c = r1; *(d++) = r0;
+
+#define MULADDC_STOP \
+}
+
+#else
+#define MULADDC_INIT \
+{ \
+ t_int s0, s1, b0, b1; \
+ t_int r0, r1, rx, ry; \
+ b0 = ( b << biH ) >> biH; \
+ b1 = ( b >> biH );
+
+#define MULADDC_CORE \
+ s0 = ( *s << biH ) >> biH; \
+ s1 = ( *s >> biH ); s++; \
+ rx = s0 * b1; r0 = s0 * b0; \
+ ry = s1 * b0; r1 = s1 * b1; \
+ r1 += ( rx >> biH ); \
+ r1 += ( ry >> biH ); \
+ rx <<= biH; ry <<= biH; \
+ r0 += rx; r1 += (r0 < rx); \
+ r0 += ry; r1 += (r0 < ry); \
+ r0 += c; r1 += (r0 < c); \
+ r0 += *d; r1 += (r0 < *d); \
+ c = r1; *(d++) = r0;
+
+#define MULADDC_STOP \
+}
+
+#endif /* C (generic) */
+#endif /* C (longlong) */
+
+#endif /* bn_mul.h */
--- /dev/null
+#define POLARSSL_BASE64_C
+#define POLARSSL_BIGNUM_C
+#define POLARSSL_SHA1_C
+#define POLARSSL_SHA2_C
+#define POLARSSL_RSA_C
--- /dev/null
+/* *************** begin copy from x509.h ************************/
+/**
+ * \file x509.h
+ *
+ * Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef POLARSSL_PART_X509_H
+#define POLARSSL_PART_X509_H
+
+/*
+ * ASN1 Error codes
+ *
+ * These error codes will be OR'ed to X509 error codes for
+ * higher error granularity.
+ */
+#define POLARSSL_ERR_ASN1_OUT_OF_DATA 0x0014
+#define POLARSSL_ERR_ASN1_UNEXPECTED_TAG 0x0016
+#define POLARSSL_ERR_ASN1_INVALID_LENGTH 0x0018
+#define POLARSSL_ERR_ASN1_LENGTH_MISMATCH 0x001A
+#define POLARSSL_ERR_ASN1_INVALID_DATA 0x001C
+
+/*
+ * X509 Error codes
+ */
+#define POLARSSL_ERR_X509_FEATURE_UNAVAILABLE -0x0020
+#define POLARSSL_ERR_X509_CERT_INVALID_PEM -0x0040
+#define POLARSSL_ERR_X509_CERT_INVALID_FORMAT -0x0060
+#define POLARSSL_ERR_X509_CERT_INVALID_VERSION -0x0080
+#define POLARSSL_ERR_X509_CERT_INVALID_SERIAL -0x00A0
+#define POLARSSL_ERR_X509_CERT_INVALID_ALG -0x00C0
+#define POLARSSL_ERR_X509_CERT_INVALID_NAME -0x00E0
+#define POLARSSL_ERR_X509_CERT_INVALID_DATE -0x0100
+#define POLARSSL_ERR_X509_CERT_INVALID_PUBKEY -0x0120
+#define POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE -0x0140
+#define POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS -0x0160
+#define POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION -0x0180
+#define POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG -0x01A0
+#define POLARSSL_ERR_X509_CERT_UNKNOWN_PK_ALG -0x01C0
+#define POLARSSL_ERR_X509_CERT_SIG_MISMATCH -0x01E0
+#define POLARSSL_ERR_X509_CERT_VERIFY_FAILED -0x0200
+#define POLARSSL_ERR_X509_KEY_INVALID_PEM -0x0220
+#define POLARSSL_ERR_X509_KEY_INVALID_VERSION -0x0240
+#define POLARSSL_ERR_X509_KEY_INVALID_FORMAT -0x0260
+#define POLARSSL_ERR_X509_KEY_INVALID_ENC_IV -0x0280
+#define POLARSSL_ERR_X509_KEY_UNKNOWN_ENC_ALG -0x02A0
+#define POLARSSL_ERR_X509_KEY_PASSWORD_REQUIRED -0x02C0
+#define POLARSSL_ERR_X509_KEY_PASSWORD_MISMATCH -0x02E0
+#define POLARSSL_ERR_X509_POINT_ERROR -0x0300
+#define POLARSSL_ERR_X509_VALUE_TO_LENGTH -0x0320
+
+/*
+ * DER constants
+ */
+#define ASN1_BOOLEAN 0x01
+#define ASN1_INTEGER 0x02
+#define ASN1_BIT_STRING 0x03
+#define ASN1_OCTET_STRING 0x04
+#define ASN1_NULL 0x05
+#define ASN1_OID 0x06
+#define ASN1_UTF8_STRING 0x0C
+#define ASN1_SEQUENCE 0x10
+#define ASN1_SET 0x11
+#define ASN1_PRINTABLE_STRING 0x13
+#define ASN1_T61_STRING 0x14
+#define ASN1_IA5_STRING 0x16
+#define ASN1_UTC_TIME 0x17
+#define ASN1_GENERALIZED_TIME 0x18
+#define ASN1_UNIVERSAL_STRING 0x1C
+#define ASN1_BMP_STRING 0x1E
+#define ASN1_PRIMITIVE 0x00
+#define ASN1_CONSTRUCTED 0x20
+#define ASN1_CONTEXT_SPECIFIC 0x80
+/* *************** end copy from x509.h ************************/
+
+#endif /* part-x509.h */
--- /dev/null
+/* Functions defined in x509parse.c, which are not exported (static there) */
+/*
+ * X.509 certificate and private key decoding
+ *
+ * Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+/*
+ * The ITU-T X.509 standard defines a certificat format for PKI.
+ *
+ * http://www.ietf.org/rfc/rfc2459.txt
+ * http://www.ietf.org/rfc/rfc3279.txt
+ *
+ * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
+ *
+ * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
+ * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
+ */
+
+
+
+int asn1_get_mpi( unsigned char **p,
+ const unsigned char *end,
+ mpi *X );
+
+int asn1_get_tag( unsigned char **p,
+ const unsigned char *end,
+ int *len, int tag );
+
+int asn1_get_int( unsigned char **p,
+ const unsigned char *end,
+ int *val );
--- /dev/null
+/**
+ * \file rsa.h
+ *
+ * Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef POLARSSL_RSA_H
+#define POLARSSL_RSA_H
+
+#include "polarssl/bignum.h"
+
+/*
+ * RSA Error codes
+ */
+#define POLARSSL_ERR_RSA_BAD_INPUT_DATA -0x0400
+#define POLARSSL_ERR_RSA_INVALID_PADDING -0x0410
+#define POLARSSL_ERR_RSA_KEY_GEN_FAILED -0x0420
+#define POLARSSL_ERR_RSA_KEY_CHECK_FAILED -0x0430
+#define POLARSSL_ERR_RSA_PUBLIC_FAILED -0x0440
+#define POLARSSL_ERR_RSA_PRIVATE_FAILED -0x0450
+#define POLARSSL_ERR_RSA_VERIFY_FAILED -0x0460
+#define POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE -0x0470
+#define POLARSSL_ERR_RSA_RNG_FAILED -0x0480
+
+/*
+ * PKCS#1 constants
+ */
+#define SIG_RSA_RAW 0
+#define SIG_RSA_MD2 2
+#define SIG_RSA_MD4 3
+#define SIG_RSA_MD5 4
+#define SIG_RSA_SHA1 5
+#define SIG_RSA_SHA224 14
+#define SIG_RSA_SHA256 11
+#define SIG_RSA_SHA384 12
+#define SIG_RSA_SHA512 13
+
+#define RSA_PUBLIC 0
+#define RSA_PRIVATE 1
+
+#define RSA_PKCS_V15 0
+#define RSA_PKCS_V21 1
+
+#define RSA_SIGN 1
+#define RSA_CRYPT 2
+
+#define ASN1_STR_CONSTRUCTED_SEQUENCE "\x30"
+#define ASN1_STR_NULL "\x05"
+#define ASN1_STR_OID "\x06"
+#define ASN1_STR_OCTET_STRING "\x04"
+
+#define OID_DIGEST_ALG_MDX "\x2A\x86\x48\x86\xF7\x0D\x02\x00"
+#define OID_HASH_ALG_SHA1 "\x2b\x0e\x03\x02\x1a"
+#define OID_HASH_ALG_SHA2X "\x60\x86\x48\x01\x65\x03\x04\x02\x00"
+
+#define OID_ISO_MEMBER_BODIES "\x2a"
+#define OID_ISO_IDENTIFIED_ORG "\x2b"
+
+/*
+ * ISO Member bodies OID parts
+ */
+#define OID_COUNTRY_US "\x86\x48"
+#define OID_RSA_DATA_SECURITY "\x86\xf7\x0d"
+
+/*
+ * ISO Identified organization OID parts
+ */
+#define OID_OIW_SECSIG_SHA1 "\x0e\x03\x02\x1a"
+
+/*
+ * DigestInfo ::= SEQUENCE {
+ * digestAlgorithm DigestAlgorithmIdentifier,
+ * digest Digest }
+ *
+ * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
+ *
+ * Digest ::= OCTET STRING
+ */
+#define ASN1_HASH_MDX \
+( \
+ ASN1_STR_CONSTRUCTED_SEQUENCE "\x20" \
+ ASN1_STR_CONSTRUCTED_SEQUENCE "\x0C" \
+ ASN1_STR_OID "\x08" \
+ OID_DIGEST_ALG_MDX \
+ ASN1_STR_NULL "\x00" \
+ ASN1_STR_OCTET_STRING "\x10" \
+)
+
+#define ASN1_HASH_SHA1 \
+ ASN1_STR_CONSTRUCTED_SEQUENCE "\x21" \
+ ASN1_STR_CONSTRUCTED_SEQUENCE "\x09" \
+ ASN1_STR_OID "\x05" \
+ OID_HASH_ALG_SHA1 \
+ ASN1_STR_NULL "\x00" \
+ ASN1_STR_OCTET_STRING "\x14"
+
+#define ASN1_HASH_SHA2X \
+ ASN1_STR_CONSTRUCTED_SEQUENCE "\x11" \
+ ASN1_STR_CONSTRUCTED_SEQUENCE "\x0d" \
+ ASN1_STR_OID "\x09" \
+ OID_HASH_ALG_SHA2X \
+ ASN1_STR_NULL "\x00" \
+ ASN1_STR_OCTET_STRING "\x00"
+
+/**
+ * \brief RSA context structure
+ */
+typedef struct
+{
+ int ver; /*!< always 0 */
+ int len; /*!< size(N) in chars */
+
+ mpi N; /*!< public modulus */
+ mpi E; /*!< public exponent */
+
+ mpi D; /*!< private exponent */
+ mpi P; /*!< 1st prime factor */
+ mpi Q; /*!< 2nd prime factor */
+ mpi DP; /*!< D % (P - 1) */
+ mpi DQ; /*!< D % (Q - 1) */
+ mpi QP; /*!< 1 / (Q % P) */
+
+ mpi RN; /*!< cached R^2 mod N */
+ mpi RP; /*!< cached R^2 mod P */
+ mpi RQ; /*!< cached R^2 mod Q */
+
+ int padding; /*!< 1.5 or OAEP/PSS */
+ int hash_id; /*!< hash identifier */
+}
+rsa_context;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Initialize an RSA context
+ *
+ * \param ctx RSA context to be initialized
+ * \param padding RSA_PKCS_V15 or RSA_PKCS_V21
+ * \param hash_id RSA_PKCS_V21 hash identifier
+ *
+ * \note The hash_id parameter is actually ignored
+ * when using RSA_PKCS_V15 padding.
+ *
+ * \note Currently, RSA_PKCS_V21 padding
+ * is not supported.
+ */
+void rsa_init( rsa_context *ctx,
+ int padding,
+ int hash_id);
+
+/**
+ * \brief Generate an RSA keypair
+ *
+ * \param ctx RSA context that will hold the key
+ * \param f_rng RNG function
+ * \param p_rng RNG parameter
+ * \param nbits size of the public key in bits
+ * \param exponent public exponent (e.g., 65537)
+ *
+ * \note rsa_init() must be called beforehand to setup
+ * the RSA context.
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ */
+int rsa_gen_key( rsa_context *ctx,
+ int (*f_rng)(void *),
+ void *p_rng,
+ int nbits, int exponent );
+
+/**
+ * \brief Check a public RSA key
+ *
+ * \param ctx RSA context to be checked
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ */
+int rsa_check_pubkey( const rsa_context *ctx );
+
+/**
+ * \brief Check a private RSA key
+ *
+ * \param ctx RSA context to be checked
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ */
+int rsa_check_privkey( const rsa_context *ctx );
+
+/**
+ * \brief Do an RSA public key operation
+ *
+ * \param ctx RSA context
+ * \param input input buffer
+ * \param output output buffer
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note This function does NOT take care of message
+ * padding. Also, be sure to set input[0] = 0 or assure that
+ * input is smaller than N.
+ *
+ * \note The input and output buffers must be large
+ * enough (eg. 128 bytes if RSA-1024 is used).
+ */
+int rsa_public( rsa_context *ctx,
+ const unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief Do an RSA private key operation
+ *
+ * \param ctx RSA context
+ * \param input input buffer
+ * \param output output buffer
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note The input and output buffers must be large
+ * enough (eg. 128 bytes if RSA-1024 is used).
+ */
+int rsa_private( rsa_context *ctx,
+ const unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief Add the message padding, then do an RSA operation
+ *
+ * \param ctx RSA context
+ * \param f_rng RNG function
+ * \param p_rng RNG parameter
+ * \param mode RSA_PUBLIC or RSA_PRIVATE
+ * \param ilen contains the plaintext length
+ * \param input buffer holding the data to be encrypted
+ * \param output buffer that will hold the ciphertext
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note The output buffer must be as large as the size
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ */
+int rsa_pkcs1_encrypt( rsa_context *ctx,
+ int (*f_rng)(void *),
+ void *p_rng,
+ int mode, int ilen,
+ const unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief Do an RSA operation, then remove the message padding
+ *
+ * \param ctx RSA context
+ * \param mode RSA_PUBLIC or RSA_PRIVATE
+ * \param input buffer holding the encrypted data
+ * \param output buffer that will hold the plaintext
+ * \param olen will contain the plaintext length
+ * \param output_max_len maximum length of the output buffer
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note The output buffer must be as large as the size
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
+ * an error is thrown.
+ */
+int rsa_pkcs1_decrypt( rsa_context *ctx,
+ int mode, int *olen,
+ const unsigned char *input,
+ unsigned char *output,
+ int output_max_len );
+
+/**
+ * \brief Do a private RSA to sign a message digest
+ *
+ * \param ctx RSA context
+ * \param mode RSA_PUBLIC or RSA_PRIVATE
+ * \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
+ * \param hashlen message digest length (for SIG_RSA_RAW only)
+ * \param hash buffer holding the message digest
+ * \param sig buffer that will hold the ciphertext
+ *
+ * \return 0 if the signing operation was successful,
+ * or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note The "sig" buffer must be as large as the size
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ */
+int rsa_pkcs1_sign( rsa_context *ctx,
+ int mode,
+ int hash_id,
+ int hashlen,
+ const unsigned char *hash,
+ unsigned char *sig );
+
+/**
+ * \brief Do a public RSA and check the message digest
+ *
+ * \param ctx points to an RSA public key
+ * \param mode RSA_PUBLIC or RSA_PRIVATE
+ * \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
+ * \param hashlen message digest length (for SIG_RSA_RAW only)
+ * \param hash buffer holding the message digest
+ * \param sig buffer holding the ciphertext
+ *
+ * \return 0 if the verify operation was successful,
+ * or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note The "sig" buffer must be as large as the size
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ */
+int rsa_pkcs1_verify( rsa_context *ctx,
+ int mode,
+ int hash_id,
+ int hashlen,
+ const unsigned char *hash,
+ unsigned char *sig );
+
+/**
+ * \brief Free the components of an RSA key
+ *
+ * \param ctx RSA Context to free
+ */
+void rsa_free( rsa_context *ctx );
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ */
+int rsa_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* rsa.h */
--- /dev/null
+/**
+ * \file sha1.h
+ *
+ * Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef POLARSSL_SHA1_H
+#define POLARSSL_SHA1_H
+
+/**
+ * \brief SHA-1 context structure
+ */
+#ifndef HAVE_SHA1_CONTEXT
+#define HAVE_SHA1_CONTEXT
+typedef struct sha1_context sha1_context;
+#endif
+struct sha1_context
+{
+ unsigned long total[2]; /*!< number of bytes processed */
+ unsigned long state[5]; /*!< intermediate digest state */
+ unsigned char buffer[64]; /*!< data block being processed */
+
+ unsigned char ipad[64]; /*!< HMAC: inner padding */
+ unsigned char opad[64]; /*!< HMAC: outer padding */
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief SHA-1 context setup
+ *
+ * \param ctx context to be initialized
+ */
+void sha1_starts( sha1_context *ctx );
+
+/**
+ * \brief SHA-1 process buffer
+ *
+ * \param ctx SHA-1 context
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ */
+void sha1_update( sha1_context *ctx, const unsigned char *input, int ilen );
+
+/**
+ * \brief SHA-1 final digest
+ *
+ * \param ctx SHA-1 context
+ * \param output SHA-1 checksum result
+ */
+void sha1_finish( sha1_context *ctx, unsigned char output[20] );
+
+/**
+ * \brief Output = SHA-1( input buffer )
+ *
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ * \param output SHA-1 checksum result
+ */
+void polarssl_sha1( const unsigned char *input, int ilen, unsigned char output[20] );
+
+/**
+ * \brief Output = SHA-1( file contents )
+ *
+ * \param path input file name
+ * \param output SHA-1 checksum result
+ *
+ * \return 0 if successful, 1 if fopen failed,
+ * or 2 if fread failed
+ */
+int sha1_file( const char *path, unsigned char output[20] );
+
+/**
+ * \brief SHA-1 HMAC context setup
+ *
+ * \param ctx HMAC context to be initialized
+ * \param key HMAC secret key
+ * \param keylen length of the HMAC key
+ */
+void sha1_hmac_starts( sha1_context *ctx, const unsigned char *key, int keylen );
+
+/**
+ * \brief SHA-1 HMAC process buffer
+ *
+ * \param ctx HMAC context
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ */
+void sha1_hmac_update( sha1_context *ctx, const unsigned char *input, int ilen );
+
+/**
+ * \brief SHA-1 HMAC final digest
+ *
+ * \param ctx HMAC context
+ * \param output SHA-1 HMAC checksum result
+ */
+void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] );
+
+/**
+ * \brief SHA-1 HMAC context reset
+ *
+ * \param ctx HMAC context to be reset
+ */
+void sha1_hmac_reset( sha1_context *ctx );
+
+/**
+ * \brief Output = HMAC-SHA-1( hmac key, input buffer )
+ *
+ * \param key HMAC secret key
+ * \param keylen length of the HMAC key
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ * \param output HMAC-SHA-1 result
+ */
+void sha1_hmac( const unsigned char *key, int keylen,
+ const unsigned char *input, int ilen,
+ unsigned char output[20] );
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ */
+int sha1_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* sha1.h */
--- /dev/null
+/**
+ * \file sha2.h
+ *
+ * Copyright (C) 2006-2010, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef POLARSSL_SHA2_H
+#define POLARSSL_SHA2_H
+
+/**
+ * \brief SHA-256 context structure
+ */
+#ifndef HAVE_SHA2_CONTEXT
+#define HAVE_SHA2_CONTEXT
+typedef struct sha2_context sha2_context;
+#endif
+
+struct sha2_context
+{
+ unsigned long total[2]; /*!< number of bytes processed */
+ unsigned long state[8]; /*!< intermediate digest state */
+ unsigned char buffer[64]; /*!< data block being processed */
+
+ unsigned char ipad[64]; /*!< HMAC: inner padding */
+ unsigned char opad[64]; /*!< HMAC: outer padding */
+ int is224; /*!< 0 => SHA-256, else SHA-224 */
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief SHA-256 context setup
+ *
+ * \param ctx context to be initialized
+ * \param is224 0 = use SHA256, 1 = use SHA224
+ */
+void sha2_starts( sha2_context *ctx, int is224 );
+
+/**
+ * \brief SHA-256 process buffer
+ *
+ * \param ctx SHA-256 context
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ */
+void sha2_update( sha2_context *ctx, const unsigned char *input, int ilen );
+
+/**
+ * \brief SHA-256 final digest
+ *
+ * \param ctx SHA-256 context
+ * \param output SHA-224/256 checksum result
+ */
+void sha2_finish( sha2_context *ctx, unsigned char output[32] );
+
+/**
+ * \brief Output = SHA-256( input buffer )
+ *
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ * \param output SHA-224/256 checksum result
+ * \param is224 0 = use SHA256, 1 = use SHA224
+ */
+void sha2( const unsigned char *input, int ilen,
+ unsigned char output[32], int is224 );
+
+/**
+ * \brief Output = SHA-256( file contents )
+ *
+ * \param path input file name
+ * \param output SHA-224/256 checksum result
+ * \param is224 0 = use SHA256, 1 = use SHA224
+ *
+ * \return 0 if successful, 1 if fopen failed,
+ * or 2 if fread failed
+ */
+int sha2_file( const char *path, unsigned char output[32], int is224 );
+
+/**
+ * \brief SHA-256 HMAC context setup
+ *
+ * \param ctx HMAC context to be initialized
+ * \param key HMAC secret key
+ * \param keylen length of the HMAC key
+ * \param is224 0 = use SHA256, 1 = use SHA224
+ */
+void sha2_hmac_starts( sha2_context *ctx, const unsigned char *key, int keylen,
+ int is224 );
+
+/**
+ * \brief SHA-256 HMAC process buffer
+ *
+ * \param ctx HMAC context
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ */
+void sha2_hmac_update( sha2_context *ctx, const unsigned char *input, int ilen );
+
+/**
+ * \brief SHA-256 HMAC final digest
+ *
+ * \param ctx HMAC context
+ * \param output SHA-224/256 HMAC checksum result
+ */
+void sha2_hmac_finish( sha2_context *ctx, unsigned char output[32] );
+
+/**
+ * \brief SHA-256 HMAC context reset
+ *
+ * \param ctx HMAC context to be reset
+ */
+void sha2_hmac_reset( sha2_context *ctx );
+
+/**
+ * \brief Output = HMAC-SHA-256( hmac key, input buffer )
+ *
+ * \param key HMAC secret key
+ * \param keylen length of the HMAC key
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ * \param output HMAC-SHA-224/256 result
+ * \param is224 0 = use SHA256, 1 = use SHA224
+ */
+void sha2_hmac( const unsigned char *key, int keylen,
+ const unsigned char *input, int ilen,
+ unsigned char output[32], int is224 );
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ */
+int sha2_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* sha2.h */
* http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf
*/
-#include "rsa.h"
-#include "base64.h"
+#include "polarssl/config.h"
+
+#if defined(POLARSSL_RSA_C)
+
+#include "polarssl/rsa.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
-/* *************** begin copy from x509parse.c ********************/
-/*
- * ASN.1 DER decoding routines
- */
-static int asn1_get_len( unsigned char **p,
- const unsigned char *end,
- int *len )
-{
- if( ( end - *p ) < 1 )
- return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
-
- if( ( **p & 0x80 ) == 0 )
- *len = *(*p)++;
- else
- {
- switch( **p & 0x7F )
- {
- case 1:
- if( ( end - *p ) < 2 )
- return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
-
- *len = (*p)[1];
- (*p) += 2;
- break;
-
- case 2:
- if( ( end - *p ) < 3 )
- return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
-
- *len = ( (*p)[1] << 8 ) | (*p)[2];
- (*p) += 3;
- break;
-
- default:
- return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
- break;
- }
- }
-
- if( *len > (int) ( end - *p ) )
- return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
-
- return( 0 );
-}
-
-static int asn1_get_tag( unsigned char **p,
- const unsigned char *end,
- int *len, int tag )
-{
- if( ( end - *p ) < 1 )
- return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
-
- if( **p != tag )
- return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
-
- (*p)++;
-
- return( asn1_get_len( p, end, len ) );
-}
-
-static int asn1_get_int( unsigned char **p,
- const unsigned char *end,
- int *val )
-{
- int ret, len;
-
- if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
- return( ret );
-
- if( len > (int) sizeof( int ) || ( **p & 0x80 ) != 0 )
- return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
-
- *val = 0;
-
- while( len-- > 0 )
- {
- *val = ( *val << 8 ) | **p;
- (*p)++;
- }
-
- return( 0 );
-}
-
-static int asn1_get_mpi( unsigned char **p,
- const unsigned char *end,
- mpi *X )
-{
- int ret, len;
-
- if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
- return( ret );
-
- ret = mpi_read_binary( X, *p, len );
-
- *p += len;
-
- return( ret );
-}
-/* *************** end copy from x509parse.c ********************/
-
-
-
-
/*
* Initialize an RSA context
*/
do
{
- MPI_CHK( mpi_gen_prime( &ctx->P, ( nbits + 1 ) >> 1, 0,
+ MPI_CHK( mpi_gen_prime( &ctx->P, ( nbits + 1 ) >> 1, 0,
f_rng, p_rng ) );
MPI_CHK( mpi_gen_prime( &ctx->Q, ( nbits + 1 ) >> 1, 0,
return( POLARSSL_ERR_RSA_KEY_GEN_FAILED | ret );
}
- return( 0 );
+ return( 0 );
}
#endif
MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) );
MPI_CHK( mpi_gcd( &G2, &P1, &Q1 ) );
- MPI_CHK( mpi_div_mpi( &L1, &L2, &H, &G2 ) );
+ MPI_CHK( mpi_div_mpi( &L1, &L2, &H, &G2 ) );
MPI_CHK( mpi_mod_mpi( &I, &DE, &L1 ) );
/*
return( 0 );
}
-
+
cleanup:
mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, &G2, &L1, &L2, NULL );
}
if (ilen - (int)(p - buf) > output_max_len)
- return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE );
+ return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE );
*olen = ilen - (int)(p - buf);
memcpy( output, p, *olen );
( len == 19 + 48 && p[14] == 2 && hash_id == SIG_RSA_SHA384 ) ||
( len == 19 + 64 && p[14] == 3 && hash_id == SIG_RSA_SHA512 ) )
{
- c = p[1] - 17;
+ c = p[1] - 17;
p[1] = 17;
p[14] = 0;
&ctx->E, &ctx->N, NULL );
}
+#if defined(POLARSSL_SELF_TEST)
+
+#include "polarssl/sha1.h"
-/* PDKIM code (not copied from polarssl) */
/*
- * Parse a public RSA key
-
-OpenSSL RSA public key ASN1 container
- 0:d=0 hl=3 l= 159 cons: SEQUENCE
- 3:d=1 hl=2 l= 13 cons: SEQUENCE
- 5:d=2 hl=2 l= 9 prim: OBJECT:rsaEncryption
- 16:d=2 hl=2 l= 0 prim: NULL
- 18:d=1 hl=3 l= 141 prim: BIT STRING:RSAPublicKey (below)
-
-RSAPublicKey ASN1 container
- 0:d=0 hl=3 l= 137 cons: SEQUENCE
- 3:d=1 hl=3 l= 129 prim: INTEGER:Public modulus
-135:d=1 hl=2 l= 3 prim: INTEGER:Public exponent
-*/
-
-int rsa_parse_public_key( rsa_context *rsa, unsigned char *buf, int buflen )
+ * Example RSA-1024 keypair, for test purposes
+ */
+#define KEY_LEN 128
+
+#define RSA_N "9292758453063D803DD603D5E777D788" \
+ "8ED1D5BF35786190FA2F23EBC0848AEA" \
+ "DDA92CA6C3D80B32C4D109BE0F36D6AE" \
+ "7130B9CED7ACDF54CFC7555AC14EEBAB" \
+ "93A89813FBF3C4F8066D2D800F7C38A8" \
+ "1AE31942917403FF4946B0A83D3D3E05" \
+ "EE57C6F5F5606FB5D4BC6CD34EE0801A" \
+ "5E94BB77B07507233A0BC7BAC8F90F79"
+
+#define RSA_E "10001"
+
+#define RSA_D "24BF6185468786FDD303083D25E64EFC" \
+ "66CA472BC44D253102F8B4A9D3BFA750" \
+ "91386C0077937FE33FA3252D28855837" \
+ "AE1B484A8A9A45F7EE8C0C634F99E8CD" \
+ "DF79C5CE07EE72C7F123142198164234" \
+ "CABB724CF78B8173B9F880FC86322407" \
+ "AF1FEDFDDE2BEB674CA15F3E81A1521E" \
+ "071513A1E85B5DFA031F21ECAE91A34D"
+
+#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
+ "2C01CAD19EA484A87EA4377637E75500" \
+ "FCB2005C5C7DD6EC4AC023CDA285D796" \
+ "C3D9E75E1EFC42488BB4F1D13AC30A57"
+
+#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
+ "E211C2B9E5DB1ED0BF61D0D9899620F4" \
+ "910E4168387E3C30AA1E00C339A79508" \
+ "8452DD96A9A5EA5D9DCA68DA636032AF"
+
+#define RSA_DP "C1ACF567564274FB07A0BBAD5D26E298" \
+ "3C94D22288ACD763FD8E5600ED4A702D" \
+ "F84198A5F06C2E72236AE490C93F07F8" \
+ "3CC559CD27BC2D1CA488811730BB5725"
+
+#define RSA_DQ "4959CBF6F8FEF750AEE6977C155579C7" \
+ "D8AAEA56749EA28623272E4F7D0592AF" \
+ "7C1F1313CAC9471B5C523BFE592F517B" \
+ "407A1BD76C164B93DA2D32A383E58357"
+
+#define RSA_QP "9AE7FBC99546432DF71896FC239EADAE" \
+ "F38D18D2B2F0E2DD275AA977E2BF4411" \
+ "F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \
+ "A74206CEC169D74BF5A8C50D6F48EA08"
+
+#define PT_LEN 24
+#define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
+ "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
+
+static int myrand( void *rng_state )
{
- unsigned char *p, *end;
- int ret, len;
-
- p = buf;
- end = buf+buflen;
-
- if( ( ret = asn1_get_tag( &p, end, &len,
- ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) {
- return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
- }
-
- if( ( ret = asn1_get_tag( &p, end, &len,
- ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) == 0 ) {
- /* Skip over embedded rsaEncryption Object */
- p+=len;
-
- /* The RSAPublicKey ASN1 container is wrapped in a BIT STRING */
- if( ( ret = asn1_get_tag( &p, end, &len,
- ASN1_BIT_STRING ) ) != 0 ) {
- return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
- }
+ if( rng_state != NULL )
+ rng_state = NULL;
- /* Limit range to that BIT STRING */
- end = p + len;
- p++;
-
- if( ( ret = asn1_get_tag( &p, end, &len,
- ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) {
- return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
- }
- }
-
- if ( ( ( ret = asn1_get_mpi( &p, end, &(rsa->N) ) ) == 0 ) &&
- ( ( ret = asn1_get_mpi( &p, end, &(rsa->E) ) ) == 0 ) ) {
- rsa->len = mpi_size( &rsa->N );
- return 0;
- }
-
- return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
+ return( rand() );
}
/*
- * Parse a private RSA key
+ * Checkup routine
*/
-int rsa_parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
- unsigned char *pwd, int pwdlen )
+int rsa_self_test( int verbose )
{
- int ret, len, enc;
- unsigned char *s1, *s2;
- unsigned char *p, *end;
-
- s1 = (unsigned char *) strstr( (char *) buf,
- "-----BEGIN RSA PRIVATE KEY-----" );
-
- if( s1 != NULL )
+ int len;
+ rsa_context rsa;
+ unsigned char sha1sum[20];
+ unsigned char rsa_plaintext[PT_LEN];
+ unsigned char rsa_decrypted[PT_LEN];
+ unsigned char rsa_ciphertext[KEY_LEN];
+
+ rsa_init( &rsa, RSA_PKCS_V15, 0 );
+
+ rsa.len = KEY_LEN;
+ mpi_read_string( &rsa.N , 16, RSA_N );
+ mpi_read_string( &rsa.E , 16, RSA_E );
+ mpi_read_string( &rsa.D , 16, RSA_D );
+ mpi_read_string( &rsa.P , 16, RSA_P );
+ mpi_read_string( &rsa.Q , 16, RSA_Q );
+ mpi_read_string( &rsa.DP, 16, RSA_DP );
+ mpi_read_string( &rsa.DQ, 16, RSA_DQ );
+ mpi_read_string( &rsa.QP, 16, RSA_QP );
+
+ if( verbose != 0 )
+ printf( " RSA key validation: " );
+
+ if( rsa_check_pubkey( &rsa ) != 0 ||
+ rsa_check_privkey( &rsa ) != 0 )
{
- s2 = (unsigned char *) strstr( (char *) buf,
- "-----END RSA PRIVATE KEY-----" );
-
- if( s2 == NULL || s2 <= s1 )
- return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
+ if( verbose != 0 )
+ printf( "failed\n" );
- s1 += 31;
- if( *s1 == '\r' ) s1++;
- if( *s1 == '\n' ) s1++;
- else return( POLARSSL_ERR_X509_KEY_INVALID_PEM );
-
- enc = 0;
-
- if( memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
- {
- return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
- }
-
- len = 0;
- ret = base64_decode( NULL, &len, s1, s2 - s1 );
-
- if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
- return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
-
- if( ( buf = (unsigned char *) malloc( len ) ) == NULL )
- return( 1 );
-
- if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 )
- {
- free( buf );
- return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM );
- }
-
- buflen = len;
-
- if( enc != 0 )
- {
- return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
- }
+ return( 1 );
}
- memset( rsa, 0, sizeof( rsa_context ) );
+ if( verbose != 0 )
+ printf( "passed\n PKCS#1 encryption : " );
- p = buf;
- end = buf + buflen;
+ memcpy( rsa_plaintext, RSA_PT, PT_LEN );
- /*
- * RSAPrivateKey ::= SEQUENCE {
- * version Version,
- * modulus INTEGER, -- n
- * publicExponent INTEGER, -- e
- * privateExponent INTEGER, -- d
- * prime1 INTEGER, -- p
- * prime2 INTEGER, -- q
- * exponent1 INTEGER, -- d mod (p-1)
- * exponent2 INTEGER, -- d mod (q-1)
- * coefficient INTEGER, -- (inverse of q) mod p
- * otherPrimeInfos OtherPrimeInfos OPTIONAL
- * }
- */
- if( ( ret = asn1_get_tag( &p, end, &len,
- ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
+ if( rsa_pkcs1_encrypt( &rsa, &myrand, NULL, RSA_PUBLIC, PT_LEN,
+ rsa_plaintext, rsa_ciphertext ) != 0 )
{
- if( s1 != NULL )
- free( buf );
+ if( verbose != 0 )
+ printf( "failed\n" );
- rsa_free( rsa );
- return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
+ return( 1 );
}
- end = p + len;
+ if( verbose != 0 )
+ printf( "passed\n PKCS#1 decryption : " );
- if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
+ if( rsa_pkcs1_decrypt( &rsa, RSA_PRIVATE, &len,
+ rsa_ciphertext, rsa_decrypted,
+ sizeof(rsa_decrypted) ) != 0 )
{
- if( s1 != NULL )
- free( buf );
+ if( verbose != 0 )
+ printf( "failed\n" );
- rsa_free( rsa );
- return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
+ return( 1 );
}
- if( rsa->ver != 0 )
+ if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
{
- if( s1 != NULL )
- free( buf );
+ if( verbose != 0 )
+ printf( "failed\n" );
- rsa_free( rsa );
- return( ret | POLARSSL_ERR_X509_KEY_INVALID_VERSION );
+ return( 1 );
}
- if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
- ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
- ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
- ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
- ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
- ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
- ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
- ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
- {
- if( s1 != NULL )
- free( buf );
-
- rsa_free( rsa );
- return( ret | POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
- }
+ if( verbose != 0 )
+ printf( "passed\n PKCS#1 data sign : " );
- rsa->len = mpi_size( &rsa->N );
+ polarssl_sha1( rsa_plaintext, PT_LEN, sha1sum );
- if( p != end )
+ if( rsa_pkcs1_sign( &rsa, RSA_PRIVATE, SIG_RSA_SHA1, 20,
+ sha1sum, rsa_ciphertext ) != 0 )
{
- if( s1 != NULL )
- free( buf );
+ if( verbose != 0 )
+ printf( "failed\n" );
- rsa_free( rsa );
- return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT |
- POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
+ return( 1 );
}
- if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
+ if( verbose != 0 )
+ printf( "passed\n PKCS#1 sig. verify: " );
+
+ if( rsa_pkcs1_verify( &rsa, RSA_PUBLIC, SIG_RSA_SHA1, 20,
+ sha1sum, rsa_ciphertext ) != 0 )
{
- if( s1 != NULL )
- free( buf );
+ if( verbose != 0 )
+ printf( "failed\n" );
- rsa_free( rsa );
- return( ret );
+ return( 1 );
}
- if( s1 != NULL )
- free( buf );
+ if( verbose != 0 )
+ printf( "passed\n\n" );
+
+ rsa_free( &rsa );
return( 0 );
}
+
+#endif
+
+#endif
+++ /dev/null
-/**
- * \file rsa.h
- *
- * Copyright (C) 2006-2010, Brainspark B.V.
- *
- * This file is part of PolarSSL (http://www.polarssl.org)
- * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
- *
- * 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef POLARSSL_RSA_H
-#define POLARSSL_RSA_H
-
-#include "bignum.h"
-
-/*
- * RSA Error codes
- */
-#define POLARSSL_ERR_RSA_BAD_INPUT_DATA -0x0400
-#define POLARSSL_ERR_RSA_INVALID_PADDING -0x0410
-#define POLARSSL_ERR_RSA_KEY_GEN_FAILED -0x0420
-#define POLARSSL_ERR_RSA_KEY_CHECK_FAILED -0x0430
-#define POLARSSL_ERR_RSA_PUBLIC_FAILED -0x0440
-#define POLARSSL_ERR_RSA_PRIVATE_FAILED -0x0450
-#define POLARSSL_ERR_RSA_VERIFY_FAILED -0x0460
-#define POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE -0x0470
-#define POLARSSL_ERR_RSA_RNG_FAILED -0x0480
-
-/* *************** begin copy from x509.h ************************/
-/*
- * ASN1 Error codes
- *
- * These error codes will be OR'ed to X509 error codes for
- * higher error granularity.
- */
-#define POLARSSL_ERR_ASN1_OUT_OF_DATA 0x0014
-#define POLARSSL_ERR_ASN1_UNEXPECTED_TAG 0x0016
-#define POLARSSL_ERR_ASN1_INVALID_LENGTH 0x0018
-#define POLARSSL_ERR_ASN1_LENGTH_MISMATCH 0x001A
-#define POLARSSL_ERR_ASN1_INVALID_DATA 0x001C
-
-/*
- * X509 Error codes
- */
-#define POLARSSL_ERR_X509_FEATURE_UNAVAILABLE -0x0020
-#define POLARSSL_ERR_X509_CERT_INVALID_PEM -0x0040
-#define POLARSSL_ERR_X509_CERT_INVALID_FORMAT -0x0060
-#define POLARSSL_ERR_X509_CERT_INVALID_VERSION -0x0080
-#define POLARSSL_ERR_X509_CERT_INVALID_SERIAL -0x00A0
-#define POLARSSL_ERR_X509_CERT_INVALID_ALG -0x00C0
-#define POLARSSL_ERR_X509_CERT_INVALID_NAME -0x00E0
-#define POLARSSL_ERR_X509_CERT_INVALID_DATE -0x0100
-#define POLARSSL_ERR_X509_CERT_INVALID_PUBKEY -0x0120
-#define POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE -0x0140
-#define POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS -0x0160
-#define POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION -0x0180
-#define POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG -0x01A0
-#define POLARSSL_ERR_X509_CERT_UNKNOWN_PK_ALG -0x01C0
-#define POLARSSL_ERR_X509_CERT_SIG_MISMATCH -0x01E0
-#define POLARSSL_ERR_X509_CERT_VERIFY_FAILED -0x0200
-#define POLARSSL_ERR_X509_KEY_INVALID_PEM -0x0220
-#define POLARSSL_ERR_X509_KEY_INVALID_VERSION -0x0240
-#define POLARSSL_ERR_X509_KEY_INVALID_FORMAT -0x0260
-#define POLARSSL_ERR_X509_KEY_INVALID_ENC_IV -0x0280
-#define POLARSSL_ERR_X509_KEY_UNKNOWN_ENC_ALG -0x02A0
-#define POLARSSL_ERR_X509_KEY_PASSWORD_REQUIRED -0x02C0
-#define POLARSSL_ERR_X509_KEY_PASSWORD_MISMATCH -0x02E0
-#define POLARSSL_ERR_X509_POINT_ERROR -0x0300
-#define POLARSSL_ERR_X509_VALUE_TO_LENGTH -0x0320
-
-/*
- * DER constants
- */
-#define ASN1_BOOLEAN 0x01
-#define ASN1_INTEGER 0x02
-#define ASN1_BIT_STRING 0x03
-#define ASN1_OCTET_STRING 0x04
-#define ASN1_NULL 0x05
-#define ASN1_OID 0x06
-#define ASN1_UTF8_STRING 0x0C
-#define ASN1_SEQUENCE 0x10
-#define ASN1_SET 0x11
-#define ASN1_PRINTABLE_STRING 0x13
-#define ASN1_T61_STRING 0x14
-#define ASN1_IA5_STRING 0x16
-#define ASN1_UTC_TIME 0x17
-#define ASN1_GENERALIZED_TIME 0x18
-#define ASN1_UNIVERSAL_STRING 0x1C
-#define ASN1_BMP_STRING 0x1E
-#define ASN1_PRIMITIVE 0x00
-#define ASN1_CONSTRUCTED 0x20
-#define ASN1_CONTEXT_SPECIFIC 0x80
-/* *************** end copy from x509.h ************************/
-
-/*
- * PKCS#1 constants
- */
-#define SIG_RSA_RAW 0
-#define SIG_RSA_MD2 2
-#define SIG_RSA_MD4 3
-#define SIG_RSA_MD5 4
-#define SIG_RSA_SHA1 5
-#define SIG_RSA_SHA224 14
-#define SIG_RSA_SHA256 11
-#define SIG_RSA_SHA384 12
-#define SIG_RSA_SHA512 13
-
-#define RSA_PUBLIC 0
-#define RSA_PRIVATE 1
-
-#define RSA_PKCS_V15 0
-#define RSA_PKCS_V21 1
-
-#define RSA_SIGN 1
-#define RSA_CRYPT 2
-
-#define ASN1_STR_CONSTRUCTED_SEQUENCE "\x30"
-#define ASN1_STR_NULL "\x05"
-#define ASN1_STR_OID "\x06"
-#define ASN1_STR_OCTET_STRING "\x04"
-
-#define OID_DIGEST_ALG_MDX "\x2A\x86\x48\x86\xF7\x0D\x02\x00"
-#define OID_HASH_ALG_SHA1 "\x2b\x0e\x03\x02\x1a"
-#define OID_HASH_ALG_SHA2X "\x60\x86\x48\x01\x65\x03\x04\x02\x00"
-
-#define OID_ISO_MEMBER_BODIES "\x2a"
-#define OID_ISO_IDENTIFIED_ORG "\x2b"
-
-/*
- * ISO Member bodies OID parts
- */
-#define OID_COUNTRY_US "\x86\x48"
-#define OID_RSA_DATA_SECURITY "\x86\xf7\x0d"
-
-/*
- * ISO Identified organization OID parts
- */
-#define OID_OIW_SECSIG_SHA1 "\x0e\x03\x02\x1a"
-
-/*
- * DigestInfo ::= SEQUENCE {
- * digestAlgorithm DigestAlgorithmIdentifier,
- * digest Digest }
- *
- * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
- *
- * Digest ::= OCTET STRING
- */
-#define ASN1_HASH_MDX \
-( \
- ASN1_STR_CONSTRUCTED_SEQUENCE "\x20" \
- ASN1_STR_CONSTRUCTED_SEQUENCE "\x0C" \
- ASN1_STR_OID "\x08" \
- OID_DIGEST_ALG_MDX \
- ASN1_STR_NULL "\x00" \
- ASN1_STR_OCTET_STRING "\x10" \
-)
-
-#define ASN1_HASH_SHA1 \
- ASN1_STR_CONSTRUCTED_SEQUENCE "\x21" \
- ASN1_STR_CONSTRUCTED_SEQUENCE "\x09" \
- ASN1_STR_OID "\x05" \
- OID_HASH_ALG_SHA1 \
- ASN1_STR_NULL "\x00" \
- ASN1_STR_OCTET_STRING "\x14"
-
-#define ASN1_HASH_SHA2X \
- ASN1_STR_CONSTRUCTED_SEQUENCE "\x11" \
- ASN1_STR_CONSTRUCTED_SEQUENCE "\x0d" \
- ASN1_STR_OID "\x09" \
- OID_HASH_ALG_SHA2X \
- ASN1_STR_NULL "\x00" \
- ASN1_STR_OCTET_STRING "\x00"
-
-/**
- * \brief RSA context structure
- */
-typedef struct
-{
- int ver; /*!< always 0 */
- int len; /*!< size(N) in chars */
-
- mpi N; /*!< public modulus */
- mpi E; /*!< public exponent */
-
- mpi D; /*!< private exponent */
- mpi P; /*!< 1st prime factor */
- mpi Q; /*!< 2nd prime factor */
- mpi DP; /*!< D % (P - 1) */
- mpi DQ; /*!< D % (Q - 1) */
- mpi QP; /*!< 1 / (Q % P) */
-
- mpi RN; /*!< cached R^2 mod N */
- mpi RP; /*!< cached R^2 mod P */
- mpi RQ; /*!< cached R^2 mod Q */
-
- int padding; /*!< 1.5 or OAEP/PSS */
- int hash_id; /*!< hash identifier */
-}
-rsa_context;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \brief Initialize an RSA context
- *
- * \param ctx RSA context to be initialized
- * \param padding RSA_PKCS_V15 or RSA_PKCS_V21
- * \param hash_id RSA_PKCS_V21 hash identifier
- *
- * \note The hash_id parameter is actually ignored
- * when using RSA_PKCS_V15 padding.
- *
- * \note Currently, RSA_PKCS_V21 padding
- * is not supported.
- */
-void rsa_init( rsa_context *ctx,
- int padding,
- int hash_id);
-
-/**
- * \brief Generate an RSA keypair
- *
- * \param ctx RSA context that will hold the key
- * \param f_rng RNG function
- * \param p_rng RNG parameter
- * \param nbits size of the public key in bits
- * \param exponent public exponent (e.g., 65537)
- *
- * \note rsa_init() must be called beforehand to setup
- * the RSA context.
- *
- * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
- */
-int rsa_gen_key( rsa_context *ctx,
- int (*f_rng)(void *),
- void *p_rng,
- int nbits, int exponent );
-
-/**
- * \brief Check a public RSA key
- *
- * \param ctx RSA context to be checked
- *
- * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
- */
-int rsa_check_pubkey( const rsa_context *ctx );
-
-/**
- * \brief Check a private RSA key
- *
- * \param ctx RSA context to be checked
- *
- * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
- */
-int rsa_check_privkey( const rsa_context *ctx );
-
-/**
- * \brief Do an RSA public key operation
- *
- * \param ctx RSA context
- * \param input input buffer
- * \param output output buffer
- *
- * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
- *
- * \note This function does NOT take care of message
- * padding. Also, be sure to set input[0] = 0 or assure that
- * input is smaller than N.
- *
- * \note The input and output buffers must be large
- * enough (eg. 128 bytes if RSA-1024 is used).
- */
-int rsa_public( rsa_context *ctx,
- const unsigned char *input,
- unsigned char *output );
-
-/**
- * \brief Do an RSA private key operation
- *
- * \param ctx RSA context
- * \param input input buffer
- * \param output output buffer
- *
- * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
- *
- * \note The input and output buffers must be large
- * enough (eg. 128 bytes if RSA-1024 is used).
- */
-int rsa_private( rsa_context *ctx,
- const unsigned char *input,
- unsigned char *output );
-
-/**
- * \brief Add the message padding, then do an RSA operation
- *
- * \param ctx RSA context
- * \param f_rng RNG function
- * \param p_rng RNG parameter
- * \param mode RSA_PUBLIC or RSA_PRIVATE
- * \param ilen contains the plaintext length
- * \param input buffer holding the data to be encrypted
- * \param output buffer that will hold the ciphertext
- *
- * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
- *
- * \note The output buffer must be as large as the size
- * of ctx->N (eg. 128 bytes if RSA-1024 is used).
- */
-int rsa_pkcs1_encrypt( rsa_context *ctx,
- int (*f_rng)(void *),
- void *p_rng,
- int mode, int ilen,
- const unsigned char *input,
- unsigned char *output );
-
-/**
- * \brief Do an RSA operation, then remove the message padding
- *
- * \param ctx RSA context
- * \param mode RSA_PUBLIC or RSA_PRIVATE
- * \param input buffer holding the encrypted data
- * \param output buffer that will hold the plaintext
- * \param olen will contain the plaintext length
- * \param output_max_len maximum length of the output buffer
- *
- * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
- *
- * \note The output buffer must be as large as the size
- * of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
- * an error is thrown.
- */
-int rsa_pkcs1_decrypt( rsa_context *ctx,
- int mode, int *olen,
- const unsigned char *input,
- unsigned char *output,
- int output_max_len );
-
-/**
- * \brief Do a private RSA to sign a message digest
- *
- * \param ctx RSA context
- * \param mode RSA_PUBLIC or RSA_PRIVATE
- * \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
- * \param hashlen message digest length (for SIG_RSA_RAW only)
- * \param hash buffer holding the message digest
- * \param sig buffer that will hold the ciphertext
- *
- * \return 0 if the signing operation was successful,
- * or an POLARSSL_ERR_RSA_XXX error code
- *
- * \note The "sig" buffer must be as large as the size
- * of ctx->N (eg. 128 bytes if RSA-1024 is used).
- */
-int rsa_pkcs1_sign( rsa_context *ctx,
- int mode,
- int hash_id,
- int hashlen,
- const unsigned char *hash,
- unsigned char *sig );
-
-/**
- * \brief Do a public RSA and check the message digest
- *
- * \param ctx points to an RSA public key
- * \param mode RSA_PUBLIC or RSA_PRIVATE
- * \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
- * \param hashlen message digest length (for SIG_RSA_RAW only)
- * \param hash buffer holding the message digest
- * \param sig buffer holding the ciphertext
- *
- * \return 0 if the verify operation was successful,
- * or an POLARSSL_ERR_RSA_XXX error code
- *
- * \note The "sig" buffer must be as large as the size
- * of ctx->N (eg. 128 bytes if RSA-1024 is used).
- */
-int rsa_pkcs1_verify( rsa_context *ctx,
- int mode,
- int hash_id,
- int hashlen,
- const unsigned char *hash,
- unsigned char *sig );
-
-/**
- * \brief Free the components of an RSA key
- *
- * \param ctx RSA Context to free
- */
-void rsa_free( rsa_context *ctx );
-
-/* PDKIM declarations (not part of polarssl) */
-int rsa_parse_public_key( rsa_context *rsa, unsigned char *buf, int buflen );
-int rsa_parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
- unsigned char *pwd, int pwdlen );
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* rsa.h */
* http://www.itl.nist.gov/fipspubs/fip180-1.htm
*/
-#include "sha1.h"
+#include "polarssl/config.h"
+
+#if defined(POLARSSL_SHA1_C)
+
+#include "polarssl/sha1.h"
#include <string.h>
#include <stdio.h>
/*
* output = SHA-1( input buffer )
*/
-void sha1( const unsigned char *input, int ilen, unsigned char output[20] )
+void polarssl_sha1( const unsigned char *input, int ilen, unsigned char output[20] )
{
sha1_context ctx;
if( keylen > 64 )
{
- sha1( key, keylen, sum );
+ polarssl_sha1( key, keylen, sum );
keylen = 20;
key = sum;
}
memset( &ctx, 0, sizeof( sha1_context ) );
}
+
+#if defined(POLARSSL_SELF_TEST)
+/*
+ * FIPS-180-1 test vectors
+ */
+static unsigned char sha1_test_buf[3][57] =
+{
+ { "abc" },
+ { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
+ { "" }
+};
+
+static const int sha1_test_buflen[3] =
+{
+ 3, 56, 1000
+};
+
+static const unsigned char sha1_test_sum[3][20] =
+{
+ { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
+ 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D },
+ { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
+ 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 },
+ { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
+ 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F }
+};
+
+/*
+ * RFC 2202 test vectors
+ */
+static unsigned char sha1_hmac_test_key[7][26] =
+{
+ { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
+ "\x0B\x0B\x0B\x0B" },
+ { "Jefe" },
+ { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
+ "\xAA\xAA\xAA\xAA" },
+ { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
+ "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
+ { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
+ "\x0C\x0C\x0C\x0C" },
+ { "" }, /* 0xAA 80 times */
+ { "" }
+};
+
+static const int sha1_hmac_test_keylen[7] =
+{
+ 20, 4, 20, 25, 20, 80, 80
+};
+
+static unsigned char sha1_hmac_test_buf[7][74] =
+{
+ { "Hi There" },
+ { "what do ya want for nothing?" },
+ { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
+ { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
+ "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
+ "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
+ "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
+ "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
+ { "Test With Truncation" },
+ { "Test Using Larger Than Block-Size Key - Hash Key First" },
+ { "Test Using Larger Than Block-Size Key and Larger"
+ " Than One Block-Size Data" }
+};
+
+static const int sha1_hmac_test_buflen[7] =
+{
+ 8, 28, 50, 50, 20, 54, 73
+};
+
+static const unsigned char sha1_hmac_test_sum[7][20] =
+{
+ { 0xB6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xE2, 0x8B,
+ 0xC0, 0xB6, 0xFB, 0x37, 0x8C, 0x8E, 0xF1, 0x46, 0xBE, 0x00 },
+ { 0xEF, 0xFC, 0xDF, 0x6A, 0xE5, 0xEB, 0x2F, 0xA2, 0xD2, 0x74,
+ 0x16, 0xD5, 0xF1, 0x84, 0xDF, 0x9C, 0x25, 0x9A, 0x7C, 0x79 },
+ { 0x12, 0x5D, 0x73, 0x42, 0xB9, 0xAC, 0x11, 0xCD, 0x91, 0xA3,
+ 0x9A, 0xF4, 0x8A, 0xA1, 0x7B, 0x4F, 0x63, 0xF1, 0x75, 0xD3 },
+ { 0x4C, 0x90, 0x07, 0xF4, 0x02, 0x62, 0x50, 0xC6, 0xBC, 0x84,
+ 0x14, 0xF9, 0xBF, 0x50, 0xC8, 0x6C, 0x2D, 0x72, 0x35, 0xDA },
+ { 0x4C, 0x1A, 0x03, 0x42, 0x4B, 0x55, 0xE0, 0x7F, 0xE7, 0xF2,
+ 0x7B, 0xE1 },
+ { 0xAA, 0x4A, 0xE5, 0xE1, 0x52, 0x72, 0xD0, 0x0E, 0x95, 0x70,
+ 0x56, 0x37, 0xCE, 0x8A, 0x3B, 0x55, 0xED, 0x40, 0x21, 0x12 },
+ { 0xE8, 0xE9, 0x9D, 0x0F, 0x45, 0x23, 0x7D, 0x78, 0x6D, 0x6B,
+ 0xBA, 0xA7, 0x96, 0x5C, 0x78, 0x08, 0xBB, 0xFF, 0x1A, 0x91 }
+};
+
+/*
+ * Checkup routine
+ */
+int sha1_self_test( int verbose )
+{
+ int i, j, buflen;
+ unsigned char buf[1024];
+ unsigned char sha1sum[20];
+ sha1_context ctx;
+
+ /*
+ * SHA-1
+ */
+ for( i = 0; i < 3; i++ )
+ {
+ if( verbose != 0 )
+ printf( " SHA-1 test #%d: ", i + 1 );
+
+ sha1_starts( &ctx );
+
+ if( i == 2 )
+ {
+ memset( buf, 'a', buflen = 1000 );
+
+ for( j = 0; j < 1000; j++ )
+ sha1_update( &ctx, buf, buflen );
+ }
+ else
+ sha1_update( &ctx, sha1_test_buf[i],
+ sha1_test_buflen[i] );
+
+ sha1_finish( &ctx, sha1sum );
+
+ if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n" );
+ }
+
+ if( verbose != 0 )
+ printf( "\n" );
+
+ for( i = 0; i < 7; i++ )
+ {
+ if( verbose != 0 )
+ printf( " HMAC-SHA-1 test #%d: ", i + 1 );
+
+ if( i == 5 || i == 6 )
+ {
+ memset( buf, '\xAA', buflen = 80 );
+ sha1_hmac_starts( &ctx, buf, buflen );
+ }
+ else
+ sha1_hmac_starts( &ctx, sha1_hmac_test_key[i],
+ sha1_hmac_test_keylen[i] );
+
+ sha1_hmac_update( &ctx, sha1_hmac_test_buf[i],
+ sha1_hmac_test_buflen[i] );
+
+ sha1_hmac_finish( &ctx, sha1sum );
+
+ buflen = ( i == 4 ) ? 12 : 20;
+
+ if( memcmp( sha1sum, sha1_hmac_test_sum[i], buflen ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n" );
+ }
+
+ if( verbose != 0 )
+ printf( "\n" );
+
+ return( 0 );
+}
+
+#endif
+
+#endif
+++ /dev/null
-/**
- * \file sha1.h
- *
- * Copyright (C) 2006-2010, Brainspark B.V.
- *
- * This file is part of PolarSSL (http://www.polarssl.org)
- * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
- *
- * 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef POLARSSL_SHA1_H
-#define POLARSSL_SHA1_H
-
-/**
- * \brief SHA-1 context structure
- */
-#ifndef HAVE_SHA1_CONTEXT
-#define HAVE_SHA1_CONTEXT
-typedef struct sha1_context sha1_context;
-#endif
-
-struct sha1_context
-{
- unsigned long total[2]; /*!< number of bytes processed */
- unsigned long state[5]; /*!< intermediate digest state */
- unsigned char buffer[64]; /*!< data block being processed */
-
- unsigned char ipad[64]; /*!< HMAC: inner padding */
- unsigned char opad[64]; /*!< HMAC: outer padding */
-};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \brief SHA-1 context setup
- *
- * \param ctx context to be initialized
- */
-void sha1_starts( sha1_context *ctx );
-
-/**
- * \brief SHA-1 process buffer
- *
- * \param ctx SHA-1 context
- * \param input buffer holding the data
- * \param ilen length of the input data
- */
-void sha1_update( sha1_context *ctx, const unsigned char *input, int ilen );
-
-/**
- * \brief SHA-1 final digest
- *
- * \param ctx SHA-1 context
- * \param output SHA-1 checksum result
- */
-void sha1_finish( sha1_context *ctx, unsigned char output[20] );
-
-/**
- * \brief Output = SHA-1( input buffer )
- *
- * \param input buffer holding the data
- * \param ilen length of the input data
- * \param output SHA-1 checksum result
- */
-void sha1( const unsigned char *input, int ilen, unsigned char output[20] );
-
-/**
- * \brief Output = SHA-1( file contents )
- *
- * \param path input file name
- * \param output SHA-1 checksum result
- *
- * \return 0 if successful, 1 if fopen failed,
- * or 2 if fread failed
- */
-int sha1_file( const char *path, unsigned char output[20] );
-
-/**
- * \brief SHA-1 HMAC context setup
- *
- * \param ctx HMAC context to be initialized
- * \param key HMAC secret key
- * \param keylen length of the HMAC key
- */
-void sha1_hmac_starts( sha1_context *ctx, const unsigned char *key, int keylen );
-
-/**
- * \brief SHA-1 HMAC process buffer
- *
- * \param ctx HMAC context
- * \param input buffer holding the data
- * \param ilen length of the input data
- */
-void sha1_hmac_update( sha1_context *ctx, const unsigned char *input, int ilen );
-
-/**
- * \brief SHA-1 HMAC final digest
- *
- * \param ctx HMAC context
- * \param output SHA-1 HMAC checksum result
- */
-void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] );
-
-/**
- * \brief SHA-1 HMAC context reset
- *
- * \param ctx HMAC context to be reset
- */
-void sha1_hmac_reset( sha1_context *ctx );
-
-/**
- * \brief Output = HMAC-SHA-1( hmac key, input buffer )
- *
- * \param key HMAC secret key
- * \param keylen length of the HMAC key
- * \param input buffer holding the data
- * \param ilen length of the input data
- * \param output HMAC-SHA-1 result
- */
-void sha1_hmac( const unsigned char *key, int keylen,
- const unsigned char *input, int ilen,
- unsigned char output[20] );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* sha1.h */
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
*/
-#include "sha2.h"
+#include "polarssl/config.h"
+
+#if defined(POLARSSL_SHA2_C)
+
+#include "polarssl/sha2.h"
#include <string.h>
#include <stdio.h>
memset( &ctx, 0, sizeof( sha2_context ) );
}
+
+#if defined(POLARSSL_SELF_TEST)
+/*
+ * FIPS-180-2 test vectors
+ */
+static unsigned char sha2_test_buf[3][57] =
+{
+ { "abc" },
+ { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
+ { "" }
+};
+
+static const int sha2_test_buflen[3] =
+{
+ 3, 56, 1000
+};
+
+static const unsigned char sha2_test_sum[6][32] =
+{
+ /*
+ * SHA-224 test vectors
+ */
+ { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22,
+ 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
+ 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7,
+ 0xE3, 0x6C, 0x9D, 0xA7 },
+ { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC,
+ 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
+ 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19,
+ 0x52, 0x52, 0x25, 0x25 },
+ { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8,
+ 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B,
+ 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE,
+ 0x4E, 0xE7, 0xAD, 0x67 },
+
+ /*
+ * SHA-256 test vectors
+ */
+ { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
+ 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
+ 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
+ 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
+ { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
+ 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
+ 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
+ 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
+ { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
+ 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
+ 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
+ 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }
+};
+
+/*
+ * RFC 4231 test vectors
+ */
+static unsigned char sha2_hmac_test_key[7][26] =
+{
+ { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
+ "\x0B\x0B\x0B\x0B" },
+ { "Jefe" },
+ { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
+ "\xAA\xAA\xAA\xAA" },
+ { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
+ "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
+ { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
+ "\x0C\x0C\x0C\x0C" },
+ { "" }, /* 0xAA 131 times */
+ { "" }
+};
+
+static const int sha2_hmac_test_keylen[7] =
+{
+ 20, 4, 20, 25, 20, 131, 131
+};
+
+static unsigned char sha2_hmac_test_buf[7][153] =
+{
+ { "Hi There" },
+ { "what do ya want for nothing?" },
+ { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
+ { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
+ "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
+ "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
+ "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
+ "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
+ { "Test With Truncation" },
+ { "Test Using Larger Than Block-Size Key - Hash Key First" },
+ { "This is a test using a larger than block-size key "
+ "and a larger than block-size data. The key needs to "
+ "be hashed before being used by the HMAC algorithm." }
+};
+
+static const int sha2_hmac_test_buflen[7] =
+{
+ 8, 28, 50, 50, 20, 54, 152
+};
+
+static const unsigned char sha2_hmac_test_sum[14][32] =
+{
+ /*
+ * HMAC-SHA-224 test vectors
+ */
+ { 0x89, 0x6F, 0xB1, 0x12, 0x8A, 0xBB, 0xDF, 0x19,
+ 0x68, 0x32, 0x10, 0x7C, 0xD4, 0x9D, 0xF3, 0x3F,
+ 0x47, 0xB4, 0xB1, 0x16, 0x99, 0x12, 0xBA, 0x4F,
+ 0x53, 0x68, 0x4B, 0x22 },
+ { 0xA3, 0x0E, 0x01, 0x09, 0x8B, 0xC6, 0xDB, 0xBF,
+ 0x45, 0x69, 0x0F, 0x3A, 0x7E, 0x9E, 0x6D, 0x0F,
+ 0x8B, 0xBE, 0xA2, 0xA3, 0x9E, 0x61, 0x48, 0x00,
+ 0x8F, 0xD0, 0x5E, 0x44 },
+ { 0x7F, 0xB3, 0xCB, 0x35, 0x88, 0xC6, 0xC1, 0xF6,
+ 0xFF, 0xA9, 0x69, 0x4D, 0x7D, 0x6A, 0xD2, 0x64,
+ 0x93, 0x65, 0xB0, 0xC1, 0xF6, 0x5D, 0x69, 0xD1,
+ 0xEC, 0x83, 0x33, 0xEA },
+ { 0x6C, 0x11, 0x50, 0x68, 0x74, 0x01, 0x3C, 0xAC,
+ 0x6A, 0x2A, 0xBC, 0x1B, 0xB3, 0x82, 0x62, 0x7C,
+ 0xEC, 0x6A, 0x90, 0xD8, 0x6E, 0xFC, 0x01, 0x2D,
+ 0xE7, 0xAF, 0xEC, 0x5A },
+ { 0x0E, 0x2A, 0xEA, 0x68, 0xA9, 0x0C, 0x8D, 0x37,
+ 0xC9, 0x88, 0xBC, 0xDB, 0x9F, 0xCA, 0x6F, 0xA8 },
+ { 0x95, 0xE9, 0xA0, 0xDB, 0x96, 0x20, 0x95, 0xAD,
+ 0xAE, 0xBE, 0x9B, 0x2D, 0x6F, 0x0D, 0xBC, 0xE2,
+ 0xD4, 0x99, 0xF1, 0x12, 0xF2, 0xD2, 0xB7, 0x27,
+ 0x3F, 0xA6, 0x87, 0x0E },
+ { 0x3A, 0x85, 0x41, 0x66, 0xAC, 0x5D, 0x9F, 0x02,
+ 0x3F, 0x54, 0xD5, 0x17, 0xD0, 0xB3, 0x9D, 0xBD,
+ 0x94, 0x67, 0x70, 0xDB, 0x9C, 0x2B, 0x95, 0xC9,
+ 0xF6, 0xF5, 0x65, 0xD1 },
+
+ /*
+ * HMAC-SHA-256 test vectors
+ */
+ { 0xB0, 0x34, 0x4C, 0x61, 0xD8, 0xDB, 0x38, 0x53,
+ 0x5C, 0xA8, 0xAF, 0xCE, 0xAF, 0x0B, 0xF1, 0x2B,
+ 0x88, 0x1D, 0xC2, 0x00, 0xC9, 0x83, 0x3D, 0xA7,
+ 0x26, 0xE9, 0x37, 0x6C, 0x2E, 0x32, 0xCF, 0xF7 },
+ { 0x5B, 0xDC, 0xC1, 0x46, 0xBF, 0x60, 0x75, 0x4E,
+ 0x6A, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xC7,
+ 0x5A, 0x00, 0x3F, 0x08, 0x9D, 0x27, 0x39, 0x83,
+ 0x9D, 0xEC, 0x58, 0xB9, 0x64, 0xEC, 0x38, 0x43 },
+ { 0x77, 0x3E, 0xA9, 0x1E, 0x36, 0x80, 0x0E, 0x46,
+ 0x85, 0x4D, 0xB8, 0xEB, 0xD0, 0x91, 0x81, 0xA7,
+ 0x29, 0x59, 0x09, 0x8B, 0x3E, 0xF8, 0xC1, 0x22,
+ 0xD9, 0x63, 0x55, 0x14, 0xCE, 0xD5, 0x65, 0xFE },
+ { 0x82, 0x55, 0x8A, 0x38, 0x9A, 0x44, 0x3C, 0x0E,
+ 0xA4, 0xCC, 0x81, 0x98, 0x99, 0xF2, 0x08, 0x3A,
+ 0x85, 0xF0, 0xFA, 0xA3, 0xE5, 0x78, 0xF8, 0x07,
+ 0x7A, 0x2E, 0x3F, 0xF4, 0x67, 0x29, 0x66, 0x5B },
+ { 0xA3, 0xB6, 0x16, 0x74, 0x73, 0x10, 0x0E, 0xE0,
+ 0x6E, 0x0C, 0x79, 0x6C, 0x29, 0x55, 0x55, 0x2B },
+ { 0x60, 0xE4, 0x31, 0x59, 0x1E, 0xE0, 0xB6, 0x7F,
+ 0x0D, 0x8A, 0x26, 0xAA, 0xCB, 0xF5, 0xB7, 0x7F,
+ 0x8E, 0x0B, 0xC6, 0x21, 0x37, 0x28, 0xC5, 0x14,
+ 0x05, 0x46, 0x04, 0x0F, 0x0E, 0xE3, 0x7F, 0x54 },
+ { 0x9B, 0x09, 0xFF, 0xA7, 0x1B, 0x94, 0x2F, 0xCB,
+ 0x27, 0x63, 0x5F, 0xBC, 0xD5, 0xB0, 0xE9, 0x44,
+ 0xBF, 0xDC, 0x63, 0x64, 0x4F, 0x07, 0x13, 0x93,
+ 0x8A, 0x7F, 0x51, 0x53, 0x5C, 0x3A, 0x35, 0xE2 }
+};
+
+/*
+ * Checkup routine
+ */
+int sha2_self_test( int verbose )
+{
+ int i, j, k, buflen;
+ unsigned char buf[1024];
+ unsigned char sha2sum[32];
+ sha2_context ctx;
+
+ for( i = 0; i < 6; i++ )
+ {
+ j = i % 3;
+ k = i < 3;
+
+ if( verbose != 0 )
+ printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 );
+
+ sha2_starts( &ctx, k );
+
+ if( j == 2 )
+ {
+ memset( buf, 'a', buflen = 1000 );
+
+ for( j = 0; j < 1000; j++ )
+ sha2_update( &ctx, buf, buflen );
+ }
+ else
+ sha2_update( &ctx, sha2_test_buf[j],
+ sha2_test_buflen[j] );
+
+ sha2_finish( &ctx, sha2sum );
+
+ if( memcmp( sha2sum, sha2_test_sum[i], 32 - k * 4 ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n" );
+ }
+
+ if( verbose != 0 )
+ printf( "\n" );
+
+ for( i = 0; i < 14; i++ )
+ {
+ j = i % 7;
+ k = i < 7;
+
+ if( verbose != 0 )
+ printf( " HMAC-SHA-%d test #%d: ", 256 - k * 32, j + 1 );
+
+ if( j == 5 || j == 6 )
+ {
+ memset( buf, '\xAA', buflen = 131 );
+ sha2_hmac_starts( &ctx, buf, buflen, k );
+ }
+ else
+ sha2_hmac_starts( &ctx, sha2_hmac_test_key[j],
+ sha2_hmac_test_keylen[j], k );
+
+ sha2_hmac_update( &ctx, sha2_hmac_test_buf[j],
+ sha2_hmac_test_buflen[j] );
+
+ sha2_hmac_finish( &ctx, sha2sum );
+
+ buflen = ( j == 4 ) ? 16 : 32 - k * 4;
+
+ if( memcmp( sha2sum, sha2_hmac_test_sum[i], buflen ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n" );
+ }
+
+ if( verbose != 0 )
+ printf( "\n" );
+
+ return( 0 );
+}
+
+#endif
+
+#endif
+++ /dev/null
-/**
- * \file sha2.h
- *
- * Copyright (C) 2006-2010, Brainspark B.V.
- *
- * This file is part of PolarSSL (http://www.polarssl.org)
- * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
- *
- * 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef POLARSSL_SHA2_H
-#define POLARSSL_SHA2_H
-
-/**
- * \brief SHA-256 context structure
- */
-#ifndef HAVE_SHA2_CONTEXT
-#define HAVE_SHA2_CONTEXT
-typedef struct sha2_context sha2_context;
-#endif
-
-struct sha2_context
-{
- unsigned long total[2]; /*!< number of bytes processed */
- unsigned long state[8]; /*!< intermediate digest state */
- unsigned char buffer[64]; /*!< data block being processed */
-
- unsigned char ipad[64]; /*!< HMAC: inner padding */
- unsigned char opad[64]; /*!< HMAC: outer padding */
- int is224; /*!< 0 => SHA-256, else SHA-224 */
-};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \brief SHA-256 context setup
- *
- * \param ctx context to be initialized
- * \param is224 0 = use SHA256, 1 = use SHA224
- */
-void sha2_starts( sha2_context *ctx, int is224 );
-
-/**
- * \brief SHA-256 process buffer
- *
- * \param ctx SHA-256 context
- * \param input buffer holding the data
- * \param ilen length of the input data
- */
-void sha2_update( sha2_context *ctx, const unsigned char *input, int ilen );
-
-/**
- * \brief SHA-256 final digest
- *
- * \param ctx SHA-256 context
- * \param output SHA-224/256 checksum result
- */
-void sha2_finish( sha2_context *ctx, unsigned char output[32] );
-
-/**
- * \brief Output = SHA-256( input buffer )
- *
- * \param input buffer holding the data
- * \param ilen length of the input data
- * \param output SHA-224/256 checksum result
- * \param is224 0 = use SHA256, 1 = use SHA224
- */
-void sha2( const unsigned char *input, int ilen,
- unsigned char output[32], int is224 );
-
-/**
- * \brief Output = SHA-256( file contents )
- *
- * \param path input file name
- * \param output SHA-224/256 checksum result
- * \param is224 0 = use SHA256, 1 = use SHA224
- *
- * \return 0 if successful, 1 if fopen failed,
- * or 2 if fread failed
- */
-int sha2_file( const char *path, unsigned char output[32], int is224 );
-
-/**
- * \brief SHA-256 HMAC context setup
- *
- * \param ctx HMAC context to be initialized
- * \param key HMAC secret key
- * \param keylen length of the HMAC key
- * \param is224 0 = use SHA256, 1 = use SHA224
- */
-void sha2_hmac_starts( sha2_context *ctx, const unsigned char *key, int keylen,
- int is224 );
-
-/**
- * \brief SHA-256 HMAC process buffer
- *
- * \param ctx HMAC context
- * \param input buffer holding the data
- * \param ilen length of the input data
- */
-void sha2_hmac_update( sha2_context *ctx, const unsigned char *input, int ilen );
-
-/**
- * \brief SHA-256 HMAC final digest
- *
- * \param ctx HMAC context
- * \param output SHA-224/256 HMAC checksum result
- */
-void sha2_hmac_finish( sha2_context *ctx, unsigned char output[32] );
-
-/**
- * \brief SHA-256 HMAC context reset
- *
- * \param ctx HMAC context to be reset
- */
-void sha2_hmac_reset( sha2_context *ctx );
-
-/**
- * \brief Output = HMAC-SHA-256( hmac key, input buffer )
- *
- * \param key HMAC secret key
- * \param keylen length of the HMAC key
- * \param input buffer holding the data
- * \param ilen length of the input data
- * \param output HMAC-SHA-224/256 result
- * \param is224 0 = use SHA256, 1 = use SHA224
- */
-void sha2_hmac( const unsigned char *key, int keylen,
- const unsigned char *input, int ilen,
- unsigned char output[32], int is224 );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* sha2.h */
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Functions that operate on the input queue. */
{
if (action == MSG_ADD_RECIPIENT)
{
+#ifdef SUPPORT_I18N
+ if (string_is_utf8(recipient)) allow_utf8_domains = message_smtputf8 = TRUE;
+#endif
receive_add_recipient(recipient, -1);
log_write(0, LOG_MAIN, "recipient <%s> added by %s",
recipient, username);
}
else /* MSG_EDIT_SENDER */
{
+#ifdef SUPPORT_I18N
+ if (string_is_utf8(recipient)) allow_utf8_domains = message_smtputf8 = TRUE;
+#endif
sender_address = recipient;
log_write(0, LOG_MAIN, "sender address changed to <%s> by %s",
recipient, username);
BOOL *set;
int sep = 0;
struct stat statbuf;
-uschar *s, *ss, *name;
+const uschar *s;
+uschar *ss, *name;
uschar buffer[1024];
if (queue_only_file == NULL) return;
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* This module contains code for extracting addresses from a forwarding list
*/
static int
-rda_write_string(int fd, uschar *s)
+rda_write_string(int fd, const uschar *s)
{
int len = (s == NULL)? 0 : Ustrlen(s) + 1;
return ( write(fd, &len, sizeof(int)) != sizeof(int)
{
DEBUG(D_rewrite) debug_printf("turned off address rewrite logging (not "
"root or exim in this process)\n");
- log_write_selector &= ~L_address_rewrite;
+ BIT_CLEAR(log_selector, log_selector_size, Li_address_rewrite);
}
/* Now do the business */
!= sizeof(addr->mode)
|| write(fd, &(addr->flags), sizeof(addr->flags))
!= sizeof(addr->flags)
- || rda_write_string(fd, addr->p.errors_address) != 0
+ || rda_write_string(fd, addr->prop.errors_address) != 0
)
goto bad;
if (read(fd, &(addr->mode), sizeof(addr->mode)) != sizeof(addr->mode) ||
read(fd, &(addr->flags), sizeof(addr->flags)) != sizeof(addr->flags) ||
- !rda_read_string(fd, &(addr->p.errors_address))) goto DISASTER;
+ !rda_read_string(fd, &(addr->prop.errors_address))) goto DISASTER;
/* Next comes a possible setting for $thisaddress and any numerical
variables for pipe expansion, terminated by a NULL string. The maximum
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Functions for reading the configuration file, and for displaying
#include "exim.h"
static void fn_smtp_receive_timeout(const uschar * name, const uschar * str);
-
+static void save_config_line(const uschar* line);
+static void save_config_position(const uschar *file, int line);
+static void print_config(BOOL admin);
#define CSTATE_STACK_SIZE 10
int lineno;
} config_file_item;
+/* Structure for chain of configuration lines (-bP config) */
+
+typedef struct config_line_item {
+ struct config_line_item *next;
+ uschar *line;
+} config_line_item;
+
+static config_line_item* config_lines;
+
/* Structure of table of conditional words and their state transitions */
typedef struct cond_item {
int value;
} syslog_fac_item;
+/* constants */
+static const char * const hidden = "<value not displayable>";
/* Static variables */
{ "dns_ipv4_lookup", opt_stringptr, &dns_ipv4_lookup },
{ "dns_retrans", opt_time, &dns_retrans },
{ "dns_retry", opt_int, &dns_retry },
+ { "dns_trust_aa", opt_stringptr, &dns_trust_aa },
{ "dns_use_edns0", opt_int, &dns_use_edns0 },
/* This option is now a no-op, retained for compability */
{ "drop_cr", opt_bool, &drop_cr },
{ "envelope_to_remove", opt_bool, &envelope_to_remove },
{ "errors_copy", opt_stringptr, &errors_copy },
{ "errors_reply_to", opt_stringptr, &errors_reply_to },
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
{ "event_action", opt_stringptr, &event_action },
#endif
{ "exim_group", opt_gid, &exim_gid },
{ "host_lookup_order", opt_stringptr, &host_lookup_order },
{ "host_reject_connection", opt_stringptr, &host_reject_connection },
{ "hosts_connection_nolog", opt_stringptr, &hosts_connection_nolog },
+#ifdef SUPPORT_PROXY
+ { "hosts_proxy", opt_stringptr, &hosts_proxy },
+#endif
{ "hosts_treat_as_local", opt_stringptr, &hosts_treat_as_local },
#ifdef LOOKUP_IBASE
{ "ibase_servers", opt_stringptr, &ibase_servers },
{ "print_topbitchars", opt_bool, &print_topbitchars },
{ "process_log_path", opt_stringptr, &process_log_path },
{ "prod_requires_admin", opt_bool, &prod_requires_admin },
-#ifdef EXPERIMENTAL_PROXY
- { "proxy_required_hosts", opt_stringptr, &proxy_required_hosts },
-#endif
{ "qualify_domain", opt_stringptr, &qualify_domain_sender },
{ "qualify_recipient", opt_stringptr, &qualify_domain_recipient },
{ "queue_domains", opt_stringptr, &queue_domains },
{ "recipient_unqualified_hosts", opt_stringptr, &recipient_unqualified_hosts },
{ "recipients_max", opt_int, &recipients_max },
{ "recipients_max_reject", opt_bool, &recipients_max_reject },
-#ifdef EXPERIMENTAL_REDIS
+#ifdef LOOKUP_REDIS
{ "redis_servers", opt_stringptr, &redis_servers },
#endif
{ "remote_max_parallel", opt_int, &remote_max_parallel },
{ "rfc1413_hosts", opt_stringptr, &rfc1413_hosts },
{ "rfc1413_query_timeout", opt_time, &rfc1413_query_timeout },
{ "sender_unqualified_hosts", opt_stringptr, &sender_unqualified_hosts },
+ { "slow_lookup_log", opt_int, &slow_lookup_log },
{ "smtp_accept_keepalive", opt_bool, &smtp_accept_keepalive },
{ "smtp_accept_max", opt_int, &smtp_accept_max },
{ "smtp_accept_max_nonmail", opt_int, &smtp_accept_max_nonmail },
{ "smtp_receive_timeout", opt_func, &fn_smtp_receive_timeout },
{ "smtp_reserve_hosts", opt_stringptr, &smtp_reserve_hosts },
{ "smtp_return_error_details",opt_bool, &smtp_return_error_details },
+#ifdef SUPPORT_I18N
+ { "smtputf8_advertise_hosts", opt_stringptr, &smtputf8_advertise_hosts },
+#endif
#ifdef WITH_CONTENT_SCAN
{ "spamd_address", opt_stringptr, &spamd_address },
#endif
#endif
{ "timeout_frozen_after", opt_time, &timeout_frozen_after },
{ "timezone", opt_stringptr, &timezone_string },
-#ifdef SUPPORT_TLS
{ "tls_advertise_hosts", opt_stringptr, &tls_advertise_hosts },
+#ifdef SUPPORT_TLS
{ "tls_certificate", opt_stringptr, &tls_certificate },
{ "tls_crl", opt_stringptr, &tls_crl },
{ "tls_dh_max_bits", opt_int, &tls_dh_max_bits },
{ "tls_dhparam", opt_stringptr, &tls_dhparam },
+ { "tls_eccurve", opt_stringptr, &tls_eccurve },
# ifndef DISABLE_OCSP
{ "tls_ocsp_file", opt_stringptr, &tls_ocsp_file },
# endif
config_filename = config_file_stack->filename;
config_lineno = config_file_stack->lineno;
config_file_stack = config_file_stack->next;
+ if (config_lines)
+ save_config_position(config_filename, config_lineno);
continue;
}
config_lineno++;
newlen = len + Ustrlen(big_buffer + len);
+ if (config_lines && config_lineno == 1)
+ save_config_position(config_filename, config_lineno);
+
/* Handle pathologically long physical lines - yes, it did happen - by
extending big_buffer at this point. The code also copes with very long
logical lines. */
if (include_if_exists != 0 && (Ustat(ss, &statbuf) != 0)) continue;
+ if (config_lines)
+ save_config_position(config_filename, config_lineno);
save = store_get(sizeof(config_file_item));
save->next = config_file_stack;
config_file_stack = save;
section names do fit. Leave space for pluralizing. */
s = big_buffer + startoffset; /* First non-space character */
+
+if (config_lines)
+ save_config_line(s);
+
if (strncmpic(s, US"begin ", 6) == 0)
{
s += 6;
*/
static int
-readconf_readfixed(uschar *s, int terminator)
+readconf_readfixed(const uschar *s, int terminator)
{
int yield = 0;
int value, count;
*/
static void
-extra_chars_error(uschar *s, uschar *t1, uschar *t2, uschar *t3)
+extra_chars_error(const uschar *s, const uschar *t1, const uschar *t2, const uschar *t3)
{
uschar *comment = US"";
if (*s == '#') comment = US" (# is comment only at line start)";
*/
static rewrite_rule *
-readconf_one_rewrite(uschar *p, int *existflags, BOOL isglobal)
+readconf_one_rewrite(const uschar *p, int *existflags, BOOL isglobal)
{
rewrite_rule *next = store_get(sizeof(rewrite_rule));
*/
static uschar *
-read_string(uschar *s, uschar *name)
+read_string(const uschar *s, const uschar *name)
{
uschar *yield;
-uschar *ss;
+const uschar *ss;
if (*s != '\"') return string_copy(s);
static void
fn_smtp_receive_timeout(const uschar * name, const uschar * str)
{
-int value;
-
if (*str == '$')
smtp_receive_timeout_s = string_copy(str);
else
}
else if (ol->type & opt_rep_str)
{
- uschar sep = Ustrncmp(name, "headers_add", 11)==0 ? '\n' : ':';
- uschar * cp;
-
- /* Strip trailing whitespace and seperators */
- for (cp = sptr + Ustrlen(sptr) - 1;
- cp >= sptr && (*cp == '\n' || *cp == '\t' || *cp == ' ' || *cp == sep);
- cp--) *cp = '\0';
-
- if (cp >= sptr)
- *str_target = string_copy_malloc(
- *str_target ? string_sprintf("%s%c%s", *str_target, sep, sptr)
- : sptr);
+ uschar sep_o = Ustrncmp(name, "headers_add", 11)==0 ? '\n' : ':';
+ int sep_i = -(int)sep_o;
+ const uschar * list = sptr;
+ uschar * s;
+ uschar * list_o = *str_target;
+
+ while ((s = string_nextinlist(&list, &sep_i, NULL, 0)))
+ list_o = string_append_listele(list_o, sep_o, s);
+ if (list_o)
+ *str_target = string_copy_malloc(list_o);
}
else
{
flagptr = (int *)((uschar *)data_block + (long int)(ol3->value));
}
- while ((p = string_nextinlist(&sptr, &sep, big_buffer, BIG_BUFFER_SIZE))
- != NULL)
+ while ((p = string_nextinlist(CUSS &sptr, &sep, big_buffer, BIG_BUFFER_SIZE)))
{
rewrite_rule *next = readconf_one_rewrite(p, flagptr, FALSE);
*chain = next;
int count = 1;
uid_t *list;
int ptr = 0;
- uschar *p;
- uschar *op = expand_string (sptr);
+ const uschar *p;
+ const uschar *op = expand_string (sptr);
if (op == NULL)
log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "failed to expand %s: %s",
int count = 1;
gid_t *list;
int ptr = 0;
- uschar *p;
- uschar *op = expand_string (sptr);
+ const uschar *p;
+ const uschar *op = expand_string (sptr);
if (op == NULL)
log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "failed to expand %s: %s",
if (!admin_user && (ol->type & opt_secure) != 0)
{
- const char * const hidden = "<value not displayable>";
if (no_labels)
printf("%s\n", hidden);
else
second argument is NULL. There are some special values:
all print all main configuration options
- configure_file print the name of the configuration file
+ config_file print the name of the configuration file
+ (configure_file will still work, for backward
+ compatibility)
routers print the routers' configurations
transports print the transports' configuration
authenticators print the authenticators' configuration
macro_list print a list of macro names
+name print a named list item
local_scan print the local_scan options
+ config print the configuration as it is parsed
If the second argument is not NULL, it must be one of "router", "transport",
"authenticator" or "macro" in which case the first argument identifies the
return;
}
- if (Ustrcmp(name, "configure_file") == 0)
+ if ( Ustrcmp(name, "configure_file") == 0
+ ||Ustrcmp(name, "config_file") == 0)
{
printf("%s\n", CS config_main_filename);
return;
return;
}
+ if (Ustrcmp(name, "config") == 0)
+ {
+ print_config(admin_user);
+ return;
+ }
+
if (Ustrcmp(name, "routers") == 0)
{
type = US"router";
int rc, status;
void (*oldsignal)(int);
+/* If TLS will never be used, no point checking ciphers */
+
+if ( !tls_advertise_hosts
+ || !*tls_advertise_hosts
+ || Ustrcmp(tls_advertise_hosts, ":") == 0
+ )
+ return TRUE;
+else if (!tls_certificate)
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "Warning: No server certificate defined; TLS connections will fail.\n"
+ " Suggested action: either install a certificate or change tls_advertise_hosts option");
+
oldsignal = signal(SIGCHLD, SIG_DFL);
fflush(NULL);
int sep = 0;
struct stat statbuf;
uschar *s, *filename;
-uschar *list = config_main_filelist;
+const uschar *list = config_main_filelist;
/* Loop through the possible file names */
config_filename = config_main_filename = string_copy(filename);
p = Ustrrchr(filename, '/');
- config_main_directory = p ? string_copyn(filename, p - filename)
+ config_main_directory = p ? string_copyn(filename, p - filename)
: string_copy(US".");
}
else
if (primary_hostname == NULL)
{
- uschar *hostname;
+ const uschar *hostname;
struct utsname uts;
if (uname(&uts) < 0)
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "uname() failed to yield host name");
#if HAVE_IPV6
if (!disable_ipv6 && (dns_ipv4_lookup == NULL ||
- match_isinlist(hostname, &dns_ipv4_lookup, 0, NULL, NULL, MCL_DOMAIN,
- TRUE, NULL) != OK))
+ match_isinlist(hostname, CUSS &dns_ipv4_lookup, 0, NULL, NULL,
+ MCL_DOMAIN, TRUE, NULL) != OK))
af = AF_INET6;
#else
af = AF_INET;
if (*log_file_path != 0)
{
- uschar *ss, *sss;
+ const uschar *ss, *sss;
int sep = ':'; /* Fixed for log file path */
s = expand_string(log_file_path);
if (s == NULL)
*/
uschar *
-readconf_retry_error(uschar *pp, uschar *p, int *basic_errno, int *more_errno)
+readconf_retry_error(const uschar *pp, const uschar *p,
+ int *basic_errno, int *more_errno)
{
int len;
-uschar *q = pp;
+const uschar *q = pp;
while (q < p && *q != '_') q++;
len = q - pp;
{
int i;
int xlen = p - q - 1;
- uschar *x = q + 1;
+ const uschar *x = q + 1;
static uschar *extras[] =
{ US"A", US"MX", US"connect", US"connect_A", US"connect_MX" };
{ 'A', 'M', RTEF_CTOUT, RTEF_CTOUT|'A', RTEF_CTOUT|'M' };
for (i = 0; i < sizeof(extras)/sizeof(uschar *); i++)
- {
if (strncmpic(x, extras[i], xlen) == 0)
{
*more_errno = values[i];
break;
}
- }
if (i >= sizeof(extras)/sizeof(uschar *))
- {
if (strncmpic(x, US"DNS", xlen) == 0)
- {
log_write(0, LOG_MAIN|LOG_PANIC, "\"timeout_dns\" is no longer "
"available in retry rules (it has never worked) - treated as "
"\"timeout\"");
- }
- else return US"\"A\", \"MX\", or \"connect\" expected after \"timeout\"";
- }
+ else
+ return US"\"A\", \"MX\", or \"connect\" expected after \"timeout\"";
}
}
return string_sprintf("%.4s_4 must be followed by xx, dx, or dd, where "
"x is literal and d is any digit", pp);
- *basic_errno = (*pp == 'm')? ERRNO_MAIL4XX :
- (*pp == 'r')? ERRNO_RCPT4XX : ERRNO_DATA4XX;
+ *basic_errno = *pp == 'm' ? ERRNO_MAIL4XX :
+ *pp == 'r' ? ERRNO_RCPT4XX : ERRNO_DATA4XX;
*more_errno = x << 8;
}
else if (strncmpic(pp, US"tls_required", p - pp) == 0)
*basic_errno = ERRNO_TLSREQUIRED;
+else if (strncmpic(pp, US"lookup", p - pp) == 0)
+ *basic_errno = ERRNO_UNKNOWNHOST;
+
else if (len != 1 || Ustrncmp(pp, "*", 1) != 0)
return string_sprintf("unknown or malformed retry error \"%.*s\"", (int) (p-pp), pp);
*/
static int
-retry_arg(uschar **paddr, int type)
+retry_arg(const uschar **paddr, int type)
{
-uschar *p = *paddr;
-uschar *pp;
+const uschar *p = *paddr;
+const uschar *pp;
if (*p++ != ',') log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "comma expected");
*paddr = p;
switch (type)
{
- case 0:
- return readconf_readtime(pp, *p, FALSE);
- case 1:
- return readconf_readfixed(pp, *p);
+ case 0: return readconf_readtime(pp, *p, FALSE);
+ case 1: return readconf_readfixed(pp, *p);
}
return 0; /* Keep picky compilers happy */
}
{
retry_config **chain = &retries;
retry_config *next;
-uschar *p;
+const uschar *p;
-while ((p = get_config_line()) != NULL)
+while ((p = get_config_line()))
{
retry_rule **rchain;
- uschar *pp, *error;
+ const uschar *pp;
+ uschar *error;
next = store_get(sizeof(retry_config));
next->next = NULL;
/* Test error names for things we understand. */
- if ((error = readconf_retry_error(pp, p, &(next->basic_errno),
- &(next->more_errno))) != NULL)
+ if ((error = readconf_retry_error(pp, p, &next->basic_errno,
+ &next->more_errno)))
log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "%s", error);
/* There may be an optional address list of senders to be used as another
switch (rule->rule)
{
case 'F': /* Fixed interval */
- rule->p1 = retry_arg(&p, 0);
- break;
+ rule->p1 = retry_arg(&p, 0);
+ break;
case 'G': /* Geometrically increasing intervals */
case 'H': /* Ditto, but with randomness */
- rule->p1 = retry_arg(&p, 0);
- rule->p2 = retry_arg(&p, 1);
- break;
+ rule->p1 = retry_arg(&p, 0);
+ rule->p2 = retry_arg(&p, 1);
+ break;
default:
- log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "unknown retry rule letter");
- break;
+ log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "unknown retry rule letter");
+ break;
}
if (rule->timeout <= 0 || rule->p1 <= 0 ||
(void)fclose(config_file);
}
+/* Init the storage for the pre-parsed config lines */
+void
+readconf_save_config(const uschar *s)
+{
+ save_config_line(string_sprintf("# Exim Configuration (%s)",
+ running_in_test_harness ? US"X" : s));
+}
+
+static void
+save_config_position(const uschar *file, int line)
+{
+ save_config_line(string_sprintf("# %d \"%s\"", line, file));
+}
+
+/* Append a pre-parsed logical line to the config lines store,
+this operates on a global (static) list that holds all the pre-parsed
+config lines, we do no further processing here, output formatting and
+honouring of <hide> or macros will be done during output */
+static void
+save_config_line(const uschar* line)
+{
+static config_line_item *current;
+config_line_item *next;
+
+next = (config_line_item*) store_get(sizeof(config_line_item));
+next->line = string_copy(line);
+next->next = NULL;
+
+if (!config_lines) config_lines = next;
+else current->next = next;
+
+current = next;
+}
+
+/* List the parsed config lines, care about nice formatting and
+hide the <hide> values unless we're the admin user */
+void
+print_config(BOOL admin)
+{
+config_line_item *i;
+const int TS = 2;
+int indent = 0;
+
+for (i = config_lines; i; i = i->next)
+ {
+ uschar *current;
+ uschar *p;
+
+ /* skip over to the first non-space */
+ for (current = i->line; *current && isspace(*current); ++current)
+ ;
+
+ if (*current == '\0')
+ continue;
+
+ /* Collapse runs of spaces. We stop this if we encounter one of the
+ * following characters: "'$, as this may indicate careful formatting */
+ for (p = current; *p; ++p)
+ {
+ uschar *next;
+ if (!isspace(*p)) continue;
+ if (*p != ' ') *p = ' ';
+
+ for (next = p; isspace(*next); ++next)
+ ;
+
+ if (next - p > 1)
+ memmove(p+1, next, strlen(next)+1);
+
+ if (*next == '"' || *next == '\'' || *next == '$')
+ break;
+ }
+
+ /* # lines */
+ if (current[0] == '#')
+ puts(CCS current);
+
+ /* begin lines are left aligned */
+ else if (Ustrncmp(current, "begin", 5) == 0 && isspace(current[5]))
+ {
+ puts("");
+ puts(CCS current);
+ indent = TS;
+ }
+
+ /* router/acl/transport block names */
+ else if (current[Ustrlen(current)-1] == ':' && !Ustrchr(current, '='))
+ {
+ printf("\n%*s%s\n", TS, "", current);
+ indent = 2 * TS;
+ }
+
+ /* hidden lines (all MACROS or lines prefixed with "hide") */
+ else if ( !admin
+ && ( isupper(*current)
+ || Ustrncmp(current, "hide", 4) == 0 && isspace(current[4])
+ )
+ )
+ {
+ if ((p = Ustrchr(current, '=')))
+ {
+ *p = '\0';
+ printf("%*s%s= %s\n", indent, "", current, hidden);
+ }
+ /* e.g.: hide split_spool_directory */
+ else
+ printf("%*s\n", indent, hidden);
+ }
+
+ else
+ /* rest is public */
+ printf("%*s%s\n", indent, "", current);
+ }
+}
+
/* vi: aw ai sw=2
*/
/* End of readconf.c */
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Code for receiving a message and setting up spool files. */
qnewsender = (Ustrchr(newsender, '@') != NULL)?
newsender : string_sprintf("%s@%s", newsender, qualify_domain_sender);
return
- match_address_list(qnewsender, TRUE, TRUE, &untrusted_set_sender, NULL, -1,
+ match_address_list(qnewsender, TRUE, TRUE, CUSS &untrusted_set_sender, NULL, -1,
0, NULL) == OK;
}
else
{
int sep = ':'; /* Not variable - outside scripts use */
- uschar *p = log_file_path;
+ const uschar *p = log_file_path;
name = US"log";
/* An empty log_file_path means "use the default". This is the same as an
empty item in a list. */
if (*p == 0) p = US":";
- while ((path = string_nextinlist(&p, &sep, buffer, sizeof(buffer))) != NULL)
- {
- if (Ustrcmp(path, "syslog") != 0) break;
- }
+ while ((path = string_nextinlist(&p, &sep, buffer, sizeof(buffer))))
+ if (Ustrcmp(path, "syslog") != 0)
+ break;
if (path == NULL) /* No log files */
{
case ACL_WHERE_DKIM:
case ACL_WHERE_MIME:
case ACL_WHERE_DATA:
- if (cutthrough_fd >= 0 && (acl_removed_headers || acl_added_headers))
+ if (cutthrough.fd >= 0 && (acl_removed_headers || acl_added_headers))
{
log_write(0, LOG_MAIN|LOG_PANIC, "Header modification in data ACLs"
" will not take effect on cutthrough deliveries");
{
DEBUG(D_receive|D_acl) debug_printf(">>Headers removed by %s ACL:\n", acl_name);
- for (h = header_list; h != NULL; h = h->next)
+ for (h = header_list; h != NULL; h = h->next) if (h->type != htype_old)
{
- uschar *list;
- BOOL include_header;
-
- if (h->type == htype_old) continue;
-
- include_header = TRUE;
- list = acl_removed_headers;
-
+ const uschar * list = acl_removed_headers;
int sep = ':'; /* This is specified as a colon-separated list */
uschar *s;
uschar buffer[128];
- while ((s = string_nextinlist(&list, &sep, buffer, sizeof(buffer)))
- != NULL)
- {
- int len = Ustrlen(s);
- if (header_testname(h, s, len, FALSE))
+
+ while ((s = string_nextinlist(&list, &sep, buffer, sizeof(buffer))))
+ if (header_testname(h, s, Ustrlen(s), FALSE))
{
h->type = htype_old;
DEBUG(D_receive|D_acl) debug_printf(" %s", h->text);
}
- }
}
acl_removed_headers = NULL;
DEBUG(D_receive|D_acl) debug_printf(">>\n");
if (sender_fullhost != NULL)
{
s = string_append(s, sizeptr, ptrptr, 2, US" H=", sender_fullhost);
- if ((log_extra_selector & LX_incoming_interface) != 0 &&
- interface_address != NULL)
+ if (LOGGING(incoming_interface) && interface_address != NULL)
{
uschar *ss = string_sprintf(" I=[%s]:%d", interface_address,
interface_port);
pp = recipient = store_get(ss - s + 1);
for (p = s; p < ss; p++) if (*p != '\n') *pp++ = *p;
*pp = 0;
+
+#ifdef SUPPORT_I18N
+ {
+ BOOL b = allow_utf8_domains;
+ allow_utf8_domains = TRUE;
+#endif
recipient = parse_extract_address(recipient, &errmess, &start, &end,
&domain, FALSE);
+#ifdef SUPPORT_I18N
+ if (string_is_utf8(recipient))
+ message_smtputf8 = TRUE;
+ else
+ allow_utf8_domains = b;
+ }
+#endif
+
/* Keep a list of all the bad addresses so we can send a single
error message at the end. However, an empty address is not an error;
just ignore it. This can come from an empty group list like
rewriting. Must copy the count, because later ACLs and the local_scan()
function may mess with the real recipients. */
-if ((log_extra_selector & LX_received_recipients) != 0)
+if (LOGGING(received_recipients))
{
raw_recipients = store_get(recipients_count * sizeof(uschar *));
for (i = 0; i < recipients_count; i++)
}
/* Cutthrough delivery:
- We have to create the Received header now rather than at the end of reception,
- so the timestamp behaviour is a change to the normal case.
- XXX Ensure this gets documented XXX.
- Having created it, send the headers to the destination.
-*/
-if (cutthrough_fd >= 0)
+We have to create the Received header now rather than at the end of reception,
+so the timestamp behaviour is a change to the normal case.
+XXX Ensure this gets documented XXX.
+Having created it, send the headers to the destination. */
+if (cutthrough.fd >= 0)
{
if (received_count > received_headers_max)
{
else
{
int sep = 0;
- uschar *ptr = dkim_verify_signers_expanded;
+ const uschar *ptr = dkim_verify_signers_expanded;
uschar *item = NULL;
uschar *seen_items = NULL;
int seen_items_size = 0;
rc = OK;
while ((item = string_nextinlist(&ptr, &sep,
itembuf,
- sizeof(itembuf))) != NULL)
+ sizeof(itembuf))))
{
/* Prevent running ACL for an empty item */
if (!item || (item[0] == '\0')) continue;
- /* Only run ACL once for each domain or identity, no matter how often it
- appears in the expanded list. */
- if (seen_items != NULL)
+
+ /* Only run ACL once for each domain or identity,
+ no matter how often it appears in the expanded list. */
+ if (seen_items)
{
uschar *seen_item = NULL;
uschar seen_item_buf[256];
- uschar *seen_items_list = seen_items;
- int seen_this_item = 0;
+ const uschar *seen_items_list = seen_items;
+ BOOL seen_this_item = FALSE;
while ((seen_item = string_nextinlist(&seen_items_list, &sep,
seen_item_buf,
- sizeof(seen_item_buf))) != NULL)
- {
- if (Ustrcmp(seen_item,item) == 0)
- {
- seen_this_item = 1;
- break;
- }
- }
-
- if (seen_this_item > 0)
+ sizeof(seen_item_buf))))
+ if (Ustrcmp(seen_item,item) == 0)
+ {
+ seen_this_item = TRUE;
+ break;
+ }
+
+ if (seen_this_item)
{
DEBUG(D_receive)
- debug_printf("acl_smtp_dkim: skipping signer %s, already seen\n", item);
+ debug_printf("acl_smtp_dkim: skipping signer %s, "
+ "already seen\n", item);
continue;
}
- seen_items = string_append(seen_items,&seen_items_size,&seen_items_offset,1,":");
+ seen_items = string_append(seen_items, &seen_items_size,
+ &seen_items_offset, 1, ":");
}
- seen_items = string_append(seen_items,&seen_items_size,&seen_items_offset,1,item);
+ seen_items = string_append(seen_items, &seen_items_size,
+ &seen_items_offset, 1, item);
seen_items[seen_items_offset] = '\0';
DEBUG(D_receive)
- debug_printf("calling acl_smtp_dkim for dkim_cur_signer=%s\n", item);
+ debug_printf("calling acl_smtp_dkim for dkim_cur_signer=%s\n",
+ item);
dkim_exim_acl_setup(item);
- rc = acl_check(ACL_WHERE_DKIM, NULL, acl_smtp_dkim, &user_msg, &log_msg);
+ rc = acl_check(ACL_WHERE_DKIM, NULL, acl_smtp_dkim,
+ &user_msg, &log_msg);
if (rc != OK)
- {
- DEBUG(D_receive)
- debug_printf("acl_smtp_dkim: acl_check returned %d on %s, skipping remaining items\n", rc, item);
- cancel_cutthrough_connection("dkim acl not ok");
- break;
- }
+ {
+ DEBUG(D_receive)
+ debug_printf("acl_smtp_dkim: acl_check returned %d on %s, "
+ "skipping remaining items\n", rc, item);
+ cancel_cutthrough_connection("dkim acl not ok");
+ break;
+ }
}
add_acl_headers(ACL_WHERE_DKIM, US"DKIM");
if (rc == DISCARD)
goto TEMPREJECT;
case LOCAL_SCAN_REJECT_NOLOGHDR:
- log_extra_selector &= ~LX_rejected_header;
+ BIT_CLEAR(log_selector, log_selector_size, Li_rejected_header);
/* Fall through */
case LOCAL_SCAN_REJECT:
break;
case LOCAL_SCAN_TEMPREJECT_NOLOGHDR:
- log_extra_selector &= ~LX_rejected_header;
+ BIT_CLEAR(log_selector, log_selector_size, Li_rejected_header);
/* Fall through */
case LOCAL_SCAN_TEMPREJECT:
s = add_host_info_for_log(s, &size, &sptr);
#ifdef SUPPORT_TLS
-if (log_extra_selector & LX_tls_cipher && tls_in.cipher)
+if (LOGGING(tls_cipher) && tls_in.cipher)
s = string_append(s, &size, &sptr, 2, US" X=", tls_in.cipher);
-if (log_extra_selector & LX_tls_certificate_verified && tls_in.cipher)
+if (LOGGING(tls_certificate_verified) && tls_in.cipher)
s = string_append(s, &size, &sptr, 2, US" CV=",
tls_in.certificate_verified? "yes":"no");
-if (log_extra_selector & LX_tls_peerdn && tls_in.peerdn)
+if (LOGGING(tls_peerdn) && tls_in.peerdn)
s = string_append(s, &size, &sptr, 3, US" DN=\"",
string_printing(tls_in.peerdn), US"\"");
-if (log_extra_selector & LX_tls_sni && tls_in.sni)
+if (LOGGING(tls_sni) && tls_in.sni)
s = string_append(s, &size, &sptr, 3, US" SNI=\"",
string_printing(tls_in.sni), US"\"");
#endif
if (authenticated_id != NULL)
{
s = string_append(s, &size, &sptr, 2, US":", authenticated_id);
- if (log_extra_selector & LX_smtp_mailauth && authenticated_sender != NULL)
+ if (LOGGING(smtp_mailauth) && authenticated_sender != NULL)
s = string_append(s, &size, &sptr, 2, US":", authenticated_sender);
}
}
s = string_append(s, &size, &sptr, 1, US" PRDR");
#endif
-#ifdef EXPERIMENTAL_PROXY
-if (proxy_session && log_extra_selector & LX_proxy)
- s = string_append(s, &size, &sptr, 2, US" PRX=", proxy_host_address);
+#ifdef SUPPORT_PROXY
+if (proxy_session && LOGGING(proxy))
+ s = string_append(s, &size, &sptr, 2, US" PRX=", proxy_local_address);
#endif
sprintf(CS big_buffer, "%d", msg_size);
0 ... no BODY= used
7 ... 7BIT
8 ... 8BITMIME */
-if (log_extra_selector & LX_8bitmime)
+if (LOGGING(8bitmime))
{
sprintf(CS big_buffer, "%d", body_8bitmime);
s = string_append(s, &size, &sptr, 2, US" M8S=", big_buffer);
/* If subject logging is turned on, create suitable printing-character
text. By expanding $h_subject: we make use of the MIME decoding. */
-if ((log_extra_selector & LX_subject) != 0 && subject_header != NULL)
+if (LOGGING(subject) && subject_header != NULL)
{
int i;
uschar *p = big_buffer;
XXX We do not handle queue-only, freezing, or blackholes.
*/
-if(cutthrough_fd >= 0)
+if(cutthrough.fd >= 0)
{
uschar * msg= cutthrough_finaldot(); /* Ask the target system to accept the messsage */
/* Logging was done in finaldot() */
#endif
{
log_write(0, LOG_MAIN |
- (((log_extra_selector & LX_received_recipients) != 0)? LOG_RECIPIENTS : 0) |
- (((log_extra_selector & LX_received_sender) != 0)? LOG_SENDER : 0),
+ (LOGGING(received_recipients)? LOG_RECIPIENTS : 0) |
+ (LOGGING(received_sender)? LOG_SENDER : 0),
"%s", s);
/* Log any control actions taken by an ACL or local_scan(). */
case TMP_REJ: message_id[0] = 0; /* Prevent a delivery from starting */
default:break;
}
- cutthrough_delivery = FALSE;
+ cutthrough.delivery = FALSE;
}
/* For batched SMTP, generate an error message on failure, and do
if (blackholed_by != NULL)
{
- uschar *detail = (local_scan_data != NULL)?
- string_printing(local_scan_data) :
- string_sprintf("(%s discarded recipients)", blackholed_by);
+ const uschar *detail = local_scan_data
+ ? string_printing(local_scan_data)
+ : string_sprintf("(%s discarded recipients)", blackholed_by);
log_write(0, LOG_MAIN, "=> blackhole %s%s", detail, blackhole_log_msg);
log_write(0, LOG_MAIN, "Completed");
message_id[0] = 0;
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) Tom Kistner <tom@duncanthrax.net> 2003-???? */
+/* Copyright (c) Tom Kistner <tom@duncanthrax.net> 2003-2015 */
/* License: GPL */
/* Code for matching regular expressions against headers and body.
extern FILE *mime_stream;
extern uschar *mime_current_boundary;
-int regex(uschar **listptr) {
- int sep = 0;
- uschar *list = *listptr;
- uschar *regex_string;
- uschar regex_string_buffer[1024];
- unsigned long mbox_size;
- FILE *mbox_file;
- pcre *re;
- pcre_list *re_list_head = NULL;
- pcre_list *re_list_item;
- const char *pcre_error;
- int pcre_erroffset;
- uschar *linebuffer;
- long f_pos = 0;
-
- /* reset expansion variable */
- regex_match_string = NULL;
-
- if (mime_stream == NULL) {
- /* We are in the DATA ACL */
- mbox_file = spool_mbox(&mbox_size, NULL);
- if (mbox_file == NULL) {
- /* error while spooling */
- log_write(0, LOG_MAIN|LOG_PANIC,
- "regex acl condition: error while creating mbox spool file");
- return DEFER;
- };
- }
- else {
- f_pos = ftell(mime_stream);
- mbox_file = mime_stream;
- };
-
- /* precompile our regexes */
- while ((regex_string = string_nextinlist(&list, &sep,
- regex_string_buffer,
- sizeof(regex_string_buffer))) != NULL) {
-
- /* parse option */
- if ( (strcmpic(regex_string,US"false") == 0) ||
- (Ustrcmp(regex_string,"0") == 0) ) {
- /* explicitly no matching */
- continue;
- };
+static pcre_list *
+compile(const uschar * list)
+{
+int sep = 0;
+uschar *regex_string;
+const char *pcre_error;
+int pcre_erroffset;
+pcre_list *re_list_head = NULL;
+pcre_list *ri;
+
+/* precompile our regexes */
+while ((regex_string = string_nextinlist(&list, &sep, NULL, 0)))
+ if (strcmpic(regex_string, US"false") != 0 && Ustrcmp(regex_string, "0") != 0)
+ {
+ pcre *re;
/* compile our regular expression */
- re = pcre_compile( CS regex_string,
- 0,
- &pcre_error,
- &pcre_erroffset,
- NULL );
-
- if (re == NULL) {
+ if (!(re = pcre_compile( CS regex_string,
+ 0, &pcre_error, &pcre_erroffset, NULL )))
+ {
log_write(0, LOG_MAIN,
- "regex acl condition warning - error in regex '%s': %s at offset %d, skipped.", regex_string, pcre_error, pcre_erroffset);
+ "regex acl condition warning - error in regex '%s': %s at offset %d, skipped.",
+ regex_string, pcre_error, pcre_erroffset);
continue;
+ }
+
+ ri = store_get(sizeof(pcre_list));
+ ri->re = re;
+ ri->pcre_text = regex_string;
+ ri->next = re_list_head;
+ re_list_head = ri;
}
- else {
- re_list_item = store_get(sizeof(pcre_list));
- re_list_item->re = re;
- re_list_item->pcre_text = string_copy(regex_string);
- re_list_item->next = re_list_head;
- re_list_head = re_list_item;
- };
- };
-
- /* no regexes -> nothing to do */
- if (re_list_head == NULL) {
- return FAIL;
- };
-
- /* match each line against all regexes */
- linebuffer = store_get(32767);
- while (fgets(CS linebuffer, 32767, mbox_file) != NULL) {
- if ( (mime_stream != NULL) && (mime_current_boundary != NULL) ) {
- /* check boundary */
- if (Ustrncmp(linebuffer,"--",2) == 0) {
- if (Ustrncmp((linebuffer+2),mime_current_boundary,Ustrlen(mime_current_boundary)) == 0)
- /* found boundary */
- break;
- };
- };
- re_list_item = re_list_head;
- do {
- /* try matcher on the line */
- if (pcre_exec(re_list_item->re, NULL, CS linebuffer,
- (int)Ustrlen(linebuffer), 0, 0, NULL, 0) >= 0) {
- Ustrncpy(regex_match_string_buffer, re_list_item->pcre_text, 1023);
- regex_match_string = regex_match_string_buffer;
- if (mime_stream == NULL)
- (void)fclose(mbox_file);
- else {
- clearerr(mime_stream);
- fseek(mime_stream,f_pos,SEEK_SET);
- };
- return OK;
- };
- re_list_item = re_list_item->next;
- } while (re_list_item != NULL);
- };
-
- if (mime_stream == NULL)
- (void)fclose(mbox_file);
- else {
- clearerr(mime_stream);
- fseek(mime_stream,f_pos,SEEK_SET);
- };
-
- /* no matches ... */
- return FAIL;
+return re_list_head;
}
+static int
+matcher(pcre_list * re_list_head, uschar * linebuffer, int len)
+{
+pcre_list * ri;
+
+for(ri = re_list_head; ri; ri = ri->next)
+ {
+ int ovec[3*(REGEX_VARS+1)];
+ int n, nn;
+
+ /* try matcher on the line */
+ n = pcre_exec(ri->re, NULL, CS linebuffer, len, 0, 0, ovec, nelem(ovec));
+ if (n > 0)
+ {
+ Ustrncpy(regex_match_string_buffer, ri->pcre_text,
+ sizeof(regex_match_string_buffer)-1);
+ regex_match_string = regex_match_string_buffer;
+
+ for (nn = 1; nn < n; nn++)
+ regex_vars[nn-1] =
+ string_copyn(linebuffer + ovec[nn*2], ovec[nn*2+1] - ovec[nn*2]);
+
+ return OK;
+ }
+ }
+return FAIL;
+}
-int mime_regex(uschar **listptr) {
- int sep = 0;
- uschar *list = *listptr;
- uschar *regex_string;
- uschar regex_string_buffer[1024];
- pcre *re;
- pcre_list *re_list_head = NULL;
- pcre_list *re_list_item;
- const char *pcre_error;
- int pcre_erroffset;
- FILE *f;
- uschar *mime_subject = NULL;
- int mime_subject_len = 0;
-
- /* reset expansion variable */
- regex_match_string = NULL;
-
- /* precompile our regexes */
- while ((regex_string = string_nextinlist(&list, &sep,
- regex_string_buffer,
- sizeof(regex_string_buffer))) != NULL) {
-
- /* parse option */
- if ( (strcmpic(regex_string,US"false") == 0) ||
- (Ustrcmp(regex_string,"0") == 0) ) {
- /* explicitly no matching */
- continue;
- };
+int
+regex(const uschar **listptr)
+{
+unsigned long mbox_size;
+FILE *mbox_file;
+pcre_list *re_list_head;
+uschar *linebuffer;
+long f_pos = 0;
+int ret = FAIL;
+
+/* reset expansion variable */
+regex_match_string = NULL;
+
+if (!mime_stream) /* We are in the DATA ACL */
+ {
+ if (!(mbox_file = spool_mbox(&mbox_size, NULL)))
+ { /* error while spooling */
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "regex acl condition: error while creating mbox spool file");
+ return DEFER;
+ }
+ }
+else
+ {
+ f_pos = ftell(mime_stream);
+ mbox_file = mime_stream;
+ }
- /* compile our regular expression */
- re = pcre_compile( CS regex_string,
- 0,
- &pcre_error,
- &pcre_erroffset,
- NULL );
+/* precompile our regexes */
+if (!(re_list_head = compile(*listptr)))
+ return FAIL; /* no regexes -> nothing to do */
+
+/* match each line against all regexes */
+linebuffer = store_get(32767);
+while (fgets(CS linebuffer, 32767, mbox_file))
+ {
+ if ( mime_stream && mime_current_boundary /* check boundary */
+ && Ustrncmp(linebuffer, "--", 2) == 0
+ && Ustrncmp((linebuffer+2), mime_current_boundary,
+ Ustrlen(mime_current_boundary)) == 0)
+ break; /* found boundary */
+
+ if ((ret = matcher(re_list_head, linebuffer, (int)Ustrlen(linebuffer))) == OK)
+ goto done;
+ }
+/* no matches ... */
+
+done:
+if (!mime_stream)
+ (void)fclose(mbox_file);
+else
+ {
+ clearerr(mime_stream);
+ fseek(mime_stream, f_pos, SEEK_SET);
+ }
- if (re == NULL) {
- log_write(0, LOG_MAIN,
- "regex acl condition warning - error in regex '%s': %s at offset %d, skipped.", regex_string, pcre_error, pcre_erroffset);
- continue;
- }
- else {
- re_list_item = store_get(sizeof(pcre_list));
- re_list_item->re = re;
- re_list_item->pcre_text = string_copy(regex_string);
- re_list_item->next = re_list_head;
- re_list_head = re_list_item;
- };
- };
-
- /* no regexes -> nothing to do */
- if (re_list_head == NULL) {
- return FAIL;
- };
-
- /* check if the file is already decoded */
- if (mime_decoded_filename == NULL) {
- uschar *empty = US"";
- /* no, decode it first */
- mime_decode(&empty);
- if (mime_decoded_filename == NULL) {
- /* decoding failed */
- log_write(0, LOG_MAIN,
- "mime_regex acl condition warning - could not decode MIME part to file.");
- return DEFER;
- };
- };
+return ret;
+}
- /* open file */
- f = fopen(CS mime_decoded_filename, "rb");
- if (f == NULL) {
- /* open failed */
+int
+mime_regex(const uschar **listptr)
+{
+pcre_list *re_list_head = NULL;
+FILE *f;
+uschar *mime_subject = NULL;
+int mime_subject_len = 0;
+int ret;
+
+/* reset expansion variable */
+regex_match_string = NULL;
+
+/* precompile our regexes */
+if (!(re_list_head = compile(*listptr)))
+ return FAIL; /* no regexes -> nothing to do */
+
+/* check if the file is already decoded */
+if (!mime_decoded_filename)
+ { /* no, decode it first */
+ const uschar *empty = US"";
+ mime_decode(&empty);
+ if (!mime_decoded_filename)
+ { /* decoding failed */
log_write(0, LOG_MAIN,
- "mime_regex acl condition warning - can't open '%s' for reading.", mime_decoded_filename);
+ "mime_regex acl condition warning - could not decode MIME part to file");
return DEFER;
- };
-
- /* get 32k memory */
- mime_subject = (uschar *)store_get(32767);
-
- /* read max 32k chars from file */
- mime_subject_len = fread(mime_subject, 1, 32766, f);
-
- re_list_item = re_list_head;
- do {
- /* try matcher on the mmapped file */
- debug_printf("Matching '%s'\n", re_list_item->pcre_text);
- if (pcre_exec(re_list_item->re, NULL, CS mime_subject,
- mime_subject_len, 0, 0, NULL, 0) >= 0) {
- Ustrncpy(regex_match_string_buffer, re_list_item->pcre_text, 1023);
- regex_match_string = regex_match_string_buffer;
- (void)fclose(f);
- return OK;
- };
- re_list_item = re_list_item->next;
- } while (re_list_item != NULL);
-
- (void)fclose(f);
-
- /* no matches ... */
- return FAIL;
+ }
+ }
+
+/* open file */
+if (!(f = fopen(CS mime_decoded_filename, "rb")))
+ {
+ log_write(0, LOG_MAIN,
+ "mime_regex acl condition warning - can't open '%s' for reading",
+ mime_decoded_filename);
+ return DEFER;
+ }
+
+/* get 32k memory */
+mime_subject = store_get(32767);
+
+mime_subject_len = fread(mime_subject, 1, 32766, f);
+
+ret = matcher(re_list_head, mime_subject, mime_subject_len);
+(void)fclose(f);
+return ret;
}
#endif /* WITH_CONTENT_SCAN */
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Functions concerned with retrying unsuccessful deliveries. */
*/
BOOL
-retry_ultimate_address_timeout(uschar *retry_key, uschar *domain,
+retry_ultimate_address_timeout(uschar *retry_key, const uschar *domain,
dbdata_retry *retry_record, time_t now)
{
BOOL address_timeout;
*/
BOOL
-retry_check_address(uschar *domain, host_item *host, uschar *portstring,
+retry_check_address(const uschar *domain, host_item *host, uschar *portstring,
BOOL include_ip_address, uschar **retry_host_key, uschar **retry_message_key)
{
BOOL yield = FALSE;
*/
retry_config *
-retry_find_config(uschar *key, uschar *alternate, int basic_errno,
+retry_find_config(const uschar *key, const uschar *alternate, int basic_errno,
int more_errno)
{
-int replace = 0;
-uschar *use_key, *use_alternate;
-uschar *colon = Ustrchr(key, ':');
+const uschar *colon = Ustrchr(key, ':');
retry_config *yield;
/* If there's a colon in the key, there are two possibilities:
hostname:ip+port
- In this case, we temporarily replace the colon with a zero, to terminate
- the string after the host name.
+ In this case, we copy the host name.
(2) This is a key for a pipe, file, or autoreply delivery, in the format
with a letter or a digit. In this case we want to use the original address
to search for a retry rule. */
-if (colon != NULL)
- {
- if (isalnum(*key))
- replace = ':';
- else
- key = Ustrrchr(key, ':') + 1; /* Take from the last colon */
- }
-
-if (replace == 0) colon = key + Ustrlen(key);
-*colon = 0;
+if (colon)
+ key = isalnum(*key)
+ ? string_copyn(key, colon-key) /* the hostname */
+ : Ustrrchr(key, ':') + 1; /* Take from the last colon */
/* Sort out the keys */
-use_key = (Ustrchr(key, '@') != NULL)? key : string_sprintf("*@%s", key);
-use_alternate = (alternate == NULL)? NULL : string_sprintf("*@%s", alternate);
+if (!Ustrchr(key, '@')) key = string_sprintf("*@%s", key);
+if (alternate) alternate = string_sprintf("*@%s", alternate);
/* Scan the configured retry items. */
for (yield = retries; yield != NULL; yield = yield->next)
{
- uschar *plist = yield->pattern;
- uschar *slist = yield->senders;
+ const uschar *plist = yield->pattern;
+ const uschar *slist = yield->senders;
/* If a specific error is set for this item, check that we are handling that
specific error, and if so, check any additional error information if
/* Check for a match between the address list item at the start of this retry
rule and either the main or alternate keys. */
- if (match_address_list(use_key, TRUE, TRUE, &plist, NULL, -1, UCHAR_MAX+1,
+ if (match_address_list(key, TRUE, TRUE, &plist, NULL, -1, UCHAR_MAX+1,
NULL) == OK ||
- (use_alternate != NULL &&
- match_address_list(use_alternate, TRUE, TRUE, &plist, NULL, -1,
+ (alternate != NULL &&
+ match_address_list(alternate, TRUE, TRUE, &plist, NULL, -1,
UCHAR_MAX+1, NULL) == OK))
break;
}
-*colon = replace;
return yield;
}
message = (rti->basic_errno > 0)? US strerror(rti->basic_errno) :
(rti->message == NULL)?
- US"unknown error" : string_printing(rti->message);
+ US"unknown error" : US string_printing(rti->message);
message_length = Ustrlen(message);
if (message_length > 150) message_length = 150;
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Functions concerned with rewriting headers */
{
int start, end, pdomain;
int count = 0;
- uschar *save_localpart, *save_domain;
+ uschar *save_localpart;
+ const uschar *save_domain;
uschar *error, *new, *newparsed;
/* Ensure that the flag matches the flags in the rule. */
/* Use the general function for matching an address against a list (here
just one item, so use the "impossible value" separator UCHAR_MAX+1). */
- if (match_address_list(subject, FALSE, TRUE, &(rule->key), NULL, 0,
+ if (match_address_list(subject, FALSE, TRUE, CUSS &(rule->key), NULL, 0,
UCHAR_MAX + 1, NULL) != OK)
continue;
/* We have a validly rewritten address */
- if ((log_write_selector & L_address_rewrite) != 0 ||
- (debug_selector & D_rewrite) != 0)
+ if (LOGGING(address_rewrite) || (debug_selector & D_rewrite) != 0)
{
int i;
const uschar *where = CUS"?";
{
uschar *p1 = new + start - 1;
uschar *p2 = new + end + 1;
- uschar *pf1, *pf2;
+ const uschar *pf1, *pf2;
uschar buff1[256], buff2[256];
while (p1 > new && p1[-1] == ' ') p1--;
*/
static header_line *
-rewrite_one_header(header_line *h, int flag, uschar *routed_old,
- uschar *routed_new, rewrite_rule *rewrite_rules, int existflags, BOOL replace)
+rewrite_one_header(header_line *h, int flag,
+ const uschar *routed_old, const uschar *routed_new,
+ rewrite_rule *rewrite_rules, int existflags, BOOL replace)
{
int lastnewline = 0;
header_line *newh = NULL;
*/
header_line *
-rewrite_header(header_line *h, uschar *routed_old, uschar *routed_new,
+rewrite_header(header_line *h,
+ const uschar *routed_old, const uschar *routed_new,
rewrite_rule *rewrite_rules, int existflags, BOOL replace)
{
switch (h->type)
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Functions concerned with routing, and the list of generic router options. */
(void *)offsetof(router_instance, debug_string) },
{ "disable_logging", opt_bool | opt_public,
(void *)offsetof(router_instance, disable_logging) },
+ { "dnssec_request_domains", opt_stringptr|opt_public,
+ (void *)offsetof(router_instance, dnssec.request) },
+ { "dnssec_require_domains", opt_stringptr|opt_public,
+ (void *)offsetof(router_instance, dnssec.require) },
{ "domains", opt_stringptr|opt_public,
(void *)offsetof(router_instance, domains) },
{ "driver", opt_stringptr|opt_public,
BOOL afterthis = FALSE;
router_instance *rr;
-for (rr = routers; rr != NULL; rr = rr->next)
+for (rr = routers; rr; rr = rr->next)
{
if (Ustrcmp(name, rr->name) == 0)
{
if (rr == r) afterthis = TRUE;
}
-if (rr == NULL)
+if (!rr)
log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
"new_router \"%s\" not found for \"%s\" router", name, r->name);
optionlist_routers, /* generic options */
optionlist_routers_size);
-for (r = routers; r != NULL; r = r->next)
+for (r = routers; r; r = r->next)
{
uschar *s = r->self;
if (r->pass_router_name != NULL)
set_router(r, r->pass_router_name, &(r->pass_router), TRUE);
- DEBUG(D_route) {
- if (r->dsn_lasthop == FALSE)
- debug_printf("DSN: %s propagating DSN\n", r->name);
- else
- debug_printf("DSN: %s lasthop set\n", r->name);
- }
+ DEBUG(D_route) debug_printf("DSN: %s %s\n", r->name,
+ r->dsn_lasthop ? "lasthop set" : "propagating DSN");
}
}
route_tidyup(void)
{
router_instance *r;
-for (r = routers; r != NULL; r = r->next)
- if (r->info->tidyup != NULL) (r->info->tidyup)(r);
+for (r = routers; r; r = r->next)
+ if (r->info->tidyup) (r->info->tidyup)(r);
}
*/
int
-route_check_prefix(uschar *local_part, uschar *prefixes)
+route_check_prefix(const uschar *local_part, const uschar *prefixes)
{
int sep = 0;
uschar *prefix;
-uschar *listptr = prefixes;
+const uschar *listptr = prefixes;
uschar prebuf[64];
-while ((prefix = string_nextinlist(&listptr, &sep, prebuf, sizeof(prebuf)))
- != NULL)
+while ((prefix = string_nextinlist(&listptr, &sep, prebuf, sizeof(prebuf))))
{
int plen = Ustrlen(prefix);
if (prefix[0] == '*')
{
- uschar *p;
+ const uschar *p;
prefix++;
for (p = local_part + Ustrlen(local_part) - (--plen);
p >= local_part; p--)
*/
int
-route_check_suffix(uschar *local_part, uschar *suffixes)
+route_check_suffix(const uschar *local_part, const uschar *suffixes)
{
int sep = 0;
int alen = Ustrlen(local_part);
uschar *suffix;
-uschar *listptr = suffixes;
+const uschar *listptr = suffixes;
uschar sufbuf[64];
-while ((suffix = string_nextinlist(&listptr, &sep, sufbuf, sizeof(sufbuf)))
- != NULL)
+while ((suffix = string_nextinlist(&listptr, &sep, sufbuf, sizeof(sufbuf))))
{
int slen = Ustrlen(suffix);
if (suffix[slen-1] == '*')
{
- uschar *p, *pend;
+ const uschar *p, *pend;
pend = local_part + alen - (--slen) + 1;
for (p = local_part; p < pend; p++)
if (strncmpic(suffix, p, slen) == 0) return alen - (p - local_part);
*/
static int
-route_check_dls(uschar *rname, uschar *type, uschar *list, tree_node
- **anchorptr, unsigned int *cache_bits, int listtype, uschar *domloc,
- uschar **ldata, BOOL caseless, uschar **perror)
+route_check_dls(uschar *rname, uschar *type, const uschar *list,
+ tree_node **anchorptr, unsigned int *cache_bits, int listtype,
+ const uschar *domloc, const uschar **ldata, BOOL caseless, uschar **perror)
{
-int rc;
-
-if (list == NULL) return OK; /* Empty list always succeeds */
+if (!list) return OK; /* Empty list always succeeds */
DEBUG(D_route) debug_printf("checking %s\n", type);
/* The domain and local part use the same matching function, whereas sender
has its own code. */
-if (domloc != NULL)
- {
- rc = match_isinlist(domloc, &list, 0, anchorptr, cache_bits, listtype,
- caseless, ldata);
- }
-else
- {
- uschar *address = (sender_address == NULL)? US"" : sender_address;
- rc = match_address_list(address, TRUE, TRUE, &list, cache_bits, -1, 0,
- &sender_data);
- }
-
-switch(rc)
+switch(domloc
+ ? match_isinlist(domloc, &list, 0, anchorptr, cache_bits, listtype,
+ caseless, ldata)
+ : match_address_list(sender_address ? sender_address : US"",
+ TRUE, TRUE, &list, cache_bits, -1, 0, CUSS &sender_data)
+ )
{
case OK:
- return OK;
+ return OK;
case FAIL:
- *perror = string_sprintf("%s router skipped: %s mismatch", rname, type);
- DEBUG(D_route) debug_printf("%s\n", *perror);
- return SKIP;
+ *perror = string_sprintf("%s router skipped: %s mismatch", rname, type);
+ DEBUG(D_route) debug_printf("%s\n", *perror);
+ return SKIP;
default: /* Paranoia, and keeps compilers happy */
case DEFER:
- *perror = string_sprintf("%s check lookup or other defer", type);
- DEBUG(D_route) debug_printf("%s\n", *perror);
- return DEFER;
+ *perror = string_sprintf("%s check lookup or other defer", type);
+ DEBUG(D_route) debug_printf("%s\n", *perror);
+ return DEFER;
}
}
DEBUG(D_route) debug_printf("route_check_access(%s,%d,%d,%o)\n", path,
(int)uid, (int)gid, bits);
-if (rp == NULL) return FALSE;
+if (!rp) return FALSE;
-while ((slash = Ustrchr(sp, '/')) != NULL)
+while ((slash = Ustrchr(sp, '/')))
{
*slash = 0;
DEBUG(D_route) debug_printf("stat %s\n", rp);
SKIP otherwise
*/
-int
-check_files(uschar *s, uschar **perror)
+static int
+check_files(const uschar *s, uschar **perror)
{
int sep = 0; /* List has default separators */
uid_t uid = 0; /* For picky compilers */
gid_t gid = 0; /* For picky compilers */
BOOL ugid_set = FALSE;
-uschar *check, *listptr;
+const uschar *listptr;
+uschar *check;
uschar buffer[1024];
-if (s == NULL) return OK;
+if (!s) return OK;
DEBUG(D_route) debug_printf("checking require_files\n");
listptr = s;
-while ((check = string_nextinlist(&listptr, &sep, buffer, sizeof(buffer)))
- != NULL)
+while ((check = string_nextinlist(&listptr, &sep, buffer, sizeof(buffer))))
{
int rc;
int eacces_code = 0;
struct stat statbuf;
uschar *ss = expand_string(check);
- if (ss == NULL)
+ if (!ss)
{
if (expand_string_forcedfail) continue;
*perror = string_sprintf("failed to expand \"%s\" for require_files: %s",
/* Skip this router if there's a domain mismatch. */
if ((rc = route_check_dls(r->name, US"domains", r->domains, &domainlist_anchor,
- addr->domain_cache, TRUE, addr->domain, &deliver_domain_data, MCL_DOMAIN,
- perror)) != OK)
+ addr->domain_cache, TRUE, addr->domain, CUSS &deliver_domain_data,
+ MCL_DOMAIN, perror)) != OK)
return rc;
/* Skip this router if there's a local part mismatch. We want to pass over the
required. Also, we only use the match cache for local parts that have not had
a prefix or suffix stripped. */
-if (addr->prefix == NULL && addr->suffix == NULL)
+if (!addr->prefix && !addr->suffix)
{
localpart_cache = addr->localpart_cache;
check_local_part = addr->cc_local_part;
{
localpart_cache = NULL;
check_local_part = string_copy(addr->cc_local_part);
- if (addr->prefix != NULL)
+ if (addr->prefix)
check_local_part += Ustrlen(addr->prefix);
- if (addr->suffix != NULL)
+ if (addr->suffix)
check_local_part[Ustrlen(check_local_part) - Ustrlen(addr->suffix)] = 0;
}
if ((rc = route_check_dls(r->name, US"local_parts", r->local_parts,
&localpartlist_anchor, localpart_cache, MCL_LOCALPART,
- check_local_part, &deliver_localpart_data, !r->caseful_local_part,
- perror)) != OK)
+ check_local_part, CUSS &deliver_localpart_data,
+ !r->caseful_local_part, perror)) != OK)
return rc;
/* If the check_local_user option is set, check that the local_part is the
could mean different things for different options, which would be extremely
confusing. */
-if (r->router_home_directory != NULL)
+if (r->router_home_directory)
{
uschar *router_home = expand_string(r->router_home_directory);
- if (router_home == NULL)
+ if (!router_home)
{
if (!expand_string_forcedfail)
{
/* Now the general condition test. */
-if (r->condition != NULL)
+if (r->condition)
{
DEBUG(D_route) debug_printf("checking \"condition\"\n");
if (!expand_check_condition(r->condition, r->name, US"router"))
#ifdef EXPERIMENTAL_BRIGHTMAIL
/* check if a specific Brightmail AntiSpam rule fired on the message */
-if (r->bmi_rule != NULL) {
+if (r->bmi_rule)
+ {
DEBUG(D_route) debug_printf("checking bmi_rule\n");
- if (bmi_check_rule(bmi_base64_verdict, r->bmi_rule) == 0) {
- /* none of the rules fired */
+ if (bmi_check_rule(bmi_base64_verdict, r->bmi_rule) == 0)
+ { /* none of the rules fired */
DEBUG(D_route)
debug_printf("%s router skipped: none of bmi_rule rules fired\n", r->name);
return SKIP;
- };
-};
+ }
+ }
/* check if message should not be delivered */
-if (r->bmi_dont_deliver) {
- if (bmi_deliver == 1) {
- DEBUG(D_route)
- debug_printf("%s router skipped: bmi_dont_deliver is FALSE\n", r->name);
- return SKIP;
- };
-};
+if (r->bmi_dont_deliver && bmi_deliver == 1)
+ {
+ DEBUG(D_route)
+ debug_printf("%s router skipped: bmi_dont_deliver is FALSE\n", r->name);
+ return SKIP;
+ }
/* check if message should go to an alternate location */
-if (r->bmi_deliver_alternate) {
- if ((bmi_deliver == 0) || (bmi_alt_location == NULL)) {
- DEBUG(D_route)
- debug_printf("%s router skipped: bmi_deliver_alternate is FALSE\n", r->name);
- return SKIP;
- };
-};
+if ( r->bmi_deliver_alternate
+ && (bmi_deliver == 0 || !bmi_alt_location)
+ )
+ {
+ DEBUG(D_route)
+ debug_printf("%s router skipped: bmi_deliver_alternate is FALSE\n", r->name);
+ return SKIP;
+ }
/* check if message should go to default location */
-if (r->bmi_deliver_default) {
- if ((bmi_deliver == 0) || (bmi_alt_location != NULL)) {
- DEBUG(D_route)
- debug_printf("%s router skipped: bmi_deliver_default is FALSE\n", r->name);
- return SKIP;
- };
-};
+if ( r->bmi_deliver_default
+ && (bmi_deliver == 0 || bmi_alt_location)
+ )
+ {
+ DEBUG(D_route)
+ debug_printf("%s router skipped: bmi_deliver_default is FALSE\n", r->name);
+ return SKIP;
+ }
#endif
/* All the checks passed. */
static uschar lastshell[128];
BOOL
-route_finduser(uschar *s, struct passwd **pw, uid_t *return_uid)
+route_finduser(const uschar *s, struct passwd **pw, uid_t *return_uid)
{
BOOL cache_set = (Ustrcmp(lastname, s) == 0);
{
int i = 0;
- if (return_uid != NULL && (isdigit(*s) || *s == '-') &&
+ if (return_uid && (isdigit(*s) || *s == '-') &&
s[Ustrspn(s+1, "0123456789")+1] == 0)
{
*return_uid = (uid_t)Uatoi(s);
- if (pw != NULL) *pw = NULL;
+ if (pw) *pw = NULL;
return TRUE;
}
else for (;;)
{
errno = 0;
- if ((lastpw = getpwnam(CS s)) != NULL) break;
+ if ((lastpw = getpwnam(CS s))) break;
if (++i > finduser_retries) break;
sleep(1);
}
- if (lastpw != NULL)
+ if (lastpw)
{
pwcopy.pw_uid = lastpw->pw_uid;
pwcopy.pw_gid = lastpw->pw_gid;
lastpw = &pwcopy;
}
- else DEBUG(D_uid)
- {
- if (errno != 0) debug_printf("getpwnam(%s) failed: %s\n", s,
- strerror(errno));
- }
+ else DEBUG(D_uid) if (errno != 0)
+ debug_printf("getpwnam(%s) failed: %s\n", s, strerror(errno));
}
-if (lastpw == NULL)
+if (!lastpw)
{
DEBUG(D_uid) debug_printf("getpwnam() returned NULL (user not found)\n");
return FALSE;
}
-else
- {
- DEBUG(D_uid) debug_printf("getpwnam() succeeded uid=%d gid=%d\n",
+
+DEBUG(D_uid) debug_printf("getpwnam() succeeded uid=%d gid=%d\n",
lastpw->pw_uid, lastpw->pw_gid);
- }
-if (return_uid != NULL) *return_uid = lastpw->pw_uid;
-if (pw != NULL) *pw = lastpw;
+if (return_uid) *return_uid = lastpw->pw_uid;
+if (pw) *pw = lastpw;
return TRUE;
}
for (;;)
{
- if ((gr = getgrnam(CS s)) != NULL)
+ if ((gr = getgrnam(CS s)))
{
*return_gid = gr->gr_gid;
return TRUE;
{
uschar *user = expand_string(string);
-if (user == NULL)
+if (!user)
{
*errmsg = string_sprintf("Failed to expand user string \"%s\" for the "
"%s %s: %s", string, driver_name, driver_type, expand_string_message);
BOOL yield = TRUE;
uschar *group = expand_string(string);
-if (group == NULL)
+if (!group)
{
*errmsg = string_sprintf("Failed to expand group string \"%s\" for the "
"%s %s: %s", string, driver_name, driver_type, expand_string_message);
*parent = *addr;
parent->child_count = 2;
-parent->p.errors_address =
- (addr->parent == NULL)? NULL : addr->parent->p.errors_address;
+parent->prop.errors_address =
+ addr->parent ? addr->parent->prop.errors_address : NULL;
/* The routed address gets a new parent. */
take the errors address from the unseen router. */
new->parent = parent;
-new->p.errors_address = parent->p.errors_address;
+new->prop.errors_address = parent->prop.errors_address;
/* Copy the propagated flags and address_data from the original. */
copyflag(new, addr, af_propagate);
-new->p.address_data = addr->p.address_data;
+new->prop.address_data = addr->prop.address_data;
new->dsn_flags = addr->dsn_flags;
new->dsn_orcpt = addr->dsn_orcpt;
again. Otherwise, it was an alias or something, and the addresses it generated
are handled in the normal way. */
-if (addr->transport != NULL &&
- tree_search(tree_nonrecipients, addr->unique) != NULL)
+if (addr->transport && tree_search(tree_nonrecipients, addr->unique))
{
DEBUG(D_route)
debug_printf("\"unseen\" delivery previously done - discarded\n");
int yield = OK;
BOOL unseen;
router_instance *r, *nextr;
-uschar *old_domain = addr->domain;
+const uschar *old_domain = addr->domain;
HDEBUG(D_route)
{
encounters an error. If the address has start_router set, we begin from there
instead of at the first router. */
-for (r = (addr->start_router == NULL)? routers : addr->start_router;
- r != NULL; r = nextr)
+for (r = addr->start_router ? addr->start_router : routers; r; r = nextr)
{
uschar *error;
struct passwd *pw = NULL;
continally adding to an address, for example), put a long stop counter on
the number of parents. */
- for (parent = addr->parent; parent != NULL; parent = parent->parent)
+ for (parent = addr->parent; parent; parent = parent->parent)
{
if (parent->router == r)
{
and setting the prefix. Skip the router if the prefix doesn't match,
unless the prefix is optional. */
- if (r->prefix != NULL)
+ if (r->prefix)
{
int plen = route_check_prefix(addr->local_part, r->prefix);
if (plen > 0)
/* Handle any configured suffix likewise. */
- if (r->suffix != NULL)
+ if (r->suffix)
{
int slen = route_check_suffix(addr->local_part, r->suffix);
if (slen > 0)
success, the string is attached to the address for all subsequent processing.
*/
- if (r->address_data != NULL)
+ if (r->address_data)
{
DEBUG(D_route) debug_printf("processing address_data\n");
deliver_address_data = expand_string(r->address_data);
- if (deliver_address_data == NULL)
+ if (!deliver_address_data)
{
if (expand_string_forcedfail)
{
goto ROUTE_EXIT;
}
}
- addr->p.address_data = deliver_address_data;
+ addr->prop.address_data = deliver_address_data;
}
/* We are finally cleared for take-off with this router. Clear the the flag
clearflag(addr, af_local_host_removed);
- if (pw != NULL)
+ if (pw)
{
pwcopy.pw_name = CS string_copy(US pw->pw_name);
pwcopy.pw_uid = pw->pw_uid;
/* Run the router, and handle the consequences. */
-/* ... but let us check on DSN before. If this should be the last hop for DSN
- set flag
-*/
- if ((r->dsn_lasthop == TRUE) && ((addr->dsn_flags & rf_dsnlasthop) == 0))
+ /* ... but let us check on DSN before. If this should be the last hop for DSN
+ set flag. */
+
+ if (r->dsn_lasthop && !(addr->dsn_flags & rf_dsnlasthop))
{
addr->dsn_flags |= rf_dsnlasthop;
HDEBUG(D_route) debug_printf("DSN: last hop for %s\n", addr->address);
router response. Note that FAIL errors and errors detected before actually
running a router go direct to ROUTE_EXIT from code above. */
-if (r == NULL)
+if (!r)
{
HDEBUG(D_route) debug_printf("no more routers\n");
- if (addr->message == NULL)
+ if (!addr->message)
{
uschar *message = US"Unrouteable address";
- if (addr->router != NULL && addr->router->cannot_route_message != NULL)
+ if (addr->router && addr->router->cannot_route_message)
{
uschar *expmessage = expand_string(addr->router->cannot_route_message);
- if (expmessage == NULL)
+ if (!expmessage)
{
if (!expand_string_forcedfail)
log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand "
#ifdef SUPPORT_TRANSLATE_IP_ADDRESS
-if (r->translate_ip_address != NULL)
+if (r->translate_ip_address)
{
int rc;
int old_pool = store_pool;
host_item *h;
- for (h = addr->host_list; h != NULL; h = h->next)
+ for (h = addr->host_list; h; h = h->next)
{
uschar *newaddress;
uschar *oldaddress, *oldname;
- if (h->address == NULL) continue;
+ if (!h->address) continue;
deliver_host_address = h->address;
newaddress = expand_string(r->translate_ip_address);
deliver_host_address = NULL;
- if (newaddress == NULL)
+ if (!newaddress)
{
if (expand_string_forcedfail) continue;
addr->basic_errno = ERRNO_EXPANDFAIL;
/* Debugging output recording a successful routing */
-HDEBUG(D_route)
- {
- debug_printf("routed by %s router%s\n", r->name,
+HDEBUG(D_route) debug_printf("routed by %s router%s\n", r->name,
unseen? " (unseen)" : "");
- }
DEBUG(D_route)
{
debug_printf(" transport: %s\n", (addr->transport == NULL)?
US"<none>" : addr->transport->name);
- if (addr->p.errors_address != NULL)
- debug_printf(" errors to %s\n", addr->p.errors_address);
+ if (addr->prop.errors_address)
+ debug_printf(" errors to %s\n", addr->prop.errors_address);
- for (h = addr->host_list; h != NULL; h = h->next)
+ for (h = addr->host_list; h; h = h->next)
{
debug_printf(" host %s", h->name);
- if (h->address != NULL) debug_printf(" [%s]", h->address);
+ if (h->address) debug_printf(" [%s]", h->address);
if (h->mx >= 0) debug_printf(" MX=%d", h->mx);
else if (h->mx != MX_NONE) debug_printf(" rgroup=%d", h->mx);
if (h->port != PORT_NONE) debug_printf(" port=%d", h->port);
the "unseen" option (ignore if there are no further routers). */
addr->message = NULL;
-if (unseen && r->next != NULL)
+if (unseen && r->next)
route_unseen(r->name, addr, paddr_local, paddr_remote, addr_new);
/* Unset the address expansions, and return the final result. */
ROUTE_EXIT:
-if (yield == DEFER) {
- if (
- ((Ustrstr(addr->message, "failed to expand") != NULL) || (Ustrstr(addr->message, "expansion of ") != NULL)) &&
- (
- Ustrstr(addr->message, "mysql") != NULL ||
- Ustrstr(addr->message, "pgsql") != NULL ||
-#ifdef EXPERIMENTAL_REDIS
- Ustrstr(addr->message, "redis") != NULL ||
-#endif
- Ustrstr(addr->message, "sqlite") != NULL ||
- Ustrstr(addr->message, "ldap:") != NULL ||
- Ustrstr(addr->message, "ldapdn:") != NULL ||
- Ustrstr(addr->message, "ldapm:") != NULL
- )
- ) {
- addr->message = string_sprintf("Temporary internal error");
- }
-}
+if ( yield == DEFER
+ && addr->message
+ && ( Ustrstr(addr->message, "failed to expand") != NULL
+ || Ustrstr(addr->message, "expansion of ") != NULL
+ )
+ && ( Ustrstr(addr->message, "mysql") != NULL
+ || Ustrstr(addr->message, "pgsql") != NULL
+ || Ustrstr(addr->message, "redis") != NULL
+ || Ustrstr(addr->message, "sqlite") != NULL
+ || Ustrstr(addr->message, "ldap:") != NULL
+ || Ustrstr(addr->message, "ldapdn:") != NULL
+ || Ustrstr(addr->message, "ldapm:") != NULL
+ )
+ )
+ addr->message = string_sprintf("Temporary internal error");
deliver_set_expansions(NULL);
router_name = NULL;
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
addr, rblock->name, NULL)) return DEFER;
addr->transport = rblock->transport;
-addr->p.errors_address = errors_to;
-addr->p.extra_headers = extra_headers;
-addr->p.remove_headers = remove_headers;
+addr->prop.errors_address = errors_to;
+addr->prop.extra_headers = extra_headers;
+addr->prop.remove_headers = remove_headers;
return rf_queue_add(addr, addr_local, addr_remote, rblock, pw)? OK : DEFER;
}
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
#include "../exim.h"
(void *)(offsetof(dnslookup_router_options_block, check_secondary_mx)) },
{ "check_srv", opt_stringptr,
(void *)(offsetof(dnslookup_router_options_block, check_srv)) },
- { "dnssec_request_domains", opt_stringptr,
- (void *)(offsetof(dnslookup_router_options_block, dnssec_request_domains)) },
- { "dnssec_require_domains", opt_stringptr,
- (void *)(offsetof(dnslookup_router_options_block, dnssec_require_domains)) },
+ { "fail_defer_domains", opt_stringptr,
+ (void *)(offsetof(dnslookup_router_options_block, fail_defer_domains)) },
{ "mx_domains", opt_stringptr,
(void *)(offsetof(dnslookup_router_options_block, mx_domains)) },
{ "mx_fail_domains", opt_stringptr,
NULL, /* mx_fail_domains */
NULL, /* srv_fail_domains */
NULL, /* check_srv */
- NULL, /* dnssec_request_domains */
- NULL /* dnssec_require_domains */
+ NULL /* fail_defer_domains */
};
(dnslookup_router_options_block *)(rblock->options_block);
uschar *srv_service = NULL;
uschar *widen = NULL;
-uschar *pre_widen = addr->domain;
-uschar *post_widen = NULL;
-uschar *fully_qualified_name;
-uschar *listptr;
+const uschar *pre_widen = addr->domain;
+const uschar *post_widen = NULL;
+const uschar *fully_qualified_name;
+const uschar *listptr;
uschar widen_buffer[256];
addr_new = addr_new; /* Keep picky compilers happy */
/* If an SRV check is required, expand the service name */
-if (ob->check_srv != NULL)
+if (ob->check_srv)
{
- srv_service = expand_string(ob->check_srv);
- if (srv_service == NULL && !expand_string_forcedfail)
+ if ( !(srv_service = expand_string(ob->check_srv))
+ && !expand_string_forcedfail)
{
addr->message = string_sprintf("%s router: failed to expand \"%s\": %s",
rblock->name, ob->check_srv, expand_string_message);
suppression of widening for sender addresses is silent because it is the
normal desirable behaviour. */
-if (ob->widen_domains != NULL &&
- (verify != v_sender || !ob->rewrite_headers || addr->parent != NULL))
+if ( ob->widen_domains
+ && (verify != v_sender || !ob->rewrite_headers || addr->parent))
{
listptr = ob->widen_domains;
widen = string_nextinlist(&listptr, &widen_sep, widen_buffer,
int flags = whichrrs;
BOOL removed = FALSE;
- if (pre_widen != NULL)
+ if (pre_widen)
{
h.name = pre_widen;
pre_widen = NULL;
}
- else if (widen != NULL)
+ else if (widen)
{
h.name = string_sprintf("%s.%s", addr->domain, widen);
widen = string_nextinlist(&listptr, &widen_sep, widen_buffer,
DEBUG(D_route) debug_printf("%s router widened %s to %s\n", rblock->name,
addr->domain, h.name);
}
- else if (post_widen != NULL)
+ else if (post_widen)
{
h.name = post_widen;
post_widen = NULL;
subsequently. We use the same logic as that for widen_domains above to avoid
requesting a header rewrite that cannot work. */
- if (verify != v_sender || !ob->rewrite_headers || addr->parent != NULL)
+ if (verify != v_sender || !ob->rewrite_headers || addr->parent)
{
if (ob->qualify_single) flags |= HOST_FIND_QUALIFY_SINGLE;
if (ob->search_parents) flags |= HOST_FIND_SEARCH_PARENTS;
}
- rc = host_find_bydns(&h, rblock->ignore_target_hosts, flags, srv_service,
+ rc = host_find_bydns(&h, CUS rblock->ignore_target_hosts, flags, srv_service,
ob->srv_fail_domains, ob->mx_fail_domains,
- ob->dnssec_request_domains, ob->dnssec_require_domains,
- &fully_qualified_name, &removed);
+ &rblock->dnssec, &fully_qualified_name, &removed);
if (removed) setflag(addr, af_local_host_removed);
/* If host found with only address records, test for the domain's being in
the option is historical. */
if ((rc == HOST_FOUND || rc == HOST_FOUND_LOCAL) && h.mx < 0 &&
- ob->mx_domains != NULL)
- {
- switch(match_isinlist(fully_qualified_name, &(ob->mx_domains), 0,
+ ob->mx_domains)
+ switch(match_isinlist(fully_qualified_name,
+ CUSS &(ob->mx_domains), 0,
&domainlist_anchor, addr->domain_cache, MCL_DOMAIN, TRUE, NULL))
{
case DEFER:
rblock->name, fully_qualified_name);
continue;
}
- }
/* Deferral returns forthwith, and anything other than failure breaks the
loop. */
addr->message = US"an MX or SRV record indicated no SMTP service";
else
{
+ addr->basic_errno = ERRNO_UNKNOWNHOST;
addr->message = US"all relevant MX records point to non-existent hosts";
if (!allow_mx_to_ip && string_is_ip_address(h.name, NULL) != 0)
{
addr->message);
}
}
+ if (ob->fail_defer_domains)
+ {
+ switch(match_isinlist(fully_qualified_name,
+ CUSS &ob->fail_defer_domains, 0,
+ &domainlist_anchor, addr->domain_cache, MCL_DOMAIN, TRUE, NULL))
+ {
+ case DEFER:
+ addr->message = US"lookup defer for fail_defer_domains";
+ return DEFER;
+
+ case OK:
+ DEBUG(D_route) debug_printf("%s router: matched fail_defer_domains\n",
+ rblock->name);
+ return DEFER;
+ }
+ }
return DECLINE;
}
/* Set up the errors address, if any. */
-rc = rf_get_errors_address(addr, rblock, verify, &(addr->p.errors_address));
+rc = rf_get_errors_address(addr, rblock, verify, &addr->prop.errors_address);
if (rc != OK) return rc;
/* Set up the additional and removeable headers for this address. */
-rc = rf_get_munge_headers(addr, rblock, &(addr->p.extra_headers),
- &(addr->p.remove_headers));
+rc = rf_get_munge_headers(addr, rblock, &addr->prop.extra_headers,
+ &addr->prop.remove_headers);
if (rc != OK) return rc;
/* Get store in which to preserve the original host item, chained on
}
/* End of routers/dnslookup.c */
+/* vi: aw ai sw=2
+*/
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Private structure for the private options. */
uschar *mx_fail_domains;
uschar *srv_fail_domains;
uschar *check_srv;
- uschar *dnssec_request_domains;
- uschar *dnssec_require_domains;
+ uschar *fail_defer_domains;
} dnslookup_router_options_block;
/* Data for reading the private options. */
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
(ipliteral_router_options_block *)(rblock->options_block);
*/
host_item *h;
-uschar *domain = addr->domain;
-uschar *ip;
+const uschar *domain = addr->domain;
+const uschar *ip;
int len = Ustrlen(domain);
int rc, ipv;
"(unnamed)". */
if (domain[0] != '[' || domain[len-1] != ']') return DECLINE;
-domain[len-1] = 0; /* temporarily */
-
-ip = domain + 1;
+ip = string_copyn(domain+1, len-2);
if (strncmpic(ip, US"IPV6:", 5) == 0 || strncmpic(ip, US"IPV4:", 5) == 0)
ip += 5;
ipv = string_is_ip_address(ip, NULL);
if (ipv == 0 || (disable_ipv6 && ipv == 6))
- {
- domain[len-1] = ']';
return DECLINE;
- }
/* It seems unlikely that ignore_target_hosts will be used with this router,
but if it is set, it should probably work. */
-if (verify_check_this_host(&(rblock->ignore_target_hosts), NULL, domain,
- ip, NULL) == OK)
+if (verify_check_this_host(CUSS&rblock->ignore_target_hosts,
+ NULL, domain, ip, NULL) == OK)
{
DEBUG(D_route)
debug_printf("%s is in ignore_target_hosts\n", ip);
addr->message = US"IP literal host explicitly ignored";
- domain[len-1] = ']';
return DECLINE;
}
h->next = NULL;
h->address = string_copy(ip);
h->port = PORT_NONE;
-domain[len-1] = ']'; /* restore */
-h->name = string_copy(domain);
+h->name = domain;
h->mx = MX_NONE;
h->status = hstatus_unknown;
h->why = hwhy_unknown;
/* Set up the errors address, if any. */
-rc = rf_get_errors_address(addr, rblock, verify, &(addr->p.errors_address));
+rc = rf_get_errors_address(addr, rblock, verify, &addr->prop.errors_address);
if (rc != OK) return rc;
/* Set up the additional and removeable headers for this address. */
-rc = rf_get_munge_headers(addr, rblock, &(addr->p.extra_headers),
- &(addr->p.remove_headers));
+rc = rf_get_munge_headers(addr, rblock, &addr->prop.extra_headers,
+ &addr->prop.remove_headers);
if (rc != OK) return rc;
/* Fill in the transport, queue the address for local or remote delivery, and
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
{
uschar *query = NULL;
uschar *reply;
-uschar *hostname, *reroute, *domain, *listptr;
+uschar *hostname, *reroute, *domain;
+const uschar *listptr;
uschar host_buffer[256];
host_item *host = store_get(sizeof(host_item));
address_item *new_addr;
host->address = host->name;
else
{
+/*XXX might want dnssec request/require on an iplookup router? */
int rc = host_find_byname(host, NULL, HOST_FIND_QUALIFY_SINGLE, NULL, TRUE);
if (rc == HOST_FIND_FAILED || rc == HOST_FIND_AGAIN) continue;
}
new_addr->parent = addr;
copyflag(new_addr, addr, af_propagate);
-new_addr->p = addr->p;
+new_addr->prop = addr->prop;
if (addr->child_count == SHRT_MAX)
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s router generated more than %d "
/* Set up the errors address, if any, and the additional and removeable headers
for this new address. */
-rc = rf_get_errors_address(addr, rblock, verify, &(new_addr->p.errors_address));
+rc = rf_get_errors_address(addr, rblock, verify, &new_addr->prop.errors_address);
if (rc != OK) return rc;
-rc = rf_get_munge_headers(addr, rblock, &(new_addr->p.extra_headers),
- &(new_addr->p.remove_headers));
+rc = rf_get_munge_headers(addr, rblock, &new_addr->prop.extra_headers,
+ &new_addr->prop.remove_headers);
if (rc != OK) return rc;
return OK;
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
*/
static BOOL
-parse_route_item(uschar *s, uschar **domain, uschar **hostlist,
- uschar **options)
+parse_route_item(const uschar *s, const uschar **domain, const uschar **hostlist,
+ const uschar **options)
{
while (*s != 0 && isspace(*s)) s++;
{
int rc, lookup_type;
uschar *route_item = NULL;
-uschar *options = NULL;
-uschar *hostlist = NULL;
-uschar *domain, *newhostlist, *listptr;
+const uschar *options = NULL;
+const uschar *hostlist = NULL;
+const uschar *domain;
+uschar *newhostlist;
+const uschar *listptr;
manualroute_router_options_block *ob =
(manualroute_router_options_block *)(rblock->options_block);
transport_instance *transport = NULL;
/* Check the current domain; if it matches, break the loop */
if ((rc = match_isinlist(addr->domain, &domain, UCHAR_MAX+1,
- &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, &lookup_value)) == OK)
+ &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, CUSS &lookup_value)) == OK)
break;
/* If there was a problem doing the check, defer */
while (*options != 0)
{
- int term;
- uschar *s = options;
+ unsigned n;
+ const uschar *s = options;
while (*options != 0 && !isspace(*options)) options++;
- term = *options;
- *options = 0;
+ n = options-s;
- if (Ustrcmp(s, "randomize") == 0) randomize = TRUE;
- else if (Ustrcmp(s, "no_randomize") == 0) randomize = FALSE;
- else if (Ustrcmp(s, "byname") == 0) lookup_type = lk_byname;
- else if (Ustrcmp(s, "bydns") == 0) lookup_type = lk_bydns;
+ if (Ustrncmp(s, "randomize", n) == 0) randomize = TRUE;
+ else if (Ustrncmp(s, "no_randomize", n) == 0) randomize = FALSE;
+ else if (Ustrncmp(s, "byname", n) == 0) lookup_type = lk_byname;
+ else if (Ustrncmp(s, "bydns", n) == 0) lookup_type = lk_bydns;
else
{
transport_instance *t;
for (t = transports; t != NULL; t = t->next)
- {
if (Ustrcmp(t->name, s) == 0)
{
transport = t;
individual_transport_set = TRUE;
break;
}
- }
+
if (t == NULL)
{
s = string_sprintf("unknown routing option or transport name \"%s\"", s);
}
}
- if (term != 0)
+ if (*options)
{
options++;
while (*options != 0 && isspace(*options)) options++;
/* Set up the errors address, if any. */
-rc = rf_get_errors_address(addr, rblock, verify, &(addr->p.errors_address));
+rc = rf_get_errors_address(addr, rblock, verify, &addr->prop.errors_address);
if (rc != OK) return rc;
/* Set up the additional and removeable headers for this address. */
-rc = rf_get_munge_headers(addr, rblock, &(addr->p.extra_headers),
- &(addr->p.remove_headers));
+rc = rf_get_munge_headers(addr, rblock, &addr->prop.extra_headers,
+ &addr->prop.remove_headers);
if (rc != OK) return rc;
/* If an individual transport is not set, get the transport for this router, if
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
#include "../exim.h"
next->parent = addr;
orflag(next, addr, af_propagate);
- next->p = *addr_prop;
+ next->prop = *addr_prop;
next->start_router = rblock->redirect_router;
next->next = *addr_new;
pid_t pid;
struct passwd *upw = NULL;
uschar buffer[1024];
-uschar **argvptr;
+const uschar **argvptr;
uschar *rword, *rdata, *s;
address_item_propagated addr_prop;
queryprogram_router_options_block *ob =
addr_prop.address_data = deliver_address_data;
-rc = rf_get_errors_address(addr, rblock, verify, &(addr_prop.errors_address));
+rc = rf_get_errors_address(addr, rblock, verify, &addr_prop.errors_address);
if (rc != OK) return rc;
-rc = rf_get_munge_headers(addr, rblock, &(addr_prop.extra_headers),
- &(addr_prop.remove_headers));
+rc = rf_get_munge_headers(addr, rblock, &addr_prop.extra_headers,
+ &addr_prop.remove_headers);
if (rc != OK) return rc;
/* Get the fixed or expanded uid under which the command is to run
/* Put the errors address, extra headers, and address_data into this address */
-addr->p = addr_prop;
+addr->prop = addr_prop;
/* Queue the address for local or remote delivery. */
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
int verify, address_item_propagated *addr_prop)
{
int frc = rf_get_errors_address(addr, rblock, verify,
- &(addr_prop->errors_address));
+ &addr_prop->errors_address);
if (frc != OK) return frc;
-addr->p.errors_address = addr_prop->errors_address;
-return rf_get_munge_headers(addr, rblock, &(addr_prop->extra_headers),
- &(addr_prop->remove_headers));
+addr->prop.errors_address = addr_prop->errors_address;
+return rf_get_munge_headers(addr, rblock, &addr_prop->extra_headers,
+ &addr_prop->remove_headers);
}
{
address_item *parent;
address_item *next = generated;
- uschar *errors_address = next->p.errors_address;
+ uschar *errors_address = next->prop.errors_address;
generated = next->next;
next->parent = addr;
If so, we must take care to re-instate it when we copy in the propagated
data so that it overrides any errors_to setting on the router. */
- next->p = *addr_prop;
- if (errors_address != NULL) next->p.errors_address = errors_address;
+ next->prop = *addr_prop;
+ if (errors_address != NULL) next->prop.errors_address = errors_address;
/* For pipes, files, and autoreplies, record this router as handling them,
because they don't go through the routing process again. Then set up uid,
}
}
+#ifdef SUPPORT_I18N
+ next->prop.utf8_msg = string_is_utf8(next->address)
+ || (sender_address && string_is_utf8(sender_address));
+#endif
+
DEBUG(D_route)
{
debug_printf("%s router generated %s\n %serrors_to=%s transport=%s\n",
rblock->name,
next->address,
testflag(next, af_pfr)? "pipe, file, or autoreply\n " : "",
- next->p.errors_address,
+ next->prop.errors_address,
(next->transport == NULL)? US"NULL" : next->transport->name);
if (testflag(next, af_uid_set))
else
debug_printf("gid=unset ");
+#ifdef SUPPORT_I18N
+ if (next->prop.utf8_msg) debug_printf("utf8 ");
+#endif
+
debug_printf("home=%s\n", next->home_dir);
}
}
redirect_router_options_block *ob =
(redirect_router_options_block *)(rblock->options_block);
address_item *generated = NULL;
-uschar *save_qualify_domain_recipient = qualify_domain_recipient;
+const uschar *save_qualify_domain_recipient = qualify_domain_recipient;
uschar *discarded = US"discarded";
address_item_propagated addr_prop;
error_block *eblock = NULL;
data that propagates. */
copyflag(next, addr, af_propagate);
- next->p = addr_prop;
+ next->prop = addr_prop;
DEBUG(D_route) debug_printf("%s router autogenerated %s\n%s%s%s",
rblock->name,
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
*/
void
-rf_change_domain(address_item *addr, uschar *domain, BOOL rewrite,
+rf_change_domain(address_item *addr, const uschar *domain, BOOL rewrite,
address_item **addr_new)
{
address_item *parent = store_get(sizeof(address_item));
up the new fields. */
*addr = address_defaults;
-addr->p = parent->p;
+addr->prop = parent->prop;
addr->address = address;
addr->unique = string_copy(address);
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Header for the functions that are shared by the routers */
extern void rf_add_generated(router_instance *, address_item **,
address_item *, address_item *, uschar *, header_line *,
uschar *, ugid_block *, struct passwd *);
-extern void rf_change_domain(address_item *, uschar *, BOOL, address_item **);
+extern void rf_change_domain(address_item *, const uschar *, BOOL, address_item **);
extern uschar *rf_expand_data(address_item *, uschar *, int *);
extern int rf_get_errors_address(address_item *, router_instance *,
BOOL, uschar **);
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
#include "../exim.h"
{
uschar *s;
-*errors_to = addr->p.errors_address;
+*errors_to = addr->prop.errors_address;
if (rblock->errors_to == NULL) return OK;
s = expand_string(rblock->errors_to);
BOOL save_address_test_mode = address_test_mode;
int save1 = 0;
int i;
- uschar ***p;
- uschar *address_expansions_save[ADDRESS_EXPANSIONS_COUNT];
+ const uschar ***p;
+ const uschar *address_expansions_save[ADDRESS_EXPANSIONS_COUNT];
address_item *snew = deliver_make_addr(s, FALSE);
if (sender_address != NULL)
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
#include "../exim.h"
header_line **extra_headers, uschar **remove_headers)
{
/* Default is to retain existing headers */
-*extra_headers = addr->p.extra_headers;
+*extra_headers = addr->prop.extra_headers;
if (rblock->extra_headers)
{
- uschar * list = rblock->extra_headers;
+ const uschar * list = rblock->extra_headers;
int sep = '\n';
uschar * s;
int slen;
{
if (!expand_string_forcedfail)
{
- addr->message = string_sprintf("%s router failed to expand \"%s\": %s",
- rblock->name, rblock->extra_headers, expand_string_message);
+ addr->message = string_sprintf(
+ "%s router failed to expand add_headers item \"%s\": %s",
+ rblock->name, s, expand_string_message);
return DEFER;
}
}
}
/* Default is to retain existing removes */
-*remove_headers = addr->p.remove_headers;
+*remove_headers = addr->prop.remove_headers;
/* Expand items from colon-sep list separately, then build new list */
if (rblock->remove_headers)
{
- uschar * list = rblock->remove_headers;
+ const uschar * list = rblock->remove_headers;
int sep = ':';
uschar * s;
- uschar buffer[128];
- while ((s = string_nextinlist(&list, &sep, buffer, sizeof(buffer))))
+ while ((s = string_nextinlist(&list, &sep, NULL, 0)))
if (!(s = expand_string(s)))
{
if (!expand_string_forcedfail)
{
- addr->message = string_sprintf("%s router failed to expand \"%s\": %s",
- rblock->name, rblock->remove_headers, expand_string_message);
+ addr->message = string_sprintf(
+ "%s router failed to expand remove_headers item \"%s\": %s",
+ rblock->name, s, expand_string_message);
return DEFER;
}
}
return OK;
}
+/* vi: aw ai sw=4
+*/
/* End of rf_get_munge_headers.c */
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
list of MX hosts. If the first host is the local host, act according to the
"self" option in the configuration. */
-prev = NULL;
-for (h = addr->host_list; h != NULL; h = next_h)
+for (prev = NULL, h = addr->host_list; h; h = next_h)
{
- uschar *canonical_name;
- int rc, len, port;
+ const uschar *canonical_name;
+ int rc, len, port, mx, sort_key;
next_h = h->next;
- if (h->address != NULL) { prev = h; continue; }
+ if (h->address) { prev = h; continue; }
DEBUG(D_route|D_host_lookup)
debug_printf("finding IP address for %s\n", h->name);
port = host_item_get_port(h);
+ /* Store the previous mx and sort_key values, which were assigned in
+ host_build_hostlist and will be overwritten by host_find_bydns. */
+
+ mx = h->mx;
+ sort_key = h->sort_key;
+
/* If the name ends with "/MX", we interpret it to mean "the list of hosts
- pointed to by MX records with this name". */
+ pointed to by MX records with this name", and the MX record values override
+ the ordering from host_build_hostlist. */
len = Ustrlen(h->name);
if (len > 3 && strcmpic(h->name + len - 3, US"/mx") == 0)
DEBUG(D_route|D_host_lookup)
debug_printf("doing DNS MX lookup for %s\n", h->name);
+ mx = MX_NONE;
h->name = string_copyn(h->name, len - 3);
rc = host_find_bydns(h,
ignore_target_hosts,
NULL, /* SRV service not relevant */
NULL, /* failing srv domains not relevant */
NULL, /* no special mx failing domains */
- NULL, /* no dnssec request XXX ? */
- NULL, /* no dnssec require XXX ? */
+ &rblock->dnssec, /* dnssec request/require */
NULL, /* fully_qualified_name */
NULL); /* indicate local host removed */
}
{
BOOL removed;
DEBUG(D_route|D_host_lookup) debug_printf("doing DNS lookup\n");
- rc = host_find_bydns(h, ignore_target_hosts, HOST_FIND_BY_A, NULL, NULL,
- NULL,
- NULL, NULL, /*XXX dnssec? */
- &canonical_name, &removed);
- if (rc == HOST_FOUND)
- {
- if (removed) setflag(addr, af_local_host_removed);
- }
- else if (rc == HOST_FIND_FAILED)
+ switch (rc = host_find_bydns(h, ignore_target_hosts, HOST_FIND_BY_A, NULL,
+ NULL, NULL,
+ &rblock->dnssec, /* domains for request/require */
+ &canonical_name, &removed))
{
- if (lookup_type == lk_default)
- {
- DEBUG(D_route|D_host_lookup)
- debug_printf("DNS lookup failed: trying getipnodebyname\n");
- rc = host_find_byname(h, ignore_target_hosts, HOST_FIND_QUALIFY_SINGLE,
- &canonical_name, TRUE);
- }
+ case HOST_FOUND:
+ if (removed) setflag(addr, af_local_host_removed);
+ break;
+ case HOST_FIND_FAILED:
+ if (lookup_type == lk_default)
+ {
+ DEBUG(D_route|D_host_lookup)
+ debug_printf("DNS lookup failed: trying getipnodebyname\n");
+ rc = host_find_byname(h, ignore_target_hosts, HOST_FIND_QUALIFY_SINGLE,
+ &canonical_name, TRUE);
+ }
+ break;
}
}
if (hff_code == hff_pass) return PASS;
if (hff_code == hff_decline) return DECLINE;
+ addr->basic_errno = ERRNO_UNKNOWNHOST;
addr->message =
string_sprintf("lookup of host \"%s\" failed in %s router%s",
h->name, rblock->name,
return DEFER;
}
- /* Deal with a port setting */
+ /* Deal with the settings that were previously cleared:
+ port, mx and sort_key. */
if (port != PORT_NONE)
{
for (hh = h; hh != next_h; hh = hh->next) hh->port = port;
}
+ if (mx != MX_NONE)
+ {
+ host_item *hh;
+ for (hh = h; hh != next_h; hh = hh->next)
+ {
+ hh->mx = mx;
+ hh->sort_key = sort_key;
+ }
+ }
+
/* A local host gets chopped, with its successors, if there are previous
hosts. Otherwise the self option is used. If it is set to "send", any
subsequent hosts that are also the local host do NOT get chopped. */
if (rc == HOST_FOUND_LOCAL && !self_send)
{
- if (prev != NULL)
+ if (prev)
{
DEBUG(D_route)
{
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
#include "../exim.h"
rf_queue_add(address_item *addr, address_item **paddr_local,
address_item **paddr_remote, router_instance *rblock, struct passwd *pw)
{
-addr->p.domain_data = deliver_domain_data; /* Save these values for */
-addr->p.localpart_data = deliver_localpart_data; /* use in the transport */
+addr->prop.domain_data = deliver_domain_data; /* Save these values for */
+addr->prop.localpart_data = deliver_localpart_data; /* use in the transport */
/* Handle a local transport */
debug_printf("queued for %s transport: local_part = %s\ndomain = %s\n"
" errors_to=%s\n",
(addr->transport == NULL)? US"<unset>" : addr->transport->name,
- addr->local_part, addr->domain, addr->p.errors_address);
- debug_printf(" domain_data=%s localpart_data=%s\n", addr->p.domain_data,
- addr->p.localpart_data);
+ addr->local_part, addr->domain, addr->prop.errors_address);
+ debug_printf(" domain_data=%s localpart_data=%s\n", addr->prop.domain_data,
+ addr->prop.localpart_data);
}
return TRUE;
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* A set of functions to search databases in various formats. An open
*/
int
-search_findtype(uschar *name, int len)
+search_findtype(const uschar *name, int len)
{
int bot = 0;
int top = lookup_list_count;
*/
int
-search_findtype_partial(uschar *name, int *ptypeptr, uschar **ptypeaff,
+search_findtype_partial(const uschar *name, int *ptypeptr, const uschar **ptypeaff,
int *afflen, int *starflags)
{
int len, stype;
int pv = -1;
-uschar *ss = name;
+const uschar *ss = name;
*starflags = 0;
*ptypeaff = NULL;
{
tree_node *t = (tree_node *)handle;
search_cache *c = (search_cache *)(t->data.ptr);
+expiring_data *e;
uschar *data = NULL;
int search_type = t->name[0] - '0';
int old_pool = store_pool;
/* Look up the data for the key, unless it is already in the cache for this
file. No need to check c->item_cache for NULL, tree_search will do so. */
-if ((t = tree_search(c->item_cache, keystring)) == NULL)
+if ( (t = tree_search(c->item_cache, keystring))
+ && (!(e = t->data.ptr)->expiry || e->expiry > time(NULL))
+ )
+ { /* Data was in the cache already; set the pointer from the tree node */
+ data = e->ptr;
+ DEBUG(D_lookup) debug_printf("cached data used for lookup of %s%s%s\n",
+ keystring,
+ filename ? US"\n in " : US"", filename ? filename : US"");
+ }
+else
{
- BOOL do_cache = TRUE;
+ uint do_cache = UINT_MAX;
int keylength = Ustrlen(keystring);
DEBUG(D_lookup)
{
- if (filename != NULL)
- debug_printf("file lookup required for %s\n in %s\n",
- keystring, filename);
- else
- debug_printf("database lookup required for %s\n", keystring);
+ if (t) debug_printf("cached data found but past valid time; ");
+ debug_printf("%s lookup required for %s%s%s\n",
+ filename ? US"file" : US"database",
+ keystring,
+ filename ? US"\n in " : US"", filename ? filename : US"");
}
/* Call the code for the different kinds of search. DEFER is handled
if (lookup_list[search_type]->find(c->handle, filename, keystring, keylength,
&data, &search_error_message, &do_cache) == DEFER)
- {
search_find_defer = TRUE;
- }
/* A record that has been found is now in data, which is either NULL
or points to a bit of dynamic store. Cache the result of the lookup if
else if (do_cache)
{
int len = keylength + 1;
- t = store_get(sizeof(tree_node) + len);
- memcpy(t->name, keystring, len);
- t->data.ptr = data;
- tree_insertnode(&c->item_cache, t);
+
+ if (t) /* Previous, out-of-date cache entry. Update with the */
+ { /* new result and forget the old one */
+ e->expiry = do_cache == UINT_MAX ? 0 : time(NULL)+do_cache;
+ e->ptr = data;
+ }
+ else
+ {
+ e = store_get(sizeof(expiring_data) + sizeof(tree_node) + len);
+ e->expiry = do_cache == UINT_MAX ? 0 : time(NULL)+do_cache;
+ e->ptr = data;
+ t = (tree_node *)(e+1);
+ memcpy(t->name, keystring, len);
+ t->data.ptr = e;
+ tree_insertnode(&c->item_cache, t);
+ }
}
/* If caching was disabled, empty the cache tree. We just set the cache
}
}
-/* Data was in the cache already; set the pointer from the tree node */
-
-else
- {
- data = US t->data.ptr;
- DEBUG(D_lookup) debug_printf("cached data used for lookup of %s%s%s\n",
- keystring,
- (filename == NULL)? US"" : US"\n in ",
- (filename == NULL)? US"" : filename);
- }
-
-/* Debug: output the answer */
-
DEBUG(D_lookup)
{
- if (data == NULL)
- {
- if (search_find_defer) debug_printf("lookup deferred: %s\n",
- search_error_message);
- else debug_printf("lookup failed\n");
- }
- else debug_printf("lookup yielded: %s\n", data);
+ if (data)
+ debug_printf("lookup yielded: %s\n", data);
+ else if (search_find_defer)
+ debug_printf("lookup deferred: %s\n", search_error_message);
+ else debug_printf("lookup failed\n");
}
/* Return it in new dynamic store in the regular pool */
store_pool = old_pool;
-return (data == NULL)? NULL : string_copy(data);
+return data ? string_copy(data) : NULL;
}
uschar *
search_find(void *handle, uschar *filename, uschar *keystring, int partial,
- uschar *affix, int affixlen, int starflags, int *expand_setup)
+ const uschar *affix, int affixlen, int starflags, int *expand_setup)
{
tree_node *t = (tree_node *)handle;
BOOL set_null_wild = FALSE;
--- /dev/null
+/*************************************************
+* Exim - an Internet mail transport agent *
+*************************************************/
+
+/* Copyright (c) Michael Haardt 2015 */
+/* Copyright (c) Jeremy Harris 2015 */
+/* See the file NOTICE for conditions of use and distribution. */
+
+/* This module provides (un)setenv routines for those environments
+lacking them in libraries. */
+
+
+static int
+setenv(const char * name, const char * val, int overwrite)
+{
+uschar * s;
+if (Ustrchr(name, '=')) return -1;
+if (overwrite || !getenv(name))
+ putenv(CS string_copy_malloc(string_sprintf("%s=%s", name, val)));
+return 0;
+}
+
+static int
+unsetenv(const char *name)
+{
+size_t len;
+const char * end;
+char ** e;
+extern char ** environ;
+
+if (!name)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+for (end = name; *end != '=' && *end; ) end++;
+len = end - name;
+
+/* Find name in environment and move remaining variables down.
+Do not early-out in case there are duplicate names. */
+
+for (e = environ; *e; e++)
+ if (strncmp(*e, name, len) == 0 && (*e)[len] == '=')
+ {
+ char ** sp = e;
+ do *sp = sp[1]; while (*++sp);
+ }
+
+return 0;
+}
+
+/* vi: aw ai sw=2
+*/
+/* End of setenv.c */
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) Michael Haardt 2003-2008 */
+/* Copyright (c) Michael Haardt 2003 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* This code was contributed by Michael Haardt. */
setflag(new_addr, af_pfr|af_file);
new_addr->mode = 0;
}
-new_addr->p.errors_address = NULL;
+new_addr->prop.errors_address = NULL;
new_addr->next = *generated;
*generated = new_addr;
}
1 other success
-1 syntax or execution error
*/
-static int parse_commands(struct Sieve *filter, int exec,
- address_item **generated)
+static int
+parse_commands(struct Sieve *filter, int exec, address_item **generated)
{
while (*filter->pc)
{
int m;
struct String from;
struct String importance;
- struct String *options;
struct String message;
struct String method;
struct Notification *already;
from.length=-1;
importance.character=(uschar*)0;
importance.length=-1;
- options=(struct String*)0;
message.character=(uschar*)0;
message.length=-1;
recipient=NULL;
/* Allocation is larger than neccessary, but enough even for split MIME words */
buffer_capacity=32+4*subject.length;
buffer=store_get(buffer_capacity);
- addr->reply->subject=parse_quote_2047(subject.character, subject.length, US"utf-8", buffer, buffer_capacity, TRUE);
+ /* deconst cast safe as we pass in a non-const item */
+ addr->reply->subject = US parse_quote_2047(subject.character, subject.length, US"utf-8", buffer, buffer_capacity, TRUE);
addr->reply->oncelog=once;
addr->reply->once_repeat=days*86400;
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Functions for handling an incoming SMTP call. */
#include "exim.h"
+#include <assert.h>
/* Initialize for TCP wrappers if so configured. It appears that the macro
/* Size of buffer for reading SMTP commands. We used to use 512, as defined
by RFC 821. However, RFC 1869 specifies that this must be increased for SMTP
commands that accept arguments, and this in particular applies to AUTH, where
-the data can be quite long. More recently this value was 2048 in Exim;
+the data can be quite long. More recently this value was 2048 in Exim;
however, RFC 4954 (circa 2007) recommends 12288 bytes to handle AUTH. Clients
-such as Thunderbird will send an AUTH with an initial-response for GSSAPI.
-The maximum size of a Kerberos ticket under Windows 2003 is 12000 bytes, and
+such as Thunderbird will send an AUTH with an initial-response for GSSAPI.
+The maximum size of a Kerberos ticket under Windows 2003 is 12000 bytes, and
we need room to handle large base64-encoded AUTHs for GSSAPI.
*/
VRFY_CMD, EXPN_CMD, NOOP_CMD, /* RFC as requiring synchronization */
ETRN_CMD, /* This by analogy with TURN from the RFC */
STARTTLS_CMD, /* Required by the STARTTLS RFC */
+ TLS_AUTH_CMD, /* auto-command at start of SSL */
/* This is a dummy to identify the non-sync commands when pipelining */
QUIT_CMD, HELP_CMD,
-#ifdef EXPERIMENTAL_PROXY
+#ifdef SUPPORT_PROXY
PROXY_FAIL_IGNORE_CMD,
#endif
static BOOL rcpt_in_progress;
static int nonmail_command_count;
static BOOL smtp_exit_function_called = 0;
+#ifdef SUPPORT_I18N
+static BOOL smtputf8_advertised;
+#endif
static int synprot_error_count;
static int unknown_command_count;
static int sync_cmd_limit;
forced TRUE, to allow for the re-authentication that can happen at that point.
QUIT is also "falsely" labelled as a mail command so that it doesn't up the
-count of non-mail commands and possibly provoke an error. */
+count of non-mail commands and possibly provoke an error.
+
+tls_auth is a pseudo-command, never expected in input. It is activated
+on TLS startup and looks for a tls authenticator. */
static smtp_cmd_list cmd_list[] = {
+ /* name len cmd has_arg is_mail_cmd */
+
{ "rset", sizeof("rset")-1, RSET_CMD, FALSE, FALSE }, /* First */
{ "helo", sizeof("helo")-1, HELO_CMD, TRUE, FALSE },
{ "ehlo", sizeof("ehlo")-1, EHLO_CMD, TRUE, FALSE },
{ "auth", sizeof("auth")-1, AUTH_CMD, TRUE, TRUE },
#ifdef SUPPORT_TLS
{ "starttls", sizeof("starttls")-1, STARTTLS_CMD, FALSE, FALSE },
+ { "tls_auth", 0, TLS_AUTH_CMD, FALSE, TRUE },
#endif
/* If you change anything above here, also fix the definitions below. */
#define CMD_LIST_EHLO 2
#define CMD_LIST_AUTH 3
#define CMD_LIST_STARTTLS 4
+#define CMD_LIST_TLS_AUTH 5
/* This list of names is used for performing the smtp_no_mail logging action.
It must be kept in step with the SCH_xxx enumerations. */
US"HELP", US"MAIL", US"NOOP", US"QUIT", US"RCPT", US"RSET", US"STARTTLS",
US"VRFY" };
-static uschar *protocols[] = {
+static uschar *protocols_local[] = {
US"local-smtp", /* HELO */
US"local-smtps", /* The rare case EHLO->STARTTLS->HELO */
US"local-esmtp", /* EHLO */
US"local-esmtpa", /* EHLO->AUTH */
US"local-esmtpsa" /* EHLO->STARTTLS->EHLO->AUTH */
};
+static uschar *protocols[] = {
+ US"smtp", /* HELO */
+ US"smtps", /* The rare case EHLO->STARTTLS->HELO */
+ US"esmtp", /* EHLO */
+ US"esmtps", /* EHLO->STARTTLS->EHLO */
+ US"esmtpa", /* EHLO->AUTH */
+ US"esmtpsa" /* EHLO->STARTTLS->EHLO->AUTH */
+ };
#define pnormal 0
#define pextend 2
#define pcrpted 1 /* added to pextend or pnormal */
#define pauthed 2 /* added to pextend */
-#define pnlocal 6 /* offset to remove "local" */
/* Sanity check and validate optional args to MAIL FROM: envelope */
enum {
+ ENV_MAIL_OPT_NULL,
ENV_MAIL_OPT_SIZE, ENV_MAIL_OPT_BODY, ENV_MAIL_OPT_AUTH,
#ifndef DISABLE_PRDR
ENV_MAIL_OPT_PRDR,
#endif
ENV_MAIL_OPT_RET, ENV_MAIL_OPT_ENVID,
- ENV_MAIL_OPT_NULL
+#ifdef SUPPORT_I18N
+ ENV_MAIL_OPT_UTF8,
+#endif
};
typedef struct {
uschar * name; /* option requested during MAIL cmd */
#endif
{ US"RET", ENV_MAIL_OPT_RET, TRUE },
{ US"ENVID", ENV_MAIL_OPT_ENVID, TRUE },
- { US"NULL", ENV_MAIL_OPT_NULL, FALSE }
+#ifdef SUPPORT_I18N
+ { US"SMTPUTF8",ENV_MAIL_OPT_UTF8, FALSE }, /* rfc6531 */
+#endif
+ /* keep this the last entry */
+ { US"NULL", ENV_MAIL_OPT_NULL, FALSE },
};
/* When reading SMTP from a remote host, we have to use our own versions of the
-#ifdef EXPERIMENTAL_PROXY
+#ifdef SUPPORT_PROXY
/*************************************************
* Restore socket timeout to previous value *
*************************************************/
/* Cannot configure local connection as a proxy inbound */
if (sender_host_address == NULL) return proxy_session;
-rc = verify_check_this_host(&proxy_required_hosts, NULL, NULL,
+rc = verify_check_this_host(CUSS &hosts_proxy, NULL, NULL,
sender_host_address, NULL);
if (rc == OK)
{
DEBUG(D_receive) debug_printf("Invalid %s source IP\n", iptype);
return ERRNO_PROXYFAIL;
}
- proxy_host_address = sender_host_address;
+ proxy_local_address = sender_host_address;
sender_host_address = string_copy(US tmpip);
tmpport = ntohs(hdr.v2.addr.ip4.src_port);
- proxy_host_port = sender_host_port;
+ proxy_local_port = sender_host_port;
sender_host_port = tmpport;
/* Save dest ip/port */
tmpaddr.sin_addr.s_addr = hdr.v2.addr.ip4.dst_addr;
DEBUG(D_receive) debug_printf("Invalid %s dest port\n", iptype);
return ERRNO_PROXYFAIL;
}
- proxy_target_address = string_copy(US tmpip);
+ proxy_external_address = string_copy(US tmpip);
tmpport = ntohs(hdr.v2.addr.ip4.dst_port);
- proxy_target_port = tmpport;
+ proxy_external_port = tmpport;
goto done;
case 0x21: /* TCPv6 address type */
iptype = US"IPv6";
DEBUG(D_receive) debug_printf("Invalid %s source IP\n", iptype);
return ERRNO_PROXYFAIL;
}
- proxy_host_address = sender_host_address;
+ proxy_local_address = sender_host_address;
sender_host_address = string_copy(US tmpip6);
tmpport = ntohs(hdr.v2.addr.ip6.src_port);
- proxy_host_port = sender_host_port;
+ proxy_local_port = sender_host_port;
sender_host_port = tmpport;
/* Save dest ip/port */
memmove(tmpaddr6.sin6_addr.s6_addr, hdr.v2.addr.ip6.dst_addr, 16);
DEBUG(D_receive) debug_printf("Invalid %s dest port\n", iptype);
return ERRNO_PROXYFAIL;
}
- proxy_target_address = string_copy(US tmpip6);
+ proxy_external_address = string_copy(US tmpip6);
tmpport = ntohs(hdr.v2.addr.ip6.dst_port);
- proxy_target_port = tmpport;
+ proxy_external_port = tmpport;
goto done;
default:
DEBUG(D_receive)
debug_printf("Proxied src arg is not an %s address\n", iptype);
goto proxyfail;
}
- proxy_host_address = sender_host_address;
+ proxy_local_address = sender_host_address;
sender_host_address = p;
p = sp + 1;
if ((sp = Ustrchr(p, ' ')) == NULL)
debug_printf("Proxy dest arg is not an %s address\n", iptype);
goto proxyfail;
}
- proxy_target_address = p;
+ proxy_external_address = p;
p = sp + 1;
if ((sp = Ustrchr(p, ' ')) == NULL)
{
debug_printf("Proxied src port '%s' not an integer\n", p);
goto proxyfail;
}
- proxy_host_port = sender_host_port;
+ proxy_local_port = sender_host_port;
sender_host_port = tmp_port;
p = sp + 1;
if ((sp = Ustrchr(p, '\0')) == NULL)
debug_printf("Proxy dest port '%s' not an integer\n", p);
goto proxyfail;
}
- proxy_target_port = tmp_port;
+ proxy_external_port = tmp_port;
/* Already checked for /r /n above. Good V1 header received. */
goto done;
}
for (p = cmd_list; p < cmd_list_end; p++)
{
- #ifdef EXPERIMENTAL_PROXY
+ #ifdef SUPPORT_PROXY
/* Only allow QUIT command if Proxy Protocol parsing failed */
if (proxy_session && proxy_session_failed)
{
continue;
}
#endif
- if (strncmpic(smtp_cmd_buffer, US p->name, p->len) == 0 &&
- (smtp_cmd_buffer[p->len-1] == ':' || /* "mail from:" or "rcpt to:" */
- smtp_cmd_buffer[p->len] == 0 ||
- smtp_cmd_buffer[p->len] == ' '))
+ if ( p->len
+ && strncmpic(smtp_cmd_buffer, US p->name, p->len) == 0
+ && ( smtp_cmd_buffer[p->len-1] == ':' /* "mail from:" or "rcpt to:" */
+ || smtp_cmd_buffer[p->len] == 0
+ || smtp_cmd_buffer[p->len] == ' '
+ ) )
{
if (smtp_inptr < smtp_inend && /* Outstanding input */
p->cmd < sync_cmd_limit && /* Command should sync */
}
}
-#ifdef EXPERIMENTAL_PROXY
+#ifdef SUPPORT_PROXY
/* Only allow QUIT command if Proxy Protocol parsing failed */
if (proxy_session && proxy_session_failed)
return PROXY_FAIL_IGNORE_CMD;
if (is_inetd)
return string_sprintf("SMTP connection from %s (via inetd)", hostname);
-if ((log_extra_selector & LX_incoming_interface) != 0 &&
- interface_address != NULL)
+if (LOGGING(incoming_interface) && interface_address != NULL)
return string_sprintf("SMTP connection from %s I=[%s]:%d", hostname,
interface_address, interface_port);
int size = sizep ? *sizep : 0;
int ptr = ptrp ? *ptrp : 0;
- if ((log_extra_selector & LX_tls_cipher) != 0 && tls_in.cipher != NULL)
+ if (LOGGING(tls_cipher) && tls_in.cipher != NULL)
s = string_append(s, &size, &ptr, 2, US" X=", tls_in.cipher);
- if ((log_extra_selector & LX_tls_certificate_verified) != 0 &&
- tls_in.cipher != NULL)
+ if (LOGGING(tls_certificate_verified) && tls_in.cipher != NULL)
s = string_append(s, &size, &ptr, 2, US" CV=",
tls_in.certificate_verified? "yes":"no");
- if ((log_extra_selector & LX_tls_peerdn) != 0 && tls_in.peerdn != NULL)
+ if (LOGGING(tls_peerdn) && tls_in.peerdn != NULL)
s = string_append(s, &size, &ptr, 3, US" DN=\"",
string_printing(tls_in.peerdn), US"\"");
- if ((log_extra_selector & LX_tls_sni) != 0 && tls_in.sni != NULL)
+ if (LOGGING(tls_sni) && tls_in.sni != NULL)
s = string_append(s, &size, &ptr, 3, US" SNI=\"",
string_printing(tls_in.sni), US"\"");
int size, ptr, i;
uschar *s, *sep;
-if (smtp_mailcmd_count > 0 || (log_extra_selector & LX_smtp_no_mail) == 0)
+if (smtp_mailcmd_count > 0 || !LOGGING(smtp_no_mail))
return;
s = NULL;
memset(sender_address_cache, 0, sizeof(sender_address_cache));
memset(sender_domain_cache, 0, sizeof(sender_domain_cache));
+#ifndef DISABLE_PRDR
+prdr_requested = FALSE;
+#endif
+
/* Reset the DSN flags */
dsn_ret = 0;
dsn_envid = NULL;
spf_result = NULL;
spf_smtp_comment = NULL;
#endif
+#ifdef SUPPORT_I18N
+message_smtputf8 = FALSE;
+#endif
body_linecount = body_zerocount = 0;
sender_rate = sender_rate_limit = sender_rate_period = NULL;
it is the canonical extracted address which is all that is kept. */
case MAIL_CMD:
+ smtp_mailcmd_count++; /* Count for no-mail log */
if (sender_address != NULL)
/* The function moan_smtp_batch() does not return. */
moan_smtp_batch(smtp_cmd_buffer, "503 Sender already given");
sync_cmd_limit = NON_SYNC_CMD_NON_PIPELINING;
smtp_exit_function_called = FALSE; /* For avoiding loop in not-quit exit */
-memset(sender_host_cache, 0, sizeof(sender_host_cache));
-
/* If receiving by -bs from a trusted user, or testing with -bh, we allow
authentication settings from -oMaa to remain in force. */
tls_advertised = FALSE;
#endif
dsn_advertised = FALSE;
+#ifdef SUPPORT_I18N
+smtputf8_advertised = FALSE;
+#endif
/* Reset ACL connection variables */
else
received_protocol =
- protocols[pnormal] + ((sender_host_address != NULL)? pnlocal : 0);
+ (sender_host_address ? protocols : protocols_local) [pnormal];
/* Set up the buffer for inputting using direct read() calls, and arrange to
call the local functions instead of the standard C ones. */
if (smtp_batched_input) return TRUE;
-#ifdef EXPERIMENTAL_PROXY
+#ifdef SUPPORT_PROXY
/* If valid Proxy Protocol source is connecting, set up session.
* Failure will not allow any SMTP function other than QUIT. */
proxy_session = FALSE;
yield = 1;
log_write(0, LOG_MAIN|LOG_REJECT, "SMTP call from %s dropped: too many "
"syntax or protocol errors (last command was \"%s\")",
- host_and_ident(FALSE), smtp_cmd_buffer);
+ host_and_ident(FALSE), string_printing(smtp_cmd_buffer));
}
if (code > 0)
incomplete_transaction_log(uschar *what)
{
if (sender_address == NULL || /* No transaction in progress */
- (log_write_selector & L_smtp_incomplete_transaction) == 0 /* Not logging */
- ) return;
+ !LOGGING(smtp_incomplete_transaction))
+ return;
/* Build list of recipients for logging */
setflag(sender_verified_failed, af_sverify_told);
- if (rc != FAIL || (log_extra_selector & LX_sender_verify_fail) != 0)
+ if (rc != FAIL || LOGGING(sender_verify_fail))
log_write(0, LOG_MAIN|LOG_REJECT, "%s sender verify %s for <%s>%s",
host_and_ident(TRUE),
((sender_verified_failed->special_action & 255) == DEFER)? "defer":"fail",
/* If a host name is known, check it and all its aliases. */
- if (sender_host_name != NULL)
- {
- helo_verified = strcmpic(sender_host_name, sender_helo_name) == 0;
-
- if (helo_verified)
+ if (sender_host_name)
+ if ((helo_verified = strcmpic(sender_host_name, sender_helo_name) == 0))
{
+ sender_helo_dnssec = sender_host_dnssec;
HDEBUG(D_receive) debug_printf("matched host name\n");
}
else
{
uschar **aliases = sender_host_aliases;
- while (*aliases != NULL)
- {
- helo_verified = strcmpic(*aliases++, sender_helo_name) == 0;
- if (helo_verified) break;
- }
- HDEBUG(D_receive)
- {
- if (helo_verified)
+ while (*aliases)
+ if ((helo_verified = strcmpic(*aliases++, sender_helo_name) == 0))
+ {
+ sender_helo_dnssec = sender_host_dnssec;
+ break;
+ }
+
+ HDEBUG(D_receive) if (helo_verified)
debug_printf("matched alias %s\n", *(--aliases));
- }
}
- }
/* Final attempt: try a forward lookup of the helo name */
{
int rc;
host_item h;
+ dnssec_domains d;
+ host_item *hh;
+
h.name = sender_helo_name;
h.address = NULL;
h.mx = MX_NONE;
h.next = NULL;
+ d.request = US"*";
+ d.require = US"";
+
HDEBUG(D_receive) debug_printf("getting IP address for %s\n",
sender_helo_name);
- rc = host_find_byname(&h, NULL, 0, NULL, TRUE);
+ rc = host_find_bydns(&h, NULL, HOST_FIND_BY_A,
+ NULL, NULL, NULL, &d, NULL, NULL);
if (rc == HOST_FOUND || rc == HOST_FOUND_LOCAL)
- {
- host_item *hh = &h;
- while (hh != NULL)
- {
+ for (hh = &h; hh; hh = hh->next)
if (Ustrcmp(hh->address, sender_host_address) == 0)
{
helo_verified = TRUE;
+ if (h.dnssec == DS_YES) sender_helo_dnssec = TRUE;
HDEBUG(D_receive)
- debug_printf("IP address for %s matches calling address\n",
- sender_helo_name);
+ {
+ debug_printf("IP address for %s matches calling address\n"
+ "Forward DNS security status: %sverified\n",
+ sender_helo_name, sender_helo_dnssec ? "" : "un");
+ }
break;
}
- hh = hh->next;
- }
- }
}
}
+static int
+smtp_in_auth(auth_instance *au, uschar ** s, uschar ** ss)
+{
+const uschar *set_id = NULL;
+int rc, i;
+
+/* Run the checking code, passing the remainder of the command line as
+data. Initials the $auth<n> variables as empty. Initialize $0 empty and set
+it as the only set numerical variable. The authenticator may set $auth<n>
+and also set other numeric variables. The $auth<n> variables are preferred
+nowadays; the numerical variables remain for backwards compatibility.
+
+Afterwards, have a go at expanding the set_id string, even if
+authentication failed - for bad passwords it can be useful to log the
+userid. On success, require set_id to expand and exist, and put it in
+authenticated_id. Save this in permanent store, as the working store gets
+reset at HELO, RSET, etc. */
+
+for (i = 0; i < AUTH_VARS; i++) auth_vars[i] = NULL;
+expand_nmax = 0;
+expand_nlength[0] = 0; /* $0 contains nothing */
+
+rc = (au->info->servercode)(au, smtp_cmd_data);
+if (au->set_id) set_id = expand_string(au->set_id);
+expand_nmax = -1; /* Reset numeric variables */
+for (i = 0; i < AUTH_VARS; i++) auth_vars[i] = NULL; /* Reset $auth<n> */
+
+/* The value of authenticated_id is stored in the spool file and printed in
+log lines. It must not contain binary zeros or newline characters. In
+normal use, it never will, but when playing around or testing, this error
+can (did) happen. To guard against this, ensure that the id contains only
+printing characters. */
+
+if (set_id) set_id = string_printing(set_id);
+
+/* For the non-OK cases, set up additional logging data if set_id
+is not empty. */
+
+if (rc != OK)
+ set_id = set_id && *set_id
+ ? string_sprintf(" (set_id=%s)", set_id) : US"";
+
+/* Switch on the result */
+
+switch(rc)
+ {
+ case OK:
+ if (!au->set_id || set_id) /* Complete success */
+ {
+ if (set_id) authenticated_id = string_copy_malloc(set_id);
+ sender_host_authenticated = au->name;
+ authentication_failed = FALSE;
+ authenticated_fail_id = NULL; /* Impossible to already be set? */
+
+ received_protocol =
+ (sender_host_address ? protocols : protocols_local)
+ [pextend + pauthed + (tls_in.active >= 0 ? pcrpted:0)];
+ *s = *ss = US"235 Authentication succeeded";
+ authenticated_by = au;
+ break;
+ }
+
+ /* Authentication succeeded, but we failed to expand the set_id string.
+ Treat this as a temporary error. */
+
+ auth_defer_msg = expand_string_message;
+ /* Fall through */
+
+ case DEFER:
+ if (set_id) authenticated_fail_id = string_copy_malloc(set_id);
+ *s = string_sprintf("435 Unable to authenticate at present%s",
+ auth_defer_user_msg);
+ *ss = string_sprintf("435 Unable to authenticate at present%s: %s",
+ set_id, auth_defer_msg);
+ break;
+
+ case BAD64:
+ *s = *ss = US"501 Invalid base64 data";
+ break;
+
+ case CANCELLED:
+ *s = *ss = US"501 Authentication cancelled";
+ break;
+
+ case UNEXPECTED:
+ *s = *ss = US"553 Initial data not expected";
+ break;
+
+ case FAIL:
+ if (set_id) authenticated_fail_id = string_copy_malloc(set_id);
+ *s = US"535 Incorrect authentication data";
+ *ss = string_sprintf("535 Incorrect authentication data%s", set_id);
+ break;
+
+ default:
+ if (set_id) authenticated_fail_id = string_copy_malloc(set_id);
+ *s = US"435 Internal error";
+ *ss = string_sprintf("435 Internal error%s: return %d from authentication "
+ "check", set_id, rc);
+ break;
+ }
+
+return rc;
+}
+
+
+
/*************************************************
* Initialize for SMTP incoming message *
*************************************************/
cmd_list[CMD_LIST_EHLO].is_mail_cmd = TRUE;
#ifdef SUPPORT_TLS
cmd_list[CMD_LIST_STARTTLS].is_mail_cmd = TRUE;
+cmd_list[CMD_LIST_TLS_AUTH].is_mail_cmd = TRUE;
#endif
/* Set the local signal handler for SIGTERM - it tries to end off tidily */
while (done <= 0)
{
- uschar **argv;
+ const uschar **argv;
uschar *etrn_command;
uschar *etrn_serialize_key;
uschar *errmess;
uschar *user_msg = NULL;
uschar *recipient = NULL;
uschar *hello = NULL;
- uschar *set_id = NULL;
uschar *s, *ss;
BOOL was_rej_mail = FALSE;
BOOL was_rcpt = FALSE;
pid_t pid;
int start, end, sender_domain, recipient_domain;
int ptr, size, rc;
- int c, i;
+ int c;
auth_instance *au;
uschar *orcpt = NULL;
int flags;
+#if defined(SUPPORT_TLS) && defined(AUTH_TLS)
+ /* Check once per STARTTLS or SSL-on-connect for a TLS AUTH */
+ if ( tls_in.active >= 0
+ && tls_in.peercert
+ && tls_in.certificate_verified
+ && cmd_list[CMD_LIST_TLS_AUTH].is_mail_cmd
+ )
+ {
+ cmd_list[CMD_LIST_TLS_AUTH].is_mail_cmd = FALSE;
+ if (acl_smtp_auth)
+ {
+ rc = acl_check(ACL_WHERE_AUTH, NULL, acl_smtp_auth, &user_msg, &log_msg);
+ if (rc != OK)
+ {
+ done = smtp_handle_acl_fail(ACL_WHERE_AUTH, rc, user_msg, log_msg);
+ continue;
+ }
+ }
+
+ for (au = auths; au; au = au->next)
+ if (strcmpic(US"tls", au->driver_name) == 0)
+ {
+ smtp_cmd_data = NULL;
+
+ if (smtp_in_auth(au, &s, &ss) == OK)
+ DEBUG(D_auth) debug_printf("tls auth succeeded\n");
+ else
+ DEBUG(D_auth) debug_printf("tls auth not succeeded\n");
+ break;
+ }
+ }
+#endif
+
switch(smtp_read_command(TRUE))
{
/* The AUTH command is not permitted to occur inside a transaction, and may
US"AUTH command used when not advertised");
break;
}
- if (sender_host_authenticated != NULL)
+ if (sender_host_authenticated)
{
done = synprot_error(L_smtp_protocol_error, 503, NULL,
US"already authenticated");
break;
}
- if (sender_address != NULL)
+ if (sender_address)
{
done = synprot_error(L_smtp_protocol_error, 503, NULL,
US"not permitted in mail transaction");
/* Check the ACL */
- if (acl_smtp_auth != NULL)
+ if (acl_smtp_auth)
{
rc = acl_check(ACL_WHERE_AUTH, NULL, acl_smtp_auth, &user_msg, &log_msg);
if (rc != OK)
as a server and which has been advertised (unless, sigh, allow_auth_
unadvertised is set). */
- for (au = auths; au != NULL; au = au->next)
- {
+ for (au = auths; au; au = au->next)
if (strcmpic(s, au->public_name) == 0 && au->server &&
- (au->advertised || allow_auth_unadvertised)) break;
- }
-
- if (au == NULL)
- {
- done = synprot_error(L_smtp_protocol_error, 504, NULL,
- string_sprintf("%s authentication mechanism not supported", s));
- break;
- }
-
- /* Run the checking code, passing the remainder of the command line as
- data. Initials the $auth<n> variables as empty. Initialize $0 empty and set
- it as the only set numerical variable. The authenticator may set $auth<n>
- and also set other numeric variables. The $auth<n> variables are preferred
- nowadays; the numerical variables remain for backwards compatibility.
-
- Afterwards, have a go at expanding the set_id string, even if
- authentication failed - for bad passwords it can be useful to log the
- userid. On success, require set_id to expand and exist, and put it in
- authenticated_id. Save this in permanent store, as the working store gets
- reset at HELO, RSET, etc. */
+ (au->advertised || allow_auth_unadvertised))
+ break;
- for (i = 0; i < AUTH_VARS; i++) auth_vars[i] = NULL;
- expand_nmax = 0;
- expand_nlength[0] = 0; /* $0 contains nothing */
-
- c = (au->info->servercode)(au, smtp_cmd_data);
- if (au->set_id != NULL) set_id = expand_string(au->set_id);
- expand_nmax = -1; /* Reset numeric variables */
- for (i = 0; i < AUTH_VARS; i++) auth_vars[i] = NULL; /* Reset $auth<n> */
-
- /* The value of authenticated_id is stored in the spool file and printed in
- log lines. It must not contain binary zeros or newline characters. In
- normal use, it never will, but when playing around or testing, this error
- can (did) happen. To guard against this, ensure that the id contains only
- printing characters. */
-
- if (set_id != NULL) set_id = string_printing(set_id);
-
- /* For the non-OK cases, set up additional logging data if set_id
- is not empty. */
-
- if (c != OK)
+ if (au)
{
- if (set_id != NULL && *set_id != 0)
- set_id = string_sprintf(" (set_id=%s)", set_id);
- else set_id = US"";
- }
+ c = smtp_in_auth(au, &s, &ss);
- /* Switch on the result */
-
- switch(c)
- {
- case OK:
- if (au->set_id == NULL || set_id != NULL) /* Complete success */
- {
- if (set_id != NULL) authenticated_id = string_copy_malloc(set_id);
- sender_host_authenticated = au->name;
- authentication_failed = FALSE;
- authenticated_fail_id = NULL; /* Impossible to already be set? */
- received_protocol =
- protocols[pextend + pauthed + ((tls_in.active >= 0)? pcrpted:0)] +
- ((sender_host_address != NULL)? pnlocal : 0);
- s = ss = US"235 Authentication succeeded";
- authenticated_by = au;
- break;
- }
-
- /* Authentication succeeded, but we failed to expand the set_id string.
- Treat this as a temporary error. */
-
- auth_defer_msg = expand_string_message;
- /* Fall through */
-
- case DEFER:
- if (set_id != NULL) authenticated_fail_id = string_copy_malloc(set_id);
- s = string_sprintf("435 Unable to authenticate at present%s",
- auth_defer_user_msg);
- ss = string_sprintf("435 Unable to authenticate at present%s: %s",
- set_id, auth_defer_msg);
- break;
-
- case BAD64:
- s = ss = US"501 Invalid base64 data";
- break;
-
- case CANCELLED:
- s = ss = US"501 Authentication cancelled";
- break;
-
- case UNEXPECTED:
- s = ss = US"553 Initial data not expected";
- break;
-
- case FAIL:
- if (set_id != NULL) authenticated_fail_id = string_copy_malloc(set_id);
- s = US"535 Incorrect authentication data";
- ss = string_sprintf("535 Incorrect authentication data%s", set_id);
- break;
-
- default:
- if (set_id != NULL) authenticated_fail_id = string_copy_malloc(set_id);
- s = US"435 Internal error";
- ss = string_sprintf("435 Internal error%s: return %d from authentication "
- "check", set_id, c);
- break;
+ smtp_printf("%s\r\n", s);
+ if (c != OK)
+ log_write(0, LOG_MAIN|LOG_REJECT, "%s authenticator failed for %s: %s",
+ au->name, host_and_ident(FALSE), ss);
}
-
- smtp_printf("%s\r\n", s);
- if (c != OK)
- log_write(0, LOG_MAIN|LOG_REJECT, "%s authenticator failed for %s: %s",
- au->name, host_and_ident(FALSE), ss);
+ else
+ done = synprot_error(L_smtp_protocol_error, 504, NULL,
+ string_sprintf("%s authentication mechanism not supported", s));
break; /* AUTH_CMD */
{
log_write(0, LOG_MAIN|LOG_REJECT, "SMTP call from %s dropped: too many "
"syntax or protocol errors (last command was \"%s\")",
- host_and_ident(FALSE), smtp_cmd_buffer);
+ host_and_ident(FALSE), string_printing(smtp_cmd_buffer));
done = 1;
}
if (sender_host_name == NULL &&
(deliver_domain = sender_helo_name, /* set $domain */
- match_isinlist(sender_helo_name, &helo_lookup_domains, 0,
+ match_isinlist(sender_helo_name, CUSS &helo_lookup_domains, 0,
&domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL)) == OK)
(void)host_name_lookup();
now obsolescent, since the verification can now be requested selectively
at ACL time. */
- helo_verified = helo_verify_failed = FALSE;
+ helo_verified = helo_verify_failed = sender_helo_dnssec = FALSE;
if (helo_required || helo_verify)
{
BOOL tempfail = !smtp_verify_helo();
auth_advertised = FALSE;
pipelining_advertised = FALSE;
- #ifdef SUPPORT_TLS
+#ifdef SUPPORT_TLS
tls_advertised = FALSE;
- #endif
+#endif
dsn_advertised = FALSE;
+#ifdef SUPPORT_I18N
+ smtputf8_advertised = FALSE;
+#endif
smtp_code = US"250 "; /* Default response code plus space*/
if (user_msg == NULL)
}
/* Advertise DSN support if configured to do so. */
- if (verify_check_host(&dsn_advertise_hosts) != FAIL)
+ if (verify_check_host(&dsn_advertise_hosts) != FAIL)
{
s = string_cat(s, &size, &ptr, smtp_code, 3);
s = string_cat(s, &size, &ptr, US"-DSN\r\n", 6);
letters, so output the names in upper case, though we actually recognize
them in either case in the AUTH command. */
- if (auths != NULL)
- {
- if (verify_check_host(&auth_advertise_hosts) == OK)
- {
- auth_instance *au;
- BOOL first = TRUE;
- for (au = auths; au != NULL; au = au->next)
- {
- if (au->server && (au->advertise_condition == NULL ||
- expand_check_condition(au->advertise_condition, au->name,
- US"authenticator")))
- {
- int saveptr;
- if (first)
- {
- s = string_cat(s, &size, &ptr, smtp_code, 3);
- s = string_cat(s, &size, &ptr, US"-AUTH", 5);
- first = FALSE;
- auth_advertised = TRUE;
- }
- saveptr = ptr;
- s = string_cat(s, &size, &ptr, US" ", 1);
- s = string_cat(s, &size, &ptr, au->public_name,
- Ustrlen(au->public_name));
- while (++saveptr < ptr) s[saveptr] = toupper(s[saveptr]);
- au->advertised = TRUE;
- }
- else au->advertised = FALSE;
- }
- if (!first) s = string_cat(s, &size, &ptr, US"\r\n", 2);
- }
- }
+ if ( auths
+#if defined(SUPPORT_TLS) && defined(AUTH_TLS)
+ && !sender_host_authenticated
+#endif
+ && verify_check_host(&auth_advertise_hosts) == OK
+ )
+ {
+ auth_instance *au;
+ BOOL first = TRUE;
+ for (au = auths; au; au = au->next)
+ if (au->server && (au->advertise_condition == NULL ||
+ expand_check_condition(au->advertise_condition, au->name,
+ US"authenticator")))
+ {
+ int saveptr;
+ if (first)
+ {
+ s = string_cat(s, &size, &ptr, smtp_code, 3);
+ s = string_cat(s, &size, &ptr, US"-AUTH", 5);
+ first = FALSE;
+ auth_advertised = TRUE;
+ }
+ saveptr = ptr;
+ s = string_cat(s, &size, &ptr, US" ", 1);
+ s = string_cat(s, &size, &ptr, au->public_name,
+ Ustrlen(au->public_name));
+ while (++saveptr < ptr) s[saveptr] = toupper(s[saveptr]);
+ au->advertised = TRUE;
+ }
+ else
+ au->advertised = FALSE;
+
+ if (!first) s = string_cat(s, &size, &ptr, US"\r\n", 2);
+ }
/* Advertise TLS (Transport Level Security) aka SSL (Secure Socket Layer)
if it has been included in the binary, and the host matches
tls_advertise_hosts. We must *not* advertise if we are already in a
secure connection. */
- #ifdef SUPPORT_TLS
+#ifdef SUPPORT_TLS
if (tls_in.active < 0 &&
verify_check_host(&tls_advertise_hosts) != FAIL)
{
s = string_cat(s, &size, &ptr, US"-STARTTLS\r\n", 11);
tls_advertised = TRUE;
}
- #endif
+#endif
- #ifndef DISABLE_PRDR
+#ifndef DISABLE_PRDR
/* Per Recipient Data Response, draft by Eric A. Hall extending RFC */
if (prdr_enable)
{
s = string_cat(s, &size, &ptr, smtp_code, 3);
s = string_cat(s, &size, &ptr, US"-PRDR\r\n", 7);
}
- #endif
+#endif
+
+#ifdef SUPPORT_I18N
+ if ( accept_8bitmime
+ && verify_check_host(&smtputf8_advertise_hosts) != FAIL)
+ {
+ s = string_cat(s, &size, &ptr, smtp_code, 3);
+ s = string_cat(s, &size, &ptr, US"-SMTPUTF8\r\n", 11);
+ smtputf8_advertised = TRUE;
+ }
+#endif
/* Finish off the multiline reply with one that is always available. */
s[ptr] = 0;
- #ifdef SUPPORT_TLS
+#ifdef SUPPORT_TLS
if (tls_in.active >= 0) (void)tls_write(TRUE, s, ptr); else
- #endif
+#endif
{
int i = fwrite(s, 1, ptr, smtp_out); i = i; /* compiler quietening */
helo_seen = TRUE;
/* Reset the protocol and the state, abandoning any previous message. */
-
- received_protocol = (esmtp?
- protocols[pextend +
- ((sender_host_authenticated != NULL)? pauthed : 0) +
- ((tls_in.active >= 0)? pcrpted : 0)]
- :
- protocols[pnormal + ((tls_in.active >= 0)? pcrpted : 0)])
- +
- ((sender_host_address != NULL)? pnlocal : 0);
-
+ received_protocol =
+ (sender_host_address ? protocols : protocols_local)
+ [ (esmtp
+ ? pextend + (sender_host_authenticated ? pauthed : 0)
+ : pnormal)
+ + (tls_in.active >= 0 ? pcrpted : 0)
+ ];
smtp_reset(reset_point);
toomany = FALSE;
break; /* HELO/EHLO */
if (!extract_option(&name, &value)) break;
for (mail_args = env_mail_type_list;
- (char *)mail_args < (char *)env_mail_type_list + sizeof(env_mail_type_list);
+ mail_args->value != ENV_MAIL_OPT_NULL;
mail_args++
)
- {
if (strcmpic(name, mail_args->name) == 0)
break;
- }
if (mail_args->need_value && strcmpic(value, US"") == 0)
break;
and "7BIT" as body types, but take no action. */
case ENV_MAIL_OPT_BODY:
if (accept_8bitmime) {
- if (strcmpic(value, US"8BITMIME") == 0) {
+ if (strcmpic(value, US"8BITMIME") == 0)
body_8bitmime = 8;
- } else if (strcmpic(value, US"7BIT") == 0) {
+ else if (strcmpic(value, US"7BIT") == 0)
body_8bitmime = 7;
- } else {
+ else
+ {
body_8bitmime = 0;
done = synprot_error(L_smtp_syntax_error, 501, NULL,
US"invalid data for BODY");
goto COMMAND_LOOP;
- }
+ }
DEBUG(D_receive) debug_printf("8BITMIME: %d\n", body_8bitmime);
break;
}
is included only if configured in at build time. */
case ENV_MAIL_OPT_RET:
- if (dsn_advertised) {
+ if (dsn_advertised)
+ {
/* Check if RET has already been set */
- if (dsn_ret > 0) {
+ if (dsn_ret > 0)
+ {
synprot_error(L_smtp_syntax_error, 501, NULL,
US"RET can be specified once only");
goto COMMAND_LOOP;
- }
- dsn_ret = (strcmpic(value, US"HDRS") == 0)? dsn_ret_hdrs :
- (strcmpic(value, US"FULL") == 0)? dsn_ret_full : 0;
+ }
+ dsn_ret = strcmpic(value, US"HDRS") == 0
+ ? dsn_ret_hdrs
+ : strcmpic(value, US"FULL") == 0
+ ? dsn_ret_full
+ : 0;
DEBUG(D_receive) debug_printf("DSN_RET: %d\n", dsn_ret);
/* Check for invalid invalid value, and exit with error */
- if (dsn_ret == 0) {
+ if (dsn_ret == 0)
+ {
synprot_error(L_smtp_syntax_error, 501, NULL,
US"Value for RET is invalid");
goto COMMAND_LOOP;
- }
- }
+ }
+ }
break;
case ENV_MAIL_OPT_ENVID:
- if (dsn_advertised) {
+ if (dsn_advertised)
+ {
/* Check if the dsn envid has been already set */
- if (dsn_envid != NULL) {
+ if (dsn_envid != NULL)
+ {
synprot_error(L_smtp_syntax_error, 501, NULL,
US"ENVID can be specified once only");
goto COMMAND_LOOP;
- }
+ }
dsn_envid = string_copy(value);
DEBUG(D_receive) debug_printf("DSN_ENVID: %s\n", dsn_envid);
- }
+ }
break;
/* Handle the AUTH extension. If the value given is not "<>" and either
rc = acl_check(ACL_WHERE_MAILAUTH, NULL, acl_smtp_mailauth,
&user_msg, &log_msg);
}
-
+
switch (rc)
{
case OK:
- if (authenticated_by == NULL ||
- authenticated_by->mail_auth_condition == NULL ||
- expand_check_condition(authenticated_by->mail_auth_condition,
- authenticated_by->name, US"authenticator"))
- break; /* Accept the AUTH */
-
- ignore_msg = US"server_mail_auth_condition failed";
- if (authenticated_id != NULL)
- ignore_msg = string_sprintf("%s: authenticated ID=\"%s\"",
- ignore_msg, authenticated_id);
-
+ if (authenticated_by == NULL ||
+ authenticated_by->mail_auth_condition == NULL ||
+ expand_check_condition(authenticated_by->mail_auth_condition,
+ authenticated_by->name, US"authenticator"))
+ break; /* Accept the AUTH */
+
+ ignore_msg = US"server_mail_auth_condition failed";
+ if (authenticated_id != NULL)
+ ignore_msg = string_sprintf("%s: authenticated ID=\"%s\"",
+ ignore_msg, authenticated_id);
+
/* Fall through */
-
+
case FAIL:
- authenticated_sender = NULL;
- log_write(0, LOG_MAIN, "ignoring AUTH=%s from %s (%s)",
- value, host_and_ident(TRUE), ignore_msg);
- break;
-
+ authenticated_sender = NULL;
+ log_write(0, LOG_MAIN, "ignoring AUTH=%s from %s (%s)",
+ value, host_and_ident(TRUE), ignore_msg);
+ break;
+
/* Should only get DEFER or ERROR here. Put back terminator
overrides for error message */
-
+
default:
- value[-1] = '=';
- name[-1] = ' ';
- (void)smtp_handle_acl_fail(ACL_WHERE_MAILAUTH, rc, user_msg,
- log_msg);
- goto COMMAND_LOOP;
+ value[-1] = '=';
+ name[-1] = ' ';
+ (void)smtp_handle_acl_fail(ACL_WHERE_MAILAUTH, rc, user_msg,
+ log_msg);
+ goto COMMAND_LOOP;
}
}
break;
break;
#endif
- /* Unknown option. Stick back the terminator characters and break
+#ifdef SUPPORT_I18N
+ case ENV_MAIL_OPT_UTF8:
+ if (smtputf8_advertised)
+ {
+ DEBUG(D_receive) debug_printf("smtputf8 requested\n");
+ message_smtputf8 = allow_utf8_domains = TRUE;
+ received_protocol = string_sprintf("utf8%s", received_protocol);
+ }
+ break;
+#endif
+ /* No valid option. Stick back the terminator characters and break
the loop. Do the name-terminator second as extract_option sets
- value==name when it found no equal-sign.
- An error for a malformed address will occur. */
- default:
+ value==name when it found no equal-sign.
+ An error for a malformed address will occur. */
+ case ENV_MAIL_OPT_NULL:
value[-1] = '=';
name[-1] = ' ';
arg_error = TRUE;
break;
+
+ default: assert(0);
}
/* Break out of for loop if switch() had bad argument or
when start of the email address is reached */
/* Now extract the address, first applying any SMTP-time rewriting. The
TRUE flag allows "<>" as a sender address. */
- raw_sender = ((rewrite_existflags & rewrite_smtp) != 0)?
- rewrite_one(smtp_cmd_data, rewrite_smtp, NULL, FALSE, US"",
- global_rewrite_rules) : smtp_cmd_data;
+ raw_sender = rewrite_existflags & rewrite_smtp
+ ? rewrite_one(smtp_cmd_data, rewrite_smtp, NULL, FALSE, US"",
+ global_rewrite_rules)
+ : smtp_cmd_data;
/* rfc821_domains = TRUE; << no longer needed */
raw_sender =
US"",
#endif
US"\r\n");
- else
+ else
{
#ifndef DISABLE_PRDR
if (prdr_requested)
if (user_msg == NULL) smtp_printf("250 Accepted\r\n");
else smtp_user_msg(US"250", user_msg);
receive_add_recipient(recipient, -1);
-
+
/* Set the dsn flags in the recipients_list */
- if (orcpt != NULL)
- recipients_list[recipients_count-1].orcpt = orcpt;
- else
- recipients_list[recipients_count-1].orcpt = NULL;
+ recipients_list[recipients_count-1].orcpt = orcpt;
+ recipients_list[recipients_count-1].dsn_flags = flags;
- if (flags != 0)
- recipients_list[recipients_count-1].dsn_flags = flags;
- else
- recipients_list[recipients_count-1].dsn_flags = 0;
- DEBUG(D_receive) debug_printf("DSN: orcpt: %s flags: %d\n", recipients_list[recipients_count-1].orcpt, recipients_list[recipients_count-1].dsn_flags);
+ DEBUG(D_receive) debug_printf("DSN: orcpt: %s flags: %d\n",
+ recipients_list[recipients_count-1].orcpt,
+ recipients_list[recipients_count-1].dsn_flags);
}
/* The recipient was discarded */
else smtp_user_msg(US"250", user_msg);
rcpt_fail_count++;
discarded = TRUE;
- log_write(0, LOG_MAIN|LOG_REJECT, "%s F=<%s> rejected RCPT %s: "
+ log_write(0, LOG_MAIN|LOG_REJECT, "%s F=<%s> RCPT %s: "
"discarded by %s ACL%s%s", host_and_ident(TRUE),
- (sender_address_unrewritten != NULL)?
- sender_address_unrewritten : sender_address,
+ sender_address_unrewritten? sender_address_unrewritten : sender_address,
smtp_cmd_argument, recipients_discarded? "MAIL" : "RCPT",
- (log_msg == NULL)? US"" : US": ",
- (log_msg == NULL)? US"" : log_msg);
+ log_msg ? US": " : US"", log_msg ? log_msg : US"");
}
/* Either the ACL failed the address, or it was deferred. */
ACL may have delayed. To handle cutthrough delivery enforce a dummy call
to get the DATA command sent. */
- if (acl_smtp_predata == NULL && cutthrough_fd < 0) rc = OK; else
+ if (acl_smtp_predata == NULL && cutthrough.fd < 0) rc = OK; else
{
uschar * acl= acl_smtp_predata ? acl_smtp_predata : US"accept";
enable_dollar_recipients = TRUE;
helo_seen = esmtp = auth_advertised = pipelining_advertised = FALSE;
cmd_list[CMD_LIST_EHLO].is_mail_cmd = TRUE;
cmd_list[CMD_LIST_AUTH].is_mail_cmd = TRUE;
+ cmd_list[CMD_LIST_TLS_AUTH].is_mail_cmd = TRUE;
if (sender_helo_name != NULL)
{
store_free(sender_helo_name);
set_process_info("handling incoming TLS connection from %s",
host_and_ident(FALSE));
}
- received_protocol = (esmtp?
- protocols[pextend + pcrpted +
- ((sender_host_authenticated != NULL)? pauthed : 0)]
- :
- protocols[pnormal + pcrpted])
- +
- ((sender_host_address != NULL)? pnlocal : 0);
+ received_protocol =
+ (sender_host_address ? protocols : protocols_local)
+ [ (esmtp
+ ? pextend + (sender_host_authenticated ? pauthed : 0)
+ : pnormal)
+ + (tls_in.active >= 0 ? pcrpted : 0)
+ ];
sender_host_authenticated = NULL;
authenticated_id = NULL;
break;
}
etrn_command = US"exim -R";
- argv = child_exec_exim(CEE_RETURN_ARGV, TRUE, NULL, TRUE, 2, US"-R",
+ argv = CUSS child_exec_exim(CEE_RETURN_ARGV, TRUE, NULL, TRUE, 2, US"-R",
smtp_cmd_data);
}
/* If ETRN queue runs are to be serialized, check the database to
ensure one isn't already running. */
- if (smtp_etrn_serialize && !enq_start(etrn_serialize_key))
+ if (smtp_etrn_serialize && !enq_start(etrn_serialize_key, 1))
{
smtp_printf("458 Already processing %s\r\n", smtp_cmd_data);
break;
done = 1; /* Pretend eof - drops connection */
break;
- #ifdef EXPERIMENTAL_PROXY
+#ifdef SUPPORT_PROXY
case PROXY_FAIL_IGNORE_CMD:
smtp_printf("503 Command refused, required Proxy negotiation failed\r\n");
break;
- #endif
+#endif
default:
if (unknown_command_count++ >= smtp_max_unknown_commands)
done = 2;
log_write(0, LOG_MAIN|LOG_REJECT, "SMTP call from %s dropped: too many "
"unrecognized commands (last was \"%s\")", host_and_ident(FALSE),
- smtp_cmd_buffer);
+ string_printing(smtp_cmd_buffer));
}
else
done = synprot_error(L_smtp_syntax_error, 500, NULL,
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* A number of functions for driving outgoing SMTP calls. */
#include "exim.h"
+#include "transports/smtp.h"
which case the function does nothing
host_af AF_INET or AF_INET6 for the outgoing IP address
addr the mail address being handled (for setting errors)
- changed if not NULL, set TRUE if expansion actually changed istring
interface point this to the interface
msg to add to any error message
BOOL
smtp_get_interface(uschar *istring, int host_af, address_item *addr,
- BOOL *changed, uschar **interface, uschar *msg)
+ uschar **interface, uschar *msg)
{
-uschar *expint;
+const uschar * expint;
uschar *iface;
int sep = 0;
return FALSE;
}
-if (changed != NULL) *changed = expint != istring;
-
while (isspace(*expint)) expint++;
if (*expint == 0) return TRUE;
-/*************************************************
-* Connect to remote host *
-*************************************************/
-
-/* Create a socket, and connect it to a remote host. IPv6 addresses are
-detected by checking for a colon in the address. AF_INET6 is defined even on
-non-IPv6 systems, to enable the code to be less messy. However, on such systems
-host->address will always be an IPv4 address.
-
-The port field in the host item is used if it is set (usually router from SRV
-records or elsewhere). In other cases, the default passed as an argument is
-used, and the host item is updated with its value.
-
-Arguments:
- host host item containing name and address (and sometimes port)
- host_af AF_INET or AF_INET6
- port default remote port to connect to, in host byte order, for those
- hosts whose port setting is PORT_NONE
- interface outgoing interface address or NULL
- timeout timeout value or 0
- keepalive TRUE to use keepalive
- dscp DSCP value to assign to socket
- event event expansion
-
-Returns: connected socket number, or -1 with errno set
-*/
-
int
-smtp_connect(host_item *host, int host_af, int port, uschar *interface,
- int timeout, BOOL keepalive, const uschar *dscp
-#ifdef EXPERIMENTAL_EVENT
- , uschar * event
-#endif
- )
+smtp_sock_connect(host_item * host, int host_af, int port, uschar * interface,
+ transport_instance * tb, int timeout)
{
-int on = 1;
-int save_errno = 0;
+smtp_transport_options_block * ob =
+ (smtp_transport_options_block *)tb->options_block;
+const uschar * dscp = ob->dscp;
int dscp_value;
int dscp_level;
int dscp_option;
int sock;
+int on = 1;
+int save_errno = 0;
-if (host->port != PORT_NONE)
- {
- HDEBUG(D_transport|D_acl|D_v)
- debug_printf("Transport port=%d replaced by host-specific port=%d\n", port,
- host->port);
- port = host->port;
- }
-else host->port = port; /* Set the port actually used */
-
-HDEBUG(D_transport|D_acl|D_v)
- {
- if (interface == NULL)
- debug_printf("Connecting to %s [%s]:%d ... ",host->name,host->address,port);
- else
- debug_printf("Connecting to %s [%s]:%d from %s ... ", host->name,
- host->address, port, interface);
- }
-
-#ifdef EXPERIMENTAL_EVENT
- deliver_host_address = host->address;
- deliver_host_port = port;
- if (event_raise(event, US"tcp:connect", NULL)) return -1;
- /* Logging? Debug? */
+#ifndef DISABLE_EVENT
+deliver_host_address = host->address;
+deliver_host_port = port;
+if (event_raise(tb->event_action, US"tcp:connect", NULL)) return -1;
#endif
-/* Create the socket */
-
if ((sock = ip_socket(SOCK_STREAM, host_af)) < 0) return -1;
/* Set TCP_NODELAY; Exim does its own buffering. */
option for both; ignore failures here */
if (host_af == AF_INET6 &&
dscp_lookup(dscp, AF_INET, &dscp_level, &dscp_option, &dscp_value))
- {
(void) setsockopt(sock, dscp_level, dscp_option, &dscp_value, sizeof(dscp_value));
- }
}
/* Bind to a specific interface if requested. Caller must ensure the interface
is the same type (IPv4 or IPv6) as the outgoing address. */
-if (interface != NULL && ip_bind(sock, host_af, interface, 0) < 0)
+if (interface && ip_bind(sock, host_af, interface, 0) < 0)
{
save_errno = errno;
HDEBUG(D_transport|D_acl|D_v)
close(sock);
return -1;
}
- if (keepalive) ip_keepalive(sock, host->address, TRUE);
+ if (ob->keepalive) ip_keepalive(sock, host->address, TRUE);
return sock;
}
}
+/*************************************************
+* Connect to remote host *
+*************************************************/
+
+/* Create a socket, and connect it to a remote host. IPv6 addresses are
+detected by checking for a colon in the address. AF_INET6 is defined even on
+non-IPv6 systems, to enable the code to be less messy. However, on such systems
+host->address will always be an IPv4 address.
+
+The port field in the host item is used if it is set (usually router from SRV
+records or elsewhere). In other cases, the default passed as an argument is
+used, and the host item is updated with its value.
+
+Arguments:
+ host host item containing name and address (and sometimes port)
+ host_af AF_INET or AF_INET6
+ port default remote port to connect to, in host byte order, for those
+ hosts whose port setting is PORT_NONE
+ interface outgoing interface address or NULL
+ timeout timeout value or 0
+ tb transport
+
+Returns: connected socket number, or -1 with errno set
+*/
+
+int
+smtp_connect(host_item *host, int host_af, int port, uschar *interface,
+ int timeout, transport_instance * tb)
+{
+#ifdef SUPPORT_SOCKS
+smtp_transport_options_block * ob =
+ (smtp_transport_options_block *)tb->options_block;
+#endif
+
+if (host->port != PORT_NONE)
+ {
+ HDEBUG(D_transport|D_acl|D_v)
+ debug_printf("Transport port=%d replaced by host-specific port=%d\n", port,
+ host->port);
+ port = host->port;
+ }
+else host->port = port; /* Set the port actually used */
+
+callout_address = string_sprintf("[%s]:%d", host->address, port);
+
+HDEBUG(D_transport|D_acl|D_v)
+ {
+ uschar * s = US" ";
+ if (interface) s = string_sprintf(" from %s ", interface);
+#ifdef SUPPORT_SOCKS
+ if (ob->socks_proxy) s = string_sprintf("%svia proxy ", s);
+#endif
+ debug_printf("Connecting to %s %s%s... ", host->name, callout_address, s);
+ }
+
+/* Create and connect the socket */
+
+#ifdef SUPPORT_SOCKS
+if (ob->socks_proxy)
+ return socks_sock_connect(host, host_af, port, interface, tb, timeout);
+#endif
+
+return smtp_sock_connect(host, host_af, port, interface, tb, timeout);
+}
+
/*************************************************
* Flush outgoing command buffer *
}
/* End of smtp_out.c */
+/* vi: aw ai sw=2
+*/
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) Tom Kistner <tom@duncanthrax.net> 2003-???? */
+/* Copyright (c) Tom Kistner <tom@duncanthrax.net> 2003 - 2015 */
/* License: GPL */
/* Code for calling spamassassin's spamd. Called from acl.c. */
uschar spam_score_buffer[16];
uschar spam_score_int_buffer[16];
uschar spam_bar_buffer[128];
+uschar spam_action_buffer[32];
uschar spam_report_buffer[32600];
uschar prev_user_name[128] = "";
int spam_ok = 0;
int spam_rc = 0;
uschar *prev_spamd_address_work = NULL;
-int
-spam(uschar **listptr)
+static const uschar * loglabel = US"spam acl condition:";
+
+
+static int
+spamd_param_init(spamd_address_container *spamd)
{
- int sep = 0;
- uschar *list = *listptr;
- uschar *user_name;
- uschar user_name_buffer[128];
- unsigned long mbox_size;
- FILE *mbox_file;
- int spamd_sock = -1;
- uschar spamd_buffer[32600];
- int i, j, offset, result;
- uschar spamd_version[8];
- uschar spamd_score_char;
- double spamd_threshold, spamd_score;
- int spamd_report_offset;
- uschar *p,*q;
- int override = 0;
- time_t start;
- size_t read, wrote;
- struct sockaddr_un server;
-#ifndef NO_POLL_H
- struct pollfd pollfd;
-#else /* Patch posted by Erik ? for OS X */
- struct timeval select_tv; /* and applied by PH */
- fd_set select_fd;
-#endif
- uschar *spamd_address_work;
- static const uschar * loglabel = US"spam acl condition:";
+/* default spamd server weight, time and priority value */
+spamd->is_rspamd = FALSE;
+spamd->is_failed = FALSE;
+spamd->weight = SPAMD_WEIGHT;
+spamd->timeout = SPAMD_TIMEOUT;
+spamd->retry = 0;
+spamd->priority = 1;
+return 0;
+}
- /* stop compiler warning */
- result = 0;
- /* find the username from the option list */
- if ((user_name = string_nextinlist(&list, &sep,
- user_name_buffer,
- sizeof(user_name_buffer))) == NULL)
+static int
+spamd_param(const uschar * param, spamd_address_container * spamd)
+{
+static int timesinceday = -1;
+const uschar * s;
+const uschar * name;
+
+/*XXX more clever parsing could discard embedded spaces? */
+
+if (sscanf(CCS param, "pri=%u", &spamd->priority))
+ return 0; /* OK */
+
+if (sscanf(CCS param, "weight=%u", &spamd->weight))
+ {
+ if (spamd->weight == 0) /* this server disabled: skip it */
+ return 1;
+ return 0; /* OK */
+ }
+
+if (Ustrncmp(param, "time=", 5) == 0)
+ {
+ unsigned int start_h = 0, start_m = 0, start_s = 0;
+ unsigned int end_h = 24, end_m = 0, end_s = 0;
+ unsigned int time_start, time_end;
+ const uschar * end_string;
+
+ name = US"time";
+ s = param+5;
+ if ((end_string = Ustrchr(s, '-')))
{
- /* no username given, this means no scanning should be done */
- return FAIL;
+ end_string++;
+ if ( sscanf(CS end_string, "%u.%u.%u", &end_h, &end_m, &end_s) == 0
+ || sscanf(CS s, "%u.%u.%u", &start_h, &start_m, &start_s) == 0
+ )
+ goto badval;
}
+ else
+ goto badval;
- /* if username is "0" or "false", do not scan */
- if ( (Ustrcmp(user_name,"0") == 0) ||
- (strcmpic(user_name,US"false") == 0) )
- return FAIL;
-
- /* if there is an additional option, check if it is "true" */
- if (strcmpic(list,US"true") == 0)
- /* in that case, always return true later */
- override = 1;
-
- /* expand spamd_address if needed */
- if (*spamd_address == '$')
+ if (timesinceday < 0)
{
- spamd_address_work = expand_string(spamd_address);
- if (spamd_address_work == NULL)
- {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "%s spamd_address starts with $, but expansion failed: %s",
- loglabel, expand_string_message);
- return DEFER;
- }
+ time_t now = time(NULL);
+ struct tm *tmp = localtime(&now);
+ timesinceday = tmp->tm_hour*3600 + tmp->tm_min*60 + tmp->tm_sec;
}
- else
- spamd_address_work = spamd_address;
- /* check if previous spamd_address was expanded and has changed. dump cached results if so */
- if ( spam_ok
- && prev_spamd_address_work != NULL
- && Ustrcmp(prev_spamd_address_work, spamd_address_work) != 0
- )
- spam_ok = 0;
+ time_start = start_h*3600 + start_m*60 + start_s;
+ time_end = end_h*3600 + end_m*60 + end_s;
+
+ if (timesinceday < time_start || timesinceday >= time_end)
+ return 1; /* skip spamd server */
+
+ return 0; /* OK */
+ }
+
+if (Ustrcmp(param, "variant=rspamd") == 0)
+ {
+ spamd->is_rspamd = TRUE;
+ return 0;
+ }
+
+if (Ustrncmp(param, "tmo=", 4) == 0)
+ {
+ int sec = readconf_readtime((s = param+4), '\0', FALSE);
+ name = US"timeout";
+ if (sec < 0)
+ goto badval;
+ spamd->timeout = sec;
+ return 0;
+ }
+
+if (Ustrncmp(param, "retry=", 6) == 0)
+ {
+ int sec = readconf_readtime((s = param+6), '\0', FALSE);
+ name = US"retry";
+ if (sec < 0)
+ goto badval;
+ spamd->retry = sec;
+ return 0;
+ }
+
+log_write(0, LOG_MAIN, "%s warning - invalid spamd parameter: '%s'",
+ loglabel, param);
+return -1; /* syntax error */
+
+badval:
+ log_write(0, LOG_MAIN,
+ "%s warning - invalid spamd %s value: '%s'", loglabel, name, s);
+ return -1; /* syntax error */
+}
+
- /* if we scanned for this username last time, just return */
- if (spam_ok && Ustrcmp(prev_user_name, user_name) == 0)
- return override ? OK : spam_rc;
+static int
+spamd_get_server(spamd_address_container ** spamds, int num_servers)
+{
+unsigned int i;
+spamd_address_container * sd;
+long rnd, weights;
+unsigned pri;
+static BOOL srandomed = FALSE;
+
+/* seedup, if we have only 1 server */
+if (num_servers == 1)
+ return (spamds[0]->is_failed ? -1 : 0);
+
+/* init ranmod */
+if (!srandomed)
+ {
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ srandom((unsigned int)(tv.tv_usec/1000));
+ srandomed = TRUE;
+ }
+
+/* scan for highest pri */
+for (pri = 0, i = 0; i < num_servers; i++)
+ {
+ sd = spamds[i];
+ if (!sd->is_failed && sd->priority > pri) pri = sd->priority;
+ }
+
+/* get sum of weights */
+for (weights = 0, i = 0; i < num_servers; i++)
+ {
+ sd = spamds[i];
+ if (!sd->is_failed && sd->priority == pri) weights += sd->weight;
+ }
+if (weights == 0) /* all servers failed */
+ return -1;
+
+for (rnd = random() % weights, i = 0; i < num_servers; i++)
+ {
+ sd = spamds[i];
+ if (!sd->is_failed && sd->priority == pri)
+ if ((rnd -= sd->weight) <= 0)
+ return i;
+ }
+
+log_write(0, LOG_MAIN|LOG_PANIC,
+ "%s unknown error (memory/cpu corruption?)", loglabel);
+return -1;
+}
- /* make sure the eml mbox file is spooled up */
- mbox_file = spool_mbox(&mbox_size, NULL);
- if (mbox_file == NULL)
+int
+spam(const uschar **listptr)
+{
+int sep = 0;
+const uschar *list = *listptr;
+uschar *user_name;
+uschar user_name_buffer[128];
+unsigned long mbox_size;
+FILE *mbox_file;
+int spamd_sock = -1;
+uschar spamd_buffer[32600];
+int i, j, offset, result;
+uschar spamd_version[8];
+uschar spamd_short_result[8];
+uschar spamd_score_char;
+double spamd_threshold, spamd_score, spamd_reject_score;
+int spamd_report_offset;
+uschar *p,*q;
+int override = 0;
+time_t start;
+size_t read, wrote;
+#ifndef NO_POLL_H
+struct pollfd pollfd;
+#else /* Patch posted by Erik ? for OS X */
+struct timeval select_tv; /* and applied by PH */
+fd_set select_fd;
+#endif
+uschar *spamd_address_work;
+spamd_address_container * sd;
+
+/* stop compiler warning */
+result = 0;
+
+/* find the username from the option list */
+if ((user_name = string_nextinlist(&list, &sep,
+ user_name_buffer,
+ sizeof(user_name_buffer))) == NULL)
+ {
+ /* no username given, this means no scanning should be done */
+ return FAIL;
+ }
+
+/* if username is "0" or "false", do not scan */
+if ( (Ustrcmp(user_name,"0") == 0) ||
+ (strcmpic(user_name,US"false") == 0) )
+ return FAIL;
+
+/* if there is an additional option, check if it is "true" */
+if (strcmpic(list,US"true") == 0)
+ /* in that case, always return true later */
+ override = 1;
+
+/* expand spamd_address if needed */
+if (*spamd_address == '$')
+ {
+ spamd_address_work = expand_string(spamd_address);
+ if (spamd_address_work == NULL)
{
- /* error while spooling */
log_write(0, LOG_MAIN|LOG_PANIC,
- "%s error while creating mbox spool file", loglabel);
+ "%s spamd_address starts with $, but expansion failed: %s",
+ loglabel, expand_string_message);
return DEFER;
}
-
- start = time(NULL);
-
- /* socket does not start with '/' -> network socket */
- if (*spamd_address_work != '/')
+ }
+else
+ spamd_address_work = spamd_address;
+
+DEBUG(D_acl) debug_printf("spamd: addrlist '%s'\n", spamd_address_work);
+
+/* check if previous spamd_address was expanded and has changed. dump cached results if so */
+if ( spam_ok
+ && prev_spamd_address_work != NULL
+ && Ustrcmp(prev_spamd_address_work, spamd_address_work) != 0
+ )
+ spam_ok = 0;
+
+/* if we scanned for this username last time, just return */
+if (spam_ok && Ustrcmp(prev_user_name, user_name) == 0)
+ return override ? OK : spam_rc;
+
+/* make sure the eml mbox file is spooled up */
+mbox_file = spool_mbox(&mbox_size, NULL);
+
+if (mbox_file == NULL)
+ {
+ /* error while spooling */
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "%s error while creating mbox spool file", loglabel);
+ return DEFER;
+ }
+
+start = time(NULL);
+
+ {
+ int num_servers = 0;
+ int current_server;
+ uschar * address;
+ const uschar * spamd_address_list_ptr = spamd_address_work;
+ spamd_address_container * spamd_address_vector[32];
+
+ /* Check how many spamd servers we have
+ and register their addresses */
+ sep = 0; /* default colon-sep */
+ while ((address = string_nextinlist(&spamd_address_list_ptr, &sep,
+ NULL, 0)) != NULL)
{
- int num_servers = 0;
- int current_server;
- uschar *address = NULL;
- uschar *spamd_address_list_ptr = spamd_address_work;
- uschar address_buffer[256];
- spamd_address_container * spamd_address_vector[32];
-
- /* Check how many spamd servers we have
- and register their addresses */
- while ((address = string_nextinlist(&spamd_address_list_ptr, &sep,
- address_buffer,
- sizeof(address_buffer))) != NULL)
+ const uschar * sublist;
+ int sublist_sep = -(int)' '; /* default space-sep */
+ unsigned args;
+ uschar * s;
+
+ DEBUG(D_acl) debug_printf("spamd: addr entry '%s'\n", address);
+ sd = (spamd_address_container *)store_get(sizeof(spamd_address_container));
+
+ for (sublist = address, args = 0, spamd_param_init(sd);
+ (s = string_nextinlist(&sublist, &sublist_sep, NULL, 0));
+ args++
+ )
{
-
- /* Potential memory leak as we never free the store. */
- spamd_address_container *this_spamd =
- (spamd_address_container *)store_get(sizeof(spamd_address_container));
-
- /* grok spamd address and port */
- if (sscanf(CS address, "%23s %u", this_spamd->tcp_addr, &this_spamd->tcp_port) != 2)
- {
- log_write(0, LOG_MAIN,
- "%s warning - invalid spamd address: '%s'", loglabel, address);
- continue;
+ DEBUG(D_acl) debug_printf("spamd: addr parm '%s'\n", s);
+ switch (args)
+ {
+ case 0: sd->hostspec = s;
+ if (*s == '/') args++; /* local; no port */
+ break;
+ case 1: sd->hostspec = string_sprintf("%s %s", sd->hostspec, s);
+ break;
+ default: spamd_param(s, sd);
+ break;
}
-
- spamd_address_vector[num_servers] = this_spamd;
- if ( ++num_servers
- >= sizeof(spamd_address_vector)/sizeof(spamd_address_vector[0]))
- break;
}
-
- /* check if we have at least one server */
- if (!num_servers)
+ if (args < 2)
{
- log_write(0, LOG_MAIN|LOG_PANIC,
- "%s no useable spamd server addresses in spamd_address configuration option.",
- loglabel);
- (void)fclose(mbox_file);
- return DEFER;
+ log_write(0, LOG_MAIN,
+ "%s warning - invalid spamd address: '%s'", loglabel, address);
+ continue;
}
- while (num_servers > 0)
- {
- int i;
-
- /* Randomly pick a server to try */
- current_server = random_number(num_servers);
-
- debug_printf("trying server %s, port %u\n",
- spamd_address_vector[current_server]->tcp_addr,
- spamd_address_vector[current_server]->tcp_port);
-
- /* contact a spamd */
- if ((spamd_sock = ip_socket(SOCK_STREAM, AF_INET)) < 0)
- {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "%s error creating IP socket for spamd", loglabel);
- (void)fclose(mbox_file);
- return DEFER;
- }
-
- if (ip_connect(spamd_sock,
- AF_INET,
- spamd_address_vector[current_server]->tcp_addr,
- spamd_address_vector[current_server]->tcp_port,
- 5 ) > -1)
- /* connection OK */
- break;
-
- log_write(0, LOG_MAIN|LOG_PANIC,
- "%s warning - spamd connection to %s, port %u failed: %s",
- loglabel,
- spamd_address_vector[current_server]->tcp_addr,
- spamd_address_vector[current_server]->tcp_port,
- strerror(errno));
-
- (void)close(spamd_sock);
-
- /* Remove the server from the list. XXX We should free the memory */
- num_servers--;
- for (i = current_server; i < num_servers; i++)
- spamd_address_vector[i] = spamd_address_vector[i+1];
- }
+ spamd_address_vector[num_servers] = sd;
+ if (++num_servers > 31)
+ break;
+ }
- if (num_servers == 0)
- {
- log_write(0, LOG_MAIN|LOG_PANIC, "%s all spamd servers failed", loglabel);
- (void)fclose(mbox_file);
- return DEFER;
- }
+ /* check if we have at least one server */
+ if (!num_servers)
+ {
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "%s no useable spamd server addresses in spamd_address configuration option.",
+ loglabel);
+ goto defer;
}
- else
+
+ current_server = spamd_get_server(spamd_address_vector, num_servers);
+ sd = spamd_address_vector[current_server];
+ for(;;)
{
- /* open the local socket */
+ uschar * errstr;
- if ((spamd_sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
+ DEBUG(D_acl) debug_printf("spamd: trying server %s\n", sd->hostspec);
+
+ for (;;)
{
- log_write(0, LOG_MAIN|LOG_PANIC,
- "%s spamd: unable to acquire socket (%s)",
- loglabel,
- strerror(errno));
- (void)fclose(mbox_file);
- return DEFER;
+ if ( (spamd_sock = ip_streamsocket(sd->hostspec, &errstr, 5)) >= 0
+ || sd->retry <= 0
+ )
+ break;
+ DEBUG(D_acl) debug_printf("spamd: server %s: retry conn\n", sd->hostspec);
+ while (sd->retry > 0) sd->retry = sleep(sd->retry);
}
+ if (spamd_sock >= 0)
+ break;
- server.sun_family = AF_UNIX;
- Ustrcpy(server.sun_path, spamd_address_work);
+ log_write(0, LOG_MAIN, "%s spamd: %s", loglabel, errstr);
+ sd->is_failed = TRUE;
- if (connect(spamd_sock, (struct sockaddr *) &server, sizeof(struct sockaddr_un)) < 0)
+ current_server = spamd_get_server(spamd_address_vector, num_servers);
+ if (current_server < 0)
{
- log_write(0, LOG_MAIN|LOG_PANIC,
- "%s spamd: unable to connect to UNIX socket %s (%s)",
- loglabel,
- spamd_address_work, strerror(errno) );
- (void)fclose(mbox_file);
- (void)close(spamd_sock);
- return DEFER;
+ log_write(0, LOG_MAIN|LOG_PANIC, "%s all spamd servers failed", loglabel);
+ goto defer;
}
+ sd = spamd_address_vector[current_server];
}
-
- if (spamd_sock == -1)
- {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "programming fault, spamd_sock unexpectedly unset");
- (void)fclose(mbox_file);
- (void)close(spamd_sock);
- return DEFER;
- }
-
- /* now we are connected to spamd on spamd_sock */
+ }
+
+if (spamd_sock == -1)
+ {
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "programming fault, spamd_sock unexpectedly unset");
+ goto defer;
+ }
+
+(void)fcntl(spamd_sock, F_SETFL, O_NONBLOCK);
+/* now we are connected to spamd on spamd_sock */
+if (sd->is_rspamd)
+ { /* rspamd variant */
+ uschar *req_str;
+ const uschar * helo;
+ const uschar * fcrdns;
+ const uschar * authid;
+
+ req_str = string_sprintf("CHECK RSPAMC/1.3\r\nContent-length: %lu\r\n"
+ "Queue-Id: %s\r\nFrom: <%s>\r\nRecipient-Number: %d\r\n",
+ mbox_size, message_id, sender_address, recipients_count);
+ for (i = 0; i < recipients_count; i ++)
+ req_str = string_sprintf("%sRcpt: <%s>\r\n", req_str, recipients_list[i].address);
+ if ((helo = expand_string(US"$sender_helo_name")) != NULL && *helo != '\0')
+ req_str = string_sprintf("%sHelo: %s\r\n", req_str, helo);
+ if ((fcrdns = expand_string(US"$sender_host_name")) != NULL && *fcrdns != '\0')
+ req_str = string_sprintf("%sHostname: %s\r\n", req_str, fcrdns);
+ if (sender_host_address != NULL)
+ req_str = string_sprintf("%sIP: %s\r\n", req_str, sender_host_address);
+ if ((authid = expand_string(US"$authenticated_id")) != NULL && *authid != '\0')
+ req_str = string_sprintf("%sUser: %s\r\n", req_str, authid);
+ req_str = string_sprintf("%s\r\n", req_str);
+ wrote = send(spamd_sock, req_str, Ustrlen(req_str), 0);
+ }
+else
+ { /* spamassassin variant */
(void)string_format(spamd_buffer,
- sizeof(spamd_buffer),
- "REPORT SPAMC/1.2\r\nUser: %s\r\nContent-length: %ld\r\n\r\n",
- user_name,
- mbox_size);
-
+ sizeof(spamd_buffer),
+ "REPORT SPAMC/1.2\r\nUser: %s\r\nContent-length: %ld\r\n\r\n",
+ user_name,
+ mbox_size);
/* send our request */
- if (send(spamd_sock, spamd_buffer, Ustrlen(spamd_buffer), 0) < 0)
- {
- (void)close(spamd_sock);
- log_write(0, LOG_MAIN|LOG_PANIC,
- "%s spamd send failed: %s", loglabel, strerror(errno));
- (void)fclose(mbox_file);
- (void)close(spamd_sock);
- return DEFER;
- }
+ wrote = send(spamd_sock, spamd_buffer, Ustrlen(spamd_buffer), 0);
+ }
- /* now send the file */
- /* spamd sometimes accepts conections but doesn't read data off
- * the connection. We make the file descriptor non-blocking so
- * that the write will only write sufficient data without blocking
- * and we poll the desciptor to make sure that we can write without
- * blocking. Short writes are gracefully handled and if the whole
- * trasaction takes too long it is aborted.
- * Note: poll() is not supported in OSX 10.2 and is reported to be
- * broken in more recent versions (up to 10.4).
- */
+if (wrote == -1)
+ {
+ (void)close(spamd_sock);
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "%s spamd %s send failed: %s", loglabel, callout_address, strerror(errno));
+ goto defer;
+ }
+
+/* now send the file */
+/* spamd sometimes accepts conections but doesn't read data off
+ * the connection. We make the file descriptor non-blocking so
+ * that the write will only write sufficient data without blocking
+ * and we poll the desciptor to make sure that we can write without
+ * blocking. Short writes are gracefully handled and if the whole
+ * trasaction takes too long it is aborted.
+ * Note: poll() is not supported in OSX 10.2 and is reported to be
+ * broken in more recent versions (up to 10.4).
+ */
#ifndef NO_POLL_H
- pollfd.fd = spamd_sock;
- pollfd.events = POLLOUT;
+pollfd.fd = spamd_sock;
+pollfd.events = POLLOUT;
#endif
- (void)fcntl(spamd_sock, F_SETFL, O_NONBLOCK);
- do
+(void)fcntl(spamd_sock, F_SETFL, O_NONBLOCK);
+do
+ {
+ read = fread(spamd_buffer,1,sizeof(spamd_buffer),mbox_file);
+ if (read > 0)
{
- read = fread(spamd_buffer,1,sizeof(spamd_buffer),mbox_file);
- if (read > 0)
- {
- offset = 0;
+ offset = 0;
again:
#ifndef NO_POLL_H
- result = poll(&pollfd, 1, 1000);
+ result = poll(&pollfd, 1, 1000);
/* Patch posted by Erik ? for OS X and applied by PH */
#else
- select_tv.tv_sec = 1;
- select_tv.tv_usec = 0;
- FD_ZERO(&select_fd);
- FD_SET(spamd_sock, &select_fd);
- result = select(spamd_sock+1, NULL, &select_fd, NULL, &select_tv);
+ select_tv.tv_sec = 1;
+ select_tv.tv_usec = 0;
+ FD_ZERO(&select_fd);
+ FD_SET(spamd_sock, &select_fd);
+ result = select(spamd_sock+1, NULL, &select_fd, NULL, &select_tv);
#endif
/* End Erik's patch */
- if (result == -1 && errno == EINTR)
- goto again;
- else if (result < 1)
- {
- if (result == -1)
- log_write(0, LOG_MAIN|LOG_PANIC,
- "%s %s on spamd socket", loglabel, strerror(errno));
- else
- {
- if (time(NULL) - start < SPAMD_TIMEOUT)
- goto again;
- log_write(0, LOG_MAIN|LOG_PANIC,
- "%s timed out writing spamd socket", loglabel);
- }
- (void)close(spamd_sock);
- (void)fclose(mbox_file);
- return DEFER;
- }
-
- wrote = send(spamd_sock,spamd_buffer + offset,read - offset,0);
- if (wrote == -1)
- {
+ if (result == -1 && errno == EINTR)
+ goto again;
+ else if (result < 1)
+ {
+ if (result == -1)
log_write(0, LOG_MAIN|LOG_PANIC,
- "%s %s on spamd socket", loglabel, strerror(errno));
- (void)close(spamd_sock);
- (void)fclose(mbox_file);
- return DEFER;
- }
- if (offset + wrote != read)
+ "%s %s on spamd %s socket", loglabel, callout_address, strerror(errno));
+ else
{
- offset += wrote;
- goto again;
+ if (time(NULL) - start < sd->timeout)
+ goto again;
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "%s timed out writing spamd %s, socket", loglabel, callout_address);
}
+ (void)close(spamd_sock);
+ goto defer;
}
- }
- while (!feof(mbox_file) && !ferror(mbox_file));
- if (ferror(mbox_file))
- {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "%s error reading spool file: %s", loglabel, strerror(errno));
- (void)close(spamd_sock);
- (void)fclose(mbox_file);
- return DEFER;
+ wrote = send(spamd_sock,spamd_buffer + offset,read - offset,0);
+ if (wrote == -1)
+ {
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "%s %s on spamd %s socket", loglabel, callout_address, strerror(errno));
+ (void)close(spamd_sock);
+ goto defer;
+ }
+ if (offset + wrote != read)
+ {
+ offset += wrote;
+ goto again;
+ }
}
+ }
+while (!feof(mbox_file) && !ferror(mbox_file));
- (void)fclose(mbox_file);
-
- /* we're done sending, close socket for writing */
- shutdown(spamd_sock,SHUT_WR);
-
- /* read spamd response using what's left of the timeout.
- */
- memset(spamd_buffer, 0, sizeof(spamd_buffer));
- offset = 0;
- while ((i = ip_recv(spamd_sock,
- spamd_buffer + offset,
- sizeof(spamd_buffer) - offset - 1,
- SPAMD_TIMEOUT - time(NULL) + start)) > 0 )
- offset += i;
-
- /* error handling */
- if (i <= 0 && errno != 0)
+if (ferror(mbox_file))
+ {
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "%s error reading spool file: %s", loglabel, strerror(errno));
+ (void)close(spamd_sock);
+ goto defer;
+ }
+
+(void)fclose(mbox_file);
+
+/* we're done sending, close socket for writing */
+shutdown(spamd_sock,SHUT_WR);
+
+/* read spamd response using what's left of the timeout. */
+memset(spamd_buffer, 0, sizeof(spamd_buffer));
+offset = 0;
+while ((i = ip_recv(spamd_sock,
+ spamd_buffer + offset,
+ sizeof(spamd_buffer) - offset - 1,
+ sd->timeout - time(NULL) + start)) > 0 )
+ offset += i;
+
+/* error handling */
+if (i <= 0 && errno != 0)
+ {
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "%s error reading from spamd %s, socket: %s", loglabel, callout_address, strerror(errno));
+ (void)close(spamd_sock);
+ return DEFER;
+ }
+
+/* reading done */
+(void)close(spamd_sock);
+
+if (sd->is_rspamd)
+ { /* rspamd variant of reply */
+ int r;
+ if ((r = sscanf(CS spamd_buffer,
+ "RSPAMD/%7s 0 EX_OK\r\nMetric: default; %7s %lf / %lf / %lf\r\n%n",
+ spamd_version, spamd_short_result, &spamd_score, &spamd_threshold,
+ &spamd_reject_score, &spamd_report_offset)) != 5)
{
log_write(0, LOG_MAIN|LOG_PANIC,
- "%s error reading from spamd socket: %s", loglabel, strerror(errno));
- (void)close(spamd_sock);
+ "%s cannot parse spamd %s, output: %d", loglabel, callout_address, r);
return DEFER;
}
+ /* now parse action */
+ p = &spamd_buffer[spamd_report_offset];
- /* reading done */
- (void)close(spamd_sock);
-
- /* dig in the spamd output and put the report in a multiline header, if requested */
- if (sscanf(CS spamd_buffer,
- "SPAMD/%7s 0 EX_OK\r\nContent-length: %*u\r\n\r\n%lf/%lf\r\n%n",
- spamd_version, &spamd_score, &spamd_threshold,
- &spamd_report_offset) != 3)
+ if (Ustrncmp(p, "Action: ", sizeof("Action: ") - 1) == 0)
{
-
- /* try to fall back to pre-2.50 spamd output */
- if (sscanf(CS spamd_buffer,
- "SPAMD/%7s 0 EX_OK\r\nSpam: %*s ; %lf / %lf\r\n\r\n%n",
- spamd_version, &spamd_score, &spamd_threshold,
- &spamd_report_offset) != 3 )
- {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "%s cannot parse spamd output", loglabel);
- return DEFER;
- }
+ p += sizeof("Action: ") - 1;
+ q = &spam_action_buffer[0];
+ while (*p && *p != '\r' && (q - spam_action_buffer) < sizeof(spam_action_buffer) - 1)
+ *q++ = *p++;
+ *q = '\0';
}
-
- /* Create report. Since this is a multiline string,
- we must hack it into shape first */
- p = &spamd_buffer[spamd_report_offset];
- q = spam_report_buffer;
- while (*p != '\0')
- {
- /* skip \r */
- if (*p == '\r')
- {
- p++;
- continue;
- }
- *q++ = *p;
- if (*p++ == '\n')
- {
- /* add an extra space after the newline to ensure
- that it is treated as a header continuation line */
- *q++ = ' ';
- }
- }
- /* NULL-terminate */
- *q-- = '\0';
- /* cut off trailing leftovers */
- while (*q <= ' ')
- *q-- = '\0';
-
- spam_report = spam_report_buffer;
-
- /* create spam bar */
- spamd_score_char = spamd_score > 0 ? '+' : '-';
- j = abs((int)(spamd_score));
- i = 0;
- if (j != 0)
- while ((i < j) && (i <= MAX_SPAM_BAR_CHARS))
- spam_bar_buffer[i++] = spamd_score_char;
- else
+ }
+else
+ { /* spamassassin */
+ /* dig in the spamd output and put the report in a multiline header,
+ if requested */
+ if (sscanf(CS spamd_buffer,
+ "SPAMD/%7s 0 EX_OK\r\nContent-length: %*u\r\n\r\n%lf/%lf\r\n%n",
+ spamd_version,&spamd_score,&spamd_threshold,&spamd_report_offset) != 3)
{
- spam_bar_buffer[0] = '/';
- i = 1;
+ /* try to fall back to pre-2.50 spamd output */
+ if (sscanf(CS spamd_buffer,
+ "SPAMD/%7s 0 EX_OK\r\nSpam: %*s ; %lf / %lf\r\n\r\n%n",
+ spamd_version,&spamd_score,&spamd_threshold,&spamd_report_offset) != 3)
+ {
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "%s cannot parse spamd %s output", loglabel, callout_address);
+ return DEFER;
+ }
}
- spam_bar_buffer[i] = '\0';
- spam_bar = spam_bar_buffer;
-
- /* create "float" spam score */
- (void)string_format(spam_score_buffer, sizeof(spam_score_buffer),"%.1f", spamd_score);
- spam_score = spam_score_buffer;
- /* create "int" spam score */
- j = (int)((spamd_score + 0.001)*10);
- (void)string_format(spam_score_int_buffer, sizeof(spam_score_int_buffer), "%d", j);
- spam_score_int = spam_score_int_buffer;
-
- /* compare threshold against score */
- if (spamd_score >= spamd_threshold)
+ Ustrcpy(spam_action_buffer,
+ spamd_score >= spamd_threshold ? "reject" : "no action");
+ }
+
+/* Create report. Since this is a multiline string,
+we must hack it into shape first */
+p = &spamd_buffer[spamd_report_offset];
+q = spam_report_buffer;
+while (*p != '\0')
+ {
+ /* skip \r */
+ if (*p == '\r')
{
- /* spam as determined by user's threshold */
- spam_rc = OK;
+ p++;
+ continue;
}
- else
+ *q++ = *p;
+ if (*p++ == '\n')
{
- /* not spam */
- spam_rc = FAIL;
+ /* add an extra space after the newline to ensure
+ that it is treated as a header continuation line */
+ *q++ = ' ';
}
+ }
+/* NULL-terminate */
+*q-- = '\0';
+/* cut off trailing leftovers */
+while (*q <= ' ')
+ *q-- = '\0';
- /* remember expanded spamd_address if needed */
- if (spamd_address_work != spamd_address)
- prev_spamd_address_work = string_copy(spamd_address_work);
-
- /* remember user name and "been here" for it */
- Ustrcpy(prev_user_name, user_name);
- spam_ok = 1;
-
- if (override) /* always return OK, no matter what the score */
- return OK;
- else
- return spam_rc;
+spam_report = spam_report_buffer;
+spam_action = spam_action_buffer;
+
+/* create spam bar */
+spamd_score_char = spamd_score > 0 ? '+' : '-';
+j = abs((int)(spamd_score));
+i = 0;
+if (j != 0)
+ while ((i < j) && (i <= MAX_SPAM_BAR_CHARS))
+ spam_bar_buffer[i++] = spamd_score_char;
+else
+ {
+ spam_bar_buffer[0] = '/';
+ i = 1;
+ }
+spam_bar_buffer[i] = '\0';
+spam_bar = spam_bar_buffer;
+
+/* create "float" spam score */
+(void)string_format(spam_score_buffer, sizeof(spam_score_buffer),
+ "%.1f", spamd_score);
+spam_score = spam_score_buffer;
+
+/* create "int" spam score */
+j = (int)((spamd_score + 0.001)*10);
+(void)string_format(spam_score_int_buffer, sizeof(spam_score_int_buffer),
+ "%d", j);
+spam_score_int = spam_score_int_buffer;
+
+/* compare threshold against score */
+spam_rc = spamd_score >= spamd_threshold
+ ? OK /* spam as determined by user's threshold */
+ : FAIL; /* not spam */
+
+/* remember expanded spamd_address if needed */
+if (spamd_address_work != spamd_address)
+ prev_spamd_address_work = string_copy(spamd_address_work);
+
+/* remember user name and "been here" for it */
+Ustrcpy(prev_user_name, user_name);
+spam_ok = 1;
+
+return override
+ ? OK /* always return OK, no matter what the score */
+ : spam_rc;
+
+defer:
+ (void)fclose(mbox_file);
+ return DEFER;
}
#endif
+/* vi: aw ai sw=2
+*/
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) Tom Kistner <tom@duncanthrax.net> 2003-???? */
+/* Copyright (c) Tom Kistner <tom@duncanthrax.net> 2003 - 2015 */
/* License: GPL */
/* spam defines */
/* timeout for reading and writing spamd */
#define SPAMD_TIMEOUT 120
-/* maximum length of the spam bar */
+/* maximum length of the spam bar, please update the
+ * spec, the max length is mentioned there */
#define MAX_SPAM_BAR_CHARS 50
/* SHUT_WR seems to be undefined on Unixware ? */
#ifndef SHUT_WR
-#define SHUT_WR 1
+# define SHUT_WR 1
#endif
-typedef struct spamd_address_container {
- uschar tcp_addr[24];
- unsigned int tcp_port;
+/* default weight */
+#define SPAMD_WEIGHT 1
+
+typedef struct spamd_address_container
+{
+ uschar * hostspec;
+ int is_rspamd:1;
+ int is_failed:1;
+ unsigned int weight;
+ unsigned int timeout;
+ unsigned int retry;
+ unsigned int priority;
} spamd_address_container;
#endif
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2012 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Functions for reading spool files. When compiling for a utility (eximon),
tls_in.dane_verified = FALSE;
# endif
tls_in.cipher = NULL;
-tls_in.ourcert = NULL;
-tls_in.peercert = NULL;
+# ifndef COMPILE_UTILITY /* tls support fns not built in */
+tls_free_cert(&tls_in.ourcert);
+tls_free_cert(&tls_in.peercert);
+# endif
tls_in.peerdn = NULL;
tls_in.sni = NULL;
tls_in.ocsp = OCSP_NOT_REQ;
#endif
#ifdef WITH_CONTENT_SCAN
+spam_bar = NULL;
+spam_score = NULL;
spam_score_int = NULL;
#endif
+#if defined(SUPPORT_I18N) && !defined(COMPILE_UTILITY)
+message_smtputf8 = FALSE;
+message_utf8_downconvert = 0;
+#endif
+
dsn_ret = 0;
dsn_envid = NULL;
if (Ustrncmp(p, "ender_set_untrusted", 19) == 0)
sender_set_untrusted = TRUE;
#ifdef WITH_CONTENT_SCAN
+ else if (Ustrncmp(p, "pam_bar ", 8) == 0)
+ spam_bar = string_copy(big_buffer + 10);
+ else if (Ustrncmp(p, "pam_score ", 10) == 0)
+ spam_score = string_copy(big_buffer + 12);
else if (Ustrncmp(p, "pam_score_int ", 14) == 0)
spam_score_int = string_copy(big_buffer + 16);
+#endif
+#if defined(SUPPORT_I18N) && !defined(COMPILE_UTILITY)
+ else if (Ustrncmp(p, "mtputf8", 7) == 0)
+ message_smtputf8 = TRUE;
#endif
break;
break;
#endif
+#if defined(SUPPORT_I18N) && !defined(COMPILE_UTILITY)
+ case 'u':
+ if (Ustrncmp(p, "tf8_downcvt", 11) == 0)
+ message_utf8_downconvert = 1;
+ else if (Ustrncmp(p, "tf8_optdowncvt", 15) == 0)
+ message_utf8_downconvert = -1;
+ break;
+#endif
+
default: /* Present because some compilers complain if all */
break; /* possibilities are not covered. */
}
{
p -= len;
errors_to = string_copy(p);
- }
+ }
}
*(--p) = 0; /* Terminate address */
{
p -= len;
orcpt = string_copy(p);
- }
+ }
}
*(--p) = 0; /* Terminate address */
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) Tom Kistner <tom@duncanthrax.net> 2003-???? */
+/* Copyright (c) Tom Kistner <tom@duncanthrax.net> 2003 - 2015 */
/* License: GPL */
/* Code for setting up a MBOX style spool file inside a /scan/<msgid>
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2012 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Functions for writing spool files, and moving them about. */
if (local_error_message) fprintf(f, "-localerror\n");
if (local_scan_data != NULL) fprintf(f, "-local_scan %s\n", local_scan_data);
#ifdef WITH_CONTENT_SCAN
-if (spam_score_int != NULL) fprintf(f,"-spam_score_int %s\n", spam_score_int);
+if (spam_bar) fprintf(f,"-spam_bar %s\n", spam_bar);
+if (spam_score) fprintf(f,"-spam_score %s\n", spam_score);
+if (spam_score_int) fprintf(f,"-spam_score_int %s\n", spam_score_int);
#endif
if (deliver_manual_thaw) fprintf(f, "-manual_thaw\n");
if (sender_set_untrusted) fprintf(f, "-sender_set_untrusted\n");
if (tls_in.ocsp) fprintf(f, "-tls_ocsp %d\n", tls_in.ocsp);
#endif
+#ifdef SUPPORT_I18N
+if (message_smtputf8)
+ {
+ fprintf(f, "-smtputf8\n");
+ if (message_utf8_downconvert)
+ fprintf(f, "-utf8_%sdowncvt\n", message_utf8_downconvert < 0 ? "opt" : "");
+ }
+#endif
+
/* Write the dsn flags to the spool header file */
DEBUG(D_deliver) debug_printf("DSN: Write SPOOL :-dsn_envid %s\n", dsn_envid);
if (dsn_envid != NULL) fprintf(f, "-dsn_envid %s\n", dsn_envid);
fprintf(f, "%s %s %d,%d %s %d,%d#3\n", r->address, orcpt, Ustrlen(orcpt), r->dsn_flags,
errors_to, Ustrlen(errors_to), r->pno);
}
-
+
DEBUG(D_deliver) debug_printf("DSN: **** SPOOL_OUT - address: |%s| errorsto: |%s| orcpt: |%s| dsn_flags: %d\n",
r->address, r->errors_to, r->orcpt, r->dsn_flags);
}
#endif
/* End of spool_out.c */
+/* vi: aw ai sw=2
+*/
yield_length[store_pool] = newblock->length;
next_yield[store_pool] =
(void *)((char *)current_block[store_pool] + ALIGNED_SIZEOF_STOREBLOCK);
- VALGRIND_MAKE_MEM_NOACCESS(next_yield[store_pool], yield_length[store_pool]);
+ (void) VALGRIND_MAKE_MEM_NOACCESS(next_yield[store_pool], yield_length[store_pool]);
}
/* There's (now) enough room in the current block; the yield is the next
}
#endif /* COMPILE_UTILITY */
-VALGRIND_MAKE_MEM_UNDEFINED(store_last_get[store_pool], size);
+(void) VALGRIND_MAKE_MEM_UNDEFINED(store_last_get[store_pool], size);
/* Update next pointer and number of bytes left in the current block. */
next_yield[store_pool] = (void *)((char *)next_yield[store_pool] + size);
if (newsize % alignment != 0) newsize += alignment - (newsize % alignment);
next_yield[store_pool] = (char *)ptr + newsize;
yield_length[store_pool] -= newsize - rounded_oldsize;
-VALGRIND_MAKE_MEM_UNDEFINED(ptr + oldsize, inc);
+(void) VALGRIND_MAKE_MEM_UNDEFINED(ptr + oldsize, inc);
return TRUE;
}
#ifndef COMPILE_UTILITY
if (running_in_test_harness) memset(ptr, 0xF0, newlength);
#endif
-VALGRIND_MAKE_MEM_NOACCESS(ptr, newlength);
+(void) VALGRIND_MAKE_MEM_NOACCESS(ptr, newlength);
yield_length[store_pool] = newlength - (newlength % alignment);
next_yield[store_pool] = (char *)ptr + (newlength % alignment);
current_block[store_pool] = b;
b->next->length == STORE_BLOCK_SIZE)
{
b = b->next;
- VALGRIND_MAKE_MEM_NOACCESS((char *)b + ALIGNED_SIZEOF_STOREBLOCK, b->length - ALIGNED_SIZEOF_STOREBLOCK);
+ (void) VALGRIND_MAKE_MEM_NOACCESS((char *)b + ALIGNED_SIZEOF_STOREBLOCK,
+ b->length - ALIGNED_SIZEOF_STOREBLOCK);
}
bb = b->next;
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Miscellaneous string-handling functions. Some are not required for
*/
int
-string_interpret_escape(uschar **pp)
+string_interpret_escape(const uschar **pp)
{
#ifdef COMPILE_UTILITY
const uschar *hex_digits= CUS"0123456789abcdef";
#endif
int ch;
-uschar *p = *pp;
+const uschar *p = *pp;
ch = *(++p);
if (isdigit(ch) && ch != '8' && ch != '9')
{
Returns: string with non-printers encoded as printing sequences
*/
-uschar *
-string_printing2(uschar *s, BOOL allow_tab)
+const uschar *
+string_printing2(const uschar *s, BOOL allow_tab)
{
int nonprintcount = 0;
int length = 0;
-uschar *t = s;
+const uschar *t = s;
uschar *ss, *tt;
while (*t != 0)
{
if (*p == '\\')
{
- *q++ = string_interpret_escape(&p);
+ *q++ = string_interpret_escape((const uschar **)&p);
p++;
}
else
*/
uschar *
-string_copy_malloc(uschar *s)
+string_copy_malloc(const uschar *s)
{
int len = Ustrlen(s) + 1;
uschar *ss = store_malloc(len);
*/
uschar *
-string_copylc(uschar *s)
+string_copylc(const uschar *s)
{
uschar *ss = store_get(Ustrlen(s) + 1);
uschar *p = ss;
*/
uschar *
-string_copyn(uschar *s, int n)
+string_copyn(const uschar *s, int n)
{
uschar *ss = store_get(n + 1);
Ustrncpy(ss, s, n);
*/
uschar *
-string_dequote(uschar **sptr)
+string_dequote(const uschar **sptr)
{
-uschar *s = *sptr;
+const uschar *s = *sptr;
uschar *t, *yield;
/* First find the end of the string */
va_start(ap, format);
if (!string_vformat(buffer, sizeof(buffer), format, ap))
log_write(0, LOG_MAIN|LOG_PANIC_DIE,
- "string_sprintf expansion was longer than " SIZE_T_FMT " (%s)",
- sizeof(buffer), format);
+ "string_sprintf expansion was longer than " SIZE_T_FMT
+ "; format string was (%s)\nexpansion started '%.32s'",
+ sizeof(buffer), format, buffer);
va_end(ap);
return string_copy(buffer);
}
*/
uschar *
-string_nextinlist(uschar **listptr, int *separator, uschar *buffer, int buflen)
+string_nextinlist(const uschar **listptr, int *separator, uschar *buffer, int buflen)
{
-register int sep = *separator;
-register uschar *s = *listptr;
+int sep = *separator;
+const uschar *s = *listptr;
BOOL sep_is_special;
if (s == NULL) return NULL;
{
int size = 0;
int ptr = 0;
- uschar *ss;
+ const uschar *ss;
/* We know that *s != 0 at this point. However, it might be pointing to a
separator, which could indicate an empty string, or (if an ispunct()
new[off] = '\0';
return new;
}
+
+
+static const uschar *
+Ustrnchr(const uschar * s, int c, unsigned * len)
+{
+unsigned siz = *len;
+while (siz)
+ {
+ if (!*s) return NULL;
+ if (*s == c)
+ {
+ *len = siz;
+ return s;
+ }
+ s++;
+ siz--;
+ }
+return NULL;
+}
+
+uschar *
+string_append_listele_n(uschar * list, uschar sep, const uschar * ele,
+ unsigned len)
+{
+uschar * new = NULL;
+int sz = 0, off = 0;
+const uschar * sp;
+
+if (list)
+ {
+ new = string_cat(new, &sz, &off, list, Ustrlen(list));
+ new = string_cat(new, &sz, &off, &sep, 1);
+ }
+
+while((sp = Ustrnchr(ele, sep, &len)))
+ {
+ new = string_cat(new, &sz, &off, ele, sp-ele+1);
+ new = string_cat(new, &sz, &off, &sep, 1);
+ ele = sp+1;
+ len--;
+ }
+new = string_cat(new, &sz, &off, ele, len);
+new[off] = '\0';
+return new;
+}
#endif /* COMPILE_UTILITY */
string_get_localpart(address_item *addr, uschar *yield, int *sizeptr,
int *ptrptr)
{
-if (testflag(addr, af_include_affixes) && addr->prefix != NULL)
- yield = string_cat(yield, sizeptr, ptrptr, addr->prefix,
- Ustrlen(addr->prefix));
-yield = string_cat(yield, sizeptr, ptrptr, addr->local_part,
- Ustrlen(addr->local_part));
-if (testflag(addr, af_include_affixes) && addr->suffix != NULL)
- yield = string_cat(yield, sizeptr, ptrptr, addr->suffix,
- Ustrlen(addr->suffix));
+uschar * s;
+
+s = addr->prefix;
+if (testflag(addr, af_include_affixes) && s)
+ {
+#ifdef SUPPORT_I18N
+ if (testflag(addr, af_utf8_downcvt))
+ s = string_localpart_utf8_to_alabel(s, NULL);
+#endif
+ yield = string_cat(yield, sizeptr, ptrptr, s, Ustrlen(s));
+ }
+
+s = addr->local_part;
+#ifdef SUPPORT_I18N
+if (testflag(addr, af_utf8_downcvt))
+ s = string_localpart_utf8_to_alabel(s, NULL);
+#endif
+yield = string_cat(yield, sizeptr, ptrptr, s, Ustrlen(s));
+
+s = addr->suffix;
+if (testflag(addr, af_include_affixes) && s)
+ {
+#ifdef SUPPORT_I18N
+ if (testflag(addr, af_utf8_downcvt))
+ s = string_localpart_utf8_to_alabel(s, NULL);
+#endif
+ yield = string_cat(yield, sizeptr, ptrptr, s, Ustrlen(s));
+ }
+
return yield;
}
{
if (addr->local_part != NULL)
{
+ const uschar * s;
yield = string_get_localpart(addr, yield, &size, &ptr);
yield = string_cat(yield, &size, &ptr, US"@", 1);
- yield = string_cat(yield, &size, &ptr, addr->domain,
- Ustrlen(addr->domain) );
+ s = addr->domain;
+#ifdef SUPPORT_I18N
+ if (testflag(addr, af_utf8_downcvt))
+ s = string_localpart_utf8_to_alabel(s, NULL);
+#endif
+ yield = string_cat(yield, &size, &ptr, s, Ustrlen(s) );
}
else
{
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
typedef struct bit_table {
uschar *name;
- unsigned int bit;
+ int bit;
} bit_table;
/* Block for holding a uid and gid, possibly unset, and an initgroups flag. */
typedef struct host_item {
struct host_item *next;
- uschar *name; /* Host name */
- uschar *address; /* IP address in text form */
+ const uschar *name; /* Host name */
+ const uschar *address; /* IP address in text form */
int port; /* port value in host order (if SRV lookup) */
int mx; /* MX value if found via MX records */
int sort_key; /* MX*1000 plus random "fraction" */
uschar *remove_headers; /* Remove these headers */
uschar *return_path; /* Overriding (rewriting) return path */
uschar *debug_string; /* Debugging output */
+ uschar *max_parallel; /* Number of concurrent instances */
uschar *message_size_limit; /* Biggest message this transport handles */
uschar *headers_rewrite; /* Rules for rewriting headers */
rewrite_rule *rewrite_rules; /* Parsed rewriting rules */
BOOL log_fail_output;
BOOL log_defer_output;
BOOL retry_use_local_part; /* Defaults true for local, false for remote */
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
uschar *event_action; /* String to expand on notable events */
#endif
} transport_instance;
+typedef struct {
+ uschar *request;
+ uschar *require;
+} dnssec_domains;
+
/* Structure for holding information about the configured routers. */
typedef struct router_instance {
transport_instance *transport; /* Transport block (when found) */
struct router_instance *pass_router; /* Actual router for passed address */
struct router_instance *redirect_router; /* Actual router for generated address */
+
+ dnssec_domains dnssec;
} router_instance;
#ifdef EXPERIMENTAL_SRS
uschar *srs_sender; /* Change return path when delivering */
#endif
+ #ifdef SUPPORT_I18N
+ BOOL utf8_msg:1; /* requires SMTPUTF8 processing */
+ BOOL utf8_downcvt:1; /* mandatory downconvert on delivery */
+ BOOL utf8_downcvt_maybe:1; /* optional downconvert on delivery */
+ #endif
} address_item_propagated;
/* Bits for the flags field below */
#ifdef EXPERIMENTAL_DANE
# define af_dane_verified 0x20000000 /* TLS cert verify done with DANE */
#endif
+#ifdef SUPPORT_I18N
+# define af_utf8_downcvt 0x40000000 /* downconvert was done for delivery */
+#endif
/* These flags must be propagated when a child is created */
uschar *local_part; /* points to cc or lc version */
uschar *prefix; /* stripped prefix of local part */
uschar *suffix; /* stripped suffix of local part */
- uschar *domain; /* working domain (lower cased) */
+ const uschar *domain; /* working domain (lower cased) */
uschar *address_retry_key; /* retry key including full address */
uschar *domain_retry_key; /* retry key for domain only */
uschar *self_hostname; /* after self=pass */
uschar *shadow_message; /* info about shadow transporting */
- #ifdef SUPPORT_TLS
+#ifdef SUPPORT_TLS
uschar *cipher; /* Cipher used for transport */
void *ourcert; /* Certificate offered to peer, binary */
void *peercert; /* Certificate from peer, binary */
uschar *peerdn; /* DN of server's certificate */
int ocsp; /* OCSP status of peer cert */
- #endif
+#endif
+
+#ifdef EXPERIMENTAL_DSN_INFO
+ const uschar *smtp_greeting; /* peer self-identification */
+ const uschar *helo_response; /* peer message */
+#endif
uschar *authenticator; /* auth driver name used by transport */
uschar *auth_id; /* auth "login" name used by transport */
/* ( also */
/* ( contains verify rc in sender verify cache */
short int transport_return; /* result of delivery attempt */
- address_item_propagated p; /* fields that are propagated to children */
+ address_item_propagated prop; /* fields that are propagated to children */
} address_item;
/* The table of header names consists of items of this type */
typedef struct error_block {
struct error_block *next;
- uschar *text1;
+ const uschar *text1;
uschar *text2;
} error_block;
uschar name[1]; /* node name - variable length */
} tree_node;
+/* Structure for holding time-limited data such as DNS returns.
+We use this rather than extending tree_node to avoid wasting
+space for most tree use (variables...) at the cost of complexity
+for the lookups cache */
+
+typedef struct expiring_data {
+ time_t expiry; /* if nonzero, data invalid after this time */
+ void *ptr; /* pointer to data */
+} expiring_data;
+
/* Structure for holding the handle and the cached last lookup for searches.
This block is pointed to by the tree entry for the file. The file can get
closed if too many are opened at once. There is a LRU chain for deciding which
typedef struct {
uschar name[DNS_MAXNAME]; /* domain name */
int type; /* record type */
+ unsigned short ttl; /* time-to-live, seconds */
int size; /* size of data */
uschar *data; /* pointer to data */
} dns_record;
/* Structure for passing arguments to check_host() */
typedef struct check_host_block {
- uschar *host_name;
- uschar *host_address;
- uschar *host_ipv4;
+ const uschar *host_name;
+ const uschar *host_address;
+ const uschar *host_ipv4;
BOOL negative;
} check_host_block;
/* Structure for holding data for an entry in a named list */
typedef struct namedlist_block {
- uschar *string; /* the list string */
+ const uschar *string; /* the list string */
namedlist_cacheblock *cache_data; /* cached domain_data or localpart_data */
int number; /* the number of the list for caching */
} namedlist_block;
int verb;
} acl_block;
+/* smtp transport calc outbound_ip */
+typedef BOOL (*oicf) (uschar *message_id, void *data);
+
/* End of structs.h */
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Copyright (c) Phil Pennock 2012 */
# warning "GnuTLS library version too old; define DISABLE_OCSP in Makefile"
# define DISABLE_OCSP
#endif
-#if GNUTLS_VERSION_NUMBER < 0x020a00 && defined(EXPERIMENTAL_EVENT)
+#if GNUTLS_VERSION_NUMBER < 0x020a00 && !defined(DISABLE_EVENT)
# warning "GnuTLS library version too old; tls:cert event unsupported"
-# undef EXPERIMENTAL_EVENT
+# define DISABLE_EVENT
#endif
#if GNUTLS_VERSION_NUMBER >= 0x030306
# define SUPPORT_CA_DIR
#else
# undef SUPPORT_CA_DIR
#endif
-#if GNUTLS_VERSION_NUMBER >= 0x030314
+#if GNUTLS_VERSION_NUMBER >= 0x030014
# define SUPPORT_SYSDEFAULT_CABUNDLE
#endif
uschar *exp_tls_crl;
uschar *exp_tls_require_ciphers;
uschar *exp_tls_ocsp_file;
- uschar *exp_tls_verify_cert_hostnames;
-#ifdef EXPERIMENTAL_EVENT
+ const uschar *exp_tls_verify_cert_hostnames;
+#ifndef DISABLE_EVENT
uschar *event_action;
#endif
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL,
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
NULL,
#endif
NULL,
static BOOL exim_gnutls_base_init_done = FALSE;
+#ifndef DISABLE_OCSP
+static BOOL gnutls_buggy_ocsp = FALSE;
+#endif
+
/* ------------------------------------------------------------------------ */
/* macros */
} while (0)
static int
-import_cert(const gnutls_datum * cert, gnutls_x509_crt_t * crtp)
+import_cert(const gnutls_datum_t * cert, gnutls_x509_crt_t * crtp)
{
int rc;
/* record our certificate */
{
- const gnutls_datum * cert = gnutls_certificate_get_ours(state->session);
+ const gnutls_datum_t * cert = gnutls_certificate_get_ours(state->session);
gnutls_x509_crt_t crt;
tlsp->ourcert = cert && import_cert(cert, &crt)==0 ? crt : NULL;
{
int fd, rc;
unsigned int dh_bits;
-gnutls_datum m;
+gnutls_datum_t m;
uschar filename_buf[PATH_MAX];
uschar *filename = NULL;
size_t sz;
&& tls_ocsp_file
)
{
- if (!expand_check(tls_ocsp_file, US"tls_ocsp_file",
- &state->exp_tls_ocsp_file))
- return DEFER;
+ if (gnutls_buggy_ocsp)
+ {
+ DEBUG(D_tls) debug_printf("GnuTLS library is buggy for OCSP; avoiding\n");
+ }
+ else
+ {
+ if (!expand_check(tls_ocsp_file, US"tls_ocsp_file",
+ &state->exp_tls_ocsp_file))
+ return DEFER;
- /* Use the full callback method for stapling just to get observability.
- More efficient would be to read the file once only, if it never changed
- (due to SNI). Would need restart on file update, or watch datestamp. */
+ /* Use the full callback method for stapling just to get observability.
+ More efficient would be to read the file once only, if it never changed
+ (due to SNI). Would need restart on file update, or watch datestamp. */
- gnutls_certificate_set_ocsp_status_request_function(state->x509_cred,
- server_ocsp_stapling_cb, state->exp_tls_ocsp_file);
+ gnutls_certificate_set_ocsp_status_request_function(state->x509_cred,
+ server_ocsp_stapling_cb, state->exp_tls_ocsp_file);
- DEBUG(D_tls) debug_printf("Set OCSP response file %s\n", &state->exp_tls_ocsp_file);
+ DEBUG(D_tls) debug_printf("OCSP response file = %s\n", state->exp_tls_ocsp_file);
+ }
}
#endif
* Initialize for GnuTLS *
*************************************************/
+
+#ifndef DISABLE_OCSP
+
+static BOOL
+tls_is_buggy_ocsp(void)
+{
+const uschar * s;
+uschar maj, mid, mic;
+
+s = CUS gnutls_check_version(NULL);
+maj = atoi(CCS s);
+if (maj == 3)
+ {
+ while (*s && *s != '.') s++;
+ mid = atoi(CCS ++s);
+ if (mid <= 2)
+ return TRUE;
+ else if (mid >= 5)
+ return FALSE;
+ else
+ {
+ while (*s && *s != '.') s++;
+ mic = atoi(CCS ++s);
+ return mic <= (mid == 3 ? 16 : 3);
+ }
+ }
+return FALSE;
+}
+
+#endif
+
+
/* Called from both server and client code. In the case of a server, errors
before actual TLS negotiation return DEFER.
}
#endif
+#ifndef DISABLE_OCSP
+ if (tls_ocsp_file && (gnutls_buggy_ocsp = tls_is_buggy_ocsp()))
+ log_write(0, LOG_MAIN, "OCSP unusable with this GnuTLS library version");
+#endif
+
exim_gnutls_base_init_done = TRUE;
}
peer_status(exim_gnutls_state_st *state)
{
uschar cipherbuf[256];
-const gnutls_datum *cert_list;
+const gnutls_datum_t *cert_list;
int old_pool, rc;
unsigned int cert_list_size = 0;
gnutls_protocol_t protocol;
if (state->exp_tls_verify_cert_hostnames)
{
int sep = 0;
- uschar * list = state->exp_tls_verify_cert_hostnames;
+ const uschar * list = state->exp_tls_verify_cert_hostnames;
uschar * name;
while (name = string_nextinlist(&list, &sep, NULL, 0))
if (gnutls_x509_crt_check_hostname(state->tlsp->peercert, CS name))
#endif
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
/*
We use this callback to get observability and detail-level control
for an exim TLS connection (either direction), raising a tls:cert event
static int
verify_cb(gnutls_session_t session)
{
-const gnutls_datum * cert_list;
+const gnutls_datum_t * cert_list;
unsigned int cert_list_size = 0;
gnutls_x509_crt_t crt;
int rc;
gnutls_certificate_server_set_request(state->session, GNUTLS_CERT_IGNORE);
}
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
if (event_action)
{
state->event_action = event_action;
that the GnuTLS library doesn't. */
gnutls_transport_set_ptr2(state->session,
- (gnutls_transport_ptr)(long) fileno(smtp_in),
- (gnutls_transport_ptr)(long) fileno(smtp_out));
+ (gnutls_transport_ptr_t)(long) fileno(smtp_in),
+ (gnutls_transport_ptr_t)(long) fileno(smtp_out));
state->fd_in = fileno(smtp_in);
state->fd_out = fileno(smtp_out);
{
if (verify_check_given_host(&ob->tls_verify_cert_hostnames, host) == OK)
{
- state->exp_tls_verify_cert_hostnames = host->name;
+ state->exp_tls_verify_cert_hostnames =
+#ifdef SUPPORT_I18N
+ string_domain_utf8_to_alabel(host->name, NULL);
+#else
+ host->name;
+#endif
DEBUG(D_tls)
debug_printf("TLS: server cert verification includes hostname: \"%s\".\n",
state->exp_tls_verify_cert_hostnames);
gnutls_dh_set_prime_bits(state->session, dh_min_bits);
}
-/* Stick to the old behaviour for compatibility if tls_verify_certificates is
+/* Stick to the old behaviour for compatibility if tls_verify_certificates is
set but both tls_verify_hosts and tls_try_verify_hosts are unset. Check only
the specified host patterns if one of them is defined */
}
#endif
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
if (tb->event_action)
{
state->event_action = tb->event_action;
}
#endif
-gnutls_transport_set_ptr(state->session, (gnutls_transport_ptr)(long) fd);
+gnutls_transport_set_ptr(state->session, (gnutls_transport_ptr_t)(long) fd);
state->fd_in = fd;
state->fd_out = fd;
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Portions Copyright (c) The OpenSSL Project 1999 */
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/rand.h>
+#ifndef OPENSSL_NO_ECDH
+# include <openssl/ec.h>
+#endif
#ifndef DISABLE_OCSP
# include <openssl/ocsp.h>
#endif
#if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
# define EXIM_HAVE_OPENSSL_TLSEXT
#endif
-#if OPENSSL_VERSION_NUMBER >= 0x010100000L
-# define EXIM_HAVE_OPENSSL_CHECKHOST
-#endif
-#if OPENSSL_VERSION_NUMBER >= 0x010000000L \
+
+/*
+ * X509_check_host provides sane certificate hostname checking, but was added
+ * to OpenSSL late, after other projects forked off the code-base. So in
+ * addition to guarding against the base version number, beware that LibreSSL
+ * does not (at this time) support this function.
+ *
+ * If LibreSSL gains a different API, perhaps via libtls, then we'll probably
+ * opt to disentangle and ask a LibreSSL user to provide glue for a third
+ * crypto provider for libtls instead of continuing to tie the OpenSSL glue
+ * into even twistier knots. If LibreSSL gains the same API, we can just
+ * change this guard and punt the issue for a while longer.
+ */
+#ifndef LIBRESSL_VERSION_NUMBER
+# if OPENSSL_VERSION_NUMBER >= 0x010100000L
+# define EXIM_HAVE_OPENSSL_CHECKHOST
+# endif
+# if OPENSSL_VERSION_NUMBER >= 0x010000000L \
&& (OPENSSL_VERSION_NUMBER & 0x0000ff000L) >= 0x000002000L
-# define EXIM_HAVE_OPENSSL_CHECKHOST
+# define EXIM_HAVE_OPENSSL_CHECKHOST
+# endif
+
+# if !defined(OPENSSL_NO_ECDH)
+# if OPENSSL_VERSION_NUMBER >= 0x0090800fL
+# define EXIM_HAVE_ECDH
+# endif
+# if OPENSSL_VERSION_NUMBER >= 0x10002000L
+# define EXIM_HAVE_OPENSSL_ECDH_AUTO
+# define EXIM_HAVE_OPENSSL_EC_NIST2NID
+# endif
+# endif
#endif
#if !defined(EXIM_HAVE_OPENSSL_TLSEXT) && !defined(DISABLE_OCSP)
uschar *server_cipher_list;
/* only passed down to tls_error: */
host_item *host;
- uschar * verify_cert_hostnames;
-#ifdef EXPERIMENTAL_EVENT
+ const uschar * verify_cert_hostnames;
+#ifndef DISABLE_EVENT
uschar * event_action;
#endif
} tls_ext_ctx_cb;
*/
static int
-tls_error(uschar *prefix, host_item *host, uschar *msg)
+tls_error(uschar * prefix, const host_item * host, uschar * msg)
{
if (!msg)
{
{
X509 * current_cert= tmp_obj->data.x509;
X509_NAME_oneline(X509_get_subject_name(current_cert), CS name, sizeof(name));
+ name[sizeof(name)-1] = '\0';
debug_printf(" %s\n", name);
}
}
*/
+#ifndef DISABLE_EVENT
+static int
+verify_event(tls_support * tlsp, X509 * cert, int depth, const uschar * dn,
+ BOOL *calledp, const BOOL *optionalp, const uschar * what)
+{
+uschar * ev;
+uschar * yield;
+X509 * old_cert;
+
+ev = tlsp == &tls_out ? client_static_cbinfo->event_action : event_action;
+if (ev)
+ {
+ DEBUG(D_tls) debug_printf("verify_event: %s %d\n", what, depth);
+ old_cert = tlsp->peercert;
+ tlsp->peercert = X509_dup(cert);
+ /* NB we do not bother setting peerdn */
+ if ((yield = event_raise(ev, US"tls:cert", string_sprintf("%d", depth))))
+ {
+ log_write(0, LOG_MAIN, "[%s] %s verify denied by event-action: "
+ "depth=%d cert=%s: %s",
+ tlsp == &tls_out ? deliver_host_address : sender_host_address,
+ what, depth, dn, yield);
+ *calledp = TRUE;
+ if (!*optionalp)
+ {
+ if (old_cert) tlsp->peercert = old_cert; /* restore 1st failing cert */
+ return 1; /* reject (leaving peercert set) */
+ }
+ DEBUG(D_tls) debug_printf("Event-action verify failure overridden "
+ "(host in tls_try_verify_hosts)\n");
+ }
+ X509_free(tlsp->peercert);
+ tlsp->peercert = old_cert;
+ }
+return 0;
+}
+#endif
+
/*************************************************
* Callback for verification *
*************************************************/
/* The SSL library does certificate verification if set up to do so. This
callback has the current yes/no state is in "state". If verification succeeded,
-we set up the tls_peerdn string. If verification failed, what happens depends
-on whether the client is required to present a verifiable certificate or not.
+we set the certificate-verified flag. If verification failed, what happens
+depends on whether the client is required to present a verifiable certificate
+or not.
If verification is optional, we change the state to yes, but still log the
verification error. For some reason (it really would help to have proper
documentation of OpenSSL), this callback function then gets called again, this
-time with state = 1. In fact, that's useful, because we can set up the peerdn
-value, but we must take care not to set the private verified flag on the second
-time through.
+time with state = 1. We must take care not to set the private verified flag on
+the second time through.
Note: this function is not called if the client fails to present a certificate
when asked. We get here only if a certificate has been received. Handling of
for a given "depth" in the certificate chain.
Arguments:
- state current yes/no state as 1/0
- x509ctx certificate information.
- client TRUE for client startup, FALSE for server startup
+ preverify_ok current yes/no state as 1/0
+ x509ctx certificate information.
+ tlsp per-direction (client vs. server) support data
+ calledp has-been-called flag
+ optionalp verification-is-optional flag
-Returns: 1 if verified, 0 if not
+Returns: 0 if verification should fail, otherwise 1
*/
static int
-verify_callback(int state, X509_STORE_CTX *x509ctx,
+verify_callback(int preverify_ok, X509_STORE_CTX *x509ctx,
tls_support *tlsp, BOOL *calledp, BOOL *optionalp)
{
X509 * cert = X509_STORE_CTX_get_current_cert(x509ctx);
int depth = X509_STORE_CTX_get_error_depth(x509ctx);
-static uschar txt[256];
-#ifdef EXPERIMENTAL_EVENT
-uschar * ev;
-uschar * yield;
-#endif
+uschar dn[256];
-X509_NAME_oneline(X509_get_subject_name(cert), CS txt, sizeof(txt));
+X509_NAME_oneline(X509_get_subject_name(cert), CS dn, sizeof(dn));
+dn[sizeof(dn)-1] = '\0';
-if (state == 0)
+if (preverify_ok == 0)
{
- log_write(0, LOG_MAIN, "SSL verify error: depth=%d error=%s cert=%s",
+ log_write(0, LOG_MAIN, "[%s] SSL verify error: depth=%d error=%s cert=%s",
+ tlsp == &tls_out ? deliver_host_address : sender_host_address,
depth,
X509_verify_cert_error_string(X509_STORE_CTX_get_error(x509ctx)),
- txt);
+ dn);
*calledp = TRUE;
if (!*optionalp)
{
- tlsp->peercert = X509_dup(cert);
- return 0; /* reject */
+ if (!tlsp->peercert)
+ tlsp->peercert = X509_dup(cert); /* record failing cert */
+ return 0; /* reject */
}
DEBUG(D_tls) debug_printf("SSL verify failure overridden (host in "
"tls_try_verify_hosts)\n");
else if (depth != 0)
{
- DEBUG(D_tls) debug_printf("SSL verify ok: depth=%d SN=%s\n", depth, txt);
+ DEBUG(D_tls) debug_printf("SSL verify ok: depth=%d SN=%s\n", depth, dn);
#ifndef DISABLE_OCSP
if (tlsp == &tls_out && client_static_cbinfo->u_ocsp.client.verify_store)
{ /* client, wanting stapling */
/* Add the server cert's signing chain as the one
for the verification of the OCSP stapled information. */
-
+
if (!X509_STORE_add_cert(client_static_cbinfo->u_ocsp.client.verify_store,
cert))
ERR_clear_error();
}
#endif
-#ifdef EXPERIMENTAL_EVENT
- ev = tlsp == &tls_out ? client_static_cbinfo->event_action : event_action;
- if (ev)
- {
- tlsp->peercert = X509_dup(cert);
- if ((yield = event_raise(ev, US"tls:cert", string_sprintf("%d", depth))))
- {
- log_write(0, LOG_MAIN, "SSL verify denied by event-action: "
- "depth=%d cert=%s: %s", depth, txt, yield);
- *calledp = TRUE;
- if (!*optionalp)
- return 0; /* reject */
- DEBUG(D_tls) debug_printf("Event-action verify failure overridden "
- "(host in tls_try_verify_hosts)\n");
- }
- X509_free(tlsp->peercert);
- tlsp->peercert = NULL;
- }
+#ifndef DISABLE_EVENT
+ if (verify_event(tlsp, cert, depth, dn, calledp, optionalp, US"SSL"))
+ return 0; /* reject, with peercert set */
#endif
}
else
{
- uschar * verify_cert_hostnames;
-
- tlsp->peerdn = txt;
- tlsp->peercert = X509_dup(cert);
+ const uschar * verify_cert_hostnames;
if ( tlsp == &tls_out
&& ((verify_cert_hostnames = client_static_cbinfo->verify_cert_hostnames)))
/* client, wanting hostname check */
-
-# if EXIM_HAVE_OPENSSL_CHECKHOST
-# ifndef X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS
-# define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 0
-# endif
-# ifndef X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS
-# define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 0
-# endif
{
+
+#ifdef EXIM_HAVE_OPENSSL_CHECKHOST
+# ifndef X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS
+# define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 0
+# endif
+# ifndef X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS
+# define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 0
+# endif
int sep = 0;
- uschar * list = verify_cert_hostnames;
+ const uschar * list = verify_cert_hostnames;
uschar * name;
int rc;
while ((name = string_nextinlist(&list, &sep, NULL, 0)))
- if ((rc = X509_check_host(cert, name, 0,
+ if ((rc = X509_check_host(cert, CCS name, 0,
X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS
- | X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS)))
+ | X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS,
+ NULL)))
{
if (rc < 0)
{
- log_write(0, LOG_MAIN, "SSL verify error: internal error\n");
+ log_write(0, LOG_MAIN, "[%s] SSL verify error: internal error",
+ tlsp == &tls_out ? deliver_host_address : sender_host_address);
name = NULL;
}
break;
}
if (!name)
- {
- log_write(0, LOG_MAIN,
- "SSL verify error: certificate name mismatch: \"%s\"\n", txt);
- *calledp = TRUE;
- if (!*optionalp)
- return 0; /* reject */
- DEBUG(D_tls) debug_printf("SSL verify failure overridden (host in "
- "tls_try_verify_hosts)\n");
- }
- }
-# else
+#else
if (!tls_is_name_for_cert(verify_cert_hostnames, cert))
+#endif
{
log_write(0, LOG_MAIN,
- "SSL verify error: certificate name mismatch: \"%s\"\n", txt);
+ "[%s] SSL verify error: certificate name mismatch: \"%s\"",
+ tlsp == &tls_out ? deliver_host_address : sender_host_address,
+ dn);
*calledp = TRUE;
if (!*optionalp)
- return 0; /* reject */
+ {
+ if (!tlsp->peercert)
+ tlsp->peercert = X509_dup(cert); /* record failing cert */
+ return 0; /* reject */
+ }
DEBUG(D_tls) debug_printf("SSL verify failure overridden (host in "
"tls_try_verify_hosts)\n");
}
-# endif
+ }
-#ifdef EXPERIMENTAL_EVENT
- ev = tlsp == &tls_out ? client_static_cbinfo->event_action : event_action;
- if (ev)
- if ((yield = event_raise(ev, US"tls:cert", US"0")))
- {
- log_write(0, LOG_MAIN, "SSL verify denied by event-action: "
- "depth=0 cert=%s: %s", txt, yield);
- *calledp = TRUE;
- if (!*optionalp)
- return 0; /* reject */
- DEBUG(D_tls) debug_printf("Event-action verify failure overridden "
- "(host in tls_try_verify_hosts)\n");
- }
+#ifndef DISABLE_EVENT
+ if (verify_event(tlsp, cert, depth, dn, calledp, optionalp, US"SSL"))
+ return 0; /* reject, with peercert set */
#endif
DEBUG(D_tls) debug_printf("SSL%s verify ok: depth=0 SN=%s\n",
- *calledp ? "" : " authenticated", txt);
+ *calledp ? "" : " authenticated", dn);
if (!*calledp) tlsp->certificate_verified = TRUE;
*calledp = TRUE;
}
}
static int
-verify_callback_client(int state, X509_STORE_CTX *x509ctx)
+verify_callback_client(int preverify_ok, X509_STORE_CTX *x509ctx)
{
-return verify_callback(state, x509ctx, &tls_out, &client_verify_callback_called, &client_verify_optional);
+return verify_callback(preverify_ok, x509ctx, &tls_out,
+ &client_verify_callback_called, &client_verify_optional);
}
static int
-verify_callback_server(int state, X509_STORE_CTX *x509ctx)
+verify_callback_server(int preverify_ok, X509_STORE_CTX *x509ctx)
{
-return verify_callback(state, x509ctx, &tls_in, &server_verify_callback_called, &server_verify_optional);
+return verify_callback(preverify_ok, x509ctx, &tls_in,
+ &server_verify_callback_called, &server_verify_optional);
}
itself.
*/
static int
-verify_callback_client_dane(int state, X509_STORE_CTX * x509ctx)
+verify_callback_client_dane(int preverify_ok, X509_STORE_CTX * x509ctx)
{
X509 * cert = X509_STORE_CTX_get_current_cert(x509ctx);
-static uschar txt[256];
-#ifdef EXPERIMENTAL_EVENT
+uschar dn[256];
+#ifndef DISABLE_EVENT
int depth = X509_STORE_CTX_get_error_depth(x509ctx);
-uschar * yield;
+BOOL dummy_called, optional = FALSE;
#endif
-X509_NAME_oneline(X509_get_subject_name(cert), CS txt, sizeof(txt));
+X509_NAME_oneline(X509_get_subject_name(cert), CS dn, sizeof(dn));
+dn[sizeof(dn)-1] = '\0';
-DEBUG(D_tls) debug_printf("verify_callback_client_dane: %s\n", txt);
-tls_out.peerdn = txt;
-tls_out.peercert = X509_dup(cert);
+DEBUG(D_tls) debug_printf("verify_callback_client_dane: %s depth %d %s\n",
+ preverify_ok ? "ok":"BAD", depth, dn);
-#ifdef EXPERIMENTAL_EVENT
- if (client_static_cbinfo->event_action)
- {
- if ((yield = event_raise(client_static_cbinfo->event_action,
- US"tls:cert", string_sprintf("%d", depth))))
- {
- log_write(0, LOG_MAIN, "DANE verify denied by event-action: "
- "depth=%d cert=%s: %s", depth, txt, yield);
- tls_out.certificate_verified = FALSE;
- return 0; /* reject */
- }
- if (depth != 0)
- {
- X509_free(tls_out.peercert);
- tls_out.peercert = NULL;
- }
- }
+#ifndef DISABLE_EVENT
+ if (verify_event(&tls_out, cert, depth, dn,
+ &dummy_called, &optional, US"DANE"))
+ return 0; /* reject, with peercert set */
#endif
-if (state == 1)
+if (preverify_ok == 1)
tls_out.dane_verified =
tls_out.certificate_verified = TRUE;
-return 1;
+else
+ {
+ int err = X509_STORE_CTX_get_error(x509ctx);
+ DEBUG(D_tls)
+ debug_printf(" - err %d '%s'\n", err, X509_verify_cert_error_string(err));
+ if (err = X509_V_ERR_APPLICATION_VERIFICATION)
+ preverify_ok = 1;
+ }
+return preverify_ok;
}
#endif /*EXPERIMENTAL_DANE*/
/* If dhparam is set, expand it, and load up the parameters for DH encryption.
Arguments:
+ sctx The current SSL CTX (inbound or outbound)
dhparam DH parameter file or fixed parameter identity string
host connected host, if client; NULL if server
*/
static BOOL
-init_dh(SSL_CTX *sctx, uschar *dhparam, host_item *host)
+init_dh(SSL_CTX *sctx, uschar *dhparam, const host_item *host)
{
BIO *bio;
DH *dh;
+/*************************************************
+* Initialize for ECDH *
+*************************************************/
+
+/* Load parameters for ECDH encryption.
+
+For now, we stick to NIST P-256 because: it's simple and easy to configure;
+it avoids any patent issues that might bite redistributors; despite events in
+the news and concerns over curve choices, we're not cryptographers, we're not
+pretending to be, and this is "good enough" to be better than no support,
+protecting against most adversaries. Given another year or two, there might
+be sufficient clarity about a "right" way forward to let us make an informed
+decision, instead of a knee-jerk reaction.
+
+Longer-term, we should look at supporting both various named curves and
+external files generated with "openssl ecparam", much as we do for init_dh().
+We should also support "none" as a value, to explicitly avoid initialisation.
+
+Patches welcome.
+
+Arguments:
+ sctx The current SSL CTX (inbound or outbound)
+ host connected host, if client; NULL if server
+
+Returns: TRUE if OK (nothing to set up, or setup worked)
+*/
+
+static BOOL
+init_ecdh(SSL_CTX * sctx, host_item * host)
+{
+#ifdef OPENSSL_NO_ECDH
+return TRUE;
+#else
+
+EC_KEY * ecdh;
+uschar * exp_curve;
+int nid;
+BOOL rv;
+
+if (host) /* No ECDH setup for clients, only for servers */
+ return TRUE;
+
+# ifndef EXIM_HAVE_ECDH
+DEBUG(D_tls)
+ debug_printf("No OpenSSL API to define ECDH parameters, skipping\n");
+return TRUE;
+# else
+
+if (!expand_check(tls_eccurve, US"tls_eccurve", &exp_curve))
+ return FALSE;
+if (!exp_curve || !*exp_curve)
+ return TRUE;
+
+# ifdef EXIM_HAVE_OPENSSL_ECDH_AUTO
+/* check if new enough library to support auto ECDH temp key parameter selection */
+if (Ustrcmp(exp_curve, "auto") == 0)
+ {
+ DEBUG(D_tls) debug_printf(
+ "ECDH temp key parameter settings: OpenSSL 1.2+ autoselection\n");
+ SSL_CTX_set_ecdh_auto(sctx, 1);
+ return TRUE;
+ }
+# endif
+
+DEBUG(D_tls) debug_printf("ECDH: curve '%s'\n", exp_curve);
+if ( (nid = OBJ_sn2nid (CCS exp_curve)) == NID_undef
+# ifdef EXIM_HAVE_OPENSSL_EC_NIST2NID
+ && (nid = EC_curve_nist2nid(CCS exp_curve)) == NID_undef
+# endif
+ )
+ {
+ tls_error(string_sprintf("Unknown curve name tls_eccurve '%s'",
+ exp_curve),
+ host, NULL);
+ return FALSE;
+ }
+
+if (!(ecdh = EC_KEY_new_by_curve_name(nid)))
+ {
+ tls_error(US"Unable to create ec curve", host, NULL);
+ return FALSE;
+ }
+
+/* The "tmp" in the name here refers to setting a temporary key
+not to the stability of the interface. */
+
+if ((rv = SSL_CTX_set_tmp_ecdh(sctx, ecdh) == 0))
+ tls_error(string_sprintf("Error enabling '%s' curve", exp_curve), host, NULL);
+else
+ DEBUG(D_tls) debug_printf("ECDH: enabled '%s' curve\n", exp_curve);
+
+EC_KEY_free(ecdh);
+return !rv;
+
+# endif /*EXIM_HAVE_ECDH*/
+#endif /*OPENSSL_NO_ECDH*/
+}
+
+
+
+
#ifndef DISABLE_OCSP
/*************************************************
* Load OCSP information into state *
of the expansion is an empty string, ignore it also, and assume the private
key is in the same file as the certificate. */
-if (expanded != NULL && *expanded != 0)
+if (expanded && *expanded)
{
DEBUG(D_tls) debug_printf("tls_privatekey file %s\n", expanded);
if (!SSL_CTX_use_PrivateKey_file(sctx, CS expanded, SSL_FILETYPE_PEM))
}
#ifndef DISABLE_OCSP
-if (cbinfo->is_server && cbinfo->u_ocsp.server.file != NULL)
+if (cbinfo->is_server && cbinfo->u_ocsp.server.file)
{
if (!expand_check(cbinfo->u_ocsp.server.file, US"tls_ocsp_file", &expanded))
return DEFER;
- if (expanded != NULL && *expanded != 0)
+ if (expanded && *expanded)
{
DEBUG(D_tls) debug_printf("tls_ocsp_file %s\n", expanded);
- if (cbinfo->u_ocsp.server.file_expanded &&
- (Ustrcmp(expanded, cbinfo->u_ocsp.server.file_expanded) == 0))
+ if ( cbinfo->u_ocsp.server.file_expanded
+ && (Ustrcmp(expanded, cbinfo->u_ocsp.server.file_expanded) == 0))
{
- DEBUG(D_tls)
- debug_printf("tls_ocsp_file value unchanged, using existing values.\n");
- } else {
- ocsp_load_response(sctx, cbinfo, expanded);
+ DEBUG(D_tls) debug_printf(" - value unchanged, using existing values\n");
+ }
+ else
+ {
+ ocsp_load_response(sctx, cbinfo, expanded);
}
}
}
SSL_CTX_set_timeout(server_sni, SSL_CTX_get_timeout(server_ctx));
SSL_CTX_set_tlsext_servername_callback(server_sni, tls_servername_cb);
SSL_CTX_set_tlsext_servername_arg(server_sni, cbinfo);
+
+if ( !init_dh(server_sni, cbinfo->dhparam, NULL)
+ || !init_ecdh(server_sni, NULL)
+ )
+ return SSL_TLSEXT_ERR_NOACK;
+
if (cbinfo->server_cipher_list)
SSL_CTX_set_cipher_list(server_sni, CS cbinfo->server_cipher_list);
#ifndef DISABLE_OCSP
/* do this after setup_certs, because this can require the certs for verifying
OCSP information. */
-rc = tls_expand_session_files(server_sni, cbinfo);
-if (rc != OK) return SSL_TLSEXT_ERR_NOACK;
-
-if (!init_dh(server_sni, cbinfo->dhparam, NULL))
+if ((rc = tls_expand_session_files(server_sni, cbinfo)) != OK)
return SSL_TLSEXT_ERR_NOACK;
DEBUG(D_tls) debug_printf("Switching SSL context.\n");
int response_der_len;
DEBUG(D_tls)
- debug_printf("Received TLS status request (OCSP stapling); %s response.",
+ debug_printf("Received TLS status request (OCSP stapling); %s response\n",
cbinfo->u_ocsp.server.response ? "have" : "lack");
tls_in.ocsp = OCSP_NOT_RESP;
if(!p)
{
/* Expect this when we requested ocsp but got none */
- if ( cbinfo->u_ocsp.client.verify_required
- && log_extra_selector & LX_tls_cipher)
+ if (cbinfo->u_ocsp.client.verify_required && LOGGING(tls_cipher))
log_write(0, LOG_MAIN, "Received TLS status callback, null content");
else
DEBUG(D_tls) debug_printf(" null\n");
if(!(rsp = d2i_OCSP_RESPONSE(NULL, &p, len)))
{
tls_out.ocsp = OCSP_FAILED;
- if (log_extra_selector & LX_tls_cipher)
+ if (LOGGING(tls_cipher))
log_write(0, LOG_MAIN, "Received TLS cert status response, parse error");
else
DEBUG(D_tls) debug_printf(" parse error\n");
if(!(bs = OCSP_response_get1_basic(rsp)))
{
tls_out.ocsp = OCSP_FAILED;
- if (log_extra_selector & LX_tls_cipher)
+ if (LOGGING(tls_cipher))
log_write(0, LOG_MAIN, "Received TLS cert status response, error parsing response");
else
DEBUG(D_tls) debug_printf(" error parsing response\n");
cbinfo->u_ocsp.client.verify_store, 0)) <= 0)
{
tls_out.ocsp = OCSP_FAILED;
- if (log_extra_selector & LX_tls_cipher)
+ if (LOGGING(tls_cipher))
log_write(0, LOG_MAIN, "Received TLS cert status response, itself unverifiable");
BIO_printf(bp, "OCSP response verify failure\n");
ERR_print_errors(bp);
cbinfo->dhparam = dhparam;
cbinfo->server_cipher_list = NULL;
cbinfo->host = host;
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
cbinfo->event_action = NULL;
#endif
/* Set up the information callback, which outputs if debugging is at a suitable
level. */
-SSL_CTX_set_info_callback(*ctxp, (void (*)())info_callback);
+DEBUG(D_tls) SSL_CTX_set_info_callback(*ctxp, (void (*)())info_callback);
/* Automatically re-try reads/writes after renegotiation. */
(void) SSL_CTX_set_mode(*ctxp, SSL_MODE_AUTO_RETRY);
DEBUG(D_tls) debug_printf("no SSL CTX options to set\n");
/* Initialize with DH parameters if supplied */
+/* Initialize ECDH temp key parameter selection */
-if (!init_dh(*ctxp, dhparam, host)) return DEFER;
+if ( !init_dh(*ctxp, dhparam, host)
+ || !init_ecdh(*ctxp, host)
+ )
+ return DEFER;
/* Set up certificate and key (and perhaps OCSP info) */
}
+static void
+peer_cert(SSL * ssl, tls_support * tlsp, uschar * peerdn, unsigned bsize)
+{
+/*XXX we might consider a list-of-certs variable for the cert chain.
+SSL_get_peer_cert_chain(SSL*). We'd need a new variable type and support
+in list-handling functions, also consider the difference between the entire
+chain and the elements sent by the peer. */
+
+/* Will have already noted peercert on a verify fail; possibly not the leaf */
+if (!tlsp->peercert)
+ tlsp->peercert = SSL_get_peer_certificate(ssl);
+/* Beware anonymous ciphers which lead to server_cert being NULL */
+if (tlsp->peercert)
+ {
+ X509_NAME_oneline(X509_get_subject_name(tlsp->peercert), CS peerdn, bsize);
+ peerdn[bsize-1] = '\0';
+ tlsp->peerdn = peerdn; /*XXX a static buffer... */
+ }
+else
+ tlsp->peerdn = NULL;
+}
+
+
if (!expand_check(certs, US"tls_verify_certificates", &expcerts))
return DEFER;
-if (expcerts != NULL && *expcerts != '\0')
+if (expcerts && *expcerts)
{
- if (Ustrcmp(expcerts, "system") == 0)
- {
- /* Tell the library to use its compiled-in location for the system default
- CA bundle, only */
+ /* Tell the library to use its compiled-in location for the system default
+ CA bundle. Then add the ones specified in the config, if any. */
- if (!SSL_CTX_set_default_verify_paths(sctx))
- return tls_error(US"SSL_CTX_set_default_verify_paths", host, NULL);
- }
- else
+ if (!SSL_CTX_set_default_verify_paths(sctx))
+ return tls_error(US"SSL_CTX_set_default_verify_paths", host, NULL);
+
+ if (Ustrcmp(expcerts, "system") != 0)
{
struct stat statbuf;
- /* Tell the library to use its compiled-in location for the system default
- CA bundle. Those given by the exim config are additional to these */
-
- if (!SSL_CTX_set_default_verify_paths(sctx))
- return tls_error(US"SSL_CTX_set_default_verify_paths", host, NULL);
-
if (Ustat(expcerts, &statbuf) < 0)
{
log_write(0, LOG_MAIN|LOG_PANIC,
certificates are recognized, but the error message is still misleading (it
says no certificate was supplied.) But this is better. */
- if ((file == NULL || statbuf.st_size > 0) &&
- !SSL_CTX_load_verify_locations(sctx, CS file, CS dir))
+ if ( (!file || statbuf.st_size > 0)
+ && !SSL_CTX_load_verify_locations(sctx, CS file, CS dir))
return tls_error(US"SSL_CTX_load_verify_locations", host, NULL);
/* Load the list of CAs for which we will accept certs, for sending
If a list isn't loaded into the server, but
some verify locations are set, the server end appears to make
a wildcard reqest for client certs.
- Meanwhile, the client library as deafult behaviour *ignores* the list
+ Meanwhile, the client library as default behaviour *ignores* the list
we send over the wire - see man SSL_CTX_set_client_cert_cb.
Because of this, and that the dir variant is likely only used for
the public-CA bundle (not for a private CA), not worth fixing.
*/
- if (file != NULL)
+ if (file)
{
STACK_OF(X509_NAME) * names = SSL_load_client_CA_file(CS file);
- DEBUG(D_tls) debug_printf("Added %d certificate authorities.\n",
+
+ DEBUG(D_tls) debug_printf("Added %d certificate authorities.\n",
sk_X509_NAME_num(names));
SSL_CTX_set_client_CA_list(sctx, names);
}
/* Handle a certificate revocation list. */
- #if OPENSSL_VERSION_NUMBER > 0x00907000L
+#if OPENSSL_VERSION_NUMBER > 0x00907000L
/* This bit of code is now the version supplied by Lars Mainka. (I have
- * merely reformatted it into the Exim code style.)
+ merely reformatted it into the Exim code style.)
- * "From here I changed the code to add support for multiple crl's
- * in pem format in one file or to support hashed directory entries in
- * pem format instead of a file. This method now uses the library function
- * X509_STORE_load_locations to add the CRL location to the SSL context.
- * OpenSSL will then handle the verify against CA certs and CRLs by
- * itself in the verify callback." */
+ "From here I changed the code to add support for multiple crl's
+ in pem format in one file or to support hashed directory entries in
+ pem format instead of a file. This method now uses the library function
+ X509_STORE_load_locations to add the CRL location to the SSL context.
+ OpenSSL will then handle the verify against CA certs and CRLs by
+ itself in the verify callback." */
if (!expand_check(crl, US"tls_crl", &expcrl)) return DEFER;
- if (expcrl != NULL && *expcrl != 0)
+ if (expcrl && *expcrl)
{
struct stat statbufcrl;
if (Ustat(expcrl, &statbufcrl) < 0)
}
}
- #endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */
+#endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */
/* If verification is optional, don't fail if no certificate */
int rc;
uschar *expciphers;
tls_ext_ctx_cb *cbinfo;
+static uschar peerdn[256];
static uschar cipherbuf[256];
/* Check for previous activation */
/* TLS has been set up. Adjust the input functions to read via TLS,
and initialize things. */
+peer_cert(server_ssl, &tls_in, peerdn, sizeof(peerdn));
+
construct_cipher_name(server_ssl, cipherbuf, sizeof(cipherbuf), &tls_in.bits);
tls_in.cipher = cipherbuf;
)
{
int rc;
-/* stick to the old behaviour for compatibility if tls_verify_certificates is
+/* stick to the old behaviour for compatibility if tls_verify_certificates is
set but both tls_verify_hosts and tls_try_verify_hosts is not set. Check only
the specified host patterns if one of them is defined */
if (verify_check_given_host(&ob->tls_verify_cert_hostnames, host) == OK)
{
- cbinfo->verify_cert_hostnames = host->name;
+ cbinfo->verify_cert_hostnames =
+#ifdef SUPPORT_I18N
+ string_domain_utf8_to_alabel(host->name, NULL);
+#else
+ host->name;
+#endif
DEBUG(D_tls) debug_printf("Cert hostname to check: \"%s\"\n",
cbinfo->verify_cert_hostnames);
}
return OK;
log_write(0, LOG_MAIN, "DANE error: No usable TLSA records");
-return FAIL;
+return DEFER;
}
#endif /*EXPERIMENTAL_DANE*/
{
smtp_transport_options_block * ob =
(smtp_transport_options_block *)tb->options_block;
-static uschar txt[256];
+static uschar peerdn[256];
uschar * expciphers;
-X509 * server_cert;
int rc;
static uschar cipherbuf[256];
#ifdef EXPERIMENTAL_DANE
if (tlsa_dnsa)
{
- SSL_CTX_set_verify(client_ctx, SSL_VERIFY_PEER, verify_callback_client_dane);
+ SSL_CTX_set_verify(client_ctx,
+ SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
+ verify_callback_client_dane);
if (!DANESSL_library_init())
return tls_error(US"library init", host, NULL);
}
#endif
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
client_static_cbinfo->event_action = tb->event_action;
#endif
DEBUG(D_tls) debug_printf("SSL_connect succeeded\n");
-/* Beware anonymous ciphers which lead to server_cert being NULL */
-/*XXX server_cert is never freed... use X509_free() */
-server_cert = SSL_get_peer_certificate (client_ssl);
-if (server_cert)
- {
- tls_out.peerdn = US X509_NAME_oneline(X509_get_subject_name(server_cert),
- CS txt, sizeof(txt));
- tls_out.peerdn = txt; /*XXX a static buffer... */
- }
-else
- tls_out.peerdn = NULL;
+peer_cert(client_ssl, &tls_out, peerdn, sizeof(peerdn));
construct_cipher_name(client_ssl, cipherbuf, sizeof(cipherbuf), &tls_out.bits);
tls_out.cipher = cipherbuf;
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2012 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* This module provides TLS (aka SSL) support for Exim. The code for OpenSSL is
* Timezone environment flipping *
*************************************************/
+#ifdef MISSING_UNSETENV_3
+# include "setenv.c"
+#endif
+
static uschar *
to_tz(uschar * tz)
{
uschar * old = US getenv("TZ");
- setenv("TZ", CS tz, 1);
+ (void) setenv("TZ", CCS tz, 1);
tzset();
return old;
}
restore_tz(uschar * tz)
{
if (tz)
- setenv("TZ", CS tz, 1);
+ (void) setenv("TZ", CCS tz, 1);
else
- unsetenv("TZ");
+ (void) unsetenv("TZ");
tzset();
}
*************************************************/
#ifdef USE_GNUTLS
-#include "tls-gnu.c"
-#include "tlscert-gnu.c"
+# include "tls-gnu.c"
+# include "tlscert-gnu.c"
-#define ssl_xfer_buffer (state_server.xfer_buffer)
-#define ssl_xfer_buffer_lwm (state_server.xfer_buffer_lwm)
-#define ssl_xfer_buffer_hwm (state_server.xfer_buffer_hwm)
-#define ssl_xfer_eof (state_server.xfer_eof)
-#define ssl_xfer_error (state_server.xfer_error)
+# define ssl_xfer_buffer (state_server.xfer_buffer)
+# define ssl_xfer_buffer_lwm (state_server.xfer_buffer_lwm)
+# define ssl_xfer_buffer_hwm (state_server.xfer_buffer_hwm)
+# define ssl_xfer_eof (state_server.xfer_eof)
+# define ssl_xfer_error (state_server.xfer_error)
#else
-#include "tls-openssl.c"
-#include "tlscert-openssl.c"
+# include "tls-openssl.c"
+# include "tlscert-openssl.c"
#endif
Arguments:
dn Distinguished Name string
- mod string containing optional list-sep and
+ mod list containing optional output list-sep and
field selector match, comma-separated
Return:
allocated string with list of matching fields,
*/
uschar *
-tls_field_from_dn(uschar * dn, uschar * mod)
+tls_field_from_dn(uschar * dn, const uschar * mod)
{
int insep = ',';
uschar outsep = '\n';
if (ele[0] != '>')
match = ele; /* field tag to match */
else if (ele[1])
- outsep = ele[1]; /* nondefault separator */
+ outsep = ele[1]; /* nondefault output separator */
dn_to_list(dn);
insep = ',';
-len = Ustrlen(match);
-while ((ele = string_nextinlist(&dn, &insep, NULL, 0)))
- if (Ustrncmp(ele, match, len) == 0 && ele[len] == '=')
+len = match ? Ustrlen(match) : -1;
+while ((ele = string_nextinlist(CUSS &dn, &insep, NULL, 0)))
+ if ( !match
+ || Ustrncmp(ele, match, len) == 0 && ele[len] == '='
+ )
list = string_append_listele(list, outsep, ele+len+1);
return list;
}
*/
BOOL
-tls_is_name_for_cert(uschar * namelist, void * cert)
+tls_is_name_for_cert(const uschar * namelist, void * cert)
{
uschar * altnames = tls_cert_subject_altname(cert, US"dns");
uschar * subjdn;
int alt_sep = '\n';
while ((cmpname = string_nextinlist(&namelist, &cmp_sep, NULL, 0)))
{
- uschar * an = altnames;
+ const uschar * an = altnames;
while ((certname = string_nextinlist(&an, &alt_sep, NULL, 0)))
if (is_name_match(cmpname, certname))
return TRUE;
dn_to_list(subjdn);
while ((cmpname = string_nextinlist(&namelist, &cmp_sep, NULL, 0)))
{
- uschar * sn = subjdn;
+ const uschar * sn = subjdn;
while ((certname = string_nextinlist(&sn, &sn_sep, NULL, 0)))
if ( *certname++ == 'C'
&& *certname++ == 'N'
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) Jeremy Harris 2014 */
+/* Copyright (c) Jeremy Harris 2014 - 2015 */
/* This file provides TLS/SSL support for Exim using the GnuTLS library,
one of the available supported implementations. This file is #included into
size_t sz = buflen;
void * reset_point = store_get(0);
int fail;
-uschar * cp;
+const uschar * cp;
if ((fail = gnutls_x509_crt_export((gnutls_x509_crt_t)cert,
GNUTLS_X509_FMT_PEM, buf, &sz)))
{
void * reset_point = store_get(0);
gnutls_datum_t datum;
-gnutls_x509_crt_t crt;
+gnutls_x509_crt_t crt = *(gnutls_x509_crt_t *)cert;
int fail = 0;
-gnutls_global_init();
+if (crt)
+ gnutls_x509_crt_deinit(crt);
+else
+ gnutls_global_init();
+
gnutls_x509_crt_init(&crt);
datum.data = string_unprinting(US buf);
}
void
-tls_free_cert(void * cert)
+tls_free_cert(void ** cert)
{
-gnutls_x509_crt_deinit((gnutls_x509_crt_t) cert);
-gnutls_global_deinit();
+gnutls_x509_crt_t crt = *(gnutls_x509_crt_t *)cert;
+if (crt)
+ {
+ gnutls_x509_crt_deinit(crt);
+ gnutls_global_deinit();
+ *cert = NULL;
+ }
}
/*****************************************************
uschar *
tls_cert_signature(void * cert, uschar * mod)
{
-uschar * cp1;
+uschar * cp1 = NULL;
uschar * cp2;
uschar * cp3;
size_t len = 0;
switch (ret)
{
case GNUTLS_SAN_DNSNAME: tag = US"DNS"; break;
- case GNUTLS_SAN_URI: tag = US"URI"; break;
+ case GNUTLS_SAN_URI: tag = US"URI"; break;
case GNUTLS_SAN_RFC822NAME: tag = US"MAIL"; break;
default: continue; /* ignore unrecognised types */
}
- list = string_append_listele(list, sep,
+ list = string_append_listele(list, sep,
match == -1 ? string_sprintf("%s=%s", tag, ele) : ele);
}
/*NOTREACHED*/
#else
-expand_string_message =
+expand_string_message =
string_sprintf("%s: OCSP support with GnuTLS requires version 3.0.0\n",
__FUNCTION__);
return NULL;
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) Jeremy Harris 2014 */
+/* Copyright (c) Jeremy Harris 2014 - 2015 */
/* This module provides TLS (aka SSL) support for Exim using the OpenSSL
library. It is #included into the tls.c file when that library is used.
void * reset_point = store_get(0);
const uschar * cp = string_unprinting(US buf);
BIO * bp;
-X509 * x;
+X509 * x = *(X509 **)cert;
int fail = 0;
+if (x) X509_free(x);
+
bp = BIO_new_mem_buf(US cp, -1);
if (!(x = PEM_read_bio_X509(bp, NULL, 0, NULL)))
{
}
void
-tls_free_cert(void * cert)
+tls_free_cert(void ** cert)
{
-X509_free((X509 *)cert);
+X509 * x = *(X509 **)cert;
+if (x)
+ {
+ X509_free(x);
+ *cert = NULL;
+ }
}
{
struct tm tm;
struct tm * tm_p = &tm;
- BOOL mod_tz;
+ BOOL mod_tz = TRUE;
uschar * tz = to_tz(US"GMT0"); /* need to call strptime with baseline TZ */
/* Parse OpenSSL ASN1_TIME_print output. A shame there seems to
}
}
- if (mod_tz);
+ if (mod_tz)
restore_tz(tz);
}
BIO_free(bp);
if (!bp) return badalloc();
if (X509_print_ex(bp, (X509 *)cert, 0,
- X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION | X509_FLAG_NO_SERIAL |
- X509_FLAG_NO_SIGNAME | X509_FLAG_NO_ISSUER | X509_FLAG_NO_VALIDITY |
- X509_FLAG_NO_SUBJECT | X509_FLAG_NO_PUBKEY | X509_FLAG_NO_EXTENSIONS |
+ X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION | X509_FLAG_NO_SERIAL |
+ X509_FLAG_NO_SIGNAME | X509_FLAG_NO_ISSUER | X509_FLAG_NO_VALIDITY |
+ X509_FLAG_NO_SUBJECT | X509_FLAG_NO_PUBKEY | X509_FLAG_NO_EXTENSIONS |
/* X509_FLAG_NO_SIGDUMP is the missing one */
X509_FLAG_NO_AUX) == 1)
{
if (!bp) return badalloc();
if (X509_print_ex(bp, (X509 *)cert, 0,
- X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION | X509_FLAG_NO_SERIAL |
+ X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION | X509_FLAG_NO_SERIAL |
/* X509_FLAG_NO_SIGNAME is the missing one */
- X509_FLAG_NO_ISSUER | X509_FLAG_NO_VALIDITY |
- X509_FLAG_NO_SUBJECT | X509_FLAG_NO_PUBKEY | X509_FLAG_NO_EXTENSIONS |
+ X509_FLAG_NO_ISSUER | X509_FLAG_NO_VALIDITY |
+ X509_FLAG_NO_SUBJECT | X509_FLAG_NO_PUBKEY | X509_FLAG_NO_EXTENSIONS |
X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_AUX) == 1)
{
long len = BIO_get_mem_data(bp, &cp);
uschar * list = NULL;
STACK_OF(GENERAL_NAME) * san = (STACK_OF(GENERAL_NAME) *)
X509_get_ext_d2i((X509 *)cert, NID_subject_alt_name, NULL, NULL);
-uschar sep = '\n';
+uschar osep = '\n';
uschar * tag = US"";
uschar * ele;
int match = -1;
if (!san) return NULL;
-while (mod)
+while (mod && *mod)
{
- if (*mod == '>' && *++mod) sep = *mod++;
- else if (Ustrcmp(mod, "dns")==0) { match = GEN_DNS; mod += 3; }
- else if (Ustrcmp(mod, "uri")==0) { match = GEN_URI; mod += 3; }
- else if (Ustrcmp(mod, "mail")==0) { match = GEN_EMAIL; mod += 4; }
- else continue;
+ if (*mod == '>' && *++mod) osep = *mod++;
+ else if (Ustrncmp(mod,"dns",3)==0) { match = GEN_DNS; mod += 3; }
+ else if (Ustrncmp(mod,"uri",3)==0) { match = GEN_URI; mod += 3; }
+ else if (Ustrncmp(mod,"mail",4)==0) { match = GEN_EMAIL; mod += 4; }
+ else mod++;
- if (*mod++ != ',')
- break;
+ if (*mod == ',') mod++;
}
while (sk_GENERAL_NAME_num(san) > 0)
ele = string_copyn(ele, len);
if (Ustrlen(ele) == len) /* ignore any with embedded nul */
- list = string_append_listele(list, sep,
+ list = string_append_listele(list, osep,
match == -1 ? string_sprintf("%s=%s", tag, ele) : ele);
}
ACCESS_DESCRIPTION * ad = sk_ACCESS_DESCRIPTION_value(ads, i);
if (ad && OBJ_obj2nid(ad->method) == NID_ad_OCSP)
- list = string_append_listele(list, sep,
- ASN1_STRING_data(ad->location->d.ia5));
+ {
+ uschar * ele = ASN1_STRING_data(ad->location->d.ia5);
+ int len = ASN1_STRING_length(ad->location->d.ia5);
+ list = string_append_listele_n(list, sep, ele, len);
+ }
}
+sk_ACCESS_DESCRIPTION_free(ads);
return list;
}
if ( (np = sk_GENERAL_NAME_value(names, j))
&& np->type == GEN_URI
)
- list = string_append_listele(list, sep,
- ASN1_STRING_data(np->d.uniformResourceIdentifier));
+ {
+ uschar * ele = ASN1_STRING_data(np->d.uniformResourceIdentifier);
+ int len = ASN1_STRING_length(np->d.uniformResourceIdentifier);
+ list = string_append_listele_n(list, sep, ele, len);
+ }
}
+sk_DIST_POINT_free(dps);
return list;
}
return(cp);
}
-uschar *
+uschar *
tls_cert_fprt_md5(void * cert)
{
return fingerprint((X509 *)cert, EVP_md5());
}
-uschar *
+uschar *
tls_cert_fprt_sha1(void * cert)
{
return fingerprint((X509 *)cert, EVP_sha1());
}
-uschar *
+uschar *
tls_cert_fprt_sha256(void * cert)
{
return fingerprint((X509 *)cert, EVP_sha256());
struct timeval tv;
gettimeofday(&tv, NULL);
/* Unix epoch/usec format */
- (void) sprintf(CS timebuf, "%ld%06ld", tv.tv_sec, (long) tv.tv_usec );
+ (void) sprintf(CS timebuf, TIME_T_FMT "%06ld", tv.tv_sec, (long) tv.tv_usec );
return timebuf;
}
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* General functions concerned with transportation, and generic options for all
(void *)offsetof(transport_instance, driver_name) },
{ "envelope_to_add", opt_bool|opt_public,
(void *)(offsetof(transport_instance, envelope_to_add)) },
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
{ "event_action", opt_stringptr | opt_public,
(void *)offsetof(transport_instance, event_action) },
#endif
(void *)offsetof(transport_instance, home_dir) },
{ "initgroups", opt_bool|opt_public,
(void *)offsetof(transport_instance, initgroups) },
+ { "max_parallel", opt_stringptr|opt_public,
+ (void *)offsetof(transport_instance, max_parallel) },
{ "message_size_limit", opt_stringptr|opt_public,
(void *)offsetof(transport_instance, message_size_limit) },
{ "rcpt_include_affixes", opt_bool|opt_public,
were removed (e.g. Bcc). If remove_headers is not null, skip any headers that
match any entries therein. It is a colon-sep list; expand the items
separately and squash any empty ones.
-Then check addr->p.remove_headers too, provided that addr is not NULL. */
+Then check addr->prop.remove_headers too, provided that addr is not NULL. */
for (h = header_list; h != NULL; h = h->next) if (h->type != htype_old)
{
int i;
- uschar *list = remove_headers;
+ const uschar *list = remove_headers;
BOOL include_header = TRUE;
- for (i = 0; i < 2; i++) /* For remove_headers && addr->p.remove_headers */
+ for (i = 0; i < 2; i++) /* For remove_headers && addr->prop.remove_headers */
{
if (list)
{
}
if (s != NULL) { include_header = FALSE; break; }
}
- if (addr != NULL) list = addr->p.remove_headers;
+ if (addr != NULL) list = addr->prop.remove_headers;
}
/* If this header is to be output, try to rewrite it if there are rewriting
if (addr)
{
int i;
- header_line *hprev = addr->p.extra_headers;
+ header_line *hprev = addr->prop.extra_headers;
header_line *hnext;
for (i = 0; i < 2; i++)
{
int sep = '\n';
uschar * s;
- while ((s = string_nextinlist(&add_headers, &sep, NULL, 0)))
+ while ((s = string_nextinlist(CUSS &add_headers, &sep, NULL, 0)))
if (!(s = expand_string(s)))
{
if (!expand_string_forcedfail)
/* Then the message's headers. Don't write any that are flagged as "old";
that means they were rewritten, or are a record of envelope rewriting, or
were removed (e.g. Bcc). If remove_headers is not null, skip any headers that
- match any entries therein. Then check addr->p.remove_headers too, provided that
+ match any entries therein. Then check addr->prop.remove_headers too, provided that
addr is not NULL. */
if (!transport_headers_send(addr, fd, add_headers, remove_headers, &write_chunk,
use_crlf, rewrite_rules, rewrite_existflags))
uschar *dkim_strict_result = expand_string(dkim_strict);
if (dkim_strict_result)
if ( (strcmpic(dkim_strict,US"1") == 0) ||
- (strcmpic(dkim_strict,US"true") == 0) )
+ (strcmpic(dkim_strict,US"true") == 0) )
{
/* Set errno to something halfway meaningful */
save_errno = EACCES;
/* If there is no filter command set up, call the internal function that does
the actual work, passing it the incoming fd, and return its result. */
-if (transport_filter_argv == NULL)
+if ( !transport_filter_argv
+ || !*transport_filter_argv
+ || !**transport_filter_argv
+ )
return internal_transport_write_message(addr, fd, options, size_limit,
add_headers, remove_headers, check_string, escape_string,
rewrite_rules, rewrite_existflags);
write_pid = (pid_t)(-1);
(void)fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
-filter_pid = child_open(transport_filter_argv, NULL, 077, &fd_write, &fd_read,
- FALSE);
+filter_pid = child_open(USS transport_filter_argv, NULL, 077,
+ &fd_write, &fd_read, FALSE);
(void)fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) & ~FD_CLOEXEC);
if (filter_pid < 0) goto TIDY_UP; /* errno set */
transport_update_waiting(host_item *hostlist, uschar *tpname)
{
uschar buffer[256];
-uschar *prevname = US"";
+const uschar *prevname = US"";
host_item *host;
open_db dbblock;
open_db *dbm_file;
as set by the caller transport
new_message_id set to the message id of a waiting message
more set TRUE if there are yet more messages waiting
+ oicf_func function to call to validate if it is ok to send
+ to this message_id from the current instance.
+ oicf_data opaque data for oicf_func
Returns: TRUE if new_message_id set; FALSE otherwise
*/
+typedef struct msgq_s
+{
+ uschar message_id [MESSAGE_ID_LENGTH + 1];
+ BOOL bKeep;
+} msgq_t;
+
BOOL
-transport_check_waiting(uschar *transport_name, uschar *hostname,
- int local_message_max, uschar *new_message_id, BOOL *more)
+transport_check_waiting(const uschar *transport_name, const uschar *hostname,
+ int local_message_max, uschar *new_message_id, BOOL *more, oicf oicf_func, void *oicf_data)
{
dbdata_wait *host_record;
-int host_length, path_len;
+int host_length;
open_db dbblock;
open_db *dbm_file;
uschar buffer[256];
+msgq_t *msgq = NULL;
+int msgq_count = 0;
+int msgq_actual = 0;
+int i;
+BOOL bFound = FALSE;
+uschar spool_dir [PATH_MAX];
+uschar spool_file [PATH_MAX];
+struct stat statbuf;
+BOOL bContinuation = FALSE;
+
*more = FALSE;
DEBUG(D_transport)
emptied, delete it and continue with any continuation records that may exist.
*/
-host_length = host_record->count * MESSAGE_ID_LENGTH;
+/* For Bug 1141, I refactored this major portion of the routine, it is risky
+but the 1 off will remain without it. This code now allows me to SKIP over
+a message I do not want to send out on this run. */
-/* Loop to handle continuation host records in the database */
+sprintf(CS spool_dir, "%s/input/", spool_directory);
-for (;;)
+host_length = host_record->count * MESSAGE_ID_LENGTH;
+
+while (1)
{
- BOOL found = FALSE;
+ /* create an array to read entire message queue into memory for processing */
- sprintf(CS buffer, "%s/input/", spool_directory);
- path_len = Ustrlen(buffer);
+ msgq = (msgq_t*) malloc(sizeof(msgq_t) * host_record->count);
+ msgq_count = host_record->count;
+ msgq_actual = msgq_count;
- for (host_length -= MESSAGE_ID_LENGTH; host_length >= 0;
- host_length -= MESSAGE_ID_LENGTH)
+ for (i = 0; i < host_record->count; ++i)
{
- struct stat statbuf;
- Ustrncpy(new_message_id, host_record->text + host_length,
+ msgq[i].bKeep = TRUE;
+
+ Ustrncpy(msgq[i].message_id, host_record->text + (i * MESSAGE_ID_LENGTH),
MESSAGE_ID_LENGTH);
- new_message_id[MESSAGE_ID_LENGTH] = 0;
+ msgq[i].message_id[MESSAGE_ID_LENGTH] = 0;
+ }
+
+ /* first thing remove current message id if it exists */
+
+ for (i = 0; i < msgq_count; ++i)
+ if (Ustrcmp(msgq[i].message_id, message_id) == 0)
+ {
+ msgq[i].bKeep = FALSE;
+ break;
+ }
+ /* now find the next acceptable message_id */
+
+ bFound = FALSE;
+
+ for (i = msgq_count - 1; i >= 0; --i) if (msgq[i].bKeep)
+ {
if (split_spool_directory)
- sprintf(CS(buffer + path_len), "%c/%s-D", new_message_id[5], new_message_id);
+ sprintf(CS spool_file, "%s%c/%s-D",
+ spool_dir, msgq[i].message_id[5], msgq[i].message_id);
else
- sprintf(CS(buffer + path_len), "%s-D", new_message_id);
-
- /* The listed message may be the one we are currently processing. If
- so, we want to remove it from the list without doing anything else.
- If not, do a stat to see if it is an existing message. If it is, break
- the loop to handle it. No need to bother about locks; as this is all
- "hint" processing, it won't matter if it doesn't exist by the time exim
- actually tries to deliver it. */
+ sprintf(CS spool_file, "%s%s-D", spool_dir, msgq[i].message_id);
- if (Ustrcmp(new_message_id, message_id) != 0 &&
- Ustat(buffer, &statbuf) == 0)
+ if (Ustat(spool_file, &statbuf) != 0)
+ msgq[i].bKeep = FALSE;
+ else if (!oicf_func || oicf_func(msgq[i].message_id, oicf_data))
{
- found = TRUE;
+ Ustrcpy(new_message_id, msgq[i].message_id);
+ msgq[i].bKeep = FALSE;
+ bFound = TRUE;
break;
}
}
- /* If we have removed all the message ids from the record delete the record.
- If there is a continuation record, fetch it and remove it from the file,
- as it will be rewritten as the main record. Repeat in the case of an
- empty continuation. */
+ /* re-count */
+ for (msgq_actual = 0, i = 0; i < msgq_count; ++i)
+ if (msgq[i].bKeep)
+ msgq_actual++;
+
+ /* reassemble the host record, based on removed message ids, from in
+ * memory queue.
+ */
+
+ if (msgq_actual <= 0)
+ {
+ host_length = 0;
+ host_record->count = 0;
+ }
+ else
+ {
+ host_length = msgq_actual * MESSAGE_ID_LENGTH;
+ host_record->count = msgq_actual;
+
+ if (msgq_actual < msgq_count)
+ {
+ int new_count;
+ for (new_count = 0, i = 0; i < msgq_count; ++i)
+ if (msgq[i].bKeep)
+ Ustrncpy(&host_record->text[new_count++ * MESSAGE_ID_LENGTH],
+ msgq[i].message_id, MESSAGE_ID_LENGTH);
+
+ host_record->text[new_count * MESSAGE_ID_LENGTH] = 0;
+ }
+ }
+
+/* Jeremy: check for a continuation record, this code I do not know how to
+test but the code should work */
+
+ bContinuation = FALSE;
while (host_length <= 0)
{
int i;
- dbdata_wait *newr = NULL;
+ dbdata_wait * newr = NULL;
/* Search for a continuation */
- for (i = host_record->sequence - 1; i >= 0 && newr == NULL; i--)
+ for (i = host_record->sequence - 1; i >= 0 && !newr; i--)
{
sprintf(CS buffer, "%.200s:%d", hostname, i);
newr = dbfn_read(dbm_file, buffer);
/* If no continuation, delete the current and break the loop */
- if (newr == NULL)
+ if (!newr)
{
dbfn_delete(dbm_file, hostname);
break;
dbfn_delete(dbm_file, buffer);
host_record = newr;
host_length = host_record->count * MESSAGE_ID_LENGTH;
- }
- /* If we found an existing message, break the continuation loop. */
+ bContinuation = TRUE;
+ }
- if (found) break;
+ if (bFound)
+ break;
/* If host_length <= 0 we have emptied a record and not found a good message,
and there are no continuation records. Otherwise there is a continuation
DEBUG(D_transport) debug_printf("waiting messages already delivered\n");
return FALSE;
}
+
+ /* we were not able to find an acceptable message, nor was there a
+ * continuation record. So bug out, outer logic will clean this up.
+ */
+
+ if (!bContinuation)
+ {
+ Ustrcpy (new_message_id, message_id);
+ dbfn_close(dbm_file);
+ return FALSE;
+ }
+ } /* we need to process a continuation record */
+
+/* clean up in memory queue */
+if (msgq)
+ {
+ free (msgq);
+ msgq = NULL;
+ msgq_count = 0;
+ msgq_actual = 0;
}
/* Control gets here when an existing message has been encountered; its
if (host_length > 0)
{
+ uschar msg [MESSAGE_ID_LENGTH + 1];
+ int i;
+
host_record->count = host_length/MESSAGE_ID_LENGTH;
+
+ /* rebuild the host_record->text */
+
+ for (i = 0; i < host_record->count; ++i)
+ {
+ Ustrncpy(msg, host_record->text + (i*MESSAGE_ID_LENGTH), MESSAGE_ID_LENGTH);
+ msg[MESSAGE_ID_LENGTH] = 0;
+ }
+
dbfn_write(dbm_file, hostname, host_record, (int)sizeof(dbdata_wait) + host_length);
*more = TRUE;
}
return TRUE;
}
-
-
/*************************************************
* Deliver waiting message down same socket *
*************************************************/
*/
BOOL
-transport_pass_socket(uschar *transport_name, uschar *hostname,
- uschar *hostaddress, uschar *id, int socket_fd)
+transport_pass_socket(const uschar *transport_name, const uschar *hostname,
+ const uschar *hostaddress, uschar *id, int socket_fd)
{
pid_t pid;
int status;
if ((pid = fork()) == 0)
{
int i = 16;
- uschar **argv;
+ const uschar **argv;
/* Disconnect entirely from the parent process. If we are running in the
test harness, wait for a bit to allow the previous process time to finish,
/* Set up the calling arguments; use the standard function for the basics,
but we have a number of extras that may be added. */
- argv = child_exec_exim(CEE_RETURN_ARGV, TRUE, &i, FALSE, 0);
+ argv = CUSS child_exec_exim(CEE_RETURN_ARGV, TRUE, &i, FALSE, 0);
/* Call with the dsn flag */
if (smtp_use_dsn) argv[i++] = US"-MCD";
}
argv[i++] = US"-MC";
- argv[i++] = transport_name;
- argv[i++] = hostname;
- argv[i++] = hostaddress;
+ argv[i++] = US transport_name;
+ argv[i++] = US hostname;
+ argv[i++] = US hostaddress;
argv[i++] = string_sprintf("%d", continue_sequence + 1);
argv[i++] = id;
argv[i++] = NULL;
Arguments:
argvptr pointer to anchor for argv vector
- cmd points to the command string
+ cmd points to the command string (modified IN PLACE)
expand_arguments true if expansion is to occur
expand_failed error value to set if expansion fails; not relevant if
addr == NULL
*/
BOOL
-transport_set_up_command(uschar ***argvptr, uschar *cmd, BOOL expand_arguments,
- int expand_failed, address_item *addr, uschar *etext, uschar **errptr)
+transport_set_up_command(const uschar ***argvptr, uschar *cmd,
+ BOOL expand_arguments, int expand_failed, address_item *addr,
+ uschar *etext, uschar **errptr)
{
address_item *ad;
-uschar **argv;
+const uschar **argv;
uschar *s, *ss;
int address_count = 0;
int argcount = 0;
if (*s != 0) s++;
*ss++ = 0;
}
- else argv[argcount++] = string_dequote(&s);
+ else argv[argcount++] = string_copy(string_dequote(CUSS &s));
while (isspace(*s)) s++;
}
if (*s != 0) s++;
*ss++ = 0;
}
- else address_pipe_argv[address_pipe_argcount++] = string_dequote(&s);
+ else address_pipe_argv[address_pipe_argcount++] =
+ string_copy(string_dequote(CUSS &s));
while (isspace(*s)) s++; /* strip space after arg */
}
else
{
- uschar *expanded_arg;
+ const uschar *expanded_arg;
enable_dollar_recipients = allow_dollar_recipients;
- expanded_arg = expand_string(argv[i]);
+ expanded_arg = expand_cstring(argv[i]);
enable_dollar_recipients = FALSE;
if (expanded_arg == NULL)
# calling it transports.a. This is called from the main make file, after cd'ing
# to the transports subdirectory.
-OBJ = appendfile.o autoreply.o lmtp.o pipe.o smtp.o tf_maildir.o
+OBJ = appendfile.o autoreply.o lmtp.o pipe.o smtp.o smtp_socks.o tf_maildir.o
transports.a: $(OBJ)
@$(RM_COMMAND) -f transports.a
lmtp.o: $(HDRS) lmtp.c lmtp.h
pipe.o: $(HDRS) pipe.c pipe.h
smtp.o: $(HDRS) smtp.c smtp.h
+smtp_socks.o: $(HDRS) smtp_socks.c smtp.h
tf_maildir.o: $(HDRS) tf_maildir.c tf_maildir.h appendfile.h
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
NULL, /* quota_warn_threshold */
NULL, /* mailbox_size_string */
NULL, /* mailbox_filecount_string */
- NULL, /* expand_maildir_use_size_file */
+ NULL, /* expand_maildir_use_size_file */
US"^(?:cur|new|\\..*)$", /* maildir_dir_regex */
NULL, /* maildir_tag */
NULL, /* maildirfolder_create_regex */
gid = gid;
if (ob->expand_maildir_use_size_file)
- ob->maildir_use_size_file = expand_check_condition(ob->expand_maildir_use_size_file,
+ ob->maildir_use_size_file = expand_check_condition(ob->expand_maildir_use_size_file,
US"`maildir_use_size_file` in transport", tblock->name);
/* Loop for quota, quota_filecount, quota_warn_threshold, mailbox_size,
transport_instance *
check_file_format(int cfd, transport_instance *tblock, address_item *addr)
{
-uschar *format =
+const uschar *format =
((appendfile_transport_options_block *)(tblock->options_block))->file_format;
uschar data[256];
int len = read(cfd, data, sizeof(data));
uschar *basename;
(void)gettimeofday(&msg_tv, NULL);
- basename = string_sprintf("%lu.H%luP%lu.%s", msg_tv.tv_sec,
- msg_tv.tv_usec, getpid(), primary_hostname);
+ basename = string_sprintf(TIME_T_FMT ".H%luP%lu.%s",
+ msg_tv.tv_sec, msg_tv.tv_usec, getpid(), primary_hostname);
filename = dataname = string_sprintf("tmp/%s", basename);
newname = string_sprintf("new/%s", basename);
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
if (type != cke_text) for (t = ss; *t != 0; t++)
{
int c = *t;
+ const uschar * sp;
if (mac_isprint(c)) continue;
if (type == cke_hdr && c == '\n' && (t[1] == ' ' || t[1] == '\t')) continue;
- s = string_printing(s);
+ sp = string_printing(s);
addr->transport_return = FAIL;
addr->message = string_sprintf("Expansion of \"%s\" in %s transport "
- "contains non-printing character %d", s, name, c);
+ "contains non-printing character %d", sp, name, c);
return NULL;
}
*/
static void
-check_never_mail(uschar **listptr, uschar *never_mail)
+check_never_mail(uschar **listptr, const uschar *never_mail)
{
uschar *s = *listptr;
if (ob->never_mail != NULL)
{
- uschar *never_mail = expand_string(ob->never_mail);
+ const uschar *never_mail = expand_string(ob->never_mail);
if (never_mail == NULL)
{
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
if (buffer[0] != 0)
{
- uschar *s = string_printing(buffer);
+ const uschar *s = string_printing(buffer);
*message = string_sprintf("LMTP error after %s: %s", big_buffer, s);
*yield = buffer[0];
return TRUE;
address_item *addr;
uschar *igquotstr = US"";
uschar *sockname = NULL;
-uschar **argv;
+const uschar **argv;
uschar buffer[256];
DEBUG(D_transport) debug_printf("%s transport entered\n", tblock->name);
not both. When a command is specified, call the common function for creating an
argument list and expanding the items. */
-if (ob->cmd != NULL)
+if (ob->cmd)
{
DEBUG(D_transport) debug_printf("using command %s\n", ob->cmd);
sprintf(CS buffer, "%.50s transport", tblock->name);
if (!transport_set_up_command(&argv, ob->cmd, TRUE, PANIC, addrlist, buffer,
NULL))
return FALSE;
+
+ /* If the -N option is set, can't do any more. Presume all has gone well. */
+ if (dont_deliver)
+ goto MINUS_N;
+
+/* As this is a local transport, we are already running with the required
+uid/gid and current directory. Request that the new process be a process group
+leader, so we can kill it and all its children on an error. */
+
+ if ((pid = child_open(USS argv, NULL, 0, &fd_in, &fd_out, TRUE)) < 0)
+ {
+ addrlist->message = string_sprintf(
+ "Failed to create child process for %s transport: %s", tblock->name,
+ strerror(errno));
+ return FALSE;
+ }
}
/* When a socket is specified, expand the string and create a socket. */
ob->skt, tblock->name, strerror(errno));
return FALSE;
}
- }
-/* If the -N option is set, can't do any more. Presume all has gone well. */
+ /* If the -N option is set, can't do any more. Presume all has gone well. */
+ if (dont_deliver)
+ goto MINUS_N;
-if (dont_deliver)
- {
- DEBUG(D_transport)
- debug_printf("*** delivery by %s transport bypassed by -N option",
- tblock->name);
- addrlist->transport_return = OK;
- return FALSE;
- }
-
-/* As this is a local transport, we are already running with the required
-uid/gid and current directory. Request that the new process be a process group
-leader, so we can kill it and all its children on an error. */
-
-if (ob->cmd != NULL)
- {
- if ((pid = child_open(argv, NULL, 0, &fd_in, &fd_out, TRUE)) < 0)
- {
- addrlist->message = string_sprintf(
- "Failed to create child process for %s transport: %s", tblock->name,
- strerror(errno));
- return FALSE;
- }
- }
-
-/* For a socket, try to make the connection */
-
-else
- {
sockun.sun_family = AF_UNIX;
sprintf(sockun.sun_path, "%.*s", (int)(sizeof(sockun.sun_path)-1), sockname);
if(connect(fd_out, (struct sockaddr *)(&sockun), sizeof(sockun)) == -1)
}
}
+
/* Make the output we are going to read into a file. */
out = fdopen(fd_out, "rb");
if (lmtp_read_response(out, buffer, sizeof(buffer), '2', timeout))
{
addr->transport_return = OK;
- if ((log_extra_selector & LX_smtp_confirmation) != 0)
+ if (LOGGING(smtp_confirmation))
{
- uschar *s = string_printing(buffer);
- addr->message = (s == buffer)? (uschar *)string_copy(s) : s;
+ const uschar *s = string_printing(buffer);
+ /* de-const safe here as string_printing known to have alloc'n'copied */
+ addr->message = (s == buffer)? (uschar *)string_copy(s) : US s;
}
}
/* If the response has failed badly, use it for all the remaining pending
debug_printf("%s transport yields %d\n", tblock->name, yield);
return yield;
+
+
+MINUS_N:
+ DEBUG(D_transport)
+ debug_printf("*** delivery by %s transport bypassed by -N option",
+ tblock->name);
+ addrlist->transport_return = OK;
+ return FALSE;
}
/* End of transport/lmtp.c */
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
*/
static BOOL
-set_up_direct_command(uschar ***argvptr, uschar *cmd, BOOL expand_arguments,
- int expand_fail, address_item *addr, uschar *tname,
+set_up_direct_command(const uschar ***argvptr, uschar *cmd,
+ BOOL expand_arguments, int expand_fail, address_item *addr, uschar *tname,
pipe_transport_options_block *ob)
{
BOOL permitted = FALSE;
-uschar **argv;
+const uschar **argv;
uschar buffer[64];
/* Set up "transport <name>" to be put in any error messages, and then
if (ob->allow_commands != NULL)
{
int sep = 0;
- uschar *s, *p;
+ const uschar *s;
+ uschar *p;
uschar buffer[256];
- s = expand_string(ob->allow_commands);
- if (s == NULL)
+ if (!(s = expand_string(ob->allow_commands)))
{
addr->transport_return = DEFER;
addr->message = string_sprintf("failed to expand string \"%s\" "
return FALSE;
}
- while ((p = string_nextinlist(&s, &sep, buffer, sizeof(buffer))) != NULL)
- {
+ while ((p = string_nextinlist(&s, &sep, buffer, sizeof(buffer))))
if (Ustrcmp(p, argv[0]) == 0) { permitted = TRUE; break; }
- }
}
/* If permitted is TRUE it means the command was found in the allowed list, and
{
int sep = 0;
uschar *p;
- uschar *listptr = ob->path;
+ const uschar *listptr = ob->path;
uschar buffer[1024];
while ((p = string_nextinlist(&listptr, &sep, buffer, sizeof(buffer))) != NULL)
*/
static BOOL
-set_up_shell_command(uschar ***argvptr, uschar *cmd, BOOL expand_arguments,
- int expand_fail, address_item *addr, uschar *tname)
+set_up_shell_command(const uschar ***argvptr, uschar *cmd,
+ BOOL expand_arguments, int expand_fail, address_item *addr, uschar *tname)
{
-uschar **argv;
+const uschar **argv;
*argvptr = argv = store_get((4)*sizeof(uschar *));
int timeout = ob->timeout;
BOOL written_ok = FALSE;
BOOL expand_arguments;
-uschar **argv;
+const uschar **argv;
uschar *envp[50];
-uschar *envlist = ob->environment;
+const uschar *envlist = ob->environment;
uschar *cmd, *ss;
uschar *eol = (ob->use_crlf)? US"\r\n" : US"\n";
/* Add any requested items */
-if (envlist != NULL)
+if (envlist)
{
- envlist = expand_string(envlist);
+ envlist = expand_cstring(envlist);
if (envlist == NULL)
{
addr->transport_return = DEFER;
uid/gid and current directory. Request that the new process be a process group
leader, so we can kill it and all its children on a timeout. */
-if ((pid = child_open(argv, envp, ob->umask, &fd_in, &fd_out, TRUE)) < 0)
+if ((pid = child_open(USS argv, envp, ob->umask, &fd_in, &fd_out, TRUE)) < 0)
{
addr->transport_return = DEFER;
addr->message = string_sprintf(
else
{
- uschar *s = ob->temp_errors;
+ const uschar *s = ob->temp_errors;
uschar *p;
uschar buffer[64];
int sep = 0;
addr->transport_return = FAIL;
- while ((p = string_nextinlist(&s,&sep,buffer,sizeof(buffer))) != NULL)
- {
+ while ((p = string_nextinlist(&s,&sep,buffer,sizeof(buffer))))
if (rc == Uatoi(p)) { addr->transport_return = DEFER; break; }
- }
}
/* Ensure the message contains the expanded command and arguments. This
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
#include "../exim.h"
{ "dns_search_parents", opt_bool,
(void *)offsetof(smtp_transport_options_block, dns_search_parents) },
{ "dnssec_request_domains", opt_stringptr,
- (void *)offsetof(smtp_transport_options_block, dnssec_request_domains) },
+ (void *)offsetof(smtp_transport_options_block, dnssec.request) },
{ "dnssec_require_domains", opt_stringptr,
- (void *)offsetof(smtp_transport_options_block, dnssec_require_domains) },
+ (void *)offsetof(smtp_transport_options_block, dnssec.require) },
{ "dscp", opt_stringptr,
(void *)offsetof(smtp_transport_options_block, dscp) },
{ "fallback_hosts", opt_stringptr,
(void *)offsetof(smtp_transport_options_block, serialize_hosts) },
{ "size_addition", opt_int,
(void *)offsetof(smtp_transport_options_block, size_addition) }
+#ifdef SUPPORT_SOCKS
+ ,{ "socks_proxy", opt_stringptr,
+ (void *)offsetof(smtp_transport_options_block, socks_proxy) }
+#endif
#ifdef SUPPORT_TLS
,{ "tls_certificate", opt_stringptr,
(void *)offsetof(smtp_transport_options_block, tls_certificate) },
#endif
NULL, /* hosts_require_tls */
NULL, /* hosts_avoid_tls */
- US"*", /* hosts_verify_avoid_tls */
+ NULL, /* hosts_verify_avoid_tls */
NULL, /* hosts_avoid_pipelining */
NULL, /* hosts_avoid_esmtp */
NULL, /* hosts_nopass_tls */
FALSE, /* gethostbyname */
TRUE, /* dns_qualify_single */
FALSE, /* dns_search_parents */
- NULL, /* dnssec_request_domains */
- NULL, /* dnssec_require_domains */
+ { NULL, NULL }, /* dnssec_domains {request,require} */
TRUE, /* delay_after_cutoff */
FALSE, /* hosts_override */
FALSE, /* hosts_randomize */
FALSE, /* lmtp_ignore_quota */
NULL, /* expand_retry_include_ip_address */
TRUE /* retry_include_ip_address */
+#ifdef SUPPORT_SOCKS
+ ,NULL /* socks_proxy */
+#endif
#ifdef SUPPORT_TLS
,NULL, /* tls_certificate */
NULL, /* tls_crl */
rc to put in each address's transport_return field
pass_message if TRUE, set the "pass message" flag in the address
host if set, mark addrs as having used this host
+ smtp_greeting from peer
+ helo_response from peer
If errno_value has the special value ERRNO_CONNECTTIMEOUT, ETIMEDOUT is put in
the errno field, and RTEF_CTOUT is ORed into the more_errno field, to indicate
static void
set_errno(address_item *addrlist, int errno_value, uschar *msg, int rc,
- BOOL pass_message, host_item * host)
+ BOOL pass_message, host_item * host
+#ifdef EXPERIMENTAL_DSN_INFO
+ , const uschar * smtp_greeting, const uschar * helo_response
+#endif
+ )
{
address_item *addr;
int orvalue = 0;
errno_value = ETIMEDOUT;
orvalue = RTEF_CTOUT;
}
-for (addr = addrlist; addr != NULL; addr = addr->next)
+for (addr = addrlist; addr; addr = addr->next)
if (addr->transport_return >= PENDING)
{
addr->basic_errno = errno_value;
}
addr->transport_return = rc;
if (host)
+ {
addr->host_used = host;
+#ifdef EXPERIMENTAL_DSN_INFO
+ if (smtp_greeting)
+ {uschar * s = Ustrchr(smtp_greeting, '\n'); if (s) *s = '\0';}
+ addr->smtp_greeting = smtp_greeting;
+
+ if (helo_response)
+ {uschar * s = Ustrchr(helo_response, '\n'); if (s) *s = '\0';}
+ addr->helo_response = helo_response;
+#endif
+ }
}
}
+static void
+set_errno_nohost(address_item *addrlist, int errno_value, uschar *msg, int rc,
+ BOOL pass_message)
+{
+set_errno(addrlist, errno_value, msg, rc, pass_message, NULL
+#ifdef EXPERIMENTAL_DSN_INFO
+ , NULL, NULL
+#endif
+ );
+}
/*************************************************
if (*errno_value == ERRNO_SMTPFORMAT)
{
- uschar *malfresp = string_printing(buffer);
+ const uschar *malfresp = string_printing(buffer);
while (isspace(*malfresp)) malfresp++;
*message = *malfresp == 0
? string_sprintf("Malformed SMTP reply (an empty line) "
return FALSE;
}
+#ifdef SUPPORT_I18N
+/* Handle lack of advertised SMTPUTF8, for international message */
+if (*errno_value == ERRNO_UTF8_FWD)
+ {
+ *message = US string_sprintf("utf8 support required but not offered for forwarding");
+ DEBUG(D_deliver|D_transport) debug_printf("%s\n", *message);
+ return TRUE;
+ }
+#endif
+
/* Handle error responses from the remote mailer. */
if (buffer[0] != 0)
{
- uschar *s = string_printing(buffer);
+ const uschar *s = string_printing(buffer);
*message = US string_sprintf("SMTP error from remote mail server after %s%s: "
"%s", pl, smtp_command, s);
*pass_message = TRUE;
{
uschar * message = string_sprintf("H=%s [%s]", host->name, host->address);
+if (LOGGING(outgoing_port))
+ message = string_sprintf("%s:%d", message,
+ host->port == PORT_NONE ? 25 : host->port);
if (addr->message)
{
message = string_sprintf("%s: %s", message, addr->message);
}
else
{
- if (log_extra_selector & LX_outgoing_port)
- message = string_sprintf("%s:%d", message,
- host->port == PORT_NONE ? 25 : host->port);
log_write(0, LOG_MAIN, "%s %s", message, strerror(addr->basic_errno));
deliver_msglog("%s %s %s\n", tod_stamp(tod_log), message,
strerror(addr->basic_errno));
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
/*************************************************
* Post-defer action *
*************************************************/
deferred_event_raise(address_item *addr, host_item *host)
{
uschar * action = addr->transport->event_action;
-uschar * save_domain;
+const uschar * save_domain;
uschar * save_local;
if (!action)
}
#endif
-
-
/*************************************************
* Synchronize SMTP responses *
*************************************************/
{
uschar *message = string_sprintf("SMTP timeout after RCPT TO:<%s>",
transport_rcpt_address(addr, include_affixes));
- set_errno(addrlist, ETIMEDOUT, message, DEFER, FALSE, NULL);
+ set_errno_nohost(addrlist, ETIMEDOUT, message, DEFER, FALSE);
retry_add_item(addr, addr->address_retry_key, 0);
update_waiting = FALSE;
return -1;
addr->basic_errno = ERRNO_RCPT4XX;
addr->more_errno |= ((buffer[1] - '0')*10 + buffer[2] - '0') << 8;
+#ifndef DISABLE_EVENT
+ event_defer_errno = addr->more_errno;
+ msg_event_raise(US"msg:rcpt:host:defer", addr);
+#endif
+
/* Log temporary errors if there are more hosts to be tried.
If not, log this last one in the == line. */
if (host->next)
log_write(0, LOG_MAIN, "H=%s [%s]: %s", host->name, host->address, addr->message);
+#ifndef DISABLE_EVENT
+ else
+ msg_event_raise(US"msg:rcpt:defer", addr);
+#endif
+
/* Do not put this message on the list of those waiting for specific
hosts, as otherwise it is likely to be tried too often. */
/* Internal problem, message in buffer. */
case ERROR:
- set_errno(addrlist, ERRNO_AUTHPROB, string_copy(buffer),
- DEFER, FALSE, NULL);
+ set_errno_nohost(addrlist, ERRNO_AUTHPROB, string_copy(buffer),
+ DEFER, FALSE);
return ERROR;
}
if (require_auth == OK && !smtp_authenticated)
{
- set_errno(addrlist, ERRNO_AUTHFAIL,
+ set_errno_nohost(addrlist, ERRNO_AUTHFAIL,
string_sprintf("authentication required but %s", fail_reason), DEFER,
- FALSE, NULL);
+ FALSE);
return DEFER;
}
{
uschar *message = string_sprintf("failed to expand "
"authenticated_sender: %s", expand_string_message);
- set_errno(addrlist, ERRNO_EXPANDFAIL, message, DEFER, FALSE, NULL);
+ set_errno_nohost(addrlist, ERRNO_EXPANDFAIL, message, DEFER, FALSE);
return TRUE;
}
}
#ifdef EXPERIMENTAL_DANE
int
-tlsa_lookup(host_item * host, dns_answer * dnsa,
+tlsa_lookup(const host_item * host, dns_answer * dnsa,
BOOL dane_required, BOOL * dane)
{
/* move this out to host.c given the similarity to dns_lookup() ? */
uschar buffer[300];
-uschar * fullname = buffer;
+const uschar * fullname = buffer;
/* TLSA lookup string */
(void)sprintf(CS buffer, "_%d._tcp.%.256s", host->port, host->name);
default:
case DNS_FAIL:
if (dane_required)
- {
- log_write(0, LOG_MAIN, "DANE error: TLSA lookup failed");
return FAIL;
- }
break;
case DNS_SUCCEED:
#endif
+
+typedef struct smtp_compare_s
+{
+ uschar *current_sender_address;
+ struct transport_instance *tblock;
+} smtp_compare_t;
+
+/*
+Create a unique string that identifies this message, it is based on
+sender_address, helo_data and tls_certificate if enabled. */
+
+static uschar *
+smtp_local_identity(uschar * sender, struct transport_instance * tblock)
+{
+address_item * addr1;
+uschar * if1 = US"";
+uschar * helo1 = US"";
+#ifdef SUPPORT_TLS
+uschar * tlsc1 = US"";
+#endif
+uschar * save_sender_address = sender_address;
+uschar * local_identity = NULL;
+smtp_transport_options_block * ob =
+ (smtp_transport_options_block *)tblock->options_block;
+
+sender_address = sender;
+
+addr1 = deliver_make_addr (sender, TRUE);
+deliver_set_expansions(addr1);
+
+if (ob->interface)
+ if1 = expand_string(ob->interface);
+
+if (ob->helo_data)
+ helo1 = expand_string(ob->helo_data);
+
+#ifdef SUPPORT_TLS
+if (ob->tls_certificate)
+ tlsc1 = expand_string(ob->tls_certificate);
+local_identity = string_sprintf ("%s^%s^%s", if1, helo1, tlsc1);
+#else
+local_identity = string_sprintf ("%s^%s", if1, helo1);
+#endif
+
+deliver_set_expansions(NULL);
+sender_address = save_sender_address;
+
+return local_identity;
+}
+
+
+
+/* This routine is a callback that is called from transport_check_waiting.
+This function will evaluate the incoming message versus the previous
+message. If the incoming message is using a different local identity then
+we will veto this new message. */
+
+static BOOL
+smtp_are_same_identities(uschar * message_id, smtp_compare_t * s_compare)
+{
+
+uschar * message_local_identity,
+ * current_local_identity,
+ * new_sender_address;
+
+current_local_identity =
+ smtp_local_identity(s_compare->current_sender_address, s_compare->tblock);
+
+if (!(new_sender_address = deliver_get_sender_address(message_id)))
+ return 0;
+
+message_local_identity =
+ smtp_local_identity(new_sender_address, s_compare->tblock);
+
+return Ustrcmp(current_local_identity, message_local_identity) == 0;
+}
+
+
+
/*************************************************
* Deliver address list to given host *
*************************************************/
port default TCP/IP port to use, in host byte order
interface interface to bind to, or NULL
tblock transport instance block
- copy_host TRUE if host set in addr->host_used must be copied, because
- it is specific to this call of the transport
message_defer set TRUE if yield is OK, but all addresses were deferred
because of a non-recipient, non-host failure, that is, a
4xx response to MAIL FROM, DATA, or ".". This is a defer
static int
smtp_deliver(address_item *addrlist, host_item *host, int host_af, int port,
- uschar *interface, transport_instance *tblock, BOOL copy_host,
+ uschar *interface, transport_instance *tblock,
BOOL *message_defer, BOOL suppress_tls)
{
address_item *addr;
BOOL prdr_offered = FALSE;
BOOL prdr_active;
#endif
+#ifdef SUPPORT_I18N
+BOOL utf8_needed = FALSE;
+BOOL utf8_offered = FALSE;
+#endif
BOOL dsn_all_lasthop = TRUE;
#if defined(SUPPORT_TLS) && defined(EXPERIMENTAL_DANE)
BOOL dane = FALSE;
+BOOL dane_required = verify_check_given_host(&ob->hosts_require_dane, host) == OK;
dns_answer tlsa_dnsa;
#endif
smtp_inblock inblock;
smtp_outblock outblock;
int max_rcpt = tblock->max_addresses;
uschar *igquotstr = US"";
+
+#ifdef EXPERIMENTAL_DSN_INFO
+uschar *smtp_greeting = NULL;
+uschar *helo_response = NULL;
+#endif
uschar *helo_data = NULL;
+
uschar *message = NULL;
uschar new_message_id[MESSAGE_ID_LENGTH + 1];
uschar *p;
#ifndef SUPPORT_TLS
if (smtps)
{
- set_errno(addrlist, ERRNO_TLSFAILURE, US"TLS support not available",
- DEFER, FALSE, NULL);
+ set_errno_nohost(addrlist, ERRNO_TLSFAILURE, US"TLS support not available",
+ DEFER, FALSE);
return ERROR;
}
#endif
{
/* This puts port into host->port */
inblock.sock = outblock.sock =
- smtp_connect(host, host_af, port, interface, ob->connect_timeout,
- ob->keepalive, ob->dscp
-#ifdef EXPERIMENTAL_EVENT
- , tblock->event_action
-#endif
- );
+ smtp_connect(host, host_af, port, interface, ob->connect_timeout, tblock);
if (inblock.sock < 0)
{
- set_errno(addrlist, (errno == ETIMEDOUT)? ERRNO_CONNECTTIMEOUT : errno,
- NULL, DEFER, FALSE, NULL);
+ set_errno_nohost(addrlist, (errno == ETIMEDOUT)? ERRNO_CONNECTTIMEOUT : errno,
+ NULL, DEFER, FALSE);
return DEFER;
}
#if defined(SUPPORT_TLS) && defined(EXPERIMENTAL_DANE)
{
- BOOL dane_required;
-
tls_out.dane_verified = FALSE;
tls_out.tlsa_usage = 0;
- dane_required = verify_check_given_host(&ob->hosts_require_dane, host) == OK;
-
if (host->dnssec == DS_YES)
{
- if( dane_required
- || verify_check_given_host(&ob->hosts_try_dane, host) == OK
+ if( ( dane_required
+ || verify_check_given_host(&ob->hosts_try_dane, host) == OK
+ )
+ && (rc = tlsa_lookup(host, &tlsa_dnsa, dane_required, &dane)) != OK
+ && dane_required /* do not error on only dane-requested */
)
- if ((rc = tlsa_lookup(host, &tlsa_dnsa, dane_required, &dane)) != OK)
- return rc;
+ {
+ set_errno_nohost(addrlist, ERRNO_DNSDEFER,
+ string_sprintf("DANE error: tlsa lookup %s",
+ rc == DEFER ? "DEFER" : "FAIL"),
+ rc, FALSE);
+ return rc;
+ }
}
else if (dane_required)
{
- log_write(0, LOG_MAIN, "DANE error: %s lookup not DNSSEC", host->name);
- return FAIL;
+ set_errno_nohost(addrlist, ERRNO_DNSDEFER,
+ string_sprintf("DANE error: %s lookup not DNSSEC", host->name),
+ FAIL, FALSE);
+ return FAIL;
}
if (dane)
delayed till here so that $sending_interface and $sending_port are set. */
helo_data = expand_string(ob->helo_data);
+#ifdef SUPPORT_I18N
+ if (helo_data)
+ {
+ uschar * errstr = NULL;
+ if ((helo_data = string_domain_utf8_to_alabel(helo_data, &errstr)), errstr)
+ {
+ errstr = string_sprintf("failed to expand helo_data: %s", errstr);
+ set_errno_nohost(addrlist, ERRNO_EXPANDFAIL, errstr, DEFER, FALSE);
+ yield = DEFER;
+ goto SEND_QUIT;
+ }
+ }
+#endif
/* The first thing is to wait for an initial OK response. The dreaded "goto"
is nevertheless a reasonably clean way of programming this kind of logic,
if (!smtps)
{
- if (!smtp_read_response(&inblock, buffer, sizeof(buffer), '2',
- ob->command_timeout)) goto RESPONSE_FAILED;
+ BOOL good_response = smtp_read_response(&inblock, buffer, sizeof(buffer),
+ '2', ob->command_timeout);
+#ifdef EXPERIMENTAL_DSN_INFO
+ smtp_greeting = string_copy(buffer);
+#endif
+ if (!good_response) goto RESPONSE_FAILED;
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
{
uschar * s;
lookup_dnssec_authenticated = host->dnssec==DS_YES ? US"yes"
s = event_raise(tblock->event_action, US"smtp:connect", buffer);
if (s)
{
- set_errno(addrlist, ERRNO_EXPANDFAIL,
+ set_errno_nohost(addrlist, ERRNO_EXPANDFAIL,
string_sprintf("deferred by smtp:connect event expansion: %s", s),
- DEFER, FALSE, NULL);
+ DEFER, FALSE);
yield = DEFER;
goto SEND_QUIT;
}
{
uschar *message = string_sprintf("failed to expand helo_data: %s",
expand_string_message);
- set_errno(addrlist, ERRNO_EXPANDFAIL, message, DEFER, FALSE, NULL);
+ set_errno_nohost(addrlist, ERRNO_EXPANDFAIL, message, DEFER, FALSE);
yield = DEFER;
goto SEND_QUIT;
}
if (!smtp_read_response(&inblock, buffer, sizeof(buffer), '2',
ob->command_timeout))
{
- if (errno != 0 || buffer[0] == 0 || lmtp) goto RESPONSE_FAILED;
+ if (errno != 0 || buffer[0] == 0 || lmtp)
+ {
+#ifdef EXPERIMENTAL_DSN_INFO
+ helo_response = string_copy(buffer);
+#endif
+ goto RESPONSE_FAILED;
+ }
esmtp = FALSE;
}
+#ifdef EXPERIMENTAL_DSN_INFO
+ helo_response = string_copy(buffer);
+#endif
}
else
{
if (!esmtp)
{
+ BOOL good_response;
+
if (smtp_write_command(&outblock, FALSE, "HELO %s\r\n", helo_data) < 0)
goto SEND_FAILED;
- if (!smtp_read_response(&inblock, buffer, sizeof(buffer), '2',
- ob->command_timeout)) goto RESPONSE_FAILED;
+ good_response = smtp_read_response(&inblock, buffer, sizeof(buffer),
+ '2', ob->command_timeout);
+#ifdef EXPERIMENTAL_DSN_INFO
+ helo_response = string_copy(buffer);
+#endif
+ if (!good_response) goto RESPONSE_FAILED;
}
/* Set IGNOREQUOTA if the response to LHLO specifies support and the
if (prdr_offered)
{DEBUG(D_transport) debug_printf("PRDR usable\n");}
#endif
+
+#ifdef SUPPORT_I18N
+ if (addrlist->prop.utf8_msg)
+ {
+ utf8_needed = !addrlist->prop.utf8_downcvt
+ && !addrlist->prop.utf8_downcvt_maybe;
+ DEBUG(D_transport) if (!utf8_needed) debug_printf("utf8: %s downconvert\n",
+ addrlist->prop.utf8_downcvt ? "mandatory" : "optional");
+
+ utf8_offered = esmtp
+ && pcre_exec(regex_UTF8, NULL, CS buffer, Ustrlen(buffer), 0,
+ PCRE_EOPT, NULL, 0) >= 0;
+ }
+#endif
}
/* For continuing deliveries down the same channel, the socket is the standard
set from the command line if they were set in the process that passed the
connection on. */
+/*XXX continue case needs to propagate DSN_INFO, prob. in deliver.c
+as the contine goes via transport_pass_socket() and doublefork and exec.
+It does not wait. Unclear how we keep separate host's responses
+separate - we could match up by host ip+port as a bodge. */
+
else
{
inblock.sock = outblock.sock = fileno(stdin);
if (rc != OK)
{
+# ifdef EXPERIMENTAL_DANE
+ if (rc == DEFER && dane && !dane_required)
+ {
+ log_write(0, LOG_MAIN, "DANE attempt failed;"
+ " trying CA-root TLS to %s [%s] (not in hosts_require_dane)",
+ host->name, host->address);
+ dane = FALSE;
+ goto TLS_NEGOTIATE;
+ }
+# endif
+
save_errno = ERRNO_TLSFAILURE;
message = US"failure while setting up TLS session";
send_quit = FALSE;
/* TLS session is set up */
- for (addr = addrlist; addr != NULL; addr = addr->next)
+ for (addr = addrlist; addr; addr = addr->next)
if (addr->transport_return == PENDING_DEFER)
{
addr->cipher = tls_out.cipher;
if (tls_out.active >= 0)
{
char *greeting_cmd;
+ BOOL good_response;
+
if (helo_data == NULL)
{
helo_data = expand_string(ob->helo_data);
{
uschar *message = string_sprintf("failed to expand helo_data: %s",
expand_string_message);
- set_errno(addrlist, ERRNO_EXPANDFAIL, message, DEFER, FALSE, NULL);
+ set_errno_nohost(addrlist, ERRNO_EXPANDFAIL, message, DEFER, FALSE);
yield = DEFER;
goto SEND_QUIT;
}
/* For SMTPS we need to wait for the initial OK response. */
if (smtps)
{
- if (!smtp_read_response(&inblock, buffer, sizeof(buffer), '2',
- ob->command_timeout)) goto RESPONSE_FAILED;
+ good_response = smtp_read_response(&inblock, buffer, sizeof(buffer),
+ '2', ob->command_timeout);
+#ifdef EXPERIMENTAL_DSN_INFO
+ smtp_greeting = string_copy(buffer);
+#endif
+ if (!good_response) goto RESPONSE_FAILED;
}
if (esmtp)
if (smtp_write_command(&outblock, FALSE, "%s %s\r\n",
lmtp? "LHLO" : greeting_cmd, helo_data) < 0)
goto SEND_FAILED;
- if (!smtp_read_response(&inblock, buffer, sizeof(buffer), '2',
- ob->command_timeout))
- goto RESPONSE_FAILED;
+ good_response = smtp_read_response(&inblock, buffer, sizeof(buffer),
+ '2', ob->command_timeout);
+#ifdef EXPERIMENTAL_DSN_INFO
+ helo_response = string_copy(buffer);
+#endif
+ if (!good_response) goto RESPONSE_FAILED;
}
/* If the host is required to use a secure channel, ensure that we
#ifndef DISABLE_PRDR
prdr_offered = esmtp
&& pcre_exec(regex_PRDR, NULL, CS buffer, Ustrlen(CS buffer), 0,
- PCRE_EOPT, NULL, 0) >= 0
+ PCRE_EOPT, NULL, 0) >= 0
&& verify_check_given_host(&ob->hosts_try_prdr, host) == OK;
if (prdr_offered)
{DEBUG(D_transport) debug_printf("PRDR usable\n");}
#endif
+#ifdef SUPPORT_I18N
+ if (addrlist->prop.utf8_msg)
+ utf8_offered = esmtp
+ && pcre_exec(regex_UTF8, NULL, CS buffer, Ustrlen(buffer), 0,
+ PCRE_EOPT, NULL, 0) >= 0;
+#endif
+
/* Note if the server supports DSN */
- smtp_use_dsn = esmtp && pcre_exec(regex_DSN, NULL, CS buffer, (int)Ustrlen(CS buffer), 0,
- PCRE_EOPT, NULL, 0) >= 0;
+ smtp_use_dsn = esmtp
+ && pcre_exec(regex_DSN, NULL, CS buffer, Ustrlen(CS buffer), 0,
+ PCRE_EOPT, NULL, 0) >= 0;
DEBUG(D_transport) debug_printf("use_dsn=%d\n", smtp_use_dsn);
/* Note if the response to EHLO specifies support for the AUTH extension.
setting_up = FALSE;
+#ifdef SUPPORT_I18N
+/* If this is an international message we need the host to speak SMTPUTF8 */
+if (utf8_needed && !utf8_offered)
+ {
+ errno = ERRNO_UTF8_FWD;
+ goto RESPONSE_FAILED;
+ }
+#endif
+
/* If there is a filter command specified for this transport, we can now
set it up. This cannot be done until the identify of the host is known. */
if (!rc)
{
- set_errno(addrlist->next, addrlist->basic_errno, addrlist->message, DEFER,
- FALSE, NULL);
+ set_errno_nohost(addrlist->next, addrlist->basic_errno, addrlist->message, DEFER,
+ FALSE);
yield = ERROR;
goto SEND_QUIT;
}
}
#endif
+#ifdef SUPPORT_I18N
+if (addrlist->prop.utf8_msg && !addrlist->prop.utf8_downcvt && utf8_offered)
+ sprintf(CS p, " SMTPUTF8"), p += 9;
+#endif
+
/* check if all addresses have lasthop flag */
/* do not send RET and ENVID if true */
-dsn_all_lasthop = TRUE;
-for (addr = first_addr;
+for (dsn_all_lasthop = TRUE, addr = first_addr;
address_count < max_rcpt && addr != NULL;
addr = addr->next)
if ((addr->dsn_flags & rf_dsnlasthop) != 1)
+ {
dsn_all_lasthop = FALSE;
+ break;
+ }
/* Add any DSN flags to the mail command */
-if ((smtp_use_dsn) && (dsn_all_lasthop == FALSE))
+if (smtp_use_dsn && !dsn_all_lasthop)
{
if (dsn_ret == dsn_ret_hdrs)
{
pending_MAIL = TRUE; /* The block starts with MAIL */
-rc = smtp_write_command(&outblock, smtp_use_pipelining,
- "MAIL FROM:<%s>%s\r\n", return_path, buffer);
+ {
+ uschar * s = return_path;
+#ifdef SUPPORT_I18N
+ uschar * errstr = NULL;
+
+ /* If we must downconvert, do the from-address here. Remember we had to
+ for the to-addresses (done below), and also (ugly) for re-doing when building
+ the delivery log line. */
+
+ if (addrlist->prop.utf8_msg && (addrlist->prop.utf8_downcvt || !utf8_offered))
+ {
+ if (s = string_address_utf8_to_alabel(return_path, &errstr), errstr)
+ {
+ set_errno_nohost(addrlist, ERRNO_EXPANDFAIL, errstr, DEFER, FALSE);
+ yield = ERROR;
+ goto SEND_QUIT;
+ }
+ setflag(addrlist, af_utf8_downcvt);
+ }
+#endif
+
+ rc = smtp_write_command(&outblock, smtp_use_pipelining,
+ "MAIL FROM:<%s>%s\r\n", s, buffer);
+ }
+
mail_command = string_copy(big_buffer); /* Save for later error message */
switch(rc)
{
case -1: /* Transmission error */
- goto SEND_FAILED;
+ goto SEND_FAILED;
case +1: /* Block was sent */
- if (!smtp_read_response(&inblock, buffer, sizeof(buffer), '2',
+ if (!smtp_read_response(&inblock, buffer, sizeof(buffer), '2',
ob->command_timeout))
- {
- if (errno == 0 && buffer[0] == '4')
{
- errno = ERRNO_MAIL4XX;
- addrlist->more_errno |= ((buffer[1] - '0')*10 + buffer[2] - '0') << 8;
+ if (errno == 0 && buffer[0] == '4')
+ {
+ errno = ERRNO_MAIL4XX;
+ addrlist->more_errno |= ((buffer[1] - '0')*10 + buffer[2] - '0') << 8;
+ }
+ goto RESPONSE_FAILED;
}
- goto RESPONSE_FAILED;
- }
- pending_MAIL = FALSE;
- break;
+ pending_MAIL = FALSE;
+ break;
}
/* Pass over all the relevant recipient addresses for this host, which are the
{
int count;
BOOL no_flush;
+ uschar * rcpt_addr;
addr->dsn_aware = smtp_use_dsn ? dsn_support_yes : dsn_support_no;
yield as OK, because this error can often mean that there is a problem with
just one address, so we don't want to delay the host. */
+ rcpt_addr = transport_rcpt_address(addr, tblock->rcpt_include_affixes);
+
+#ifdef SUPPORT_I18N
+ {
+ uschar * dummy_errstr;
+ if ( testflag(addrlist, af_utf8_downcvt)
+ && (rcpt_addr = string_address_utf8_to_alabel(rcpt_addr, &dummy_errstr),
+ dummy_errstr
+ ) )
+ {
+ errno = ERRNO_EXPANDFAIL;
+ goto SEND_FAILED;
+ }
+ }
+#endif
+
count = smtp_write_command(&outblock, no_flush, "RCPT TO:<%s>%s%s\r\n",
- transport_rcpt_address(addr, tblock->rcpt_include_affixes), igquotstr, buffer);
+ rcpt_addr, igquotstr, buffer);
if (count < 0) goto SEND_FAILED;
if (count > 0)
if (badaddr->transport_return != PENDING_OK)
{
/*XXX could we find a better errno than 0 here? */
- set_errno(addrlist, 0, badaddr->message, FAIL,
- testflag(badaddr, af_pass_message), NULL);
+ set_errno_nohost(addrlist, 0, badaddr->message, FAIL,
+ testflag(badaddr, af_pass_message));
ok = FALSE;
break;
}
int flag = '=';
int delivery_time = (int)(time(NULL) - start_delivery_time);
int len;
- host_item *thost;
uschar *conf = NULL;
send_rset = FALSE;
- /* Make a copy of the host if it is local to this invocation
- of the transport. */
-
- if (copy_host)
- {
- thost = store_get(sizeof(host_item));
- *thost = *host;
- thost->name = string_copy(host->name);
- thost->address = string_copy(host->address);
- }
- else thost = host;
-
/* Set up confirmation if needed - applies only to SMTP */
if (
-#ifndef EXPERIMENTAL_EVENT
- (log_extra_selector & LX_smtp_confirmation) != 0 &&
+#ifdef DISABLE_EVENT
+ LOGGING(smtp_confirmation) &&
#endif
!lmtp
)
{
- uschar *s = string_printing(buffer);
- conf = (s == buffer)? (uschar *)string_copy(s) : s;
+ const uschar *s = string_printing(buffer);
+ /* deconst cast ok here as string_printing was checked to have alloc'n'copied */
+ conf = (s == buffer)? (uschar *)string_copy(s) : US s;
}
/* Process all transported addresses - for LMTP or PRDR, read a status for
continue;
}
completed_address = TRUE; /* NOW we can set this flag */
- if ((log_extra_selector & LX_smtp_confirmation) != 0)
+ if (LOGGING(smtp_confirmation))
{
- uschar *s = string_printing(buffer);
- conf = (s == buffer)? (uschar *)string_copy(s) : s;
+ const uschar *s = string_printing(buffer);
+ /* deconst cast ok here as string_printing was checked to have alloc'n'copied */
+ conf = (s == buffer)? (uschar *)string_copy(s) : US s;
}
}
addr->transport_return = OK;
addr->more_errno = delivery_time;
- addr->host_used = thost;
+ addr->host_used = host;
addr->special_action = flag;
addr->message = conf;
#ifndef DISABLE_PRDR
else
sprintf(CS buffer, "%.500s\n", addr->unique);
- DEBUG(D_deliver) debug_printf("journalling %s", buffer);
+ DEBUG(D_deliver) debug_printf("journalling %s\n", buffer);
len = Ustrlen(CS buffer);
if (write(journal_fd, buffer, len) != len)
log_write(0, LOG_MAIN|LOG_PANIC, "failed to write journal for "
else
sprintf(CS buffer, "%.500s\n", addr->unique);
- DEBUG(D_deliver) debug_printf("journalling(PRDR) %s", buffer);
+ DEBUG(D_deliver) debug_printf("journalling(PRDR) %s\n", buffer);
len = Ustrlen(CS buffer);
if (write(journal_fd, buffer, len) != len)
log_write(0, LOG_MAIN|LOG_PANIC, "failed to write journal for "
if (!ok)
{
- int code;
+ int code, set_rc;
+ uschar * set_message;
RESPONSE_FAILED:
- save_errno = errno;
- message = NULL;
- send_quit = check_response(host, &save_errno, addrlist->more_errno,
- buffer, &code, &message, &pass_message);
- goto FAILED;
+ {
+ save_errno = errno;
+ message = NULL;
+ send_quit = check_response(host, &save_errno, addrlist->more_errno,
+ buffer, &code, &message, &pass_message);
+ goto FAILED;
+ }
SEND_FAILED:
- save_errno = errno;
- code = '4';
- message = US string_sprintf("send() to %s [%s] failed: %s",
- host->name, host->address, strerror(save_errno));
- send_quit = FALSE;
- goto FAILED;
+ {
+ save_errno = errno;
+ code = '4';
+ message = US string_sprintf("send() to %s [%s] failed: %s",
+ host->name, host->address, strerror(save_errno));
+ send_quit = FALSE;
+ goto FAILED;
+ }
/* This label is jumped to directly when a TLS negotiation has failed,
or was not done for a host for which it is required. Values will be set
FAILED:
ok = FALSE; /* For when reached by GOTO */
+ set_message = message;
if (setting_up)
{
if (code == '5')
- set_errno(addrlist, save_errno, message, FAIL, pass_message, host);
+ set_rc = FAIL;
else
- {
- set_errno(addrlist, save_errno, message, DEFER, pass_message, host);
- yield = DEFER;
- }
+ yield = set_rc = DEFER;
}
/* We want to handle timeouts after MAIL or "." and loss of connection after
switch(save_errno)
{
+#ifdef SUPPORT_I18N
+ case ERRNO_UTF8_FWD:
+ code = '5';
+ /*FALLTHROUGH*/
+#endif
case 0:
case ERRNO_MAIL4XX:
case ERRNO_DATA4XX:
- message_error = TRUE;
- break;
+ message_error = TRUE;
+ break;
case ETIMEDOUT:
- message_error = Ustrncmp(smtp_command,"MAIL",4) == 0 ||
- Ustrncmp(smtp_command,"end ",4) == 0;
- break;
+ message_error = Ustrncmp(smtp_command,"MAIL",4) == 0 ||
+ Ustrncmp(smtp_command,"end ",4) == 0;
+ break;
case ERRNO_SMTPCLOSED:
- message_error = Ustrncmp(smtp_command,"end ",4) == 0;
- break;
+ message_error = Ustrncmp(smtp_command,"end ",4) == 0;
+ break;
default:
- message_error = FALSE;
- break;
+ message_error = FALSE;
+ break;
}
/* Handle the cases that are treated as message errors. These are:
(a) negative response or timeout after MAIL
(b) negative response after DATA
(c) negative response or timeout or dropped connection after "."
+ (d) utf8 support required and not offered
It won't be a negative response or timeout after RCPT, as that is dealt
with separately above. The action in all cases is to set an appropriate
if (message_error)
{
if (mua_wrapper) code = '5'; /* Force hard failure in wrapper mode */
- set_errno(addrlist, save_errno, message, (code == '5')? FAIL : DEFER,
- pass_message, host);
/* If there's an errno, the message contains just the identity of
the host. */
- if (code != '5') /* Anything other than 5 is treated as temporary */
+ if (code == '5')
+ set_rc = FAIL;
+ else /* Anything other than 5 is treated as temporary */
{
+ set_rc = DEFER;
if (save_errno > 0)
message = US string_sprintf("%s: %s", message, strerror(save_errno));
if (host->next != NULL) log_write(0, LOG_MAIN, "%s", message);
else
{
+ set_rc = DEFER;
yield = (save_errno == ERRNO_CHHEADER_FAIL ||
save_errno == ERRNO_FILTER_FAIL)? ERROR : DEFER;
- set_errno(addrlist, save_errno, message, DEFER, pass_message, host);
}
}
+
+ set_errno(addrlist, save_errno, set_message, set_rc, pass_message, host
+#ifdef EXPERIMENTAL_DSN_INFO
+ , smtp_greeting, helo_response
+#endif
+ );
}
if (completed_address && ok && send_quit)
{
BOOL more;
+ smtp_compare_t t_compare;
+
+ t_compare.tblock = tblock;
+ t_compare.current_sender_address = sender_address;
+
if ( first_addr != NULL
|| continue_more
|| ( ( tls_out.active < 0
)
&&
transport_check_waiting(tblock->name, host->name,
- tblock->connection_max_messages, new_message_id, &more)
+ tblock->connection_max_messages, new_message_id, &more,
+ (oicf)smtp_are_same_identities, (void*)&t_compare)
) )
{
uschar *msg;
/* If the socket is successfully passed, we musn't send QUIT (or
indeed anything!) from here. */
+/*XXX DSN_INFO: assume likely to do new HELO; but for greet we'll want to
+propagate it from the initial
+*/
if (ok && transport_pass_socket(tblock->name, host->name, host->address,
new_message_id, inblock.sock))
{
/* If RSET failed and there are addresses left, they get deferred. */
- else set_errno(first_addr, errno, msg, DEFER, FALSE, host);
+ else set_errno(first_addr, errno, msg, DEFER, FALSE, host
+#ifdef EXPERIMENTAL_DSN_INFO
+ , smtp_greeting, helo_response
+#endif
+ );
}
}
(void)close(inblock.sock);
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
(void) event_raise(tblock->event_action, US"tcp:close", NULL);
#endif
addr->peercert = NULL;
addr->peerdn = NULL;
addr->ocsp = OCSP_NOT_REQ;
+#endif
+#ifdef EXPERIMENTAL_DSN_INFO
+ addr->smtp_greeting = NULL;
+ addr->helo_response = NULL;
#endif
}
return first_addr;
if (Ustrchr(s, '$') != NULL)
{
- expanded_hosts = expand_string(s);
- if (expanded_hosts == NULL)
+ if (!(expanded_hosts = expand_string(s)))
{
addrlist->message = string_sprintf("failed to expand list of hosts "
"\"%s\" in %s transport: %s", s, tblock->name, expand_string_message);
/* If there was no expansion of hosts, save the host list for
next time. */
- if (expanded_hosts == NULL) ob->hostlist = hostlist;
+ if (!expanded_hosts) ob->hostlist = hostlist;
}
/* This is not the first time this transport has been run in this delivery;
the host list was built previously. */
- else hostlist = ob->hostlist;
+ else
+ hostlist = ob->hostlist;
}
/* The host list was supplied with the address. If hosts_randomize is set, we
hostlist = addrlist->host_list = newlist;
}
-
/* Sort out the default port. */
if (!smtp_get_port(ob->port, addrlist, &port, tid)) return FALSE;
-
/* For each host-plus-IP-address on the list:
. If this is a continued delivery and the host isn't the one with the
BOOL serialized = FALSE;
BOOL host_is_expired = FALSE;
BOOL message_defer = FALSE;
- BOOL ifchanges = FALSE;
BOOL some_deferred = FALSE;
address_item *first_addr = NULL;
uschar *interface = NULL;
{
int new_port, flags;
host_item *hh;
- uschar *canonical_name;
if (host->status >= hstatus_unusable)
{
if (ob->dns_search_parents) flags |= HOST_FIND_SEARCH_PARENTS;
if (ob->gethostbyname || string_is_ip_address(host->name, NULL) != 0)
- rc = host_find_byname(host, NULL, flags, &canonical_name, TRUE);
+ rc = host_find_byname(host, NULL, flags, NULL, TRUE);
else
rc = host_find_bydns(host, NULL, flags, NULL, NULL, NULL,
- ob->dnssec_request_domains, ob->dnssec_require_domains,
- &canonical_name, NULL);
+ &ob->dnssec, /* domains for request/require */
+ NULL, NULL);
/* Update the host (and any additional blocks, resulting from
multihoming) with a host-specific port, if any. */
doing a two-stage queue run, don't do this if forcing. */
if ((!deliver_force || queue_2stage) && (queue_smtp ||
- match_isinlist(addrlist->domain, &queue_smtp_domains, 0,
+ match_isinlist(addrlist->domain,
+ (const uschar **)&queue_smtp_domains, 0,
&domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL) == OK))
{
expired = FALSE;
if (Ustrcmp(pistring, ":25") == 0) pistring = US"";
/* Select IPv4 or IPv6, and choose an outgoing interface. If the interface
- string changes upon expansion, we must add it to the key that is used for
- retries, because connections to the same host from a different interface
- should be treated separately. */
+ string is set, even if constant (as different transports can have different
+ constant settings), we must add it to the key that is used for retries,
+ because connections to the same host from a different interface should be
+ treated separately. */
host_af = (Ustrchr(host->address, ':') == NULL)? AF_INET : AF_INET6;
- if (!smtp_get_interface(ob->interface, host_af, addrlist, &ifchanges,
- &interface, tid))
- return FALSE;
- if (ifchanges) pistring = string_sprintf("%s/%s", pistring, interface);
+ if ((rs = ob->interface) && *rs)
+ {
+ if (!smtp_get_interface(rs, host_af, addrlist, &interface, tid))
+ return FALSE;
+ pistring = string_sprintf("%s/%s", pistring, interface);
+ }
/* The first time round the outer loop, check the status of the host by
inspecting the retry data. The second time round, we are interested only
verify_check_given_host(&ob->serialize_hosts, host) == OK)
{
serialize_key = string_sprintf("host-serialize-%s", host->name);
- if (!enq_start(serialize_key))
+ if (!enq_start(serialize_key, 1))
{
DEBUG(D_transport)
debug_printf("skipping host %s because another Exim process "
if (dont_deliver)
{
host_item *host2;
- set_errno(addrlist, 0, NULL, OK, FALSE, NULL);
+ set_errno_nohost(addrlist, 0, NULL, OK, FALSE);
for (addr = addrlist; addr != NULL; addr = addr->next)
{
addr->host_used = host;
else
{
+ host_item * thost;
+ /* Make a copy of the host if it is local to this invocation
+ of the transport. */
+
+ if (expanded_hosts)
+ {
+ thost = store_get(sizeof(host_item));
+ *thost = *host;
+ thost->name = string_copy(host->name);
+ thost->address = string_copy(host->address);
+ }
+ else
+ thost = host;
+
if (!host_is_expired && ++unexpired_hosts_tried >= ob->hosts_max_try)
{
host_item *h;
DEBUG(D_transport)
debug_printf("hosts_max_try limit reached with this host\n");
- for (h = host; h != NULL; h = h->next)
- if (h->mx != host->mx) break;
- if (h != NULL)
- {
- nexthost = h;
- unexpired_hosts_tried--;
- DEBUG(D_transport) debug_printf("however, a higher MX host exists "
- "and will be tried\n");
- }
+ for (h = host; h; h = h->next) if (h->mx != host->mx)
+ {
+ nexthost = h;
+ unexpired_hosts_tried--;
+ DEBUG(D_transport) debug_printf("however, a higher MX host exists "
+ "and will be tried\n");
+ break;
+ }
}
/* Attempt the delivery. */
total_hosts_tried++;
- rc = smtp_deliver(addrlist, host, host_af, port, interface, tblock,
- expanded_hosts != NULL, &message_defer, FALSE);
+ rc = smtp_deliver(addrlist, thost, host_af, port, interface, tblock,
+ &message_defer, FALSE);
/* Yield is one of:
OK => connection made, each address contains its result;
first_addr->basic_errno != ERRNO_TLSFAILURE)
write_logs(first_addr, host);
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
if (rc == DEFER)
deferred_event_raise(first_addr, host);
#endif
log_write(0, LOG_MAIN, "TLS session failure: delivering unencrypted "
"to %s [%s] (not in hosts_require_tls)", host->name, host->address);
first_addr = prepare_addresses(addrlist, host);
- rc = smtp_deliver(addrlist, host, host_af, port, interface, tblock,
- expanded_hosts != NULL, &message_defer, TRUE);
+ rc = smtp_deliver(addrlist, thost, host_af, port, interface, tblock,
+ &message_defer, TRUE);
if (rc == DEFER && first_addr->basic_errno != ERRNO_AUTHFAIL)
write_logs(first_addr, host);
-# ifdef EXPERIMENTAL_EVENT
+# ifndef DISABLE_EVENT
if (rc == DEFER)
deferred_event_raise(first_addr, host);
# endif
case, see if any of them are deferred. */
if (rc == OK)
- {
- for (addr = addrlist; addr != NULL; addr = addr->next)
- {
+ for (addr = addrlist; addr; addr = addr->next)
if (addr->transport_return == DEFER)
{
some_deferred = TRUE;
break;
}
- }
- }
/* If no addresses deferred or the result was ERROR, return. We do this for
ERROR because a failing filter set-up or add_headers expansion is likely to
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Private structure for the private options and other private data. */
BOOL gethostbyname;
BOOL dns_qualify_single;
BOOL dns_search_parents;
- uschar *dnssec_request_domains;
- uschar *dnssec_require_domains;
+ dnssec_domains dnssec;
BOOL delay_after_cutoff;
BOOL hosts_override;
BOOL hosts_randomize;
BOOL lmtp_ignore_quota;
uschar *expand_retry_include_ip_address;
BOOL retry_include_ip_address;
+#ifdef SUPPORT_SOCKS
+ uschar *socks_proxy;
+#endif
#ifdef SUPPORT_TLS
uschar *tls_certificate;
uschar *tls_crl;
extern BOOL smtp_mail_auth_str(uschar *, unsigned,
address_item *, smtp_transport_options_block *);
+#ifdef SUPPORT_SOCKS
+extern int socks_sock_connect(host_item *, int, int, uschar *,
+ transport_instance *, int);
+#endif
+
/* End of transports/smtp.h */
--- /dev/null
+/*************************************************
+* Exim - an Internet mail transport agent *
+*************************************************/
+
+/* Copyright (c) Jeremy Harris 2015 */
+/* See the file NOTICE for conditions of use and distribution. */
+
+/* SOCKS version 5 proxy, client-mode */
+
+#include "../exim.h"
+#include "smtp.h"
+
+#ifdef SUPPORT_SOCKS /* entire file */
+
+#ifndef nelem
+# define nelem(arr) (sizeof(arr)/sizeof(*arr))
+#endif
+
+
+/* Defaults */
+#define SOCKS_PORT 1080
+#define SOCKS_TIMEOUT 5
+#define SOCKS_WEIGHT 1
+#define SOCKS_PRIORITY 1
+
+#define AUTH_NONE 0
+#define AUTH_NAME 2 /* user/password per RFC 1929 */
+#define AUTH_NAME_VER 1
+
+struct socks_err
+ {
+ uschar * reason;
+ int errcode;
+ } socks_errs[] =
+ {
+ {NULL, 0},
+ {US"general SOCKS server failure", EIO},
+ {US"connection not allowed by ruleset", EACCES},
+ {US"Network unreachable", ENETUNREACH},
+ {US"Host unreachable", EHOSTUNREACH},
+ {US"Connection refused", ECONNREFUSED},
+ {US"TTL expired", ECANCELED},
+ {US"Command not supported", EOPNOTSUPP},
+ {US"Address type not supported", EAFNOSUPPORT}
+ };
+
+typedef struct
+ {
+ const uschar * proxy_host;
+ uschar auth_type; /* RFC 1928 encoding */
+ const uschar * auth_name;
+ const uschar * auth_pwd;
+ short port;
+ BOOL is_failed;
+ unsigned timeout;
+ unsigned weight;
+ unsigned priority;
+ } socks_opts;
+
+static void
+socks_option_defaults(socks_opts * sob)
+{
+sob->proxy_host = NULL;
+sob->auth_type = AUTH_NONE;
+sob->auth_name = US"";
+sob->auth_pwd = US"";
+sob->is_failed = FALSE;
+sob->port = SOCKS_PORT;
+sob->timeout = SOCKS_TIMEOUT;
+sob->weight = SOCKS_WEIGHT;
+sob->priority = SOCKS_PRIORITY;
+}
+
+static void
+socks_option(socks_opts * sob, const uschar * opt)
+{
+const uschar * s;
+
+if (Ustrncmp(opt, "auth=", 5) == 0)
+ {
+ opt += 5;
+ if (Ustrcmp(opt, "none") == 0) sob->auth_type = AUTH_NONE;
+ else if (Ustrcmp(opt, "name") == 0) sob->auth_type = AUTH_NAME;
+ }
+else if (Ustrncmp(opt, "name=", 5) == 0)
+ sob->auth_name = opt + 5;
+else if (Ustrncmp(opt, "pass=", 5) == 0)
+ sob->auth_pwd = opt + 5;
+else if (Ustrncmp(opt, "port=", 5) == 0)
+ sob->port = atoi(opt + 5);
+else if (Ustrncmp(opt, "tmo=", 4) == 0)
+ sob->timeout = atoi(opt + 4);
+else if (Ustrncmp(opt, "pri=", 4) == 0)
+ sob->priority = atoi(opt + 4);
+else if (Ustrncmp(opt, "weight=", 7) == 0)
+ sob->weight = atoi(opt + 7);
+return;
+}
+
+static int
+socks_auth(int fd, int method, socks_opts * sob, time_t tmo)
+{
+uschar * s;
+int len, i, j;
+
+switch(method)
+ {
+ default:
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "Unrecognised socks auth method %d", method);
+ return FAIL;
+ case AUTH_NONE:
+ return OK;
+ case AUTH_NAME:
+ HDEBUG(D_transport|D_acl|D_v) debug_printf(" socks auth NAME '%s' '%s'\n",
+ sob->auth_name, sob->auth_pwd);
+ i = Ustrlen(sob->auth_name);
+ j = Ustrlen(sob->auth_pwd);
+ s = string_sprintf("%c%c%.255s%c%.255s", AUTH_NAME_VER,
+ i, sob->auth_name, j, sob->auth_pwd);
+ len = i + j + 3;
+ HDEBUG(D_transport|D_acl|D_v)
+ {
+ int i;
+ debug_printf(" SOCKS>>");
+ for (i = 0; i<len; i++) debug_printf(" %02x", s[i]);
+ debug_printf("\n");
+ }
+ if ( send(fd, s, len, 0) < 0
+ || !fd_ready(fd, tmo-time(NULL))
+ || read(fd, s, 2) != 2
+ )
+ return FAIL;
+ HDEBUG(D_transport|D_acl|D_v)
+ debug_printf(" SOCKS<< %02x %02x\n", s[0], s[1]);
+ if (s[0] == AUTH_NAME_VER && s[1] == 0)
+ {
+ HDEBUG(D_transport|D_acl|D_v) debug_printf(" socks auth OK\n");
+ return OK;
+ }
+
+ log_write(0, LOG_MAIN|LOG_PANIC, "socks auth failed");
+ errno = EPROTO;
+ return FAIL;
+ }
+}
+
+
+
+/* Find a suitable proxy to use from the list.
+Possible common code with spamd_get_server() ?
+
+Return: index into proxy spec array, or -1
+*/
+
+static int
+socks_get_proxy(socks_opts * proxies, unsigned nproxies)
+{
+unsigned int i;
+socks_opts * sd;
+socks_opts * lim = &proxies[nproxies];
+long rnd, weights;
+unsigned pri;
+static BOOL srandomed = FALSE;
+
+if (nproxies == 1) /* shortcut, if we have only 1 server */
+ return (proxies[0].is_failed ? -1 : 0);
+
+/* init random */
+if (!srandomed)
+ {
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ srandom((unsigned int)(tv.tv_usec/1000));
+ srandomed = TRUE;
+ }
+
+/* scan for highest pri */
+for (pri = 0, sd = proxies; sd < lim; sd++)
+ if (!sd->is_failed && sd->priority > pri)
+ pri = sd->priority;
+
+/* get sum of weights at this pri */
+for (weights = 0, sd = proxies; sd < lim; sd++)
+ if (!sd->is_failed && sd->priority == pri)
+ weights += sd->weight;
+if (weights == 0) /* all servers failed */
+ return -1;
+
+for (rnd = random() % weights, i = 0; i < nproxies; i++)
+ {
+ sd = &proxies[i];
+ if (!sd->is_failed && sd->priority == pri)
+ if ((rnd -= sd->weight) <= 0)
+ return i;
+ }
+
+log_write(0, LOG_MAIN|LOG_PANIC,
+ "%s unknown error (memory/cpu corruption?)", __FUNCTION__);
+return -1;
+}
+
+
+
+/* Make a connection via a socks proxy
+
+Arguments:
+ host smtp target host
+ host_af address family
+ port remote tcp port number
+ interface local interface
+ tb transport
+ timeout connection timeout (zero for indefinite)
+
+Return value:
+ 0 on success; -1 on failure, with errno set
+*/
+
+int
+socks_sock_connect(host_item * host, int host_af, int port, uschar * interface,
+ transport_instance * tb, int timeout)
+{
+smtp_transport_options_block * ob =
+ (smtp_transport_options_block *)tb->options_block;
+const uschar * proxy_list;
+const uschar * proxy_spec;
+int sep = 0;
+int fd;
+time_t tmo;
+const uschar * state;
+uschar buf[24];
+socks_opts proxies[32]; /* max #proxies handled */
+unsigned nproxies;
+socks_opts * sob;
+unsigned size;
+
+if (!timeout) timeout = 24*60*60; /* use 1 day for "indefinite" */
+tmo = time(NULL) + timeout;
+
+if (!(proxy_list = expand_string(ob->socks_proxy)))
+ {
+ log_write(0, LOG_MAIN|LOG_PANIC, "Bad expansion for socks_proxy in %s",
+ tb->name);
+ return -1;
+ }
+
+/* Read proxy list */
+
+for (nproxies = 0;
+ nproxies < nelem(proxies)
+ && (proxy_spec = string_nextinlist(&proxy_list, &sep, NULL, 0));
+ nproxies++)
+ {
+ int subsep = -' ';
+ const uschar * option;
+
+ socks_option_defaults(sob = &proxies[nproxies]);
+
+ if (!(sob->proxy_host = string_nextinlist(&proxy_spec, &subsep, NULL, 0)))
+ {
+ /* paniclog config error */
+ return -1;
+ }
+
+ /*XXX consider global options eg. "hide socks_password = wibble" on the tpt */
+ /* extract any further per-proxy options */
+ while ((option = string_nextinlist(&proxy_spec, &subsep, NULL, 0)))
+ socks_option(sob, option);
+ }
+
+/* Try proxies until a connection succeeds */
+
+for(;;)
+ {
+ int idx;
+ host_item proxy;
+ int proxy_af;
+
+ if ((idx = socks_get_proxy(proxies, nproxies)) < 0)
+ {
+ HDEBUG(D_transport|D_acl|D_v) debug_printf(" no proxies left\n");
+ errno = EBUSY;
+ return -1;
+ }
+ sob = &proxies[idx];
+
+ /* bodge up a host struct for the proxy */
+ proxy.address = sob->proxy_host;
+ proxy_af = Ustrchr(sob->proxy_host, ':') ? AF_INET6 : AF_INET;
+
+ if ((fd = smtp_sock_connect(&proxy, proxy_af, sob->port,
+ interface, tb, sob->timeout)) >= 0)
+ {
+ proxy_local_address = string_copy(proxy.address);
+ proxy_local_port = sob->port;
+ break;
+ }
+
+ log_write(0, LOG_MAIN, "%s: %s", __FUNCTION__, strerror(errno));
+ sob->is_failed = TRUE;
+ }
+
+/* Do the socks protocol stuff */
+/* Send method-selection */
+
+state = US"method select";
+HDEBUG(D_transport|D_acl|D_v) debug_printf(" SOCKS>> 05 01 %02x\n", sob->auth_type);
+buf[0] = 5; buf[1] = 1; buf[2] = sob->auth_type;
+if (send(fd, buf, 3, 0) < 0)
+ goto snd_err;
+
+/* expect method response */
+
+if ( !fd_ready(fd, tmo-time(NULL))
+ || read(fd, buf, 2) != 2
+ )
+ goto rcv_err;
+HDEBUG(D_transport|D_acl|D_v)
+ debug_printf(" SOCKS<< %02x %02x\n", buf[0], buf[1]);
+if ( buf[0] != 5
+ || socks_auth(fd, buf[1], sob, tmo) != OK
+ )
+ goto proxy_err;
+
+ {
+ union sockaddr_46 sin;
+ (void) ip_addr(&sin, host_af, host->address, port);
+
+ /* send connect (ipver, ipaddr, port) */
+
+ buf[0] = 5; buf[1] = 1; buf[2] = 0; buf[3] = host_af == AF_INET6 ? 4 : 1;
+ #if HAVE_IPV6
+ if (host_af == AF_INET6)
+ {
+ memcpy(buf+4, &sin.v6.sin6_addr, sizeof(sin.v6.sin6_addr));
+ memcpy(buf+4+sizeof(sin.v6.sin6_addr),
+ &sin.v6.sin6_port, sizeof(sin.v6.sin6_port));
+ size = 4+sizeof(sin.v6.sin6_addr)+sizeof(sin.v6.sin6_port);
+ }
+ else
+ #endif
+ {
+ memcpy(buf+4, &sin.v4.sin_addr.s_addr, sizeof(sin.v4.sin_addr.s_addr));
+ memcpy(buf+4+sizeof(sin.v4.sin_addr.s_addr),
+ &sin.v4.sin_port, sizeof(sin.v4.sin_port));
+ size = 4+sizeof(sin.v4.sin_addr.s_addr)+sizeof(sin.v4.sin_port);
+ }
+ }
+
+state = US"connect";
+HDEBUG(D_transport|D_acl|D_v)
+ {
+ int i;
+ debug_printf(" SOCKS>>");
+ for (i = 0; i<size; i++) debug_printf(" %02x", buf[i]);
+ debug_printf("\n");
+ }
+if (send(fd, buf, size, 0) < 0)
+ goto snd_err;
+
+/* expect conn-reply (success, local(ipver, addr, port))
+of same length as conn-request, or non-success fail code */
+
+if ( !fd_ready(fd, tmo-time(NULL))
+ || (size = read(fd, buf, size)) < 2
+ )
+ goto rcv_err;
+HDEBUG(D_transport|D_acl|D_v)
+ {
+ int i;
+ debug_printf(" SOCKS>>");
+ for (i = 0; i<size; i++) debug_printf(" %02x", buf[i]);
+ debug_printf("\n");
+ }
+if ( buf[0] != 5
+ || buf[1] != 0
+ )
+ goto proxy_err;
+
+proxy_external_address = string_copy(
+ host_ntoa(buf[3] == 4 ? AF_INET6 : AF_INET, buf+4, NULL, NULL));
+proxy_external_port = ntohs(*((uint16_t *)(buf + (buf[3] == 4 ? 20 : 8))));
+proxy_session = TRUE;
+
+HDEBUG(D_transport|D_acl|D_v)
+ debug_printf(" proxy farside: [%s]:%d\n", proxy_external_address, proxy_external_port);
+
+return fd;
+
+snd_err:
+ HDEBUG(D_transport|D_acl|D_v) debug_printf(" proxy snd_err %s: %s\n", state, strerror(errno));
+ return -1;
+
+proxy_err:
+ {
+ struct socks_err * se =
+ buf[1] > nelem(socks_errs) ? NULL : socks_errs + buf[1];
+ HDEBUG(D_transport|D_acl|D_v)
+ debug_printf(" proxy %s: %s\n", state, se ? se->reason : US"unknown error code received");
+ errno = se ? se->errcode : EPROTO;
+ }
+
+rcv_err:
+ HDEBUG(D_transport|D_acl|D_v) debug_printf(" proxy rcv_err %s: %s\n", state, strerror(errno));
+ if (!errno) errno = EPROTO;
+ else if (errno == ENOENT) errno = ECONNABORTED;
+ return -1;
+}
+
+#endif /* entire file */
+/* vi: aw ai sw=2
+*/
FALSE);
(void)gettimeofday(&tv, NULL);
- tempname = string_sprintf("%s/tmp/%lu.H%luP%lu.%s", path, tv.tv_sec,
- tv.tv_usec, (long unsigned) getpid(), primary_hostname);
+ tempname = string_sprintf("%s/tmp/" TIME_T_FMT ".H%luP%lu.%s",
+ path, tv.tv_sec, tv.tv_usec, (long unsigned) getpid(), primary_hostname);
fd = Uopen(tempname, O_RDWR|O_CREAT|O_EXCL, ob->mode ? ob->mode : 0600);
if (fd >= 0)
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Functions for maintaining binary balanced trees and some associated
*/
tree_node *
-tree_search(tree_node *p, uschar *name)
+tree_search(tree_node *p, const uschar *name)
{
while (p != NULL)
{
--- /dev/null
+/*************************************************
+* Exim - an Internet mail transport agent *
+*************************************************/
+
+/* Copyright (c) Jeremy Harris 2015 */
+/* See the file NOTICE for conditions of use and distribution. */
+
+
+#include "exim.h"
+
+#ifdef SUPPORT_I18N
+
+#include <idna.h>
+#include <punycode.h>
+#include <stringprep.h>
+
+BOOL
+string_is_utf8(const uschar * s)
+{
+uschar c;
+while ((c = *s++)) if (c & 0x80) return TRUE;
+return FALSE;
+}
+
+/**************************************************/
+/* Domain conversions */
+/* the *err string pointer should be null before the call */
+
+uschar *
+string_domain_utf8_to_alabel(const uschar * utf8, uschar ** err)
+{
+uschar * s1;
+uschar * s;
+int rc;
+
+s = US stringprep_utf8_nfkc_normalize(CCS utf8, -1);
+if ( (rc = idna_to_ascii_8z(CCS s, CSS &s1, IDNA_ALLOW_UNASSIGNED))
+ != IDNA_SUCCESS)
+ {
+ free(s);
+ if (err) *err = US idna_strerror(rc);
+ return NULL;
+ }
+free(s);
+s = string_copy(s1);
+free(s1);
+return s;
+}
+
+
+
+uschar *
+string_domain_alabel_to_utf8(const uschar * alabel, uschar ** err)
+{
+uschar * s1;
+uschar * s;
+int rc;
+
+if ( (rc = idna_to_unicode_8z8z(CCS alabel, CSS &s1, IDNA_USE_STD3_ASCII_RULES))
+ != IDNA_SUCCESS)
+ {
+ if (err) *err = US idna_strerror(rc);
+ return NULL;
+ }
+s = string_copy(s1);
+free(s1);
+return s;
+}
+
+/**************************************************/
+/* localpart conversions */
+/* the *err string pointer should be null before the call */
+
+
+uschar *
+string_localpart_utf8_to_alabel(const uschar * utf8, uschar ** err)
+{
+size_t ucs4_len;
+punycode_uint * p;
+size_t p_len;
+uschar * res;
+int rc;
+
+if (!string_is_utf8(utf8)) return string_copy(utf8);
+
+p = (punycode_uint *) stringprep_utf8_to_ucs4(CCS utf8, -1, &ucs4_len);
+p_len = ucs4_len*4; /* this multiplier is pure guesswork */
+res = store_get(p_len+5);
+
+res[0] = 'x'; res[1] = 'n'; res[2] = res[3] = '-';
+
+if ((rc = punycode_encode(ucs4_len, p, NULL, &p_len, CS res+4)) != PUNYCODE_SUCCESS)
+ {
+ DEBUG(D_expand) debug_printf("l_u2a: bad '%s'\n", punycode_strerror(rc));
+ free(p);
+ if (err) *err = US punycode_strerror(rc);
+ return NULL;
+ }
+p_len += 4;
+free(p);
+res[p_len] = '\0';
+return res;
+}
+
+
+uschar *
+string_localpart_alabel_to_utf8(const uschar * alabel, uschar ** err)
+{
+size_t p_len = Ustrlen(alabel);
+punycode_uint * p;
+uschar * s;
+uschar * res;
+int rc;
+
+if (alabel[0] != 'x' || alabel[1] != 'n' || alabel[2] != '-' || alabel[3] != '-')
+ {
+ if (err) *err = US"bad alabel prefix";
+ return NULL;
+ }
+
+p_len -= 4;
+p = (punycode_uint *) store_get((p_len+1) * sizeof(*p));
+
+if ((rc = punycode_decode(p_len, CCS alabel+4, &p_len, p, NULL)) != PUNYCODE_SUCCESS)
+ {
+ if (err) *err = US punycode_strerror(rc);
+ return NULL;
+ }
+
+s = US stringprep_ucs4_to_utf8(p, p_len, NULL, &p_len);
+res = string_copyn(s, p_len);
+free(s);
+return res;
+}
+
+
+/**************************************************/
+/* whole address conversion */
+/* the *err string pointer should be null before the call */
+
+uschar *
+string_address_utf8_to_alabel(const uschar * utf8, uschar ** err)
+{
+const uschar * s;
+uschar * l;
+uschar * d;
+
+if (!*utf8) return string_copy(utf8);
+
+DEBUG(D_expand) debug_printf("addr from utf8 <%s>", utf8);
+
+for (s = utf8; *s; s++)
+ if (*s == '@')
+ {
+ l = string_copyn(utf8, s - utf8);
+ if ( (l = string_localpart_utf8_to_alabel(l, err), err && *err)
+ || (d = string_domain_utf8_to_alabel(++s, err), err && *err)
+ )
+ return NULL;
+ l = string_sprintf("%s@%s", l, d);
+ DEBUG(D_expand) debug_printf(" -> <%s>\n", l);
+ return l;
+ }
+
+l = string_localpart_utf8_to_alabel(utf8, err);
+DEBUG(D_expand) debug_printf(" -> <%s>\n", l);
+return l;
+}
+
+
+
+/*************************************************
+* Report the library versions. *
+*************************************************/
+
+/* See a description in tls-openssl.c for an explanation of why this exists.
+
+Arguments: a FILE* to print the results to
+Returns: nothing
+*/
+
+void
+utf8_version_report(FILE *f)
+{
+fprintf(f, "Library version: IDN: Compile: %s\n"
+ " Runtime: %s\n",
+ STRINGPREP_VERSION,
+ stringprep_check_version(NULL));
+}
+
+#endif /* whole file */
+
+/* vi: aw ai sw=2
+*/
+/* End of utf8.c */
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- 2. The origin of this software must not be misrepresented; you must
- not claim that you wrote the original software. If you use this
- software in a product, an acknowledgment in the product
+ 2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
3. Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software.
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
+ 4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
the terms of the GNU General Public License, version 2. See the
COPYING file in the source distribution for details.
- ----------------------------------------------------------------
+ ----------------------------------------------------------------
*/
/* This file is for inclusion into client (your!) code.
- You can use these macros to manipulate and query Valgrind's
+ You can use these macros to manipulate and query Valgrind's
execution inside your own programs.
The resulting executables will still run without Valgrind, just a
this is executed not under Valgrind. Args are passed in a memory
block, and so there's no intrinsic limit to the number that could
be passed, but it's currently five.
-
- The macro args are:
+
+ The macro args are:
_zzq_rlval result lvalue
_zzq_default default value (result returned when running on real CPU)
_zzq_request request code
|| (defined(PLAT_x86_win32) && defined(__GNUC__))
typedef
- struct {
+ struct {
unsigned int nraddr; /* where's the code? */
}
OrigFn;
#if defined(PLAT_x86_win32) && !defined(__GNUC__)
typedef
- struct {
+ struct {
unsigned int nraddr; /* where's the code? */
}
OrigFn;
#if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin)
typedef
- struct {
+ struct {
unsigned long long int nraddr; /* where's the code? */
}
OrigFn;
#if defined(PLAT_ppc32_linux)
typedef
- struct {
+ struct {
unsigned int nraddr; /* where's the code? */
}
OrigFn;
#if defined(PLAT_ppc64_linux)
typedef
- struct {
+ struct {
unsigned long long int nraddr; /* where's the code? */
unsigned long long int r2; /* what tocptr do we need? */
}
#if defined(PLAT_arm_linux)
typedef
- struct {
+ struct {
unsigned int nraddr; /* where's the code? */
}
OrigFn;
#if defined(PLAT_ppc32_aix5)
typedef
- struct {
+ struct {
unsigned int nraddr; /* where's the code? */
unsigned int r2; /* what tocptr do we need? */
}
#if defined(PLAT_ppc64_aix5)
typedef
- struct {
+ struct {
unsigned long long int nraddr; /* where's the code? */
unsigned long long int r2; /* what tocptr do we need? */
}
"r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \
"r11", "r12", "r13"
-/* These CALL_FN_ macros assume that on ppc32-linux,
+/* These CALL_FN_ macros assume that on ppc32-linux,
sizeof(unsigned long) == 4. */
#define CALL_FN_W_v(lval, orig) \
#define VG_IS_TOOL_USERREQ(a, b, v) \
(VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000))
-/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
+/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
This enum comprises an ABI exported by Valgrind to programs
which use client requests. DO NOT CHANGE THE ORDER OF THESE
ENTRIES, NOR DELETE ANY -- add new ones at the end. */
VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,
VG_USERREQ__PRINTF_VALIST_BY_REF,
(unsigned long)format,
- (unsigned long)&vargs,
+ (unsigned long)&vargs,
0, 0, 0);
#endif
va_end(vargs);
VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,
VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF,
(unsigned long)format,
- (unsigned long)&vargs,
+ (unsigned long)&vargs,
0, 0, 0);
#endif
va_end(vargs);
/* These requests allow control to move from the simulated CPU to the
real CPU, calling an arbitary function.
-
+
Note that the current ThreadId is inserted as the first argument.
So this call:
- It marks the block as being addressable and undefined (if 'is_zeroed' is
not set), or addressable and defined (if 'is_zeroed' is set). This
controls how accesses to the block by the program are handled.
-
+
'addr' is the start of the usable block (ie. after any
redzone), 'sizeB' is its size. 'rzB' is the redzone size if the allocator
can apply redzones -- these are blocks of padding at the start and end of
Valgrind will spot block overruns. `is_zeroed' indicates if the memory is
zeroed (or filled with another predictable value), as is the case for
calloc().
-
+
VALGRIND_MALLOCLIKE_BLOCK should be put immediately after the point where a
heap block -- that will be used by the client program -- is allocated.
It's best to put it at the outermost level of the allocator if possible;
Note: there is currently no VALGRIND_REALLOCLIKE_BLOCK client request; it
has to be emulated with MALLOCLIKE/FREELIKE and memory copying.
-
+
Ignored if addr == 0.
*/
#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed) \
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Functions concerned with verifying things. The original code for callout
#define CUTTHROUGH_CMD_TIMEOUT 30 /* timeout for cutthrough-routing calls */
#define CUTTHROUGH_DATA_TIMEOUT 60 /* timeout for cutthrough-routing calls */
-address_item cutthrough_addr;
static smtp_outblock ctblock;
uschar ctbuffer[8192];
/* Structure for caching DNSBL lookups */
typedef struct dnsbl_cache_block {
+ time_t expiry;
dns_address *rhs;
uschar *text;
int rc;
#define MT_NOT 1
#define MT_ALL 2
+static uschar cutthrough_response(char, uschar **);
/*************************************************
*/
static dbdata_callout_cache *
-get_callout_cache_record(open_db *dbm_file, uschar *key, uschar *type,
+get_callout_cache_record(open_db *dbm_file, const uschar *key, uschar *type,
int positive_expire, int negative_expire)
{
BOOL negative;
if (cache_record == NULL)
{
- HDEBUG(D_verify) debug_printf("callout cache: no %s record found\n", type);
+ HDEBUG(D_verify) debug_printf("callout cache: no %s record found for %s\n", type, key);
return NULL;
}
if (now - cache_record->time_stamp > expire)
{
- HDEBUG(D_verify) debug_printf("callout cache: %s record expired\n", type);
+ HDEBUG(D_verify) debug_printf("callout cache: %s record expired for %s\n", type, key);
return NULL;
}
cache_record->random_result = ccache_unknown;
}
-HDEBUG(D_verify) debug_printf("callout cache: found %s record\n", type);
+HDEBUG(D_verify) debug_printf("callout cache: found %s record for %s\n", type, key);
return cache_record;
}
uschar *address_key;
uschar *from_address;
uschar *random_local_part = NULL;
-uschar *save_deliver_domain = deliver_domain;
+const uschar *save_deliver_domain = deliver_domain;
uschar **failure_ptr = is_recipient?
&recipient_verify_failure : &sender_verify_failure;
open_db dbblock;
dbdata_callout_cache_address new_address_record;
host_item *host;
time_t callout_start_time;
+#ifdef SUPPORT_I18N
+BOOL utf8_offered = FALSE;
+#endif
new_domain_record.result = ccache_unknown;
new_domain_record.postmaster_result = ccache_unknown;
if (is_recipient)
{
- if ((options & vopt_callout_recipsender) != 0)
+ if (options & vopt_callout_recipsender)
{
address_key = string_sprintf("%s/<%s>", addr->address, sender_address);
from_address = sender_address;
}
- else if ((options & vopt_callout_recippmaster) != 0)
+ else if (options & vopt_callout_recippmaster)
{
address_key = string_sprintf("%s/<postmaster@%s>", addr->address,
qualify_domain_sender);
log the fact, but carry on without randomming. */
if (callout_random && callout_random_local_part != NULL)
- {
- random_local_part = expand_string(callout_random_local_part);
- if (random_local_part == NULL)
+ if (!(random_local_part = expand_string(callout_random_local_part)))
log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand "
"callout_random_local_part: %s", expand_string_message);
- }
/* Default the connect and overall callout timeouts if not set, and record the
time we are starting so that we can enforce it. */
if (smtp_out != NULL && !disable_callout_flush) mac_smtp_fflush();
+/* cutthrough-multi: if a nonfirst rcpt has the same routing as the first,
+and we are holding a cutthrough conn open, we can just append the rcpt to
+that conn for verification purposes (and later delivery also). Simplest
+coding means skipping this whole loop and doing the append separately.
+
+We will need to remember it has been appended so that rcpt-acl tail code
+can do it there for the non-rcpt-verify case. For this we keep an addresscount.
+*/
+
+ /* Can we re-use an open cutthrough connection? */
+ if ( cutthrough.fd >= 0
+ && (options & (vopt_callout_recipsender | vopt_callout_recippmaster))
+ == vopt_callout_recipsender
+ && !random_local_part
+ && !pm_mailfrom
+ )
+ {
+ if (addr->transport == cutthrough.addr.transport)
+ for (host = host_list; host; host = host->next)
+ if (Ustrcmp(host->address, cutthrough.host.address) == 0)
+ {
+ int host_af;
+ uschar *interface = NULL; /* Outgoing interface to use; NULL => any */
+ int port = 25;
+
+ deliver_host = host->name;
+ deliver_host_address = host->address;
+ deliver_host_port = host->port;
+ deliver_domain = addr->domain;
+ transport_name = addr->transport->name;
+
+ host_af = (Ustrchr(host->address, ':') == NULL)? AF_INET:AF_INET6;
+
+ if (!smtp_get_interface(tf->interface, host_af, addr, &interface,
+ US"callout") ||
+ !smtp_get_port(tf->port, addr, &port, US"callout"))
+ log_write(0, LOG_MAIN|LOG_PANIC, "<%s>: %s", addr->address,
+ addr->message);
+
+ if ( ( interface == cutthrough.interface
+ || ( interface
+ && cutthrough.interface
+ && Ustrcmp(interface, cutthrough.interface) == 0
+ ) )
+ && port == cutthrough.host.port
+ )
+ {
+ uschar * resp;
+
+ /* Match! Send the RCPT TO, append the addr, set done */
+ done =
+ smtp_write_command(&ctblock, FALSE, "RCPT TO:<%.1000s>\r\n",
+ transport_rcpt_address(addr,
+ (addr->transport == NULL)? FALSE :
+ addr->transport->rcpt_include_affixes)) >= 0 &&
+ cutthrough_response('2', &resp) == '2';
+
+ /* This would go horribly wrong if a callout fail was ignored by ACL.
+ We punt by abandoning cutthrough on a reject, like the
+ first-rcpt does. */
+
+ if (done)
+ {
+ address_item * na = store_get(sizeof(address_item));
+ *na = cutthrough.addr;
+ cutthrough.addr = *addr;
+ cutthrough.addr.host_used = &cutthrough.host;
+ cutthrough.addr.next = na;
+
+ cutthrough.nrcpt++;
+ }
+ else
+ {
+ cancel_cutthrough_connection("recipient rejected");
+ if (errno == ETIMEDOUT)
+ {
+ HDEBUG(D_verify) debug_printf("SMTP timeout\n");
+ }
+ else if (errno == 0)
+ {
+ if (*resp == 0)
+ Ustrcpy(resp, US"connection dropped");
+
+ addr->message =
+ string_sprintf("response to \"%s\" from %s [%s] was: %s",
+ big_buffer, host->name, host->address,
+ string_printing(resp));
+
+ addr->user_message =
+ string_sprintf("Callout verification failed:\n%s", resp);
+
+ /* Hard rejection ends the process */
+
+ if (resp[0] == '5') /* Address rejected */
+ {
+ yield = FAIL;
+ done = TRUE;
+ }
+ }
+ }
+ }
+ break;
+ }
+ if (!done)
+ cancel_cutthrough_connection("incompatible connection");
+ }
+
/* Now make connections to the hosts and do real callouts. The list of hosts
is passed in as an argument. */
uschar *interface = NULL; /* Outgoing interface to use; NULL => any */
#if defined(SUPPORT_TLS) && defined(EXPERIMENTAL_DANE)
BOOL dane = FALSE;
+ BOOL dane_required;
dns_answer tlsa_dnsa;
#endif
uschar inbuffer[4096];
deliver_domain = addr->domain;
transport_name = addr->transport->name;
- if (!smtp_get_interface(tf->interface, host_af, addr, NULL, &interface,
- US"callout") ||
- !smtp_get_port(tf->port, addr, &port, US"callout"))
+ if ( !smtp_get_interface(tf->interface, host_af, addr, &interface,
+ US"callout")
+ || !smtp_get_port(tf->port, addr, &port, US"callout")
+ )
log_write(0, LOG_MAIN|LOG_PANIC, "<%s>: %s", addr->address,
addr->message);
HDEBUG(D_verify) debug_printf("interface=%s port=%d\n", interface, port);
-#if defined(SUPPORT_TLS) && defined(EXPERIMENTAL_DANE)
- {
- BOOL dane_required;
- int rc;
-
- tls_out.dane_verified = FALSE;
- tls_out.tlsa_usage = 0;
-
- dane_required =
- verify_check_given_host(&ob->hosts_require_dane, host) == OK;
-
- if (host->dnssec == DS_YES)
- {
- if( dane_required
- || verify_check_given_host(&ob->hosts_try_dane, host) == OK
- )
- if ((rc = tlsa_lookup(host, &tlsa_dnsa, dane_required, &dane)) != OK)
- return rc;
- }
- else if (dane_required)
- {
- log_write(0, LOG_MAIN, "DANE error: %s lookup not DNSSEC", host->name);
- return FAIL;
- }
-
- if (dane)
- ob->tls_tempfail_tryclear = FALSE;
- }
-#endif /*DANE*/
-
/* Set up the buffer for reading SMTP response packets. */
inblock.buffer = inbuffer;
outblock.cmd_count = 0;
outblock.authenticating = FALSE;
- /* Reset the parameters of a TLS session */
- tls_out.cipher = tls_out.peerdn = NULL;
-
/* Connect to the host; on failure, just loop for the next one, but we
set the error for the last one. Use the callout_connect timeout. */
tls_retry_connection:
+ /* Reset the parameters of a TLS session */
+ tls_out.cipher = tls_out.peerdn = tls_out.peercert = NULL;
+
inblock.sock = outblock.sock =
- smtp_connect(host, host_af, port, interface, callout_connect, TRUE, NULL
-#ifdef EXPERIMENTAL_EVENT
- /*XXX event action? NULL for now. */
- , NULL
-#endif
- );
- /* reconsider DSCP here */
+ smtp_connect(host, host_af, port, interface, callout_connect,
+ addr->transport);
if (inblock.sock < 0)
{
addr->message = string_sprintf("could not connect to %s [%s]: %s",
continue;
}
+#if defined(SUPPORT_TLS) && defined(EXPERIMENTAL_DANE)
+ {
+ int rc;
+
+ tls_out.dane_verified = FALSE;
+ tls_out.tlsa_usage = 0;
+
+ dane_required =
+ verify_check_given_host(&ob->hosts_require_dane, host) == OK;
+
+ if (host->dnssec == DS_YES)
+ {
+ if( ( dane_required
+ || verify_check_given_host(&ob->hosts_try_dane, host) == OK
+ )
+ && (rc = tlsa_lookup(host, &tlsa_dnsa, dane_required, &dane)) != OK
+ )
+ return rc;
+ }
+ else if (dane_required)
+ {
+ log_write(0, LOG_MAIN, "DANE error: %s lookup not DNSSEC", host->name);
+ return FAIL;
+ }
+
+ if (dane)
+ ob->tls_tempfail_tryclear = FALSE;
+ }
+#endif /*DANE*/
+
/* Expand the helo_data string to find the host name to use. */
if (tf->helo_data != NULL)
if (!(done= smtp_read_response(&inblock, responsebuffer, sizeof(responsebuffer), '2', callout)))
goto RESPONSE_FAILED;
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
lookup_dnssec_authenticated = host->dnssec==DS_YES ? US"yes"
: host->dnssec==DS_NO ? US"no" : NULL;
if (event_raise(addr->transport->event_action,
}
/* Not worth checking greeting line for ESMTP support */
- if (!(esmtp = verify_check_given_host(&(ob->hosts_avoid_esmtp), host) != OK))
+ if (!(esmtp = verify_check_given_host(&ob->hosts_avoid_esmtp, host) != OK))
DEBUG(D_transport)
debug_printf("not sending EHLO (host matches hosts_avoid_esmtp)\n");
int oldtimeout = ob->command_timeout;
int rc;
+ tls_negotiate:
ob->command_timeout = callout;
rc = tls_client_start(inblock.sock, host, addr, addr->transport
-#ifdef EXPERIMENTAL_DANE
+# ifdef EXPERIMENTAL_DANE
, dane ? &tlsa_dnsa : NULL
-#endif
+# endif
);
ob->command_timeout = oldtimeout;
- /* TLS negotiation failed; give an error. Try in clear on a new connection,
- if the options permit it for this host. */
+ /* TLS negotiation failed; give an error. Try in clear on a new
+ connection, if the options permit it for this host. */
if (rc != OK)
{
- if ( rc == DEFER
- && ob->tls_tempfail_tryclear
- && !smtps
- && verify_check_given_host(&ob->hosts_require_tls, host) != OK
- )
+ if (rc == DEFER)
{
(void)close(inblock.sock);
-#ifdef EXPERIMENTAL_EVENT
+# ifndef DISABLE_EVENT
(void) event_raise(addr->transport->event_action,
US"tcp:close", NULL);
-#endif
- log_write(0, LOG_MAIN, "TLS session failure: delivering unencrypted "
- "to %s [%s] (not in hosts_require_tls)", host->name, host->address);
- suppress_tls = TRUE;
- goto tls_retry_connection;
+# endif
+# ifdef EXPERIMENTAL_DANE
+ if (dane)
+ {
+ if (!dane_required)
+ {
+ log_write(0, LOG_MAIN, "DANE attempt failed;"
+ " trying CA-root TLS to %s [%s] (not in hosts_require_dane)",
+ host->name, host->address);
+ dane = FALSE;
+ goto tls_negotiate;
+ }
+ }
+ else
+# endif
+ if ( ob->tls_tempfail_tryclear
+ && !smtps
+ && verify_check_given_host(&ob->hosts_require_tls, host) != OK
+ )
+ {
+ log_write(0, LOG_MAIN, "TLS session failure:"
+ " delivering unencrypted to %s [%s] (not in hosts_require_tls)",
+ host->name, host->address);
+ suppress_tls = TRUE;
+ goto tls_retry_connection;
+ }
}
+
/*save_errno = ERRNO_TLSFAILURE;*/
/*message = US"failure while setting up TLS session";*/
send_quit = FALSE;
/* If the host is required to use a secure channel, ensure that we have one. */
if (tls_out.active < 0)
if (
-#ifdef EXPERIMENTAL_DANE
+# ifdef EXPERIMENTAL_DANE
dane ||
-#endif
+# endif
verify_check_given_host(&ob->hosts_require_tls, host) == OK
)
{
goto TLS_FAILED;
}
- #endif /*SUPPORT_TLS*/
+#endif /*SUPPORT_TLS*/
done = TRUE; /* so far so good; have response to HELO */
/* For now, transport_filter by cutthrough-delivery is not supported */
/* Need proper integration with the proper transport mechanism. */
- if (cutthrough_delivery)
+ if (cutthrough.delivery)
{
if (addr->transport->filter_command)
{
- cutthrough_delivery= FALSE;
+ cutthrough.delivery = FALSE;
HDEBUG(D_acl|D_v) debug_printf("Cutthrough cancelled by presence of transport filter\n");
}
#ifndef DISABLE_DKIM
if (ob->dkim_domain)
{
- cutthrough_delivery= FALSE;
+ cutthrough.delivery = FALSE;
HDEBUG(D_acl|D_v) debug_printf("Cutthrough cancelled by presence of DKIM signing\n");
}
#endif
}
}
+#ifdef SUPPORT_I18N
+ else if ( addr->prop.utf8_msg
+ && !addr->prop.utf8_downcvt
+ && !( esmtp
+ && ( regex_UTF8
+ || ( (regex_UTF8 = regex_must_compile(
+ US"\\n250[\\s\\-]SMTPUTF8(\\s|\\n|$)", FALSE, TRUE)),
+ TRUE
+ ) )
+ && ( (utf8_offered = pcre_exec(regex_UTF8, NULL,
+ CS responsebuffer, Ustrlen(responsebuffer),
+ 0, PCRE_EOPT, NULL, 0) >= 0)
+ || addr->prop.utf8_downcvt_maybe
+ ) ) )
+ {
+ HDEBUG(D_acl|D_v) debug_printf("utf8 required but not offered\n");
+ errno = ERRNO_UTF8_FWD;
+ setflag(addr, af_verify_nsfail);
+ done = FALSE;
+ }
+ else if ( addr->prop.utf8_msg
+ && (addr->prop.utf8_downcvt || !utf8_offered)
+ && (setflag(addr, af_utf8_downcvt),
+ from_address = string_address_utf8_to_alabel(from_address,
+ &addr->message),
+ addr->message
+ ) )
+ {
+ errno = ERRNO_EXPANDFAIL;
+ setflag(addr, af_verify_nsfail);
+ done = FALSE;
+ }
+#endif
+
/* If we haven't authenticated, but are required to, give up. */
/* Try to AUTH */
( (addr->auth_sndr = client_authenticated_sender),
/* Send the MAIL command */
- (smtp_write_command(&outblock, FALSE, "MAIL FROM:<%s>%s\r\n",
+ (smtp_write_command(&outblock, FALSE,
+#ifdef SUPPORT_I18N
+ addr->prop.utf8_msg && !addr->prop.utf8_downcvt
+ ? "MAIL FROM:<%s>%s SMTPUTF8\r\n"
+ :
+#endif
+ "MAIL FROM:<%s>%s\r\n",
from_address, responsebuffer) >= 0)
) &&
else
{
+ const uschar * rcpt_domain = addr->domain;
+
+#ifdef SUPPORT_I18N
+ uschar * errstr = NULL;
+ if ( testflag(addr, af_utf8_downcvt)
+ && (rcpt_domain = string_domain_utf8_to_alabel(rcpt_domain,
+ &errstr), errstr)
+ )
+ {
+ addr->message = errstr;
+ errno = ERRNO_EXPANDFAIL;
+ setflag(addr, af_verify_nsfail);
+ done = FALSE;
+ rcpt_domain = US""; /*XXX errorhandling! */
+ }
+#endif
+
new_domain_record.result =
(old_domain_cache_result == ccache_reject_mfnull)?
ccache_reject_mfnull: ccache_accept;
BOOL random_ok =
smtp_write_command(&outblock, FALSE,
"RCPT TO:<%.1000s@%.1000s>\r\n", random_local_part,
- addr->domain) >= 0 &&
+ rcpt_domain) >= 0 &&
smtp_read_response(&inblock, randombuffer,
sizeof(randombuffer), '2', callout);
/* Otherwise, cache a real negative response, and get back to the right
state to send RCPT. Unless there's some problem such as a dropped
- connection, we expect to succeed, because the commands succeeded above. */
+ connection, we expect to succeed, because the commands succeeded above.
+ However, some servers drop the connection after responding to an
+ invalid recipient, so on (any) error we drop and remake the connection.
+ */
else if (errno == 0)
{
+ /* This would be ok for 1st rcpt a cutthrough, but no way to
+ handle a subsequent. So refuse to support any */
+ cancel_cutthrough_connection("random-recipient");
+
if (randombuffer[0] == '5')
new_domain_record.random_result = ccache_reject;
smtp_read_response(&inblock, responsebuffer, sizeof(responsebuffer),
'2', callout) &&
- smtp_write_command(&outblock, FALSE, "MAIL FROM:<%s>\r\n",
+ smtp_write_command(&outblock, FALSE,
+#ifdef SUPPORT_I18N
+ addr->prop.utf8_msg && !addr->prop.utf8_downcvt
+ ? "MAIL FROM:<%s> SMTPUTF8\r\n"
+ :
+#endif
+ "MAIL FROM:<%s>\r\n",
from_address) >= 0 &&
smtp_read_response(&inblock, responsebuffer, sizeof(responsebuffer),
'2', callout);
+
+ if (!done)
+ {
+ HDEBUG(D_acl|D_v)
+ debug_printf("problem after random/rset/mfrom; reopen conn\n");
+ random_local_part = NULL;
+#ifdef SUPPORT_TLS
+ tls_close(FALSE, TRUE);
+#endif
+ (void)close(inblock.sock);
+#ifndef DISABLE_EVENT
+ (void) event_raise(addr->transport->event_action,
+ US"tcp:close", NULL);
+#endif
+ goto tls_retry_connection;
+ }
}
else done = FALSE; /* Some timeout/connection problem */
} /* Random check */
/* Get the rcpt_include_affixes flag from the transport if there is one,
but assume FALSE if there is not. */
+ uschar * rcpt = transport_rcpt_address(addr,
+ addr->transport ? addr->transport->rcpt_include_affixes : FALSE);
+
+#ifdef SUPPORT_I18N
+ /*XXX should the conversion be moved into transport_rcpt_address() ? */
+ uschar * dummy_errstr = NULL;
+ if ( testflag(addr, af_utf8_downcvt)
+ && (rcpt = string_address_utf8_to_alabel(rcpt, &dummy_errstr),
+ dummy_errstr
+ ) )
+ {
+ errno = ERRNO_EXPANDFAIL;
+ *failure_ptr = US"recipient";
+ done = FALSE;
+ }
+ else
+#endif
+
done =
smtp_write_command(&outblock, FALSE, "RCPT TO:<%.1000s>\r\n",
- transport_rcpt_address(addr,
- (addr->transport == NULL)? FALSE :
- addr->transport->rcpt_include_affixes)) >= 0 &&
+ rcpt) >= 0 &&
smtp_read_response(&inblock, responsebuffer, sizeof(responsebuffer),
'2', callout);
if (done && pm_mailfrom != NULL)
{
- /*XXX not suitable for cutthrough - sequencing problems */
- cutthrough_delivery= FALSE;
+ /* Could possibly shift before main verify, just above, and be ok
+ for cutthrough. But no way to handle a subsequent rcpt, so just
+ refuse any */
+ cancel_cutthrough_connection("postmaster verify");
HDEBUG(D_acl|D_v) debug_printf("Cutthrough cancelled by presence of postmaster verify\n");
done =
((
smtp_write_command(&outblock, FALSE,
- "RCPT TO:<postmaster@%.1000s>\r\n", addr->domain) >= 0 &&
+ "RCPT TO:<postmaster@%.1000s>\r\n", rcpt_domain) >= 0 &&
smtp_read_response(&inblock, responsebuffer,
sizeof(responsebuffer), '2', callout)
)
HDEBUG(D_verify) debug_printf("SMTP timeout\n");
send_quit = FALSE;
}
+#ifdef SUPPORT_I18N
+ else if (errno == ERRNO_UTF8_FWD)
+ {
+ extern int acl_where; /* src/acl.c */
+ errno = 0;
+ addr->message = string_sprintf(
+ "response to \"%s\" from %s [%s] did not include SMTPUTF8",
+ big_buffer, host->name, host->address);
+ addr->user_message = acl_where == ACL_WHERE_RCPT
+ ? US"533 mailbox name not allowed"
+ : US"550 mailbox unavailable";
+ yield = FAIL;
+ done = TRUE;
+ }
+#endif
else if (errno == 0)
{
if (*responsebuffer == 0) Ustrcpy(responsebuffer, US"connection dropped");
/* End the SMTP conversation and close the connection. */
- /* Cutthrough - on a successfull connect and recipient-verify with use-sender
- and we have no cutthrough conn so far
+ /* Cutthrough - on a successfull connect and recipient-verify with
+ use-sender and we are 1st rcpt and have no cutthrough conn so far
here is where we want to leave the conn open */
- if ( cutthrough_delivery
+ if ( cutthrough.delivery
+ && rcpt_count == 1
&& done
&& yield == OK
&& (options & (vopt_callout_recipsender|vopt_callout_recippmaster)) == vopt_callout_recipsender
&& !random_local_part
&& !pm_mailfrom
- && cutthrough_fd < 0
+ && cutthrough.fd < 0
+ && !lmtp
)
{
- cutthrough_fd= outblock.sock; /* We assume no buffer in use in the outblock */
- cutthrough_addr = *addr; /* Save the address_item for later logging */
- cutthrough_addr.next = NULL;
- cutthrough_addr.host_used = store_get(sizeof(host_item));
- *(cutthrough_addr.host_used) = *host;
+ cutthrough.fd = outblock.sock; /* We assume no buffer in use in the outblock */
+ cutthrough.nrcpt = 1;
+ cutthrough.interface = interface;
+ cutthrough.host = *host;
+ cutthrough.addr = *addr; /* Save the address_item for later logging */
+ cutthrough.addr.next = NULL;
+ cutthrough.addr.host_used = &cutthrough.host;
if (addr->parent)
- *(cutthrough_addr.parent = store_get(sizeof(address_item)))= *addr->parent;
+ *(cutthrough.addr.parent = store_get(sizeof(address_item))) =
+ *addr->parent;
ctblock.buffer = ctbuffer;
ctblock.buffersize = sizeof(ctbuffer);
ctblock.ptr = ctbuffer;
/* ctblock.cmd_count = 0; ctblock.authenticating = FALSE; */
- ctblock.sock = cutthrough_fd;
+ ctblock.sock = cutthrough.fd;
}
else
{
tls_close(FALSE, TRUE);
#endif
(void)close(inblock.sock);
-#ifdef EXPERIMENTAL_EVENT
- (void) event_raise(addr->transport->event_action,
- US"tcp:close", NULL);
+#ifndef DISABLE_EVENT
+ (void) event_raise(addr->transport->event_action, US"tcp:close", NULL);
#endif
}
get rewritten. */
addr2 = *addr;
-HDEBUG(D_acl) debug_printf("----------- start cutthrough setup ------------\n");
+HDEBUG(D_acl) debug_printf("----------- %s cutthrough setup ------------\n",
+ rcpt_count > 1 ? "more" : "start");
(void) verify_address(&addr2, NULL,
vopt_is_recipient | vopt_callout_recipsender | vopt_callout_no_cache,
CUTTHROUGH_CMD_TIMEOUT, -1, -1,
static BOOL
cutthrough_send(int n)
{
-if(cutthrough_fd < 0)
+if(cutthrough.fd < 0)
return TRUE;
if(
#ifdef SUPPORT_TLS
- (tls_out.active == cutthrough_fd) ? tls_write(FALSE, ctblock.buffer, n) :
+ (tls_out.active == cutthrough.fd) ? tls_write(FALSE, ctblock.buffer, n) :
#endif
- send(cutthrough_fd, ctblock.buffer, n, 0) > 0
+ send(cutthrough.fd, ctblock.buffer, n, 0) > 0
)
{
transport_count += n;
BOOL
cutthrough_puts(uschar * cp, int n)
{
-if (cutthrough_fd < 0) return TRUE;
+if (cutthrough.fd < 0) return TRUE;
if (_cutthrough_puts(cp, n)) return TRUE;
cancel_cutthrough_connection("transmit failed");
return FALSE;
static BOOL
-_cutthrough_flush_send( void )
+_cutthrough_flush_send(void)
{
int n= ctblock.ptr-ctblock.buffer;
/* Send out any bufferred output. Return boolean success. */
BOOL
-cutthrough_flush_send( void )
+cutthrough_flush_send(void)
{
if (_cutthrough_flush_send()) return TRUE;
cancel_cutthrough_connection("transmit failed");
BOOL
-cutthrough_put_nl( void )
+cutthrough_put_nl(void)
{
return cutthrough_puts(US"\r\n", 2);
}
inblock.buffersize = sizeof(inbuffer);
inblock.ptr = inbuffer;
inblock.ptrend = inbuffer;
-inblock.sock = cutthrough_fd;
+inblock.sock = cutthrough.fd;
/* this relies on (inblock.sock == tls_out.active) */
if(!smtp_read_response(&inblock, responsebuffer, sizeof(responsebuffer), expect, CUTTHROUGH_DATA_TIMEOUT))
cancel_cutthrough_connection("target timeout on read");
if(copy != NULL)
{
uschar * cp;
- *copy= cp= string_copy(responsebuffer);
+ *copy = cp = string_copy(responsebuffer);
/* Trim the trailing end of line */
cp += Ustrlen(responsebuffer);
if(cp > *copy && cp[-1] == '\n') *--cp = '\0';
/* Negotiate dataphase with the cutthrough target, returning success boolean */
BOOL
-cutthrough_predata( void )
+cutthrough_predata(void)
{
-if(cutthrough_fd < 0)
+if(cutthrough.fd < 0)
return FALSE;
HDEBUG(D_transport|D_acl|D_v) debug_printf(" SMTP>> DATA\n");
/* Expands newlines to wire format (CR,NL). */
/* Also sends header-terminating blank line. */
BOOL
-cutthrough_headers_send( void )
+cutthrough_headers_send(void)
{
-if(cutthrough_fd < 0)
+if(cutthrough.fd < 0)
return FALSE;
/* We share a routine with the mainline transport to handle header add/remove/rewrites,
*/
HDEBUG(D_acl) debug_printf("----------- start cutthrough headers send -----------\n");
-if (!transport_headers_send(&cutthrough_addr, cutthrough_fd,
- cutthrough_addr.transport->add_headers, cutthrough_addr.transport->remove_headers,
+if (!transport_headers_send(&cutthrough.addr, cutthrough.fd,
+ cutthrough.addr.transport->add_headers,
+ cutthrough.addr.transport->remove_headers,
&cutthrough_write_chunk, TRUE,
- cutthrough_addr.transport->rewrite_rules, cutthrough_addr.transport->rewrite_existflags))
+ cutthrough.addr.transport->rewrite_rules,
+ cutthrough.addr.transport->rewrite_existflags))
return FALSE;
HDEBUG(D_acl) debug_printf("----------- done cutthrough headers send ------------\n");
static void
-close_cutthrough_connection( const char * why )
+close_cutthrough_connection(const char * why)
{
-if(cutthrough_fd >= 0)
+if(cutthrough.fd >= 0)
{
/* We could be sending this after a bunch of data, but that is ok as
the only way to cancel the transfer in dataphase is to drop the tcp
#ifdef SUPPORT_TLS
tls_close(FALSE, TRUE);
#endif
- (void)close(cutthrough_fd);
- cutthrough_fd= -1;
+ (void)close(cutthrough.fd);
+ cutthrough.fd = -1;
HDEBUG(D_acl) debug_printf("----------- cutthrough shutdown (%s) ------------\n", why);
}
ctblock.ptr = ctbuffer;
}
void
-cancel_cutthrough_connection( const char * why )
+cancel_cutthrough_connection(const char * why)
{
close_cutthrough_connection(why);
-cutthrough_delivery= FALSE;
+cutthrough.delivery = FALSE;
}
Return smtp response-class digit.
*/
uschar *
-cutthrough_finaldot( void )
+cutthrough_finaldot(void)
{
+uschar res;
+address_item * addr;
HDEBUG(D_transport|D_acl|D_v) debug_printf(" SMTP>> .\n");
/* Assume data finshed with new-line */
-if(!cutthrough_puts(US".", 1) || !cutthrough_put_nl() || !cutthrough_flush_send())
- return cutthrough_addr.message;
+if( !cutthrough_puts(US".", 1)
+ || !cutthrough_put_nl()
+ || !cutthrough_flush_send()
+ )
+ return cutthrough.addr.message;
-switch(cutthrough_response('2', &cutthrough_addr.message))
+res = cutthrough_response('2', &cutthrough.addr.message);
+for (addr = &cutthrough.addr; addr; addr = addr->next)
{
- case '2':
- delivery_log(LOG_MAIN, &cutthrough_addr, (int)'>', NULL);
- close_cutthrough_connection("delivered");
- break;
+ addr->message = cutthrough.addr.message;
+ switch(res)
+ {
+ case '2':
+ delivery_log(LOG_MAIN, addr, (int)'>', NULL);
+ close_cutthrough_connection("delivered");
+ break;
- case '4':
- delivery_log(LOG_MAIN, &cutthrough_addr, 0, US"tmp-reject from cutthrough after DATA:");
- break;
+ case '4':
+ delivery_log(LOG_MAIN, addr, 0,
+ US"tmp-reject from cutthrough after DATA:");
+ break;
- case '5':
- delivery_log(LOG_MAIN|LOG_REJECT, &cutthrough_addr, 0, US"rejected after DATA:");
- break;
+ case '5':
+ delivery_log(LOG_MAIN|LOG_REJECT, addr, 0,
+ US"rejected after DATA:");
+ break;
- default:
- break;
+ default:
+ break;
+ }
}
- return cutthrough_addr.message;
+return cutthrough.addr.message;
}
vaddr->user_message = addr->user_message;
vaddr->basic_errno = addr->basic_errno;
vaddr->more_errno = addr->more_errno;
- vaddr->p.address_data = addr->p.address_data;
+ vaddr->prop.address_data = addr->prop.address_data;
copyflag(vaddr, addr, af_pass_message);
}
return yield;
/* Just in case some router parameter refers to it. */
- return_path = (addr->p.errors_address != NULL)?
- addr->p.errors_address : sender_address;
+ return_path = (addr->prop.errors_address != NULL)?
+ addr->prop.errors_address : sender_address;
/* Split the address into domain and local part, handling the %-hack if
necessary, and then route it. While routing a sender address, set
if (callout > 0)
{
host_item *host_list = addr->host_list;
+ transport_instance * tp;
/* Make up some data for use in the case where there is no remote
transport. */
transport's options, so as to mimic what would happen if we were really
sending a message to this address. */
- if (addr->transport != NULL && !addr->transport->info->local)
+ if ((tp = addr->transport) && !tp->info->local)
{
- (void)(addr->transport->setup)(addr->transport, addr, &tf, 0, 0, NULL);
+ (void)(tp->setup)(tp, addr, &tf, 0, 0, NULL);
/* If the transport has hosts and the router does not, or if the
transport is configured to override the router's hosts, we must build a
if (tf.hosts != NULL && (host_list == NULL || tf.hosts_override))
{
uschar *s;
- uschar *save_deliver_domain = deliver_domain;
+ const uschar *save_deliver_domain = deliver_domain;
uschar *save_deliver_localpart = deliver_localpart;
host_list = NULL; /* Ignore the router's hosts */
{
log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand list of hosts "
"\"%s\" in %s transport for callout: %s", tf.hosts,
- addr->transport->name, expand_string_message);
+ tp->name, expand_string_message);
}
else
{
int flags;
- uschar *canonical_name;
host_item *host, *nexthost;
host_build_hostlist(&host_list, s, tf.hosts_randomize);
nexthost = host->next;
if (tf.gethostbyname ||
string_is_ip_address(host->name, NULL) != 0)
- (void)host_find_byname(host, NULL, flags, &canonical_name, TRUE);
+ (void)host_find_byname(host, NULL, flags, NULL, TRUE);
else
{
- uschar * d_request = NULL, * d_require = NULL;
- if (Ustrcmp(addr->transport->driver_name, "smtp") == 0)
+ dnssec_domains * dnssec_domains = NULL;
+ if (Ustrcmp(tp->driver_name, "smtp") == 0)
{
smtp_transport_options_block * ob =
- (smtp_transport_options_block *)
- addr->transport->options_block;
- d_request = ob->dnssec_request_domains;
- d_require = ob->dnssec_require_domains;
+ (smtp_transport_options_block *) tp->options_block;
+ dnssec_domains = &ob->dnssec;
}
(void)host_find_bydns(host, NULL, flags, NULL, NULL, NULL,
- d_request, d_require, &canonical_name, NULL);
+ dnssec_domains, NULL, NULL);
}
}
}
/* If we have carried on to verify a child address, we want the value
of $address_data to be that of the child */
- vaddr->p.address_data = addr->p.address_data;
+ vaddr->prop.address_data = addr->prop.address_data;
yield = OK;
goto out;
}
}
for (addr_list = addr_local, i = 0; i < 2; addr_list = addr_remote, i++)
- {
- while (addr_list != NULL)
+ while (addr_list)
{
address_item *addr = addr_list;
address_item *p = addr->parent;
+ transport_instance * tp = addr->transport;
+
addr_list = addr->next;
fprintf(f, "%s", CS addr->address);
#ifdef EXPERIMENTAL_SRS
- if(addr->p.srs_sender)
- fprintf(f, " [srs = %s]", addr->p.srs_sender);
+ if(addr->prop.srs_sender)
+ fprintf(f, " [srs = %s]", addr->prop.srs_sender);
#endif
/* If the address is a duplicate, show something about it. */
if (!testflag(addr, af_pfr))
{
tree_node *tnode;
- if ((tnode = tree_search(tree_duplicates, addr->unique)) != NULL)
+ if ((tnode = tree_search(tree_duplicates, addr->unique)))
fprintf(f, " [duplicate, would not be delivered]");
else tree_add_duplicate(addr->unique, addr);
}
/* Now show its parents */
- while (p != NULL)
- {
+ for (p = addr->parent; p; p = p->parent)
fprintf(f, "\n <-- %s", p->address);
- p = p->parent;
- }
fprintf(f, "\n ");
/* Show router, and transport */
- fprintf(f, "router = %s, ", addr->router->name);
- fprintf(f, "transport = %s\n", (addr->transport == NULL)? US"unset" :
- addr->transport->name);
+ fprintf(f, "router = %s, transport = %s\n",
+ addr->router->name, tp ? tp->name : US"unset");
/* Show any hosts that are set up by a router unless the transport
is going to override them; fiddle a bit to get a nice format. */
- if (addr->host_list != NULL && addr->transport != NULL &&
- !addr->transport->overrides_hosts)
+ if (addr->host_list && tp && !tp->overrides_hosts)
{
host_item *h;
int maxlen = 0;
int maxaddlen = 0;
- for (h = addr->host_list; h != NULL; h = h->next)
- {
+ for (h = addr->host_list; h; h = h->next)
+ { /* get max lengths of host names, addrs */
int len = Ustrlen(h->name);
if (len > maxlen) maxlen = len;
- len = (h->address != NULL)? Ustrlen(h->address) : 7;
+ len = h->address ? Ustrlen(h->address) : 7;
if (len > maxaddlen) maxaddlen = len;
}
- for (h = addr->host_list; h != NULL; h = h->next)
- {
- int len = Ustrlen(h->name);
- fprintf(f, " host %s ", h->name);
- while (len++ < maxlen) fprintf(f, " ");
- if (h->address != NULL)
- {
- fprintf(f, "[%s] ", h->address);
- len = Ustrlen(h->address);
- }
- else if (!addr->transport->info->local) /* Omit [unknown] for local */
- {
- fprintf(f, "[unknown] ");
- len = 7;
- }
- else len = -3;
- while (len++ < maxaddlen) fprintf(f," ");
- if (h->mx >= 0) fprintf(f, "MX=%d", h->mx);
+ for (h = addr->host_list; h; h = h->next)
+ {
+ fprintf(f, " host %-*s ", maxlen, h->name);
+
+ if (h->address)
+ fprintf(f, "[%s%-*c", h->address, maxaddlen+1 - Ustrlen(h->address), ']');
+ else if (tp->info->local)
+ fprintf(f, " %-*s ", maxaddlen, ""); /* Omit [unknown] for local */
+ else
+ fprintf(f, "[%s%-*c", "unknown", maxaddlen+1 - 7, ']');
+
+ if (h->mx >= 0) fprintf(f, " MX=%d", h->mx);
if (h->port != PORT_NONE) fprintf(f, " port=%d", h->port);
- if (h->status == hstatus_unusable) fprintf(f, " ** unusable **");
- fprintf(f, "\n");
+ if (running_in_test_harness && h->dnssec == DS_YES) fputs(" AD", f);
+ if (h->status == hstatus_unusable) fputs(" ** unusable **", f);
+ fputc('\n', f);
}
}
}
- }
/* Yield will be DEFER or FAIL if any one address has, only for full_info (which is
the -bv or -bt case). */
verb = US"begins";
}
- *msgptr = string_printing(
+ /* deconst cast ok as we're passing a non-const to string_printing() */
+ *msgptr = US string_printing(
string_sprintf("%s: failing address in \"%.*s:\" header %s: %.*s",
errmess, tt - h->text, h->text, verb, len, s));
if (ip_connect(sock, host_af, sender_host_address, port, rfc1413_query_timeout)
< 0)
{
- if (errno == ETIMEDOUT && (log_extra_selector & LX_ident_timeout) != 0)
+ if (errno == ETIMEDOUT && LOGGING(ident_timeout))
{
log_write(0, LOG_MAIN, "ident connection to %s timed out",
sender_host_address);
/* The rest of the line is the data we want. We turn it into printing
characters when we save it, so that it cannot mess up the format of any logging
or Received: lines into which it gets inserted. We keep a maximum of 127
-characters. */
+characters. The deconst cast is ok as we fed a nonconst to string_printing() */
-sender_ident = string_printing(string_copyn(p, 127));
+sender_ident = US string_printing(string_copyn(p, 127));
DEBUG(D_ident) debug_printf("sender_ident = %s\n", sender_ident);
END_OFF:
*/
int
-check_host(void *arg, uschar *ss, uschar **valueptr, uschar **error)
+check_host(void *arg, const uschar *ss, const uschar **valueptr, uschar **error)
{
check_host_block *cb = (check_host_block *)arg;
int mlen = -1;
BOOL iplookup = FALSE;
BOOL isquery = FALSE;
BOOL isiponly = cb->host_name != NULL && cb->host_name[0] == 0;
-uschar *t;
+const uschar *t;
uschar *semicolon;
uschar **aliases;
h.address = NULL;
h.mx = MX_NONE;
+ /* Using byname rather than bydns here means we cannot determine dnssec
+ status. On the other hand it is unclear how that could be either
+ propagated up or enforced. */
+
rc = host_find_byname(&h, NULL, HOST_FIND_QUALIFY_SINGLE, NULL, FALSE);
if (rc == HOST_FOUND || rc == HOST_FOUND_LOCAL)
{
if ((semicolon = Ustrchr(ss, ';')) != NULL)
{
- uschar *affix;
+ const uschar *affix;
int partial, affixlen, starflags, id;
*semicolon = 0;
"+allow_unknown" was met earlier in the list, in which case OK is returned. */
int
-verify_check_this_host(uschar **listptr, unsigned int *cache_bits,
- uschar *host_name, uschar *host_address, uschar **valueptr)
+verify_check_this_host(const uschar **listptr, unsigned int *cache_bits,
+ const uschar *host_name, const uschar *host_address, const uschar **valueptr)
{
int rc;
unsigned int *local_cache_bits = cache_bits;
-uschar *save_host_address = deliver_host_address;
+const uschar *save_host_address = deliver_host_address;
check_host_block cb;
cb.host_name = host_name;
cb.host_address = host_address;
int
verify_check_given_host(uschar **listptr, host_item *host)
{
-return verify_check_this_host(listptr, NULL, host->name, host->address, NULL);
+return verify_check_this_host(CUSS listptr, NULL, host->name, host->address, NULL);
}
/*************************************************
int
verify_check_host(uschar **listptr)
{
-return verify_check_this_host(listptr, sender_host_cache, NULL,
+return verify_check_this_host(CUSS listptr, sender_host_cache, NULL,
(sender_host_address == NULL)? US"" : sender_host_address, NULL);
}
/* Look for this query in the cache. */
-t = tree_search(dnsbl_cache, query);
+if ( (t = tree_search(dnsbl_cache, query))
+ && (cb = t->data.ptr)->expiry > time(NULL)
+ )
+
+/* Previous lookup was cached */
+
+ {
+ HDEBUG(D_dnsbl) debug_printf("using result of previous DNS lookup\n");
+ }
/* If not cached from a previous lookup, we must do a DNS lookup, and
cache the result in permanent memory. */
-if (t == NULL)
+else
{
+ uint ttl = 3600;
+
store_pool = POOL_PERM;
- /* Set up a tree entry to cache the lookup */
+ if (t)
+ {
+ HDEBUG(D_dnsbl) debug_printf("cached data found but past valid time; ");
+ }
- t = store_get(sizeof(tree_node) + Ustrlen(query));
- Ustrcpy(t->name, query);
- t->data.ptr = cb = store_get(sizeof(dnsbl_cache_block));
- (void)tree_insertnode(&dnsbl_cache, t);
+ else
+ { /* Set up a tree entry to cache the lookup */
+ t = store_get(sizeof(tree_node) + Ustrlen(query));
+ Ustrcpy(t->name, query);
+ t->data.ptr = cb = store_get(sizeof(dnsbl_cache_block));
+ (void)tree_insertnode(&dnsbl_cache, t);
+ }
/* Do the DNS loopup . */
Quite apart from one A6 RR generating multiple addresses, there are DNS
lists that return more than one A record, so we must handle multiple
- addresses generated in that way as well. */
+ addresses generated in that way as well.
+
+ Mark the cache entry with the "now" plus the minimum of the address TTLs,
+ or some suitably far-future time if none were found. */
if (cb->rc == DNS_SUCCEED)
{
dns_record *rr;
dns_address **addrp = &(cb->rhs);
for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
- rr != NULL;
+ rr;
rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
{
if (rr->type == T_A)
{
dns_address *da = dns_address_from_rr(&dnsa, rr);
- if (da != NULL)
+ if (da)
{
*addrp = da;
while (da->next != NULL) da = da->next;
addrp = &(da->next);
+ if (ttl > rr->ttl) ttl = rr->ttl;
}
}
}
if (cb->rhs == NULL) cb->rc = DNS_NODATA;
}
+ cb->expiry = time(NULL)+ttl;
store_pool = old_pool;
}
-/* Previous lookup was cached */
-
-else
- {
- HDEBUG(D_dnsbl) debug_printf("using result of previous DNS lookup\n");
- cb = t->data.ptr;
- }
-
/* We now have the result of the DNS lookup, either newly done, or cached
from a previous call. If the lookup succeeded, check against the address
list if there is one. This may be a positive equality list (introduced by
{
int ipsep = ',';
uschar ip[46];
- uschar *ptr = iplist;
+ const uschar *ptr = iplist;
uschar *res;
/* Handle exact matching */
Note: a domain for testing RFCI is example.tld.dsn.rfc-ignorant.org
Arguments:
+ where the acl type
listptr the domain/address/data list
+ log_msgptr log message on error
Returns: OK successful lookup (i.e. the address is on the list), or
lookup deferred after +include_unknown
*/
int
-verify_check_dnsbl(uschar **listptr)
+verify_check_dnsbl(int where, const uschar ** listptr, uschar ** log_msgptr)
{
int sep = 0;
int defer_return = FAIL;
-uschar *list = *listptr;
+const uschar *list = *listptr;
uschar *domain;
uschar *s;
uschar buffer[1024];
/* See if there's explicit data to be looked up */
- key = Ustrchr(domain, '/');
- if (key != NULL) *key++ = 0;
+ if ((key = Ustrchr(domain, '/'))) *key++ = 0;
/* See if there's a list of addresses supplied after the domain name. This is
introduced by an = or a & character; if preceded by = we require all matches
and if preceded by ! we invert the result. */
- iplist = Ustrchr(domain, '=');
- if (iplist == NULL)
+ if (!(iplist = Ustrchr(domain, '=')))
{
bitmask = TRUE;
iplist = Ustrchr(domain, '&');
}
- if (iplist != NULL) /* Found either = or & */
+ if (iplist) /* Found either = or & */
{
if (iplist > domain && iplist[-1] == '!') /* Handle preceding ! */
{
}
}
+
/* If there is a comma in the domain, it indicates that a second domain for
looking up TXT records is provided, before the main domain. Otherwise we must
set domain_txt == domain. */
if (key == NULL)
{
+ if (where == ACL_WHERE_NOTSMTP_START || where == ACL_WHERE_NOTSMTP)
+ {
+ *log_msgptr = string_sprintf
+ ("cannot test auto-keyed dnslists condition in %s ACL",
+ acl_wherenames[where]);
+ return ERROR;
+ }
if (sender_host_address == NULL) return FAIL; /* can never match */
if (revadd[0] == 0) invert_address(revadd, sender_host_address);
rc = one_check_dnsbl(domain, domain_txt, sender_host_address, revadd,
uschar keybuffer[256];
uschar keyrevadd[128];
- while ((keydomain = string_nextinlist(&key, &keysep, keybuffer,
+ while ((keydomain = string_nextinlist(CUSS &key, &keysep, keybuffer,
sizeof(keybuffer))) != NULL)
{
uschar *prepend = keydomain;
# These variables are set by the configure script.
CC=@CC@
-CFLAGS=@CFLAGS@ @BIND_8_COMPAT@
+CFLAGS=@CFLAGS@ @BIND_8_COMPAT@ @DEFS@
LDFLAGS=@LDFLAGS@
CLIENT_SSL=@CLIENT_SSL@
CLIENT_GNUTLS=@CLIENT_GNUTLS@
@echo " "
bin/fakens: src/fakens.c Makefile
- $(CC) $(CFLAGS) $(LDFLAGS) -o bin/fakens src/fakens.c
+ $(CC) $(CFLAGS) $(LDFLAGS) -o bin/fakens src/fakens.c $(LIBS)
@echo ">>> bin/fakens command built"
@echo " "
and "xyz" and single letters that are used in the tests. The test suite
expects the login to have a gecos name; I think it will now run if the
gecos field is empty but there may be anomalies.
+ The login must not contain a dash or an equal sign. (Otherwise some tests
+ about local_from_{suffix,prefix} will fail.)
(4) The directory into which you unpack the test suite must be accessible by
the Exim user, so that code running as exim can access the files therein.
is also an IPv6 address, additional tests are run when the Exim binary
contains IPv6 support. There are checks in the scripts for a running IPv4
interface; when one is not found, some tests are skipped (with a warning
- message).
+ message). The local net may not be in 10.0/8 as that is used by the suite.
(9) Exim must be built with TRUSTED_CONFIG_LIST support, so that the test
configs can be placed into it. A suitable file location is .../exim/test/trusted_configs
+ with content .../exim/test/test-config [fill out the ... to make full
+ paths]. This file should be owner/group matching CONFIGURE_OWNER/GROUP,
+ or root/root. The config files in .../exim/test/confs/ should be owner/group the same.
DISABLE_D_OPTION must not be used. If ALT_CONFIG_PREFIX is used, it
must contain the directory of the test-suite. WHITELIST_D_MACROS should contain:
------------------
If you do not supply any arguments to ./runtest, it searches for an Exim
-source tree at the same level as the test suite directory. It then looks for an
-Exim binary in a "build" directory of that source tree. If there are several
-Exim source trees, it chooses the latest version of Exim. Consider the
-following example:
+source tree at the same level as the test suite directory. A source tree
+is a source tree, if it contains a build-* directory.
+
+It then looks for an Exim binary in a "build" directory of that source
+tree. If there are several Exim source trees, it chooses the latest
+version of Exim. Consider the following example:
$ ls -F /source/exim
exim-4.60/ exim-4.62/ exim-testsuite-x.xx/
(If it turns out that most people prefer to use diff, I'll change
the default.)
+ -FLAVOR <flavor>
+ -FLAVOUR <flavour>
+ This allows "overrides" for the test results. It's intended
+ use is to deal with distro specific differences in the test
+ output. The default flavour is "foo". If during the test
+ run differences between the current and the expected output
+ are found and no flavour file exists already, you may update
+ the "common" expected output or you may create a flavour
+ file. If a flavour file already exists, any updates will go
+ into that flavour file!
+
-KEEP Normally, after a successful run, the test output files are
deleted. This option prevents this. It is useful when running a
single test, in order to look at the actual output before it is
usage, the asterisks must be given.
+ background
+
+This command takes one script line and runs it in the background,
+in parallel with following commands. For external daemons, eg. redis-server.
+
+
catwrite <file name> [nxm[=start-of-line-text]]*
This command operates like the "write" command, which is described below,
Finally, "exim" can be preceded by "sudo", to run Exim as root. If more than
one of these prefixes is present, they must be in the above order.
+If the options include "-DSERVER" but not "-DNOTDAEMON", the script waits for
+Exim to start but then continues without waiting for it to terminate. Typically
+this will be for a daemon-mode "-bd" operation. The daemon should be later
+terminated using "killdaemon".
+
exim_exim [<options>] [<arguments>]
-d causes the server to output debugging information
- -t sets a timeout in seconds (default 5) for when the server is
+ -t <sec> sets a timeout (default 5) for when the server is
awaiting an incoming connection
-noipv4 causes the server not to set up an IPv4 socket
-noipv6 causes the server not to set up an IPv6 socket
+ -i <sec> sets an initial pause, to delay before creating the listen sockets
+
By default, in an IPv6 environment, both kinds of socket are set up. However,
the test script knows which interfaces actually exist on the host, and it adds
-noipv4 or -noipv6 to the server command as required. An error occurs if both
(d) If the line starts with ">*eof", nothing is sent and the connection
is closed.
- The data that is sent starts after the initial '>' sequence.
+ The data that is sent starts after the initial '>' sequence. Within
+ each line the sequence '\x' followed by two hex digits can be used
+ to specify an arbitrary byte value. The sequence '\\' specifies a
+ single backslash.
(2) A line that starts with "*sleep" specifies a number of seconds to wait
before proceeding.
(5) Otherwise, the line defines the start of an input line that the client
is expected to send. To allow for lines that start with digits, the line
may start with '<', which is not taken as part of the input data. If the
- input does not match, the server bombs out with an error message.
+ lines starts with '<<' then only the characters are expected; no return-
+ linefeed terminator. If the input does not match, the server bombs out
+ with an error message. Backslash-escape sequences may be used in the
+ line content as for output lines.
Here is a simple example of server use in a test script:
dynamic zone files for the name of the current host and its IP address(es). The
idea is that there should not be any need to rely on an external DNS.
-The domain names that are handled directly by Exim, without being passed to
-fakens, are:
+The fakens program handles some names programmatically rather than using the
+fake zone files. These are:
+
+ manyhome.test.ex This name is used for testing hosts with ridiculously large
+ numbers of IP addresses; 2048 IP addresses are generated
+ and returned. Doing it this way saves having to make the
+ interface to fakens handle more records that can fit in the
+ data block. The addresses that are generated are in the
+ 10.250.0.0/16 network.
test.again.dns This always provokes a TRY_AGAIN response, for testing the
handling of temporary DNS error. If the full domain name
test.fail.dns This always provokes a NO_RECOVERY response, for testing
DNS server failures.
-This special handling could now be done in the fakens program, but while the
-old test suite is still being used it has to be done in Exim itself, so for the
-moment it remains there.
-
The use of gethostbyname() and its IPv6 friends is also subverted when Exim is
running in the test harness. The test code handles a few special names
directly; for all the others it uses DNS lookups, which are then handled as
just described. Thus, the use of /etc/hosts is completely bypassed. The names
that are specially handled are:
- manyhome.test.ex This name is used for testing hosts with ridiculously large
- numbers of IP addresses; 2048 IP addresses are generated
- and returned. Doing it this way saves having to make the
- interface to fakens handle more records that can fit in the
- data block. The addresses that are generated are in the
- 10.250.0.0/16 network.
-
localhost Always returns 127.0.0.1 or ::1, for IPv4 and IPv6 lookups,
respectively.
--- /dev/null
+From: mrgus@text.ex
+To: bakawolf@yahoo.com
+Date: Thu, 19 Nov 2015 17:00:07 -0700
+Message-ID: <qwerty1234@disco-zombie.net>
+Subject: simple test
+
+This is a simple test.
--- /dev/null
+From: mrgus@test.ex
+To: bakawolf@yahoo.com
+Date: Thu, 19 Nov 2015 17:00:07 -0700
+Message-ID: <qwerty1234@disco-zombie.net>
+Subject: simple space test
+
+This is a test of simple with spaces.
+
+
+
+End of content (spaced line two lines down).
--- /dev/null
+Message-ID: <564CFC9B.1040905@yahoo.com>
+Date: Wed, 18 Nov 2015 14:32:59 -0800
+From: Joaquin Lopez <bakawolf@test.ex>
+User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:24.0) Gecko/20100101 Thunderbird/24.0
+MIME-Version: 1.0
+To: bakawolf@yahoo.com
+Subject: test
+Content-Type: text/plain; charset=ISO-8859-1; format=flowed
+Content-Transfer-Encoding: 7bit
+Content-Length: 13
+
+
+
+test
+
+
+
+
+
+
+
+
--- /dev/null
+Received: from xxxxxxxx.sproing.at ([127.0.0.1]:6225 helo=xxxxxxxx.sproing.at)
+ by yyyyyyyyyy.sproing.at with esmtp (Exim 4.86)
+ (envelope-from <postmaster@sproing.at>)
+ id 1a2FuN-0007pz-HD
+ for eximdkimtest@sproing.at; Fri, 27 Nov 2015 11:05:39 +0100
+From: <postmaster@test.ex>
+To: <eximdkimtest@sproing.at>
+Subject: test
+Date: Fri, 27 Nov 2015 11:05:38 +0100
+MIME-Version: 1.0
+Content-Type: text/plain;
+
+
+
+
+
+
--- /dev/null
+Received: from xxxxxxxx.sproing.at ([127.0.0.1]:6225 helo=xxxxxxxx.sproing.at)
+ by yyyyyyyyyy.sproing.at with esmtp (Exim 4.86)
+ (envelope-from <postmaster@sproing.at>)
+ id 1a2FuN-0007pz-HD
+ for eximdkimtest@sproing.at; Fri, 27 Nov 2015 11:05:39 +0100
+From: <postmaster@test.ex>
+To: <eximdkimtest@sproing.at>
+Subject: test
+Date: Fri, 27 Nov 2015 11:05:38 +0100
+MIME-Version: 1.0
+Content-Type: text/plain;
+
+Some content, then two blank lines.
+
+
--- /dev/null
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDXRFf+VhT+lCgFhhSkinZKcFNeRzjYdW8vT29Rbb3NadvTFwAd
++cVLPFwZL8H5tUD/7JbUPqNTCPxmpgIL+V5T4tEZMorHatvvUM2qfcpQ45IfsZ+Y
+dhbIiAslHCpy4xNxIR3zylgqRUF4+Dtsaqy3a5LhwMiKCLrnzhXk1F1hxwIDAQAB
+AoGAZPokJKQQmRK6a0zn5f8lWemy0airG66KhzDF0Pafb/nWKgDCB02gpJgdw5rJ
+bO7/HI3IeqsfRdYTP7tjfmZtPiPo1mnF7D1rSRspZjOF2yXY/ky7t7c5xChRcSxf
++69CknwjrfteY9Aj0j6o7N+2w2uvHO+AAq8BHDgXKmPo0SECQQDzQ/glyhNH9tlO
+x+3TTMwwyZUf2mYYosN3Q9NIl3Umz/3+13K5b6Ed6fZvS/XwU55Qf5IBUVj2Fujk
+Rv2lbGPpAkEA4okpnzYz5nm1X5WjpJPQPyo8nGEU1A5QfoDbkAvWYvVoYrpWPOx5
+HFpOAHkvSk1Y1vhCUa+zHwiQRBC8OMp6LwJBAOAUK/AjQ792UpWO9DM++pe2F/dP
+ZdwrkYG6qFSlrvQhgwXLz5GgkfjMGoRKpDDL1XixCfzMwfVtBPnBqsNGJIECQGYX
+SIGu7L7edMXJ60C9OKluwHf9LGTQuqf4LHsDSq+4Rz3PGhREwePsMqD1/EDxEKt4
+oHKtyvyeYF28aQbzARMCQQCRtJlR6vlKhxYL8+xoPrCu3MijKgVruRUcNstXkDZK
+fKQax6vhiMq+0qIiEwLA1wavyLVKZ7Mfag+/4NTcDUVC
+-----END RSA PRIVATE KEY-----
--- /dev/null
+-----BEGIN RSA PRIVATE KEY-----
+MIIBOAIBAAJBAL6eAQxd9didJ0/+05iDwJOqT6ly826Vi8aGPecsBiYK5/tAT97f
+xXk+dPWMZp9kQxtknEzYjYjAydzf+HQ2yJMCAwEAAQI/d+Dmx+BPvOsYzjZ03HX/
+pt51OxwP/HwQa8oBJGGLfGBJbxdKZoqZu1srifgA9o25x3YrSjfK9zrUgdqJEZRp
+AiEA5hUWdth65YX8dNMs93lsV0YkXdYzZ6Yxw6xyBAmpMh8CIQDUFtrIV8EYwgjq
+Ck0Un4RXbZleqOljmvhK+t7IBJsjDQIgGSMEqUdNZfYVds37g64IYCCRqI7WXuSR
+W0djzX0gtxECIEpwQxWyByoDYFGUj/0/B5oP85aPvmqhR6g5aNvXEgQ5AiBFgvNg
+ecXPBzNb52PZWOwH/DyuYE4agI2zLTmTsDJ09Q==
+-----END RSA PRIVATE KEY-----
--- /dev/null
+use Mail::DKIM::Signer;
+use Mail::DKIM::TextWrap; #recommended
+use Getopt::Long;
+
+# default option values
+my $method = "simple/simple";
+my $selector = "sel";
+my $keyfile = "aux-fixed/dkim/dkim.private";
+
+GetOptions(
+ "method=s" => \$method,
+ "selector=s" => \$selector,
+ "keyfile=s" => \$keyfile,
+);
+
+# create a signer object
+my $dkim = Mail::DKIM::Signer->new(
+ Algorithm => "rsa-sha1",
+ Method => $method,
+ Domain => "test.ex",
+ Selector => $selector,
+ KeyFile => $keyfile,
+ );
+
+# read an email and pass it into the signer, one line at a time
+while (<STDIN>)
+{
+ # remove local line terminators
+ chomp;
+ s/\015$//;
+
+ # use SMTP line terminators
+ $dkim->PRINT("$_\015\012");
+}
+$dkim->CLOSE;
+
+# what is the signature result?
+my $signature = $dkim->signature;
+print $signature->as_string;
+print "\n";
+
+#print $dkim->headers;
+#print "\n";
-----BEGIN CERTIFICATE-----
-MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA0WhcNMzgw\r
-MTAxMTIzNDA0WjApMRQwEgYDVQQKEwtleGFtcGxlLmNvbTERMA8GA1UEAxMIY2xp\r
-Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL0wro64rve876glpdRh\r
-tD6qFY6iH2kCarFFq3WaKmfCvOjYmn4CJr7pL7J5DuvCFh7A0H8lD/on5NK3yqkX\r
-Yi6EUlaYWxeRo2/PuZYUGbCpejST41sibw9V2dT4MHLidjDShE0W9SfgiMmxfF02\r
-H5hLYswAGCL1kezsVeEJeH31AgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw\r
-DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBAIn9+8uyQtaq8sBEohTl\r
-qyJQQeZk5xxaILYP/rCIxc+z5fgOh+usB9adaiD23RPuuD/P2c3UqHJQWqIUTu46\r
-eOKn9K7X7ndIH3WnaC/u4nysL+SIAug72/k1BAVGNQvyNQMhth6CfZTgY0tgcS0Z\r
-RSHyhbTD0HeiJDI281BoOJjm
+MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM3WhcNMzgw\r
+MTAxMTIzNDM3WjApMRQwEgYDVQQKEwtleGFtcGxlLmNvbTERMA8GA1UEAxMIY2xp\r
+Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOh0bvMeu3S1F6t7vEWH\r
+86hJbiW97pjm8A930DFhe/UIlgPsAmCePZEMg6EtakY5Huva4kYeBUejbRtd3LE7\r
+q07sOVQqcKt+X8wXThBBHPk/7q6BL+je3cfuisxsS1neX3m5BOAhROPr6kvFDz4f\r
+SRb4s3jT3bRgh5a7vl5JRv9FAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw\r
+DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBAA1n72ajcRt82cyo3R4P\r
+E9bqjhm4Y6d+a6vk4tPLk1uLD/EQw5ShAY6sM/FUzX8M4oyZ4A9Xouse0iXAVb50\r
+6gdqzfNtXeR5jIkTVNly0XJ99JfTgVHX0EcHPi3pffhiRCuNG2zEE6jIvUPym7UN\r
+3BXv6NWbBMOXAaVl99vckvxm
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA1WhcNMzgw\r
-MTAxMTIzNDA1WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp\r
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzwXsp\r
-P4RsZUoDfQfm5O5bi5unhwl+BTrKIaOtl5TBxMau+qEdKa02DD7Bx6PCzLKhWiZ3\r
-/MrO7V/cXIBun97dF5Zr5kk+HJk+y3es+xoPd3doknvGQEC/0cSGLcEC7aQ/bEqi\r
-fw2CgEY5ffkEAnDrdvGGeqBfJJGft/tqmlZbeQIDAQABo1owWDAOBgNVHQ8BAf8E\r
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM3WhcNMzgw\r
+MTAxMTIzNDM3WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp\r
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/GggX\r
+i+loP31ey0vxDpYe0mlBMHwC9ucGZo2HdTsJeOcGjqR4OTpZcOGbZB+Rhm+ZKZ+D\r
+lmIAjAit/sSJkqVj0hWlTdtSmgBuejsVqBHg3JwxVCnZmzo0+ILuod9tPcnVMjpz\r
+qj9CQAEcP+S329jlRKny14LCQzRc09QpszLuxwIDAQABo1owWDAOBgNVHQ8BAf8E\r
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw\r
-Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA\r
-Lq4cCtWMjqLHqf6lJUOBMsm+tgFcYDdxwkTquSZyUrbP1jrODkg5lQWNCdvB76B2\r
-tZQfMJ3F/kct2EAfsKbHqN3f+DARqPAR2qtOqzl3Ou5+TJjExKgojjzIAPFQzswH\r
-7v4aglpReaPBaVSNOZ7bMn/E8yRy3o466bhzdEIDcII=
+Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA\r
+yc6X34U2IKvN9y2EnNYwfsRPEE2LerSN9Tt3UgOuhuETJM7upwacJqOiN+HXQ0xp\r
+qhRxcDdrNy7MvymNLkc0mSiFGEjWG8dmZz/NFwGCzHSIhPxl6YryfbldbnqQLop0\r
+KpaftG9PQ4QxymUGjbvty95QvU2MlGA19NbXcLa4Vio=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA0WhcNMzgw\r
-MTAxMTIzNDA0WjApMRQwEgYDVQQKEwtleGFtcGxlLmNvbTERMA8GA1UEAxMIY2xp\r
-Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL0wro64rve876glpdRh\r
-tD6qFY6iH2kCarFFq3WaKmfCvOjYmn4CJr7pL7J5DuvCFh7A0H8lD/on5NK3yqkX\r
-Yi6EUlaYWxeRo2/PuZYUGbCpejST41sibw9V2dT4MHLidjDShE0W9SfgiMmxfF02\r
-H5hLYswAGCL1kezsVeEJeH31AgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw\r
-DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBAIn9+8uyQtaq8sBEohTl\r
-qyJQQeZk5xxaILYP/rCIxc+z5fgOh+usB9adaiD23RPuuD/P2c3UqHJQWqIUTu46\r
-eOKn9K7X7ndIH3WnaC/u4nysL+SIAug72/k1BAVGNQvyNQMhth6CfZTgY0tgcS0Z\r
-RSHyhbTD0HeiJDI281BoOJjm
+MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM3WhcNMzgw\r
+MTAxMTIzNDM3WjApMRQwEgYDVQQKEwtleGFtcGxlLmNvbTERMA8GA1UEAxMIY2xp\r
+Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOh0bvMeu3S1F6t7vEWH\r
+86hJbiW97pjm8A930DFhe/UIlgPsAmCePZEMg6EtakY5Huva4kYeBUejbRtd3LE7\r
+q07sOVQqcKt+X8wXThBBHPk/7q6BL+je3cfuisxsS1neX3m5BOAhROPr6kvFDz4f\r
+SRb4s3jT3bRgh5a7vl5JRv9FAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw\r
+DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBAA1n72ajcRt82cyo3R4P\r
+E9bqjhm4Y6d+a6vk4tPLk1uLD/EQw5ShAY6sM/FUzX8M4oyZ4A9Xouse0iXAVb50\r
+6gdqzfNtXeR5jIkTVNly0XJ99JfTgVHX0EcHPi3pffhiRCuNG2zEE6jIvUPym7UN\r
+3BXv6NWbBMOXAaVl99vckvxm
-----END CERTIFICATE-----
Bag Attributes
friendlyName: OCSP Signer
- localKeyID: A6 CA B2 02 9F 97 B7 22 79 C0 88 21 64 7D 68 9D F1 AE EB B4
+ localKeyID: A9 C9 02 7E EE 3B 0C ED EE D4 5A 38 52 2E 0F B1 4E 78 90 6F
Key Attributes: <No Attributes>
-----BEGIN PRIVATE KEY-----
-MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAM6cTVJb3XKpcx/R
-yywzRGgPTlu5kmOdDMliOvkCKy79zYfkguzTi1twxUWCxbQTGNOsYLZ5IaLCU5lc
-feQPe77YvWMgH1qZ2S87OpURTJRe/SSP2ufy7c+a9oGSXjD6wLfzfKjQPUMq7po0
-NwI877gJg5dybIYL+ZrHPuKtQkbtAgMBAAECgYA20FrnLb4bjH8hgvw/Fr7gSKdG
-SH5g9SqORwRUSdIBHo6nreVaRWlkcg+0OFSRSLu+dK4X2x0kXB/nwRUZK05twnOR
-4/yxB3yYRLWKSSs+wNyCEB/nmLqY4gxgkwiYvMhGqcRz5PIFO+kWs0NhZCnI5haO
-eRwbokPoJSwnDsZptQJBAOgDC/t9AhT2+n3+fhs3QMHJYBXb5TU6bUeK7d3EkpBk
-5R43S3iC5JyDMVoimH9Ml6qE9gpUFSmp2tGactmSGe8CQQDj+OzyrtiNoo8unA74
-ebasVZL3YhcYMHtcfHSxAUbRpRT00m/UaLlfboHcts4iH50rqUx4iIGiUInzuU/C
-hzjjAkEAim9G9wff9iJn1EXFePe+6+H8Mw7B9MCn88gxpeFkkkOhciYMIhv3zGt7
-RwzdcReCZ3xuUjtZZUK0DdzaKnfCgQJAG9wK0OmPK1fnWZHWvoTZTxwyFqtVGS6r
-lLTc6di3F92tvvGMmw+lP8VYd2mbrU3hvjk1UDGWbgiboz5NQf+WcwJACZuXjzTr
-LT9uWdLvfAkp02YxSemGgzNiF/MAEdA4Wx3YIFsWIoktRqMVTX/+eBUxCSKCaOf0
-9d7cy6kI01EH0Q==
+MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBANS7PhoxmaBtzEYQ
+NnbpFdSPXjAnKmo4hpJ085KxTD0avIxef+dXk07P8ZgnRBVHLg2aQu6YB2RIEAoA
+rcHiBw07ph4zeCRRGFw1uhvvSjUAutzckuKGqjIFlBS1e2O1+R5PByURSU38MBUx
+HBLz5n9/JA1qvBPj0VdlmXPzdMPNAgMBAAECgYEAzF3Vm3RrEiRpSiXpLPNfdYUG
+B1yY8tK69ZhFJ3gMtecpm/BtD+KiMeSzRGj0jzyCka7Q/kYvU7enMPTV+J0cB2mU
+iCTzijotvRKyqCNTUAGPoW5fexnUSh1LfzpON+V1AL+7ZNXE0rQCOAITMLW8JZwb
+lUQc3sdWOcS5A+i7mgECQQD0oLG72Cmvgm5BJx4c9BebHisr9Oo8BaGUrlLkzufh
+Lsh5ty+iraibPpsEQfZS6PsXzC7PMRX9kUd05FjscF55AkEA3p7znhdcvyd/fIt3
+QlF7cyU8qQBtjUOMRVn2njMko7/3STHiPEeOxJdCVrQKxFRB4bYAcEVvFPDiGHIx
+Ex6q9QJAAkA0QnEzuPyvPQQ6H7QTP4cgiJABU7oNiYutEZPhyE2g5JXN52ZHpd4G
+mRxuQscIAGkNiTR/akza5nVvaAWEqQJBANkY+4y1Tb4gX6PuQgwLeC8PJjvNbghv
+0hAjrmwShe2mnBnmKrEMO38d3xS8mS9i16ism3rhS3WJf4PFgHQb2S0CQQCsI1e3
+Py8DxpsRqyIoxv/3HOT+vAiByiItW24Q59Qbd628bPP0q4y/Fa1dSkXPW8/4DvPr
++sBszxcYF+ReAISE
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
-MIICBTCCAW6gAwIBAgIBAzANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt\r
+MIICBTCCAW6gAwIBAgIBAzANBgkqhkiG9w0BAQsFADAzMRQwEgYDVQQKEwtleGFt\r
cGxlLmNvbTEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy\r
-MzQwNVoXDTM4MDEwMTEyMzQwNVowMjEUMBIGA1UEChMLZXhhbXBsZS5jb20xGjAY\r
+MzQzN1oXDTM4MDEwMTEyMzQzN1owMjEUMBIGA1UEChMLZXhhbXBsZS5jb20xGjAY\r
BgNVBAMTEWNsaWNhIE9DU1AgU2lnbmVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB\r
-iQKBgQDOnE1SW91yqXMf0cssM0RoD05buZJjnQzJYjr5Aisu/c2H5ILs04tbcMVF\r
-gsW0ExjTrGC2eSGiwlOZXH3kD3u+2L1jIB9amdkvOzqVEUyUXv0kj9rn8u3PmvaB\r
-kl4w+sC383yo0D1DKu6aNDcCPO+4CYOXcmyGC/maxz7irUJG7QIDAQABoyowKDAO\r
+iQKBgQDUuz4aMZmgbcxGEDZ26RXUj14wJypqOIaSdPOSsUw9GryMXn/nV5NOz/GY\r
+J0QVRy4NmkLumAdkSBAKAK3B4gcNO6YeM3gkURhcNbob70o1ALrc3JLihqoyBZQU\r
+tXtjtfkeTwclEUlN/DAVMRwS8+Z/fyQNarwT49FXZZlz83TDzQIDAQABoyowKDAO\r
BgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwkwDQYJKoZIhvcN\r
-AQEFBQADgYEASKF8V7Ykc7MK5uVOcL272uheZzwFUtlx4HjWRI11QliwyBzegL3b\r
-ZdhmnDr/XbtWFTF2pId76dRWNPcWd9nCV8yvhwOgydLHnDov20soUyJeqJJuXonb\r
-InlafhkIGJ8wMEeCjY70VbIip+akW8lSCw8ralCMg2ewNuKv5D0ujsQ=
+AQELBQADgYEAsXoaEXn4y4thG5KiB0k1HwU3NQ5TmuN6Z03WUO/5NLFYtMB0ztaL\r
+GOJgI5k8jQNuZxNb5nqvQBivZ/DiDAV/G3dPQDbqSgtF2Y5tROdC8/lYynhiY3nI\r
+2k0BO1snUtbjZbVdzAMVXBUmqUL+xIB2+A2MuTF3pHLMugeQYtbBbJc=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA1WhcNMzgw\r
-MTAxMTIzNDA1WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp\r
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzwXsp\r
-P4RsZUoDfQfm5O5bi5unhwl+BTrKIaOtl5TBxMau+qEdKa02DD7Bx6PCzLKhWiZ3\r
-/MrO7V/cXIBun97dF5Zr5kk+HJk+y3es+xoPd3doknvGQEC/0cSGLcEC7aQ/bEqi\r
-fw2CgEY5ffkEAnDrdvGGeqBfJJGft/tqmlZbeQIDAQABo1owWDAOBgNVHQ8BAf8E\r
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM3WhcNMzgw\r
+MTAxMTIzNDM3WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp\r
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/GggX\r
+i+loP31ey0vxDpYe0mlBMHwC9ucGZo2HdTsJeOcGjqR4OTpZcOGbZB+Rhm+ZKZ+D\r
+lmIAjAit/sSJkqVj0hWlTdtSmgBuejsVqBHg3JwxVCnZmzo0+ILuod9tPcnVMjpz\r
+qj9CQAEcP+S329jlRKny14LCQzRc09QpszLuxwIDAQABo1owWDAOBgNVHQ8BAf8E\r
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw\r
-Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA\r
-Lq4cCtWMjqLHqf6lJUOBMsm+tgFcYDdxwkTquSZyUrbP1jrODkg5lQWNCdvB76B2\r
-tZQfMJ3F/kct2EAfsKbHqN3f+DARqPAR2qtOqzl3Ou5+TJjExKgojjzIAPFQzswH\r
-7v4aglpReaPBaVSNOZ7bMn/E8yRy3o466bhzdEIDcII=
+Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA\r
+yc6X34U2IKvN9y2EnNYwfsRPEE2LerSN9Tt3UgOuhuETJM7upwacJqOiN+HXQ0xp\r
+qhRxcDdrNy7MvymNLkc0mSiFGEjWG8dmZz/NFwGCzHSIhPxl6YryfbldbnqQLop0\r
+KpaftG9PQ4QxymUGjbvty95QvU2MlGA19NbXcLa4Vio=
-----END CERTIFICATE-----
; Config::Simple 4.59
-; Thu Nov 1 12:34:02 2012
+; Thu Nov 1 12:34:37 2012
[CLICA]
+ocsp_signer=OCSP Signer
+sighash=SHA256
crl_url=http://crl.example.com/latest.crl
-crl_signer=Signing Cert
+ocsp_url=http://oscp/example.com/
level=1
+crl_signer=Signing Cert
signer=Signing Cert
-ocsp_signer=OCSP Signer
-ocsp_url=http://oscp/example.com/
[CA]
-org=example.com
subject=clica CA
name=Certificate Authority
+org=example.com
bits=1024
-update=20140422152734Z
+update=20151216164103Z
-----BEGIN X509 CRL-----
-MIHtMFgCAQEwDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhhbXBsZS5jb20x
-GzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydBgPMjAxNDA0MjIxNTI3MzRaMA0G
-CSqGSIb3DQEBBQUAA4GBAHoGAZpobbrLkTayml3YbpVuF8Ig9FAAj6zmvNuqqsha
-dSn0qL1ca9RgVaa1XIlqVeIs1uHFF0zA/F3BVvxWfPxTbgn8b/QyKEwG36f6Urax
-nngK87UT2z8M5+prZeSIaroYV+sG5M2+4fFsUt62RmJr1rAnsxO+vguM97LSOJaB
+MIHtMFgCAQEwDQYJKoZIhvcNAQELBQAwMzEUMBIGA1UEChMLZXhhbXBsZS5jb20x
+GzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydBgPMjAxNTEyMTYxNjQxMDNaMA0G
+CSqGSIb3DQEBCwUAA4GBAHP7LDu9YflzDqwChDy5txXymX13+iYnBZx0Q9JfbThm
+wPVH4iCfsqQ+vWhEnTcFDYWZ43USFm6JjKWOLQBO7NX1pFF/5Y/YSV3OiKER1cGl
+GRikqJ/B+80V4+7SjFdkGU3A5sYSsnRDZYEtSfykc5tdhZqjXmBwFUckGzCPLuso
-----END X509 CRL-----
-update=20140422152736Z
-addcert 102 20140422152736Z
-addcert 202 20140422152736Z
+update=20151216164105Z
+addcert 102 20151216164105Z
+addcert 202 20151216164105Z
-----BEGIN X509 CRL-----
-MIIBHTCBhwIBATANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFtcGxlLmNv
-bTEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0GA8yMDE0MDQyMjE1MjczNlow
-LTAUAgFmGA8yMDE0MDQyMjE1MjczNlowFQICAMoYDzIwMTQwNDIyMTUyNzM2WjAN
-BgkqhkiG9w0BAQUFAAOBgQBNEXTCKmqCrYZ5/C4lKqSjKsy2iXoJCNcYoFj60AA2
-Lc8yju8/TkUe8DkZ/leefksdLGzsCGsAgpgSSqMClfL83r9a50OBSCg21dvahyEx
-A45RfUx7M9Hy+ITWSY7hV7VaMoaL76ZxPBtdjMoqp8pxOj8k68d9V32OdcEpRsT+
-wA==
+MIIBHTCBhwIBATANBgkqhkiG9w0BAQsFADAzMRQwEgYDVQQKEwtleGFtcGxlLmNv
+bTEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0GA8yMDE1MTIxNjE2NDEwNVow
+LTAUAgFmGA8yMDE1MTIxNjE2NDEwNVowFQICAMoYDzIwMTUxMjE2MTY0MTA1WjAN
+BgkqhkiG9w0BAQsFAAOBgQCbR/9pp3MS1SqJiPu1/7lix4dtcqXEDkSH/AjiTZNi
+WXuK0wystCuzaSuAR+iZwk7DmxGhx5k+L5adlcWJNhBXR3zfZB4dwVhVKUpKSayO
+RE5iq8kYF5ifU9aroTtrbh2yR+XXHd8X7tkkt/bsMVNm1aQ/NgJeApmlZtB7Gx/o
+jg==
-----END X509 CRL-----
processor : 0
vendor_id : GenuineIntel
cpu family : 6
-model : 13
-model name : QEMU Virtual CPU version (cpu64-rhel6)
-stepping : 3
-cpu MHz : 1994.999
+model : 58
+model name : Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
+stepping : 9
+microcode : 0x1b
+cpu MHz : 2615.210
cache size : 4096 KB
+physical id : 0
+siblings : 4
+core id : 0
+cpu cores : 2
+apicid : 0
+initial apicid : 0
fpu : yes
fpu_exception : yes
-cpuid level : 4
+cpuid level : 13
wp : yes
-flags : fpu de pse tsc msr pae mce cx8 apic mtrr pge mca cmov pse36 clflush mmx fxsr sse sse2 syscall nx lm up unfair_spinlock pni cx16 hypervisor lahf_lm
-bogomips : 3989.99
+flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm ida arat epb pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt
+bugs :
+bogomips : 5786.61
clflush size : 64
cache_alignment : 64
-address sizes : 38 bits physical, 48 bits virtual
+address sizes : 36 bits physical, 48 bits virtual
power management:
- CPU0
- 0: 258 IO-APIC-edge timer
- 1: 6 IO-APIC-edge i8042
- 4: 1 IO-APIC-edge
- 8: 0 IO-APIC-edge rtc0
- 9: 0 IO-APIC-fasteoi acpi
- 10: 953 IO-APIC-fasteoi virtio3
- 11: 62 IO-APIC-fasteoi uhci_hcd:usb1, snd_hda_intel
- 12: 104 IO-APIC-edge i8042
- 14: 0 IO-APIC-edge ata_piix
- 15: 106 IO-APIC-edge ata_piix
- 24: 0 PCI-MSI-edge virtio2-config
- 25: 48985 PCI-MSI-edge virtio2-requests
- 26: 0 PCI-MSI-edge virtio0-config
- 27: 296814 PCI-MSI-edge virtio0-input
- 28: 1 PCI-MSI-edge virtio0-output
- 29: 0 PCI-MSI-edge virtio1-config
- 30: 18867 PCI-MSI-edge virtio1-input
- 31: 1 PCI-MSI-edge virtio1-output
-NMI: 0 Non-maskable interrupts
-LOC: 771688 Local timer interrupts
-SPU: 0 Spurious interrupts
-PMI: 0 Performance monitoring interrupts
-IWI: 0 IRQ work interrupts
-RES: 0 Rescheduling interrupts
-CAL: 0 Function call interrupts
-TLB: 0 TLB shootdowns
-TRM: 0 Thermal event interrupts
-THR: 0 Threshold APIC interrupts
-MCE: 0 Machine check exceptions
-MCP: 271 Machine check polls
+processor : 1
+vendor_id : GenuineIntel
+cpu family : 6
+model : 58
+model name : Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
+stepping : 9
+microcode : 0x1b
+cpu MHz : 3274.734
+cache size : 4096 KB
+physical id : 0
+siblings : 4
+core id : 0
+cpu cores : 2
+apicid : 1
+initial apicid : 1
+fpu : yes
+fpu_exception : yes
+cpuid level : 13
+wp : yes
+flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm ida arat epb pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt
+bugs :
+bogomips : 5786.61
+clflush size : 64
+cache_alignment : 64
+address sizes : 36 bits physical, 48 bits virtual
+power management:
+
+processor : 2
+vendor_id : GenuineIntel
+cpu family : 6
+model : 58
+model name : Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
+stepping : 9
+microcode : 0x1b
+cpu MHz : 3300.222
+cache size : 4096 KB
+physical id : 0
+siblings : 4
+core id : 1
+cpu cores : 2
+apicid : 2
+initial apicid : 2
+fpu : yes
+fpu_exception : yes
+cpuid level : 13
+wp : yes
+flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm ida arat epb pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt
+bugs :
+bogomips : 5786.61
+clflush size : 64
+cache_alignment : 64
+address sizes : 36 bits physical, 48 bits virtual
+power management:
+
+processor : 3
+vendor_id : GenuineIntel
+cpu family : 6
+model : 58
+model name : Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
+stepping : 9
+microcode : 0x1b
+cpu MHz : 3594.414
+cache size : 4096 KB
+physical id : 0
+siblings : 4
+core id : 1
+cpu cores : 2
+apicid : 3
+initial apicid : 3
+fpu : yes
+fpu_exception : yes
+cpuid level : 13
+wp : yes
+flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm ida arat epb pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt
+bugs :
+bogomips : 5786.61
+clflush size : 64
+cache_alignment : 64
+address sizes : 36 bits physical, 48 bits virtual
+power management:
+
+ CPU0 CPU1 CPU2 CPU3
+ 0: 68 0 0 0 IO-APIC 2-edge timer
+ 1: 689 7853 658 778 IO-APIC 1-edge i8042
+ 8: 0 0 1 0 IO-APIC 8-edge rtc0
+ 9: 1160 695 344 261 IO-APIC 9-fasteoi acpi
+ 12: 314976 1327914 163447 143732 IO-APIC 12-edge i8042
+ 16: 332 194 163 132 IO-APIC 16-fasteoi ehci_hcd:usb3, mmc0
+ 18: 0 0 0 0 IO-APIC 18-fasteoi i801_smbus
+ 23: 17 31 0 0 IO-APIC 23-fasteoi ehci_hcd:usb4
+ 24: 43314 5748 786804 3298 PCI-MSI 512000-edge 0000:00:1f.2
+ 25: 0 0 0 0 PCI-MSI 327680-edge xhci_hcd
+ 26: 3 4 0 1 PCI-MSI 409600-edge enp0s25
+ 27: 852 591 64 42 PCI-MSI 32768-edge i915
+ 28: 8 6 3 6 PCI-MSI 360448-edge mei_me
+ 29: 62 82 0 6 PCI-MSI 442368-edge snd_hda_intel
+ 30: 779441 1591 37 80 PCI-MSI 1572864-edge iwlwifi
+NMI: 94 87 91 87 Non-maskable interrupts
+LOC: 2715890 2175650 2756976 2240423 Local timer interrupts
+SPU: 0 0 0 0 Spurious interrupts
+PMI: 94 87 91 87 Performance monitoring interrupts
+IWI: 0 6 3 4 IRQ work interrupts
+RTR: 0 0 0 0 APIC ICR read retries
+RES: 181874 181890 174943 218142 Rescheduling interrupts
+CAL: 155876 95337 153276 90505 Function call interrupts
+TLB: 19954 22438 21482 20783 TLB shootdowns
+TRM: 0 0 0 0 Thermal event interrupts
+THR: 0 0 0 0 Threshold APIC interrupts
+DFR: 0 0 0 0 Deferred Error APIC interrupts
+MCE: 0 0 0 0 Machine check exceptions
+MCP: 29 29 29 29 Machine check polls
+HYP: 0 0 0 0 Hypervisor callback interrupts
ERR: 0
MIS: 0
-MemTotal: 487904 kB
-MemFree: 74352 kB
-Buffers: 73812 kB
-Cached: 140872 kB
-SwapCached: 0 kB
-Active: 131704 kB
-Inactive: 118904 kB
-Active(anon): 15124 kB
-Inactive(anon): 21900 kB
-Active(file): 116580 kB
-Inactive(file): 97004 kB
-Unevictable: 0 kB
-Mlocked: 0 kB
-SwapTotal: 524280 kB
-SwapFree: 524280 kB
-Dirty: 848 kB
+PIN: 0 0 0 0 Posted-interrupt notification event
+PIW: 0 0 0 0 Posted-interrupt wakeup event
+MemTotal: 16127228 kB
+MemFree: 11188304 kB
+MemAvailable: 11366680 kB
+Buffers: 13528 kB
+Cached: 250856 kB
+SwapCached: 1969132 kB
+Active: 2291068 kB
+Inactive: 2270716 kB
+Active(anon): 2258368 kB
+Inactive(anon): 2128068 kB
+Active(file): 32700 kB
+Inactive(file): 142648 kB
+Unevictable: 22232 kB
+Mlocked: 22232 kB
+SwapTotal: 7286780 kB
+SwapFree: 617204 kB
+Dirty: 3652 kB
Writeback: 0 kB
-AnonPages: 35972 kB
-Mapped: 15624 kB
-Shmem: 1128 kB
-Slab: 136276 kB
-SReclaimable: 83896 kB
-SUnreclaim: 52380 kB
-KernelStack: 752 kB
-PageTables: 3420 kB
+AnonPages: 2350492 kB
+Mapped: 158544 kB
+Shmem: 80340 kB
+Slab: 122620 kB
+SReclaimable: 63028 kB
+SUnreclaim: 59592 kB
+KernelStack: 12384 kB
+PageTables: 60012 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
-CommitLimit: 768232 kB
-Committed_AS: 116976 kB
+CommitLimit: 15350392 kB
+Committed_AS: 22212804 kB
VmallocTotal: 34359738367 kB
-VmallocUsed: 12116 kB
-VmallocChunk: 34359713232 kB
+VmallocUsed: 457088 kB
+VmallocChunk: 34358947836 kB
HardwareCorrupted: 0 kB
-AnonHugePages: 2048 kB
+AnonHugePages: 1890304 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
-DirectMap4k: 7156 kB
-DirectMap2M: 1492992 kB
-slabinfo - version: 2.1
-# name <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>
-nf_conntrack_expect 0 0 240 16 1 : tunables 120 60 0 : slabdata 0 0 0
-nf_conntrack_ffffffff81b18540 35 36 312 12 1 : tunables 54 27 0 : slabdata 3 3 0
-fib6_nodes 45 59 64 59 1 : tunables 120 60 0 : slabdata 1 1 0
-ip6_dst_cache 24 40 384 10 1 : tunables 54 27 0 : slabdata 4 4 0
-ndisc_cache 24 30 256 15 1 : tunables 120 60 0 : slabdata 2 2 0
-ip6_mrt_cache 0 0 128 30 1 : tunables 120 60 0 : slabdata 0 0 0
-RAWv6 4 4 1024 4 1 : tunables 54 27 0 : slabdata 1 1 0
-UDPLITEv6 0 0 1024 4 1 : tunables 54 27 0 : slabdata 0 0 0
-UDPv6 0 0 1024 4 1 : tunables 54 27 0 : slabdata 0 0 0
-tw_sock_TCPv6 0 0 320 12 1 : tunables 54 27 0 : slabdata 0 0 0
-request_sock_TCPv6 0 0 192 20 1 : tunables 120 60 0 : slabdata 0 0 0
-TCPv6 9 10 1920 2 1 : tunables 24 12 0 : slabdata 5 5 0
-jbd2_1k 0 0 1024 4 1 : tunables 54 27 0 : slabdata 0 0 0
-avtab_node 551039 551088 24 144 1 : tunables 120 60 0 : slabdata 3827 3827 0
-ext4_inode_cache 36092 36888 1016 4 1 : tunables 54 27 0 : slabdata 9222 9222 0
-ext4_xattr 5 44 88 44 1 : tunables 120 60 0 : slabdata 1 1 0
-ext4_free_block_extents 16 67 56 67 1 : tunables 120 60 0 : slabdata 1 1 0
-ext4_alloc_context 16 28 136 28 1 : tunables 120 60 0 : slabdata 1 1 0
-ext4_prealloc_space 3 37 104 37 1 : tunables 120 60 0 : slabdata 1 1 0
-ext4_system_zone 0 0 40 92 1 : tunables 120 60 0 : slabdata 0 0 0
-jbd2_journal_handle 16 144 24 144 1 : tunables 120 60 0 : slabdata 1 1 0
-jbd2_journal_head 68 68 112 34 1 : tunables 120 60 0 : slabdata 2 2 0
-jbd2_revoke_table 4 202 16 202 1 : tunables 120 60 0 : slabdata 1 1 0
-jbd2_revoke_record 0 0 32 112 1 : tunables 120 60 0 : slabdata 0 0 0
-scsi_sense_cache 2 30 128 30 1 : tunables 120 60 0 : slabdata 1 1 0
-scsi_cmd_cache 2 15 256 15 1 : tunables 120 60 0 : slabdata 1 1 0
-dm_raid1_read_record 0 0 1064 7 2 : tunables 24 12 0 : slabdata 0 0 0
-kcopyd_job 0 0 3240 2 2 : tunables 24 12 0 : slabdata 0 0 0
-io 0 0 64 59 1 : tunables 120 60 0 : slabdata 0 0 0
-dm_uevent 0 0 2608 3 2 : tunables 24 12 0 : slabdata 0 0 0
-dm_rq_clone_bio_info 0 0 16 202 1 : tunables 120 60 0 : slabdata 0 0 0
-dm_rq_target_io 0 0 392 10 1 : tunables 54 27 0 : slabdata 0 0 0
-dm_target_io 576 576 24 144 1 : tunables 120 60 0 : slabdata 4 4 0
-dm_io 552 552 40 92 1 : tunables 120 60 0 : slabdata 6 6 0
-flow_cache 0 0 104 37 1 : tunables 120 60 0 : slabdata 0 0 0
-uhci_urb_priv 0 0 56 67 1 : tunables 120 60 0 : slabdata 0 0 0
-cfq_io_context 0 0 136 28 1 : tunables 120 60 0 : slabdata 0 0 0
-cfq_queue 0 0 240 16 1 : tunables 120 60 0 : slabdata 0 0 0
-bsg_cmd 0 0 312 12 1 : tunables 54 27 0 : slabdata 0 0 0
-mqueue_inode_cache 1 4 896 4 1 : tunables 54 27 0 : slabdata 1 1 0
-isofs_inode_cache 0 0 640 6 1 : tunables 54 27 0 : slabdata 0 0 0
-hugetlbfs_inode_cache 1 6 608 6 1 : tunables 54 27 0 : slabdata 1 1 0
-dquot 0 0 256 15 1 : tunables 120 60 0 : slabdata 0 0 0
-kioctx 0 0 384 10 1 : tunables 54 27 0 : slabdata 0 0 0
-kiocb 0 0 256 15 1 : tunables 120 60 0 : slabdata 0 0 0
-inotify_event_private_data 0 0 32 112 1 : tunables 120 60 0 : slabdata 0 0 0
-inotify_inode_mark_entry 110 136 112 34 1 : tunables 120 60 0 : slabdata 4 4 0
-dnotify_mark_entry 0 0 112 34 1 : tunables 120 60 0 : slabdata 0 0 0
-dnotify_struct 0 0 32 112 1 : tunables 120 60 0 : slabdata 0 0 0
-dio 0 0 640 6 1 : tunables 54 27 0 : slabdata 0 0 0
-fasync_cache 0 0 24 144 1 : tunables 120 60 0 : slabdata 0 0 0
-khugepaged_mm_slot 17 92 40 92 1 : tunables 120 60 0 : slabdata 1 1 0
-ksm_mm_slot 0 0 48 77 1 : tunables 120 60 0 : slabdata 0 0 0
-ksm_stable_node 0 0 48 77 1 : tunables 120 60 0 : slabdata 0 0 0
-ksm_rmap_item 0 0 64 59 1 : tunables 120 60 0 : slabdata 0 0 0
-utrace_engine 0 0 56 67 1 : tunables 120 60 0 : slabdata 0 0 0
-utrace 0 0 64 59 1 : tunables 120 60 0 : slabdata 0 0 0
-pid_namespace 0 0 2168 3 2 : tunables 24 12 0 : slabdata 0 0 0
-posix_timers_cache 0 0 176 22 1 : tunables 120 60 0 : slabdata 0 0 0
-uid_cache 3 30 128 30 1 : tunables 120 60 0 : slabdata 1 1 0
-UNIX 107 110 768 5 1 : tunables 54 27 0 : slabdata 22 22 0
-ip_mrt_cache 0 0 128 30 1 : tunables 120 60 0 : slabdata 0 0 0
-UDP-Lite 0 0 832 9 2 : tunables 54 27 0 : slabdata 0 0 0
-tcp_bind_bucket 9 59 64 59 1 : tunables 120 60 0 : slabdata 1 1 0
-inet_peer_cache 2 59 64 59 1 : tunables 120 60 0 : slabdata 1 1 0
-secpath_cache 0 0 64 59 1 : tunables 120 60 0 : slabdata 0 0 0
-xfrm_dst_cache 0 0 448 8 1 : tunables 54 27 0 : slabdata 0 0 0
-ip_fib_alias 1 112 32 112 1 : tunables 120 60 0 : slabdata 1 1 0
-ip_fib_hash 14 53 72 53 1 : tunables 120 60 0 : slabdata 1 1 0
-ip_dst_cache 26 30 384 10 1 : tunables 54 27 0 : slabdata 3 3 0
-arp_cache 6 15 256 15 1 : tunables 120 60 0 : slabdata 1 1 0
-PING 0 0 832 9 2 : tunables 54 27 0 : slabdata 0 0 0
-RAW 2 9 832 9 2 : tunables 54 27 0 : slabdata 1 1 0
-UDP 1 9 832 9 2 : tunables 54 27 0 : slabdata 1 1 0
-tw_sock_TCP 0 0 256 15 1 : tunables 120 60 0 : slabdata 0 0 0
-request_sock_TCP 0 0 128 30 1 : tunables 120 60 0 : slabdata 0 0 0
-TCP 10 12 1728 4 2 : tunables 24 12 0 : slabdata 3 3 0
-eventpoll_pwq 59 106 72 53 1 : tunables 120 60 0 : slabdata 2 2 0
-eventpoll_epi 59 90 128 30 1 : tunables 120 60 0 : slabdata 3 3 0
-sgpool-128 2 2 4096 1 1 : tunables 24 12 0 : slabdata 2 2 0
-sgpool-64 2 2 2048 2 1 : tunables 24 12 0 : slabdata 1 1 0
-sgpool-32 2 4 1024 4 1 : tunables 54 27 0 : slabdata 1 1 0
-sgpool-16 2 8 512 8 1 : tunables 54 27 0 : slabdata 1 1 0
-sgpool-8 2 15 256 15 1 : tunables 120 60 0 : slabdata 1 1 0
-scsi_data_buffer 0 0 24 144 1 : tunables 120 60 0 : slabdata 0 0 0
-blkdev_integrity 0 0 112 34 1 : tunables 120 60 0 : slabdata 0 0 0
-blkdev_queue 28 28 2864 2 2 : tunables 24 12 0 : slabdata 14 14 0
-blkdev_requests 22 22 352 11 1 : tunables 54 27 0 : slabdata 2 2 0
-blkdev_ioc 3 48 80 48 1 : tunables 120 60 0 : slabdata 1 1 0
-fsnotify_event_holder 0 0 24 144 1 : tunables 120 60 0 : slabdata 0 0 0
-fsnotify_event 0 0 104 37 1 : tunables 120 60 0 : slabdata 0 0 0
-bio-0 80 80 192 20 1 : tunables 120 60 0 : slabdata 4 4 0
-biovec-256 34 34 4096 1 1 : tunables 24 12 0 : slabdata 34 34 0
-biovec-128 0 0 2048 2 1 : tunables 24 12 0 : slabdata 0 0 0
-biovec-64 4 4 1024 4 1 : tunables 54 27 0 : slabdata 1 1 0
-biovec-16 15 15 256 15 1 : tunables 120 60 0 : slabdata 1 1 0
-bip-256 2 2 4224 1 2 : tunables 8 4 0 : slabdata 2 2 0
-bip-128 0 0 2176 3 2 : tunables 24 12 0 : slabdata 0 0 0
-bip-64 0 0 1152 7 2 : tunables 24 12 0 : slabdata 0 0 0
-bip-16 0 0 384 10 1 : tunables 54 27 0 : slabdata 0 0 0
-bip-4 0 0 192 20 1 : tunables 120 60 0 : slabdata 0 0 0
-bip-1 0 0 128 30 1 : tunables 120 60 0 : slabdata 0 0 0
-sock_inode_cache 151 160 704 5 1 : tunables 54 27 0 : slabdata 32 32 0
-skbuff_fclone_cache 7 7 512 7 1 : tunables 54 27 0 : slabdata 1 1 0
-skbuff_head_cache 66 105 256 15 1 : tunables 120 60 0 : slabdata 7 7 0
-file_lock_cache 21 22 176 22 1 : tunables 120 60 0 : slabdata 1 1 0
-net_namespace 0 0 2432 3 2 : tunables 24 12 0 : slabdata 0 0 0
-shmem_inode_cache 654 655 784 5 1 : tunables 54 27 0 : slabdata 131 131 0
-Acpi-Operand 1211 1219 72 53 1 : tunables 120 60 0 : slabdata 23 23 0
-Acpi-ParseExt 0 0 72 53 1 : tunables 120 60 0 : slabdata 0 0 0
-Acpi-Parse 0 0 48 77 1 : tunables 120 60 0 : slabdata 0 0 0
-Acpi-State 0 0 80 48 1 : tunables 120 60 0 : slabdata 0 0 0
-Acpi-Namespace 407 460 40 92 1 : tunables 120 60 0 : slabdata 5 5 0
-task_delay_info 102 102 112 34 1 : tunables 120 60 0 : slabdata 3 3 0
-taskstats 0 0 328 12 1 : tunables 54 27 0 : slabdata 0 0 0
-proc_inode_cache 408 408 656 6 1 : tunables 54 27 0 : slabdata 68 68 0
-sigqueue 9 24 160 24 1 : tunables 120 60 0 : slabdata 1 1 0
-bdev_cache 31 32 832 4 1 : tunables 54 27 0 : slabdata 8 8 0
-sysfs_dir_cache 7588 7614 144 27 1 : tunables 120 60 0 : slabdata 282 282 0
-mnt_cache 27 30 256 15 1 : tunables 120 60 0 : slabdata 2 2 0
-filp 840 840 192 20 1 : tunables 120 60 0 : slabdata 42 42 0
-inode_cache 5826 5826 592 6 1 : tunables 54 27 0 : slabdata 971 971 0
-dentry 189280 189280 192 20 1 : tunables 120 60 0 : slabdata 9464 9464 0
-names_cache 1 1 4096 1 1 : tunables 24 12 0 : slabdata 1 1 0
-avc_node 518 708 64 59 1 : tunables 120 60 0 : slabdata 12 12 0
-selinux_inode_security 43199 46799 72 53 1 : tunables 120 60 0 : slabdata 883 883 0
-radix_tree_node 2964 3598 560 7 1 : tunables 54 27 0 : slabdata 514 514 0
-key_jar 5 20 192 20 1 : tunables 120 60 0 : slabdata 1 1 0
-buffer_head 24032 25493 104 37 1 : tunables 120 60 0 : slabdata 689 689 0
-nsproxy 0 0 48 77 1 : tunables 120 60 0 : slabdata 0 0 0
-vm_area_struct 2565 2565 200 19 1 : tunables 120 60 0 : slabdata 135 135 0
-mm_struct 40 40 1408 5 2 : tunables 24 12 0 : slabdata 8 8 0
-fs_cache 59 59 64 59 1 : tunables 120 60 0 : slabdata 1 1 0
-files_cache 44 44 704 11 2 : tunables 54 27 0 : slabdata 4 4 0
-signal_cache 91 91 1088 7 2 : tunables 24 12 0 : slabdata 13 13 0
-sighand_cache 90 90 2112 3 2 : tunables 24 12 0 : slabdata 30 30 0
-task_xstate 48 48 512 8 1 : tunables 54 27 0 : slabdata 6 6 0
-task_struct 96 96 2656 3 2 : tunables 24 12 0 : slabdata 32 32 0
-cred_jar 240 240 192 20 1 : tunables 120 60 0 : slabdata 12 12 0
-anon_vma_chain 1795 2079 48 77 1 : tunables 120 60 0 : slabdata 27 27 0
-anon_vma 1209 1380 40 92 1 : tunables 120 60 0 : slabdata 15 15 0
-pid 107 120 128 30 1 : tunables 120 60 0 : slabdata 4 4 0
-shared_policy_node 0 0 48 77 1 : tunables 120 60 0 : slabdata 0 0 0
-numa_policy 0 0 136 28 1 : tunables 120 60 0 : slabdata 0 0 0
-idr_layer_cache 281 287 544 7 1 : tunables 54 27 0 : slabdata 41 41 0
-size-4194304(DMA) 0 0 4194304 1 1024 : tunables 1 1 0 : slabdata 0 0 0
-size-4194304 0 0 4194304 1 1024 : tunables 1 1 0 : slabdata 0 0 0
-size-2097152(DMA) 0 0 2097152 1 512 : tunables 1 1 0 : slabdata 0 0 0
-size-2097152 0 0 2097152 1 512 : tunables 1 1 0 : slabdata 0 0 0
-size-1048576(DMA) 0 0 1048576 1 256 : tunables 1 1 0 : slabdata 0 0 0
-size-1048576 0 0 1048576 1 256 : tunables 1 1 0 : slabdata 0 0 0
-size-524288(DMA) 0 0 524288 1 128 : tunables 1 1 0 : slabdata 0 0 0
-size-524288 0 0 524288 1 128 : tunables 1 1 0 : slabdata 0 0 0
-size-262144(DMA) 0 0 262144 1 64 : tunables 1 1 0 : slabdata 0 0 0
-size-262144 0 0 262144 1 64 : tunables 1 1 0 : slabdata 0 0 0
-size-131072(DMA) 0 0 131072 1 32 : tunables 8 4 0 : slabdata 0 0 0
-size-131072 0 0 131072 1 32 : tunables 8 4 0 : slabdata 0 0 0
-size-65536(DMA) 0 0 65536 1 16 : tunables 8 4 0 : slabdata 0 0 0
-size-65536 2 2 65536 1 16 : tunables 8 4 0 : slabdata 2 2 0
-size-32768(DMA) 0 0 32768 1 8 : tunables 8 4 0 : slabdata 0 0 0
-size-32768 3 3 32768 1 8 : tunables 8 4 0 : slabdata 3 3 0
-size-16384(DMA) 0 0 16384 1 4 : tunables 8 4 0 : slabdata 0 0 0
-size-16384 7 7 16384 1 4 : tunables 8 4 0 : slabdata 7 7 0
-size-8192(DMA) 0 0 8192 1 2 : tunables 8 4 0 : slabdata 0 0 0
-size-8192 12 12 8192 1 2 : tunables 8 4 0 : slabdata 12 12 0
-size-4096(DMA) 0 0 4096 1 1 : tunables 24 12 0 : slabdata 0 0 0
-size-4096 119 119 4096 1 1 : tunables 24 12 0 : slabdata 119 119 0
-size-2048(DMA) 0 0 2048 2 1 : tunables 24 12 0 : slabdata 0 0 0
-size-2048 200 200 2048 2 1 : tunables 24 12 0 : slabdata 100 100 0
-size-1024(DMA) 0 0 1024 4 1 : tunables 54 27 0 : slabdata 0 0 0
-size-1024 578 588 1024 4 1 : tunables 54 27 0 : slabdata 147 147 0
-size-512(DMA) 0 0 512 8 1 : tunables 54 27 0 : slabdata 0 0 0
-size-512 608 608 512 8 1 : tunables 54 27 0 : slabdata 76 76 0
-size-256(DMA) 0 0 256 15 1 : tunables 120 60 0 : slabdata 0 0 0
-size-256 815 825 256 15 1 : tunables 120 60 0 : slabdata 55 55 0
-size-192(DMA) 0 0 192 20 1 : tunables 120 60 0 : slabdata 0 0 0
-size-192 1260 1260 192 20 1 : tunables 120 60 0 : slabdata 63 63 0
-size-128(DMA) 0 0 128 30 1 : tunables 120 60 0 : slabdata 0 0 0
-size-64(DMA) 0 0 64 59 1 : tunables 120 60 0 : slabdata 0 0 0
-size-64 23094 25783 64 59 1 : tunables 120 60 0 : slabdata 437 437 0
-size-32(DMA) 0 0 32 112 1 : tunables 120 60 0 : slabdata 0 0 0
-size-128 3271 3450 128 30 1 : tunables 120 60 0 : slabdata 115 115 0
-size-32 352497 352576 32 112 1 : tunables 120 60 0 : slabdata 3148 3148 0
-kmem_cache 183 183 32896 1 16 : tunables 8 4 0 : slabdata 183 183 0
+DirectMap4k: 144572 kB
+DirectMap2M: 16322560 kB
Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
- lo: 5243413 23981 0 0 0 0 0 0 5243413 23981 0 0 0 0 0 0
- eth0:25462133 318845 0 0 0 0 0 0 2039181 15966 0 0 0 0 0 0
- eth1: 1386405 18972 0 0 0 0 0 0 95634 1485 0 0 0 0 0 0
+virbr1-nic: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ vnet0: 128666 393 0 0 0 0 0 0 317089 3974 0 0 0 0 0 0
+ vnet5: 43924 524 0 0 0 0 0 0 221582 3857 0 0 0 0 0 0
+enp0s25: 31338290 49183 0 0 0 0 0 1035 10708826 44319 0 0 0 0 0 0
+virbr0-nic: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ vnet2: 69293 283 0 0 0 0 0 0 364106 3768 0 0 0 0 0 0
+ vnet4: 59178 194 0 0 0 0 0 0 238283 3592 0 0 0 0 0 0
+virbr0: 5345737 5274 0 0 0 0 0 0 1408922 5318 0 0 0 0 0 0
+ vnet1: 5034219 3505 0 0 0 0 0 0 1151009 7191 0 0 0 0 0 0
+ lo: 20864 210 0 0 0 0 0 0 20864 210 0 0 0 0 0 0
+virbr1: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+wlp3s0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ vnet3: 84293 375 0 0 0 0 0 0 279453 3662 0 0 0 0 0 0
subject=/O=example.com/CN=clica Signing Cert
issuer=/O=example.com/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA1WhcNMzgw
-MTAxMTIzNDA1WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzwXsp
-P4RsZUoDfQfm5O5bi5unhwl+BTrKIaOtl5TBxMau+qEdKa02DD7Bx6PCzLKhWiZ3
-/MrO7V/cXIBun97dF5Zr5kk+HJk+y3es+xoPd3doknvGQEC/0cSGLcEC7aQ/bEqi
-fw2CgEY5ffkEAnDrdvGGeqBfJJGft/tqmlZbeQIDAQABo1owWDAOBgNVHQ8BAf8E
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM3WhcNMzgw
+MTAxMTIzNDM3WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/GggX
+i+loP31ey0vxDpYe0mlBMHwC9ucGZo2HdTsJeOcGjqR4OTpZcOGbZB+Rhm+ZKZ+D
+lmIAjAit/sSJkqVj0hWlTdtSmgBuejsVqBHg3JwxVCnZmzo0+ILuod9tPcnVMjpz
+qj9CQAEcP+S329jlRKny14LCQzRc09QpszLuxwIDAQABo1owWDAOBgNVHQ8BAf8E
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw
-Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA
-Lq4cCtWMjqLHqf6lJUOBMsm+tgFcYDdxwkTquSZyUrbP1jrODkg5lQWNCdvB76B2
-tZQfMJ3F/kct2EAfsKbHqN3f+DARqPAR2qtOqzl3Ou5+TJjExKgojjzIAPFQzswH
-7v4aglpReaPBaVSNOZ7bMn/E8yRy3o466bhzdEIDcII=
+Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA
+yc6X34U2IKvN9y2EnNYwfsRPEE2LerSN9Tt3UgOuhuETJM7upwacJqOiN+HXQ0xp
+qhRxcDdrNy7MvymNLkc0mSiFGEjWG8dmZz/NFwGCzHSIhPxl6YryfbldbnqQLop0
+KpaftG9PQ4QxymUGjbvty95QvU2MlGA19NbXcLa4Vio=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: Certificate Authority
subject=/O=example.com/CN=clica CA
issuer=/O=example.com/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA0WhcNMzgw
-MTAxMTIzNDA0WjApMRQwEgYDVQQKEwtleGFtcGxlLmNvbTERMA8GA1UEAxMIY2xp
-Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL0wro64rve876glpdRh
-tD6qFY6iH2kCarFFq3WaKmfCvOjYmn4CJr7pL7J5DuvCFh7A0H8lD/on5NK3yqkX
-Yi6EUlaYWxeRo2/PuZYUGbCpejST41sibw9V2dT4MHLidjDShE0W9SfgiMmxfF02
-H5hLYswAGCL1kezsVeEJeH31AgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
-DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBAIn9+8uyQtaq8sBEohTl
-qyJQQeZk5xxaILYP/rCIxc+z5fgOh+usB9adaiD23RPuuD/P2c3UqHJQWqIUTu46
-eOKn9K7X7ndIH3WnaC/u4nysL+SIAug72/k1BAVGNQvyNQMhth6CfZTgY0tgcS0Z
-RSHyhbTD0HeiJDI281BoOJjm
------END CERTIFICATE-----
-Bag Attributes
- friendlyName: expired1.example.com
- localKeyID: 54 BE 44 70 F3 50 A6 ED E3 73 5C F3 DC BB E0 12 26 DC 31 A1
-subject=/CN=expired1.example.com
-issuer=/O=example.com/CN=clica Signing Cert
------BEGIN CERTIFICATE-----
-MIICiTCCAfKgAwIBAgIBZzANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt
-cGxlLmNvbTEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
-MzQwNloXDTEyMTIwMTEyMzQwNlowHzEdMBsGA1UEAxMUZXhwaXJlZDEuZXhhbXBs
-ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANUk3PULhKJc9xJO2RQU
-MeMwVInv1cw7Izt2VRgM+G9GgKlK8ZUN+99b7UW7zIbeOlOLjbbSBWxkg7FhynFk
-XL8xoYXgKutwSvCTxtCEzssUidmUcuQiLvGn5HVj4lBpzHU7VErirBi2yoYIEWuI
-5Rbv3nvvUhGZTVLIP4VLGjlHAgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
-A1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAj
-hiFodHRwOi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEE
-KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLmNvbS8wHwYDVR0R
-BBgwFoIUZXhwaXJlZDEuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQEFBQADgYEARc5Z
-IIljQytcuQHIwHLWNPG1JxCDpIBbJs9fRpN9KgsE2G+PIWK1YYP65f6VfiMt1SWT
-gx+qt9/WJX8g5r8xyr+pBIhjcMo9lACK/hMVCfm7/0GX5f5WAPmepK47KF7llp/5
-hAqmARw/XJgkEPmcZ0lRinR3J/eeRo1dNpP/IIU=
+MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM3WhcNMzgw
+MTAxMTIzNDM3WjApMRQwEgYDVQQKEwtleGFtcGxlLmNvbTERMA8GA1UEAxMIY2xp
+Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOh0bvMeu3S1F6t7vEWH
+86hJbiW97pjm8A930DFhe/UIlgPsAmCePZEMg6EtakY5Huva4kYeBUejbRtd3LE7
+q07sOVQqcKt+X8wXThBBHPk/7q6BL+je3cfuisxsS1neX3m5BOAhROPr6kvFDz4f
+SRb4s3jT3bRgh5a7vl5JRv9FAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
+DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBAA1n72ajcRt82cyo3R4P
+E9bqjhm4Y6d+a6vk4tPLk1uLD/EQw5ShAY6sM/FUzX8M4oyZ4A9Xouse0iXAVb50
+6gdqzfNtXeR5jIkTVNly0XJ99JfTgVHX0EcHPi3pffhiRCuNG2zEE6jIvUPym7UN
+3BXv6NWbBMOXAaVl99vckvxm
-----END CERTIFICATE-----
Bag Attributes
friendlyName: expired1.example.com
- localKeyID: 54 BE 44 70 F3 50 A6 ED E3 73 5C F3 DC BB E0 12 26 DC 31 A1
+ localKeyID: 1D 8D B3 EB E2 01 97 B8 A4 4F 93 B5 39 7A 10 AF 68 87 60 97
subject=/CN=expired1.example.com
issuer=/O=example.com/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICiTCCAfKgAwIBAgIBZzANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt
+MIICiTCCAfKgAwIBAgIBZzANBgkqhkiG9w0BAQsFADAzMRQwEgYDVQQKEwtleGFt
cGxlLmNvbTEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
-MzQwNloXDTEyMTIwMTEyMzQwNlowHzEdMBsGA1UEAxMUZXhwaXJlZDEuZXhhbXBs
-ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANUk3PULhKJc9xJO2RQU
-MeMwVInv1cw7Izt2VRgM+G9GgKlK8ZUN+99b7UW7zIbeOlOLjbbSBWxkg7FhynFk
-XL8xoYXgKutwSvCTxtCEzssUidmUcuQiLvGn5HVj4lBpzHU7VErirBi2yoYIEWuI
-5Rbv3nvvUhGZTVLIP4VLGjlHAgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
+MzQzOFoXDTEyMTIwMTEyMzQzOFowHzEdMBsGA1UEAxMUZXhwaXJlZDEuZXhhbXBs
+ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKmS9h3sQnaUqTtzQdvM
+dsszclutlJF9n2k/e/8Mz9xu/yiRc2pcWSFGNx2XmYIrLdrb79F0dHFejctZNOoB
+7dctDzyN8FOkbUnGcAYMW7RnsAcocnNoWqyR60w7BajfL5elVPKTtmwxCNOy7j5s
+pn3o70o0WaJP34SGaPdYfWBrAgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
A1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAj
hiFodHRwOi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEE
KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLmNvbS8wHwYDVR0R
-BBgwFoIUZXhwaXJlZDEuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQEFBQADgYEARc5Z
-IIljQytcuQHIwHLWNPG1JxCDpIBbJs9fRpN9KgsE2G+PIWK1YYP65f6VfiMt1SWT
-gx+qt9/WJX8g5r8xyr+pBIhjcMo9lACK/hMVCfm7/0GX5f5WAPmepK47KF7llp/5
-hAqmARw/XJgkEPmcZ0lRinR3J/eeRo1dNpP/IIU=
+BBgwFoIUZXhwaXJlZDEuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADgYEAuW6u
+xSxwfUv1NIJQIGyDPf9kEi7nPch1u1ta7E6usS3nlH1GfYNYTdBudLABm4sU44iD
+1I9QHqTfGfmFsKWtIG8XQE/tTW9DqOtht0j6WTxfeZXqCFlIJhwr1DrvEkKw/DPE
+kxhqh7U8uIf2h9UXIa1agAZQ2q9pnPvtu7hsMuc=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA1WhcNMzgw\r
-MTAxMTIzNDA1WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp\r
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzwXsp\r
-P4RsZUoDfQfm5O5bi5unhwl+BTrKIaOtl5TBxMau+qEdKa02DD7Bx6PCzLKhWiZ3\r
-/MrO7V/cXIBun97dF5Zr5kk+HJk+y3es+xoPd3doknvGQEC/0cSGLcEC7aQ/bEqi\r
-fw2CgEY5ffkEAnDrdvGGeqBfJJGft/tqmlZbeQIDAQABo1owWDAOBgNVHQ8BAf8E\r
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM3WhcNMzgw\r
+MTAxMTIzNDM3WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp\r
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/GggX\r
+i+loP31ey0vxDpYe0mlBMHwC9ucGZo2HdTsJeOcGjqR4OTpZcOGbZB+Rhm+ZKZ+D\r
+lmIAjAit/sSJkqVj0hWlTdtSmgBuejsVqBHg3JwxVCnZmzo0+ILuod9tPcnVMjpz\r
+qj9CQAEcP+S329jlRKny14LCQzRc09QpszLuxwIDAQABo1owWDAOBgNVHQ8BAf8E\r
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw\r
-Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA\r
-Lq4cCtWMjqLHqf6lJUOBMsm+tgFcYDdxwkTquSZyUrbP1jrODkg5lQWNCdvB76B2\r
-tZQfMJ3F/kct2EAfsKbHqN3f+DARqPAR2qtOqzl3Ou5+TJjExKgojjzIAPFQzswH\r
-7v4aglpReaPBaVSNOZ7bMn/E8yRy3o466bhzdEIDcII=
+Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA\r
+yc6X34U2IKvN9y2EnNYwfsRPEE2LerSN9Tt3UgOuhuETJM7upwacJqOiN+HXQ0xp\r
+qhRxcDdrNy7MvymNLkc0mSiFGEjWG8dmZz/NFwGCzHSIhPxl6YryfbldbnqQLop0\r
+KpaftG9PQ4QxymUGjbvty95QvU2MlGA19NbXcLa4Vio=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: expired1.example.com
- localKeyID: 54 BE 44 70 F3 50 A6 ED E3 73 5C F3 DC BB E0 12 26 DC 31 A1
+ localKeyID: 1D 8D B3 EB E2 01 97 B8 A4 4F 93 B5 39 7A 10 AF 68 87 60 97
Key Attributes: <No Attributes>
-----BEGIN ENCRYPTED PRIVATE KEY-----
-MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIEJETKcyNPKkCAggA
-MBQGCCqGSIb3DQMHBAj+HLWzdCLulASCAoCle4sKpW54xzwgFBCtdLDXFO55QrNL
-rjiwWrmMDKP/SQTu6srl4wrB75aghZQTv9yuvhhiyrkEUm87m+J/scLIE8XEMiDv
-64S0nsLkvRt/5ysZnAVHbpgR6GBHCa+aMSFLZcWeZ4mRRePJy3dxi2MID9Cu7P/Z
-llAbQHC4yYAO/sboesY4k7Qp4x0Q1fwVqrhl/N2BtuBHJeeU/mug2SXJl7m3panu
-cxUko+aGwHr/p3xQqHpCZ6RSTo1h+N8DqJHVs57JrN5l5/DYJbuo53MQpbahzLpL
-SIXYq6lAni05+B88hXDW5ZPNMQwnjPL6SVSLUH2aDntJY5Ezor74NMSXKOmVf++q
-MqUbxf5EpzwW/H/3clXA0UCoUXs6/Xr7DydsAyORMLFS7CI+ehF48BAhwYcpEjGv
-uQyZdWsJMU5qaB3XnGFTwnsted1oVszu1FCqtQntfeuuG1V8s4LZgPtP25sE6zFP
-NGvFU5SCkuoj5+lhbsFSoF6YjJO5rcbIbd3OuUUZgo6posHeoo49T7gI0G563E7E
-KcMhpYR+/ayHGWRXm4J92x1X7NGCbbF+j1if76U8zd0fpgrXWdZKP2npA5gfp0Ae
-un4KhQOSLSvJQ0Vq0Vzc788j9jeHowYlnNoItgfoUIJ1DaILZjEtXlXPkH/sUgkF
-jsvmcjsMp4DpwDacmjzMvAu76Aw3FX3iU9aR9iYEwD9XkRkZzSf1hhB7Cfs4RXQX
-Zj0y2KTP/cltPghKdc6Gx1UyzX3ZvHZNA516pV73vHpkMzkiiSo7Ko2Vz71m9QwA
-dIkyMUVP00uZo6prpM/SfkEbrVmH8nwRbVNfR1Gwkol2Bk8mer+ifI+L
+MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQId4zaw1+hp4UCAggA
+MBQGCCqGSIb3DQMHBAhWhjpnf3JJfwSCAoBwGvY8Z+AUn2O1j9MqHrwj9U/+uPQH
+0I4dumc8zqOkNZ4XvyDN7An8BlKPFSIkrB8+/AliWNhhmk80/7kB7XZ8BrqZ1Lyj
+CuMJO4u1Pg7aCO2eO7Uq/0H7WgnZOFsJ+BmL7ozu7LXZVuVZXIgtb76Cmmv1+Llf
+31UgEHMHugNyCS1t9aSVXzUQwaFOporeDuQucF2xZK+KlIZ+SA9es9zPubFNrSh6
+lz8k6muz/TVlv+mUQ1NJjfRi2mlgtmnVBtkcAzW9JULt+QGSoTeWCVekCma/hbWG
+I2dhyF1ILC1wNRTe4rW1jigIAvKSWu1iZmnPEtMLaax3uVUifszq/WEazlpuk7jo
+7AmuG8s0XRTW6MH3idNN8LJQ07ZaMZrDk9VeBgrfM8LfIBgWj/QOgObJdqz1YpPg
+52tNLBThqto2QFV8Nyw8wCYLdPALEapHnmIWHzpozyOyhhNJtxHqunnZ7lrihD2n
++yqMORMzAjNBgXgmrqhTfNFwK1bDGM+feBZWh/d9yLTgEeHIn12bjB619leBtUI5
+8+YaXbl8Z9s8h0OuF4Q1ix8R2WZdCAwy6W96B/HxqcWy6BsnapwkYQbc9ifHqAT9
+TXpnWJ/xYL7ZgUPzGGzu4FhZcHOtKO8SM1YOLJhe+Uws622M/7a+XPl9WL6Xvw8C
+J/Lq/RnHm0CbMOcAPk5IiMbWXi6oWaDEUI6HkcNDPWEMRNeZaBto7VBV3rhkohFO
+YpyAK+ttXGFo/iHr4VkFKZQ6AaUpkzE+DkLAPM+0x7Rrdm1NFNfP/WmPAP8vjrCT
+FdMBy5vCXtUsHVKl4Aa9ic/fAXPVO/xLuqY0vaSn4Krvj5H6tBbo8L7l
-----END ENCRYPTED PRIVATE KEY-----
Bag Attributes
friendlyName: expired1.example.com
- localKeyID: 54 BE 44 70 F3 50 A6 ED E3 73 5C F3 DC BB E0 12 26 DC 31 A1
+ localKeyID: 1D 8D B3 EB E2 01 97 B8 A4 4F 93 B5 39 7A 10 AF 68 87 60 97
subject=/CN=expired1.example.com
issuer=/O=example.com/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICiTCCAfKgAwIBAgIBZzANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt
+MIICiTCCAfKgAwIBAgIBZzANBgkqhkiG9w0BAQsFADAzMRQwEgYDVQQKEwtleGFt
cGxlLmNvbTEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
-MzQwNloXDTEyMTIwMTEyMzQwNlowHzEdMBsGA1UEAxMUZXhwaXJlZDEuZXhhbXBs
-ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANUk3PULhKJc9xJO2RQU
-MeMwVInv1cw7Izt2VRgM+G9GgKlK8ZUN+99b7UW7zIbeOlOLjbbSBWxkg7FhynFk
-XL8xoYXgKutwSvCTxtCEzssUidmUcuQiLvGn5HVj4lBpzHU7VErirBi2yoYIEWuI
-5Rbv3nvvUhGZTVLIP4VLGjlHAgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
+MzQzOFoXDTEyMTIwMTEyMzQzOFowHzEdMBsGA1UEAxMUZXhwaXJlZDEuZXhhbXBs
+ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKmS9h3sQnaUqTtzQdvM
+dsszclutlJF9n2k/e/8Mz9xu/yiRc2pcWSFGNx2XmYIrLdrb79F0dHFejctZNOoB
+7dctDzyN8FOkbUnGcAYMW7RnsAcocnNoWqyR60w7BajfL5elVPKTtmwxCNOy7j5s
+pn3o70o0WaJP34SGaPdYfWBrAgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
A1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAj
hiFodHRwOi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEE
KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLmNvbS8wHwYDVR0R
-BBgwFoIUZXhwaXJlZDEuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQEFBQADgYEARc5Z
-IIljQytcuQHIwHLWNPG1JxCDpIBbJs9fRpN9KgsE2G+PIWK1YYP65f6VfiMt1SWT
-gx+qt9/WJX8g5r8xyr+pBIhjcMo9lACK/hMVCfm7/0GX5f5WAPmepK47KF7llp/5
-hAqmARw/XJgkEPmcZ0lRinR3J/eeRo1dNpP/IIU=
+BBgwFoIUZXhwaXJlZDEuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADgYEAuW6u
+xSxwfUv1NIJQIGyDPf9kEi7nPch1u1ta7E6usS3nlH1GfYNYTdBudLABm4sU44iD
+1I9QHqTfGfmFsKWtIG8XQE/tTW9DqOtht0j6WTxfeZXqCFlIJhwr1DrvEkKw/DPE
+kxhqh7U8uIf2h9UXIa1agAZQ2q9pnPvtu7hsMuc=
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
-MIICXAIBAAKBgQDVJNz1C4SiXPcSTtkUFDHjMFSJ79XMOyM7dlUYDPhvRoCpSvGV
-DfvfW+1Fu8yG3jpTi4220gVsZIOxYcpxZFy/MaGF4CrrcErwk8bQhM7LFInZlHLk
-Ii7xp+R1Y+JQacx1O1RK4qwYtsqGCBFriOUW795771IRmU1SyD+FSxo5RwIDAQAB
-AoGAPhr3pw8sHoMoGtWOuyMHRkOW3npbuZ6hrXnVYaSl3waUBsAnlF72vSZ0BJWs
-CsBGDoHjURnxKpw/IzhzXIb53tNj5h8jIwxZfylqXQirkv7TfAW6WuxfAXwW7/Ca
-OQnriyz0UB8AVohZ6UZQG4MrHcUypHrEsw8uwEkdb4I4f0ECQQD+BOlQuRuVOZ26
-iKrJs4K0DrJHTD/3cLtRYNGWRAF+q+tG2hAu0L7Dh4BDYA62A21hEHBp1XCBBk8h
-2Q0rZ/uzAkEA1s5aq2tZCEPlvR+aRLJz4yEHAOtuj2wyVAq3weY/2SfDbtqTrHNa
-sRWHGx2ofyO22jHDRXG4GdyhvBhHAk9yHQJAQEF5y4OnqI3UilT77t3L2ERHcKWn
-IK6Rk7pMChjVz/cpItkScuU2/DsQhPqNfhlL19vSs9LcDKdN6SAAptQ85QJBALy0
-0Aaj6bVPILbC2p3bP9+bFjICokAxRw151PDsu86kFhZ+wxjOxi+nv+dcaLg4wdxx
-tyB8xMVDhHpfwZIQBSkCQDmP11qxf43phqxiUo8T6uqMG7DfA5YdDtGlV43sgKmd
-8iuIc26FKxdvr3kxn5w0qEIe1QqVisUHGvBYRfrF3so=
+MIICXAIBAAKBgQCpkvYd7EJ2lKk7c0HbzHbLM3JbrZSRfZ9pP3v/DM/cbv8okXNq
+XFkhRjcdl5mCKy3a2+/RdHRxXo3LWTTqAe3XLQ88jfBTpG1JxnAGDFu0Z7AHKHJz
+aFqsketMOwWo3y+XpVTyk7ZsMQjTsu4+bKZ96O9KNFmiT9+Ehmj3WH1gawIDAQAB
+AoGAfQ/j8CGkyuvM/Al/Euny2t5wgui736l0fhzSCEKcsogyKutK4bCGE6JDV9HM
+51GNGhKHBkUK8+m2TbjW65bMn2hJxlViQLuvnb2mlZZOLOpEIdbpV1yRENztrx2l
+f7ZND+EjsItH78wnsXa+qgxi8sUMaALOeQ7yQgOjqO1O5VECQQDQ24S+iYOfvkL8
+xzHYGjKOyQrEWaDkZKq0we6adF/Aylc+MMida5W11ZVdjDzTrspamJomF9MOJkiQ
+NYQ+jii1AkEAz9mEA9rWLFIY+BjoDPUP3V3xup0uDLlwlN9SGwo//88+Zlam0O2t
+ebWSFvfslgybE2FDtFohudnwsE90UzC4nwJAQ4oJVjhP6TN0pBuiQbjPCp92rOIz
+BkiLb2KbTzU81bJZHhJWfZmR0zhbUeIMtYN7imp4xsLDjHrS0leMCVKdVQJAZKgY
+MK237rrLcMrPBgdf6XpnaFJaTLs5dD86SfIK0F2TAIiSPLf9vOVbnFfwcTIln5sI
+6LyFfLW4xAmWcfs0TQJBALePhUzat8EM5Ao1a5vmAVOH6Yp2lh/sdSF2wU3Rr/bt
+jfT+7rX1Ue5hOgjJ+c8K4f2KQU4yX7HtkwmFFg6W1/s=
-----END RSA PRIVATE KEY-----
subject=/O=example.com/CN=clica Signing Cert
issuer=/O=example.com/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA1WhcNMzgw
-MTAxMTIzNDA1WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzwXsp
-P4RsZUoDfQfm5O5bi5unhwl+BTrKIaOtl5TBxMau+qEdKa02DD7Bx6PCzLKhWiZ3
-/MrO7V/cXIBun97dF5Zr5kk+HJk+y3es+xoPd3doknvGQEC/0cSGLcEC7aQ/bEqi
-fw2CgEY5ffkEAnDrdvGGeqBfJJGft/tqmlZbeQIDAQABo1owWDAOBgNVHQ8BAf8E
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM3WhcNMzgw
+MTAxMTIzNDM3WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/GggX
+i+loP31ey0vxDpYe0mlBMHwC9ucGZo2HdTsJeOcGjqR4OTpZcOGbZB+Rhm+ZKZ+D
+lmIAjAit/sSJkqVj0hWlTdtSmgBuejsVqBHg3JwxVCnZmzo0+ILuod9tPcnVMjpz
+qj9CQAEcP+S329jlRKny14LCQzRc09QpszLuxwIDAQABo1owWDAOBgNVHQ8BAf8E
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw
-Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA
-Lq4cCtWMjqLHqf6lJUOBMsm+tgFcYDdxwkTquSZyUrbP1jrODkg5lQWNCdvB76B2
-tZQfMJ3F/kct2EAfsKbHqN3f+DARqPAR2qtOqzl3Ou5+TJjExKgojjzIAPFQzswH
-7v4aglpReaPBaVSNOZ7bMn/E8yRy3o466bhzdEIDcII=
+Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA
+yc6X34U2IKvN9y2EnNYwfsRPEE2LerSN9Tt3UgOuhuETJM7upwacJqOiN+HXQ0xp
+qhRxcDdrNy7MvymNLkc0mSiFGEjWG8dmZz/NFwGCzHSIhPxl6YryfbldbnqQLop0
+KpaftG9PQ4QxymUGjbvty95QvU2MlGA19NbXcLa4Vio=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: Certificate Authority
subject=/O=example.com/CN=clica CA
issuer=/O=example.com/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA0WhcNMzgw
-MTAxMTIzNDA0WjApMRQwEgYDVQQKEwtleGFtcGxlLmNvbTERMA8GA1UEAxMIY2xp
-Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL0wro64rve876glpdRh
-tD6qFY6iH2kCarFFq3WaKmfCvOjYmn4CJr7pL7J5DuvCFh7A0H8lD/on5NK3yqkX
-Yi6EUlaYWxeRo2/PuZYUGbCpejST41sibw9V2dT4MHLidjDShE0W9SfgiMmxfF02
-H5hLYswAGCL1kezsVeEJeH31AgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
-DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBAIn9+8uyQtaq8sBEohTl
-qyJQQeZk5xxaILYP/rCIxc+z5fgOh+usB9adaiD23RPuuD/P2c3UqHJQWqIUTu46
-eOKn9K7X7ndIH3WnaC/u4nysL+SIAug72/k1BAVGNQvyNQMhth6CfZTgY0tgcS0Z
-RSHyhbTD0HeiJDI281BoOJjm
------END CERTIFICATE-----
-Bag Attributes
- friendlyName: expired2.example.com
- localKeyID: C6 AF 42 A4 62 E4 DE A3 FA 0A 88 C9 9F 8A 3A 95 F8 BD 5F 68
-subject=/CN=expired2.example.com
-issuer=/O=example.com/CN=clica Signing Cert
------BEGIN CERTIFICATE-----
-MIICijCCAfOgAwIBAgICAMswDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhh
-bXBsZS5jb20xGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDEx
-MjM0MDdaFw0xMjEyMDExMjM0MDdaMB8xHTAbBgNVBAMTFGV4cGlyZWQyLmV4YW1w
-bGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC1CGIJL05trceWyUkd
-Jdp3QFiQGuYn+nRTLUOOJR4v9cYUFomihLdPZ2ElUZuQUQaP3mo0rNwSZBnUWaS+
-2MBOInu3DwBMhCqX2lPmVtOoj9PC0jsxl18pIYW5tKKpVdSVuTXZa/bUCbf351DN
-clNIEfh7zFXevzbwrI2x5qrteQIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
-BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
-I4YhaHR0cDovL2NybC5leGFtcGxlLmNvbS9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
-BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5jb20vMB8GA1Ud
-EQQYMBaCFGV4cGlyZWQyLmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBBQUAA4GBAGNy
-FvCmqIUPn/BSasd66jOrg46+YkCh/YN8zt1ysQr5ZgM+mP26W+el9JiknnD17G26
-ImFaxP+X8ghPM54sErbAB3euFpjsdqVqdOr2g7SJJnVvD0XygYqxEy7h7XAl8M9n
-ofNIBV2IWKQ1wLHnHquM1v5e3s1dL0ptyfBMPhDE
+MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM3WhcNMzgw
+MTAxMTIzNDM3WjApMRQwEgYDVQQKEwtleGFtcGxlLmNvbTERMA8GA1UEAxMIY2xp
+Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOh0bvMeu3S1F6t7vEWH
+86hJbiW97pjm8A930DFhe/UIlgPsAmCePZEMg6EtakY5Huva4kYeBUejbRtd3LE7
+q07sOVQqcKt+X8wXThBBHPk/7q6BL+je3cfuisxsS1neX3m5BOAhROPr6kvFDz4f
+SRb4s3jT3bRgh5a7vl5JRv9FAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
+DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBAA1n72ajcRt82cyo3R4P
+E9bqjhm4Y6d+a6vk4tPLk1uLD/EQw5ShAY6sM/FUzX8M4oyZ4A9Xouse0iXAVb50
+6gdqzfNtXeR5jIkTVNly0XJ99JfTgVHX0EcHPi3pffhiRCuNG2zEE6jIvUPym7UN
+3BXv6NWbBMOXAaVl99vckvxm
-----END CERTIFICATE-----
Bag Attributes
friendlyName: expired2.example.com
- localKeyID: C6 AF 42 A4 62 E4 DE A3 FA 0A 88 C9 9F 8A 3A 95 F8 BD 5F 68
+ localKeyID: 48 F3 D4 21 D9 EF 74 92 A0 CB E0 C0 CB E6 A7 51 91 BA CD DA
subject=/CN=expired2.example.com
issuer=/O=example.com/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICijCCAfOgAwIBAgICAMswDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhh
+MIICijCCAfOgAwIBAgICAMswDQYJKoZIhvcNAQELBQAwMzEUMBIGA1UEChMLZXhh
bXBsZS5jb20xGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDEx
-MjM0MDdaFw0xMjEyMDExMjM0MDdaMB8xHTAbBgNVBAMTFGV4cGlyZWQyLmV4YW1w
-bGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC1CGIJL05trceWyUkd
-Jdp3QFiQGuYn+nRTLUOOJR4v9cYUFomihLdPZ2ElUZuQUQaP3mo0rNwSZBnUWaS+
-2MBOInu3DwBMhCqX2lPmVtOoj9PC0jsxl18pIYW5tKKpVdSVuTXZa/bUCbf351DN
-clNIEfh7zFXevzbwrI2x5qrteQIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
+MjM0MzhaFw0xMjEyMDExMjM0MzhaMB8xHTAbBgNVBAMTFGV4cGlyZWQyLmV4YW1w
+bGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDmqrEeyxGQtG7IJoUJ
+0VHcLaQ5naoruyTS0vqijmyQPJjPNA+FiZypHjhIT9M0TMa4Ynu/DDKRZm1p0XPw
+Ntrg5hGnae6HucyOCk0Xpftz2A5OmP2scYfUV8sMC9a6Wf0WQxOzUxGwAOJK1pIz
+eHAs0YBUPlDmFv49fAtKk6IcQwIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
I4YhaHR0cDovL2NybC5leGFtcGxlLmNvbS9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5jb20vMB8GA1Ud
-EQQYMBaCFGV4cGlyZWQyLmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBBQUAA4GBAGNy
-FvCmqIUPn/BSasd66jOrg46+YkCh/YN8zt1ysQr5ZgM+mP26W+el9JiknnD17G26
-ImFaxP+X8ghPM54sErbAB3euFpjsdqVqdOr2g7SJJnVvD0XygYqxEy7h7XAl8M9n
-ofNIBV2IWKQ1wLHnHquM1v5e3s1dL0ptyfBMPhDE
+EQQYMBaCFGV4cGlyZWQyLmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4GBAL3Z
+BanvuX9pUeYcY4Z3BTR9XiUpcGKWqjUtuQtPJOjGfOVIinVfRc0NQt6p4G0eeAcG
+Ap4USuH8+Ijq7rENwcd/StkZNU+oeMu+Ip2dqSyQw0HAjuSVtZ1e/ZmneKs69MlI
+nG905GotlbcyM0IXWJZiJojzpTAhRJ1fkX3z/NY5
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA1WhcNMzgw\r
-MTAxMTIzNDA1WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp\r
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzwXsp\r
-P4RsZUoDfQfm5O5bi5unhwl+BTrKIaOtl5TBxMau+qEdKa02DD7Bx6PCzLKhWiZ3\r
-/MrO7V/cXIBun97dF5Zr5kk+HJk+y3es+xoPd3doknvGQEC/0cSGLcEC7aQ/bEqi\r
-fw2CgEY5ffkEAnDrdvGGeqBfJJGft/tqmlZbeQIDAQABo1owWDAOBgNVHQ8BAf8E\r
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM3WhcNMzgw\r
+MTAxMTIzNDM3WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp\r
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/GggX\r
+i+loP31ey0vxDpYe0mlBMHwC9ucGZo2HdTsJeOcGjqR4OTpZcOGbZB+Rhm+ZKZ+D\r
+lmIAjAit/sSJkqVj0hWlTdtSmgBuejsVqBHg3JwxVCnZmzo0+ILuod9tPcnVMjpz\r
+qj9CQAEcP+S329jlRKny14LCQzRc09QpszLuxwIDAQABo1owWDAOBgNVHQ8BAf8E\r
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw\r
-Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA\r
-Lq4cCtWMjqLHqf6lJUOBMsm+tgFcYDdxwkTquSZyUrbP1jrODkg5lQWNCdvB76B2\r
-tZQfMJ3F/kct2EAfsKbHqN3f+DARqPAR2qtOqzl3Ou5+TJjExKgojjzIAPFQzswH\r
-7v4aglpReaPBaVSNOZ7bMn/E8yRy3o466bhzdEIDcII=
+Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA\r
+yc6X34U2IKvN9y2EnNYwfsRPEE2LerSN9Tt3UgOuhuETJM7upwacJqOiN+HXQ0xp\r
+qhRxcDdrNy7MvymNLkc0mSiFGEjWG8dmZz/NFwGCzHSIhPxl6YryfbldbnqQLop0\r
+KpaftG9PQ4QxymUGjbvty95QvU2MlGA19NbXcLa4Vio=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: expired2.example.com
- localKeyID: C6 AF 42 A4 62 E4 DE A3 FA 0A 88 C9 9F 8A 3A 95 F8 BD 5F 68
+ localKeyID: 48 F3 D4 21 D9 EF 74 92 A0 CB E0 C0 CB E6 A7 51 91 BA CD DA
Key Attributes: <No Attributes>
-----BEGIN ENCRYPTED PRIVATE KEY-----
-MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIcKV+HaIPaikCAggA
-MBQGCCqGSIb3DQMHBAi+airF86oTpgSCAoAQpQyqLzxpkwzliQxxYsv2vMv+YzZy
-k0w0p7KUl8ZP3n/UxfM7oPZqASlDkaGEMTcXG7CbH3f5geqYt3utdD4DoaKwDWcc
-FI9NlgyqNrYttaF6cTI42OytDlafmQodvD0Wky3OVN3m+RvSNZqXkQb1zeS5Z2OR
-exjM7K7IVqy33O4ShrrI7/tajBneKPZos/z56ubDKcSJvJw6D50xxzWXt9QiQR1r
-be8vr2HP5kg/XnckX9KByMACqIBjGaWyG6AzvSmsmy0AWME5b+wTSDUxPaVcjLt0
-OjqWz4SsgS3xxlr2yWQzyxJgSQilNcaj9w0/z/3lEinDt+osTulMl0bT5mGm736c
-P7v5A7qoBWgjBbgs61NzZy9+pP6721zBjXPG9UAEkSdjkx7gxhLe4ZN5j4Jvz4AW
-dpHtcEntmmVF8aYjoCTNhHCpKaiP9NVr3pIuo6vXTufDmkwEEB56sKt/Cgku4jdC
-agvMlgAy4iQTZcKPwMc6h9dsfLaj0NBdJ1t8kKkz0dD1VchlX5YoYcua6RSmvVM0
-ziCyznqOB2meSLLAMLcXQAt9waVATgy3UcaW9f7zr4Dq2kTKkfjAHJPArNStWmkR
-XdiTTNJ5eiO7lEM3uY9PLpYpZBavbA3D02RRbxDds0PemJzb0SQicInPkLs+gjzJ
-Dvj9LGm2/3v9Wlu6AJttYHTur7pYk5vOyJ8QhpnwYe3a1JZ6jQ1NurDRK/UHEzOV
-GaWvrsWPzdVS9kJSmHnHdKMxXMZ6HLPgkBwEOQormnAxtIOR3HP43/UzV5RlmO0c
-UHjiZgr+rwe88fd6SHegk7KZkNPboZMlVAA9kIk/+0OzySiLDtCsphse
+MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQI49ai+j3zSLECAggA
+MBQGCCqGSIb3DQMHBAiunIlM+CtJBwSCAoAWHvPMKjy3JnV/lSz9asSUbqZcTCqT
+61bqwCLxtG4L+KweqzwantJyVJLdX1+g/LqU318xXB/2pF2bkEYKJylywPB+UZty
+o/u434lz/qPc67vRW8PzITaD6PG4pc69yTEluhTc/RCIj1AmKkYPAaEfxthlNTnP
+Eu+BpP+6g944wyLuejWDVg0e8LL64+vKYuyeDm1+gl6hD+NIu0d+1KztmWJQNT2K
+PBwkC0GqC89sMqQbV8tJYK8PwNB6HxnlhX+7C64z+hUzHWppne1FMuqRmN9e/yyT
+2m65Uw7DCEx2dSlIsoxKXeLraep1SfWSwSIZ9WTkP7QbRIqrE0SjNTet1imFelyN
+M3G8SC+XwxE2DrkyfsxF3NYyoLJVPLlGTDjy4tqZOO1E3QVuqlFmv4vUDBVFiqkI
+ESsBuQqfO1XRq9KogsmT3x2t/wedTywv4mOOnJCBB1JRNrqlsfpbfOYujrDRoIfp
+BltSHq76QMwBy0y5CWtmVDIBtO7+5x7aoX/XqaBw3y7SoaG7yWtHEPyc0AMVx3xG
+7umvkew0wNs1ns+2P6obpnOZYRWbtuYiBenYJVF6YXzNbHA8xtab3+hYEtZLarms
+Xs3n5UY854cmGvZBWYwd37/rTfoMg522mN7+Or6nKYLhBXbCm2HKJ+TZIzS1BPMc
+Fn21GheAmtOlKJwQ6JXMDwLgjMXe+409HYySsmst8RNQ+ygDWLxb57sl2vob2xLP
++s/fd+W0VXy042xrEQzaDktuHMnFM5RtEjL7c8I9KrPTV+6xwdn7iZIQPl06SGwv
+fZN9oFqADkhCoEWi8gFg6pR/WfLyMEDl5K1jt79GbJBN4ZmVGl4Ri7El
-----END ENCRYPTED PRIVATE KEY-----
Bag Attributes
friendlyName: expired2.example.com
- localKeyID: C6 AF 42 A4 62 E4 DE A3 FA 0A 88 C9 9F 8A 3A 95 F8 BD 5F 68
+ localKeyID: 48 F3 D4 21 D9 EF 74 92 A0 CB E0 C0 CB E6 A7 51 91 BA CD DA
subject=/CN=expired2.example.com
issuer=/O=example.com/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICijCCAfOgAwIBAgICAMswDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhh
+MIICijCCAfOgAwIBAgICAMswDQYJKoZIhvcNAQELBQAwMzEUMBIGA1UEChMLZXhh
bXBsZS5jb20xGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDEx
-MjM0MDdaFw0xMjEyMDExMjM0MDdaMB8xHTAbBgNVBAMTFGV4cGlyZWQyLmV4YW1w
-bGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC1CGIJL05trceWyUkd
-Jdp3QFiQGuYn+nRTLUOOJR4v9cYUFomihLdPZ2ElUZuQUQaP3mo0rNwSZBnUWaS+
-2MBOInu3DwBMhCqX2lPmVtOoj9PC0jsxl18pIYW5tKKpVdSVuTXZa/bUCbf351DN
-clNIEfh7zFXevzbwrI2x5qrteQIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
+MjM0MzhaFw0xMjEyMDExMjM0MzhaMB8xHTAbBgNVBAMTFGV4cGlyZWQyLmV4YW1w
+bGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDmqrEeyxGQtG7IJoUJ
+0VHcLaQ5naoruyTS0vqijmyQPJjPNA+FiZypHjhIT9M0TMa4Ynu/DDKRZm1p0XPw
+Ntrg5hGnae6HucyOCk0Xpftz2A5OmP2scYfUV8sMC9a6Wf0WQxOzUxGwAOJK1pIz
+eHAs0YBUPlDmFv49fAtKk6IcQwIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
I4YhaHR0cDovL2NybC5leGFtcGxlLmNvbS9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5jb20vMB8GA1Ud
-EQQYMBaCFGV4cGlyZWQyLmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBBQUAA4GBAGNy
-FvCmqIUPn/BSasd66jOrg46+YkCh/YN8zt1ysQr5ZgM+mP26W+el9JiknnD17G26
-ImFaxP+X8ghPM54sErbAB3euFpjsdqVqdOr2g7SJJnVvD0XygYqxEy7h7XAl8M9n
-ofNIBV2IWKQ1wLHnHquM1v5e3s1dL0ptyfBMPhDE
+EQQYMBaCFGV4cGlyZWQyLmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4GBAL3Z
+BanvuX9pUeYcY4Z3BTR9XiUpcGKWqjUtuQtPJOjGfOVIinVfRc0NQt6p4G0eeAcG
+Ap4USuH8+Ijq7rENwcd/StkZNU+oeMu+Ip2dqSyQw0HAjuSVtZ1e/ZmneKs69MlI
+nG905GotlbcyM0IXWJZiJojzpTAhRJ1fkX3z/NY5
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
-MIICXQIBAAKBgQC1CGIJL05trceWyUkdJdp3QFiQGuYn+nRTLUOOJR4v9cYUFomi
-hLdPZ2ElUZuQUQaP3mo0rNwSZBnUWaS+2MBOInu3DwBMhCqX2lPmVtOoj9PC0jsx
-l18pIYW5tKKpVdSVuTXZa/bUCbf351DNclNIEfh7zFXevzbwrI2x5qrteQIDAQAB
-AoGAAaTA1xqB2McSH9FWA5i7YgfIhg5odoZ0lei8S0cU/hR6JuaJe1s/Gs5yeFdE
-VUwXBilbx3ymRth3z5C8ySrInCkRewoskB4CBzAqEXxgq/njX6cvCdqf/6afzgvE
-YQ6UTSASRYnd+dUrdz5m+XP8BU3iW+9aT0ZRWnc4nkKb3gECQQDq4OC7PWtqU1b/
-8fDqp5Loejw1zSVhBTCEyfXKP+s+uWfLoM4e4krGxhjBgBrNS0Qdv006J/nDUPlK
-0uT12UTBAkEAxU/tR3RytfW3hRUYFMNhkUGhC/906IoKajKoIiK17vBIA1qynAZ3
-jviT6Q5JQCYCRh25PHQvk+/0jZRNDuG+uQJAPkyNbzyYTCh00Ah1VVhDUCRz6fVS
-78v3lZEX/6A6nnWBAXLSmUB+gwCyOkjnUwKeu6EtM7q8tcC5js4naspJQQJBAMEc
-vvCmafbo7JrV0GHR79YI06Q4e6V0JUlXFvOB4WpfxTtzM0g9lBpb8/evQcYE7UjO
-opMma8JwoXtH4DtmehECQQDWG5T5BXZMPkVSSG9pF6BYlLZveYK6Y7PK6naYj7VN
-gR8uaIdeHDlIfvSCxTdiTNeC0y5bEKGNgAjkfrZNsNwn
+MIICXAIBAAKBgQDmqrEeyxGQtG7IJoUJ0VHcLaQ5naoruyTS0vqijmyQPJjPNA+F
+iZypHjhIT9M0TMa4Ynu/DDKRZm1p0XPwNtrg5hGnae6HucyOCk0Xpftz2A5OmP2s
+cYfUV8sMC9a6Wf0WQxOzUxGwAOJK1pIzeHAs0YBUPlDmFv49fAtKk6IcQwIDAQAB
+AoGBAM069dhWCUzcnOyMCTaQ/OqP2VxCAZRjMAI8IS/c1I8Iu1UwFtdTdwWpk54T
+F/GilfSb+0oiSiPAJH1QFH2X8OkUkPgv0DHtSW+0fwJN/nK4tTuV/8BVVKsUt0v2
+5xLnK+itUSjoDCMEW43Win6lIj9tggGSkY27emE+y7BvomQRAkEA9ui7p9cB3dNj
+KwbW6ltpjzYutUs0GAA4qqLswqRZ/k+T+PldtejfYmROL6ibVSnHJ70TqQApdSGc
+TkxwGQjNhwJBAO8o3Wy5hLGXhbDW1OSuIUaodj3lG1Bd+irwHb+Zb5Csmu5u/NzO
+SlxYTurkDqkkFHFyMXyehfoZIAlT+opASmUCQBPvCC9tuVXaWhhALhuvk58fRbgX
+QTZq1ihYjPrN4AIbFJw2La2hBl/gLzvDxf6jJ9P6fNrZC3/MXd0oaKhswIMCQCrD
+7OxPNDopdR+NGt6VgJ/I6fPhbwPs+hoJe9hSEJAXPVEbiZ3WSZe/tsTr6O8342vx
+1oWJNz3klkT0vl1QZ70CQDMfkK5odTziL5HXcekpOO0sa4r5kxQL5+yCnfJ2nmZM
+N406ISc2/TxDgY+QnOZyioIXt04hhBVAXKACTXboeGo=
-----END RSA PRIVATE KEY-----
subject=/O=example.com/CN=clica Signing Cert
issuer=/O=example.com/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA1WhcNMzgw
-MTAxMTIzNDA1WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzwXsp
-P4RsZUoDfQfm5O5bi5unhwl+BTrKIaOtl5TBxMau+qEdKa02DD7Bx6PCzLKhWiZ3
-/MrO7V/cXIBun97dF5Zr5kk+HJk+y3es+xoPd3doknvGQEC/0cSGLcEC7aQ/bEqi
-fw2CgEY5ffkEAnDrdvGGeqBfJJGft/tqmlZbeQIDAQABo1owWDAOBgNVHQ8BAf8E
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM3WhcNMzgw
+MTAxMTIzNDM3WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/GggX
+i+loP31ey0vxDpYe0mlBMHwC9ucGZo2HdTsJeOcGjqR4OTpZcOGbZB+Rhm+ZKZ+D
+lmIAjAit/sSJkqVj0hWlTdtSmgBuejsVqBHg3JwxVCnZmzo0+ILuod9tPcnVMjpz
+qj9CQAEcP+S329jlRKny14LCQzRc09QpszLuxwIDAQABo1owWDAOBgNVHQ8BAf8E
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw
-Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA
-Lq4cCtWMjqLHqf6lJUOBMsm+tgFcYDdxwkTquSZyUrbP1jrODkg5lQWNCdvB76B2
-tZQfMJ3F/kct2EAfsKbHqN3f+DARqPAR2qtOqzl3Ou5+TJjExKgojjzIAPFQzswH
-7v4aglpReaPBaVSNOZ7bMn/E8yRy3o466bhzdEIDcII=
+Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA
+yc6X34U2IKvN9y2EnNYwfsRPEE2LerSN9Tt3UgOuhuETJM7upwacJqOiN+HXQ0xp
+qhRxcDdrNy7MvymNLkc0mSiFGEjWG8dmZz/NFwGCzHSIhPxl6YryfbldbnqQLop0
+KpaftG9PQ4QxymUGjbvty95QvU2MlGA19NbXcLa4Vio=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: Certificate Authority
subject=/O=example.com/CN=clica CA
issuer=/O=example.com/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA0WhcNMzgw
-MTAxMTIzNDA0WjApMRQwEgYDVQQKEwtleGFtcGxlLmNvbTERMA8GA1UEAxMIY2xp
-Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL0wro64rve876glpdRh
-tD6qFY6iH2kCarFFq3WaKmfCvOjYmn4CJr7pL7J5DuvCFh7A0H8lD/on5NK3yqkX
-Yi6EUlaYWxeRo2/PuZYUGbCpejST41sibw9V2dT4MHLidjDShE0W9SfgiMmxfF02
-H5hLYswAGCL1kezsVeEJeH31AgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
-DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBAIn9+8uyQtaq8sBEohTl
-qyJQQeZk5xxaILYP/rCIxc+z5fgOh+usB9adaiD23RPuuD/P2c3UqHJQWqIUTu46
-eOKn9K7X7ndIH3WnaC/u4nysL+SIAug72/k1BAVGNQvyNQMhth6CfZTgY0tgcS0Z
-RSHyhbTD0HeiJDI281BoOJjm
------END CERTIFICATE-----
-Bag Attributes
- friendlyName: revoked1.example.com
- localKeyID: 20 71 F8 DC E7 30 30 96 0E C4 15 76 D6 41 24 BA ED 19 8C 15
-subject=/CN=revoked1.example.com
-issuer=/O=example.com/CN=clica Signing Cert
------BEGIN CERTIFICATE-----
-MIICiTCCAfKgAwIBAgIBZjANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt
-cGxlLmNvbTEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
-MzQwNloXDTM4MDEwMTEyMzQwNlowHzEdMBsGA1UEAxMUcmV2b2tlZDEuZXhhbXBs
-ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKu5DqPk2+MvI4TMS/rU
-60uPCkU7DuVVJzyOSkUzxZFsQcEJxfd6sfkicGbzoMkhx2UclbtcP9ll9dLuUplh
-hZVbQVI5vAeuEUKPGnHp1KIN776sOYDilf4PCOhQVDNR91OcOwcCKROjCfXu6w7c
-RqVCdrIoaCRf/bpBrIyou8WxAgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
-A1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAj
-hiFodHRwOi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEE
-KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLmNvbS8wHwYDVR0R
-BBgwFoIUcmV2b2tlZDEuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQEFBQADgYEAMOti
-HVUrF17HKVH9eRvCKNJ+1h1R76otCpevvmujGxY/2wrYpbZ5NIWPWoF2tDXfBNDK
-r5w5f1DlNWeVZKW5dYtmVS8O7IxhICGlAq9U4A0laj3x6iglbGggqRnQl/QRUd7s
-jCG0Bbsa1/nc+9JbPqWGz5LXT3t5cF/6NDeKi68=
+MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM3WhcNMzgw
+MTAxMTIzNDM3WjApMRQwEgYDVQQKEwtleGFtcGxlLmNvbTERMA8GA1UEAxMIY2xp
+Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOh0bvMeu3S1F6t7vEWH
+86hJbiW97pjm8A930DFhe/UIlgPsAmCePZEMg6EtakY5Huva4kYeBUejbRtd3LE7
+q07sOVQqcKt+X8wXThBBHPk/7q6BL+je3cfuisxsS1neX3m5BOAhROPr6kvFDz4f
+SRb4s3jT3bRgh5a7vl5JRv9FAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
+DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBAA1n72ajcRt82cyo3R4P
+E9bqjhm4Y6d+a6vk4tPLk1uLD/EQw5ShAY6sM/FUzX8M4oyZ4A9Xouse0iXAVb50
+6gdqzfNtXeR5jIkTVNly0XJ99JfTgVHX0EcHPi3pffhiRCuNG2zEE6jIvUPym7UN
+3BXv6NWbBMOXAaVl99vckvxm
-----END CERTIFICATE-----
Bag Attributes
friendlyName: revoked1.example.com
- localKeyID: 20 71 F8 DC E7 30 30 96 0E C4 15 76 D6 41 24 BA ED 19 8C 15
+ localKeyID: 06 E2 CF 1F 8F 0C AA 53 ED 62 CE 37 E5 20 9A CE EE 71 5C 5C
subject=/CN=revoked1.example.com
issuer=/O=example.com/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICiTCCAfKgAwIBAgIBZjANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt
+MIICiTCCAfKgAwIBAgIBZjANBgkqhkiG9w0BAQsFADAzMRQwEgYDVQQKEwtleGFt
cGxlLmNvbTEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
-MzQwNloXDTM4MDEwMTEyMzQwNlowHzEdMBsGA1UEAxMUcmV2b2tlZDEuZXhhbXBs
-ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKu5DqPk2+MvI4TMS/rU
-60uPCkU7DuVVJzyOSkUzxZFsQcEJxfd6sfkicGbzoMkhx2UclbtcP9ll9dLuUplh
-hZVbQVI5vAeuEUKPGnHp1KIN776sOYDilf4PCOhQVDNR91OcOwcCKROjCfXu6w7c
-RqVCdrIoaCRf/bpBrIyou8WxAgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
+MzQzOFoXDTM4MDEwMTEyMzQzOFowHzEdMBsGA1UEAxMUcmV2b2tlZDEuZXhhbXBs
+ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAN+vuGqXGYUPhjF/K7QR
+M8pUsJFK9zLkFaXI7/uAAYaR1JxZbNGziRqR+GRcTtcYWaolwdqCRHb4f/OmUPwe
+a5bLLUCwp0uj12ixmHnvjPoDWqgE8aZ23m4+gizORuCd82159ON8CfQz4Q91ybI2
+UwltpKh+4Dkj6ru/6KjUTHQjAgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
A1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAj
hiFodHRwOi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEE
KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLmNvbS8wHwYDVR0R
-BBgwFoIUcmV2b2tlZDEuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQEFBQADgYEAMOti
-HVUrF17HKVH9eRvCKNJ+1h1R76otCpevvmujGxY/2wrYpbZ5NIWPWoF2tDXfBNDK
-r5w5f1DlNWeVZKW5dYtmVS8O7IxhICGlAq9U4A0laj3x6iglbGggqRnQl/QRUd7s
-jCG0Bbsa1/nc+9JbPqWGz5LXT3t5cF/6NDeKi68=
+BBgwFoIUcmV2b2tlZDEuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADgYEASefM
+vigqpVMCxf2n21RaSiHBr5EXU8hpAXLIVRBmch8tf5PBpKPmIKWe6ZiOGg9sG7oA
+Y42jKaBaCPyO/nUC0hcMB6ronLCK/na3RaiE3EBQAHaKNhHJ6DqoSc4hg4JEP7pF
+hCq7eYA/3G+JWo9COZr8T/qxAzd3wFSzI+1CgUY=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA1WhcNMzgw\r
-MTAxMTIzNDA1WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp\r
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzwXsp\r
-P4RsZUoDfQfm5O5bi5unhwl+BTrKIaOtl5TBxMau+qEdKa02DD7Bx6PCzLKhWiZ3\r
-/MrO7V/cXIBun97dF5Zr5kk+HJk+y3es+xoPd3doknvGQEC/0cSGLcEC7aQ/bEqi\r
-fw2CgEY5ffkEAnDrdvGGeqBfJJGft/tqmlZbeQIDAQABo1owWDAOBgNVHQ8BAf8E\r
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM3WhcNMzgw\r
+MTAxMTIzNDM3WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp\r
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/GggX\r
+i+loP31ey0vxDpYe0mlBMHwC9ucGZo2HdTsJeOcGjqR4OTpZcOGbZB+Rhm+ZKZ+D\r
+lmIAjAit/sSJkqVj0hWlTdtSmgBuejsVqBHg3JwxVCnZmzo0+ILuod9tPcnVMjpz\r
+qj9CQAEcP+S329jlRKny14LCQzRc09QpszLuxwIDAQABo1owWDAOBgNVHQ8BAf8E\r
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw\r
-Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA\r
-Lq4cCtWMjqLHqf6lJUOBMsm+tgFcYDdxwkTquSZyUrbP1jrODkg5lQWNCdvB76B2\r
-tZQfMJ3F/kct2EAfsKbHqN3f+DARqPAR2qtOqzl3Ou5+TJjExKgojjzIAPFQzswH\r
-7v4aglpReaPBaVSNOZ7bMn/E8yRy3o466bhzdEIDcII=
+Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA\r
+yc6X34U2IKvN9y2EnNYwfsRPEE2LerSN9Tt3UgOuhuETJM7upwacJqOiN+HXQ0xp\r
+qhRxcDdrNy7MvymNLkc0mSiFGEjWG8dmZz/NFwGCzHSIhPxl6YryfbldbnqQLop0\r
+KpaftG9PQ4QxymUGjbvty95QvU2MlGA19NbXcLa4Vio=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: revoked1.example.com
- localKeyID: 20 71 F8 DC E7 30 30 96 0E C4 15 76 D6 41 24 BA ED 19 8C 15
+ localKeyID: 06 E2 CF 1F 8F 0C AA 53 ED 62 CE 37 E5 20 9A CE EE 71 5C 5C
Key Attributes: <No Attributes>
-----BEGIN ENCRYPTED PRIVATE KEY-----
-MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIaz4go+5KBqgCAggA
-MBQGCCqGSIb3DQMHBAhtc8IZfwyFPwSCAoAPcxPLBxhSJXrDApap04PKVC86gzJ9
-4c0mZu50tugE1nDu7jDRCErbmYF9QH2IEoGFVL33gO5q+BH+c5r2D5vkiQ8csrfb
-s8DZoPnk36cR40q1LjFBXmxut+Xq3Dw+K4fTzl3vgOtkUqaXYPnMvaB6iejjWNiF
-bOIh7A8rlOxJZjVF3wVRVE/j3TyVFqzJ4NMaSfZwW/bMPDMsRpc06UyiX3ffb7i3
-N2I2Sb+MerlIbt/NCM5MRAOP5QzTg08qN959nuPjPyiRtvXwcExj70yqL+fC5KxL
-gM2fO3rPIU5bOCJFZJxitddKSC2r99vyIUG+qEXqllGfYKaLvo8xbNJ3JK4kAum+
-j2oF2/PkYDxjhGVd6yLk37xmnMHNqwqNFS1lf9tXbpYD2sOQeyPqiYUSfSEbXniv
-j+Gh4nJOccOPvTYakNLk4vSbg6tSmYjICoZIzwiNT5Um7Qstji53UCBggPOplIfN
-Eqzxy7m5CxR/l5w2wx5El4F7ECN5lvg3eX2lMp5NT4Bui6lNQOAiAmE3e6MkJ+38
-9tv+NKEYVi5V2BdqOFXEUrZSI2azuSL5q4Ws0Qpp3It6541y/IE85hljvjiYvxqC
-oPLdNdI/R5ANmCVNxKWVVmFe7ScoY/spePt2L93Zpikfa0cmheE5TePlfTJVHAVK
-KH8fIAHo717gqfQYnE40IVzcLcL9v6WYQ3+nasnvM818CVNWsCKSDLkPFBoKuU8c
-Ec0AXFIa+EPIwD96EEIZaZhcG9DicDaaEzLKssP9WL1MFuqDgpRpTKD8tqh3ytqq
-PKqDohc0uRQRQuTodSjT73FtAyTZNVe62fxmfDQ0uxkDQzxaiBOzZEmm
+MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIKh17F/r2BAECAggA
+MBQGCCqGSIb3DQMHBAiGnj7bRKR/PQSCAoAs1sshi/N0T6mcZ7Djfl/v9bX8BNml
+Mz0WDjYPtEnth5FZdRdzhyvSLg8Ntygu2A0PVzFH9o4hAxAUTpZ1KP9zKk3dYcWF
+hucqMxTSZV4wrdpD+9KfqI3W261BsSETEPs1ZwEkkZWbz3kgy1jbJOMundSQ7b4D
+S2kNsSEAV0LkPxzbKZxZamzxshQQNdKO7vfj/KsRJmjNoZ8KgEgP61OMo2e+KEKu
+FZSAK56pFZtRRCa1oVoT6urqmMPb9hxNjb1V5uvZ/c1xKyp5B+zcyzH17WpFuBGQ
+PMT+hgAJqu85KbE0xbbpNQ1b69aoTl8Fvz5+ZUnFLeJOZZa77Vexk5PDqdC98rWb
+NxlNNhyYHclUtN/09qpeIRmIQR0DVmaR6NnYVtiWNpi7iCUTWb5JK9zt6c+28Q0Q
+bEO6JZz13mjunvbjIynsG5iSS86hleJIbYy3YALoun83z1RDcb/o44AyI8sUFL/+
+cJ/eknsdYXdnoWJZG3/iMIG63o+dIalmspxH2SfalB6RRB8y16xigRvO7dbha3bY
+aI+6x7LJ1Wp3XU23OmcBV3wdLt5hP5N8aBKwq+e8WqpEWNq0gU7BHuZjDiu4o4x7
+IlKAir+nmjXrEs3UCAIHD6Ea+vqgsZa+lnNDYHkQiw5dlvbom6KUtTwCoqswbh7F
+EO2HJsiysUOIWeYBgRFtllTv8Nf4S2KkgxEAtqHd81Zo+ZGcWVfDE4UVf53nY0Vz
+E4buuS7oE4kl7/QGAjAiJd7T5YA8abicHO365T64qRFpFMv10TZAN4Ijn+Lq8c/C
+h0FsSUNibO7+XYsQK2eYYif7ligPEQsHN+AiRnJxDhaMaeH1YShgijsX
-----END ENCRYPTED PRIVATE KEY-----
Bag Attributes
friendlyName: revoked1.example.com
- localKeyID: 20 71 F8 DC E7 30 30 96 0E C4 15 76 D6 41 24 BA ED 19 8C 15
+ localKeyID: 06 E2 CF 1F 8F 0C AA 53 ED 62 CE 37 E5 20 9A CE EE 71 5C 5C
subject=/CN=revoked1.example.com
issuer=/O=example.com/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICiTCCAfKgAwIBAgIBZjANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt
+MIICiTCCAfKgAwIBAgIBZjANBgkqhkiG9w0BAQsFADAzMRQwEgYDVQQKEwtleGFt
cGxlLmNvbTEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
-MzQwNloXDTM4MDEwMTEyMzQwNlowHzEdMBsGA1UEAxMUcmV2b2tlZDEuZXhhbXBs
-ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKu5DqPk2+MvI4TMS/rU
-60uPCkU7DuVVJzyOSkUzxZFsQcEJxfd6sfkicGbzoMkhx2UclbtcP9ll9dLuUplh
-hZVbQVI5vAeuEUKPGnHp1KIN776sOYDilf4PCOhQVDNR91OcOwcCKROjCfXu6w7c
-RqVCdrIoaCRf/bpBrIyou8WxAgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
+MzQzOFoXDTM4MDEwMTEyMzQzOFowHzEdMBsGA1UEAxMUcmV2b2tlZDEuZXhhbXBs
+ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAN+vuGqXGYUPhjF/K7QR
+M8pUsJFK9zLkFaXI7/uAAYaR1JxZbNGziRqR+GRcTtcYWaolwdqCRHb4f/OmUPwe
+a5bLLUCwp0uj12ixmHnvjPoDWqgE8aZ23m4+gizORuCd82159ON8CfQz4Q91ybI2
+UwltpKh+4Dkj6ru/6KjUTHQjAgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
A1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAj
hiFodHRwOi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEE
KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLmNvbS8wHwYDVR0R
-BBgwFoIUcmV2b2tlZDEuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQEFBQADgYEAMOti
-HVUrF17HKVH9eRvCKNJ+1h1R76otCpevvmujGxY/2wrYpbZ5NIWPWoF2tDXfBNDK
-r5w5f1DlNWeVZKW5dYtmVS8O7IxhICGlAq9U4A0laj3x6iglbGggqRnQl/QRUd7s
-jCG0Bbsa1/nc+9JbPqWGz5LXT3t5cF/6NDeKi68=
+BBgwFoIUcmV2b2tlZDEuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADgYEASefM
+vigqpVMCxf2n21RaSiHBr5EXU8hpAXLIVRBmch8tf5PBpKPmIKWe6ZiOGg9sG7oA
+Y42jKaBaCPyO/nUC0hcMB6ronLCK/na3RaiE3EBQAHaKNhHJ6DqoSc4hg4JEP7pF
+hCq7eYA/3G+JWo9COZr8T/qxAzd3wFSzI+1CgUY=
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
-MIICXAIBAAKBgQCruQ6j5NvjLyOEzEv61OtLjwpFOw7lVSc8jkpFM8WRbEHBCcX3
-erH5InBm86DJIcdlHJW7XD/ZZfXS7lKZYYWVW0FSObwHrhFCjxpx6dSiDe++rDmA
-4pX+DwjoUFQzUfdTnDsHAikTown17usO3EalQnayKGgkX/26QayMqLvFsQIDAQAB
-AoGAJghnkK8YcFm5YSkqTtSnhGWa3bh11R8mAIh3NJqB0HKMoad7fBNlpYsWIAcn
-fkSH+AH7u7Jzxb+KUXxNOQFbZ1r6+Ye8nX0Gj1zEeRM9FWbJ3KB5hgd0jWS9tqoW
-fbuqKMsxiPTzo10yJ8RNegtsUmx6KCc2om0RvROtiLrH79ECQQDdS826UMtHQwNk
-518YWEQ6XogJpu9yO3HNhMfBG3mVpIZRw1vUhNuMAze4I2IAD7gqYPzx1QeX5pq1
-s57VKj19AkEAxqcTv/wwm9tPEUyPx/EBf9cQ4ta+XEpOkwy8VRHkZYi1vUcuniMO
-7aQVLHDBG/Ksh2GWpFC7v5qjo9eNgXBvRQJAOhooBs4lwS0YHAsfja3HJCgjwZ0B
-61UuOQ6uv8Xt81tCJP+NAcxsNGO34nHvziJScVYLs5cCKmDSp/hkMIWppQJAD6QI
-Ag2xJhRWXV5R08Q+AfrE8ZdG1a1kEl/mVCxcd0IUTRrVqM3J1xwcLquSCMlKnD4q
-xjU1Exjx2WyXT6GyoQJBAMM9muE6OBGpbcVM4g2jQFH5hUpLRt12+Zth9j6ZmprU
-LljRN27vg++BFGdRSKk8dszK9RYJdRhenKqLUUagOoY=
+MIICXAIBAAKBgQDfr7hqlxmFD4Yxfyu0ETPKVLCRSvcy5BWlyO/7gAGGkdScWWzR
+s4kakfhkXE7XGFmqJcHagkR2+H/zplD8HmuWyy1AsKdLo9dosZh574z6A1qoBPGm
+dt5uPoIszkbgnfNtefTjfAn0M+EPdcmyNlMJbaSofuA5I+q7v+io1Ex0IwIDAQAB
+AoGAGQLs+/4pPFegCajOmjPSNq2BkL1xJp+aTA9LxjNp+EIWI+Vb5ZbNncr0m0Q3
+DJYMcJoIMwad4S+oHvZZ19cO8HfmEGnn1ePs87ZFnalp+ibDLGFdfV163kqs02NQ
+/6oy37/a6wNhufv38m6JtRMB3NXdxC7a58tKAPoRraIn/gECQQD/i7nz/gIT3Ij+
+SrsF45Pq1AtazXUq5oiGHImr6xTJXHdnTyQujXQWhWmwJLi69VOhiUEvKcCfAcLl
+FO4ZSuJ7AkEA4BV/eL1qsEzF4EDAn5z6MTaScebAkG6K+fcITK+I7Iky5zxI3UA5
+xGrLjeJVQ8mX5yAVQ3Ka9TJTQ0IiAK24eQJBAN3GOX9StiLehdWKrXyS4NAvbhtD
+q6erolghdClLPyLxqH5z5IayJElXRz2i4N8AAbBzGasApTZZpPaCj5BLuPkCQDeN
+PM+67ZMNRVTl2Jr5OJEwvTddhEmKDgwP8M/KCIDTNnpa2Jl5DZki/JmNDaRDetQC
+gSL6a23z7u5Sm8ldR8kCQCPlnKzTrhnY39ECcXPqigyhSwagZJdbhID+RAaeeX3C
+y8M6hyk9Xnm4ctOiC+T5Fiz2JNIuRf3OqqBphMrVTI0=
-----END RSA PRIVATE KEY-----
subject=/O=example.com/CN=clica Signing Cert
issuer=/O=example.com/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA1WhcNMzgw
-MTAxMTIzNDA1WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzwXsp
-P4RsZUoDfQfm5O5bi5unhwl+BTrKIaOtl5TBxMau+qEdKa02DD7Bx6PCzLKhWiZ3
-/MrO7V/cXIBun97dF5Zr5kk+HJk+y3es+xoPd3doknvGQEC/0cSGLcEC7aQ/bEqi
-fw2CgEY5ffkEAnDrdvGGeqBfJJGft/tqmlZbeQIDAQABo1owWDAOBgNVHQ8BAf8E
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM3WhcNMzgw
+MTAxMTIzNDM3WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/GggX
+i+loP31ey0vxDpYe0mlBMHwC9ucGZo2HdTsJeOcGjqR4OTpZcOGbZB+Rhm+ZKZ+D
+lmIAjAit/sSJkqVj0hWlTdtSmgBuejsVqBHg3JwxVCnZmzo0+ILuod9tPcnVMjpz
+qj9CQAEcP+S329jlRKny14LCQzRc09QpszLuxwIDAQABo1owWDAOBgNVHQ8BAf8E
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw
-Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA
-Lq4cCtWMjqLHqf6lJUOBMsm+tgFcYDdxwkTquSZyUrbP1jrODkg5lQWNCdvB76B2
-tZQfMJ3F/kct2EAfsKbHqN3f+DARqPAR2qtOqzl3Ou5+TJjExKgojjzIAPFQzswH
-7v4aglpReaPBaVSNOZ7bMn/E8yRy3o466bhzdEIDcII=
+Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA
+yc6X34U2IKvN9y2EnNYwfsRPEE2LerSN9Tt3UgOuhuETJM7upwacJqOiN+HXQ0xp
+qhRxcDdrNy7MvymNLkc0mSiFGEjWG8dmZz/NFwGCzHSIhPxl6YryfbldbnqQLop0
+KpaftG9PQ4QxymUGjbvty95QvU2MlGA19NbXcLa4Vio=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: Certificate Authority
subject=/O=example.com/CN=clica CA
issuer=/O=example.com/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA0WhcNMzgw
-MTAxMTIzNDA0WjApMRQwEgYDVQQKEwtleGFtcGxlLmNvbTERMA8GA1UEAxMIY2xp
-Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL0wro64rve876glpdRh
-tD6qFY6iH2kCarFFq3WaKmfCvOjYmn4CJr7pL7J5DuvCFh7A0H8lD/on5NK3yqkX
-Yi6EUlaYWxeRo2/PuZYUGbCpejST41sibw9V2dT4MHLidjDShE0W9SfgiMmxfF02
-H5hLYswAGCL1kezsVeEJeH31AgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
-DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBAIn9+8uyQtaq8sBEohTl
-qyJQQeZk5xxaILYP/rCIxc+z5fgOh+usB9adaiD23RPuuD/P2c3UqHJQWqIUTu46
-eOKn9K7X7ndIH3WnaC/u4nysL+SIAug72/k1BAVGNQvyNQMhth6CfZTgY0tgcS0Z
-RSHyhbTD0HeiJDI281BoOJjm
------END CERTIFICATE-----
-Bag Attributes
- friendlyName: revoked2.example.com
- localKeyID: F6 B8 57 6A D8 2D CB DC DC 43 07 E6 86 40 B7 FA 7B 99 A1 E5
-subject=/CN=revoked2.example.com
-issuer=/O=example.com/CN=clica Signing Cert
------BEGIN CERTIFICATE-----
-MIICijCCAfOgAwIBAgICAMowDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhh
-bXBsZS5jb20xGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDEx
-MjM0MDdaFw0zODAxMDExMjM0MDdaMB8xHTAbBgNVBAMTFHJldm9rZWQyLmV4YW1w
-bGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNy5rRDiIwXth1Wi0p
-FFPOoZ/cXt9lQ3blYjE4gdk0gMZk4Tjqa0UEb/m0bB3EIgVa7IXWo84hMso2fMCP
-ElM3Xm8oGzCQ1i9Ju+CKTFc+6yLJD4Ql/pN4tzBxC/Dc3sYWEvRKLNbsd082cO3L
-GpKCgIly36apDf7pfQZxqEt1RwIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
-BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
-I4YhaHR0cDovL2NybC5leGFtcGxlLmNvbS9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
-BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5jb20vMB8GA1Ud
-EQQYMBaCFHJldm9rZWQyLmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBBQUAA4GBAIDM
-Wzp1Bzw74TGL96zIVmr92SKV+6EeFKiSm07CXHd7amfj+rIAabexTzEMxFil+VCD
-om3NIObOF5HTtCOygBtnMc8/lF9r0rpYMo2cJTQXwUQVQ4UDtj2SsR3BofbCDxb5
-XPMB4J50KwXz7U3M/Kd1cGdSmbkutI56lJWDXSAI
+MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM3WhcNMzgw
+MTAxMTIzNDM3WjApMRQwEgYDVQQKEwtleGFtcGxlLmNvbTERMA8GA1UEAxMIY2xp
+Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOh0bvMeu3S1F6t7vEWH
+86hJbiW97pjm8A930DFhe/UIlgPsAmCePZEMg6EtakY5Huva4kYeBUejbRtd3LE7
+q07sOVQqcKt+X8wXThBBHPk/7q6BL+je3cfuisxsS1neX3m5BOAhROPr6kvFDz4f
+SRb4s3jT3bRgh5a7vl5JRv9FAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
+DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBAA1n72ajcRt82cyo3R4P
+E9bqjhm4Y6d+a6vk4tPLk1uLD/EQw5ShAY6sM/FUzX8M4oyZ4A9Xouse0iXAVb50
+6gdqzfNtXeR5jIkTVNly0XJ99JfTgVHX0EcHPi3pffhiRCuNG2zEE6jIvUPym7UN
+3BXv6NWbBMOXAaVl99vckvxm
-----END CERTIFICATE-----
Bag Attributes
friendlyName: revoked2.example.com
- localKeyID: F6 B8 57 6A D8 2D CB DC DC 43 07 E6 86 40 B7 FA 7B 99 A1 E5
+ localKeyID: BA A1 F0 8D 1A 19 D9 11 A9 DD 54 D6 A5 13 AA 51 78 94 9F BF
subject=/CN=revoked2.example.com
issuer=/O=example.com/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICijCCAfOgAwIBAgICAMowDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhh
+MIICijCCAfOgAwIBAgICAMowDQYJKoZIhvcNAQELBQAwMzEUMBIGA1UEChMLZXhh
bXBsZS5jb20xGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDEx
-MjM0MDdaFw0zODAxMDExMjM0MDdaMB8xHTAbBgNVBAMTFHJldm9rZWQyLmV4YW1w
-bGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNy5rRDiIwXth1Wi0p
-FFPOoZ/cXt9lQ3blYjE4gdk0gMZk4Tjqa0UEb/m0bB3EIgVa7IXWo84hMso2fMCP
-ElM3Xm8oGzCQ1i9Ju+CKTFc+6yLJD4Ql/pN4tzBxC/Dc3sYWEvRKLNbsd082cO3L
-GpKCgIly36apDf7pfQZxqEt1RwIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
+MjM0MzhaFw0zODAxMDExMjM0MzhaMB8xHTAbBgNVBAMTFHJldm9rZWQyLmV4YW1w
+bGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCz8dtSCUuUklr3d1y7
+FbtPN8uEKekTvZlKgW95OaPd5f4TsjHbo9b9BM+bFiX8yQ6mxQPqKfYHXF8UC87H
+2xYex0q9Oz/kcpAF/SUglqCOZrIIvA3TdSwUUjNf/FuDS8Sa8FAHFTGKeY9gdCEZ
+yZ0dYke9lajL974fmVWR9J4TrQIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
I4YhaHR0cDovL2NybC5leGFtcGxlLmNvbS9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5jb20vMB8GA1Ud
-EQQYMBaCFHJldm9rZWQyLmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBBQUAA4GBAIDM
-Wzp1Bzw74TGL96zIVmr92SKV+6EeFKiSm07CXHd7amfj+rIAabexTzEMxFil+VCD
-om3NIObOF5HTtCOygBtnMc8/lF9r0rpYMo2cJTQXwUQVQ4UDtj2SsR3BofbCDxb5
-XPMB4J50KwXz7U3M/Kd1cGdSmbkutI56lJWDXSAI
+EQQYMBaCFHJldm9rZWQyLmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4GBAKXo
+tzQ2BtddjynZ41wryaFTmJURCUZqx/TUGpD9LZSKjumZQWOJ+J9fAIYk4bDJ/odI
+mzclOaxEYhZpddEdyU0XK14LlzxA44lBMVhkLVlrpcqWT2nggwj+0Rx/LxXHftnQ
+XbPGAqNhBhAbk8U+DC/28TlkcocapCiQJN2nGexX
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA1WhcNMzgw\r
-MTAxMTIzNDA1WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp\r
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzwXsp\r
-P4RsZUoDfQfm5O5bi5unhwl+BTrKIaOtl5TBxMau+qEdKa02DD7Bx6PCzLKhWiZ3\r
-/MrO7V/cXIBun97dF5Zr5kk+HJk+y3es+xoPd3doknvGQEC/0cSGLcEC7aQ/bEqi\r
-fw2CgEY5ffkEAnDrdvGGeqBfJJGft/tqmlZbeQIDAQABo1owWDAOBgNVHQ8BAf8E\r
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM3WhcNMzgw\r
+MTAxMTIzNDM3WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp\r
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/GggX\r
+i+loP31ey0vxDpYe0mlBMHwC9ucGZo2HdTsJeOcGjqR4OTpZcOGbZB+Rhm+ZKZ+D\r
+lmIAjAit/sSJkqVj0hWlTdtSmgBuejsVqBHg3JwxVCnZmzo0+ILuod9tPcnVMjpz\r
+qj9CQAEcP+S329jlRKny14LCQzRc09QpszLuxwIDAQABo1owWDAOBgNVHQ8BAf8E\r
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw\r
-Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA\r
-Lq4cCtWMjqLHqf6lJUOBMsm+tgFcYDdxwkTquSZyUrbP1jrODkg5lQWNCdvB76B2\r
-tZQfMJ3F/kct2EAfsKbHqN3f+DARqPAR2qtOqzl3Ou5+TJjExKgojjzIAPFQzswH\r
-7v4aglpReaPBaVSNOZ7bMn/E8yRy3o466bhzdEIDcII=
+Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA\r
+yc6X34U2IKvN9y2EnNYwfsRPEE2LerSN9Tt3UgOuhuETJM7upwacJqOiN+HXQ0xp\r
+qhRxcDdrNy7MvymNLkc0mSiFGEjWG8dmZz/NFwGCzHSIhPxl6YryfbldbnqQLop0\r
+KpaftG9PQ4QxymUGjbvty95QvU2MlGA19NbXcLa4Vio=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: revoked2.example.com
- localKeyID: F6 B8 57 6A D8 2D CB DC DC 43 07 E6 86 40 B7 FA 7B 99 A1 E5
+ localKeyID: BA A1 F0 8D 1A 19 D9 11 A9 DD 54 D6 A5 13 AA 51 78 94 9F BF
Key Attributes: <No Attributes>
-----BEGIN ENCRYPTED PRIVATE KEY-----
-MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIlxIrxmJRt8QCAggA
-MBQGCCqGSIb3DQMHBAgod4MeM3j+0ASCAoBwu4gld5x2UyoP3M2re8SrlwbNnWut
-VQH6reInjBZfOOYco4PekLMSoD2kZYcdcupquBe6cmb72ODBkmDHa84p/NtQznhI
-FO1oF/isGm0OSQBp1odVoSY9ZqYrMlbikBHoCVljLFGimFZcdU69xRnNk9LKReB2
-sUVF2DzYQkgPM+OCQjza53nJh8XJTgXJkKjaqcjkfbP8QuVQBzBXgVRPqh2WnXA3
-St4Pj3qXuG177Q86X+NDS0S4mRuVwkarB8jDqkWnhdl3fcZz3NHCSj4aDxuOxos1
-3XcGCXG50W+31cAoj6oRfPKgaDt0zOfMySBJqhBYSYTV36Wddoq3rzPJyNOTHpFW
-Y5K+792SYC++bIFEyJOrTH0a/NsVDrFHvX9ib94KscD9TM2yUP06Yr8j3jh9ecDs
-YNfsVqdNq62Hj+B9hBPIrBUufuAMHwOengcB+tcpJvNX5/ckBIPCSFjxlbFWZ/nr
-E87+AEmt4xYAQAXvutBRC/W6kLvcdD7oGIEKEmhUrBPegA6hFaAo7L+whpW5dp90
-cVwGTpPMqiHkbBEl5XOQmmpqtyZteRfccvAD6+obJHt59dZ6T/il7GItPmBOxO9Q
-UWd4bCOLvI1gmSsfpP0akX2gUDFPAlzCuYgalMZ5krkk1VlEunRTMBUuW5zziiEE
-YKw8I0AV9LjmYCsGHl00LGKgOof0GjCbh+RV+qcuJIlVe26Q+gl1ubsI/3sfPu+e
-l+SFAdtxmWh0gQVrQIW6SdZJ5gfqIZZOleq6PXOl4em7/GnRD1+xtnzsEZRRMILt
-+UF6GFSlar8Ug87RLEsTbA0uqcXA8KhsACU//Zof3ZWzGor4+dqcEabj
+MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQI8yFiiVFOqjECAggA
+MBQGCCqGSIb3DQMHBAjJRNO3cgYqMASCAoCmbh+OMTNlW6/2nOhcsTH00BpEr7IQ
+ERPq/St6LbTBulx4kYhaNcj/sFwVhk/1FI1SNCtp/nfhJxMvCSmOne/aQVi5o5li
+/4MtTmQD223rA78za23lAGqtPQS9n9E15SW9lBMBt5epEdxdUKQ4tjDCJMwd7h5A
+7wAdumaMk+Ks6JjrrrH2v7ms3fFDD25JBoTL3NnVoZQfiNky+IDwECALujyZ/FuD
+A19PdEqS5BWN72lE3OZogO3N9oxrN1EOBGxDyuyp4ShB2Ngr6gcNejYNtkCPhLBl
+duKSb1ujpnhQPxxgsxarwBKjcUUlFmcL3OUlNr9VJLAMTqmnlnvQRJEldhqNd66T
+u2eAW3Axg7wN/oRDTNTCOC3ef1sfk+jJ8iWcWjPKe6RJWELNb9p44TL1dYKwZdbQ
+dhzW4ke0Sqsk86OyXM4iSbsORD5nvOl/Bvu3foRnJ2QX5lq88/WLgDudZZT+JEFD
+r8vSBAUaIoTPjKuT5YO3n/lrCowk1hzkMYkSk/UW0+zIYyKju4CgnVwFeWmuC9AP
+Yx4gCRMJE58ZszGRZS49RzsbnNyDCJEbZB9lB5t8L1Rg/YI5THUM4L0tT/Il3tvs
+3HI1WOl0rbduSA+ZRIk2f9WsscwpFZzhXFfr1Fuf6oFZrZ2a9JXL7o4TFviAyfyM
++VL6yZomDOunCHEf1XTP6MNnYTf5/upLr9fMum/yno+gtoomub0ycfrEmMCirzW1
+OsbXxoDvyrf08CDNYs60eyZYYJ4BjZA8ma+inPzdEch1Hj3b+FCbvT/nJFrxDxp9
+8NvOYuFlQH2C3eSmUrDkx372EgfzvXlUYT3PpvAgFg5MJlUH4oMqxLjM
-----END ENCRYPTED PRIVATE KEY-----
Bag Attributes
friendlyName: revoked2.example.com
- localKeyID: F6 B8 57 6A D8 2D CB DC DC 43 07 E6 86 40 B7 FA 7B 99 A1 E5
+ localKeyID: BA A1 F0 8D 1A 19 D9 11 A9 DD 54 D6 A5 13 AA 51 78 94 9F BF
subject=/CN=revoked2.example.com
issuer=/O=example.com/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICijCCAfOgAwIBAgICAMowDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhh
+MIICijCCAfOgAwIBAgICAMowDQYJKoZIhvcNAQELBQAwMzEUMBIGA1UEChMLZXhh
bXBsZS5jb20xGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDEx
-MjM0MDdaFw0zODAxMDExMjM0MDdaMB8xHTAbBgNVBAMTFHJldm9rZWQyLmV4YW1w
-bGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNy5rRDiIwXth1Wi0p
-FFPOoZ/cXt9lQ3blYjE4gdk0gMZk4Tjqa0UEb/m0bB3EIgVa7IXWo84hMso2fMCP
-ElM3Xm8oGzCQ1i9Ju+CKTFc+6yLJD4Ql/pN4tzBxC/Dc3sYWEvRKLNbsd082cO3L
-GpKCgIly36apDf7pfQZxqEt1RwIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
+MjM0MzhaFw0zODAxMDExMjM0MzhaMB8xHTAbBgNVBAMTFHJldm9rZWQyLmV4YW1w
+bGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCz8dtSCUuUklr3d1y7
+FbtPN8uEKekTvZlKgW95OaPd5f4TsjHbo9b9BM+bFiX8yQ6mxQPqKfYHXF8UC87H
+2xYex0q9Oz/kcpAF/SUglqCOZrIIvA3TdSwUUjNf/FuDS8Sa8FAHFTGKeY9gdCEZ
+yZ0dYke9lajL974fmVWR9J4TrQIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
I4YhaHR0cDovL2NybC5leGFtcGxlLmNvbS9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5jb20vMB8GA1Ud
-EQQYMBaCFHJldm9rZWQyLmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBBQUAA4GBAIDM
-Wzp1Bzw74TGL96zIVmr92SKV+6EeFKiSm07CXHd7amfj+rIAabexTzEMxFil+VCD
-om3NIObOF5HTtCOygBtnMc8/lF9r0rpYMo2cJTQXwUQVQ4UDtj2SsR3BofbCDxb5
-XPMB4J50KwXz7U3M/Kd1cGdSmbkutI56lJWDXSAI
+EQQYMBaCFHJldm9rZWQyLmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4GBAKXo
+tzQ2BtddjynZ41wryaFTmJURCUZqx/TUGpD9LZSKjumZQWOJ+J9fAIYk4bDJ/odI
+mzclOaxEYhZpddEdyU0XK14LlzxA44lBMVhkLVlrpcqWT2nggwj+0Rx/LxXHftnQ
+XbPGAqNhBhAbk8U+DC/28TlkcocapCiQJN2nGexX
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
-MIICXQIBAAKBgQDNy5rRDiIwXth1Wi0pFFPOoZ/cXt9lQ3blYjE4gdk0gMZk4Tjq
-a0UEb/m0bB3EIgVa7IXWo84hMso2fMCPElM3Xm8oGzCQ1i9Ju+CKTFc+6yLJD4Ql
-/pN4tzBxC/Dc3sYWEvRKLNbsd082cO3LGpKCgIly36apDf7pfQZxqEt1RwIDAQAB
-AoGAS7io5Fcg+U9MshFWIJFcLOGHYpx98lKagthYaARPGWRwm1nLiWWi5XkWFe7a
-HPqvob75l/p5s/luMhJA/+OsPkAwxCN7+o1vBBAT2NFtF7AVk3gjaK5eAIdE+4XV
-Og7njMoQM0yvHkN4JbHQrQgefla/R6JkOFn9cMxYQhoQLpECQQDvPOVaMSR+LPri
-UAlxnPfiMB7wRSGCNMVXEoocOa6+2KJltxwospcqTgqFM4OUJQIMnETN9UBUaMZy
-kUlrJGX1AkEA3DbdXbwSypr0IhMH9uIDSnU6UJozy04WXndC3Ucdxjl3prs49na5
-9S7EPjY/MYuaxJe8hXQ6/Oq3/S0W43asywJBAL5LAN/B0RYv7wtOwIRHaADZZ/KT
-+nhYQ1PkIkkbNL0HEf24LcTNcWIsG0AiXpna6gtfzXbJinbZtGfy2qRHmnUCQHE7
-2PoQ8kyx/uTiik7dirmnq9O0ZvucbI4onv4vSlUaSbc3QCQjip1Tbd9bf4UXdv6t
-02eAC7DvdKo/nCxcYp8CQQDsyIFsn5fVBGXTceFtFYVTw5KwG1b7+l6gM4q0IkKn
-BS0IhuSjRpJuw6QfHMaxb2d6d2z/JOiRVCRJwpTnl9Zz
+MIICXQIBAAKBgQCz8dtSCUuUklr3d1y7FbtPN8uEKekTvZlKgW95OaPd5f4TsjHb
+o9b9BM+bFiX8yQ6mxQPqKfYHXF8UC87H2xYex0q9Oz/kcpAF/SUglqCOZrIIvA3T
+dSwUUjNf/FuDS8Sa8FAHFTGKeY9gdCEZyZ0dYke9lajL974fmVWR9J4TrQIDAQAB
+AoGAXCSR0R1PZYHYMPYfNvG226bPgRrQ7jndQAito16/qYX3J/DMlRL9qMyI3npl
+816lMQKbsZHRGQ3U5ffx5+cpGLe3jPJ+ywdpfvBwcy/kRjGl/KDQAuqdNcmt2RLZ
+zby2sVeRtW9E6ixPiWvZfVbr/7fWspofCBXnQ/oK74TKimECQQDd6pu58Wze+IPB
+D59xCj+hkB6gtAqXlsYbVlkh9bM69LTKTE38mGqYU0XHpjepWrkGdIHFrq/9JNh+
+4NhPmBslAkEAz5T9hZSTR/m+d/yMHxWSJuNzjlvK/ymLV1cPOUXC9Mo1NO9qk9yx
+cUCy0YBIYYhYx7PBdHhTlR20+OJc/iEz6QJBAI0uWtBbNeZMuJW0uL0TxhOlOrcG
+k86JD5QIxUADrnkNgY9KKDtRRE+Qes5fgv3tR9VBfeYkEra8IDfoF/XbUTkCQC+M
+jVYf5mzCRGLvspkcM9I8n6eoVyODvKtRAee4lyPDfdSWUu9zyiGLFGrw26Obu9pi
+zpmDRoINv/qSv4Jm0KECQQC2jHpwrSPzJGLn5heATVfVDsFdH7ddXDaiLbgTlsBH
+GpZfeOl9UPGpBTZmBczFrUGPovtTOOYl5u68tFGpkUbP
-----END RSA PRIVATE KEY-----
subject=/O=example.com/CN=clica Signing Cert
issuer=/O=example.com/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA1WhcNMzgw
-MTAxMTIzNDA1WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzwXsp
-P4RsZUoDfQfm5O5bi5unhwl+BTrKIaOtl5TBxMau+qEdKa02DD7Bx6PCzLKhWiZ3
-/MrO7V/cXIBun97dF5Zr5kk+HJk+y3es+xoPd3doknvGQEC/0cSGLcEC7aQ/bEqi
-fw2CgEY5ffkEAnDrdvGGeqBfJJGft/tqmlZbeQIDAQABo1owWDAOBgNVHQ8BAf8E
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM3WhcNMzgw
+MTAxMTIzNDM3WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/GggX
+i+loP31ey0vxDpYe0mlBMHwC9ucGZo2HdTsJeOcGjqR4OTpZcOGbZB+Rhm+ZKZ+D
+lmIAjAit/sSJkqVj0hWlTdtSmgBuejsVqBHg3JwxVCnZmzo0+ILuod9tPcnVMjpz
+qj9CQAEcP+S329jlRKny14LCQzRc09QpszLuxwIDAQABo1owWDAOBgNVHQ8BAf8E
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw
-Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA
-Lq4cCtWMjqLHqf6lJUOBMsm+tgFcYDdxwkTquSZyUrbP1jrODkg5lQWNCdvB76B2
-tZQfMJ3F/kct2EAfsKbHqN3f+DARqPAR2qtOqzl3Ou5+TJjExKgojjzIAPFQzswH
-7v4aglpReaPBaVSNOZ7bMn/E8yRy3o466bhzdEIDcII=
+Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA
+yc6X34U2IKvN9y2EnNYwfsRPEE2LerSN9Tt3UgOuhuETJM7upwacJqOiN+HXQ0xp
+qhRxcDdrNy7MvymNLkc0mSiFGEjWG8dmZz/NFwGCzHSIhPxl6YryfbldbnqQLop0
+KpaftG9PQ4QxymUGjbvty95QvU2MlGA19NbXcLa4Vio=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: Certificate Authority
subject=/O=example.com/CN=clica CA
issuer=/O=example.com/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA0WhcNMzgw
-MTAxMTIzNDA0WjApMRQwEgYDVQQKEwtleGFtcGxlLmNvbTERMA8GA1UEAxMIY2xp
-Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL0wro64rve876glpdRh
-tD6qFY6iH2kCarFFq3WaKmfCvOjYmn4CJr7pL7J5DuvCFh7A0H8lD/on5NK3yqkX
-Yi6EUlaYWxeRo2/PuZYUGbCpejST41sibw9V2dT4MHLidjDShE0W9SfgiMmxfF02
-H5hLYswAGCL1kezsVeEJeH31AgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
-DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBAIn9+8uyQtaq8sBEohTl
-qyJQQeZk5xxaILYP/rCIxc+z5fgOh+usB9adaiD23RPuuD/P2c3UqHJQWqIUTu46
-eOKn9K7X7ndIH3WnaC/u4nysL+SIAug72/k1BAVGNQvyNQMhth6CfZTgY0tgcS0Z
-RSHyhbTD0HeiJDI281BoOJjm
------END CERTIFICATE-----
-Bag Attributes
- friendlyName: server1.example.com
- localKeyID: 39 11 FB 30 22 36 42 DA FC D7 A2 8A 0C 60 83 2F 66 A7 B8 4E
-subject=/CN=server1.example.com
-issuer=/O=example.com/CN=clica Signing Cert
------BEGIN CERTIFICATE-----
-MIIC0DCCAjmgAwIBAgIBZTANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt
-cGxlLmNvbTEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
-MzQwNVoXDTM4MDEwMTEyMzQwNVowHjEcMBoGA1UEAxMTc2VydmVyMS5leGFtcGxl
-LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyAGT263/ZlxGjPEi2BQj
-DMa/86TF+zVzMfozEZNOLiX6Sov54fW5I0nXCm0CjACOelLa2Eos/vqffxu0w5hM
-A8slRHrt0Gak7dJjwgKK/5NAQDrA+WnyJx/62u25299oCKk+egulCC0D3XczA89N
-cLuz8iKvYnWT+rdnbFdAPdcCAwEAAaOCAQcwggEDMA4GA1UdDwEB/wQEAwIE8DAg
-BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
-I4YhaHR0cDovL2NybC5leGFtcGxlLmNvbS9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
-BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5jb20vMGUGA1Ud
-EQReMFyCIWFsdGVybmF0ZW5hbWUuc2VydmVyMS5leGFtcGxlLmNvbYIiYWx0ZXJu
-YXRlbmFtZTIuc2VydmVyMS5leGFtcGxlLmNvbYITc2VydmVyMS5leGFtcGxlLmNv
-bTANBgkqhkiG9w0BAQUFAAOBgQBWOqQ8y+u4J8KQCHQTiNxIxrUs5Sa+W5HUZ+c8
-SRLXRzDfmNtY7RiofUvbl0j1XH9wuTdjM/EkYnKSYPVu2ra8c8jC3NaVmr0WFqLv
-CvHXQWj2rZha0P/ZG1GfWc4vPYTQ7ugr65syGg4CPswwiUQJKnWBRqe27X1B61pj
-+pxY7w==
+MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM3WhcNMzgw
+MTAxMTIzNDM3WjApMRQwEgYDVQQKEwtleGFtcGxlLmNvbTERMA8GA1UEAxMIY2xp
+Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOh0bvMeu3S1F6t7vEWH
+86hJbiW97pjm8A930DFhe/UIlgPsAmCePZEMg6EtakY5Huva4kYeBUejbRtd3LE7
+q07sOVQqcKt+X8wXThBBHPk/7q6BL+je3cfuisxsS1neX3m5BOAhROPr6kvFDz4f
+SRb4s3jT3bRgh5a7vl5JRv9FAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
+DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBAA1n72ajcRt82cyo3R4P
+E9bqjhm4Y6d+a6vk4tPLk1uLD/EQw5ShAY6sM/FUzX8M4oyZ4A9Xouse0iXAVb50
+6gdqzfNtXeR5jIkTVNly0XJ99JfTgVHX0EcHPi3pffhiRCuNG2zEE6jIvUPym7UN
+3BXv6NWbBMOXAaVl99vckvxm
-----END CERTIFICATE-----
Bag Attributes
friendlyName: server1.example.com
- localKeyID: 39 11 FB 30 22 36 42 DA FC D7 A2 8A 0C 60 83 2F 66 A7 B8 4E
+ localKeyID: D4 9D 8D 60 1B 5A C6 66 02 A2 64 35 71 A8 31 A8 E2 BA D7 48
subject=/CN=server1.example.com
issuer=/O=example.com/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIIC0DCCAjmgAwIBAgIBZTANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt
+MIIC2zCCAkSgAwIBAgIBZTANBgkqhkiG9w0BAQsFADAzMRQwEgYDVQQKEwtleGFt
cGxlLmNvbTEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
-MzQwNVoXDTM4MDEwMTEyMzQwNVowHjEcMBoGA1UEAxMTc2VydmVyMS5leGFtcGxl
-LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyAGT263/ZlxGjPEi2BQj
-DMa/86TF+zVzMfozEZNOLiX6Sov54fW5I0nXCm0CjACOelLa2Eos/vqffxu0w5hM
-A8slRHrt0Gak7dJjwgKK/5NAQDrA+WnyJx/62u25299oCKk+egulCC0D3XczA89N
-cLuz8iKvYnWT+rdnbFdAPdcCAwEAAaOCAQcwggEDMA4GA1UdDwEB/wQEAwIE8DAg
+MzQzOFoXDTM4MDEwMTEyMzQzOFowHjEcMBoGA1UEAxMTc2VydmVyMS5leGFtcGxl
+LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArn0R2/5S4HXPWniCUhAN
+LjIN8KmJ34ZQP2iX6Xin2mGoZRG2WBJtiR7MZfo80W2iFmQzvLN03KINUdeQj5UN
+Gs6yWzQeVHCiA+njszl/NWH7EHt0ftz2XUrQtPGqwoLCCnqnTK9iOpVblQRqbO9r
+1KoQ5LVz47/cAnphIv2938sCAwEAAaOCARIwggEOMA4GA1UdDwEB/wQEAwIE8DAg
BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
I4YhaHR0cDovL2NybC5leGFtcGxlLmNvbS9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
-BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5jb20vMGUGA1Ud
-EQReMFyCIWFsdGVybmF0ZW5hbWUuc2VydmVyMS5leGFtcGxlLmNvbYIiYWx0ZXJu
-YXRlbmFtZTIuc2VydmVyMS5leGFtcGxlLmNvbYITc2VydmVyMS5leGFtcGxlLmNv
-bTANBgkqhkiG9w0BAQUFAAOBgQBWOqQ8y+u4J8KQCHQTiNxIxrUs5Sa+W5HUZ+c8
-SRLXRzDfmNtY7RiofUvbl0j1XH9wuTdjM/EkYnKSYPVu2ra8c8jC3NaVmr0WFqLv
-CvHXQWj2rZha0P/ZG1GfWc4vPYTQ7ugr65syGg4CPswwiUQJKnWBRqe27X1B61pj
-+pxY7w==
+BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5jb20vMHAGA1Ud
+EQRpMGeCE3NlcnZlcjEuZXhhbXBsZS5jb22CIWFsdGVybmF0ZW5hbWUuc2VydmVy
+MS5leGFtcGxlLmNvbYIJKi50ZXN0LmV4giJhbHRlcm5hdGVuYW1lMi5zZXJ2ZXIx
+LmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4GBAD5WJVJcS3nHk+JG6kI1JSdB
+na0pmOL2mzK7HOlqaIG6p4J/PfjVSqaYr+R4Mb9BejthGsj2nnfG8eqX/CvIUHjD
+FTMjRmO58wTMCGg24yvPUmaVnu/wOMB89EKzpuZAUt4bFRpd53ZcMey8YFADUW6f
+Sb8ooudNbc6VBlWggSFJ
-----END CERTIFICATE-----
Bag Attributes
friendlyName: Signing Cert
subject=/O=example.com/CN=clica Signing Cert
issuer=/O=example.com/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA1WhcNMzgw
-MTAxMTIzNDA1WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzwXsp
-P4RsZUoDfQfm5O5bi5unhwl+BTrKIaOtl5TBxMau+qEdKa02DD7Bx6PCzLKhWiZ3
-/MrO7V/cXIBun97dF5Zr5kk+HJk+y3es+xoPd3doknvGQEC/0cSGLcEC7aQ/bEqi
-fw2CgEY5ffkEAnDrdvGGeqBfJJGft/tqmlZbeQIDAQABo1owWDAOBgNVHQ8BAf8E
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM3WhcNMzgw
+MTAxMTIzNDM3WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/GggX
+i+loP31ey0vxDpYe0mlBMHwC9ucGZo2HdTsJeOcGjqR4OTpZcOGbZB+Rhm+ZKZ+D
+lmIAjAit/sSJkqVj0hWlTdtSmgBuejsVqBHg3JwxVCnZmzo0+ILuod9tPcnVMjpz
+qj9CQAEcP+S329jlRKny14LCQzRc09QpszLuxwIDAQABo1owWDAOBgNVHQ8BAf8E
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw
-Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA
-Lq4cCtWMjqLHqf6lJUOBMsm+tgFcYDdxwkTquSZyUrbP1jrODkg5lQWNCdvB76B2
-tZQfMJ3F/kct2EAfsKbHqN3f+DARqPAR2qtOqzl3Ou5+TJjExKgojjzIAPFQzswH
-7v4aglpReaPBaVSNOZ7bMn/E8yRy3o466bhzdEIDcII=
+Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA
+yc6X34U2IKvN9y2EnNYwfsRPEE2LerSN9Tt3UgOuhuETJM7upwacJqOiN+HXQ0xp
+qhRxcDdrNy7MvymNLkc0mSiFGEjWG8dmZz/NFwGCzHSIhPxl6YryfbldbnqQLop0
+KpaftG9PQ4QxymUGjbvty95QvU2MlGA19NbXcLa4Vio=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: Certificate Authority
subject=/O=example.com/CN=clica CA
issuer=/O=example.com/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA0WhcNMzgw
-MTAxMTIzNDA0WjApMRQwEgYDVQQKEwtleGFtcGxlLmNvbTERMA8GA1UEAxMIY2xp
-Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL0wro64rve876glpdRh
-tD6qFY6iH2kCarFFq3WaKmfCvOjYmn4CJr7pL7J5DuvCFh7A0H8lD/on5NK3yqkX
-Yi6EUlaYWxeRo2/PuZYUGbCpejST41sibw9V2dT4MHLidjDShE0W9SfgiMmxfF02
-H5hLYswAGCL1kezsVeEJeH31AgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
-DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBAIn9+8uyQtaq8sBEohTl
-qyJQQeZk5xxaILYP/rCIxc+z5fgOh+usB9adaiD23RPuuD/P2c3UqHJQWqIUTu46
-eOKn9K7X7ndIH3WnaC/u4nysL+SIAug72/k1BAVGNQvyNQMhth6CfZTgY0tgcS0Z
-RSHyhbTD0HeiJDI281BoOJjm
+MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM3WhcNMzgw
+MTAxMTIzNDM3WjApMRQwEgYDVQQKEwtleGFtcGxlLmNvbTERMA8GA1UEAxMIY2xp
+Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOh0bvMeu3S1F6t7vEWH
+86hJbiW97pjm8A930DFhe/UIlgPsAmCePZEMg6EtakY5Huva4kYeBUejbRtd3LE7
+q07sOVQqcKt+X8wXThBBHPk/7q6BL+je3cfuisxsS1neX3m5BOAhROPr6kvFDz4f
+SRb4s3jT3bRgh5a7vl5JRv9FAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
+DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBAA1n72ajcRt82cyo3R4P
+E9bqjhm4Y6d+a6vk4tPLk1uLD/EQw5ShAY6sM/FUzX8M4oyZ4A9Xouse0iXAVb50
+6gdqzfNtXeR5jIkTVNly0XJ99JfTgVHX0EcHPi3pffhiRCuNG2zEE6jIvUPym7UN
+3BXv6NWbBMOXAaVl99vckvxm
-----END CERTIFICATE-----
Bag Attributes
friendlyName: server1.example.com
- localKeyID: 39 11 FB 30 22 36 42 DA FC D7 A2 8A 0C 60 83 2F 66 A7 B8 4E
+ localKeyID: D4 9D 8D 60 1B 5A C6 66 02 A2 64 35 71 A8 31 A8 E2 BA D7 48
subject=/CN=server1.example.com
issuer=/O=example.com/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIIC0DCCAjmgAwIBAgIBZTANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt
+MIIC2zCCAkSgAwIBAgIBZTANBgkqhkiG9w0BAQsFADAzMRQwEgYDVQQKEwtleGFt
cGxlLmNvbTEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
-MzQwNVoXDTM4MDEwMTEyMzQwNVowHjEcMBoGA1UEAxMTc2VydmVyMS5leGFtcGxl
-LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyAGT263/ZlxGjPEi2BQj
-DMa/86TF+zVzMfozEZNOLiX6Sov54fW5I0nXCm0CjACOelLa2Eos/vqffxu0w5hM
-A8slRHrt0Gak7dJjwgKK/5NAQDrA+WnyJx/62u25299oCKk+egulCC0D3XczA89N
-cLuz8iKvYnWT+rdnbFdAPdcCAwEAAaOCAQcwggEDMA4GA1UdDwEB/wQEAwIE8DAg
+MzQzOFoXDTM4MDEwMTEyMzQzOFowHjEcMBoGA1UEAxMTc2VydmVyMS5leGFtcGxl
+LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArn0R2/5S4HXPWniCUhAN
+LjIN8KmJ34ZQP2iX6Xin2mGoZRG2WBJtiR7MZfo80W2iFmQzvLN03KINUdeQj5UN
+Gs6yWzQeVHCiA+njszl/NWH7EHt0ftz2XUrQtPGqwoLCCnqnTK9iOpVblQRqbO9r
+1KoQ5LVz47/cAnphIv2938sCAwEAAaOCARIwggEOMA4GA1UdDwEB/wQEAwIE8DAg
BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
I4YhaHR0cDovL2NybC5leGFtcGxlLmNvbS9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
-BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5jb20vMGUGA1Ud
-EQReMFyCIWFsdGVybmF0ZW5hbWUuc2VydmVyMS5leGFtcGxlLmNvbYIiYWx0ZXJu
-YXRlbmFtZTIuc2VydmVyMS5leGFtcGxlLmNvbYITc2VydmVyMS5leGFtcGxlLmNv
-bTANBgkqhkiG9w0BAQUFAAOBgQBWOqQ8y+u4J8KQCHQTiNxIxrUs5Sa+W5HUZ+c8
-SRLXRzDfmNtY7RiofUvbl0j1XH9wuTdjM/EkYnKSYPVu2ra8c8jC3NaVmr0WFqLv
-CvHXQWj2rZha0P/ZG1GfWc4vPYTQ7ugr65syGg4CPswwiUQJKnWBRqe27X1B61pj
-+pxY7w==
+BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5jb20vMHAGA1Ud
+EQRpMGeCE3NlcnZlcjEuZXhhbXBsZS5jb22CIWFsdGVybmF0ZW5hbWUuc2VydmVy
+MS5leGFtcGxlLmNvbYIJKi50ZXN0LmV4giJhbHRlcm5hdGVuYW1lMi5zZXJ2ZXIx
+LmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4GBAD5WJVJcS3nHk+JG6kI1JSdB
+na0pmOL2mzK7HOlqaIG6p4J/PfjVSqaYr+R4Mb9BejthGsj2nnfG8eqX/CvIUHjD
+FTMjRmO58wTMCGg24yvPUmaVnu/wOMB89EKzpuZAUt4bFRpd53ZcMey8YFADUW6f
+Sb8ooudNbc6VBlWggSFJ
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA1WhcNMzgw\r
-MTAxMTIzNDA1WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp\r
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzwXsp\r
-P4RsZUoDfQfm5O5bi5unhwl+BTrKIaOtl5TBxMau+qEdKa02DD7Bx6PCzLKhWiZ3\r
-/MrO7V/cXIBun97dF5Zr5kk+HJk+y3es+xoPd3doknvGQEC/0cSGLcEC7aQ/bEqi\r
-fw2CgEY5ffkEAnDrdvGGeqBfJJGft/tqmlZbeQIDAQABo1owWDAOBgNVHQ8BAf8E\r
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM3WhcNMzgw\r
+MTAxMTIzNDM3WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp\r
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/GggX\r
+i+loP31ey0vxDpYe0mlBMHwC9ucGZo2HdTsJeOcGjqR4OTpZcOGbZB+Rhm+ZKZ+D\r
+lmIAjAit/sSJkqVj0hWlTdtSmgBuejsVqBHg3JwxVCnZmzo0+ILuod9tPcnVMjpz\r
+qj9CQAEcP+S329jlRKny14LCQzRc09QpszLuxwIDAQABo1owWDAOBgNVHQ8BAf8E\r
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw\r
-Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA\r
-Lq4cCtWMjqLHqf6lJUOBMsm+tgFcYDdxwkTquSZyUrbP1jrODkg5lQWNCdvB76B2\r
-tZQfMJ3F/kct2EAfsKbHqN3f+DARqPAR2qtOqzl3Ou5+TJjExKgojjzIAPFQzswH\r
-7v4aglpReaPBaVSNOZ7bMn/E8yRy3o466bhzdEIDcII=
+Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA\r
+yc6X34U2IKvN9y2EnNYwfsRPEE2LerSN9Tt3UgOuhuETJM7upwacJqOiN+HXQ0xp\r
+qhRxcDdrNy7MvymNLkc0mSiFGEjWG8dmZz/NFwGCzHSIhPxl6YryfbldbnqQLop0\r
+KpaftG9PQ4QxymUGjbvty95QvU2MlGA19NbXcLa4Vio=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: server1.example.com
- localKeyID: 39 11 FB 30 22 36 42 DA FC D7 A2 8A 0C 60 83 2F 66 A7 B8 4E
+ localKeyID: D4 9D 8D 60 1B 5A C6 66 02 A2 64 35 71 A8 31 A8 E2 BA D7 48
Key Attributes: <No Attributes>
-----BEGIN ENCRYPTED PRIVATE KEY-----
-MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQI6fjxhvGKYVoCAggA
-MBQGCCqGSIb3DQMHBAjQxvdFIdms8gSCAoAULVw7VEEz159PQHH1BB4asGdSs50D
-q7BYWQR35O+NEsAPVc/fMn2XnV50X9ETPIYX+5U+5jwAJvYxaRfgkHAoo8Nkh06F
-dMxgd0Ks2k5ri9satjESMmDVce55pFP2QIK+nqFDlpXmAg1hzYFFT0CLKRxzbPCY
-sopcEUpg5zoXUVtMZbQ26HRPbagsIF5gmg7yKAgDBr6cbWkNbFhEjH5P6zV16t1A
-dmhYOvAJgVd32arHiFLE3uj6mmi8qN+HUSTRATTXwVFgwYVz75wJL0+9TsFqqXXP
-JIl/zM7FHa67kzSOXzhzkr3CqzVM498GadDl19hIuTGrw9lwvVlNEnPJQw2GerjQ
-02R6A3FC9areZv+Ixoe/L2G30Z1Js9OIkuQbyTjAvLsPQg5yL+/Z6J4KPdY0SHZh
-a4MIZ12vX4qzQPPQHiIZ8yTEcXBCq3v5towxnKutdtszonvHiTWTcwf2fMNIO6Kc
-5H8V5l87Tl0LzIWC/gjA0nChDf7ckTJAzVPBWP8CI9Dhf0KbE7Z3d99+lSlhA9+u
-Tjkrk13qjCSvaROlnI/tE9H99LwN74b6/BMfYy5F8hwYYeIYXZsZUdbY/S+Ugb+L
-BvUxW3Z6ObTI4RPKOKVY9cCQilfUYjnnLTx9JagqkBnpgC4g6CgB8bEU7ClOulv4
-Y0+Z4WZySNAXBEC1nb5F/4V+zY2pSVbKaMRttILz7c0Uo/2lcBsQVy7lN6bD18ea
-s/jWj3oDfM/pKHSGR+DY/VEy1AGnXrovqlV6NlpeuKUnk/cLtQNOFCRPMJLub7z6
-JF3aDC4L1yiIYyMGUZDagv70kTWhH7glcB1TzUsipET88HU8HM9t1yyO
+MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIAWta/0EFh3kCAggA
+MBQGCCqGSIb3DQMHBAgg49RqNafa5gSCAoDCr7VhbDfic7umTyKEaGKtVrjiUnzy
+JLv/ONg/O6KVAzRqJZxTmwB3C1wJo9RPd377KR156hxx31Xi2My62DRlwkjFV1F9
+lDmA5lC+QXtuSKCNHM9EJGiRYo4JnZIWaviZHU9cyIyLDoV5s7qI/t3VRUeK1aLx
+lEqVqyPSbcVEX3rOGvPrzN/hW3WKLPxUSEBWBp2RidFj4cxudORCcYfjeHDszUe8
+AwTf82zKWcfAK+hEGKpq45FfD/UzP32oQkzctlQnoOi0ElI+trumldu/ywjX1gzb
+07Lbbg5x5av8kzh8Gue+RD2Swcb4bq8zEK8hPNIz0ougHnfxTvNW1qBU4K8Ygm70
+8gA3MEJed9raElBrN5CD1vFQCZOkitIFQ63PyxQyal0DzlUhVZnD6ZemPPs71+rh
+ypHMbRrb292aWJRkjO9zV1kI4ZsMSi0kh7oZEsw+7LKGHYP5lzWb6CQC0DDbEKDJ
+zpH/ewegpm2klnCXv3Vr1MLEB3Mc7hYi41ZhyQlSpxA5MXe81JfDIwcaAs64Jo0z
+H41CxdV5q0kQftgV+S8zNIQ4i36vUHvez9TdtBHlcy4dukqZeeU+o50vzzT29BP+
+QDfSzunvB5oorFAr2Nf9p4WfvjlKlZslkUo63cJmUYH1gEf/+0GWruse9pJ7BtHo
+6zgedGjEsLGUQfh9xwj5Vo5w4dv9kYkmbfmYdToLYXndW9kQFcpqXANB7ukSu21r
+WyoWuSayxYy/4yQqLrlSGu2Yj06wmJSLT95l0iEQBbs2pEdj2u72bjHNuYn9t3Kk
+Zq8xWKQdWgY/4UVKAVCb8d3yOhuqjONZykcV8a+vdK/8L9Mi9TNyVaa0
-----END ENCRYPTED PRIVATE KEY-----
Bag Attributes
friendlyName: server1.example.com
- localKeyID: 39 11 FB 30 22 36 42 DA FC D7 A2 8A 0C 60 83 2F 66 A7 B8 4E
+ localKeyID: D4 9D 8D 60 1B 5A C6 66 02 A2 64 35 71 A8 31 A8 E2 BA D7 48
subject=/CN=server1.example.com
issuer=/O=example.com/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIIC0DCCAjmgAwIBAgIBZTANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt
+MIIC2zCCAkSgAwIBAgIBZTANBgkqhkiG9w0BAQsFADAzMRQwEgYDVQQKEwtleGFt
cGxlLmNvbTEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
-MzQwNVoXDTM4MDEwMTEyMzQwNVowHjEcMBoGA1UEAxMTc2VydmVyMS5leGFtcGxl
-LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyAGT263/ZlxGjPEi2BQj
-DMa/86TF+zVzMfozEZNOLiX6Sov54fW5I0nXCm0CjACOelLa2Eos/vqffxu0w5hM
-A8slRHrt0Gak7dJjwgKK/5NAQDrA+WnyJx/62u25299oCKk+egulCC0D3XczA89N
-cLuz8iKvYnWT+rdnbFdAPdcCAwEAAaOCAQcwggEDMA4GA1UdDwEB/wQEAwIE8DAg
+MzQzOFoXDTM4MDEwMTEyMzQzOFowHjEcMBoGA1UEAxMTc2VydmVyMS5leGFtcGxl
+LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArn0R2/5S4HXPWniCUhAN
+LjIN8KmJ34ZQP2iX6Xin2mGoZRG2WBJtiR7MZfo80W2iFmQzvLN03KINUdeQj5UN
+Gs6yWzQeVHCiA+njszl/NWH7EHt0ftz2XUrQtPGqwoLCCnqnTK9iOpVblQRqbO9r
+1KoQ5LVz47/cAnphIv2938sCAwEAAaOCARIwggEOMA4GA1UdDwEB/wQEAwIE8DAg
BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
I4YhaHR0cDovL2NybC5leGFtcGxlLmNvbS9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
-BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5jb20vMGUGA1Ud
-EQReMFyCIWFsdGVybmF0ZW5hbWUuc2VydmVyMS5leGFtcGxlLmNvbYIiYWx0ZXJu
-YXRlbmFtZTIuc2VydmVyMS5leGFtcGxlLmNvbYITc2VydmVyMS5leGFtcGxlLmNv
-bTANBgkqhkiG9w0BAQUFAAOBgQBWOqQ8y+u4J8KQCHQTiNxIxrUs5Sa+W5HUZ+c8
-SRLXRzDfmNtY7RiofUvbl0j1XH9wuTdjM/EkYnKSYPVu2ra8c8jC3NaVmr0WFqLv
-CvHXQWj2rZha0P/ZG1GfWc4vPYTQ7ugr65syGg4CPswwiUQJKnWBRqe27X1B61pj
-+pxY7w==
+BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5jb20vMHAGA1Ud
+EQRpMGeCE3NlcnZlcjEuZXhhbXBsZS5jb22CIWFsdGVybmF0ZW5hbWUuc2VydmVy
+MS5leGFtcGxlLmNvbYIJKi50ZXN0LmV4giJhbHRlcm5hdGVuYW1lMi5zZXJ2ZXIx
+LmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4GBAD5WJVJcS3nHk+JG6kI1JSdB
+na0pmOL2mzK7HOlqaIG6p4J/PfjVSqaYr+R4Mb9BejthGsj2nnfG8eqX/CvIUHjD
+FTMjRmO58wTMCGg24yvPUmaVnu/wOMB89EKzpuZAUt4bFRpd53ZcMey8YFADUW6f
+Sb8ooudNbc6VBlWggSFJ
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
-MIICXAIBAAKBgQDIAZPbrf9mXEaM8SLYFCMMxr/zpMX7NXMx+jMRk04uJfpKi/nh
-9bkjSdcKbQKMAI56UtrYSiz++p9/G7TDmEwDyyVEeu3QZqTt0mPCAor/k0BAOsD5
-afInH/ra7bnb32gIqT56C6UILQPddzMDz01wu7PyIq9idZP6t2dsV0A91wIDAQAB
-AoGAIT/Z48heUBcBB4dC4qceWI5l9MwsuaFeIC3W9ZIGijd4D5KLnRvrhklNPYd3
-x+yDwyQpC5HxPwZNI6VofKfB4whObRomItHBYDvy0u2xVGinZydYXdIgg9XUw4zj
-FETx7NeIa+zQMA8oGbKfnk6c+5sFqJInylh9oYcVC5mr1BkCQQDnf/5cTco79KC+
-HDHO/XKiRrWZGlrl8m4BJldYvmocRtiYD7nu7YccrvNV5vRHiTY0xTScMZchoSaO
-vWZ13i9LAkEA3SxTPa675S4Or+Ab2wKWORdvK1rKWXYgH4th3zfN9sWB5X7XTFe1
-tmelJjlb0diGYBX3ZyNLo3aHcqSOPYE4JQJAFuvkao1FPeR92fT+tYkAxbKMnoku
-gOAdJj3+ngnUhdI59exws4iPPTbRXysL+t1KIbV4/RIn7auAHtgAAiGquwJAdtiq
-oiqSrMPjAH7ceQMa1fLRueo/cXMYL9sl7FyAQGpBMqDF8C/xZOKsy61muYwwKNGk
-77b3ng7DGcdy53nYQQJBAKxU/egi+ss4im9KOhzFLtnAS0VIqvKv5KXMUQ42bP6x
-kKM6yiLi2005IjEKmO/eq3bD2ryXETMwS9Lc8/Ecm0A=
+MIICXQIBAAKBgQCufRHb/lLgdc9aeIJSEA0uMg3wqYnfhlA/aJfpeKfaYahlEbZY
+Em2JHsxl+jzRbaIWZDO8s3Tcog1R15CPlQ0azrJbNB5UcKID6eOzOX81YfsQe3R+
+3PZdStC08arCgsIKeqdMr2I6lVuVBGps72vUqhDktXPjv9wCemEi/b3fywIDAQAB
+AoGBAKpRBne4HWlfVVC3xG0ZoePvk8/PjPaUAgyCqZWI4j61iEtvKI97HVP0rgr0
+YR0DaG12zVFp0a3yuBGk2kRsduaRCWfveyy9RKweLU3ykSJS013q4FROXXh8CEhf
+TVm/JY5LL1qwKZqQGi6BwAJEDwlntTrirjobMxjD49aWTcIBAkEA2Y4+62TvEANl
+bQygSbnQIXZdvHyQMirV944u1cqEcm3zflVULpPjDdBdvOhGMd2napdWvNorl8CP
+3/o8d8ougQJBAM1Sj3RbMOMVRvSJ3olb1qY7NG4GituL+bV2e4usZ+vh1qYEZA87
+S0jvfAgmDVYV7jcl/CrHj8vJgWHSLkziQEsCQQCj5Cf8NxZtbtGKvDdIMyXa/4uQ
+Ahqy4Fg+XStlPWJXvgLwCiIX0Kr87hqfxC+VQ1Dq2MWsEYNDl/oLFj1VVMeBAkA+
+WSzAu5RL0ME8LsWJ1n6G+gGAy7HM22OXjAQWNONVyL2CqmCsE2hYHIkAfHWeR4iP
+7JP3daQf0O/eAZIXvLijAkBWP8qfzCF5ONBnWTrGdTWG0p2OPgk/XGl4hVK2gFoD
+sqOKXCi2yb3a51bubQFGKIazO16IeDrE2XvCPzMniQwh
-----END RSA PRIVATE KEY-----
subject=/O=example.com/CN=clica Signing Cert
issuer=/O=example.com/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA1WhcNMzgw
-MTAxMTIzNDA1WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzwXsp
-P4RsZUoDfQfm5O5bi5unhwl+BTrKIaOtl5TBxMau+qEdKa02DD7Bx6PCzLKhWiZ3
-/MrO7V/cXIBun97dF5Zr5kk+HJk+y3es+xoPd3doknvGQEC/0cSGLcEC7aQ/bEqi
-fw2CgEY5ffkEAnDrdvGGeqBfJJGft/tqmlZbeQIDAQABo1owWDAOBgNVHQ8BAf8E
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM3WhcNMzgw
+MTAxMTIzNDM3WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/GggX
+i+loP31ey0vxDpYe0mlBMHwC9ucGZo2HdTsJeOcGjqR4OTpZcOGbZB+Rhm+ZKZ+D
+lmIAjAit/sSJkqVj0hWlTdtSmgBuejsVqBHg3JwxVCnZmzo0+ILuod9tPcnVMjpz
+qj9CQAEcP+S329jlRKny14LCQzRc09QpszLuxwIDAQABo1owWDAOBgNVHQ8BAf8E
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw
-Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA
-Lq4cCtWMjqLHqf6lJUOBMsm+tgFcYDdxwkTquSZyUrbP1jrODkg5lQWNCdvB76B2
-tZQfMJ3F/kct2EAfsKbHqN3f+DARqPAR2qtOqzl3Ou5+TJjExKgojjzIAPFQzswH
-7v4aglpReaPBaVSNOZ7bMn/E8yRy3o466bhzdEIDcII=
+Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA
+yc6X34U2IKvN9y2EnNYwfsRPEE2LerSN9Tt3UgOuhuETJM7upwacJqOiN+HXQ0xp
+qhRxcDdrNy7MvymNLkc0mSiFGEjWG8dmZz/NFwGCzHSIhPxl6YryfbldbnqQLop0
+KpaftG9PQ4QxymUGjbvty95QvU2MlGA19NbXcLa4Vio=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: Certificate Authority
subject=/O=example.com/CN=clica CA
issuer=/O=example.com/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA0WhcNMzgw
-MTAxMTIzNDA0WjApMRQwEgYDVQQKEwtleGFtcGxlLmNvbTERMA8GA1UEAxMIY2xp
-Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL0wro64rve876glpdRh
-tD6qFY6iH2kCarFFq3WaKmfCvOjYmn4CJr7pL7J5DuvCFh7A0H8lD/on5NK3yqkX
-Yi6EUlaYWxeRo2/PuZYUGbCpejST41sibw9V2dT4MHLidjDShE0W9SfgiMmxfF02
-H5hLYswAGCL1kezsVeEJeH31AgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
-DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBAIn9+8uyQtaq8sBEohTl
-qyJQQeZk5xxaILYP/rCIxc+z5fgOh+usB9adaiD23RPuuD/P2c3UqHJQWqIUTu46
-eOKn9K7X7ndIH3WnaC/u4nysL+SIAug72/k1BAVGNQvyNQMhth6CfZTgY0tgcS0Z
-RSHyhbTD0HeiJDI281BoOJjm
------END CERTIFICATE-----
-Bag Attributes
- friendlyName: server2.example.com
- localKeyID: 40 B2 13 5E 6B 67 AE 36 A3 97 69 6D A3 28 42 36 85 E7 4C E3
-subject=/CN=server2.example.com
-issuer=/O=example.com/CN=clica Signing Cert
------BEGIN CERTIFICATE-----
-MIICiDCCAfGgAwIBAgICAMkwDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhh
-bXBsZS5jb20xGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDEx
-MjM0MDZaFw0zODAxMDExMjM0MDZaMB4xHDAaBgNVBAMTE3NlcnZlcjIuZXhhbXBs
-ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALLgFpuQXy2obzVio/WK
-IQr7+KQt3p1umyTBM0FgRS2wEvbobbp5yi304Ob3v2BOpBwpKBbH+SXwAWKg5z8j
-XVf/h76XGcKdbwSQtt7Rq1ANKW63urh0+MaGyHeBFC1zYdQHqvqHcfFzSA1Ai4yy
-tXf7OdNmRI7cK/FwtPLji28xAgMBAAGjgb8wgbwwDgYDVR0PAQH/BAQDAgTwMCAG
-A1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAj
-hiFodHRwOi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEE
-KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLmNvbS8wHgYDVR0R
-BBcwFYITc2VydmVyMi5leGFtcGxlLmNvbTANBgkqhkiG9w0BAQUFAAOBgQBsN0Em
-TV30tTEQZ8r7ZLYimGL3HpV7bOZ0RyH0Xok2PrmcisVSu8SvEpMmO9c94FZxHh0h
-IALt8E7VXkVC/Tw4QVSDhgs7v8VHOf8V6pPc/cc9GFhZyt0q2Ln5L7l2k/Su45FW
-gC+MBC+tV+/SURn0tO8ynKw6fA24Odux4zBzGg==
+MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM3WhcNMzgw
+MTAxMTIzNDM3WjApMRQwEgYDVQQKEwtleGFtcGxlLmNvbTERMA8GA1UEAxMIY2xp
+Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOh0bvMeu3S1F6t7vEWH
+86hJbiW97pjm8A930DFhe/UIlgPsAmCePZEMg6EtakY5Huva4kYeBUejbRtd3LE7
+q07sOVQqcKt+X8wXThBBHPk/7q6BL+je3cfuisxsS1neX3m5BOAhROPr6kvFDz4f
+SRb4s3jT3bRgh5a7vl5JRv9FAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
+DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBAA1n72ajcRt82cyo3R4P
+E9bqjhm4Y6d+a6vk4tPLk1uLD/EQw5ShAY6sM/FUzX8M4oyZ4A9Xouse0iXAVb50
+6gdqzfNtXeR5jIkTVNly0XJ99JfTgVHX0EcHPi3pffhiRCuNG2zEE6jIvUPym7UN
+3BXv6NWbBMOXAaVl99vckvxm
-----END CERTIFICATE-----
Bag Attributes
friendlyName: server2.example.com
- localKeyID: 40 B2 13 5E 6B 67 AE 36 A3 97 69 6D A3 28 42 36 85 E7 4C E3
+ localKeyID: 1A 42 0D 86 5B 90 06 8F B8 22 E7 15 67 A4 56 A3 57 8D 26 AA
subject=/CN=server2.example.com
issuer=/O=example.com/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICiDCCAfGgAwIBAgICAMkwDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhh
+MIICiDCCAfGgAwIBAgICAMkwDQYJKoZIhvcNAQELBQAwMzEUMBIGA1UEChMLZXhh
bXBsZS5jb20xGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDEx
-MjM0MDZaFw0zODAxMDExMjM0MDZaMB4xHDAaBgNVBAMTE3NlcnZlcjIuZXhhbXBs
-ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALLgFpuQXy2obzVio/WK
-IQr7+KQt3p1umyTBM0FgRS2wEvbobbp5yi304Ob3v2BOpBwpKBbH+SXwAWKg5z8j
-XVf/h76XGcKdbwSQtt7Rq1ANKW63urh0+MaGyHeBFC1zYdQHqvqHcfFzSA1Ai4yy
-tXf7OdNmRI7cK/FwtPLji28xAgMBAAGjgb8wgbwwDgYDVR0PAQH/BAQDAgTwMCAG
+MjM0MzhaFw0zODAxMDExMjM0MzhaMB4xHDAaBgNVBAMTE3NlcnZlcjIuZXhhbXBs
+ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALoxxS9eRRSkEJF5CmlL
+ToLY3886wsCOc+vuBo+2V69Q7aCC3Wa13UTZ7SVPhliw29gl48Ua7Go5E6E4+6n7
+SNL+VfuMtNg2zs4BIhXTfiPZ9U2YF77+Y64MFPBxK98F/RB/wjqAiWf5aigaQCSG
+X7Bf1bb1s3UwCi0M/wXHYj7TAgMBAAGjgb8wgbwwDgYDVR0PAQH/BAQDAgTwMCAG
A1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAj
hiFodHRwOi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEE
KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLmNvbS8wHgYDVR0R
-BBcwFYITc2VydmVyMi5leGFtcGxlLmNvbTANBgkqhkiG9w0BAQUFAAOBgQBsN0Em
-TV30tTEQZ8r7ZLYimGL3HpV7bOZ0RyH0Xok2PrmcisVSu8SvEpMmO9c94FZxHh0h
-IALt8E7VXkVC/Tw4QVSDhgs7v8VHOf8V6pPc/cc9GFhZyt0q2Ln5L7l2k/Su45FW
-gC+MBC+tV+/SURn0tO8ynKw6fA24Odux4zBzGg==
+BBcwFYITc2VydmVyMi5leGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOBgQCZCepT
+W/JRRZlxxEIcQVlQLpdcxuJnYvNbZwzn7Os0K7og1S7jl4PDncao6APk6f4WAfFj
+b4ZZc1NytSHPLuodWToY1bUzIBMKwk9Jof2yw2mr/3ElyzRDlVmXri+6b0X5WmfM
+eWI7npeb6Pl6n18tTYKkGGcFwsFsC+CeuLOzNw==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA1WhcNMzgw\r
-MTAxMTIzNDA1WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp\r
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzwXsp\r
-P4RsZUoDfQfm5O5bi5unhwl+BTrKIaOtl5TBxMau+qEdKa02DD7Bx6PCzLKhWiZ3\r
-/MrO7V/cXIBun97dF5Zr5kk+HJk+y3es+xoPd3doknvGQEC/0cSGLcEC7aQ/bEqi\r
-fw2CgEY5ffkEAnDrdvGGeqBfJJGft/tqmlZbeQIDAQABo1owWDAOBgNVHQ8BAf8E\r
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLmNvbTERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM3WhcNMzgw\r
+MTAxMTIzNDM3WjAzMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEbMBkGA1UEAxMSY2xp\r
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/GggX\r
+i+loP31ey0vxDpYe0mlBMHwC9ucGZo2HdTsJeOcGjqR4OTpZcOGbZB+Rhm+ZKZ+D\r
+lmIAjAit/sSJkqVj0hWlTdtSmgBuejsVqBHg3JwxVCnZmzo0+ILuod9tPcnVMjpz\r
+qj9CQAEcP+S329jlRKny14LCQzRc09QpszLuxwIDAQABo1owWDAOBgNVHQ8BAf8E\r
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw\r
-Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA\r
-Lq4cCtWMjqLHqf6lJUOBMsm+tgFcYDdxwkTquSZyUrbP1jrODkg5lQWNCdvB76B2\r
-tZQfMJ3F/kct2EAfsKbHqN3f+DARqPAR2qtOqzl3Ou5+TJjExKgojjzIAPFQzswH\r
-7v4aglpReaPBaVSNOZ7bMn/E8yRy3o466bhzdEIDcII=
+Oi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA\r
+yc6X34U2IKvN9y2EnNYwfsRPEE2LerSN9Tt3UgOuhuETJM7upwacJqOiN+HXQ0xp\r
+qhRxcDdrNy7MvymNLkc0mSiFGEjWG8dmZz/NFwGCzHSIhPxl6YryfbldbnqQLop0\r
+KpaftG9PQ4QxymUGjbvty95QvU2MlGA19NbXcLa4Vio=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: server2.example.com
- localKeyID: 40 B2 13 5E 6B 67 AE 36 A3 97 69 6D A3 28 42 36 85 E7 4C E3
+ localKeyID: 1A 42 0D 86 5B 90 06 8F B8 22 E7 15 67 A4 56 A3 57 8D 26 AA
Key Attributes: <No Attributes>
-----BEGIN ENCRYPTED PRIVATE KEY-----
-MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQI9nwG/TOpp3MCAggA
-MBQGCCqGSIb3DQMHBAilpHreae+faASCAoBx69kd96hrjqkgteXaXrMEVH/9sbBQ
-GXzBvazDadBDfUGHJweJKHJfJMujbHCL+ogsQsfwilWZotbkStMjg5ik5pwmq7ry
-nRZF/6vm5lusqXc/4XJcb1tiag8ItcMrgfKCBHIA7HuJveE02C1z20vU40CAvgBW
-QV1+0yZ7t4PPncYU/Mia1DY+hfEDX0U/pV3btevlIqAB38a6/pMptdwEdfQqsgjW
-T+Fu7oW9C9Flo2R5xfGOzfeA4/Ujng9uxQTQoC3fE9j/jp64wE0vRDr6SRTfXM70
-F8YH38oKnhCkAwmnWAV65UBS9k90NIqgqdKljpSmikBuGi7oawgYWFXokAGWru9E
-m8LoMsf6eyxKD9NVJ0F+2lK+qBfHEdR5VOCVZP1VveY/CgZq/E7nRejhQjKsrf/6
-eKmxFYsH4zuz8heEqjZKfl0YAHffKd34dsBetmPviegf6FUBXAUAdtm5nEshYt1g
-A8YQtBNOzoM42T/7temhyo7ZrYBKeXLmej/ZQXCoDT6t1o0vtjPMBBMqTmKZXLGt
-lf2xjAy7uQYvZfarPNVO8ENUSgwsKIfF4ty5wVOQfHrHjRpe51AWi/AcTOcM87r+
-cUvOEUERq6zjC72WEPZB0X2+sTN6yWZgPipIOCuPEiChvs5hjcmXGkOlEjhH11F9
-diTTUvjQh2v8x1Iz+wMlbTVSJnqZXFrXEgQe212zKy8RpKA8tat2y57cgchHJ2n1
-BSSJbWom2HVZ2yYtZoHZSgH9rVJul7QsGI0/MgEuAGy3TKYZhlsSRgjBKqSz+mgU
-Kw7KQxhJnF4nzRsZ17pGWxoEzs0cSTO7c+QGZI126KwCMGIFHFXwcHwV
+MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQI3ifkFALe1RsCAggA
+MBQGCCqGSIb3DQMHBAivK+R4BHCKOQSCAoDZEpqVLwIbnvhINpJF4GbhfuJsegMB
+CHrWIWE+/Uzc9dcf4FILsvwcvH+u0JbpZfxpKNs/XYkb6x8rlKajodb4MZUQP6z7
+5fYM+4dpRTEzgNBGUgGenEWqzOJYn07QJcqYhEkeWDfLomOZXkfrNh0CON1nYdUm
+1u33hIWqgbJoUXyxn5goHbwKRrDzdGRNzRKaOSC2Z7i/ZD95irOQ92jttqnpgXiw
+guF4rZH9659yZc7oO5RC4aS8qNXbD86vfKeGch1NBCG6tWxnVbKib5xV/MVb47qq
+CLR0s16UooFsCnXdy+bnkn5/pZ0mCPSab1vhMFwWDvcczJrNxFEYy/Bm+p1iExuu
+mOToNay/97ggu1nlZKMKMmB7/gGP/d/be44oKEr6kgUj+W5t0BrBltntm6dZo9pK
+o8mXC7Fj+qXGs4m3j/jr+iVGvpt0A0JWvtRaty9HmoHZpEJgECvhktUmHiMuvKSX
+iLrTJpHpBBPwHcwYx/xxQzSMmupDMsTpoRbBklMSQdeJBkRlkudsiZRdUKMnn+bS
+whH5jH8wzMaKzzHAsXUTajmUDSoK3ETFqfZpNWdUysppjK5BTBQFWo54/7fuiloe
+zz0dW9iJVbt6HHRYmnpgZ4wg2LajhfHBXMSiKJhGZmZf8CvPN8K6HETDoK0Sylqy
+ACbsHqOC0sIqFgxWLfqkafh4iB/tmoBT31Qg97OFAeOHwd4kMu01CzgDXiUyUb8s
+H+I8jmmWK7lPs1cXW/ePdt4vdqrdW7FC7Ealqs9KiMkYd1nSvHyE1mAtEQl4+/xG
+FWPEQIvXYUpZAAxevXmukAUKNPY0AytybqqqfkQe6CbpSeOfzdtdnOgz
-----END ENCRYPTED PRIVATE KEY-----
Bag Attributes
friendlyName: server2.example.com
- localKeyID: 40 B2 13 5E 6B 67 AE 36 A3 97 69 6D A3 28 42 36 85 E7 4C E3
+ localKeyID: 1A 42 0D 86 5B 90 06 8F B8 22 E7 15 67 A4 56 A3 57 8D 26 AA
subject=/CN=server2.example.com
issuer=/O=example.com/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICiDCCAfGgAwIBAgICAMkwDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhh
+MIICiDCCAfGgAwIBAgICAMkwDQYJKoZIhvcNAQELBQAwMzEUMBIGA1UEChMLZXhh
bXBsZS5jb20xGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDEx
-MjM0MDZaFw0zODAxMDExMjM0MDZaMB4xHDAaBgNVBAMTE3NlcnZlcjIuZXhhbXBs
-ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALLgFpuQXy2obzVio/WK
-IQr7+KQt3p1umyTBM0FgRS2wEvbobbp5yi304Ob3v2BOpBwpKBbH+SXwAWKg5z8j
-XVf/h76XGcKdbwSQtt7Rq1ANKW63urh0+MaGyHeBFC1zYdQHqvqHcfFzSA1Ai4yy
-tXf7OdNmRI7cK/FwtPLji28xAgMBAAGjgb8wgbwwDgYDVR0PAQH/BAQDAgTwMCAG
+MjM0MzhaFw0zODAxMDExMjM0MzhaMB4xHDAaBgNVBAMTE3NlcnZlcjIuZXhhbXBs
+ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALoxxS9eRRSkEJF5CmlL
+ToLY3886wsCOc+vuBo+2V69Q7aCC3Wa13UTZ7SVPhliw29gl48Ua7Go5E6E4+6n7
+SNL+VfuMtNg2zs4BIhXTfiPZ9U2YF77+Y64MFPBxK98F/RB/wjqAiWf5aigaQCSG
+X7Bf1bb1s3UwCi0M/wXHYj7TAgMBAAGjgb8wgbwwDgYDVR0PAQH/BAQDAgTwMCAG
A1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAj
hiFodHRwOi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEE
KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLmNvbS8wHgYDVR0R
-BBcwFYITc2VydmVyMi5leGFtcGxlLmNvbTANBgkqhkiG9w0BAQUFAAOBgQBsN0Em
-TV30tTEQZ8r7ZLYimGL3HpV7bOZ0RyH0Xok2PrmcisVSu8SvEpMmO9c94FZxHh0h
-IALt8E7VXkVC/Tw4QVSDhgs7v8VHOf8V6pPc/cc9GFhZyt0q2Ln5L7l2k/Su45FW
-gC+MBC+tV+/SURn0tO8ynKw6fA24Odux4zBzGg==
+BBcwFYITc2VydmVyMi5leGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOBgQCZCepT
+W/JRRZlxxEIcQVlQLpdcxuJnYvNbZwzn7Os0K7og1S7jl4PDncao6APk6f4WAfFj
+b4ZZc1NytSHPLuodWToY1bUzIBMKwk9Jof2yw2mr/3ElyzRDlVmXri+6b0X5WmfM
+eWI7npeb6Pl6n18tTYKkGGcFwsFsC+CeuLOzNw==
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
-MIICXgIBAAKBgQCy4BabkF8tqG81YqP1iiEK+/ikLd6dbpskwTNBYEUtsBL26G26
-ecot9ODm979gTqQcKSgWx/kl8AFioOc/I11X/4e+lxnCnW8EkLbe0atQDSlut7q4
-dPjGhsh3gRQtc2HUB6r6h3Hxc0gNQIuMsrV3+znTZkSO3CvxcLTy44tvMQIDAQAB
-AoGBAK76UIM6tjBmvOq/JF50EaC6HV8VU9gzM2a/65C/SMzJmbOYaIZqzuEn0718
-iuP96cF2bTXjxpBa+C/v8GYuBQcFv6Pkg02KTDOCyjjcZrvArhUcgmOx4n2BVVR/
-8nR1R0JDvdw0HJbIom4ABYLTAjNVG5HZcnWC3ylA/n57p+ABAkEA4XUa5Lc7U0b1
-rwRqHH2pdF/zYpDxSaLXcjP9YC2r1+siwyvbL7qtQy3DQyw3AM1WtCefUAQhL5Jq
-Ex630RwiAQJBAMsbgoAwiI2ZQQ1eJyIjbG8pn3Pprq6QPbUKE9NdWaoUcxjyPRSB
-1nhJcjgrk1T3BvooktNUEzseSUI8A7Wu7TECQQCpx03hPjpmk+EfUuu1WMvq3vah
-GxUYppAnaA8+BiaKCn+7CaOdZa5kEGoig4FIEVlhgRTvZKy47kEC9PbneZABAkEA
-mzhB6n+szDI0IegzlgZmZynzHx2WjvfTANlbv2uXC8EnGQh/n31+j1zp+n1q0kMb
-RPDfDLwzGjoSGJlO6Hlv8QJAZHPfEo+GCWA18JwI1HM3o+idyJ7fH92Sig0/ZwwE
-MG9RVzhYuCaqCBGlx6mRm1LIe3mjQCn4cE+x/gheyRfZhw==
+MIICXAIBAAKBgQC6McUvXkUUpBCReQppS06C2N/POsLAjnPr7gaPtlevUO2ggt1m
+td1E2e0lT4ZYsNvYJePFGuxqOROhOPup+0jS/lX7jLTYNs7OASIV034j2fVNmBe+
+/mOuDBTwcSvfBf0Qf8I6gIln+WooGkAkhl+wX9W29bN1MAotDP8Fx2I+0wIDAQAB
+AoGAR4bHESNNtlgwZTHyZfCgAHP/xkP0fLQ8o+2UZ7DMjnSwVHDxTHugvMpa53Jd
+UcTfL3GexiFJoKS8fbq+MtZtarg3ftcZlIo6MevkmrFx+egJGOFjxtQ1WuQvfXiQ
+0EVluY7UQ0uQwGcR6DKzF64W+g+3KvvaB63Yk9mW5zDALcECQQDsJuD04ViTIiAW
+vLcgY3sKJ3xtmDm89EpqCCIC+2mAr6s5B1La3XLBwpvB8UatTlgrorp5w23Sudjr
+xa+ztrptAkEAydf9kP0chQT6+JC+Dvqn5X5ABGFWpMyKgFkX4vCsnGzjPKpJ1cnF
+oYuSewKJ4q4uPfLGmfwx6RDcSHyaP9kWPwJBAI53/it+cCOD6PwOqiReH/LGU6kC
+t4KpluNVOL+30bSTRqdHJdNo2jzPHYzp9QvFQihBKmMfZfhFqvrC7vdq/BkCQE9U
+owZ/VNw7LuDPEsQUZDTgwAx4rXMsKSt02NyLN2xrp4xKaaarHQ/3KWVLhCIhz27t
+on0XEA7IX6vlvUJm8kUCQFGTRjMIiNL4rvukKi1hgRFul/Bgx9xjUy5pmXTJZQhp
+A7rrhpTkMJ01tTBWQOYNFw5JghzW+6hBfeQX9bbYhzU=
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
-MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDExWhcNMzgw\r
-MTAxMTIzNDExWjApMRQwEgYDVQQKEwtleGFtcGxlLm5ldDERMA8GA1UEAxMIY2xp\r
-Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALUSMNgU8YE8fsiB8Wm7\r
-lpclDOwQXJVbP/Ef2NVwoE6NnoPTWMNgvSyCddVz7709URkIy+jtrlpbyQYVdwgO\r
-HAnI8/bx2WoGtGzWTbAM1Mp+WHtiOO7LpsldWQmeHuF9uBOghFytVyqNT2l/iG7x\r
-XQCA6Q6P59vpb3Z+4PH8kgVlAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw\r
-DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBACs6X9bwml5hcwf82pyb\r
-bKOnRGP6pJsvx1yv6SULaxg4+mCelEHNPycQqidqs+84RrDma8Kkz3DVZuV11Yca\r
-o2ibon7rWhaTc9SR0j5B8BMU1Z9VEVF5uejepHWf1iCeOhxl6tNQuTTJP0uE4h6h\r
-VAtQ+ux57x052IuOi9FtrqVR
+MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDQwWhcNMzgw\r
+MTAxMTIzNDQwWjApMRQwEgYDVQQKEwtleGFtcGxlLm5ldDERMA8GA1UEAxMIY2xp\r
+Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOY7eAp9lkZsBxaHMAn5\r
+1zK898gr+Yxq+Vxgi6sXXmhsq20D/qHjVsKakEQtQLdBc3di6kRPURWiHrVqwQ+t\r
+RIpR1pQXqoaPmVf11aCvS3pEUaBreO+LQ3CJImrS887XIrGPDuuYuTaKrChtcMPN\r
+idZRKhwJAajAVJvivdDv6ucHAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw\r
+DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBABVCocYnR8xCX0k6HVaW\r
+RX+SAucii+m4sX6TJ/yWjNvQjKxrs3gwe19yOJB0WCOQKqU2s7UhxovW39qD4q60\r
+dSKq+qjW/4DfLmi1d/5aMqAq9au/s7W9Ut/jqqdL5eY31lxWRyW+D+29mfRyl+B7\r
+H0+wMSKs4DNtTYYEd+3W8kEw
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDExWhcNMzgw\r
-MTAxMTIzNDExWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp\r
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCf/Mo\r
-cl7+ta84A85TdEcSPfv+JV6/0ynu98Z+EHaz221TGgNYkOtlBDc80kZZ2QBndE6e\r
-RZAuIaPgTVk0mZJ7XUxAVx7AAlGSWenScV/k/VChgqddRaCmmLQoPT/wUkrDqlOW\r
-7omdM0BTaMxdEv2QRyUCVrrZKOJkRsTILkUvaQIDAQABo1owWDAOBgNVHQ8BAf8E\r
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDQwWhcNMzgw\r
+MTAxMTIzNDQwWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp\r
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXxUua\r
+JOUjKYqtSZyRwCoF1o5VI5yr+sinPkKPpGQnFd28bani9yCcLdvvOVCBPBmBe3vJ\r
+sjRSu5YO3fGlE7dRbiUBCvmOtZ4Kk39mgQcThWp8R8Mxk//ex5BSLlw3q43BY3Om\r
++V59fPWaYgHKE/RIjneGJb97oa3AmxjvZcZXnQIDAQABo1owWDAOBgNVHQ8BAf8E\r
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw\r
-Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA\r
-P/kvw/kOJI5Yja+W8/xmbAma4NeAWE48eLDzp6AWJBUU7oIj4Ca+PqwpaxxeNioZ\r
-ihLL5LCRrS8lsSGgyD3UzqYGCMOwqX5pBytpWXz1NRzzey9mCV55LHckBF7dRBuh\r
-XQiz+EvE4Dr1ZikrB6UjgHW7Bal9Y5QMDs8qZAsRkJ0=
+Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA\r
+rPmUtgNXl5WO6GDheUimkO9DGTeKnk8n/Hwlm6KjqYfkaJuf1YTKD2bgqfsW4TQM\r
+uN/wZurB9sbZTdrPqqD+pS8xV8CloldkH4x3PtUz+0Z4Fkgf4IQG1GKI/OGu2Ego\r
+6UjWNb+M5nNokpzyV7bAslmTj6Q7CCVQuNSKGfOIJEc=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDExWhcNMzgw\r
-MTAxMTIzNDExWjApMRQwEgYDVQQKEwtleGFtcGxlLm5ldDERMA8GA1UEAxMIY2xp\r
-Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALUSMNgU8YE8fsiB8Wm7\r
-lpclDOwQXJVbP/Ef2NVwoE6NnoPTWMNgvSyCddVz7709URkIy+jtrlpbyQYVdwgO\r
-HAnI8/bx2WoGtGzWTbAM1Mp+WHtiOO7LpsldWQmeHuF9uBOghFytVyqNT2l/iG7x\r
-XQCA6Q6P59vpb3Z+4PH8kgVlAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw\r
-DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBACs6X9bwml5hcwf82pyb\r
-bKOnRGP6pJsvx1yv6SULaxg4+mCelEHNPycQqidqs+84RrDma8Kkz3DVZuV11Yca\r
-o2ibon7rWhaTc9SR0j5B8BMU1Z9VEVF5uejepHWf1iCeOhxl6tNQuTTJP0uE4h6h\r
-VAtQ+ux57x052IuOi9FtrqVR
+MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDQwWhcNMzgw\r
+MTAxMTIzNDQwWjApMRQwEgYDVQQKEwtleGFtcGxlLm5ldDERMA8GA1UEAxMIY2xp\r
+Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOY7eAp9lkZsBxaHMAn5\r
+1zK898gr+Yxq+Vxgi6sXXmhsq20D/qHjVsKakEQtQLdBc3di6kRPURWiHrVqwQ+t\r
+RIpR1pQXqoaPmVf11aCvS3pEUaBreO+LQ3CJImrS887XIrGPDuuYuTaKrChtcMPN\r
+idZRKhwJAajAVJvivdDv6ucHAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw\r
+DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBABVCocYnR8xCX0k6HVaW\r
+RX+SAucii+m4sX6TJ/yWjNvQjKxrs3gwe19yOJB0WCOQKqU2s7UhxovW39qD4q60\r
+dSKq+qjW/4DfLmi1d/5aMqAq9au/s7W9Ut/jqqdL5eY31lxWRyW+D+29mfRyl+B7\r
+H0+wMSKs4DNtTYYEd+3W8kEw
-----END CERTIFICATE-----
Bag Attributes
friendlyName: OCSP Signer
- localKeyID: EB 2F EB 2A 88 BA 65 6E B7 DF 67 0B D9 87 99 E4 7A C3 D7 FA
+ localKeyID: 2B 71 28 34 32 0D 11 38 D4 58 56 6F 6F C3 61 5D 81 FE A0 3D
Key Attributes: <No Attributes>
-----BEGIN PRIVATE KEY-----
-MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMQaJ47PbQGWMcH3
-JT2ec4ZEeNrDzreTs0wjeQ8B12FJ8t+xuPYbeYOLU4rchEPA/spnSQY8TrMBFSNy
-bGuyrxUmqvolZt3RASK7olbOgUiQ6yFKdhu0dghS1Fonhi2a+iJN/AKH6FWla9o6
-G6XaoijCmaNK+0crLOOCUGw5SznJAgMBAAECgYBnhbseS+gqr0RDNholxlEML3dx
-XW7yQHmllxBgWMN/q48YgfS3j1d9lv6aTsFQF0EqTo4hSZLuMoMbPFt6G1ELNsYE
-jAmMALYLGhDNHH/h0B76qXviQIBLL0nOi88gKN9tpwvvHtJg3bFu02LGzkiydB2K
-/uNE1Xr0oaomFBR3EQJBAPZd4j390E+bu/hvz8LEb/qxcxUTQKncIqpcGXwr4mYz
-vQI8s5sdUwrk6y9dKVGI6Q8FSffyFX0b7c4HeNr/v2UCQQDLxSAd8aHVaNYOriRb
-T9HYioG2RhS7e1jRwkkjH4rGb9jwXeDHLX/n7k7hpnlFnJHHKJbiiDzmQImjN0o8
-kkSVAkEAkqhetrJyIAHACutcjT/svRqHPGOCmdsek7VRwnZJRrfD6yIBdPQm7BRL
-4J0frJbIzhVC7COjIR/QF1ahXhTidQJAYxHRHp3XF8HjqLmD1Z1GIiidDfiepdQ/
-h6QVGO2B9B52885AtbXqZOHZGh5tAaowugqC6VpheXTRNjhwcGiQzQJBAJLOlkmD
-KhKvuSwWaWq5OkPR0qR9u95/Jp09J6oLcxkvCPx7L38fbDKe6Fd9wvI06rCd7FoK
-mbVOWS+NUGd9VR4=
+MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOPOTJdnNPKc329E
+q6lLuWoT3Ti9dIx1ip/yvv5gC9FV2mdtmH3zmf1lHiX79FKcGzn32hhtNvOh0JOx
+nw91UuEuD9SZ2MYz0OkzmmUBneDvYnGBsBo/nGcI0oeeZp57ysUR1IlT20MVgTFP
+ghHTUY28IsdZpMkrUA2XDUUkRaQzAgMBAAECgYAEHLI3PW6wPnKuEIBEwxAqwQcK
+Qik7a9e/wWL/Nn6gHbueiFTrWR1bfJrJtr2XTCgVqMqwDDCkvzQDpn4nikefrjtt
+P9S8+iw5O1buwWOsgNPRz7w8CH5RNbA/+kG+e+782CWiDywJQRtqVZaQYmvs8xts
+CyRD9+1ZxhwWYANtYQJBAPgxWKpar5XDuTrYXm76mvjWFtALZeaBniuEWhIwCr2o
+6/X5B3DGx57rVa1EXHkkku1V4kfjPHKd1I/NWTPxkVECQQDq+MfV9cxpbFC+FAU0
+aU02UOw12mvpzLqUtlaNycjUiR5TzS4uzIupgrgkwGtYz2o/B/BqoRDmSYzkORu9
+u9xDAkEAgWdpLVkfF1z3JOFPS1nKl1c4ibyHosmOKG5XcAgwcXazoIn5ASoDRq64
++yAbfuY83RXcZ1LpX3E/NMMCcXzQIQJBANrfqI4mayWcjs2wKnT6zcCVuqIjdrgP
+S5GxE4j5+If5vfVDwAw53rKkoFEjqBrPAmH6TDmXFP3eb0474Bppvq8CQQDgaaZa
+58xBhjvmhvud/GeYPfv8n14Sivd3t9Jb5lPq//y7vosU8lLs2MKoLre/UnTZjLJ4
+xSQEj2cy8J/4YxxQ
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
-MIICBTCCAW6gAwIBAgIBAzANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt\r
+MIICBTCCAW6gAwIBAgIBAzANBgkqhkiG9w0BAQsFADAzMRQwEgYDVQQKEwtleGFt\r
cGxlLm5ldDEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy\r
-MzQxMloXDTM4MDEwMTEyMzQxMlowMjEUMBIGA1UEChMLZXhhbXBsZS5uZXQxGjAY\r
+MzQ0MFoXDTM4MDEwMTEyMzQ0MFowMjEUMBIGA1UEChMLZXhhbXBsZS5uZXQxGjAY\r
BgNVBAMTEWNsaWNhIE9DU1AgU2lnbmVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB\r
-iQKBgQDEGieOz20BljHB9yU9nnOGRHjaw863k7NMI3kPAddhSfLfsbj2G3mDi1OK\r
-3IRDwP7KZ0kGPE6zARUjcmxrsq8VJqr6JWbd0QEiu6JWzoFIkOshSnYbtHYIUtRa\r
-J4YtmvoiTfwCh+hVpWvaOhul2qIowpmjSvtHKyzjglBsOUs5yQIDAQABoyowKDAO\r
+iQKBgQDjzkyXZzTynN9vRKupS7lqE904vXSMdYqf8r7+YAvRVdpnbZh985n9ZR4l\r
++/RSnBs599oYbTbzodCTsZ8PdVLhLg/UmdjGM9DpM5plAZ3g72JxgbAaP5xnCNKH\r
+nmaee8rFEdSJU9tDFYExT4IR01GNvCLHWaTJK1ANlw1FJEWkMwIDAQABoyowKDAO\r
BgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwkwDQYJKoZIhvcN\r
-AQEFBQADgYEAZbAMzBc7Vaf2dW5zVH6/ImlnZe3qwZ2r/vb5nJlpF/Zc3AN13rrY\r
-+7h7uvcG+wcwyteU0OmFs7cTWRRyjoJmmLMp4bYBjOliRKAjFgEYT9e1FmoxjmP3\r
-1XbEu2eUgEVUp+dBM7orlNcHYXs62GYQiVyA2WPCWoMahhIqEK4IBqw=
+AQELBQADgYEABM8q56l/p1RDO9Gt5bhGazmwONqNCFh9fJWAJ1XIHo8pU4KaZJEi\r
+xs48FrHDyZRbx1GOiYtOhADffyZdbIt05/eG4eVNgR7ZdViC5vcuc0zFMThLj4kZ\r
+ho1F42EKuNoc7merGpA6DL18BFClKvy4NwnCzXZkyQFfCN8hPq61mGA=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDExWhcNMzgw\r
-MTAxMTIzNDExWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp\r
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCf/Mo\r
-cl7+ta84A85TdEcSPfv+JV6/0ynu98Z+EHaz221TGgNYkOtlBDc80kZZ2QBndE6e\r
-RZAuIaPgTVk0mZJ7XUxAVx7AAlGSWenScV/k/VChgqddRaCmmLQoPT/wUkrDqlOW\r
-7omdM0BTaMxdEv2QRyUCVrrZKOJkRsTILkUvaQIDAQABo1owWDAOBgNVHQ8BAf8E\r
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDQwWhcNMzgw\r
+MTAxMTIzNDQwWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp\r
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXxUua\r
+JOUjKYqtSZyRwCoF1o5VI5yr+sinPkKPpGQnFd28bani9yCcLdvvOVCBPBmBe3vJ\r
+sjRSu5YO3fGlE7dRbiUBCvmOtZ4Kk39mgQcThWp8R8Mxk//ex5BSLlw3q43BY3Om\r
++V59fPWaYgHKE/RIjneGJb97oa3AmxjvZcZXnQIDAQABo1owWDAOBgNVHQ8BAf8E\r
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw\r
-Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA\r
-P/kvw/kOJI5Yja+W8/xmbAma4NeAWE48eLDzp6AWJBUU7oIj4Ca+PqwpaxxeNioZ\r
-ihLL5LCRrS8lsSGgyD3UzqYGCMOwqX5pBytpWXz1NRzzey9mCV55LHckBF7dRBuh\r
-XQiz+EvE4Dr1ZikrB6UjgHW7Bal9Y5QMDs8qZAsRkJ0=
+Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA\r
+rPmUtgNXl5WO6GDheUimkO9DGTeKnk8n/Hwlm6KjqYfkaJuf1YTKD2bgqfsW4TQM\r
+uN/wZurB9sbZTdrPqqD+pS8xV8CloldkH4x3PtUz+0Z4Fkgf4IQG1GKI/OGu2Ego\r
+6UjWNb+M5nNokpzyV7bAslmTj6Q7CCVQuNSKGfOIJEc=
-----END CERTIFICATE-----
; Config::Simple 4.59
-; Thu Nov 1 12:34:11 2012
+; Thu Nov 1 12:34:40 2012
[CLICA]
-crl_url=http://crl.example.net/latest.crl
-crl_signer=Signing Cert
+sighash=SHA256
level=1
-signer=Signing Cert
-ocsp_signer=OCSP Signer
+crl_signer=Signing Cert
+crl_url=http://crl.example.net/latest.crl
ocsp_url=http://oscp/example.net/
+ocsp_signer=OCSP Signer
+signer=Signing Cert
[CA]
org=example.net
-update=20140422152734Z
+update=20151216164103Z
-----BEGIN X509 CRL-----
-MIHtMFgCAQEwDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhhbXBsZS5uZXQx
-GzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydBgPMjAxNDA0MjIxNTI3MzRaMA0G
-CSqGSIb3DQEBBQUAA4GBAFoXyOzTFY7uLHW/UjKfxOP4NP9S+4PF4nHz4fvn0tcC
-3A7VE3ucmoNFWyxpkp4cSPYNGUJctBoJhS5t3WRvYd7ZweKKDO0/qsI8AQcfzY0n
-YBu/pjphxfs6dHnXFcRdhaP7nz/eoArkWGXn1UlsneJQXnBK/ZSsld472GPL5XaM
+MIHtMFgCAQEwDQYJKoZIhvcNAQELBQAwMzEUMBIGA1UEChMLZXhhbXBsZS5uZXQx
+GzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydBgPMjAxNTEyMTYxNjQxMDNaMA0G
+CSqGSIb3DQEBCwUAA4GBABn5NY9lZHLZdatvwWpzfTv7o+l+z0eLlipis3sXx3Uu
+UocsNbNB75eqKqQVOxqVzYLoDStvvef04jHnJYK28BfbpPa9cY7hwKrQxOXu/4eo
+m0JrVyoJMKXDgOEVvAMPgB6E0u9tdAt0+O0WqHkQcrNlvp0aFFYAumMD5/gFok9v
-----END X509 CRL-----
-update=20140422152736Z
-addcert 102 20140422152736Z
-addcert 202 20140422152736Z
+update=20151216164105Z
+addcert 102 20151216164105Z
+addcert 202 20151216164105Z
-----BEGIN X509 CRL-----
-MIIBHTCBhwIBATANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFtcGxlLm5l
-dDEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0GA8yMDE0MDQyMjE1MjczNlow
-LTAUAgFmGA8yMDE0MDQyMjE1MjczNlowFQICAMoYDzIwMTQwNDIyMTUyNzM2WjAN
-BgkqhkiG9w0BAQUFAAOBgQCCvMQ1eAkuztnM/mIUCWFRyRZuqVyf/gnCISf3Ha5w
-nOBMSJLn6vr2WYaTqe3vENqHYupQi5T2mK6B1JS/i3PGx2N+lCPAwTr/j08HAKwv
-WICtPYMdjx+HuoXRbGO4V/Q9YeaEucde0Ldk99P2bMRn2msGPdpoXlWuLUX9aneA
-Tg==
+MIIBHTCBhwIBATANBgkqhkiG9w0BAQsFADAzMRQwEgYDVQQKEwtleGFtcGxlLm5l
+dDEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0GA8yMDE1MTIxNjE2NDEwNVow
+LTAUAgFmGA8yMDE1MTIxNjE2NDEwNVowFQICAMoYDzIwMTUxMjE2MTY0MTA1WjAN
+BgkqhkiG9w0BAQsFAAOBgQAox2QRHKCtfgtt50f0G5B4NWFJUXWveolrZ1HPBgCL
+dm+y4WGB6BHzAcByRrmF4HRnIipmvyH2ntZfetUAtmwAPGZR7SXOwdEZ5Vk7dHxi
+k239UDkHrkAWyVryaVllZ8SCu45xBGYFSrNUPPQuGKAQH0uZgf9BcjsfXHYobPKe
+QQ==
-----END X509 CRL-----
processor : 0
vendor_id : GenuineIntel
cpu family : 6
-model : 13
-model name : QEMU Virtual CPU version (cpu64-rhel6)
-stepping : 3
-cpu MHz : 1994.999
+model : 58
+model name : Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
+stepping : 9
+microcode : 0x1b
+cpu MHz : 3399.910
cache size : 4096 KB
+physical id : 0
+siblings : 4
+core id : 0
+cpu cores : 2
+apicid : 0
+initial apicid : 0
fpu : yes
fpu_exception : yes
-cpuid level : 4
+cpuid level : 13
wp : yes
-flags : fpu de pse tsc msr pae mce cx8 apic mtrr pge mca cmov pse36 clflush mmx fxsr sse sse2 syscall nx lm up unfair_spinlock pni cx16 hypervisor lahf_lm
-bogomips : 3989.99
+flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm ida arat epb pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt
+bugs :
+bogomips : 5786.61
clflush size : 64
cache_alignment : 64
-address sizes : 38 bits physical, 48 bits virtual
+address sizes : 36 bits physical, 48 bits virtual
power management:
- CPU0
- 0: 258 IO-APIC-edge timer
- 1: 6 IO-APIC-edge i8042
- 4: 1 IO-APIC-edge
- 8: 0 IO-APIC-edge rtc0
- 9: 0 IO-APIC-fasteoi acpi
- 10: 953 IO-APIC-fasteoi virtio3
- 11: 62 IO-APIC-fasteoi uhci_hcd:usb1, snd_hda_intel
- 12: 104 IO-APIC-edge i8042
- 14: 0 IO-APIC-edge ata_piix
- 15: 106 IO-APIC-edge ata_piix
- 24: 0 PCI-MSI-edge virtio2-config
- 25: 49006 PCI-MSI-edge virtio2-requests
- 26: 0 PCI-MSI-edge virtio0-config
- 27: 296912 PCI-MSI-edge virtio0-input
- 28: 1 PCI-MSI-edge virtio0-output
- 29: 0 PCI-MSI-edge virtio1-config
- 30: 18868 PCI-MSI-edge virtio1-input
- 31: 1 PCI-MSI-edge virtio1-output
-NMI: 0 Non-maskable interrupts
-LOC: 778283 Local timer interrupts
-SPU: 0 Spurious interrupts
-PMI: 0 Performance monitoring interrupts
-IWI: 0 IRQ work interrupts
-RES: 0 Rescheduling interrupts
-CAL: 0 Function call interrupts
-TLB: 0 TLB shootdowns
-TRM: 0 Thermal event interrupts
-THR: 0 Threshold APIC interrupts
-MCE: 0 Machine check exceptions
-MCP: 271 Machine check polls
+processor : 1
+vendor_id : GenuineIntel
+cpu family : 6
+model : 58
+model name : Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
+stepping : 9
+microcode : 0x1b
+cpu MHz : 3399.910
+cache size : 4096 KB
+physical id : 0
+siblings : 4
+core id : 0
+cpu cores : 2
+apicid : 1
+initial apicid : 1
+fpu : yes
+fpu_exception : yes
+cpuid level : 13
+wp : yes
+flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm ida arat epb pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt
+bugs :
+bogomips : 5786.61
+clflush size : 64
+cache_alignment : 64
+address sizes : 36 bits physical, 48 bits virtual
+power management:
+
+processor : 2
+vendor_id : GenuineIntel
+cpu family : 6
+model : 58
+model name : Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
+stepping : 9
+microcode : 0x1b
+cpu MHz : 3195.664
+cache size : 4096 KB
+physical id : 0
+siblings : 4
+core id : 1
+cpu cores : 2
+apicid : 2
+initial apicid : 2
+fpu : yes
+fpu_exception : yes
+cpuid level : 13
+wp : yes
+flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm ida arat epb pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt
+bugs :
+bogomips : 5786.61
+clflush size : 64
+cache_alignment : 64
+address sizes : 36 bits physical, 48 bits virtual
+power management:
+
+processor : 3
+vendor_id : GenuineIntel
+cpu family : 6
+model : 58
+model name : Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
+stepping : 9
+microcode : 0x1b
+cpu MHz : 3399.910
+cache size : 4096 KB
+physical id : 0
+siblings : 4
+core id : 1
+cpu cores : 2
+apicid : 3
+initial apicid : 3
+fpu : yes
+fpu_exception : yes
+cpuid level : 13
+wp : yes
+flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm ida arat epb pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt
+bugs :
+bogomips : 5786.61
+clflush size : 64
+cache_alignment : 64
+address sizes : 36 bits physical, 48 bits virtual
+power management:
+
+ CPU0 CPU1 CPU2 CPU3
+ 0: 68 0 0 0 IO-APIC 2-edge timer
+ 1: 689 7853 658 778 IO-APIC 1-edge i8042
+ 8: 0 0 1 0 IO-APIC 8-edge rtc0
+ 9: 1160 695 344 261 IO-APIC 9-fasteoi acpi
+ 12: 314976 1327914 163447 143732 IO-APIC 12-edge i8042
+ 16: 332 194 163 132 IO-APIC 16-fasteoi ehci_hcd:usb3, mmc0
+ 18: 0 0 0 0 IO-APIC 18-fasteoi i801_smbus
+ 23: 17 31 0 0 IO-APIC 23-fasteoi ehci_hcd:usb4
+ 24: 44762 5748 786804 3298 PCI-MSI 512000-edge 0000:00:1f.2
+ 25: 0 0 0 0 PCI-MSI 327680-edge xhci_hcd
+ 26: 3 6 1 1 PCI-MSI 409600-edge enp0s25
+ 27: 852 591 64 42 PCI-MSI 32768-edge i915
+ 28: 8 6 3 6 PCI-MSI 360448-edge mei_me
+ 29: 62 82 0 6 PCI-MSI 442368-edge snd_hda_intel
+ 30: 779603 1591 37 80 PCI-MSI 1572864-edge iwlwifi
+NMI: 94 87 91 87 Non-maskable interrupts
+LOC: 2717165 2177070 2758401 2241707 Local timer interrupts
+SPU: 0 0 0 0 Spurious interrupts
+PMI: 94 87 91 87 Performance monitoring interrupts
+IWI: 0 38 3 4 IRQ work interrupts
+RTR: 0 0 0 0 APIC ICR read retries
+RES: 181926 181930 174985 218174 Rescheduling interrupts
+CAL: 155928 95381 153320 90535 Function call interrupts
+TLB: 19955 22444 21487 20786 TLB shootdowns
+TRM: 0 0 0 0 Thermal event interrupts
+THR: 0 0 0 0 Threshold APIC interrupts
+DFR: 0 0 0 0 Deferred Error APIC interrupts
+MCE: 0 0 0 0 Machine check exceptions
+MCP: 29 29 29 29 Machine check polls
+HYP: 0 0 0 0 Hypervisor callback interrupts
ERR: 0
MIS: 0
-MemTotal: 487904 kB
-MemFree: 72616 kB
-Buffers: 73820 kB
-Cached: 142556 kB
-SwapCached: 0 kB
-Active: 133212 kB
-Inactive: 119168 kB
-Active(anon): 15164 kB
-Inactive(anon): 21900 kB
-Active(file): 118048 kB
-Inactive(file): 97268 kB
-Unevictable: 0 kB
-Mlocked: 0 kB
-SwapTotal: 524280 kB
-SwapFree: 524280 kB
-Dirty: 2456 kB
+PIN: 0 0 0 0 Posted-interrupt notification event
+PIW: 0 0 0 0 Posted-interrupt wakeup event
+MemTotal: 16127228 kB
+MemFree: 11172348 kB
+MemAvailable: 11360848 kB
+Buffers: 16824 kB
+Cached: 258036 kB
+SwapCached: 1969000 kB
+Active: 2299052 kB
+Inactive: 2277200 kB
+Active(anon): 2261212 kB
+Inactive(anon): 2129652 kB
+Active(file): 37840 kB
+Inactive(file): 147548 kB
+Unevictable: 22232 kB
+Mlocked: 22232 kB
+SwapTotal: 7286780 kB
+SwapFree: 619792 kB
+Dirty: 5712 kB
Writeback: 0 kB
-AnonPages: 35924 kB
-Mapped: 15592 kB
-Shmem: 1128 kB
-Slab: 136348 kB
-SReclaimable: 83960 kB
-SUnreclaim: 52388 kB
-KernelStack: 752 kB
-PageTables: 3420 kB
+AnonPages: 2355600 kB
+Mapped: 161840 kB
+Shmem: 79820 kB
+Slab: 122648 kB
+SReclaimable: 63112 kB
+SUnreclaim: 59536 kB
+KernelStack: 12384 kB
+PageTables: 60456 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
-CommitLimit: 768232 kB
-Committed_AS: 116976 kB
+CommitLimit: 15350392 kB
+Committed_AS: 22203576 kB
VmallocTotal: 34359738367 kB
-VmallocUsed: 12116 kB
-VmallocChunk: 34359713232 kB
+VmallocUsed: 457088 kB
+VmallocChunk: 34358947836 kB
HardwareCorrupted: 0 kB
-AnonHugePages: 2048 kB
+AnonHugePages: 1890304 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
-DirectMap4k: 7156 kB
-DirectMap2M: 1492992 kB
-slabinfo - version: 2.1
-# name <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>
-nf_conntrack_expect 0 0 240 16 1 : tunables 120 60 0 : slabdata 0 0 0
-nf_conntrack_ffffffff81b18540 35 36 312 12 1 : tunables 54 27 0 : slabdata 3 3 0
-fib6_nodes 59 59 64 59 1 : tunables 120 60 0 : slabdata 1 1 0
-ip6_dst_cache 40 40 384 10 1 : tunables 54 27 0 : slabdata 4 4 0
-ndisc_cache 20 30 256 15 1 : tunables 120 60 0 : slabdata 2 2 0
-ip6_mrt_cache 0 0 128 30 1 : tunables 120 60 0 : slabdata 0 0 0
-RAWv6 4 4 1024 4 1 : tunables 54 27 0 : slabdata 1 1 0
-UDPLITEv6 0 0 1024 4 1 : tunables 54 27 0 : slabdata 0 0 0
-UDPv6 0 0 1024 4 1 : tunables 54 27 0 : slabdata 0 0 0
-tw_sock_TCPv6 0 0 320 12 1 : tunables 54 27 0 : slabdata 0 0 0
-request_sock_TCPv6 0 0 192 20 1 : tunables 120 60 0 : slabdata 0 0 0
-TCPv6 9 10 1920 2 1 : tunables 24 12 0 : slabdata 5 5 0
-jbd2_1k 0 0 1024 4 1 : tunables 54 27 0 : slabdata 0 0 0
-avtab_node 551039 551088 24 144 1 : tunables 120 60 0 : slabdata 3827 3827 0
-ext4_inode_cache 36254 36888 1016 4 1 : tunables 54 27 0 : slabdata 9222 9222 0
-ext4_xattr 5 44 88 44 1 : tunables 120 60 0 : slabdata 1 1 0
-ext4_free_block_extents 16 67 56 67 1 : tunables 120 60 0 : slabdata 1 1 0
-ext4_alloc_context 16 28 136 28 1 : tunables 120 60 0 : slabdata 1 1 0
-ext4_prealloc_space 11 37 104 37 1 : tunables 120 60 0 : slabdata 1 1 0
-ext4_system_zone 0 0 40 92 1 : tunables 120 60 0 : slabdata 0 0 0
-jbd2_journal_handle 16 144 24 144 1 : tunables 120 60 0 : slabdata 1 1 0
-jbd2_journal_head 102 102 112 34 1 : tunables 120 60 0 : slabdata 3 3 0
-jbd2_revoke_table 4 202 16 202 1 : tunables 120 60 0 : slabdata 1 1 0
-jbd2_revoke_record 0 0 32 112 1 : tunables 120 60 0 : slabdata 0 0 0
-scsi_sense_cache 2 30 128 30 1 : tunables 120 60 0 : slabdata 1 1 0
-scsi_cmd_cache 2 15 256 15 1 : tunables 120 60 0 : slabdata 1 1 0
-dm_raid1_read_record 0 0 1064 7 2 : tunables 24 12 0 : slabdata 0 0 0
-kcopyd_job 0 0 3240 2 2 : tunables 24 12 0 : slabdata 0 0 0
-io 0 0 64 59 1 : tunables 120 60 0 : slabdata 0 0 0
-dm_uevent 0 0 2608 3 2 : tunables 24 12 0 : slabdata 0 0 0
-dm_rq_clone_bio_info 0 0 16 202 1 : tunables 120 60 0 : slabdata 0 0 0
-dm_rq_target_io 0 0 392 10 1 : tunables 54 27 0 : slabdata 0 0 0
-dm_target_io 576 576 24 144 1 : tunables 120 60 0 : slabdata 4 4 0
-dm_io 552 552 40 92 1 : tunables 120 60 0 : slabdata 6 6 0
-flow_cache 0 0 104 37 1 : tunables 120 60 0 : slabdata 0 0 0
-uhci_urb_priv 0 0 56 67 1 : tunables 120 60 0 : slabdata 0 0 0
-cfq_io_context 0 0 136 28 1 : tunables 120 60 0 : slabdata 0 0 0
-cfq_queue 0 0 240 16 1 : tunables 120 60 0 : slabdata 0 0 0
-bsg_cmd 0 0 312 12 1 : tunables 54 27 0 : slabdata 0 0 0
-mqueue_inode_cache 1 4 896 4 1 : tunables 54 27 0 : slabdata 1 1 0
-isofs_inode_cache 0 0 640 6 1 : tunables 54 27 0 : slabdata 0 0 0
-hugetlbfs_inode_cache 1 6 608 6 1 : tunables 54 27 0 : slabdata 1 1 0
-dquot 0 0 256 15 1 : tunables 120 60 0 : slabdata 0 0 0
-kioctx 0 0 384 10 1 : tunables 54 27 0 : slabdata 0 0 0
-kiocb 0 0 256 15 1 : tunables 120 60 0 : slabdata 0 0 0
-inotify_event_private_data 0 0 32 112 1 : tunables 120 60 0 : slabdata 0 0 0
-inotify_inode_mark_entry 110 136 112 34 1 : tunables 120 60 0 : slabdata 4 4 0
-dnotify_mark_entry 0 0 112 34 1 : tunables 120 60 0 : slabdata 0 0 0
-dnotify_struct 0 0 32 112 1 : tunables 120 60 0 : slabdata 0 0 0
-dio 0 0 640 6 1 : tunables 54 27 0 : slabdata 0 0 0
-fasync_cache 0 0 24 144 1 : tunables 120 60 0 : slabdata 0 0 0
-khugepaged_mm_slot 17 92 40 92 1 : tunables 120 60 0 : slabdata 1 1 0
-ksm_mm_slot 0 0 48 77 1 : tunables 120 60 0 : slabdata 0 0 0
-ksm_stable_node 0 0 48 77 1 : tunables 120 60 0 : slabdata 0 0 0
-ksm_rmap_item 0 0 64 59 1 : tunables 120 60 0 : slabdata 0 0 0
-utrace_engine 0 0 56 67 1 : tunables 120 60 0 : slabdata 0 0 0
-utrace 0 0 64 59 1 : tunables 120 60 0 : slabdata 0 0 0
-pid_namespace 0 0 2168 3 2 : tunables 24 12 0 : slabdata 0 0 0
-posix_timers_cache 0 0 176 22 1 : tunables 120 60 0 : slabdata 0 0 0
-uid_cache 3 30 128 30 1 : tunables 120 60 0 : slabdata 1 1 0
-UNIX 107 110 768 5 1 : tunables 54 27 0 : slabdata 22 22 0
-ip_mrt_cache 0 0 128 30 1 : tunables 120 60 0 : slabdata 0 0 0
-UDP-Lite 0 0 832 9 2 : tunables 54 27 0 : slabdata 0 0 0
-tcp_bind_bucket 9 59 64 59 1 : tunables 120 60 0 : slabdata 1 1 0
-inet_peer_cache 2 59 64 59 1 : tunables 120 60 0 : slabdata 1 1 0
-secpath_cache 0 0 64 59 1 : tunables 120 60 0 : slabdata 0 0 0
-xfrm_dst_cache 0 0 448 8 1 : tunables 54 27 0 : slabdata 0 0 0
-ip_fib_alias 1 112 32 112 1 : tunables 120 60 0 : slabdata 1 1 0
-ip_fib_hash 14 53 72 53 1 : tunables 120 60 0 : slabdata 1 1 0
-ip_dst_cache 26 30 384 10 1 : tunables 54 27 0 : slabdata 3 3 0
-arp_cache 6 15 256 15 1 : tunables 120 60 0 : slabdata 1 1 0
-PING 0 0 832 9 2 : tunables 54 27 0 : slabdata 0 0 0
-RAW 2 9 832 9 2 : tunables 54 27 0 : slabdata 1 1 0
-UDP 1 9 832 9 2 : tunables 54 27 0 : slabdata 1 1 0
-tw_sock_TCP 0 0 256 15 1 : tunables 120 60 0 : slabdata 0 0 0
-request_sock_TCP 0 0 128 30 1 : tunables 120 60 0 : slabdata 0 0 0
-TCP 10 12 1728 4 2 : tunables 24 12 0 : slabdata 3 3 0
-eventpoll_pwq 59 106 72 53 1 : tunables 120 60 0 : slabdata 2 2 0
-eventpoll_epi 59 90 128 30 1 : tunables 120 60 0 : slabdata 3 3 0
-sgpool-128 2 2 4096 1 1 : tunables 24 12 0 : slabdata 2 2 0
-sgpool-64 2 2 2048 2 1 : tunables 24 12 0 : slabdata 1 1 0
-sgpool-32 2 4 1024 4 1 : tunables 54 27 0 : slabdata 1 1 0
-sgpool-16 2 8 512 8 1 : tunables 54 27 0 : slabdata 1 1 0
-sgpool-8 2 15 256 15 1 : tunables 120 60 0 : slabdata 1 1 0
-scsi_data_buffer 0 0 24 144 1 : tunables 120 60 0 : slabdata 0 0 0
-blkdev_integrity 0 0 112 34 1 : tunables 120 60 0 : slabdata 0 0 0
-blkdev_queue 28 28 2864 2 2 : tunables 24 12 0 : slabdata 14 14 0
-blkdev_requests 22 22 352 11 1 : tunables 54 27 0 : slabdata 2 2 0
-blkdev_ioc 3 48 80 48 1 : tunables 120 60 0 : slabdata 1 1 0
-fsnotify_event_holder 0 0 24 144 1 : tunables 120 60 0 : slabdata 0 0 0
-fsnotify_event 0 0 104 37 1 : tunables 120 60 0 : slabdata 0 0 0
-bio-0 120 120 192 20 1 : tunables 120 60 0 : slabdata 6 6 0
-biovec-256 34 34 4096 1 1 : tunables 24 12 0 : slabdata 34 34 0
-biovec-128 0 0 2048 2 1 : tunables 24 12 0 : slabdata 0 0 0
-biovec-64 0 0 1024 4 1 : tunables 54 27 0 : slabdata 0 0 0
-biovec-16 1 15 256 15 1 : tunables 120 60 0 : slabdata 1 1 0
-bip-256 2 2 4224 1 2 : tunables 8 4 0 : slabdata 2 2 0
-bip-128 0 0 2176 3 2 : tunables 24 12 0 : slabdata 0 0 0
-bip-64 0 0 1152 7 2 : tunables 24 12 0 : slabdata 0 0 0
-bip-16 0 0 384 10 1 : tunables 54 27 0 : slabdata 0 0 0
-bip-4 0 0 192 20 1 : tunables 120 60 0 : slabdata 0 0 0
-bip-1 0 0 128 30 1 : tunables 120 60 0 : slabdata 0 0 0
-sock_inode_cache 150 160 704 5 1 : tunables 54 27 0 : slabdata 32 32 0
-skbuff_fclone_cache 7 7 512 7 1 : tunables 54 27 0 : slabdata 1 1 0
-skbuff_head_cache 66 105 256 15 1 : tunables 120 60 0 : slabdata 7 7 0
-file_lock_cache 21 22 176 22 1 : tunables 120 60 0 : slabdata 1 1 0
-net_namespace 0 0 2432 3 2 : tunables 24 12 0 : slabdata 0 0 0
-shmem_inode_cache 654 655 784 5 1 : tunables 54 27 0 : slabdata 131 131 0
-Acpi-Operand 1211 1219 72 53 1 : tunables 120 60 0 : slabdata 23 23 0
-Acpi-ParseExt 0 0 72 53 1 : tunables 120 60 0 : slabdata 0 0 0
-Acpi-Parse 0 0 48 77 1 : tunables 120 60 0 : slabdata 0 0 0
-Acpi-State 0 0 80 48 1 : tunables 120 60 0 : slabdata 0 0 0
-Acpi-Namespace 407 460 40 92 1 : tunables 120 60 0 : slabdata 5 5 0
-task_delay_info 102 102 112 34 1 : tunables 120 60 0 : slabdata 3 3 0
-taskstats 0 0 328 12 1 : tunables 54 27 0 : slabdata 0 0 0
-proc_inode_cache 408 408 656 6 1 : tunables 54 27 0 : slabdata 68 68 0
-sigqueue 9 24 160 24 1 : tunables 120 60 0 : slabdata 1 1 0
-bdev_cache 31 32 832 4 1 : tunables 54 27 0 : slabdata 8 8 0
-sysfs_dir_cache 7588 7614 144 27 1 : tunables 120 60 0 : slabdata 282 282 0
-mnt_cache 27 30 256 15 1 : tunables 120 60 0 : slabdata 2 2 0
-filp 840 840 192 20 1 : tunables 120 60 0 : slabdata 42 42 0
-inode_cache 5826 5826 592 6 1 : tunables 54 27 0 : slabdata 971 971 0
-dentry 189540 189540 192 20 1 : tunables 120 60 0 : slabdata 9477 9477 0
-names_cache 1 1 4096 1 1 : tunables 24 12 0 : slabdata 1 1 0
-avc_node 572 708 64 59 1 : tunables 120 60 0 : slabdata 12 12 0
-selinux_inode_security 43319 46799 72 53 1 : tunables 120 60 0 : slabdata 883 883 0
-radix_tree_node 3018 3598 560 7 1 : tunables 54 27 0 : slabdata 514 514 0
-key_jar 5 20 192 20 1 : tunables 120 60 0 : slabdata 1 1 0
-buffer_head 24452 25493 104 37 1 : tunables 120 60 0 : slabdata 689 689 0
-nsproxy 0 0 48 77 1 : tunables 120 60 0 : slabdata 0 0 0
-vm_area_struct 2565 2565 200 19 1 : tunables 120 60 0 : slabdata 135 135 0
-mm_struct 40 40 1408 5 2 : tunables 24 12 0 : slabdata 8 8 0
-fs_cache 59 59 64 59 1 : tunables 120 60 0 : slabdata 1 1 0
-files_cache 44 44 704 11 2 : tunables 54 27 0 : slabdata 4 4 0
-signal_cache 91 91 1088 7 2 : tunables 24 12 0 : slabdata 13 13 0
-sighand_cache 90 90 2112 3 2 : tunables 24 12 0 : slabdata 30 30 0
-task_xstate 48 48 512 8 1 : tunables 54 27 0 : slabdata 6 6 0
-task_struct 96 96 2656 3 2 : tunables 24 12 0 : slabdata 32 32 0
-cred_jar 240 240 192 20 1 : tunables 120 60 0 : slabdata 12 12 0
-anon_vma_chain 1795 2079 48 77 1 : tunables 120 60 0 : slabdata 27 27 0
-anon_vma 1209 1380 40 92 1 : tunables 120 60 0 : slabdata 15 15 0
-pid 107 120 128 30 1 : tunables 120 60 0 : slabdata 4 4 0
-shared_policy_node 0 0 48 77 1 : tunables 120 60 0 : slabdata 0 0 0
-numa_policy 0 0 136 28 1 : tunables 120 60 0 : slabdata 0 0 0
-idr_layer_cache 281 287 544 7 1 : tunables 54 27 0 : slabdata 41 41 0
-size-4194304(DMA) 0 0 4194304 1 1024 : tunables 1 1 0 : slabdata 0 0 0
-size-4194304 0 0 4194304 1 1024 : tunables 1 1 0 : slabdata 0 0 0
-size-2097152(DMA) 0 0 2097152 1 512 : tunables 1 1 0 : slabdata 0 0 0
-size-2097152 0 0 2097152 1 512 : tunables 1 1 0 : slabdata 0 0 0
-size-1048576(DMA) 0 0 1048576 1 256 : tunables 1 1 0 : slabdata 0 0 0
-size-1048576 0 0 1048576 1 256 : tunables 1 1 0 : slabdata 0 0 0
-size-524288(DMA) 0 0 524288 1 128 : tunables 1 1 0 : slabdata 0 0 0
-size-524288 0 0 524288 1 128 : tunables 1 1 0 : slabdata 0 0 0
-size-262144(DMA) 0 0 262144 1 64 : tunables 1 1 0 : slabdata 0 0 0
-size-262144 0 0 262144 1 64 : tunables 1 1 0 : slabdata 0 0 0
-size-131072(DMA) 0 0 131072 1 32 : tunables 8 4 0 : slabdata 0 0 0
-size-131072 0 0 131072 1 32 : tunables 8 4 0 : slabdata 0 0 0
-size-65536(DMA) 0 0 65536 1 16 : tunables 8 4 0 : slabdata 0 0 0
-size-65536 2 2 65536 1 16 : tunables 8 4 0 : slabdata 2 2 0
-size-32768(DMA) 0 0 32768 1 8 : tunables 8 4 0 : slabdata 0 0 0
-size-32768 3 3 32768 1 8 : tunables 8 4 0 : slabdata 3 3 0
-size-16384(DMA) 0 0 16384 1 4 : tunables 8 4 0 : slabdata 0 0 0
-size-16384 7 7 16384 1 4 : tunables 8 4 0 : slabdata 7 7 0
-size-8192(DMA) 0 0 8192 1 2 : tunables 8 4 0 : slabdata 0 0 0
-size-8192 12 12 8192 1 2 : tunables 8 4 0 : slabdata 12 12 0
-size-4096(DMA) 0 0 4096 1 1 : tunables 24 12 0 : slabdata 0 0 0
-size-4096 119 119 4096 1 1 : tunables 24 12 0 : slabdata 119 119 0
-size-2048(DMA) 0 0 2048 2 1 : tunables 24 12 0 : slabdata 0 0 0
-size-2048 200 200 2048 2 1 : tunables 24 12 0 : slabdata 100 100 0
-size-1024(DMA) 0 0 1024 4 1 : tunables 54 27 0 : slabdata 0 0 0
-size-1024 578 588 1024 4 1 : tunables 54 27 0 : slabdata 147 147 0
-size-512(DMA) 0 0 512 8 1 : tunables 54 27 0 : slabdata 0 0 0
-size-512 608 608 512 8 1 : tunables 54 27 0 : slabdata 76 76 0
-size-256(DMA) 0 0 256 15 1 : tunables 120 60 0 : slabdata 0 0 0
-size-256 815 825 256 15 1 : tunables 120 60 0 : slabdata 55 55 0
-size-192(DMA) 0 0 192 20 1 : tunables 120 60 0 : slabdata 0 0 0
-size-192 1253 1260 192 20 1 : tunables 120 60 0 : slabdata 63 63 0
-size-128(DMA) 0 0 128 30 1 : tunables 120 60 0 : slabdata 0 0 0
-size-64(DMA) 0 0 64 59 1 : tunables 120 60 0 : slabdata 0 0 0
-size-64 23094 25783 64 59 1 : tunables 120 60 0 : slabdata 437 437 0
-size-32(DMA) 0 0 32 112 1 : tunables 120 60 0 : slabdata 0 0 0
-size-128 3271 3450 128 30 1 : tunables 120 60 0 : slabdata 115 115 0
-size-32 352497 352576 32 112 1 : tunables 120 60 0 : slabdata 3148 3148 0
-kmem_cache 183 183 32896 1 16 : tunables 8 4 0 : slabdata 183 183 0
+DirectMap4k: 144572 kB
+DirectMap2M: 16322560 kB
Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
- lo: 5243413 23981 0 0 0 0 0 0 5243413 23981 0 0 0 0 0 0
- eth0:25468831 318944 0 0 0 0 0 0 2048323 16057 0 0 0 0 0 0
- eth1: 1386465 18973 0 0 0 0 0 0 95634 1485 0 0 0 0 0 0
+virbr1-nic: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ vnet0: 128666 393 0 0 0 0 0 0 317193 3976 0 0 0 0 0 0
+ vnet5: 43924 524 0 0 0 0 0 0 221686 3859 0 0 0 0 0 0
+enp0s25: 31338290 49183 0 0 0 0 0 1035 10708826 44319 0 0 0 0 0 0
+virbr0-nic: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ vnet2: 69293 283 0 0 0 0 0 0 364210 3770 0 0 0 0 0 0
+ vnet4: 59178 194 0 0 0 0 0 0 238387 3594 0 0 0 0 0 0
+virbr0: 5345737 5274 0 0 0 0 0 0 1408922 5318 0 0 0 0 0 0
+ vnet1: 5034219 3505 0 0 0 0 0 0 1151113 7193 0 0 0 0 0 0
+ lo: 20864 210 0 0 0 0 0 0 20864 210 0 0 0 0 0 0
+virbr1: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+wlp3s0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ vnet3: 84293 375 0 0 0 0 0 0 279557 3664 0 0 0 0 0 0
subject=/O=example.net/CN=clica Signing Cert
issuer=/O=example.net/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDExWhcNMzgw
-MTAxMTIzNDExWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCf/Mo
-cl7+ta84A85TdEcSPfv+JV6/0ynu98Z+EHaz221TGgNYkOtlBDc80kZZ2QBndE6e
-RZAuIaPgTVk0mZJ7XUxAVx7AAlGSWenScV/k/VChgqddRaCmmLQoPT/wUkrDqlOW
-7omdM0BTaMxdEv2QRyUCVrrZKOJkRsTILkUvaQIDAQABo1owWDAOBgNVHQ8BAf8E
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDQwWhcNMzgw
+MTAxMTIzNDQwWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXxUua
+JOUjKYqtSZyRwCoF1o5VI5yr+sinPkKPpGQnFd28bani9yCcLdvvOVCBPBmBe3vJ
+sjRSu5YO3fGlE7dRbiUBCvmOtZ4Kk39mgQcThWp8R8Mxk//ex5BSLlw3q43BY3Om
++V59fPWaYgHKE/RIjneGJb97oa3AmxjvZcZXnQIDAQABo1owWDAOBgNVHQ8BAf8E
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw
-Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA
-P/kvw/kOJI5Yja+W8/xmbAma4NeAWE48eLDzp6AWJBUU7oIj4Ca+PqwpaxxeNioZ
-ihLL5LCRrS8lsSGgyD3UzqYGCMOwqX5pBytpWXz1NRzzey9mCV55LHckBF7dRBuh
-XQiz+EvE4Dr1ZikrB6UjgHW7Bal9Y5QMDs8qZAsRkJ0=
+Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA
+rPmUtgNXl5WO6GDheUimkO9DGTeKnk8n/Hwlm6KjqYfkaJuf1YTKD2bgqfsW4TQM
+uN/wZurB9sbZTdrPqqD+pS8xV8CloldkH4x3PtUz+0Z4Fkgf4IQG1GKI/OGu2Ego
+6UjWNb+M5nNokpzyV7bAslmTj6Q7CCVQuNSKGfOIJEc=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: Certificate Authority
subject=/O=example.net/CN=clica CA
issuer=/O=example.net/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDExWhcNMzgw
-MTAxMTIzNDExWjApMRQwEgYDVQQKEwtleGFtcGxlLm5ldDERMA8GA1UEAxMIY2xp
-Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALUSMNgU8YE8fsiB8Wm7
-lpclDOwQXJVbP/Ef2NVwoE6NnoPTWMNgvSyCddVz7709URkIy+jtrlpbyQYVdwgO
-HAnI8/bx2WoGtGzWTbAM1Mp+WHtiOO7LpsldWQmeHuF9uBOghFytVyqNT2l/iG7x
-XQCA6Q6P59vpb3Z+4PH8kgVlAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
-DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBACs6X9bwml5hcwf82pyb
-bKOnRGP6pJsvx1yv6SULaxg4+mCelEHNPycQqidqs+84RrDma8Kkz3DVZuV11Yca
-o2ibon7rWhaTc9SR0j5B8BMU1Z9VEVF5uejepHWf1iCeOhxl6tNQuTTJP0uE4h6h
-VAtQ+ux57x052IuOi9FtrqVR
------END CERTIFICATE-----
-Bag Attributes
- friendlyName: expired1.example.net
- localKeyID: 95 17 AC C5 EF E3 7C 42 C9 E2 14 CF CC CA 19 19 06 2B F6 6C
-subject=/CN=expired1.example.net
-issuer=/O=example.net/CN=clica Signing Cert
------BEGIN CERTIFICATE-----
-MIICiTCCAfKgAwIBAgIBZzANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt
-cGxlLm5ldDEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
-MzQxM1oXDTEyMTIwMTEyMzQxM1owHzEdMBsGA1UEAxMUZXhwaXJlZDEuZXhhbXBs
-ZS5uZXQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANlhAgxfclTrlENHgOLp
-okcI0OF605Nkvp4mXu+3NkJ7hxHtw5ZemQZr8yPqxCjn8GpuL6ADWdUr0T3eELM5
-bP0EwJqmXbZ+F9rp0DAl50dtGyLFdZMXe7IXe+ej+k2cGqf0M/gNp95AOSekhuwg
-8wpCRTeOP6zzK0g4SMjOcw7LAgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
-A1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAj
-hiFodHRwOi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEE
-KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLm5ldC8wHwYDVR0R
-BBgwFoIUZXhwaXJlZDEuZXhhbXBsZS5uZXQwDQYJKoZIhvcNAQEFBQADgYEAtoii
-zSaNrMH7SDRVVF+A2Ox59vck78T8Kx/YYZz6/p4dgaVWVK6LHzL1VjiYkZwTeSxG
-ZgnbqY8JNeGTUlDC0XZLwTmsIufpaeUd75JkvIniI9I9XhmOgwGOrijSqjNDgWyg
-DsS34gVsXLkAlSyegGiLY4UWtKPU+oXQLdYa5Vk=
+MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDQwWhcNMzgw
+MTAxMTIzNDQwWjApMRQwEgYDVQQKEwtleGFtcGxlLm5ldDERMA8GA1UEAxMIY2xp
+Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOY7eAp9lkZsBxaHMAn5
+1zK898gr+Yxq+Vxgi6sXXmhsq20D/qHjVsKakEQtQLdBc3di6kRPURWiHrVqwQ+t
+RIpR1pQXqoaPmVf11aCvS3pEUaBreO+LQ3CJImrS887XIrGPDuuYuTaKrChtcMPN
+idZRKhwJAajAVJvivdDv6ucHAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
+DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBABVCocYnR8xCX0k6HVaW
+RX+SAucii+m4sX6TJ/yWjNvQjKxrs3gwe19yOJB0WCOQKqU2s7UhxovW39qD4q60
+dSKq+qjW/4DfLmi1d/5aMqAq9au/s7W9Ut/jqqdL5eY31lxWRyW+D+29mfRyl+B7
+H0+wMSKs4DNtTYYEd+3W8kEw
-----END CERTIFICATE-----
Bag Attributes
friendlyName: expired1.example.net
- localKeyID: 95 17 AC C5 EF E3 7C 42 C9 E2 14 CF CC CA 19 19 06 2B F6 6C
+ localKeyID: 30 93 A9 CA 9C 39 D2 39 11 AD 46 15 42 E3 D0 BB 2A E3 3D 32
subject=/CN=expired1.example.net
issuer=/O=example.net/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICiTCCAfKgAwIBAgIBZzANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt
+MIICiTCCAfKgAwIBAgIBZzANBgkqhkiG9w0BAQsFADAzMRQwEgYDVQQKEwtleGFt
cGxlLm5ldDEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
-MzQxM1oXDTEyMTIwMTEyMzQxM1owHzEdMBsGA1UEAxMUZXhwaXJlZDEuZXhhbXBs
-ZS5uZXQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANlhAgxfclTrlENHgOLp
-okcI0OF605Nkvp4mXu+3NkJ7hxHtw5ZemQZr8yPqxCjn8GpuL6ADWdUr0T3eELM5
-bP0EwJqmXbZ+F9rp0DAl50dtGyLFdZMXe7IXe+ej+k2cGqf0M/gNp95AOSekhuwg
-8wpCRTeOP6zzK0g4SMjOcw7LAgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
+MzQ0MVoXDTEyMTIwMTEyMzQ0MVowHzEdMBsGA1UEAxMUZXhwaXJlZDEuZXhhbXBs
+ZS5uZXQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJrX3SMipXzwFiOjbvdH
+5ap8oCcCgO5GbVTW+2lFM2epq1mtF9xvVAYfzu7X9XLi3OQcdOWraVKLURlK0JJb
+AdzrAsajbs5F9PWIXuXbtLPSrWx1xa+9It/Mwc3451wXJNWWLzfutOiLrsd0B3FZ
+M1LuhJ8cc2OncVQC8+Ty1oudAgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
A1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAj
hiFodHRwOi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEE
KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLm5ldC8wHwYDVR0R
-BBgwFoIUZXhwaXJlZDEuZXhhbXBsZS5uZXQwDQYJKoZIhvcNAQEFBQADgYEAtoii
-zSaNrMH7SDRVVF+A2Ox59vck78T8Kx/YYZz6/p4dgaVWVK6LHzL1VjiYkZwTeSxG
-ZgnbqY8JNeGTUlDC0XZLwTmsIufpaeUd75JkvIniI9I9XhmOgwGOrijSqjNDgWyg
-DsS34gVsXLkAlSyegGiLY4UWtKPU+oXQLdYa5Vk=
+BBgwFoIUZXhwaXJlZDEuZXhhbXBsZS5uZXQwDQYJKoZIhvcNAQELBQADgYEAgwSn
+B4YRfFKbUCp0ILBQBaRUno4MzUyJloT7e09j+/CQaLPQhxHEuFrTBXFkwL0oxCOn
+TrsoGCO+OG/5ETUsdHJKJleqeCjPzu/cOUl48NZKHfI0FRGnjXqgeBln9r8kQLeG
+8IIvXJGecIWm+IpKMFgo0q7yd3nIVl5Xk4xq1po=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDExWhcNMzgw\r
-MTAxMTIzNDExWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp\r
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCf/Mo\r
-cl7+ta84A85TdEcSPfv+JV6/0ynu98Z+EHaz221TGgNYkOtlBDc80kZZ2QBndE6e\r
-RZAuIaPgTVk0mZJ7XUxAVx7AAlGSWenScV/k/VChgqddRaCmmLQoPT/wUkrDqlOW\r
-7omdM0BTaMxdEv2QRyUCVrrZKOJkRsTILkUvaQIDAQABo1owWDAOBgNVHQ8BAf8E\r
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDQwWhcNMzgw\r
+MTAxMTIzNDQwWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp\r
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXxUua\r
+JOUjKYqtSZyRwCoF1o5VI5yr+sinPkKPpGQnFd28bani9yCcLdvvOVCBPBmBe3vJ\r
+sjRSu5YO3fGlE7dRbiUBCvmOtZ4Kk39mgQcThWp8R8Mxk//ex5BSLlw3q43BY3Om\r
++V59fPWaYgHKE/RIjneGJb97oa3AmxjvZcZXnQIDAQABo1owWDAOBgNVHQ8BAf8E\r
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw\r
-Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA\r
-P/kvw/kOJI5Yja+W8/xmbAma4NeAWE48eLDzp6AWJBUU7oIj4Ca+PqwpaxxeNioZ\r
-ihLL5LCRrS8lsSGgyD3UzqYGCMOwqX5pBytpWXz1NRzzey9mCV55LHckBF7dRBuh\r
-XQiz+EvE4Dr1ZikrB6UjgHW7Bal9Y5QMDs8qZAsRkJ0=
+Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA\r
+rPmUtgNXl5WO6GDheUimkO9DGTeKnk8n/Hwlm6KjqYfkaJuf1YTKD2bgqfsW4TQM\r
+uN/wZurB9sbZTdrPqqD+pS8xV8CloldkH4x3PtUz+0Z4Fkgf4IQG1GKI/OGu2Ego\r
+6UjWNb+M5nNokpzyV7bAslmTj6Q7CCVQuNSKGfOIJEc=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: expired1.example.net
- localKeyID: 95 17 AC C5 EF E3 7C 42 C9 E2 14 CF CC CA 19 19 06 2B F6 6C
+ localKeyID: 30 93 A9 CA 9C 39 D2 39 11 AD 46 15 42 E3 D0 BB 2A E3 3D 32
Key Attributes: <No Attributes>
-----BEGIN ENCRYPTED PRIVATE KEY-----
-MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIUxc2uzk9xFgCAggA
-MBQGCCqGSIb3DQMHBAjVv35cwAcHJwSCAoCFZGCfB6837klYjG3Bc4tCDax/XuNq
-KLLVzyT9DH0K/vmyHDUU93GXGhNrNTRkXNZcXHFNWwY/gUi6jvkDNRz9SFmtCWXM
-8wj1O9H8fTUF0qJZW8BSK5/sCHLywCLP5UfMJvr4q7Zm/p5RY1lfmrupyeR8RfTz
-B+ZLDpO3TJw1fJgM/UyVvZFJsaGNgsj/gDEqSa7sngGDYy04F2PQoyAoorEiCIK1
-n+mWeE1a/rcrfIflcG324v2tHvXYncU0tt10sUsgWxS3YB2x/FJ73VyGZZWvKpsW
-WUgz2+NAr/iD6MfcYeAXUT2Kz2fsV9Lbqgxj/fU0vaGops0dtp0WaV2MPUY9t3gw
-Iv78OSDnIpmD5L7i7+SVrlo8DxKFjnxtJg3vBDyHbe005Ehsy5/5vcTl9rN+RjJh
-meHTY6RPjko1jFKa+xsTN89EJ6ln9fGNppmA71PKiJGLDH17mNo1FuIoMB9vjTqc
-gzX5B+Ao6+MH95RwDBdhaaHEJG0V54VVc6fi0agdfZKKIR7OwG/dgqaUpkykKnFh
-rQqG75dpyvwK4l11Wvmgblxoxy0IqPZr22t1AKRfZ92MxmQKkmlal7cT1cIgwWc+
-zMQd/LvfEsZbMa5iC5ajATFuxXp1bXlvJviBuyBGDt5oCd5RG94NxSs533T8BAZi
-e8YRULQV3JG2ADdrN3yQWX/ZHw9jI+Hgg9JseO2U2I8Q9SSwMz5tB6mdQGPwnV8f
-fN/DIiF9TjTWQoJ45q8qJCr4h/UJ8GF5J8h19lh9MHi6VZYbQpjy4NbAwQ6yxNEU
-DWan+ET8FLSB6SdeMi1bNBKBoOcMVhLqKIxM9lO+mj+eWlSfOsjd6AKL
+MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIfc37w/ONzOMCAggA
+MBQGCCqGSIb3DQMHBAj4hLDQfNOVvwSCAoB5SgUvtiT9VLrNjrSmf6aOa09y+UjS
+ZEnlot2pIS/rgC2+DfUZM0h0M6eaBYpuFY9N86qGD5byCmStCz8oABFq35jGpVx2
+QXCE18F4Ca93bLPw11pXdmVqEoOzwmXM6ElDUDqE2CXmV2ZbFGFtSVETNcrjKg30
+CgEW7ryU2Hlab0hWZ+2poEGexgiposQ5IbMO0OVeoHlCMhAVu4KEHc7n+a+XKlt7
+8O/yK+DRtMbCYG2qmFUdF4YmVx+GmECGXzvWlPJ/0lg/wHzWTIiv2oI+R1NvYxCa
+JePJ0WFpae5D1g1vGZN2eu4VAbA71bH/dkcDPx30Yc+qC7hH8HiVw4D2JFt1y/6r
+FG4ECUe0GPLkpyttKHMFh200fNJVO1zMucmV5mJg/A+LHQcvT85QNrZx1Xb3K9Ou
+o0/a/jY3K+joLP/q4uCvnLf4J2JoyiQaydCQ0jOItNUivWOeVI24mU+EqgOASEjB
+j48WU5GlopgqUl5vgTTvJww5LrZKpA0Ft+prMZuwYl86hN4FZGRc6FkymKwpTRzL
+w2WnSZCuhjx83UpLYVuzTpZze6hZwSCoV3y63Tb1moBrvf+3sxYlxjmeOq62GJ9D
+z6/nCvP6YR0GWup4I5Zs0F4BpHUJZhYchrbSKC7sty39fBS5Xfa5I55T1JOiQxLp
+pQGfWSUEqquHkAkaQ+uGqWljN1mw01e4C/4LZAXds4dnNs+/1GIIVR+CWPSj9MYe
+UxoBtgPw0ZwtQDSImo5PC9tgJibkBUQLT+Yy1IAhug3onYuORC/cQmrKmWe/NDOb
+8AvrONnFw6yeQzWpjx7irPflLo+KPKZbYOwp7IK1oFQDW3FX0efMVGMR
-----END ENCRYPTED PRIVATE KEY-----
Bag Attributes
friendlyName: expired1.example.net
- localKeyID: 95 17 AC C5 EF E3 7C 42 C9 E2 14 CF CC CA 19 19 06 2B F6 6C
+ localKeyID: 30 93 A9 CA 9C 39 D2 39 11 AD 46 15 42 E3 D0 BB 2A E3 3D 32
subject=/CN=expired1.example.net
issuer=/O=example.net/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICiTCCAfKgAwIBAgIBZzANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt
+MIICiTCCAfKgAwIBAgIBZzANBgkqhkiG9w0BAQsFADAzMRQwEgYDVQQKEwtleGFt
cGxlLm5ldDEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
-MzQxM1oXDTEyMTIwMTEyMzQxM1owHzEdMBsGA1UEAxMUZXhwaXJlZDEuZXhhbXBs
-ZS5uZXQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANlhAgxfclTrlENHgOLp
-okcI0OF605Nkvp4mXu+3NkJ7hxHtw5ZemQZr8yPqxCjn8GpuL6ADWdUr0T3eELM5
-bP0EwJqmXbZ+F9rp0DAl50dtGyLFdZMXe7IXe+ej+k2cGqf0M/gNp95AOSekhuwg
-8wpCRTeOP6zzK0g4SMjOcw7LAgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
+MzQ0MVoXDTEyMTIwMTEyMzQ0MVowHzEdMBsGA1UEAxMUZXhwaXJlZDEuZXhhbXBs
+ZS5uZXQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJrX3SMipXzwFiOjbvdH
+5ap8oCcCgO5GbVTW+2lFM2epq1mtF9xvVAYfzu7X9XLi3OQcdOWraVKLURlK0JJb
+AdzrAsajbs5F9PWIXuXbtLPSrWx1xa+9It/Mwc3451wXJNWWLzfutOiLrsd0B3FZ
+M1LuhJ8cc2OncVQC8+Ty1oudAgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
A1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAj
hiFodHRwOi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEE
KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLm5ldC8wHwYDVR0R
-BBgwFoIUZXhwaXJlZDEuZXhhbXBsZS5uZXQwDQYJKoZIhvcNAQEFBQADgYEAtoii
-zSaNrMH7SDRVVF+A2Ox59vck78T8Kx/YYZz6/p4dgaVWVK6LHzL1VjiYkZwTeSxG
-ZgnbqY8JNeGTUlDC0XZLwTmsIufpaeUd75JkvIniI9I9XhmOgwGOrijSqjNDgWyg
-DsS34gVsXLkAlSyegGiLY4UWtKPU+oXQLdYa5Vk=
+BBgwFoIUZXhwaXJlZDEuZXhhbXBsZS5uZXQwDQYJKoZIhvcNAQELBQADgYEAgwSn
+B4YRfFKbUCp0ILBQBaRUno4MzUyJloT7e09j+/CQaLPQhxHEuFrTBXFkwL0oxCOn
+TrsoGCO+OG/5ETUsdHJKJleqeCjPzu/cOUl48NZKHfI0FRGnjXqgeBln9r8kQLeG
+8IIvXJGecIWm+IpKMFgo0q7yd3nIVl5Xk4xq1po=
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
-MIICWwIBAAKBgQDZYQIMX3JU65RDR4Di6aJHCNDhetOTZL6eJl7vtzZCe4cR7cOW
-XpkGa/Mj6sQo5/Bqbi+gA1nVK9E93hCzOWz9BMCapl22fhfa6dAwJedHbRsixXWT
-F3uyF3vno/pNnBqn9DP4DafeQDknpIbsIPMKQkU3jj+s8ytIOEjIznMOywIDAQAB
-AoGAO3wuYVBlKxPkWJziijXA8ItbDbjc2QLCnuiFJjgOoxbGmYNk+GsemQFFYdjG
-oSMHSTip07HXDVyWP8Xa8BCQ4BMkzBj/1fpasm1t3BHrS8xatukWAvW9xm4rHKo2
-bOZSkoUaJ/IICifBKmlgoyNIocnF5eLEFpmdijK4vQb+BbECQQDuoiW0oZZAAyoA
-orZkvuVwfszm//MveYTHxFvcxIA2f7gvuC6JV8Auvo0OxXZ0QLT787TkJYHJnQkv
-CdgVMTFnAkEA6TLhWSQH4yu4EytXcQ7V2BbLCZWDavPttGqQz/zcCCvloyDmfdUg
-CoXK8H+W6CrwFz7Qyz+FGKcO3rkMa49k/QJASb3ZoQP+BjH0HNYrPt6u0CCe+RNG
-9vi6S3EmYgZnCHBXXoev+ckgHlHMDTB/9lS4mNMqpwXgIYlheSO1nnbhKQJAY70N
-QND2RqUmP5yj84kC0T8+a8T0xkO6ARYrBaoCecQ8nT6vFlaXM6jxmVcYtgfXVDnb
-l3J9fIPHCl9e/ooACQJAGhJ1JPgzQT3QytWx8mmZwuI5JVaRGboz7UQJ+4wTp9JE
-4oWHDbtGGanvpCWmMd47BHvOlWHT2iWCxMIez6ZwGg==
+MIICXAIBAAKBgQCa190jIqV88BYjo273R+WqfKAnAoDuRm1U1vtpRTNnqatZrRfc
+b1QGH87u1/Vy4tzkHHTlq2lSi1EZStCSWwHc6wLGo27ORfT1iF7l27Sz0q1sdcWv
+vSLfzMHN+OdcFyTVli837rToi67HdAdxWTNS7oSfHHNjp3FUAvPk8taLnQIDAQAB
+AoGAdt52Rg3H6yTIai2B91V7ayjnLWtPnRv1vKaZNJRKRS9MerhV1ASnBViP3G1v
+YPXlyzxJRTMU1Khc5sS3X1N8FnF20LuyVZpvKKFcxkGrU77+8Zl8+vpdK1zxv0S2
+X8POJAZHqScqXdRC03nnA0mp1Zb71CGQ2D4OM3f/qaLp9kUCQQDOPCdYcyLFfd5U
+IrDXucXrMPfhaKMEmpYXl99fwMVRmT7rYFgqGEIYAINjl1Bgu0FCecSfPOBH/Dar
+IldhiglLAkEAwDUQWntbAA08w3r5TS7uHcZ85Ec1Rz/q7nVDk5IVQHr0obOZLFHt
+hIZhL6xDDyB3ecCJm5csJh1WgSp0E7xVtwJAHTi8wnWd6anKBNXdhNOXzZlkphWz
+c4WL2s/0IJcp3kP+fE9sbpp9UvVPqJ7aDrq5pnemeoGfrdN404rMIs/yPQJAa44G
+DavTe07s/rJUyRUG2BCXGKKkNK+WxkNGQlDPpZpoRAgdIYji8XLE9YleqRtQ4AeW
+uUM5yEZIftUDyXttNwJBAI5usOrcqizhIF0kwAnlfn70G8QsfDVHXvuOS7Hwx4wr
+x96beknpccYAojJxWdzeP4hzLc9apLUUTBy4sYZCcMA=
-----END RSA PRIVATE KEY-----
subject=/O=example.net/CN=clica Signing Cert
issuer=/O=example.net/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDExWhcNMzgw
-MTAxMTIzNDExWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCf/Mo
-cl7+ta84A85TdEcSPfv+JV6/0ynu98Z+EHaz221TGgNYkOtlBDc80kZZ2QBndE6e
-RZAuIaPgTVk0mZJ7XUxAVx7AAlGSWenScV/k/VChgqddRaCmmLQoPT/wUkrDqlOW
-7omdM0BTaMxdEv2QRyUCVrrZKOJkRsTILkUvaQIDAQABo1owWDAOBgNVHQ8BAf8E
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDQwWhcNMzgw
+MTAxMTIzNDQwWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXxUua
+JOUjKYqtSZyRwCoF1o5VI5yr+sinPkKPpGQnFd28bani9yCcLdvvOVCBPBmBe3vJ
+sjRSu5YO3fGlE7dRbiUBCvmOtZ4Kk39mgQcThWp8R8Mxk//ex5BSLlw3q43BY3Om
++V59fPWaYgHKE/RIjneGJb97oa3AmxjvZcZXnQIDAQABo1owWDAOBgNVHQ8BAf8E
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw
-Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA
-P/kvw/kOJI5Yja+W8/xmbAma4NeAWE48eLDzp6AWJBUU7oIj4Ca+PqwpaxxeNioZ
-ihLL5LCRrS8lsSGgyD3UzqYGCMOwqX5pBytpWXz1NRzzey9mCV55LHckBF7dRBuh
-XQiz+EvE4Dr1ZikrB6UjgHW7Bal9Y5QMDs8qZAsRkJ0=
+Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA
+rPmUtgNXl5WO6GDheUimkO9DGTeKnk8n/Hwlm6KjqYfkaJuf1YTKD2bgqfsW4TQM
+uN/wZurB9sbZTdrPqqD+pS8xV8CloldkH4x3PtUz+0Z4Fkgf4IQG1GKI/OGu2Ego
+6UjWNb+M5nNokpzyV7bAslmTj6Q7CCVQuNSKGfOIJEc=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: Certificate Authority
subject=/O=example.net/CN=clica CA
issuer=/O=example.net/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDExWhcNMzgw
-MTAxMTIzNDExWjApMRQwEgYDVQQKEwtleGFtcGxlLm5ldDERMA8GA1UEAxMIY2xp
-Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALUSMNgU8YE8fsiB8Wm7
-lpclDOwQXJVbP/Ef2NVwoE6NnoPTWMNgvSyCddVz7709URkIy+jtrlpbyQYVdwgO
-HAnI8/bx2WoGtGzWTbAM1Mp+WHtiOO7LpsldWQmeHuF9uBOghFytVyqNT2l/iG7x
-XQCA6Q6P59vpb3Z+4PH8kgVlAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
-DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBACs6X9bwml5hcwf82pyb
-bKOnRGP6pJsvx1yv6SULaxg4+mCelEHNPycQqidqs+84RrDma8Kkz3DVZuV11Yca
-o2ibon7rWhaTc9SR0j5B8BMU1Z9VEVF5uejepHWf1iCeOhxl6tNQuTTJP0uE4h6h
-VAtQ+ux57x052IuOi9FtrqVR
------END CERTIFICATE-----
-Bag Attributes
- friendlyName: expired2.example.net
- localKeyID: 4C 57 EE 41 10 81 8F 15 98 AD 20 D9 85 06 8B 7D A2 3A 4D 05
-subject=/CN=expired2.example.net
-issuer=/O=example.net/CN=clica Signing Cert
------BEGIN CERTIFICATE-----
-MIICijCCAfOgAwIBAgICAMswDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhh
-bXBsZS5uZXQxGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDEx
-MjM0MTRaFw0xMjEyMDExMjM0MTRaMB8xHTAbBgNVBAMTFGV4cGlyZWQyLmV4YW1w
-bGUubmV0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXEgubmOBQOTfeVoMK
-VTyqO7QB9NUL0gMxPgF/Cv+r14dpuAEMmzB5w0waANwVyJ3RHeqMCx9uHCLpk37W
-2LSIsx3j74Oz6Plyh+vac3HDv6Z2TapetEiwTz/XaaObAaU3WHt2pIpPkju8xlqP
-s9tgzD8i3VMZqSQMC+8+HMGELwIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
-BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
-I4YhaHR0cDovL2NybC5leGFtcGxlLm5ldC9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
-BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5uZXQvMB8GA1Ud
-EQQYMBaCFGV4cGlyZWQyLmV4YW1wbGUubmV0MA0GCSqGSIb3DQEBBQUAA4GBAE6e
-wvdUVSaQqtamGhj7R4SRX6606y4bG+/RUmFRLZWXzoUmCTA8za0A8fK4uxHUcGnV
-LNWL5SpOxdDhRNuOgRqLG1J5h6gBDfrNz2ifsPqkrVXGkWWGSML4OLDhB5NIwT3W
-76zE2YzQAfjdQGYqlJ+guw6qP503tFzletcxOk5b
+MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDQwWhcNMzgw
+MTAxMTIzNDQwWjApMRQwEgYDVQQKEwtleGFtcGxlLm5ldDERMA8GA1UEAxMIY2xp
+Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOY7eAp9lkZsBxaHMAn5
+1zK898gr+Yxq+Vxgi6sXXmhsq20D/qHjVsKakEQtQLdBc3di6kRPURWiHrVqwQ+t
+RIpR1pQXqoaPmVf11aCvS3pEUaBreO+LQ3CJImrS887XIrGPDuuYuTaKrChtcMPN
+idZRKhwJAajAVJvivdDv6ucHAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
+DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBABVCocYnR8xCX0k6HVaW
+RX+SAucii+m4sX6TJ/yWjNvQjKxrs3gwe19yOJB0WCOQKqU2s7UhxovW39qD4q60
+dSKq+qjW/4DfLmi1d/5aMqAq9au/s7W9Ut/jqqdL5eY31lxWRyW+D+29mfRyl+B7
+H0+wMSKs4DNtTYYEd+3W8kEw
-----END CERTIFICATE-----
Bag Attributes
friendlyName: expired2.example.net
- localKeyID: 4C 57 EE 41 10 81 8F 15 98 AD 20 D9 85 06 8B 7D A2 3A 4D 05
+ localKeyID: AC A0 16 38 87 AB 28 96 6E 21 6E 26 E1 90 00 11 5D 25 79 AF
subject=/CN=expired2.example.net
issuer=/O=example.net/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICijCCAfOgAwIBAgICAMswDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhh
+MIICijCCAfOgAwIBAgICAMswDQYJKoZIhvcNAQELBQAwMzEUMBIGA1UEChMLZXhh
bXBsZS5uZXQxGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDEx
-MjM0MTRaFw0xMjEyMDExMjM0MTRaMB8xHTAbBgNVBAMTFGV4cGlyZWQyLmV4YW1w
-bGUubmV0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXEgubmOBQOTfeVoMK
-VTyqO7QB9NUL0gMxPgF/Cv+r14dpuAEMmzB5w0waANwVyJ3RHeqMCx9uHCLpk37W
-2LSIsx3j74Oz6Plyh+vac3HDv6Z2TapetEiwTz/XaaObAaU3WHt2pIpPkju8xlqP
-s9tgzD8i3VMZqSQMC+8+HMGELwIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
+MjM0NDFaFw0xMjEyMDExMjM0NDFaMB8xHTAbBgNVBAMTFGV4cGlyZWQyLmV4YW1w
+bGUubmV0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcSCmpy4lm9UKl6gu/
+ISgxTijBFZFTaBeT91+GxJpBwmZhAmqgUTTITRKVXQ3jTPoB6mjhUrBhRAn6fV15
+eepFOgRIfq9wleLYHf3MmHuD05FQxgdFdYqj7rMM7wslteA6BCVy0/jZmaGnRZ1Z
+oiAXXrV5goHmV++Iskx40/wh7wIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
I4YhaHR0cDovL2NybC5leGFtcGxlLm5ldC9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5uZXQvMB8GA1Ud
-EQQYMBaCFGV4cGlyZWQyLmV4YW1wbGUubmV0MA0GCSqGSIb3DQEBBQUAA4GBAE6e
-wvdUVSaQqtamGhj7R4SRX6606y4bG+/RUmFRLZWXzoUmCTA8za0A8fK4uxHUcGnV
-LNWL5SpOxdDhRNuOgRqLG1J5h6gBDfrNz2ifsPqkrVXGkWWGSML4OLDhB5NIwT3W
-76zE2YzQAfjdQGYqlJ+guw6qP503tFzletcxOk5b
+EQQYMBaCFGV4cGlyZWQyLmV4YW1wbGUubmV0MA0GCSqGSIb3DQEBCwUAA4GBADaj
+ygpTux0LFCBD60TiEh2XNOnX/DvxrRdX6BBUWCec9upygG398XNF1GivtQLd1wE2
+xN3h9LvyXOm+mTdflm3VmYQqNwdQWupjNKxGFTUWV3Jl9m/Nd+UM4fWNSM0T6TE1
+YXSuOBA0DN06kGKpp7GJZBB5PRhbbE+4sbKqQNlC
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDExWhcNMzgw\r
-MTAxMTIzNDExWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp\r
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCf/Mo\r
-cl7+ta84A85TdEcSPfv+JV6/0ynu98Z+EHaz221TGgNYkOtlBDc80kZZ2QBndE6e\r
-RZAuIaPgTVk0mZJ7XUxAVx7AAlGSWenScV/k/VChgqddRaCmmLQoPT/wUkrDqlOW\r
-7omdM0BTaMxdEv2QRyUCVrrZKOJkRsTILkUvaQIDAQABo1owWDAOBgNVHQ8BAf8E\r
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDQwWhcNMzgw\r
+MTAxMTIzNDQwWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp\r
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXxUua\r
+JOUjKYqtSZyRwCoF1o5VI5yr+sinPkKPpGQnFd28bani9yCcLdvvOVCBPBmBe3vJ\r
+sjRSu5YO3fGlE7dRbiUBCvmOtZ4Kk39mgQcThWp8R8Mxk//ex5BSLlw3q43BY3Om\r
++V59fPWaYgHKE/RIjneGJb97oa3AmxjvZcZXnQIDAQABo1owWDAOBgNVHQ8BAf8E\r
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw\r
-Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA\r
-P/kvw/kOJI5Yja+W8/xmbAma4NeAWE48eLDzp6AWJBUU7oIj4Ca+PqwpaxxeNioZ\r
-ihLL5LCRrS8lsSGgyD3UzqYGCMOwqX5pBytpWXz1NRzzey9mCV55LHckBF7dRBuh\r
-XQiz+EvE4Dr1ZikrB6UjgHW7Bal9Y5QMDs8qZAsRkJ0=
+Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA\r
+rPmUtgNXl5WO6GDheUimkO9DGTeKnk8n/Hwlm6KjqYfkaJuf1YTKD2bgqfsW4TQM\r
+uN/wZurB9sbZTdrPqqD+pS8xV8CloldkH4x3PtUz+0Z4Fkgf4IQG1GKI/OGu2Ego\r
+6UjWNb+M5nNokpzyV7bAslmTj6Q7CCVQuNSKGfOIJEc=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: expired2.example.net
- localKeyID: 4C 57 EE 41 10 81 8F 15 98 AD 20 D9 85 06 8B 7D A2 3A 4D 05
+ localKeyID: AC A0 16 38 87 AB 28 96 6E 21 6E 26 E1 90 00 11 5D 25 79 AF
Key Attributes: <No Attributes>
-----BEGIN ENCRYPTED PRIVATE KEY-----
-MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIVx/Vy3DgJSECAggA
-MBQGCCqGSIb3DQMHBAj90r/LCeWw8wSCAoB4xKSRp9hTsIfobieMallpU3Jk8Oy4
-wZieRLtvch0Bteo1H5UfnRgQo0djdTV7JGE94Kelh9o72pkv1hyIwfDhYlA4nACM
-4gVUfhi2B93zLgKD2KqYWjD3xKo+ci11q0ByklsoHRsiixP5rA0dZaAvru9p8Gog
-xx8vubDRer8coZLOEoaRtl7bV27d1N8GJPOCWu5SAR4xk76SAXUoUSThS1WrhKWK
-ZRNSEcHN5xyi4RSRvOon1WP1mhVkW8wbgjXKHuGyIOlP9NdgGJ+1YNUH1pWngg3p
-kZaMOy9A+gsE3w2owfqIpZtvbT8ByQTiwxpuTGS5O3lDF6IY1a+dYc1Hxa6KSktC
-stTL/OI97sTS+g417AWlVT6rEsAHwLETE/Ve3EygkFC0LM5QmX8rtsrQT8ZLvI1B
-53ocek2fIlXsCWzJL4Pd4to+CwZATHEjPCobXfNZrvuJ7PiYQQcPCzzJz7XZnPyN
-Hw5hFhAKKfHXCjt/NnA8Nzqn21KHv76WVPZLlCQu8OnCRw0Zg2kK+R/km4CpCyXd
-CivWV3Te8JmuISVZth6TK+5AWjpb/2MRm+1+aAsnYsK36TTxBBmC8VzhBbYdStKZ
-4TOypvo0sVVQeXfGWEjrsWytbepQlSErhXZ7q6vceHEtYTdEcM2YiFPA59axF+r9
-2H4A97AKMreFchLoJHEPZ1KVzfL8SI73UfsV7vzWow8kseP9DS33/mV1LV1rzbPb
-yiYZOjwYdnWqTfWmQm2AD29TTmBR85xapRDZkQXA6/FRFyFRVBpiGuiuCNOqGF9X
-7Kplfv/q8aienf2ULf7lVOb6SQ5urAxcevzablwUOgG9WopZad2pfs5K
+MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIn7wBE32WUxkCAggA
+MBQGCCqGSIb3DQMHBAgujTxmGe8opwSCAoDo+aUg2uDhyEsCkSLqzTxQCirDWNj7
+3qgzDmlIl5E6TK8/kTYvYK2THBMe1MnD+bWEaQym/H4N05WcNmOgh7t1HOPwhNnN
+0Iy5Y7lB8qzubLai+X+Z6qonu61K+i/FBos+yFUYgbEf3+pJYO410+rnJvuNUa+Q
+O0ez15JZAA3aBG/90McavLgsJfowyYcMs4IV8kuK4N3l3SgTC4fUegtE/FTg1Pk/
+opdrBTnh/I8Spjw5T2RtFfPH700besFMRWbGU9AcpV3U5RhTVkBCkvNlmNDRuLDO
+oOv16t/2XldumEvDCweJkFQTd1YQHxkM/v4lCG5dUtZvUHLG5m0P/GNA8HKbcAuy
+OwyrCZACYmOKgHhqM/wa0JvDb2ZPUV6yMNkOiG6pPNh99pH9/rbKGzfFu2XRifSg
+ilLpYp3vuVYlTmBwAbXBDyl/Aiv1CUGfmFMmOYQNWPxSe5XVKLck5iq8DKxAdmdN
+xi1GIXXoS68kf8jD/gcxtwOqOW1hWkdBmdfW0fZ7e27FuUTHUxJvDqDXoBcLvKUx
+68NJcH0pujmdUFbm+qKN0p7Eaclii26h3LyGoNq7cPP7Hqo9bcV4Xtpnhz1crH5U
+cs+gZ3hnVEDtCUnL7lQUKUQNKZTCzzRo5UGQDIEEHy7qYh8UtMzsIOuFacu5pmkf
+vEjIGiB3RPNQJ7EGMK1qxu1MxZ5MdQQuONpf8FFDzXhIM1p35Zqm+k3fC8Jnu42f
+CrhffQ1+8+aKUIyQ5czEcK/z1LPqQBBE8cflJVU09Gd6KNH7ZHI6oHiZO51GlrNm
+4/gGjcEavXJ6ewY2cKZBXXfo4XE2cpGFMnUeJoEtPCf+SQtQLw9Ad6Hp
-----END ENCRYPTED PRIVATE KEY-----
Bag Attributes
friendlyName: expired2.example.net
- localKeyID: 4C 57 EE 41 10 81 8F 15 98 AD 20 D9 85 06 8B 7D A2 3A 4D 05
+ localKeyID: AC A0 16 38 87 AB 28 96 6E 21 6E 26 E1 90 00 11 5D 25 79 AF
subject=/CN=expired2.example.net
issuer=/O=example.net/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICijCCAfOgAwIBAgICAMswDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhh
+MIICijCCAfOgAwIBAgICAMswDQYJKoZIhvcNAQELBQAwMzEUMBIGA1UEChMLZXhh
bXBsZS5uZXQxGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDEx
-MjM0MTRaFw0xMjEyMDExMjM0MTRaMB8xHTAbBgNVBAMTFGV4cGlyZWQyLmV4YW1w
-bGUubmV0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXEgubmOBQOTfeVoMK
-VTyqO7QB9NUL0gMxPgF/Cv+r14dpuAEMmzB5w0waANwVyJ3RHeqMCx9uHCLpk37W
-2LSIsx3j74Oz6Plyh+vac3HDv6Z2TapetEiwTz/XaaObAaU3WHt2pIpPkju8xlqP
-s9tgzD8i3VMZqSQMC+8+HMGELwIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
+MjM0NDFaFw0xMjEyMDExMjM0NDFaMB8xHTAbBgNVBAMTFGV4cGlyZWQyLmV4YW1w
+bGUubmV0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcSCmpy4lm9UKl6gu/
+ISgxTijBFZFTaBeT91+GxJpBwmZhAmqgUTTITRKVXQ3jTPoB6mjhUrBhRAn6fV15
+eepFOgRIfq9wleLYHf3MmHuD05FQxgdFdYqj7rMM7wslteA6BCVy0/jZmaGnRZ1Z
+oiAXXrV5goHmV++Iskx40/wh7wIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
I4YhaHR0cDovL2NybC5leGFtcGxlLm5ldC9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5uZXQvMB8GA1Ud
-EQQYMBaCFGV4cGlyZWQyLmV4YW1wbGUubmV0MA0GCSqGSIb3DQEBBQUAA4GBAE6e
-wvdUVSaQqtamGhj7R4SRX6606y4bG+/RUmFRLZWXzoUmCTA8za0A8fK4uxHUcGnV
-LNWL5SpOxdDhRNuOgRqLG1J5h6gBDfrNz2ifsPqkrVXGkWWGSML4OLDhB5NIwT3W
-76zE2YzQAfjdQGYqlJ+guw6qP503tFzletcxOk5b
+EQQYMBaCFGV4cGlyZWQyLmV4YW1wbGUubmV0MA0GCSqGSIb3DQEBCwUAA4GBADaj
+ygpTux0LFCBD60TiEh2XNOnX/DvxrRdX6BBUWCec9upygG398XNF1GivtQLd1wE2
+xN3h9LvyXOm+mTdflm3VmYQqNwdQWupjNKxGFTUWV3Jl9m/Nd+UM4fWNSM0T6TE1
+YXSuOBA0DN06kGKpp7GJZBB5PRhbbE+4sbKqQNlC
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
-MIICXQIBAAKBgQDXEgubmOBQOTfeVoMKVTyqO7QB9NUL0gMxPgF/Cv+r14dpuAEM
-mzB5w0waANwVyJ3RHeqMCx9uHCLpk37W2LSIsx3j74Oz6Plyh+vac3HDv6Z2Tape
-tEiwTz/XaaObAaU3WHt2pIpPkju8xlqPs9tgzD8i3VMZqSQMC+8+HMGELwIDAQAB
-AoGBAKfLeWj1FhUg/xilkGkwZTs/h0p7dPha6oixosM2lpDAf/KYT6FBNsnY9/fV
-seAA/DfZylNmnifvJcHshGok+nu6VjWekae6GP5U3HiOIThNqJRt4iky5q8Q2RKM
-I29fTeOWPeYHXy/YpLuAF+ZuTTCkc/WzN9o29/8xN1SrONfRAkEA8QiBbyOnhNh7
-6e4z0rXtbI88muLGs+S27pokTf5YlZbyLuNS9cJgvkafX7mA2n6fc4aatppUC/np
-WZ+s/U4KqQJBAORs1TUIQ3yStul6gc9sO5YuhXaQyNO3RYR5kCzDgfbKmXm2/+c2
-AVLgKTAJ3yOGL7ZLPmk2rzg6Pc6XX826dxcCQHTL51SAlXNFJ75yg8AuEg+R1Q9E
-pn6TbKVwIfl9L1XFYDOiShf2icSKGj5beHnn88IaTqv/Woy3HAEm47+W6okCQDZ8
-44rn8rk3ghxFlct1xOz5Ier7dHxUPmfwW3ziEhFdmKiZB4gOsNglEo4b/LdLnfv9
-DOEqIzflZLLwFvFLJncCQQCdNUfRNBWn832WkGQHIwvMpMq3vjwyVUCPOq8Hz9jK
-cDNuKQfw8/ZbH/IRDqgTsSWUDoZlIj3CTGeygPYEfGTg
+MIICWwIBAAKBgQDcSCmpy4lm9UKl6gu/ISgxTijBFZFTaBeT91+GxJpBwmZhAmqg
+UTTITRKVXQ3jTPoB6mjhUrBhRAn6fV15eepFOgRIfq9wleLYHf3MmHuD05FQxgdF
+dYqj7rMM7wslteA6BCVy0/jZmaGnRZ1ZoiAXXrV5goHmV++Iskx40/wh7wIDAQAB
+AoGAX5eRPPXuspdMTOO8JT0mS/83AFNztVY+pR98fOdkaZULCJ4b12ZmGWYY4mh3
+VmRZOeuXh/BySkNUcTdmEQku9/1Nnm1Oo8bOEkQ9eVW9qTEP/BmSVRbzk41hm94N
+KlhfWofC1JNpLTdUOY9x+9PjUN7M5efsG7SEgqiDxuH5FoECQQD55/AN11YKfqhC
+9pGzDbG97NerXVrTwltFWMAfBsRTNto5PC/Ni2xGjLTIXNo/ZCvo5AelBuuw2cNp
+TNUh6p2XAkEA4adLKhVgIV/I29KclidUy+Rx0SeEJf0wh3YDXTjNEHtCx7HGLGXJ
+yE2csNoj4OfNxcVN9c1TzAZeHquJJMhZaQJAGw4AEA+K8hHqN22oMmE+J9iXNKcj
+qR82cFh+XB2IbZXXpDCe4DrC2xRqkfJzcj9u/YSKS1Rnebrpi+HUhRp4OwJACJLM
+nkq1nk7/WKrF3EaeSCjj0iiIMtFN2Le5JP+VevzT6rZsax9q7TtVqrp/BnqILO10
+KtSkTGophUzLJySdkQJABowPjs9tT6uaAf6+JQKdpAqE/J7xfcjVIoUbXrEvdb4u
+yTr5X6vBC5L4hO7D5uZ/oASHokk0NldI09bU1MDUwA==
-----END RSA PRIVATE KEY-----
subject=/O=example.net/CN=clica Signing Cert
issuer=/O=example.net/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDExWhcNMzgw
-MTAxMTIzNDExWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCf/Mo
-cl7+ta84A85TdEcSPfv+JV6/0ynu98Z+EHaz221TGgNYkOtlBDc80kZZ2QBndE6e
-RZAuIaPgTVk0mZJ7XUxAVx7AAlGSWenScV/k/VChgqddRaCmmLQoPT/wUkrDqlOW
-7omdM0BTaMxdEv2QRyUCVrrZKOJkRsTILkUvaQIDAQABo1owWDAOBgNVHQ8BAf8E
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDQwWhcNMzgw
+MTAxMTIzNDQwWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXxUua
+JOUjKYqtSZyRwCoF1o5VI5yr+sinPkKPpGQnFd28bani9yCcLdvvOVCBPBmBe3vJ
+sjRSu5YO3fGlE7dRbiUBCvmOtZ4Kk39mgQcThWp8R8Mxk//ex5BSLlw3q43BY3Om
++V59fPWaYgHKE/RIjneGJb97oa3AmxjvZcZXnQIDAQABo1owWDAOBgNVHQ8BAf8E
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw
-Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA
-P/kvw/kOJI5Yja+W8/xmbAma4NeAWE48eLDzp6AWJBUU7oIj4Ca+PqwpaxxeNioZ
-ihLL5LCRrS8lsSGgyD3UzqYGCMOwqX5pBytpWXz1NRzzey9mCV55LHckBF7dRBuh
-XQiz+EvE4Dr1ZikrB6UjgHW7Bal9Y5QMDs8qZAsRkJ0=
+Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA
+rPmUtgNXl5WO6GDheUimkO9DGTeKnk8n/Hwlm6KjqYfkaJuf1YTKD2bgqfsW4TQM
+uN/wZurB9sbZTdrPqqD+pS8xV8CloldkH4x3PtUz+0Z4Fkgf4IQG1GKI/OGu2Ego
+6UjWNb+M5nNokpzyV7bAslmTj6Q7CCVQuNSKGfOIJEc=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: Certificate Authority
subject=/O=example.net/CN=clica CA
issuer=/O=example.net/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDExWhcNMzgw
-MTAxMTIzNDExWjApMRQwEgYDVQQKEwtleGFtcGxlLm5ldDERMA8GA1UEAxMIY2xp
-Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALUSMNgU8YE8fsiB8Wm7
-lpclDOwQXJVbP/Ef2NVwoE6NnoPTWMNgvSyCddVz7709URkIy+jtrlpbyQYVdwgO
-HAnI8/bx2WoGtGzWTbAM1Mp+WHtiOO7LpsldWQmeHuF9uBOghFytVyqNT2l/iG7x
-XQCA6Q6P59vpb3Z+4PH8kgVlAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
-DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBACs6X9bwml5hcwf82pyb
-bKOnRGP6pJsvx1yv6SULaxg4+mCelEHNPycQqidqs+84RrDma8Kkz3DVZuV11Yca
-o2ibon7rWhaTc9SR0j5B8BMU1Z9VEVF5uejepHWf1iCeOhxl6tNQuTTJP0uE4h6h
-VAtQ+ux57x052IuOi9FtrqVR
------END CERTIFICATE-----
-Bag Attributes
- friendlyName: revoked1.example.net
- localKeyID: C6 B2 B8 34 FA C7 C9 8E E1 B8 07 7F B4 BD 83 C0 75 0F 5D F4
-subject=/CN=revoked1.example.net
-issuer=/O=example.net/CN=clica Signing Cert
------BEGIN CERTIFICATE-----
-MIICiTCCAfKgAwIBAgIBZjANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt
-cGxlLm5ldDEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
-MzQxMloXDTM4MDEwMTEyMzQxMlowHzEdMBsGA1UEAxMUcmV2b2tlZDEuZXhhbXBs
-ZS5uZXQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANpxOtIHAc+C9AgJudRl
-8x4gNYbKoNoAM5nzCNv7ou3KKh05w3BwBPsbEl88KWOpiEc3CbLYFZva5z34A4Gf
-cwMYHjqWWThXOe4L06C3fTWT4oQM4906KloEPHFrIWyyVbFuhVpoyR/wC/BwJqCx
-Mc2fMUGwN1YAFJUKxUZR62NzAgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
-A1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAj
-hiFodHRwOi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEE
-KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLm5ldC8wHwYDVR0R
-BBgwFoIUcmV2b2tlZDEuZXhhbXBsZS5uZXQwDQYJKoZIhvcNAQEFBQADgYEAoB/8
-WmtU0/qjy0TglfTk+etUveul1GHAKdpBxq9UkVKWxQZrek9TFHpMTnlEUZpSS5PO
-1lXj9VckDNThQROcGg+bL9p6ZXeb7pOIY16TFyjycjhRPyukIprcoBvDyCoMH29y
-PrtI7xLKj4UBZEoJf7/+BKV24Nk7V8yAvCI8tYM=
+MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDQwWhcNMzgw
+MTAxMTIzNDQwWjApMRQwEgYDVQQKEwtleGFtcGxlLm5ldDERMA8GA1UEAxMIY2xp
+Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOY7eAp9lkZsBxaHMAn5
+1zK898gr+Yxq+Vxgi6sXXmhsq20D/qHjVsKakEQtQLdBc3di6kRPURWiHrVqwQ+t
+RIpR1pQXqoaPmVf11aCvS3pEUaBreO+LQ3CJImrS887XIrGPDuuYuTaKrChtcMPN
+idZRKhwJAajAVJvivdDv6ucHAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
+DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBABVCocYnR8xCX0k6HVaW
+RX+SAucii+m4sX6TJ/yWjNvQjKxrs3gwe19yOJB0WCOQKqU2s7UhxovW39qD4q60
+dSKq+qjW/4DfLmi1d/5aMqAq9au/s7W9Ut/jqqdL5eY31lxWRyW+D+29mfRyl+B7
+H0+wMSKs4DNtTYYEd+3W8kEw
-----END CERTIFICATE-----
Bag Attributes
friendlyName: revoked1.example.net
- localKeyID: C6 B2 B8 34 FA C7 C9 8E E1 B8 07 7F B4 BD 83 C0 75 0F 5D F4
+ localKeyID: 84 0F 0F B3 85 1F FA C1 B7 69 02 5E B6 E3 7B B6 7B 1D A0 D5
subject=/CN=revoked1.example.net
issuer=/O=example.net/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICiTCCAfKgAwIBAgIBZjANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt
+MIICiTCCAfKgAwIBAgIBZjANBgkqhkiG9w0BAQsFADAzMRQwEgYDVQQKEwtleGFt
cGxlLm5ldDEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
-MzQxMloXDTM4MDEwMTEyMzQxMlowHzEdMBsGA1UEAxMUcmV2b2tlZDEuZXhhbXBs
-ZS5uZXQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANpxOtIHAc+C9AgJudRl
-8x4gNYbKoNoAM5nzCNv7ou3KKh05w3BwBPsbEl88KWOpiEc3CbLYFZva5z34A4Gf
-cwMYHjqWWThXOe4L06C3fTWT4oQM4906KloEPHFrIWyyVbFuhVpoyR/wC/BwJqCx
-Mc2fMUGwN1YAFJUKxUZR62NzAgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
+MzQ0MVoXDTM4MDEwMTEyMzQ0MVowHzEdMBsGA1UEAxMUcmV2b2tlZDEuZXhhbXBs
+ZS5uZXQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPH2t5GSlQuiRWAWr5ED
+FRRamWBxppW/9ExG2ToOkHQxN54oPSaNFF8fIAsOHLCl6K9FM906Ug9lpLbTZr4f
+napBPRIqhzyTHEEJyRqx7/RqU7GR91TvaygIY4XJAVKV65wNOyZ5cb+TUYSQdzrE
+PjgLwKsOWcUtFxvffjJtm4epAgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
A1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAj
hiFodHRwOi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEE
KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLm5ldC8wHwYDVR0R
-BBgwFoIUcmV2b2tlZDEuZXhhbXBsZS5uZXQwDQYJKoZIhvcNAQEFBQADgYEAoB/8
-WmtU0/qjy0TglfTk+etUveul1GHAKdpBxq9UkVKWxQZrek9TFHpMTnlEUZpSS5PO
-1lXj9VckDNThQROcGg+bL9p6ZXeb7pOIY16TFyjycjhRPyukIprcoBvDyCoMH29y
-PrtI7xLKj4UBZEoJf7/+BKV24Nk7V8yAvCI8tYM=
+BBgwFoIUcmV2b2tlZDEuZXhhbXBsZS5uZXQwDQYJKoZIhvcNAQELBQADgYEAjVTu
+rsWM8RmPpTvywmQ92GFqyVU4DgIrg69viG6fnmvTvzwWg9qFnlgYVf6kUAQoboYr
+x63D2zplKK6JwmSdlSFSPGommOWUugDWX2XUrwF2TKw19rjHbTD7KkJQ47ZM+wau
+pxD7wIpRtIBn5YQZE9S+kSZHjGoPAY0Ms6Q6qBY=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDExWhcNMzgw\r
-MTAxMTIzNDExWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp\r
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCf/Mo\r
-cl7+ta84A85TdEcSPfv+JV6/0ynu98Z+EHaz221TGgNYkOtlBDc80kZZ2QBndE6e\r
-RZAuIaPgTVk0mZJ7XUxAVx7AAlGSWenScV/k/VChgqddRaCmmLQoPT/wUkrDqlOW\r
-7omdM0BTaMxdEv2QRyUCVrrZKOJkRsTILkUvaQIDAQABo1owWDAOBgNVHQ8BAf8E\r
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDQwWhcNMzgw\r
+MTAxMTIzNDQwWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp\r
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXxUua\r
+JOUjKYqtSZyRwCoF1o5VI5yr+sinPkKPpGQnFd28bani9yCcLdvvOVCBPBmBe3vJ\r
+sjRSu5YO3fGlE7dRbiUBCvmOtZ4Kk39mgQcThWp8R8Mxk//ex5BSLlw3q43BY3Om\r
++V59fPWaYgHKE/RIjneGJb97oa3AmxjvZcZXnQIDAQABo1owWDAOBgNVHQ8BAf8E\r
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw\r
-Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA\r
-P/kvw/kOJI5Yja+W8/xmbAma4NeAWE48eLDzp6AWJBUU7oIj4Ca+PqwpaxxeNioZ\r
-ihLL5LCRrS8lsSGgyD3UzqYGCMOwqX5pBytpWXz1NRzzey9mCV55LHckBF7dRBuh\r
-XQiz+EvE4Dr1ZikrB6UjgHW7Bal9Y5QMDs8qZAsRkJ0=
+Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA\r
+rPmUtgNXl5WO6GDheUimkO9DGTeKnk8n/Hwlm6KjqYfkaJuf1YTKD2bgqfsW4TQM\r
+uN/wZurB9sbZTdrPqqD+pS8xV8CloldkH4x3PtUz+0Z4Fkgf4IQG1GKI/OGu2Ego\r
+6UjWNb+M5nNokpzyV7bAslmTj6Q7CCVQuNSKGfOIJEc=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: revoked1.example.net
- localKeyID: C6 B2 B8 34 FA C7 C9 8E E1 B8 07 7F B4 BD 83 C0 75 0F 5D F4
+ localKeyID: 84 0F 0F B3 85 1F FA C1 B7 69 02 5E B6 E3 7B B6 7B 1D A0 D5
Key Attributes: <No Attributes>
-----BEGIN ENCRYPTED PRIVATE KEY-----
-MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIvvFLah6OKzwCAggA
-MBQGCCqGSIb3DQMHBAinGg7Lbn4gWwSCAoDWgZmIa/W0nhBW4CDqAJRok/fKaTp2
-Meq5m4AwZUVJmMBX3TQa8S7Ea/18TsBaIhzL2Klbea9x0oa2m/U3af6mytzlkRWU
-7UkgdsKjWa1GHvvA1EBnDteMK5Zhx8mlRw1MzFbHDRkkhaAY+qmOLU72DvKKm5iz
-lFrTu9OTefxa1LGGOQ77l/oULkhpRE68uBRpu3vHFWYCJ978vdk72OwxkSyhK2OY
-HOXZ/U7CzG9u8PFAb/Qdd06UGLhXPS7NpNjE82zD1tr8lKitpQqQZOKnDVksThU3
-sF6rgWkwJB4ubDpeEyNAuKXuQM5/9pdYL11iJGASMwKKhV6jqyGktWTFodg/oWcm
-nRmG3HTPpqewMJ228nsmV3N1PrucW210Bp6svUyoM8OvC5yMT9b0BR3STAxW01ft
-Ock7gkU4YvsaJ/tvUrifcPWuoyLm196dYOlVK9voszMBwfOjHwOaM/kloVKrYA5L
-Mn6Xk8fe+tSvHMf2J81fDDzQDoaUbniKhNSfn1mfp1UGJQfBqqyAVfGikaA7NJ5/
-a96vf442lveZFBNDzoMztiDNseswGeWAKFfHJhEMGzNZm3SxIJvGNTvKjeHJ30S3
-Qgm52ckB+520VeDP+Ehtmx+zBoxPBxdIt9igh0rB0a3MhnpUsyxZwtvLVcPQ1zBg
-1mrDOfK0A/OMPpy8Es9N8JGwftrcdKbXdPWHh3n4ZbKeB9Ub+mEiuXrMIB7YrcoM
-Y25+nh2Qu4vRjkUI/Hmuw2UpXRWrcoGGTFcjLc1zmTs2tXS3+RVb5s8C+9fOTsdL
-Skwb7ln43ONDVpOOrnisdVPNuuR9bHYHqSPPePUg+AMyfjk27Y73I5Q8
+MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQInBBhbOCuw44CAggA
+MBQGCCqGSIb3DQMHBAjV6peXVTL56ASCAoA0qB+hv7EJyxnqt7+Phe4noZjL8+yW
+0/q/Sm3Kgs82jX1cl2M/Qvif8X6MboXYakZES9QB8HjqH2B+VKA7ihAYr+4iPHhE
+EYjkydD0Us6pjx0JytvgOTAsHynpqIbBCc+iqgNTpKwEfU7NIYLQFJHQzhllqlp0
+I4V7O9lDdHxVmRYL21U7Kfn/tljjWLkL8nB2ez7B0m1pjwfCUm29KKjsd7D6yslY
+esrnQqF4P03YAS9Sce+n5CsNQs5cIwvvAd98s8g9jliJQtBNGKIEAqNxe5/BET4b
+raKr4xVhRw0XirMUjeIlgtlW7L20TuBaDuI3ufyUFAEjwLJ3BM99eRETIzjjd+64
+dHxvwIwKff0a+Kqsg+Qk1gwoNysTZbaWqrcjiNKQh5Cel9kwzAWtqsFZ27LPuR03
+ybme8/k/hmw3GXNDs1/rNS/+EXdpB3vmWucWxP7cHr5p3Z5MRIgkPo7IzGQVmPBQ
+ca/tPfs2YFHPX+WevtPRdhtjlGCSsGMtLfKz1IrszSWFB+e794ZhD8uYvIpj/j2F
+cpS+0Dyae6UyttC0PUTYj0tGq6bfPzMSefAxWzClB7e6bIcX+wN1+CXr60OgwYGa
+xPP8/jUEYOhYI5G+amjzEko55QS2waaG6so/mZbeeJcOityAb9F0W08rkcr7Mg1n
+mb58ukHBFYAFqRGLi85XHi3dYM9aR5Y66IOgH21tqRnW/lLUDg4E4PYYtnKMmDz2
+ytFjA/tkhHeMCq8s7VcqsTDZvswbN3nN9zb/aH+f7763VXcmnRUmHfP3wxtxBi7g
+xb0UBKWIGs3WnlshHQrB4IgMqux+dzCPqM3psfzNXFDJNTL5QqpgkYpC
-----END ENCRYPTED PRIVATE KEY-----
Bag Attributes
friendlyName: revoked1.example.net
- localKeyID: C6 B2 B8 34 FA C7 C9 8E E1 B8 07 7F B4 BD 83 C0 75 0F 5D F4
+ localKeyID: 84 0F 0F B3 85 1F FA C1 B7 69 02 5E B6 E3 7B B6 7B 1D A0 D5
subject=/CN=revoked1.example.net
issuer=/O=example.net/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICiTCCAfKgAwIBAgIBZjANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt
+MIICiTCCAfKgAwIBAgIBZjANBgkqhkiG9w0BAQsFADAzMRQwEgYDVQQKEwtleGFt
cGxlLm5ldDEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
-MzQxMloXDTM4MDEwMTEyMzQxMlowHzEdMBsGA1UEAxMUcmV2b2tlZDEuZXhhbXBs
-ZS5uZXQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANpxOtIHAc+C9AgJudRl
-8x4gNYbKoNoAM5nzCNv7ou3KKh05w3BwBPsbEl88KWOpiEc3CbLYFZva5z34A4Gf
-cwMYHjqWWThXOe4L06C3fTWT4oQM4906KloEPHFrIWyyVbFuhVpoyR/wC/BwJqCx
-Mc2fMUGwN1YAFJUKxUZR62NzAgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
+MzQ0MVoXDTM4MDEwMTEyMzQ0MVowHzEdMBsGA1UEAxMUcmV2b2tlZDEuZXhhbXBs
+ZS5uZXQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPH2t5GSlQuiRWAWr5ED
+FRRamWBxppW/9ExG2ToOkHQxN54oPSaNFF8fIAsOHLCl6K9FM906Ug9lpLbTZr4f
+napBPRIqhzyTHEEJyRqx7/RqU7GR91TvaygIY4XJAVKV65wNOyZ5cb+TUYSQdzrE
+PjgLwKsOWcUtFxvffjJtm4epAgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
A1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAj
hiFodHRwOi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEE
KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLm5ldC8wHwYDVR0R
-BBgwFoIUcmV2b2tlZDEuZXhhbXBsZS5uZXQwDQYJKoZIhvcNAQEFBQADgYEAoB/8
-WmtU0/qjy0TglfTk+etUveul1GHAKdpBxq9UkVKWxQZrek9TFHpMTnlEUZpSS5PO
-1lXj9VckDNThQROcGg+bL9p6ZXeb7pOIY16TFyjycjhRPyukIprcoBvDyCoMH29y
-PrtI7xLKj4UBZEoJf7/+BKV24Nk7V8yAvCI8tYM=
+BBgwFoIUcmV2b2tlZDEuZXhhbXBsZS5uZXQwDQYJKoZIhvcNAQELBQADgYEAjVTu
+rsWM8RmPpTvywmQ92GFqyVU4DgIrg69viG6fnmvTvzwWg9qFnlgYVf6kUAQoboYr
+x63D2zplKK6JwmSdlSFSPGommOWUugDWX2XUrwF2TKw19rjHbTD7KkJQ47ZM+wau
+pxD7wIpRtIBn5YQZE9S+kSZHjGoPAY0Ms6Q6qBY=
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
-MIICXAIBAAKBgQDacTrSBwHPgvQICbnUZfMeIDWGyqDaADOZ8wjb+6LtyiodOcNw
-cAT7GxJfPCljqYhHNwmy2BWb2uc9+AOBn3MDGB46llk4VznuC9Ogt301k+KEDOPd
-OipaBDxxayFsslWxboVaaMkf8AvwcCagsTHNnzFBsDdWABSVCsVGUetjcwIDAQAB
-AoGAeIrFX8MYH6/vBESBtJCx0W0KvKAylTpJP2oa+HHrHfdSuB/5FqHqTbtJrx4e
-5O1X05yukG+ntQLeWpbzMGOR7hyhaVErZAzxahab6Wi5acUWcQpI/oClzqxHHswz
-TaIylvaHYEwOCunrM5sj7BfB1gX1rp/0p4sLWkTKZ4o+GvECQQD8j9iG0wMutVyu
-Ow2ElGbUHOXzxqKuxhUBuLah9S+28Fu/rEdQZ6qpnOHf1tvYF9VKcp3aIMD2ZF21
-AH8z23cLAkEA3Wp6/NMQ9nJ3q31ZriEHrBWtKAdXy8xb7hDV0vY+SbveyfMjtLB9
-3KDPIu2kjrSFJ83nj3n9z7NdK2QYU47mOQJAQ4dmmq4C9NMzQ7awZ5mSYPaVGXgr
-+VUnOr2bv3QiXOSpc3dp3frJ6+3xivsU7xN4SR6aTD9juL2fPI00dbYhfwJAAN1p
-nZM1fcD0trbGoud+IC31fzKIJUOnGEb4jtpnY+JX/HH2sb3+v93g8UH8YpJR8tXb
-EbRoSWdp9cFuVuU4AQJBAIfT/Fv5fS3wunAxWoJREcZNE3QoIrZ2elqZCETkaQpE
-GdF6kOzF1S9xH10p4jvrmaT9vIw5nQOtSWprWje5lcc=
+MIICXgIBAAKBgQDx9reRkpULokVgFq+RAxUUWplgcaaVv/RMRtk6DpB0MTeeKD0m
+jRRfHyALDhywpeivRTPdOlIPZaS202a+H52qQT0SKoc8kxxBCckase/0alOxkfdU
+72soCGOFyQFSleucDTsmeXG/k1GEkHc6xD44C8CrDlnFLRcb334ybZuHqQIDAQAB
+AoGBANSydkenPRHPAYEoMAkfVoZf5ffbr/5vkMcEeKwKZX1eTm/fG3IqDkBX0gkl
+zJ6UGWkJQkA0pjIWvaZhSy3SCPsNYO/hWAWD1JgHXA3ROzHdEJG6yp9+mjvO5A4X
+NUZBsXgxX6zg053TavwLSQel1q+6T0SSDCSyPS4OJKH/+rgpAkEA/S/5JaOIMeiS
+KbprMWcKtdXQ6AeQgTUScLLOlQ2nSzNuFJwItRKTpXedl0hR42v4XeckR/yM4ZzV
+a/RXyW1S6wJBAPSm01B8VQKfTPRkKKhWNKstBFlu9jP90RV5N/vd2mGxx/wx4Xti
+/YGCxelHbPwYVhar6aZN51jhW7Q3sJ6GYrsCQQDDUsIzzlAgqJoyBPXzO9ogY55x
+knxhoY7jUJ5ckRbxxfBzh9iT0IwFCB2Uex9pgn8t+kacHnKVDwf665rZ8zQXAkEA
+veoKu73oV+LFYCmoDhTtSbvmVm52nKF5fwvcU55CefgB4FnwSVHsrG6Rp6cUiRVz
+LqJA/CIZZrt57ooUhtqXJQJAXUkGmSME4RYuBthX2nld+0ZUXjMLhMwe0vIZtsYT
+flHXDKBAJMkyvDdgbpZm9sq5awM9/rSVY0Q0DzH+8l9Pvg==
-----END RSA PRIVATE KEY-----
subject=/O=example.net/CN=clica Signing Cert
issuer=/O=example.net/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDExWhcNMzgw
-MTAxMTIzNDExWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCf/Mo
-cl7+ta84A85TdEcSPfv+JV6/0ynu98Z+EHaz221TGgNYkOtlBDc80kZZ2QBndE6e
-RZAuIaPgTVk0mZJ7XUxAVx7AAlGSWenScV/k/VChgqddRaCmmLQoPT/wUkrDqlOW
-7omdM0BTaMxdEv2QRyUCVrrZKOJkRsTILkUvaQIDAQABo1owWDAOBgNVHQ8BAf8E
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDQwWhcNMzgw
+MTAxMTIzNDQwWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXxUua
+JOUjKYqtSZyRwCoF1o5VI5yr+sinPkKPpGQnFd28bani9yCcLdvvOVCBPBmBe3vJ
+sjRSu5YO3fGlE7dRbiUBCvmOtZ4Kk39mgQcThWp8R8Mxk//ex5BSLlw3q43BY3Om
++V59fPWaYgHKE/RIjneGJb97oa3AmxjvZcZXnQIDAQABo1owWDAOBgNVHQ8BAf8E
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw
-Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA
-P/kvw/kOJI5Yja+W8/xmbAma4NeAWE48eLDzp6AWJBUU7oIj4Ca+PqwpaxxeNioZ
-ihLL5LCRrS8lsSGgyD3UzqYGCMOwqX5pBytpWXz1NRzzey9mCV55LHckBF7dRBuh
-XQiz+EvE4Dr1ZikrB6UjgHW7Bal9Y5QMDs8qZAsRkJ0=
+Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA
+rPmUtgNXl5WO6GDheUimkO9DGTeKnk8n/Hwlm6KjqYfkaJuf1YTKD2bgqfsW4TQM
+uN/wZurB9sbZTdrPqqD+pS8xV8CloldkH4x3PtUz+0Z4Fkgf4IQG1GKI/OGu2Ego
+6UjWNb+M5nNokpzyV7bAslmTj6Q7CCVQuNSKGfOIJEc=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: Certificate Authority
subject=/O=example.net/CN=clica CA
issuer=/O=example.net/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDExWhcNMzgw
-MTAxMTIzNDExWjApMRQwEgYDVQQKEwtleGFtcGxlLm5ldDERMA8GA1UEAxMIY2xp
-Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALUSMNgU8YE8fsiB8Wm7
-lpclDOwQXJVbP/Ef2NVwoE6NnoPTWMNgvSyCddVz7709URkIy+jtrlpbyQYVdwgO
-HAnI8/bx2WoGtGzWTbAM1Mp+WHtiOO7LpsldWQmeHuF9uBOghFytVyqNT2l/iG7x
-XQCA6Q6P59vpb3Z+4PH8kgVlAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
-DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBACs6X9bwml5hcwf82pyb
-bKOnRGP6pJsvx1yv6SULaxg4+mCelEHNPycQqidqs+84RrDma8Kkz3DVZuV11Yca
-o2ibon7rWhaTc9SR0j5B8BMU1Z9VEVF5uejepHWf1iCeOhxl6tNQuTTJP0uE4h6h
-VAtQ+ux57x052IuOi9FtrqVR
------END CERTIFICATE-----
-Bag Attributes
- friendlyName: revoked2.example.net
- localKeyID: 70 BF 9C CD 8D 0C AB 91 82 4D 75 C2 EF AF DC 82 97 0B 7D 55
-subject=/CN=revoked2.example.net
-issuer=/O=example.net/CN=clica Signing Cert
------BEGIN CERTIFICATE-----
-MIICijCCAfOgAwIBAgICAMowDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhh
-bXBsZS5uZXQxGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDEx
-MjM0MTNaFw0zODAxMDExMjM0MTNaMB8xHTAbBgNVBAMTFHJldm9rZWQyLmV4YW1w
-bGUubmV0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNFaI/6qFhbiFFb+jO
-60Qfp6d0KH7PKnxI1rmCQw24g4y2HyQ7cgT26mXQr3gsxj5bnRCKB9uG7DpJ1RaY
-QVvVUApFdIHnLExVjNynwvKaNMZNwb6HVPVfjUTwwPdSgLxTRU2xAAmkIrbFUPuP
-vhAbcmNKmq7hjr7AVHxNI4XnDwIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
-BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
-I4YhaHR0cDovL2NybC5leGFtcGxlLm5ldC9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
-BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5uZXQvMB8GA1Ud
-EQQYMBaCFHJldm9rZWQyLmV4YW1wbGUubmV0MA0GCSqGSIb3DQEBBQUAA4GBAGEv
-YIEr7x4/jtbVZHfcVk369td5KZdrozHyaZOAhluUX9Q3qHpWuubeBJ/GjiJkLMGC
-v5Px5F8yI0RQmQOOxeu4vINhL1dIbksPn7oxaWpPlx+40Tuub0qQlJYyPzXSYhv0
-dcScT5CK2e0GGzk7pEwT+S7WZNtFzeeOd6gOR9dE
+MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDQwWhcNMzgw
+MTAxMTIzNDQwWjApMRQwEgYDVQQKEwtleGFtcGxlLm5ldDERMA8GA1UEAxMIY2xp
+Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOY7eAp9lkZsBxaHMAn5
+1zK898gr+Yxq+Vxgi6sXXmhsq20D/qHjVsKakEQtQLdBc3di6kRPURWiHrVqwQ+t
+RIpR1pQXqoaPmVf11aCvS3pEUaBreO+LQ3CJImrS887XIrGPDuuYuTaKrChtcMPN
+idZRKhwJAajAVJvivdDv6ucHAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
+DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBABVCocYnR8xCX0k6HVaW
+RX+SAucii+m4sX6TJ/yWjNvQjKxrs3gwe19yOJB0WCOQKqU2s7UhxovW39qD4q60
+dSKq+qjW/4DfLmi1d/5aMqAq9au/s7W9Ut/jqqdL5eY31lxWRyW+D+29mfRyl+B7
+H0+wMSKs4DNtTYYEd+3W8kEw
-----END CERTIFICATE-----
Bag Attributes
friendlyName: revoked2.example.net
- localKeyID: 70 BF 9C CD 8D 0C AB 91 82 4D 75 C2 EF AF DC 82 97 0B 7D 55
+ localKeyID: FE 0B 1F 98 D3 E3 36 0D 3A 1B 60 F6 BF EA 95 48 9A A5 A9 F2
subject=/CN=revoked2.example.net
issuer=/O=example.net/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICijCCAfOgAwIBAgICAMowDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhh
+MIICijCCAfOgAwIBAgICAMowDQYJKoZIhvcNAQELBQAwMzEUMBIGA1UEChMLZXhh
bXBsZS5uZXQxGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDEx
-MjM0MTNaFw0zODAxMDExMjM0MTNaMB8xHTAbBgNVBAMTFHJldm9rZWQyLmV4YW1w
-bGUubmV0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNFaI/6qFhbiFFb+jO
-60Qfp6d0KH7PKnxI1rmCQw24g4y2HyQ7cgT26mXQr3gsxj5bnRCKB9uG7DpJ1RaY
-QVvVUApFdIHnLExVjNynwvKaNMZNwb6HVPVfjUTwwPdSgLxTRU2xAAmkIrbFUPuP
-vhAbcmNKmq7hjr7AVHxNI4XnDwIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
+MjM0NDFaFw0zODAxMDExMjM0NDFaMB8xHTAbBgNVBAMTFHJldm9rZWQyLmV4YW1w
+bGUubmV0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDvSjA1Zo+EffOhSjyb
+7oyvoCD6rf0Qql8A35hH3wOQI7EfH084ZG8+otxUDKi/HeCnIpOFT7/wsh8VGCr4
+Zz0mCYhr6S/bvcloLBxtHeZKXiOdhxJ3YM795z8OaJLNzVxd/njcClo+4wdHSpqd
+IIjoWE4xB065onTeuORon2Xg5QIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
I4YhaHR0cDovL2NybC5leGFtcGxlLm5ldC9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5uZXQvMB8GA1Ud
-EQQYMBaCFHJldm9rZWQyLmV4YW1wbGUubmV0MA0GCSqGSIb3DQEBBQUAA4GBAGEv
-YIEr7x4/jtbVZHfcVk369td5KZdrozHyaZOAhluUX9Q3qHpWuubeBJ/GjiJkLMGC
-v5Px5F8yI0RQmQOOxeu4vINhL1dIbksPn7oxaWpPlx+40Tuub0qQlJYyPzXSYhv0
-dcScT5CK2e0GGzk7pEwT+S7WZNtFzeeOd6gOR9dE
+EQQYMBaCFHJldm9rZWQyLmV4YW1wbGUubmV0MA0GCSqGSIb3DQEBCwUAA4GBAGEf
+go4f68ipm2R/BSA5o+nLp1AP/wRiehG/TgywofRT4Ut16fPn6ppTWL8XteG6uV44
+JZa7p5YV8WAl0dbWndTXNVW85RIBE9Od93azVqg1fQELTuoXamgo+F81L+bCQvZk
+gkPJ+vDlYKdFDu4RFupRbPHD5weUoQFwrgWkmzC2
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDExWhcNMzgw\r
-MTAxMTIzNDExWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp\r
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCf/Mo\r
-cl7+ta84A85TdEcSPfv+JV6/0ynu98Z+EHaz221TGgNYkOtlBDc80kZZ2QBndE6e\r
-RZAuIaPgTVk0mZJ7XUxAVx7AAlGSWenScV/k/VChgqddRaCmmLQoPT/wUkrDqlOW\r
-7omdM0BTaMxdEv2QRyUCVrrZKOJkRsTILkUvaQIDAQABo1owWDAOBgNVHQ8BAf8E\r
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDQwWhcNMzgw\r
+MTAxMTIzNDQwWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp\r
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXxUua\r
+JOUjKYqtSZyRwCoF1o5VI5yr+sinPkKPpGQnFd28bani9yCcLdvvOVCBPBmBe3vJ\r
+sjRSu5YO3fGlE7dRbiUBCvmOtZ4Kk39mgQcThWp8R8Mxk//ex5BSLlw3q43BY3Om\r
++V59fPWaYgHKE/RIjneGJb97oa3AmxjvZcZXnQIDAQABo1owWDAOBgNVHQ8BAf8E\r
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw\r
-Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA\r
-P/kvw/kOJI5Yja+W8/xmbAma4NeAWE48eLDzp6AWJBUU7oIj4Ca+PqwpaxxeNioZ\r
-ihLL5LCRrS8lsSGgyD3UzqYGCMOwqX5pBytpWXz1NRzzey9mCV55LHckBF7dRBuh\r
-XQiz+EvE4Dr1ZikrB6UjgHW7Bal9Y5QMDs8qZAsRkJ0=
+Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA\r
+rPmUtgNXl5WO6GDheUimkO9DGTeKnk8n/Hwlm6KjqYfkaJuf1YTKD2bgqfsW4TQM\r
+uN/wZurB9sbZTdrPqqD+pS8xV8CloldkH4x3PtUz+0Z4Fkgf4IQG1GKI/OGu2Ego\r
+6UjWNb+M5nNokpzyV7bAslmTj6Q7CCVQuNSKGfOIJEc=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: revoked2.example.net
- localKeyID: 70 BF 9C CD 8D 0C AB 91 82 4D 75 C2 EF AF DC 82 97 0B 7D 55
+ localKeyID: FE 0B 1F 98 D3 E3 36 0D 3A 1B 60 F6 BF EA 95 48 9A A5 A9 F2
Key Attributes: <No Attributes>
-----BEGIN ENCRYPTED PRIVATE KEY-----
-MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIlFvWRNTHWPsCAggA
-MBQGCCqGSIb3DQMHBAgnEwmcCNcQrgSCAoDD+93FeCLH5UVzsfPd0zbfjfeEOZRe
-4JbFS5eKLYNG5yTN7sOfaP3gFoB1V7XnTzu1SO9IjXaOKUt/Nj/XOsppARGn91ec
-vHi5zyP+6irN6lpP8gaz2TTnpek/rdYHNd050+osef+c9u4nQEduCq8YWPjU0Y3F
-Q3C8yPKotiUxlAYEavdG7WFqn8Ir9dgwh6VlU9HOc8LJ9q/eSJ6O8Z0Jyf9AWuKd
-IMSY1251u8UoJePZgVmFfTt4q9tZVbb/i19veej8jS/um/pcYZd3WcEtRP3AE5Xh
-l7mkZS/H9USiFZRYRK89dICeohIy6Lwzzv9db0kLwtdWFQ43GNiCRIwa52SK9uYr
-/EGLyTUrI1gzOABqKoHTzQ5GZuG1OBRE7//gRYf7px2BtUyKEkTdhZo+XEMM9J7K
-NyVBZg/YO4WTxL5RsvJ8Asfdr6dXJ2FNE110jaRyb/JKB4AXYbLw4I4wwOdirozR
-mVFw6kMP0bVH2plQzntVokOW3p4M+betmQQgifD+mqWSrDSypZylkfrVaYKARiXe
-IKgcD7UsDpy9T1Fjmk08KdPDLpogdM+iUcO0/sZk+Eo+wRjjtcKeq4T2HX3Zjdcp
-eUMZ/1+1i+7jndpdTpLGXLVuR5S8xAw8cnkb8i0IO+lW4VGuJSSidkz/qxUqgTNw
-Ilgt4Ye+0W0uVJedherpWwImyiDjdHtLtkkOpt/CPS/QRxeF6raSHsbjp4uIZGor
-PNXAV5lWV+IIBHDIbIFOqcCQxJdKanWsEjkOXLLz254OGAB3vKZgWWorpsdpYMYI
-Tk1jTSJxjefwzLPx+mLAesOr//4EtFmll3Im+GYQAZw3btVm6GVrXrqQ
+MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQI2nx+Ck+hzRcCAggA
+MBQGCCqGSIb3DQMHBAib90v/PI3I3ASCAoAvxfAub/d3g2KatqhPvllYO4Wc06Ao
+IEya93YOz0Ku2winZE6acAypUSspBRZdAeUd2i/K+9TUmPU4EXsIk6gI5MUmQ00g
+cb8lcriKhM/eqKWVu/NlwWzNVGr34fd9LTMFNZCLpcFBtMIQHkqWB9Z9Ua0pb122
+OCHEkFDi0Cb1Mcg3yXSN6mNXBTpoUUHwzzOx5TwhT4FanN5ceAiDrRDrRbHJr9WY
+w8kXAR509NnWba7LDWA2dS7POof5BlqtCUuBarApoIOmDcgJh0n7CAkNgESycfQ3
+khaw5MccDaQXMMvzA7Os3mkap1WHhKrepp2KxWITN2ahAAvVxg5FIbjlP7CA4LKw
+H9KOJ6euVpe4yoiM7bkGpbyvKU7TWCirr9VyENgS5nO2Bt9IwPsNJnZEwn76sdl+
+Qq06pUm/CKMeXiP7QWKPfxy9bcwYf8hQ0PLcC45wiJhrflKdc6GTJigCC+UGmfEz
+HYnjjBTj5ZJSLYAfTGABvHgXSir9+2arIly81lm3RYDSe3d5CErOIBr4MXMAVWeG
+O1M3V0swMLhqPrhkrZ8ICtI7T5JrIbQ7YsjwKZIHtdR6ejrwF62tsD7qHmgcvmi8
+mNmx8NHHh9tS7dz42fNyoh8YrK+/OIhEN7TbI8FRvtZhAUyBYJjewLVj9hac4x13
+upIW2itPEdDPaO4aFhgvMhGEG1avUdmKAKM2gosGk2E5PYxOiQ87T5BDfkNlHgyA
+yW+GoVQtt24K3wrKM8udlwe75474A8sa/IlAqGsjKxqqIsjbGQ65daGymhVW4h4v
+id/la+9bBz+C6B9CDhW2RD0hHSOBM2H5GvzMtx5meJy8Wcj/Rk1yXSqC
-----END ENCRYPTED PRIVATE KEY-----
Bag Attributes
friendlyName: revoked2.example.net
- localKeyID: 70 BF 9C CD 8D 0C AB 91 82 4D 75 C2 EF AF DC 82 97 0B 7D 55
+ localKeyID: FE 0B 1F 98 D3 E3 36 0D 3A 1B 60 F6 BF EA 95 48 9A A5 A9 F2
subject=/CN=revoked2.example.net
issuer=/O=example.net/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICijCCAfOgAwIBAgICAMowDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhh
+MIICijCCAfOgAwIBAgICAMowDQYJKoZIhvcNAQELBQAwMzEUMBIGA1UEChMLZXhh
bXBsZS5uZXQxGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDEx
-MjM0MTNaFw0zODAxMDExMjM0MTNaMB8xHTAbBgNVBAMTFHJldm9rZWQyLmV4YW1w
-bGUubmV0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNFaI/6qFhbiFFb+jO
-60Qfp6d0KH7PKnxI1rmCQw24g4y2HyQ7cgT26mXQr3gsxj5bnRCKB9uG7DpJ1RaY
-QVvVUApFdIHnLExVjNynwvKaNMZNwb6HVPVfjUTwwPdSgLxTRU2xAAmkIrbFUPuP
-vhAbcmNKmq7hjr7AVHxNI4XnDwIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
+MjM0NDFaFw0zODAxMDExMjM0NDFaMB8xHTAbBgNVBAMTFHJldm9rZWQyLmV4YW1w
+bGUubmV0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDvSjA1Zo+EffOhSjyb
+7oyvoCD6rf0Qql8A35hH3wOQI7EfH084ZG8+otxUDKi/HeCnIpOFT7/wsh8VGCr4
+Zz0mCYhr6S/bvcloLBxtHeZKXiOdhxJ3YM795z8OaJLNzVxd/njcClo+4wdHSpqd
+IIjoWE4xB065onTeuORon2Xg5QIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
I4YhaHR0cDovL2NybC5leGFtcGxlLm5ldC9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5uZXQvMB8GA1Ud
-EQQYMBaCFHJldm9rZWQyLmV4YW1wbGUubmV0MA0GCSqGSIb3DQEBBQUAA4GBAGEv
-YIEr7x4/jtbVZHfcVk369td5KZdrozHyaZOAhluUX9Q3qHpWuubeBJ/GjiJkLMGC
-v5Px5F8yI0RQmQOOxeu4vINhL1dIbksPn7oxaWpPlx+40Tuub0qQlJYyPzXSYhv0
-dcScT5CK2e0GGzk7pEwT+S7WZNtFzeeOd6gOR9dE
+EQQYMBaCFHJldm9rZWQyLmV4YW1wbGUubmV0MA0GCSqGSIb3DQEBCwUAA4GBAGEf
+go4f68ipm2R/BSA5o+nLp1AP/wRiehG/TgywofRT4Ut16fPn6ppTWL8XteG6uV44
+JZa7p5YV8WAl0dbWndTXNVW85RIBE9Od93azVqg1fQELTuoXamgo+F81L+bCQvZk
+gkPJ+vDlYKdFDu4RFupRbPHD5weUoQFwrgWkmzC2
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
-MIICWwIBAAKBgQDNFaI/6qFhbiFFb+jO60Qfp6d0KH7PKnxI1rmCQw24g4y2HyQ7
-cgT26mXQr3gsxj5bnRCKB9uG7DpJ1RaYQVvVUApFdIHnLExVjNynwvKaNMZNwb6H
-VPVfjUTwwPdSgLxTRU2xAAmkIrbFUPuPvhAbcmNKmq7hjr7AVHxNI4XnDwIDAQAB
-AoGAFrP5ZSf9O4LsjfpIhHeI8BQoNnSxLQ/f+FRE7wWrRCzT6+lgonAJ2qeyI7r5
-C8PabVvi09Tw2WvXPAsp2CsMFks/Orjhlktx15VE9ClFoRxI0kkA0MIfGgF1TEzu
-sO2mZJQWF0t/Rq5oUs79xidmeb/Cu8Ij8Ly2Ac9DGV9JEzECQQD5ZOC9zivkFmL4
-7QVI4bhbE6gzBAY4xijdTHJfK6ccSwT2cHhwHb9qSIKQzTt2YQC7WRgduxeA85az
-j2G0Nna5AkEA0oRL1Ui8+YSiZ3TuFjbEEnCtU570UjZWP6UD93qoYYmuMtLMUbo0
-VjrFVUdynq1VtHJp7Uc+uMNqprcxJXnoBwJAD2h1HiTrv0bGzJxQNEWFz1KylJxO
-ChnsEmgTtN+Mjonv/43JUxvzZIygTHPxlYm+stR5UfTqKdRi3isgnTK0OQJAYGNQ
-sXRfikOvdH02chdbSTIsOkhih633aaatnUedByPaDc003grK4dyA894F3h9xSXDF
-jW38iu52y6S/LPCXSwJAGD8Su7ax9CO4CFW0giEU/km7JN0r7Y75CV+G/G8IqpJT
-uo9t2r23Y9HAnCSnw2/sPyXeYv9eeiqhL2VfLB95CA==
+MIICXgIBAAKBgQDvSjA1Zo+EffOhSjyb7oyvoCD6rf0Qql8A35hH3wOQI7EfH084
+ZG8+otxUDKi/HeCnIpOFT7/wsh8VGCr4Zz0mCYhr6S/bvcloLBxtHeZKXiOdhxJ3
+YM795z8OaJLNzVxd/njcClo+4wdHSpqdIIjoWE4xB065onTeuORon2Xg5QIDAQAB
+AoGBAONns8zr/PRC5mefr13ZJKY7HVxeQSO3ZbXkyEl1LWOsJ8WV8al7+SSjjZPq
+u+t0r2zmtR96HMTX4iYf46ZSJo7LDcJsPeYMBorrbmLUrKvNPhku/x0r0mxmPPZx
+YnkB2Qt0h+XttTm6YOeNmeYEP3LAGgNA6nkrYF/Ct08VRKyBAkEA+FpDsquwxjKi
+bS7fvQcIyS/afgRpCBu1pAxbOPuN1TLN2AqhUhF22s2EYc8UcbNwMTC00gtb6hdC
+xNnzzivsEQJBAPaoe5yXUAa4hcwbyMS212VQVUbS5j4AUTqA0XYSNHNuX3xIH+ny
+6RjpNyn+1zkAPMbW+IzWz86rk94tfEVky5UCQQDZakQLvWxjBl7VkIyEMg1J+1+e
+pIPCemeYtsyBZQ80jmZP9HZnnyxavkJfUecG5tyX45jYrOMJWtWz+U4Ltr3RAkAh
+UsXQdAjVv5wj5SUMnn8fKuk6dkew3K4cr0adIvx/E8xGqB/XpX+kY+2V+N3uz39m
+hahyrprImxmRDKgbX/C5AkEA1v2059LAiJeh7jtoQWNLwke8lWl+YNiKYwMdka8s
+/KV+99ihoonE4reSWHcOQve5CIB8q/P2mLuOyieLC0qBXw==
-----END RSA PRIVATE KEY-----
subject=/O=example.net/CN=clica Signing Cert
issuer=/O=example.net/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDExWhcNMzgw
-MTAxMTIzNDExWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCf/Mo
-cl7+ta84A85TdEcSPfv+JV6/0ynu98Z+EHaz221TGgNYkOtlBDc80kZZ2QBndE6e
-RZAuIaPgTVk0mZJ7XUxAVx7AAlGSWenScV/k/VChgqddRaCmmLQoPT/wUkrDqlOW
-7omdM0BTaMxdEv2QRyUCVrrZKOJkRsTILkUvaQIDAQABo1owWDAOBgNVHQ8BAf8E
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDQwWhcNMzgw
+MTAxMTIzNDQwWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXxUua
+JOUjKYqtSZyRwCoF1o5VI5yr+sinPkKPpGQnFd28bani9yCcLdvvOVCBPBmBe3vJ
+sjRSu5YO3fGlE7dRbiUBCvmOtZ4Kk39mgQcThWp8R8Mxk//ex5BSLlw3q43BY3Om
++V59fPWaYgHKE/RIjneGJb97oa3AmxjvZcZXnQIDAQABo1owWDAOBgNVHQ8BAf8E
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw
-Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA
-P/kvw/kOJI5Yja+W8/xmbAma4NeAWE48eLDzp6AWJBUU7oIj4Ca+PqwpaxxeNioZ
-ihLL5LCRrS8lsSGgyD3UzqYGCMOwqX5pBytpWXz1NRzzey9mCV55LHckBF7dRBuh
-XQiz+EvE4Dr1ZikrB6UjgHW7Bal9Y5QMDs8qZAsRkJ0=
+Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA
+rPmUtgNXl5WO6GDheUimkO9DGTeKnk8n/Hwlm6KjqYfkaJuf1YTKD2bgqfsW4TQM
+uN/wZurB9sbZTdrPqqD+pS8xV8CloldkH4x3PtUz+0Z4Fkgf4IQG1GKI/OGu2Ego
+6UjWNb+M5nNokpzyV7bAslmTj6Q7CCVQuNSKGfOIJEc=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: Certificate Authority
subject=/O=example.net/CN=clica CA
issuer=/O=example.net/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDExWhcNMzgw
-MTAxMTIzNDExWjApMRQwEgYDVQQKEwtleGFtcGxlLm5ldDERMA8GA1UEAxMIY2xp
-Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALUSMNgU8YE8fsiB8Wm7
-lpclDOwQXJVbP/Ef2NVwoE6NnoPTWMNgvSyCddVz7709URkIy+jtrlpbyQYVdwgO
-HAnI8/bx2WoGtGzWTbAM1Mp+WHtiOO7LpsldWQmeHuF9uBOghFytVyqNT2l/iG7x
-XQCA6Q6P59vpb3Z+4PH8kgVlAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
-DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBACs6X9bwml5hcwf82pyb
-bKOnRGP6pJsvx1yv6SULaxg4+mCelEHNPycQqidqs+84RrDma8Kkz3DVZuV11Yca
-o2ibon7rWhaTc9SR0j5B8BMU1Z9VEVF5uejepHWf1iCeOhxl6tNQuTTJP0uE4h6h
-VAtQ+ux57x052IuOi9FtrqVR
------END CERTIFICATE-----
-Bag Attributes
- friendlyName: server1.example.net
- localKeyID: EF E6 02 06 86 D6 C6 E5 49 FA 05 3D AA 45 2E FE A4 7E 79 E6
-subject=/CN=server1.example.net
-issuer=/O=example.net/CN=clica Signing Cert
------BEGIN CERTIFICATE-----
-MIIC0DCCAjmgAwIBAgIBZTANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt
-cGxlLm5ldDEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
-MzQxMloXDTM4MDEwMTEyMzQxMlowHjEcMBoGA1UEAxMTc2VydmVyMS5leGFtcGxl
-Lm5ldDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzQuAXxpDWTI5zD1RqQJb
-TzdmdFsB2Y2IXMhnysg54lBGKV4pMhglVjJUNhDCqkmops0RvIYdSLjMPsvharvx
-93lNsVWn7d0rw7GS8sX/dNzUArJITOeyGFHoVK2FOgILdtmJrb9s79WweYc77VOb
-R3TmqCFuDfesYmoRcRkW0KcCAwEAAaOCAQcwggEDMA4GA1UdDwEB/wQEAwIE8DAg
-BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
-I4YhaHR0cDovL2NybC5leGFtcGxlLm5ldC9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
-BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5uZXQvMGUGA1Ud
-EQReMFyCImFsdGVybmF0ZW5hbWUyLnNlcnZlcjEuZXhhbXBsZS5uZXSCE3NlcnZl
-cjEuZXhhbXBsZS5uZXSCIWFsdGVybmF0ZW5hbWUuc2VydmVyMS5leGFtcGxlLm5l
-dDANBgkqhkiG9w0BAQUFAAOBgQAyeEckORsshBm4i97WDwuAi3VNbUcXDNSflE5u
-hTPKZnwVNUgvt62XGy35hzI1lUNom7UzuA71T9RLza65d9s70YEfWqjqurp0Fh/a
-qWILyzSdOYHPaQlvp0qqoGNY6MKHylEVfGFvAH0qgF5bTzitwp7YOmKVyVSdYsGQ
-MyjouQ==
+MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDQwWhcNMzgw
+MTAxMTIzNDQwWjApMRQwEgYDVQQKEwtleGFtcGxlLm5ldDERMA8GA1UEAxMIY2xp
+Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOY7eAp9lkZsBxaHMAn5
+1zK898gr+Yxq+Vxgi6sXXmhsq20D/qHjVsKakEQtQLdBc3di6kRPURWiHrVqwQ+t
+RIpR1pQXqoaPmVf11aCvS3pEUaBreO+LQ3CJImrS887XIrGPDuuYuTaKrChtcMPN
+idZRKhwJAajAVJvivdDv6ucHAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
+DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBABVCocYnR8xCX0k6HVaW
+RX+SAucii+m4sX6TJ/yWjNvQjKxrs3gwe19yOJB0WCOQKqU2s7UhxovW39qD4q60
+dSKq+qjW/4DfLmi1d/5aMqAq9au/s7W9Ut/jqqdL5eY31lxWRyW+D+29mfRyl+B7
+H0+wMSKs4DNtTYYEd+3W8kEw
-----END CERTIFICATE-----
--- /dev/null
+Bag Attributes
+ friendlyName: server1.example.net
+ localKeyID: 0F 3A 98 3F 6C EA 09 B2 7B 0C 1F 02 79 4C EF 58 24 6D 16 95
+subject=/CN=server1.example.net
+issuer=/O=example.net/CN=clica Signing Cert
+-----BEGIN CERTIFICATE-----
+MIIC2zCCAkSgAwIBAgIBZTANBgkqhkiG9w0BAQsFADAzMRQwEgYDVQQKEwtleGFt
+cGxlLm5ldDEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
+MzQ0MFoXDTM4MDEwMTEyMzQ0MFowHjEcMBoGA1UEAxMTc2VydmVyMS5leGFtcGxl
+Lm5ldDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqqPsme1TMZTe3IZgxUO4
+4zwa2iRWX8cL6d/HthFf+YXmaa+5MImRT6sqnWdsmSQKQbd8SvoW2+xgbxqjDHX1
+bcprcYn7QjviIIY0B3ZvuMf5E+9Tt2jnJRoO3SFX5i0pNWrIggMeDBP9lG5/k3zr
+B7kb9RXQoVBB3jwd9Ya3s/kCAwEAAaOCARIwggEOMA4GA1UdDwEB/wQEAwIE8DAg
+BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
+I4YhaHR0cDovL2NybC5leGFtcGxlLm5ldC9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
+BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5uZXQvMHAGA1Ud
+EQRpMGeCE3NlcnZlcjEuZXhhbXBsZS5uZXSCCSoudGVzdC5leIIiYWx0ZXJuYXRl
+bmFtZTIuc2VydmVyMS5leGFtcGxlLm5ldIIhYWx0ZXJuYXRlbmFtZS5zZXJ2ZXIx
+LmV4YW1wbGUubmV0MA0GCSqGSIb3DQEBCwUAA4GBAI7UXdoBXL/J3vsxnfwD0V31
+aHIturNL8/Xy8IJEf3Vp0L1wI6KKZIv0pkEhT1VGBOoZLZSKscjmniglLsulOzMh
+ADhe6HDw0QoLzPY5ED2nbNUVu0baf+Ns8m3VCdp7NtWL+9q2/Cxsa6qH1gxKWhfQ
+7HRyQbf5f81gLhZlRnnK
+-----END CERTIFICATE-----
+Bag Attributes
+ friendlyName: Signing Cert
+subject=/O=example.net/CN=clica Signing Cert
+issuer=/O=example.net/CN=clica CA
+-----BEGIN CERTIFICATE-----
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDQwWhcNMzgw
+MTAxMTIzNDQwWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXxUua
+JOUjKYqtSZyRwCoF1o5VI5yr+sinPkKPpGQnFd28bani9yCcLdvvOVCBPBmBe3vJ
+sjRSu5YO3fGlE7dRbiUBCvmOtZ4Kk39mgQcThWp8R8Mxk//ex5BSLlw3q43BY3Om
++V59fPWaYgHKE/RIjneGJb97oa3AmxjvZcZXnQIDAQABo1owWDAOBgNVHQ8BAf8E
+BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw
+Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA
+rPmUtgNXl5WO6GDheUimkO9DGTeKnk8n/Hwlm6KjqYfkaJuf1YTKD2bgqfsW4TQM
+uN/wZurB9sbZTdrPqqD+pS8xV8CloldkH4x3PtUz+0Z4Fkgf4IQG1GKI/OGu2Ego
+6UjWNb+M5nNokpzyV7bAslmTj6Q7CCVQuNSKGfOIJEc=
+-----END CERTIFICATE-----
+Bag Attributes
+ friendlyName: Certificate Authority
+subject=/O=example.net/CN=clica CA
+issuer=/O=example.net/CN=clica CA
+-----BEGIN CERTIFICATE-----
+MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDQwWhcNMzgw
+MTAxMTIzNDQwWjApMRQwEgYDVQQKEwtleGFtcGxlLm5ldDERMA8GA1UEAxMIY2xp
+Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOY7eAp9lkZsBxaHMAn5
+1zK898gr+Yxq+Vxgi6sXXmhsq20D/qHjVsKakEQtQLdBc3di6kRPURWiHrVqwQ+t
+RIpR1pQXqoaPmVf11aCvS3pEUaBreO+LQ3CJImrS887XIrGPDuuYuTaKrChtcMPN
+idZRKhwJAajAVJvivdDv6ucHAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
+DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBABVCocYnR8xCX0k6HVaW
+RX+SAucii+m4sX6TJ/yWjNvQjKxrs3gwe19yOJB0WCOQKqU2s7UhxovW39qD4q60
+dSKq+qjW/4DfLmi1d/5aMqAq9au/s7W9Ut/jqqdL5eY31lxWRyW+D+29mfRyl+B7
+H0+wMSKs4DNtTYYEd+3W8kEw
+-----END CERTIFICATE-----
Bag Attributes
friendlyName: server1.example.net
- localKeyID: EF E6 02 06 86 D6 C6 E5 49 FA 05 3D AA 45 2E FE A4 7E 79 E6
+ localKeyID: 0F 3A 98 3F 6C EA 09 B2 7B 0C 1F 02 79 4C EF 58 24 6D 16 95
subject=/CN=server1.example.net
issuer=/O=example.net/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIIC0DCCAjmgAwIBAgIBZTANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt
+MIIC2zCCAkSgAwIBAgIBZTANBgkqhkiG9w0BAQsFADAzMRQwEgYDVQQKEwtleGFt
cGxlLm5ldDEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
-MzQxMloXDTM4MDEwMTEyMzQxMlowHjEcMBoGA1UEAxMTc2VydmVyMS5leGFtcGxl
-Lm5ldDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzQuAXxpDWTI5zD1RqQJb
-TzdmdFsB2Y2IXMhnysg54lBGKV4pMhglVjJUNhDCqkmops0RvIYdSLjMPsvharvx
-93lNsVWn7d0rw7GS8sX/dNzUArJITOeyGFHoVK2FOgILdtmJrb9s79WweYc77VOb
-R3TmqCFuDfesYmoRcRkW0KcCAwEAAaOCAQcwggEDMA4GA1UdDwEB/wQEAwIE8DAg
+MzQ0MFoXDTM4MDEwMTEyMzQ0MFowHjEcMBoGA1UEAxMTc2VydmVyMS5leGFtcGxl
+Lm5ldDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqqPsme1TMZTe3IZgxUO4
+4zwa2iRWX8cL6d/HthFf+YXmaa+5MImRT6sqnWdsmSQKQbd8SvoW2+xgbxqjDHX1
+bcprcYn7QjviIIY0B3ZvuMf5E+9Tt2jnJRoO3SFX5i0pNWrIggMeDBP9lG5/k3zr
+B7kb9RXQoVBB3jwd9Ya3s/kCAwEAAaOCARIwggEOMA4GA1UdDwEB/wQEAwIE8DAg
BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
I4YhaHR0cDovL2NybC5leGFtcGxlLm5ldC9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
-BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5uZXQvMGUGA1Ud
-EQReMFyCImFsdGVybmF0ZW5hbWUyLnNlcnZlcjEuZXhhbXBsZS5uZXSCE3NlcnZl
-cjEuZXhhbXBsZS5uZXSCIWFsdGVybmF0ZW5hbWUuc2VydmVyMS5leGFtcGxlLm5l
-dDANBgkqhkiG9w0BAQUFAAOBgQAyeEckORsshBm4i97WDwuAi3VNbUcXDNSflE5u
-hTPKZnwVNUgvt62XGy35hzI1lUNom7UzuA71T9RLza65d9s70YEfWqjqurp0Fh/a
-qWILyzSdOYHPaQlvp0qqoGNY6MKHylEVfGFvAH0qgF5bTzitwp7YOmKVyVSdYsGQ
-MyjouQ==
+BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5uZXQvMHAGA1Ud
+EQRpMGeCE3NlcnZlcjEuZXhhbXBsZS5uZXSCCSoudGVzdC5leIIiYWx0ZXJuYXRl
+bmFtZTIuc2VydmVyMS5leGFtcGxlLm5ldIIhYWx0ZXJuYXRlbmFtZS5zZXJ2ZXIx
+LmV4YW1wbGUubmV0MA0GCSqGSIb3DQEBCwUAA4GBAI7UXdoBXL/J3vsxnfwD0V31
+aHIturNL8/Xy8IJEf3Vp0L1wI6KKZIv0pkEhT1VGBOoZLZSKscjmniglLsulOzMh
+ADhe6HDw0QoLzPY5ED2nbNUVu0baf+Ns8m3VCdp7NtWL+9q2/Cxsa6qH1gxKWhfQ
+7HRyQbf5f81gLhZlRnnK
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDExWhcNMzgw\r
-MTAxMTIzNDExWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp\r
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCf/Mo\r
-cl7+ta84A85TdEcSPfv+JV6/0ynu98Z+EHaz221TGgNYkOtlBDc80kZZ2QBndE6e\r
-RZAuIaPgTVk0mZJ7XUxAVx7AAlGSWenScV/k/VChgqddRaCmmLQoPT/wUkrDqlOW\r
-7omdM0BTaMxdEv2QRyUCVrrZKOJkRsTILkUvaQIDAQABo1owWDAOBgNVHQ8BAf8E\r
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDQwWhcNMzgw\r
+MTAxMTIzNDQwWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp\r
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXxUua\r
+JOUjKYqtSZyRwCoF1o5VI5yr+sinPkKPpGQnFd28bani9yCcLdvvOVCBPBmBe3vJ\r
+sjRSu5YO3fGlE7dRbiUBCvmOtZ4Kk39mgQcThWp8R8Mxk//ex5BSLlw3q43BY3Om\r
++V59fPWaYgHKE/RIjneGJb97oa3AmxjvZcZXnQIDAQABo1owWDAOBgNVHQ8BAf8E\r
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw\r
-Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA\r
-P/kvw/kOJI5Yja+W8/xmbAma4NeAWE48eLDzp6AWJBUU7oIj4Ca+PqwpaxxeNioZ\r
-ihLL5LCRrS8lsSGgyD3UzqYGCMOwqX5pBytpWXz1NRzzey9mCV55LHckBF7dRBuh\r
-XQiz+EvE4Dr1ZikrB6UjgHW7Bal9Y5QMDs8qZAsRkJ0=
+Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA\r
+rPmUtgNXl5WO6GDheUimkO9DGTeKnk8n/Hwlm6KjqYfkaJuf1YTKD2bgqfsW4TQM\r
+uN/wZurB9sbZTdrPqqD+pS8xV8CloldkH4x3PtUz+0Z4Fkgf4IQG1GKI/OGu2Ego\r
+6UjWNb+M5nNokpzyV7bAslmTj6Q7CCVQuNSKGfOIJEc=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: server1.example.net
- localKeyID: EF E6 02 06 86 D6 C6 E5 49 FA 05 3D AA 45 2E FE A4 7E 79 E6
+ localKeyID: 0F 3A 98 3F 6C EA 09 B2 7B 0C 1F 02 79 4C EF 58 24 6D 16 95
Key Attributes: <No Attributes>
-----BEGIN ENCRYPTED PRIVATE KEY-----
-MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIbTjOvT/3UgUCAggA
-MBQGCCqGSIb3DQMHBAiB4UitE/+LGwSCAoBtoxcf7PnMIhZKauwym1cVW1HTAGoW
-9RRdtk4Ymp0nZP851hKGg8DFxCLRDX2rAsSS15Rro3O3aaYLFvn/nFvgCypMYj/i
-vI3feiLCg2Z2n2nIfB7iFbOvdRd6EKh3ctbQGYSWTHIHcAqINMY9wsw42LzOTvNj
-TfoFZSVHVfaMC1jx3Y1lEYdqMub7DcugLOYYJAuW5gyivMgiklMzLlrPGbUCwrvq
-aJAPwd1GECTFusUCe0Vhwt2eq7p0Zub2pCpS5j1fOLoFZ89keB8Y6MxmBA3SMm73
-evMJXmCcymD2ZHAYRbogT/3U7F73ubn48kmfZTNwcBryBauo1ZVatQE/d8iYJeke
-q2i8ttUvTQ0nz33s/4v+rmJFfv4VkbljYc8rl/WvFKszLi5DtPcrd2klSORFVHRD
-xEie/EU7V4oiYA9SznzgcEfqGU64ep49hhxTsTRwhkGfKoM6C1OeCFho2Vv3uWNs
-sBWGU1+wh71jZAlhYxIRRxI7TK33fHDwWfaCZq3IfTToRtFzwbvjmXOcLrQD3zzw
-Mc0FVFaBHgrZMWy9cKAXJANGHXCtK0IBZ7f7wyGtJDzbFOp2JgrZhOCzzHrBAsnW
-PVALnVgLY6ydculgm0l4h4idToFfYIX7C6M5YRv0SsQ+uzZfOEpjP9BNOe+A3mTF
-1Z5cO7Y8jPDZGV0WsdmitX4Me1+l359lRNER7hJKOi9Py/YCwGxxd037cwunEWGG
-bWb2BKURho/r2iZcGL7PLLyRW5CKmV6qQVumlJSIFXcCenR3uSoJEvEzpwZ19KYb
-rH/IRcVkOd2leegIu9cSt5unYAVAZJ6CX5SplI5+5RoNEaIvTevQ3MGi
+MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIKthpSMz4bFMCAggA
+MBQGCCqGSIb3DQMHBAi/D50+VZ7OhwSCAoBMBjTIbaAT0eoRqHJsl599iG0RCiE9
+ZTwYbR6zg9r03dxY3ZG4V4TG1cXS1Z8czBYqmmegSmtwXnKgJcycE0JihfwE0WVN
+182NmWdVLWMwAiKhYchm9kiBWNb2+zs3d/jdU038/d9kOqff0+fMMChINHvZaJHL
+ceEbfjvmge2NNfu0bHh7shY09vqHr9ebunZq3/z5q+wx/GbZs91nD6UPx+Mexgxs
+I2WDTdj9fgzkSFlldTCGMiwXzDxmE1imP/qW8Dke3o5nEvIHCR/PCfI33irJ/MBB
+AOQpa/KaviJkfc16TonOHq8TF4qRLoan6ykP3zBNYxKtacDuYLgnRoUicHuT3Iqp
+g9vzoQ1/YrbFEVaPt1VzB8JYLhsRE9bfsM+MtKlQ1QCUPmWoRhwqxAtu8UX8adIA
+UfLkoHa9G4jm6p01/6YvT4kxu7CiMeBfmOMoGt1kYgCbF8gey8GLYKPFccDPZmW6
+JjD3DwAmKXxw80tl1lkJydMyfl/BWlBRmcU//k4l1VK0DYOm8OQ20P7UOpiarkUm
+Dfadmyp4Osx/Y8QjmiDY7vLg4won/Bn7J5vjwvcard+4GyATUCw6VHE9YzoWp1wa
+d+9Cl92s8k9Z8GcbEc7SgdBbM/rC/zXI4QlVZkEc7AWFKYa9ttTeQ05U28heliL4
+klFECxzMdrZHeWgg/EPNlUAZkW9ZyZsO5qeKMlQxZWXh/D+n0rcZ+caXxqoY+FCu
+LCAUu1yj+pUbpTCFHtycfdDWQfjr6F+1V3Zu6nAFBgwTqvl9Jd17L6ffSHi5CFSO
+V99DfRpSoBP/VE4zV0wqRHl4b8R/3Vamc8bwHuAVCKtRMUx+iiK7u2lp
-----END ENCRYPTED PRIVATE KEY-----
Bag Attributes
friendlyName: server1.example.net
- localKeyID: EF E6 02 06 86 D6 C6 E5 49 FA 05 3D AA 45 2E FE A4 7E 79 E6
+ localKeyID: 0F 3A 98 3F 6C EA 09 B2 7B 0C 1F 02 79 4C EF 58 24 6D 16 95
subject=/CN=server1.example.net
issuer=/O=example.net/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIIC0DCCAjmgAwIBAgIBZTANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt
+MIIC2zCCAkSgAwIBAgIBZTANBgkqhkiG9w0BAQsFADAzMRQwEgYDVQQKEwtleGFt
cGxlLm5ldDEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
-MzQxMloXDTM4MDEwMTEyMzQxMlowHjEcMBoGA1UEAxMTc2VydmVyMS5leGFtcGxl
-Lm5ldDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzQuAXxpDWTI5zD1RqQJb
-TzdmdFsB2Y2IXMhnysg54lBGKV4pMhglVjJUNhDCqkmops0RvIYdSLjMPsvharvx
-93lNsVWn7d0rw7GS8sX/dNzUArJITOeyGFHoVK2FOgILdtmJrb9s79WweYc77VOb
-R3TmqCFuDfesYmoRcRkW0KcCAwEAAaOCAQcwggEDMA4GA1UdDwEB/wQEAwIE8DAg
+MzQ0MFoXDTM4MDEwMTEyMzQ0MFowHjEcMBoGA1UEAxMTc2VydmVyMS5leGFtcGxl
+Lm5ldDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqqPsme1TMZTe3IZgxUO4
+4zwa2iRWX8cL6d/HthFf+YXmaa+5MImRT6sqnWdsmSQKQbd8SvoW2+xgbxqjDHX1
+bcprcYn7QjviIIY0B3ZvuMf5E+9Tt2jnJRoO3SFX5i0pNWrIggMeDBP9lG5/k3zr
+B7kb9RXQoVBB3jwd9Ya3s/kCAwEAAaOCARIwggEOMA4GA1UdDwEB/wQEAwIE8DAg
BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
I4YhaHR0cDovL2NybC5leGFtcGxlLm5ldC9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
-BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5uZXQvMGUGA1Ud
-EQReMFyCImFsdGVybmF0ZW5hbWUyLnNlcnZlcjEuZXhhbXBsZS5uZXSCE3NlcnZl
-cjEuZXhhbXBsZS5uZXSCIWFsdGVybmF0ZW5hbWUuc2VydmVyMS5leGFtcGxlLm5l
-dDANBgkqhkiG9w0BAQUFAAOBgQAyeEckORsshBm4i97WDwuAi3VNbUcXDNSflE5u
-hTPKZnwVNUgvt62XGy35hzI1lUNom7UzuA71T9RLza65d9s70YEfWqjqurp0Fh/a
-qWILyzSdOYHPaQlvp0qqoGNY6MKHylEVfGFvAH0qgF5bTzitwp7YOmKVyVSdYsGQ
-MyjouQ==
+BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5uZXQvMHAGA1Ud
+EQRpMGeCE3NlcnZlcjEuZXhhbXBsZS5uZXSCCSoudGVzdC5leIIiYWx0ZXJuYXRl
+bmFtZTIuc2VydmVyMS5leGFtcGxlLm5ldIIhYWx0ZXJuYXRlbmFtZS5zZXJ2ZXIx
+LmV4YW1wbGUubmV0MA0GCSqGSIb3DQEBCwUAA4GBAI7UXdoBXL/J3vsxnfwD0V31
+aHIturNL8/Xy8IJEf3Vp0L1wI6KKZIv0pkEhT1VGBOoZLZSKscjmniglLsulOzMh
+ADhe6HDw0QoLzPY5ED2nbNUVu0baf+Ns8m3VCdp7NtWL+9q2/Cxsa6qH1gxKWhfQ
+7HRyQbf5f81gLhZlRnnK
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
-MIICXgIBAAKBgQDNC4BfGkNZMjnMPVGpAltPN2Z0WwHZjYhcyGfKyDniUEYpXiky
-GCVWMlQ2EMKqSaimzRG8hh1IuMw+y+Fqu/H3eU2xVaft3SvDsZLyxf903NQCskhM
-57IYUehUrYU6Agt22Ymtv2zv1bB5hzvtU5tHdOaoIW4N96xiahFxGRbQpwIDAQAB
-AoGAQ+VME7G5nV6BPv0K/kDWhWud1GeSPDyea8K8g6w7ZpIYOXiBgaH3MwylT+XK
-3+JWIy2Ccv+h0MPIdf7C3LnxS92aLrL5ur8e4kgU/rhQAFWiPFV1ulESlmZ8CbgT
-o/eWMut0Qtlj98q2PIfLB+EvR7hrBL4EfGEO4GeMafTzvRkCQQD6obmU4DOkU3xt
-drR+lRzfleBXI4DZXryLJLCN6Q6tu+cTp4ViKhoTD8ys+VJU2Y9xh/XfFYhNkrJr
-GY8NF1X9AkEA0W/QGj3BsO1+8mQxkf9UCqkeaGD/jQXxaqaGQ8M9R/46sAKeW+IN
-g+R6z4fF98t2x/D2LBs4ynGgWToXhFbwcwJBALfn3b4xOZOVsxK7bLwJfHNPjZtD
-MPPPgTf0hxzKa3vuCiQw4z3huNpN2JkAJXqfXZMn+bFlImwRfZv62C359p0CQQCG
-GEos0we16YoTVlVqvgkoPjoK6LgWqgx1laN3tYUCGGOpGDQebnDq1ppPUAZP7sTh
-pYVonhFRhUj+eDRgdm3DAkEAhEl0G7wNvhiA1KR7Wz4lhZGj5rQnL0qgNjlIC/Wa
-EobRaD0Gz6v+jHOH2ePYQWXu7ySiIoUDwtI8n1r1ePCRFw==
+MIICWwIBAAKBgQCqo+yZ7VMxlN7chmDFQ7jjPBraJFZfxwvp38e2EV/5heZpr7kw
+iZFPqyqdZ2yZJApBt3xK+hbb7GBvGqMMdfVtymtxiftCO+IghjQHdm+4x/kT71O3
+aOclGg7dIVfmLSk1asiCAx4ME/2Ubn+TfOsHuRv1FdChUEHePB31hrez+QIDAQAB
+AoGAL8qXcokAeut5+4N7SORtvN7RmnUA5/REhu0Q7xIwsh7paII5uLlexFRpLAqS
+ZNWuNbehDRK8Ij4yyAtKzSugX/ls6wVy+Vtf0sInU92EGdjwofIB1ajQgJ9zYw+A
+8Z2Rxa90TQoqkhgY99mH8sfjWzZdIFsfTaCRRvewRlfJDQECQQDV8W2QzxfZx4tE
+ZLKxULaElSYm1QM3siSyDB6plp/hUTWwQ0zfaz8sZbzESfabFd2SX6yVg0jQKUxG
+vQhPhNehAkEAzC9O7yUDbIim8T/7ZhmCMy1TzDU8I9fphQjcFEGEWpu+Yg3B3BXS
+Uh7hJ+r9v1bmUPZ18AJ3iNsq1W+uqWudWQJAHjgY2tB1tPw7jrCOkP8umLGcjvWd
+m7tc9Y1Cs3+kG6Zl5/zJmfFDHhlMvYkY/TTsdCVxcjj2CvkaXg+LYfgIoQJAN5my
+TuCvXACiJROdK6JKmBEBvpvIcqI6zqUo+MMWfW3nm9/PKFUw3nfWK/6Ldmz9bpKO
+bvrc/gFgWpp831mUkQJALrDFsFFr0xo+wkxBZgL0ijiIvHGLy4UaVU84QUqGU5pb
+NHOKni8utK8KSNY3j58ZCGxOcLBWSDnjZmKYdnfFiA==
-----END RSA PRIVATE KEY-----
subject=/O=example.net/CN=clica Signing Cert
issuer=/O=example.net/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDExWhcNMzgw
-MTAxMTIzNDExWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCf/Mo
-cl7+ta84A85TdEcSPfv+JV6/0ynu98Z+EHaz221TGgNYkOtlBDc80kZZ2QBndE6e
-RZAuIaPgTVk0mZJ7XUxAVx7AAlGSWenScV/k/VChgqddRaCmmLQoPT/wUkrDqlOW
-7omdM0BTaMxdEv2QRyUCVrrZKOJkRsTILkUvaQIDAQABo1owWDAOBgNVHQ8BAf8E
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDQwWhcNMzgw
+MTAxMTIzNDQwWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXxUua
+JOUjKYqtSZyRwCoF1o5VI5yr+sinPkKPpGQnFd28bani9yCcLdvvOVCBPBmBe3vJ
+sjRSu5YO3fGlE7dRbiUBCvmOtZ4Kk39mgQcThWp8R8Mxk//ex5BSLlw3q43BY3Om
++V59fPWaYgHKE/RIjneGJb97oa3AmxjvZcZXnQIDAQABo1owWDAOBgNVHQ8BAf8E
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw
-Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA
-P/kvw/kOJI5Yja+W8/xmbAma4NeAWE48eLDzp6AWJBUU7oIj4Ca+PqwpaxxeNioZ
-ihLL5LCRrS8lsSGgyD3UzqYGCMOwqX5pBytpWXz1NRzzey9mCV55LHckBF7dRBuh
-XQiz+EvE4Dr1ZikrB6UjgHW7Bal9Y5QMDs8qZAsRkJ0=
+Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA
+rPmUtgNXl5WO6GDheUimkO9DGTeKnk8n/Hwlm6KjqYfkaJuf1YTKD2bgqfsW4TQM
+uN/wZurB9sbZTdrPqqD+pS8xV8CloldkH4x3PtUz+0Z4Fkgf4IQG1GKI/OGu2Ego
+6UjWNb+M5nNokpzyV7bAslmTj6Q7CCVQuNSKGfOIJEc=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: Certificate Authority
subject=/O=example.net/CN=clica CA
issuer=/O=example.net/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDExWhcNMzgw
-MTAxMTIzNDExWjApMRQwEgYDVQQKEwtleGFtcGxlLm5ldDERMA8GA1UEAxMIY2xp
-Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALUSMNgU8YE8fsiB8Wm7
-lpclDOwQXJVbP/Ef2NVwoE6NnoPTWMNgvSyCddVz7709URkIy+jtrlpbyQYVdwgO
-HAnI8/bx2WoGtGzWTbAM1Mp+WHtiOO7LpsldWQmeHuF9uBOghFytVyqNT2l/iG7x
-XQCA6Q6P59vpb3Z+4PH8kgVlAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
-DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBACs6X9bwml5hcwf82pyb
-bKOnRGP6pJsvx1yv6SULaxg4+mCelEHNPycQqidqs+84RrDma8Kkz3DVZuV11Yca
-o2ibon7rWhaTc9SR0j5B8BMU1Z9VEVF5uejepHWf1iCeOhxl6tNQuTTJP0uE4h6h
-VAtQ+ux57x052IuOi9FtrqVR
------END CERTIFICATE-----
-Bag Attributes
- friendlyName: server2.example.net
- localKeyID: A4 A7 36 66 9C 5A FC 72 B7 08 6B 0B 9F 20 62 78 D8 DF 1D 98
-subject=/CN=server2.example.net
-issuer=/O=example.net/CN=clica Signing Cert
------BEGIN CERTIFICATE-----
-MIICiDCCAfGgAwIBAgICAMkwDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhh
-bXBsZS5uZXQxGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDEx
-MjM0MTNaFw0zODAxMDExMjM0MTNaMB4xHDAaBgNVBAMTE3NlcnZlcjIuZXhhbXBs
-ZS5uZXQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALwP/FMqk/TKRQWwWsmz
-rt0QEKGC8M+3ot5LrXijR1RD9DTSSCDB6tI9J4s3rpM8jYZN2in/844/zHaZPHLe
-sM5/YLBWQD0YGy6eJUA+Ym/ySV0VTVZTwHwC78TvjETq1BRvi9fTNBp5P5CBN08L
-7QA5ebrmrLdpUNmjSRXqQc6ZAgMBAAGjgb8wgbwwDgYDVR0PAQH/BAQDAgTwMCAG
-A1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAj
-hiFodHRwOi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEE
-KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLm5ldC8wHgYDVR0R
-BBcwFYITc2VydmVyMi5leGFtcGxlLm5ldDANBgkqhkiG9w0BAQUFAAOBgQAO/PIL
-r1x6F86iuKP1ww7Gb/fG9KoRVdijXvwFKurrTGLlK9gq0+w+j+vxMIBW+UeeXpRt
-JY/231AhPwxvMR4/MYQLrZUmtYO/FCIIdkjDFkt4wGszxEYSn5Ks94PftsJGrEm2
-yjc1w7gnzx2ybtYRZnpaTgOaWaYepc6wnfXXvw==
+MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDQwWhcNMzgw
+MTAxMTIzNDQwWjApMRQwEgYDVQQKEwtleGFtcGxlLm5ldDERMA8GA1UEAxMIY2xp
+Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOY7eAp9lkZsBxaHMAn5
+1zK898gr+Yxq+Vxgi6sXXmhsq20D/qHjVsKakEQtQLdBc3di6kRPURWiHrVqwQ+t
+RIpR1pQXqoaPmVf11aCvS3pEUaBreO+LQ3CJImrS887XIrGPDuuYuTaKrChtcMPN
+idZRKhwJAajAVJvivdDv6ucHAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
+DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBABVCocYnR8xCX0k6HVaW
+RX+SAucii+m4sX6TJ/yWjNvQjKxrs3gwe19yOJB0WCOQKqU2s7UhxovW39qD4q60
+dSKq+qjW/4DfLmi1d/5aMqAq9au/s7W9Ut/jqqdL5eY31lxWRyW+D+29mfRyl+B7
+H0+wMSKs4DNtTYYEd+3W8kEw
-----END CERTIFICATE-----
Bag Attributes
friendlyName: server2.example.net
- localKeyID: A4 A7 36 66 9C 5A FC 72 B7 08 6B 0B 9F 20 62 78 D8 DF 1D 98
+ localKeyID: 9E DB 1F 81 35 7E 72 8A 0E E8 A7 29 2D C8 AA 4F 47 9E 4E FC
subject=/CN=server2.example.net
issuer=/O=example.net/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICiDCCAfGgAwIBAgICAMkwDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhh
+MIICiDCCAfGgAwIBAgICAMkwDQYJKoZIhvcNAQELBQAwMzEUMBIGA1UEChMLZXhh
bXBsZS5uZXQxGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDEx
-MjM0MTNaFw0zODAxMDExMjM0MTNaMB4xHDAaBgNVBAMTE3NlcnZlcjIuZXhhbXBs
-ZS5uZXQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALwP/FMqk/TKRQWwWsmz
-rt0QEKGC8M+3ot5LrXijR1RD9DTSSCDB6tI9J4s3rpM8jYZN2in/844/zHaZPHLe
-sM5/YLBWQD0YGy6eJUA+Ym/ySV0VTVZTwHwC78TvjETq1BRvi9fTNBp5P5CBN08L
-7QA5ebrmrLdpUNmjSRXqQc6ZAgMBAAGjgb8wgbwwDgYDVR0PAQH/BAQDAgTwMCAG
+MjM0NDFaFw0zODAxMDExMjM0NDFaMB4xHDAaBgNVBAMTE3NlcnZlcjIuZXhhbXBs
+ZS5uZXQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmz1Pq2JS+nTg2NgpEt
+n1L6c6OLq1waIWdH1PrsaXwz0sjAp6l5xjLIHau+0Jbeg4CkkYNYLWFcFlrhzry5
+kTsoBhwhJKsanY3fe7t4iKIxCtiX1YqoxC/+4vEpszdHnT4Io3hE2d2gooBdR9jD
+oYJm9S6J2U/GX1jONCJ80TPzAgMBAAGjgb8wgbwwDgYDVR0PAQH/BAQDAgTwMCAG
A1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAj
hiFodHRwOi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEE
KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLm5ldC8wHgYDVR0R
-BBcwFYITc2VydmVyMi5leGFtcGxlLm5ldDANBgkqhkiG9w0BAQUFAAOBgQAO/PIL
-r1x6F86iuKP1ww7Gb/fG9KoRVdijXvwFKurrTGLlK9gq0+w+j+vxMIBW+UeeXpRt
-JY/231AhPwxvMR4/MYQLrZUmtYO/FCIIdkjDFkt4wGszxEYSn5Ks94PftsJGrEm2
-yjc1w7gnzx2ybtYRZnpaTgOaWaYepc6wnfXXvw==
+BBcwFYITc2VydmVyMi5leGFtcGxlLm5ldDANBgkqhkiG9w0BAQsFAAOBgQA8sLmL
+GONk/MlDKooo/jYBdtDxjq4DsG1m5xJMi5FXU1XejeW4MtzhjYLqELuXLW7xlilm
+Qebnov+JLBpJlEQEC3ffUo5tQYFkXI828/0kle4FR+6O2VYUFgPMOLE8DXTsh03h
+55xpE0xly3K8FRPmWllR0QELmmFT97IltC6zHg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDExWhcNMzgw\r
-MTAxMTIzNDExWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp\r
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCf/Mo\r
-cl7+ta84A85TdEcSPfv+JV6/0ynu98Z+EHaz221TGgNYkOtlBDc80kZZ2QBndE6e\r
-RZAuIaPgTVk0mZJ7XUxAVx7AAlGSWenScV/k/VChgqddRaCmmLQoPT/wUkrDqlOW\r
-7omdM0BTaMxdEv2QRyUCVrrZKOJkRsTILkUvaQIDAQABo1owWDAOBgNVHQ8BAf8E\r
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLm5ldDERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDQwWhcNMzgw\r
+MTAxMTIzNDQwWjAzMRQwEgYDVQQKEwtleGFtcGxlLm5ldDEbMBkGA1UEAxMSY2xp\r
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXxUua\r
+JOUjKYqtSZyRwCoF1o5VI5yr+sinPkKPpGQnFd28bani9yCcLdvvOVCBPBmBe3vJ\r
+sjRSu5YO3fGlE7dRbiUBCvmOtZ4Kk39mgQcThWp8R8Mxk//ex5BSLlw3q43BY3Om\r
++V59fPWaYgHKE/RIjneGJb97oa3AmxjvZcZXnQIDAQABo1owWDAOBgNVHQ8BAf8E\r
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw\r
-Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA\r
-P/kvw/kOJI5Yja+W8/xmbAma4NeAWE48eLDzp6AWJBUU7oIj4Ca+PqwpaxxeNioZ\r
-ihLL5LCRrS8lsSGgyD3UzqYGCMOwqX5pBytpWXz1NRzzey9mCV55LHckBF7dRBuh\r
-XQiz+EvE4Dr1ZikrB6UjgHW7Bal9Y5QMDs8qZAsRkJ0=
+Oi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA\r
+rPmUtgNXl5WO6GDheUimkO9DGTeKnk8n/Hwlm6KjqYfkaJuf1YTKD2bgqfsW4TQM\r
+uN/wZurB9sbZTdrPqqD+pS8xV8CloldkH4x3PtUz+0Z4Fkgf4IQG1GKI/OGu2Ego\r
+6UjWNb+M5nNokpzyV7bAslmTj6Q7CCVQuNSKGfOIJEc=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: server2.example.net
- localKeyID: A4 A7 36 66 9C 5A FC 72 B7 08 6B 0B 9F 20 62 78 D8 DF 1D 98
+ localKeyID: 9E DB 1F 81 35 7E 72 8A 0E E8 A7 29 2D C8 AA 4F 47 9E 4E FC
Key Attributes: <No Attributes>
-----BEGIN ENCRYPTED PRIVATE KEY-----
-MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIjidyN2LNmEICAggA
-MBQGCCqGSIb3DQMHBAiM9kZJAE+TJASCAoAif/peX3iuR+MZUyC89O7/xMcYAdua
-bDFVrbNrdO5+XZG+U6elpnF/jWMKZUKxzrjkKEaJKWqQKthJp8Ds/ncD7Bx13qr9
-wTA7V+pVoVepG9JGHY1QkUTA9PNG4Txt0WrrjDU23iEYynh3G0QOoMhNYE50xCf/
-2CsWfIC6gSTL/OM2tb5ynwoDbAwS2Xml0Ky0USqCmsyJFqLq1QRo5l8EmWJ4HNut
-yQjvCbu5PAW8pAf2neJmAVlkTzwhmN5gl3vDfVKSKx2faaua0b13kCnYu8HjkbAo
-RskvJvOmOfByN04mMeUY6jhdwx7WYzvxybMFTjUlQ2ckJ3C2Yb24RrJ8m/k4GTWf
-Egy4KisBe5DFeXCh31ZSfNA5wxhNETIDYw/V/Bd5F8UvLGgOysDdn8wNIDcvR/EM
-AA/EKmj8+/0ayAxWCSQ5Rpnl9+XJKGmqlGynKF2LvvaGm/yRmq9apq1bS6CY+Plw
-Yz8webSEdIhq7BPIt09v4AiyW7VOm/GHvacfRxXlPNHakABZA/XR5Mg2HfdxV3/V
-O7lEXylQtUedyU+U36P+NtEW2PP+EkcUFkW/hno0zMWG8SdKesYTvMBz9zwPjZBz
-BfpSysxoz3pZQ3FNiRCOnPjIq5Esxp0PVMGnIQqYvptbwklUKEpq2rslSgyZJYot
-x5ui5RuQXKlLzU+bai557ofR6J0TZJnSIq7Wg0XSo2kFfMZFAUT8QAAD8cotDmwS
-q7+ncWNWIT+c/AOrUW1W8ypK11tAvytLXPifIb6R0+SXKhOzU0DB1euZwoWtBtaa
-GaKaYt+t0U/Q9umTCXXXd7gm/8+ZnpYhqNadsB2SmwGlyGU6HDsbXZW6
+MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQI6PKjsaJAXrUCAggA
+MBQGCCqGSIb3DQMHBAjMjlnQKylAngSCAoDgYIIrmVj83p/FHd2GKt7NbJxZW3jM
+Mj0jOOFXdkUJ0BPhLlcpaC3760sRiD1nAU0OGdj9DH1id9lgFKzKIOBbaKkRRKdT
+DrI2CjgMgdLYpfFWwrOMQ4OVnTaRYO7ThPBFKB8MuEQGjfspkrHc5p3twpKNucvU
+KN6Z4LiYHED2L9thLwH6kXE0nSstBk6cdmqMBX3+GUp3D0+takuyyrgBVJe8O0Tz
+nXuEIoAnziGscz7LQh399/HBhsWGwJhb/PQ6/3bkFrw14MDAg6qN2NuHfy+njU+c
+1xtrVrFeHmEFEPJTRnieyAnnHzr2LgYvIpoxtL0Yps/okS7Gl1UnaQqQARWcyTNM
+ruZoFSDZ/3FPVdB6S1tCYHrqIAZXXGYtUsqyneweurL9fprQCb6sBv1SAc3nj1AR
+UGx+p/hPp6Bm3xRmPeedltAITTIxAPE7UA+xASc6j5O5wJB7mrF9vNbt7ZkjzcgT
+87pUbe7gTtBJC6sX54PizyRaN3vnLr1nu/JDNzu1BxjEo3BshLNolrnB3YEwH8Lv
+oT8leIg6sZ8RTI6/KIdSttlatsKFFG3wqXTx8cJDBSGbyUc2mQiCPbQWBb4GUhFG
+aKwmPz8IMYyctSMJxr995eii8mogtzw7s8OirMNaJaWaG874c3I2aNIqeRm/w1Xr
+ZBD2P2vStWdivhYlcTCretqr/1G7x7iGEQPpV5bdzSz54ECEYAnCoS/IShEt/2AG
+Qxase5FQ1JyciDhPIaygRGJZCkE0i8nvdjTgqd5YiFX0OCYDlpKVa2IxysIhfjk9
+H6fkjYIWF2GhjEWpNYGXJ29fIfiNgZ+iAWHJ7cF/t98cDnHdXhUkdHxB
-----END ENCRYPTED PRIVATE KEY-----
Bag Attributes
friendlyName: server2.example.net
- localKeyID: A4 A7 36 66 9C 5A FC 72 B7 08 6B 0B 9F 20 62 78 D8 DF 1D 98
+ localKeyID: 9E DB 1F 81 35 7E 72 8A 0E E8 A7 29 2D C8 AA 4F 47 9E 4E FC
subject=/CN=server2.example.net
issuer=/O=example.net/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICiDCCAfGgAwIBAgICAMkwDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhh
+MIICiDCCAfGgAwIBAgICAMkwDQYJKoZIhvcNAQELBQAwMzEUMBIGA1UEChMLZXhh
bXBsZS5uZXQxGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDEx
-MjM0MTNaFw0zODAxMDExMjM0MTNaMB4xHDAaBgNVBAMTE3NlcnZlcjIuZXhhbXBs
-ZS5uZXQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALwP/FMqk/TKRQWwWsmz
-rt0QEKGC8M+3ot5LrXijR1RD9DTSSCDB6tI9J4s3rpM8jYZN2in/844/zHaZPHLe
-sM5/YLBWQD0YGy6eJUA+Ym/ySV0VTVZTwHwC78TvjETq1BRvi9fTNBp5P5CBN08L
-7QA5ebrmrLdpUNmjSRXqQc6ZAgMBAAGjgb8wgbwwDgYDVR0PAQH/BAQDAgTwMCAG
+MjM0NDFaFw0zODAxMDExMjM0NDFaMB4xHDAaBgNVBAMTE3NlcnZlcjIuZXhhbXBs
+ZS5uZXQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmz1Pq2JS+nTg2NgpEt
+n1L6c6OLq1waIWdH1PrsaXwz0sjAp6l5xjLIHau+0Jbeg4CkkYNYLWFcFlrhzry5
+kTsoBhwhJKsanY3fe7t4iKIxCtiX1YqoxC/+4vEpszdHnT4Io3hE2d2gooBdR9jD
+oYJm9S6J2U/GX1jONCJ80TPzAgMBAAGjgb8wgbwwDgYDVR0PAQH/BAQDAgTwMCAG
A1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAj
hiFodHRwOi8vY3JsLmV4YW1wbGUubmV0L2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEE
KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLm5ldC8wHgYDVR0R
-BBcwFYITc2VydmVyMi5leGFtcGxlLm5ldDANBgkqhkiG9w0BAQUFAAOBgQAO/PIL
-r1x6F86iuKP1ww7Gb/fG9KoRVdijXvwFKurrTGLlK9gq0+w+j+vxMIBW+UeeXpRt
-JY/231AhPwxvMR4/MYQLrZUmtYO/FCIIdkjDFkt4wGszxEYSn5Ks94PftsJGrEm2
-yjc1w7gnzx2ybtYRZnpaTgOaWaYepc6wnfXXvw==
+BBcwFYITc2VydmVyMi5leGFtcGxlLm5ldDANBgkqhkiG9w0BAQsFAAOBgQA8sLmL
+GONk/MlDKooo/jYBdtDxjq4DsG1m5xJMi5FXU1XejeW4MtzhjYLqELuXLW7xlilm
+Qebnov+JLBpJlEQEC3ffUo5tQYFkXI828/0kle4FR+6O2VYUFgPMOLE8DXTsh03h
+55xpE0xly3K8FRPmWllR0QELmmFT97IltC6zHg==
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
-MIICWwIBAAKBgQC8D/xTKpP0ykUFsFrJs67dEBChgvDPt6LeS614o0dUQ/Q00kgg
-werSPSeLN66TPI2GTdop//OOP8x2mTxy3rDOf2CwVkA9GBsuniVAPmJv8kldFU1W
-U8B8Au/E74xE6tQUb4vX0zQaeT+QgTdPC+0AOXm65qy3aVDZo0kV6kHOmQIDAQAB
-AoGAI61gsCJmuUzaNU8UmilVZijTDuD5cF6lLkjrGvTW5lyR6qdt+ZDwTHw/kUC6
-BMK7EpyYY9ljyju+PU2q0xv+LIrQONRcBPbGxSrU2W3+3S3jkWZ03tMJLRqCraFV
-w17thkexWZaqVP8eC27jcjgZMU6B3gtpsf/CeMaYYjrBGnUCQQD3g0lugwfG47kI
-Ih7M2ImeUuI/aVov0ep/nDUboLD8ZWoJylko7JpqYVMdhmNZ7CH7stqu8ufW4KkZ
-99LpZLNnAkEAwoLVEoImAJHU4uq5xjNAeklkKj5kNLvPb0ag0IkJ1pH5S5fVrgH+
-fodg2O9jvxxo4eYpbmYKbjXIx7k54QYt/wJAWM0glmaqbqAbLaDYPhReY5BHHgsV
-UVzV7kzD/RKNDTDxd2vCy10AFbSvVkN197gxhRVpQiViKoTWBrwUTqpTdwJAYHSm
-mrYFiFTI3/oMQ9gYikuoqzYjVO8pb4Hzr1W1ljzvBeh2YwLEJBSYFxunOBcrf5I2
-S3O4imyLc1dL92WsGwJALBziva48HYruICrk94ofAbMDqF3xNJS5YFMtXBvZDY/S
-WecxphaKpVPDLsABXUgDsKUKQmHBJuOYCTPqcL5FeA==
+MIICXgIBAAKBgQD5s9T6tiUvp04NjYKRLZ9S+nOji6tcGiFnR9T67Gl8M9LIwKep
+ecYyyB2rvtCW3oOApJGDWC1hXBZa4c68uZE7KAYcISSrGp2N33u7eIiiMQrYl9WK
+qMQv/uLxKbM3R50+CKN4RNndoKKAXUfYw6GCZvUuidlPxl9YzjQifNEz8wIDAQAB
+AoGBAO8Mp4fBWsZNQB8fa3E7IP1agdx/OPT6myH6Fb6HF9Fs941zSs+nogQ5qpYi
+HiVhLrm4UwpQH1nGxCwLY1UvvgTlCgJK2xQsc/GJutQPQrbiqXp2fRftS9vxS/OV
+Hzk9r+vlbQuSEmmocjcT3zbWLT8/2UBj6dtaLO8rSjIktL4JAkEA/VbRhRqnhrt4
+h+rm6GVIp2qnB5298bgBPZ6M+Qq9S5aGnZxSPCj7YrlJIVVXAvi+H4/aDBMy4Quh
+a0KpswJ3/wJBAPxTPDX4QKDnHUeNo/JAythWMYGg9WwZGYuK74KuL/kPKQYFayYr
+wxf6LvaOnW1r5UNsdhytyQWPWRlJ810u5A0CQQCULAIxgox3PhDaFiblx899s+Br
+kPQ2e3OmUaSMSJ68phan+nUSoLmfXVWLfHl+0HOKzD0xEM2SWJYZwQy2GXyLAkBR
+23rkE1Z8HJ4eEXBHbgegaU4EPMCBwh7Ma1VKMtIzXVy0rFtXdckD5VEJAblGv0MQ
+PYaPxT06xYdlMd12tHidAkEA8NeuWnXF38ztLCTVAjakKH639GEKzTj6sdLUFSNG
+HlivngW/mkugu36fR8Su1BXJs9S8U8RHm0VPv0NyzvWwYw==
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
-MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA4WhcNMzgw\r
-MTAxMTIzNDA4WjApMRQwEgYDVQQKEwtleGFtcGxlLm9yZzERMA8GA1UEAxMIY2xp\r
-Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmGE/1NBbn57y9RAMTa\r
-/jWgErk9jUKo+z0vzO5me7MUE+C3Jhk2YFF+w3ryEny3DikQOZEdRU4NFrQKZKu5\r
-1jjYg5ilg8EJTP6h9GzZmacH9olW3hdMvVqMkiLuZF97H41AYx95XPDibxwrpMgD\r
-oDVoYTQIPBwdjj8d88SdbgYjAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw\r
-DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBAINsDZLZin7u8iOLguRG\r
-37mUDNhAQ9qUAtiFV8JnjJU9DZGb0TvSpYmOkjK2iH4cH6AsEXptB6duvkkpp6ly\r
-+aGvlqy69D/MfPpLjLX7e6WOISshaWCGB7/rQqbRtAePFpa07gijUqxM22LfiHXz\r
-YHJSTjLx4idfdLNS+U5iir1Y
+MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM5WhcNMzgw\r
+MTAxMTIzNDM5WjApMRQwEgYDVQQKEwtleGFtcGxlLm9yZzERMA8GA1UEAxMIY2xp\r
+Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMmC4zNWYntPtKW8nuwo\r
+JbC14Cwuck7DufEvR6WAtos3NUxjWpS4rQl7bW62AoaSdX0bSIxpyS2wtgQxIoFJ\r
+yU0Ukseh5lTpAvXEgKyjutRJswbQj0w94O0487KcyBqd1ZDJHJYs9VJ+BfrETwwc\r
+74Tk8FUQHaH6EQJ28GIJUIJfAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw\r
+DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBAISxe2t3sJCPBKD6wyb/\r
+lAsOu+Llby0cXetGKzGhC+HFHvI5OsjhMtOE5uGp7UYlJzbRrfMx/gSR9pjaXxah\r
+Bt7JFvcPI6wSDU4bBClsuvMTisenANOOscWHSEvB/YQes3OLnqC2RGSppKshjwVF\r
+fdbkhlMTV2Oyub2TvrscntOV
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA4WhcNMzgw\r
-MTAxMTIzNDA4WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp\r
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrlUzB\r
-ANKQi0cI+jOYOVy2EYu2LOXihiMHi3dX/boaZ2+rIwbWaaAy7gMXLvfay/ml+pyY\r
-hnxQbnfADZN0xXQoHZ3AjBIU6YP2CWpOk/3jrnjW7P84fCie/6SXhfH2l6ZZFaro\r
-yRw10jnO/kgEtFKBQpN7eZ2oPDaGGwuyBVaXqQIDAQABo1owWDAOBgNVHQ8BAf8E\r
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM5WhcNMzgw\r
+MTAxMTIzNDM5WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp\r
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCpoeV\r
+zjmqBMOrYxP7rj6aXYODfaD1lZTsnopvtoNJu2BBZO9sa2bVPBcF4uyMFBG1oiMs\r
+ojP+is6A30KLytVq+N04/jj9rpDUhVKet7upKwvj29ltl/8l9/jx00pJDunSHt8h\r
+OQaWSz/SZAqW9fA+xVqEZ9RCSv/Ugo2mdGb4xQIDAQABo1owWDAOBgNVHQ8BAf8E\r
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw\r
-Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA\r
-n2I9uY34QxYLfMCIwI3oMkR+v0ehEmjLcF3S2SILybtKFOxHUvFx10IiYJOCjPKr\r
-vTwbprTp4R9HffQyiGoe9jLYu+8Tfjf86hDcoChOg8SZm1u3rXCgXPus+19XON0g\r
-UWiJmIBAWDhz8+0vQ3QyrgtLuweoX4tTcbYOlTzO5KU=
+Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA\r
+IddoaqJ/H9Ya+Iz1wRpWziTi3z7goy9Rxd6Q8f85Nra4M/3Ax2irXtgQINRho37l\r
+RmoaXVy+pTU1ncQfRiVfQML2ce9+OCQ4p5rZFxZDhh0OxKaHKrfFTvHbeNB1FH8Z\r
+SH0mRVgnK1F+8TTkThNZctKe0jhqzsp41sRBPrYIEUk=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA4WhcNMzgw\r
-MTAxMTIzNDA4WjApMRQwEgYDVQQKEwtleGFtcGxlLm9yZzERMA8GA1UEAxMIY2xp\r
-Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmGE/1NBbn57y9RAMTa\r
-/jWgErk9jUKo+z0vzO5me7MUE+C3Jhk2YFF+w3ryEny3DikQOZEdRU4NFrQKZKu5\r
-1jjYg5ilg8EJTP6h9GzZmacH9olW3hdMvVqMkiLuZF97H41AYx95XPDibxwrpMgD\r
-oDVoYTQIPBwdjj8d88SdbgYjAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw\r
-DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBAINsDZLZin7u8iOLguRG\r
-37mUDNhAQ9qUAtiFV8JnjJU9DZGb0TvSpYmOkjK2iH4cH6AsEXptB6duvkkpp6ly\r
-+aGvlqy69D/MfPpLjLX7e6WOISshaWCGB7/rQqbRtAePFpa07gijUqxM22LfiHXz\r
-YHJSTjLx4idfdLNS+U5iir1Y
+MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM5WhcNMzgw\r
+MTAxMTIzNDM5WjApMRQwEgYDVQQKEwtleGFtcGxlLm9yZzERMA8GA1UEAxMIY2xp\r
+Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMmC4zNWYntPtKW8nuwo\r
+JbC14Cwuck7DufEvR6WAtos3NUxjWpS4rQl7bW62AoaSdX0bSIxpyS2wtgQxIoFJ\r
+yU0Ukseh5lTpAvXEgKyjutRJswbQj0w94O0487KcyBqd1ZDJHJYs9VJ+BfrETwwc\r
+74Tk8FUQHaH6EQJ28GIJUIJfAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw\r
+DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBAISxe2t3sJCPBKD6wyb/\r
+lAsOu+Llby0cXetGKzGhC+HFHvI5OsjhMtOE5uGp7UYlJzbRrfMx/gSR9pjaXxah\r
+Bt7JFvcPI6wSDU4bBClsuvMTisenANOOscWHSEvB/YQes3OLnqC2RGSppKshjwVF\r
+fdbkhlMTV2Oyub2TvrscntOV
-----END CERTIFICATE-----
Bag Attributes
friendlyName: OCSP Signer
- localKeyID: CA FD 34 A0 02 63 3E 50 60 F9 97 9A 4F 56 8C A5 12 90 66 00
+ localKeyID: D6 C4 53 5D 8A 50 B5 C1 C7 EB 32 9E 6F 76 00 B5 AC 5D 11 18
Key Attributes: <No Attributes>
-----BEGIN PRIVATE KEY-----
-MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMYp+j3nm7+amKqt
-uV0wTUbE3KVXBqj8TGbTm0K839Zd+ZYuAUabDhBhkvvsbGMamvv3liF3iPdHg+z0
-vSoH7b3HODevq+SzOUSNZXz9Ha50PL5oZyP87AhqbotEMp8YkNQHDhABNDNK4mOK
-W3AvGfoXUkqodA2JBxRT/8IMg4mlAgMBAAECgYEAv9wMqLsBlLU9cqLYgV0utIIN
-jxd/H0WHQ1dFT4xGu+ooqDrKiW2+ZCXUhY0WM62iuKmx9Z0iQyg+lsEuFO+wQQSY
-Ry20gPko1qr9MfmuRITHmnojq5j5OFDfHSQj119K3vk9m6c+BPV6iL+O+a/FWWI7
-uLpi0BRlVP7nuiRjpYECQQDza+kP0qLGyDcY09NVGhcSLhJY/vXxUt+/d/y735bm
-CmpbSmKq6ngg4NmVsZ3FnA+3/qw3+BunxGQsMvYxu2B5AkEA0GdhPWgy4EhBhI//
-IO+7hTCMlW0Hy5Mmdu+X1MRXFZSKajVuebRfFOY5XowO3urLkPaWIsfZUiAQ60dk
-0/bfjQJAdb/fb43+u5WiQVpGQkZqnpq2uWIr6l6iaWZLVT4lKoYjSKHE9NSS46Sg
-3C6dGTgSynhhKnnUNuVjZ5YHTatMUQJAE+zudSqTQrJl4UDLSeDh8vgTWO4VwrcN
-BG4f/C3RjbSoD0OQjn5aYOsqLQoDGfklAXUyIZ0uABYkx/oJf+KouQJALomqbA6e
-2wII/ficucWliDecgCm3Q9E5iQTru+awd7nEyFmyGhNSbNlF/SmxkIl+Ust5JhhG
-5Lu+UkKWJ7aK+w==
+MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMMdPPNEmetl85Ya
+2a9eMRQ6i8bVY8Dimdb/PIgYBAkpxb0xu92WYxFAz26wnzp5oauUDsBLxmwC4QEh
+dN6aYGEOmt5HzblqfVPgSWWufj4z8dyKFkSmJFnRDW6vCXgnLWt+Eu3zVwfEqwU/
+VKoYZXfofS+Q0QCD0u6tnu89t6LPAgMBAAECgYA4JjXgHCHfaFuNGvUCTqz5EVAg
+TFCEtbFn+dPFpoOiz26kX6ecwSaJVIldZV6tSUuJQPZtyGC1vK5b0PD9DpglVSdw
+3QNxR9qh7fgnFm1iN+O2WhohEOCzmcV/D/YzaYeHkiNhMM4ZaCx9MoFVx17g6TVG
+xxqLwBrZQiopHIP1wQJBAPLHafZT7xrqrpFVL/s2UsmjkSWZCZ7zUX0UlgXmBI7K
+6YDXKLxzyaym+NAaT1D23pmmd4H9ph9CCgRIwlLfwbkCQQDNvVQ5T3am7zG05C2v
+GAXW7GzCW73yQ5hIxb5cuoIYewi57BMf/CJDlrwJm6WkWUHWfeSTEdyqFRUiCrcr
+fmzHAkEAnQgrG69SmyBs5YgqTtzmU5I+0gjY1j0f2j20hAAxtoK84h9JNAvYyJn/
+metKnl3vwYaRCj2cc99tRzQgrSYZ0QJAMm0oOo/Gdi4EUeDnbZYGwGHcWlrgGIQG
+zDdjbBjukA9/2QoKufkzcLt+RSCYHcsevvLGVmG3YxydvGVB9fAbuwJAQAogtDL4
+gGtl8CR7Fs8X1kxZ7+1JRb17IMXy7zajUrWid7x2rwUCYTRNPUm1iCKpEkTWN9q7
+vu0zpoakGup90Q==
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
-MIICBTCCAW6gAwIBAgIBAzANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt\r
+MIICBTCCAW6gAwIBAgIBAzANBgkqhkiG9w0BAQsFADAzMRQwEgYDVQQKEwtleGFt\r
cGxlLm9yZzEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy\r
-MzQwOFoXDTM4MDEwMTEyMzQwOFowMjEUMBIGA1UEChMLZXhhbXBsZS5vcmcxGjAY\r
+MzQzOVoXDTM4MDEwMTEyMzQzOVowMjEUMBIGA1UEChMLZXhhbXBsZS5vcmcxGjAY\r
BgNVBAMTEWNsaWNhIE9DU1AgU2lnbmVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB\r
-iQKBgQDGKfo955u/mpiqrbldME1GxNylVwao/Exm05tCvN/WXfmWLgFGmw4QYZL7\r
-7GxjGpr795Yhd4j3R4Ps9L0qB+29xzg3r6vkszlEjWV8/R2udDy+aGcj/OwIam6L\r
-RDKfGJDUBw4QATQzSuJjiltwLxn6F1JKqHQNiQcUU//CDIOJpQIDAQABoyowKDAO\r
+iQKBgQDDHTzzRJnrZfOWGtmvXjEUOovG1WPA4pnW/zyIGAQJKcW9MbvdlmMRQM9u\r
+sJ86eaGrlA7AS8ZsAuEBIXTemmBhDpreR825an1T4Ellrn4+M/HcihZEpiRZ0Q1u\r
+rwl4Jy1rfhLt81cHxKsFP1SqGGV36H0vkNEAg9LurZ7vPbeizwIDAQABoyowKDAO\r
BgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwkwDQYJKoZIhvcN\r
-AQEFBQADgYEAdbT6NKoq7DehBoMSAt8zojI26q2qR1xUmC/IN4QN3NAkmBk8R5a5\r
-Kn9oaimw0DvXO5+HP/B5Q64l9y/Prjm+08vQvK5zOP+IGZv0NcmORgzAo7n9ZePN\r
-t101UYlJMKay24ksvhcW1Xv/g9S570DncOr+vTKDYjyWGHQn2Z7terE=
+AQELBQADgYEAsP1Qz1r0qTWcsFBlNef6aw/0algvmSdcJN4KV9/HR32LD9xm5qUb\r
+/HbzUSslP9YelCdX1md1v8nTngLbrOh9PzAP33AQbHrers+agP5UNOJjSZoi6JFK\r
+R3Ajk+aG+je2eZP1zukejiOG1UnRXL6kcvIeXUQhXuOacFKeliz5BdE=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA4WhcNMzgw\r
-MTAxMTIzNDA4WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp\r
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrlUzB\r
-ANKQi0cI+jOYOVy2EYu2LOXihiMHi3dX/boaZ2+rIwbWaaAy7gMXLvfay/ml+pyY\r
-hnxQbnfADZN0xXQoHZ3AjBIU6YP2CWpOk/3jrnjW7P84fCie/6SXhfH2l6ZZFaro\r
-yRw10jnO/kgEtFKBQpN7eZ2oPDaGGwuyBVaXqQIDAQABo1owWDAOBgNVHQ8BAf8E\r
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM5WhcNMzgw\r
+MTAxMTIzNDM5WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp\r
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCpoeV\r
+zjmqBMOrYxP7rj6aXYODfaD1lZTsnopvtoNJu2BBZO9sa2bVPBcF4uyMFBG1oiMs\r
+ojP+is6A30KLytVq+N04/jj9rpDUhVKet7upKwvj29ltl/8l9/jx00pJDunSHt8h\r
+OQaWSz/SZAqW9fA+xVqEZ9RCSv/Ugo2mdGb4xQIDAQABo1owWDAOBgNVHQ8BAf8E\r
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw\r
-Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA\r
-n2I9uY34QxYLfMCIwI3oMkR+v0ehEmjLcF3S2SILybtKFOxHUvFx10IiYJOCjPKr\r
-vTwbprTp4R9HffQyiGoe9jLYu+8Tfjf86hDcoChOg8SZm1u3rXCgXPus+19XON0g\r
-UWiJmIBAWDhz8+0vQ3QyrgtLuweoX4tTcbYOlTzO5KU=
+Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA\r
+IddoaqJ/H9Ya+Iz1wRpWziTi3z7goy9Rxd6Q8f85Nra4M/3Ax2irXtgQINRho37l\r
+RmoaXVy+pTU1ncQfRiVfQML2ce9+OCQ4p5rZFxZDhh0OxKaHKrfFTvHbeNB1FH8Z\r
+SH0mRVgnK1F+8TTkThNZctKe0jhqzsp41sRBPrYIEUk=
-----END CERTIFICATE-----
; Config::Simple 4.59
-; Thu Nov 1 12:34:07 2012
+; Thu Nov 1 12:34:39 2012
+
+[CA]
+subject=clica CA
+bits=1024
+org=example.org
+name=Certificate Authority
[CLICA]
+ocsp_signer=OCSP Signer
+sighash=SHA256
crl_url=http://crl.example.org/latest.crl
-crl_signer=Signing Cert
level=1
-signer=Signing Cert
-ocsp_signer=OCSP Signer
ocsp_url=http://oscp/example.org/
-
-[CA]
-org=example.org
-subject=clica CA
-name=Certificate Authority
-bits=1024
+signer=Signing Cert
+crl_signer=Signing Cert
-update=20140422152734Z
+update=20151216164103Z
-----BEGIN X509 CRL-----
-MIHtMFgCAQEwDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhhbXBsZS5vcmcx
-GzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydBgPMjAxNDA0MjIxNTI3MzRaMA0G
-CSqGSIb3DQEBBQUAA4GBABztztS8Xe1KA+6lLFt0sZOFQGGErlzPjIzxtiG3xpFb
-zLA1m8qTBZdwmGTmWw0Al0zEyPH+1ApLy8uedoJu0oiRmLCjkRUoL6XCwA+0KV5m
-96f9y8AbrbdfbAK1zl8NTtJdKlCy/vuYBMLYQQn1ix63d28PcqACJrK+8tDq5G31
+MIHtMFgCAQEwDQYJKoZIhvcNAQELBQAwMzEUMBIGA1UEChMLZXhhbXBsZS5vcmcx
+GzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydBgPMjAxNTEyMTYxNjQxMDNaMA0G
+CSqGSIb3DQEBCwUAA4GBABEV4AP9BFujJuUkbR4aEeXrdV7x1E9hgRggYhKCM1Wc
+oQQXPo5WkZWi2clpTC3swKeX0bSzhCCi4ghfdl45L8grr1cC0T/jYQ6YkbQ4APyY
+2WZftyJafx3bRAsw/ZO/zJTaOr1959sMB0pD1urOI2keZFwl8kutjCliLxm//cVo
-----END X509 CRL-----
-update=20140422152736Z
-addcert 102 20140422152736Z
-addcert 202 20140422152736Z
+update=20151216164105Z
+addcert 102 20151216164105Z
+addcert 202 20151216164105Z
-----BEGIN X509 CRL-----
-MIIBHTCBhwIBATANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFtcGxlLm9y
-ZzEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0GA8yMDE0MDQyMjE1MjczNlow
-LTAUAgFmGA8yMDE0MDQyMjE1MjczNlowFQICAMoYDzIwMTQwNDIyMTUyNzM2WjAN
-BgkqhkiG9w0BAQUFAAOBgQAAsD6wBUQvXRStoEQu/x7SYC3K7kNU3tcvD2klq62U
-svU/gRGhyOCD3/iamcoUHkTZeCGdNjJmGG4U52zUUSvlY6qMFBe75xHDL7/8BMsl
-Db5VpBobfmDJOzyL4pJ7/Zrn7pAEuUEDT/ZUBD5Slk5IMsAvnKIrzYpN5EyYB62Z
-MA==
+MIIBHTCBhwIBATANBgkqhkiG9w0BAQsFADAzMRQwEgYDVQQKEwtleGFtcGxlLm9y
+ZzEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0GA8yMDE1MTIxNjE2NDEwNVow
+LTAUAgFmGA8yMDE1MTIxNjE2NDEwNVowFQICAMoYDzIwMTUxMjE2MTY0MTA1WjAN
+BgkqhkiG9w0BAQsFAAOBgQCdVM34udjam9lKU/yXaAV/PJsjTuxnrzlaRR3c06dp
+HMwoNSkn/64Tvw7BJOaEtcrQmqEyq1eeLtOa9uYWO1G7rgbD7HoqcVFkCCr+qGBb
+El7apHvAweVi+4RC4cL3FxmB7M6THW0gw1olGDBdahPdzD01meFXdOwLG4L1iqu+
+tw==
-----END X509 CRL-----
processor : 0
vendor_id : GenuineIntel
cpu family : 6
-model : 13
-model name : QEMU Virtual CPU version (cpu64-rhel6)
-stepping : 3
-cpu MHz : 1994.999
+model : 58
+model name : Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
+stepping : 9
+microcode : 0x1b
+cpu MHz : 2736.761
cache size : 4096 KB
+physical id : 0
+siblings : 4
+core id : 0
+cpu cores : 2
+apicid : 0
+initial apicid : 0
fpu : yes
fpu_exception : yes
-cpuid level : 4
+cpuid level : 13
wp : yes
-flags : fpu de pse tsc msr pae mce cx8 apic mtrr pge mca cmov pse36 clflush mmx fxsr sse sse2 syscall nx lm up unfair_spinlock pni cx16 hypervisor lahf_lm
-bogomips : 3989.99
+flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm ida arat epb pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt
+bugs :
+bogomips : 5786.61
clflush size : 64
cache_alignment : 64
-address sizes : 38 bits physical, 48 bits virtual
+address sizes : 36 bits physical, 48 bits virtual
power management:
- CPU0
- 0: 258 IO-APIC-edge timer
- 1: 6 IO-APIC-edge i8042
- 4: 1 IO-APIC-edge
- 8: 0 IO-APIC-edge rtc0
- 9: 0 IO-APIC-fasteoi acpi
- 10: 953 IO-APIC-fasteoi virtio3
- 11: 62 IO-APIC-fasteoi uhci_hcd:usb1, snd_hda_intel
- 12: 104 IO-APIC-edge i8042
- 14: 0 IO-APIC-edge ata_piix
- 15: 106 IO-APIC-edge ata_piix
- 24: 0 PCI-MSI-edge virtio2-config
- 25: 48993 PCI-MSI-edge virtio2-requests
- 26: 0 PCI-MSI-edge virtio0-config
- 27: 296865 PCI-MSI-edge virtio0-input
- 28: 1 PCI-MSI-edge virtio0-output
- 29: 0 PCI-MSI-edge virtio1-config
- 30: 18867 PCI-MSI-edge virtio1-input
- 31: 1 PCI-MSI-edge virtio1-output
-NMI: 0 Non-maskable interrupts
-LOC: 774993 Local timer interrupts
-SPU: 0 Spurious interrupts
-PMI: 0 Performance monitoring interrupts
-IWI: 0 IRQ work interrupts
-RES: 0 Rescheduling interrupts
-CAL: 0 Function call interrupts
-TLB: 0 TLB shootdowns
-TRM: 0 Thermal event interrupts
-THR: 0 Threshold APIC interrupts
-MCE: 0 Machine check exceptions
-MCP: 271 Machine check polls
+processor : 1
+vendor_id : GenuineIntel
+cpu family : 6
+model : 58
+model name : Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
+stepping : 9
+microcode : 0x1b
+cpu MHz : 2185.535
+cache size : 4096 KB
+physical id : 0
+siblings : 4
+core id : 0
+cpu cores : 2
+apicid : 1
+initial apicid : 1
+fpu : yes
+fpu_exception : yes
+cpuid level : 13
+wp : yes
+flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm ida arat epb pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt
+bugs :
+bogomips : 5786.61
+clflush size : 64
+cache_alignment : 64
+address sizes : 36 bits physical, 48 bits virtual
+power management:
+
+processor : 2
+vendor_id : GenuineIntel
+cpu family : 6
+model : 58
+model name : Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
+stepping : 9
+microcode : 0x1b
+cpu MHz : 2806.203
+cache size : 4096 KB
+physical id : 0
+siblings : 4
+core id : 1
+cpu cores : 2
+apicid : 2
+initial apicid : 2
+fpu : yes
+fpu_exception : yes
+cpuid level : 13
+wp : yes
+flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm ida arat epb pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt
+bugs :
+bogomips : 5786.61
+clflush size : 64
+cache_alignment : 64
+address sizes : 36 bits physical, 48 bits virtual
+power management:
+
+processor : 3
+vendor_id : GenuineIntel
+cpu family : 6
+model : 58
+model name : Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
+stepping : 9
+microcode : 0x1b
+cpu MHz : 2908.609
+cache size : 4096 KB
+physical id : 0
+siblings : 4
+core id : 1
+cpu cores : 2
+apicid : 3
+initial apicid : 3
+fpu : yes
+fpu_exception : yes
+cpuid level : 13
+wp : yes
+flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm ida arat epb pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt
+bugs :
+bogomips : 5786.61
+clflush size : 64
+cache_alignment : 64
+address sizes : 36 bits physical, 48 bits virtual
+power management:
+
+ CPU0 CPU1 CPU2 CPU3
+ 0: 68 0 0 0 IO-APIC 2-edge timer
+ 1: 689 7853 658 778 IO-APIC 1-edge i8042
+ 8: 0 0 1 0 IO-APIC 8-edge rtc0
+ 9: 1160 695 344 261 IO-APIC 9-fasteoi acpi
+ 12: 314976 1327914 163447 143732 IO-APIC 12-edge i8042
+ 16: 332 194 163 132 IO-APIC 16-fasteoi ehci_hcd:usb3, mmc0
+ 18: 0 0 0 0 IO-APIC 18-fasteoi i801_smbus
+ 23: 17 31 0 0 IO-APIC 23-fasteoi ehci_hcd:usb4
+ 24: 43443 5748 786804 3298 PCI-MSI 512000-edge 0000:00:1f.2
+ 25: 0 0 0 0 PCI-MSI 327680-edge xhci_hcd
+ 26: 3 4 1 1 PCI-MSI 409600-edge enp0s25
+ 27: 852 591 64 42 PCI-MSI 32768-edge i915
+ 28: 8 6 3 6 PCI-MSI 360448-edge mei_me
+ 29: 62 82 0 6 PCI-MSI 442368-edge snd_hda_intel
+ 30: 779528 1591 37 80 PCI-MSI 1572864-edge iwlwifi
+NMI: 94 87 91 87 Non-maskable interrupts
+LOC: 2716585 2176306 2757682 2241051 Local timer interrupts
+SPU: 0 0 0 0 Spurious interrupts
+PMI: 94 87 91 87 Performance monitoring interrupts
+IWI: 0 6 3 4 IRQ work interrupts
+RTR: 0 0 0 0 APIC ICR read retries
+RES: 181902 181908 174961 218150 Rescheduling interrupts
+CAL: 155914 95370 153295 90514 Function call interrupts
+TLB: 19954 22440 21483 20784 TLB shootdowns
+TRM: 0 0 0 0 Thermal event interrupts
+THR: 0 0 0 0 Threshold APIC interrupts
+DFR: 0 0 0 0 Deferred Error APIC interrupts
+MCE: 0 0 0 0 Machine check exceptions
+MCP: 29 29 29 29 Machine check polls
+HYP: 0 0 0 0 Hypervisor callback interrupts
ERR: 0
MIS: 0
-MemTotal: 487904 kB
-MemFree: 73484 kB
-Buffers: 73812 kB
-Cached: 141708 kB
-SwapCached: 0 kB
-Active: 132460 kB
-Inactive: 119036 kB
-Active(anon): 15152 kB
-Inactive(anon): 21900 kB
-Active(file): 117308 kB
-Inactive(file): 97136 kB
-Unevictable: 0 kB
-Mlocked: 0 kB
-SwapTotal: 524280 kB
-SwapFree: 524280 kB
-Dirty: 1628 kB
+PIN: 0 0 0 0 Posted-interrupt notification event
+PIW: 0 0 0 0 Posted-interrupt wakeup event
+MemTotal: 16127228 kB
+MemFree: 11186684 kB
+MemAvailable: 11365672 kB
+Buffers: 13604 kB
+Cached: 251132 kB
+SwapCached: 1968812 kB
+Active: 2291884 kB
+Inactive: 2270760 kB
+Active(anon): 2258436 kB
+Inactive(anon): 2128252 kB
+Active(file): 33448 kB
+Inactive(file): 142508 kB
+Unevictable: 22232 kB
+Mlocked: 22232 kB
+SwapTotal: 7286780 kB
+SwapFree: 618256 kB
+Dirty: 4152 kB
Writeback: 0 kB
-AnonPages: 35928 kB
-Mapped: 15596 kB
-Shmem: 1128 kB
-Slab: 136308 kB
-SReclaimable: 83924 kB
-SUnreclaim: 52384 kB
-KernelStack: 752 kB
-PageTables: 3412 kB
+AnonPages: 2351516 kB
+Mapped: 158396 kB
+Shmem: 79820 kB
+Slab: 122620 kB
+SReclaimable: 63032 kB
+SUnreclaim: 59588 kB
+KernelStack: 12336 kB
+PageTables: 59672 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
-CommitLimit: 768232 kB
-Committed_AS: 116976 kB
+CommitLimit: 15350392 kB
+Committed_AS: 22213012 kB
VmallocTotal: 34359738367 kB
-VmallocUsed: 12116 kB
-VmallocChunk: 34359713232 kB
+VmallocUsed: 457088 kB
+VmallocChunk: 34358947836 kB
HardwareCorrupted: 0 kB
-AnonHugePages: 2048 kB
+AnonHugePages: 1890304 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
-DirectMap4k: 7156 kB
-DirectMap2M: 1492992 kB
-slabinfo - version: 2.1
-# name <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>
-nf_conntrack_expect 0 0 240 16 1 : tunables 120 60 0 : slabdata 0 0 0
-nf_conntrack_ffffffff81b18540 36 36 312 12 1 : tunables 54 27 0 : slabdata 3 3 0
-fib6_nodes 42 59 64 59 1 : tunables 120 60 0 : slabdata 1 1 0
-ip6_dst_cache 24 40 384 10 1 : tunables 54 27 0 : slabdata 4 4 0
-ndisc_cache 21 30 256 15 1 : tunables 120 60 0 : slabdata 2 2 0
-ip6_mrt_cache 0 0 128 30 1 : tunables 120 60 0 : slabdata 0 0 0
-RAWv6 4 4 1024 4 1 : tunables 54 27 0 : slabdata 1 1 0
-UDPLITEv6 0 0 1024 4 1 : tunables 54 27 0 : slabdata 0 0 0
-UDPv6 0 0 1024 4 1 : tunables 54 27 0 : slabdata 0 0 0
-tw_sock_TCPv6 0 0 320 12 1 : tunables 54 27 0 : slabdata 0 0 0
-request_sock_TCPv6 0 0 192 20 1 : tunables 120 60 0 : slabdata 0 0 0
-TCPv6 9 10 1920 2 1 : tunables 24 12 0 : slabdata 5 5 0
-jbd2_1k 0 0 1024 4 1 : tunables 54 27 0 : slabdata 0 0 0
-avtab_node 551039 551088 24 144 1 : tunables 120 60 0 : slabdata 3827 3827 0
-ext4_inode_cache 36173 36888 1016 4 1 : tunables 54 27 0 : slabdata 9222 9222 0
-ext4_xattr 5 44 88 44 1 : tunables 120 60 0 : slabdata 1 1 0
-ext4_free_block_extents 16 67 56 67 1 : tunables 120 60 0 : slabdata 1 1 0
-ext4_alloc_context 16 28 136 28 1 : tunables 120 60 0 : slabdata 1 1 0
-ext4_prealloc_space 3 37 104 37 1 : tunables 120 60 0 : slabdata 1 1 0
-ext4_system_zone 0 0 40 92 1 : tunables 120 60 0 : slabdata 0 0 0
-jbd2_journal_handle 16 144 24 144 1 : tunables 120 60 0 : slabdata 1 1 0
-jbd2_journal_head 68 68 112 34 1 : tunables 120 60 0 : slabdata 2 2 0
-jbd2_revoke_table 4 202 16 202 1 : tunables 120 60 0 : slabdata 1 1 0
-jbd2_revoke_record 0 0 32 112 1 : tunables 120 60 0 : slabdata 0 0 0
-scsi_sense_cache 2 30 128 30 1 : tunables 120 60 0 : slabdata 1 1 0
-scsi_cmd_cache 2 15 256 15 1 : tunables 120 60 0 : slabdata 1 1 0
-dm_raid1_read_record 0 0 1064 7 2 : tunables 24 12 0 : slabdata 0 0 0
-kcopyd_job 0 0 3240 2 2 : tunables 24 12 0 : slabdata 0 0 0
-io 0 0 64 59 1 : tunables 120 60 0 : slabdata 0 0 0
-dm_uevent 0 0 2608 3 2 : tunables 24 12 0 : slabdata 0 0 0
-dm_rq_clone_bio_info 0 0 16 202 1 : tunables 120 60 0 : slabdata 0 0 0
-dm_rq_target_io 0 0 392 10 1 : tunables 54 27 0 : slabdata 0 0 0
-dm_target_io 576 576 24 144 1 : tunables 120 60 0 : slabdata 4 4 0
-dm_io 552 552 40 92 1 : tunables 120 60 0 : slabdata 6 6 0
-flow_cache 0 0 104 37 1 : tunables 120 60 0 : slabdata 0 0 0
-uhci_urb_priv 0 0 56 67 1 : tunables 120 60 0 : slabdata 0 0 0
-cfq_io_context 0 0 136 28 1 : tunables 120 60 0 : slabdata 0 0 0
-cfq_queue 0 0 240 16 1 : tunables 120 60 0 : slabdata 0 0 0
-bsg_cmd 0 0 312 12 1 : tunables 54 27 0 : slabdata 0 0 0
-mqueue_inode_cache 1 4 896 4 1 : tunables 54 27 0 : slabdata 1 1 0
-isofs_inode_cache 0 0 640 6 1 : tunables 54 27 0 : slabdata 0 0 0
-hugetlbfs_inode_cache 1 6 608 6 1 : tunables 54 27 0 : slabdata 1 1 0
-dquot 0 0 256 15 1 : tunables 120 60 0 : slabdata 0 0 0
-kioctx 0 0 384 10 1 : tunables 54 27 0 : slabdata 0 0 0
-kiocb 0 0 256 15 1 : tunables 120 60 0 : slabdata 0 0 0
-inotify_event_private_data 0 0 32 112 1 : tunables 120 60 0 : slabdata 0 0 0
-inotify_inode_mark_entry 110 136 112 34 1 : tunables 120 60 0 : slabdata 4 4 0
-dnotify_mark_entry 0 0 112 34 1 : tunables 120 60 0 : slabdata 0 0 0
-dnotify_struct 0 0 32 112 1 : tunables 120 60 0 : slabdata 0 0 0
-dio 0 0 640 6 1 : tunables 54 27 0 : slabdata 0 0 0
-fasync_cache 0 0 24 144 1 : tunables 120 60 0 : slabdata 0 0 0
-khugepaged_mm_slot 17 92 40 92 1 : tunables 120 60 0 : slabdata 1 1 0
-ksm_mm_slot 0 0 48 77 1 : tunables 120 60 0 : slabdata 0 0 0
-ksm_stable_node 0 0 48 77 1 : tunables 120 60 0 : slabdata 0 0 0
-ksm_rmap_item 0 0 64 59 1 : tunables 120 60 0 : slabdata 0 0 0
-utrace_engine 0 0 56 67 1 : tunables 120 60 0 : slabdata 0 0 0
-utrace 0 0 64 59 1 : tunables 120 60 0 : slabdata 0 0 0
-pid_namespace 0 0 2168 3 2 : tunables 24 12 0 : slabdata 0 0 0
-posix_timers_cache 0 0 176 22 1 : tunables 120 60 0 : slabdata 0 0 0
-uid_cache 3 30 128 30 1 : tunables 120 60 0 : slabdata 1 1 0
-UNIX 107 110 768 5 1 : tunables 54 27 0 : slabdata 22 22 0
-ip_mrt_cache 0 0 128 30 1 : tunables 120 60 0 : slabdata 0 0 0
-UDP-Lite 0 0 832 9 2 : tunables 54 27 0 : slabdata 0 0 0
-tcp_bind_bucket 9 59 64 59 1 : tunables 120 60 0 : slabdata 1 1 0
-inet_peer_cache 2 59 64 59 1 : tunables 120 60 0 : slabdata 1 1 0
-secpath_cache 0 0 64 59 1 : tunables 120 60 0 : slabdata 0 0 0
-xfrm_dst_cache 0 0 448 8 1 : tunables 54 27 0 : slabdata 0 0 0
-ip_fib_alias 1 112 32 112 1 : tunables 120 60 0 : slabdata 1 1 0
-ip_fib_hash 14 53 72 53 1 : tunables 120 60 0 : slabdata 1 1 0
-ip_dst_cache 26 30 384 10 1 : tunables 54 27 0 : slabdata 3 3 0
-arp_cache 6 15 256 15 1 : tunables 120 60 0 : slabdata 1 1 0
-PING 0 0 832 9 2 : tunables 54 27 0 : slabdata 0 0 0
-RAW 2 9 832 9 2 : tunables 54 27 0 : slabdata 1 1 0
-UDP 1 9 832 9 2 : tunables 54 27 0 : slabdata 1 1 0
-tw_sock_TCP 0 0 256 15 1 : tunables 120 60 0 : slabdata 0 0 0
-request_sock_TCP 0 0 128 30 1 : tunables 120 60 0 : slabdata 0 0 0
-TCP 10 12 1728 4 2 : tunables 24 12 0 : slabdata 3 3 0
-eventpoll_pwq 59 106 72 53 1 : tunables 120 60 0 : slabdata 2 2 0
-eventpoll_epi 59 90 128 30 1 : tunables 120 60 0 : slabdata 3 3 0
-sgpool-128 2 2 4096 1 1 : tunables 24 12 0 : slabdata 2 2 0
-sgpool-64 2 2 2048 2 1 : tunables 24 12 0 : slabdata 1 1 0
-sgpool-32 2 4 1024 4 1 : tunables 54 27 0 : slabdata 1 1 0
-sgpool-16 2 8 512 8 1 : tunables 54 27 0 : slabdata 1 1 0
-sgpool-8 2 15 256 15 1 : tunables 120 60 0 : slabdata 1 1 0
-scsi_data_buffer 0 0 24 144 1 : tunables 120 60 0 : slabdata 0 0 0
-blkdev_integrity 0 0 112 34 1 : tunables 120 60 0 : slabdata 0 0 0
-blkdev_queue 28 28 2864 2 2 : tunables 24 12 0 : slabdata 14 14 0
-blkdev_requests 22 22 352 11 1 : tunables 54 27 0 : slabdata 2 2 0
-blkdev_ioc 3 48 80 48 1 : tunables 120 60 0 : slabdata 1 1 0
-fsnotify_event_holder 0 0 24 144 1 : tunables 120 60 0 : slabdata 0 0 0
-fsnotify_event 0 0 104 37 1 : tunables 120 60 0 : slabdata 0 0 0
-bio-0 80 80 192 20 1 : tunables 120 60 0 : slabdata 4 4 0
-biovec-256 34 34 4096 1 1 : tunables 24 12 0 : slabdata 34 34 0
-biovec-128 0 0 2048 2 1 : tunables 24 12 0 : slabdata 0 0 0
-biovec-64 2 4 1024 4 1 : tunables 54 27 0 : slabdata 1 1 0
-biovec-16 7 15 256 15 1 : tunables 120 60 0 : slabdata 1 1 0
-bip-256 2 2 4224 1 2 : tunables 8 4 0 : slabdata 2 2 0
-bip-128 0 0 2176 3 2 : tunables 24 12 0 : slabdata 0 0 0
-bip-64 0 0 1152 7 2 : tunables 24 12 0 : slabdata 0 0 0
-bip-16 0 0 384 10 1 : tunables 54 27 0 : slabdata 0 0 0
-bip-4 0 0 192 20 1 : tunables 120 60 0 : slabdata 0 0 0
-bip-1 0 0 128 30 1 : tunables 120 60 0 : slabdata 0 0 0
-sock_inode_cache 150 160 704 5 1 : tunables 54 27 0 : slabdata 32 32 0
-skbuff_fclone_cache 7 7 512 7 1 : tunables 54 27 0 : slabdata 1 1 0
-skbuff_head_cache 66 105 256 15 1 : tunables 120 60 0 : slabdata 7 7 0
-file_lock_cache 21 22 176 22 1 : tunables 120 60 0 : slabdata 1 1 0
-net_namespace 0 0 2432 3 2 : tunables 24 12 0 : slabdata 0 0 0
-shmem_inode_cache 654 655 784 5 1 : tunables 54 27 0 : slabdata 131 131 0
-Acpi-Operand 1211 1219 72 53 1 : tunables 120 60 0 : slabdata 23 23 0
-Acpi-ParseExt 0 0 72 53 1 : tunables 120 60 0 : slabdata 0 0 0
-Acpi-Parse 0 0 48 77 1 : tunables 120 60 0 : slabdata 0 0 0
-Acpi-State 0 0 80 48 1 : tunables 120 60 0 : slabdata 0 0 0
-Acpi-Namespace 407 460 40 92 1 : tunables 120 60 0 : slabdata 5 5 0
-task_delay_info 102 102 112 34 1 : tunables 120 60 0 : slabdata 3 3 0
-taskstats 0 0 328 12 1 : tunables 54 27 0 : slabdata 0 0 0
-proc_inode_cache 408 408 656 6 1 : tunables 54 27 0 : slabdata 68 68 0
-sigqueue 9 24 160 24 1 : tunables 120 60 0 : slabdata 1 1 0
-bdev_cache 31 32 832 4 1 : tunables 54 27 0 : slabdata 8 8 0
-sysfs_dir_cache 7588 7614 144 27 1 : tunables 120 60 0 : slabdata 282 282 0
-mnt_cache 27 30 256 15 1 : tunables 120 60 0 : slabdata 2 2 0
-filp 840 840 192 20 1 : tunables 120 60 0 : slabdata 42 42 0
-inode_cache 5826 5826 592 6 1 : tunables 54 27 0 : slabdata 971 971 0
-dentry 189420 189420 192 20 1 : tunables 120 60 0 : slabdata 9471 9471 0
-names_cache 1 1 4096 1 1 : tunables 24 12 0 : slabdata 1 1 0
-avc_node 514 708 64 59 1 : tunables 120 60 0 : slabdata 12 12 0
-selinux_inode_security 43259 46799 72 53 1 : tunables 120 60 0 : slabdata 883 883 0
-radix_tree_node 2991 3598 560 7 1 : tunables 54 27 0 : slabdata 514 514 0
-key_jar 5 20 192 20 1 : tunables 120 60 0 : slabdata 1 1 0
-buffer_head 24272 25493 104 37 1 : tunables 120 60 0 : slabdata 689 689 0
-nsproxy 0 0 48 77 1 : tunables 120 60 0 : slabdata 0 0 0
-vm_area_struct 2565 2565 200 19 1 : tunables 120 60 0 : slabdata 135 135 0
-mm_struct 40 40 1408 5 2 : tunables 24 12 0 : slabdata 8 8 0
-fs_cache 59 59 64 59 1 : tunables 120 60 0 : slabdata 1 1 0
-files_cache 44 44 704 11 2 : tunables 54 27 0 : slabdata 4 4 0
-signal_cache 91 91 1088 7 2 : tunables 24 12 0 : slabdata 13 13 0
-sighand_cache 90 90 2112 3 2 : tunables 24 12 0 : slabdata 30 30 0
-task_xstate 48 48 512 8 1 : tunables 54 27 0 : slabdata 6 6 0
-task_struct 96 96 2656 3 2 : tunables 24 12 0 : slabdata 32 32 0
-cred_jar 240 240 192 20 1 : tunables 120 60 0 : slabdata 12 12 0
-anon_vma_chain 1795 2079 48 77 1 : tunables 120 60 0 : slabdata 27 27 0
-anon_vma 1209 1380 40 92 1 : tunables 120 60 0 : slabdata 15 15 0
-pid 107 120 128 30 1 : tunables 120 60 0 : slabdata 4 4 0
-shared_policy_node 0 0 48 77 1 : tunables 120 60 0 : slabdata 0 0 0
-numa_policy 0 0 136 28 1 : tunables 120 60 0 : slabdata 0 0 0
-idr_layer_cache 281 287 544 7 1 : tunables 54 27 0 : slabdata 41 41 0
-size-4194304(DMA) 0 0 4194304 1 1024 : tunables 1 1 0 : slabdata 0 0 0
-size-4194304 0 0 4194304 1 1024 : tunables 1 1 0 : slabdata 0 0 0
-size-2097152(DMA) 0 0 2097152 1 512 : tunables 1 1 0 : slabdata 0 0 0
-size-2097152 0 0 2097152 1 512 : tunables 1 1 0 : slabdata 0 0 0
-size-1048576(DMA) 0 0 1048576 1 256 : tunables 1 1 0 : slabdata 0 0 0
-size-1048576 0 0 1048576 1 256 : tunables 1 1 0 : slabdata 0 0 0
-size-524288(DMA) 0 0 524288 1 128 : tunables 1 1 0 : slabdata 0 0 0
-size-524288 0 0 524288 1 128 : tunables 1 1 0 : slabdata 0 0 0
-size-262144(DMA) 0 0 262144 1 64 : tunables 1 1 0 : slabdata 0 0 0
-size-262144 0 0 262144 1 64 : tunables 1 1 0 : slabdata 0 0 0
-size-131072(DMA) 0 0 131072 1 32 : tunables 8 4 0 : slabdata 0 0 0
-size-131072 0 0 131072 1 32 : tunables 8 4 0 : slabdata 0 0 0
-size-65536(DMA) 0 0 65536 1 16 : tunables 8 4 0 : slabdata 0 0 0
-size-65536 2 2 65536 1 16 : tunables 8 4 0 : slabdata 2 2 0
-size-32768(DMA) 0 0 32768 1 8 : tunables 8 4 0 : slabdata 0 0 0
-size-32768 3 3 32768 1 8 : tunables 8 4 0 : slabdata 3 3 0
-size-16384(DMA) 0 0 16384 1 4 : tunables 8 4 0 : slabdata 0 0 0
-size-16384 7 7 16384 1 4 : tunables 8 4 0 : slabdata 7 7 0
-size-8192(DMA) 0 0 8192 1 2 : tunables 8 4 0 : slabdata 0 0 0
-size-8192 12 12 8192 1 2 : tunables 8 4 0 : slabdata 12 12 0
-size-4096(DMA) 0 0 4096 1 1 : tunables 24 12 0 : slabdata 0 0 0
-size-4096 119 119 4096 1 1 : tunables 24 12 0 : slabdata 119 119 0
-size-2048(DMA) 0 0 2048 2 1 : tunables 24 12 0 : slabdata 0 0 0
-size-2048 200 200 2048 2 1 : tunables 24 12 0 : slabdata 100 100 0
-size-1024(DMA) 0 0 1024 4 1 : tunables 54 27 0 : slabdata 0 0 0
-size-1024 578 588 1024 4 1 : tunables 54 27 0 : slabdata 147 147 0
-size-512(DMA) 0 0 512 8 1 : tunables 54 27 0 : slabdata 0 0 0
-size-512 608 608 512 8 1 : tunables 54 27 0 : slabdata 76 76 0
-size-256(DMA) 0 0 256 15 1 : tunables 120 60 0 : slabdata 0 0 0
-size-256 815 825 256 15 1 : tunables 120 60 0 : slabdata 55 55 0
-size-192(DMA) 0 0 192 20 1 : tunables 120 60 0 : slabdata 0 0 0
-size-192 1256 1260 192 20 1 : tunables 120 60 0 : slabdata 63 63 0
-size-128(DMA) 0 0 128 30 1 : tunables 120 60 0 : slabdata 0 0 0
-size-64(DMA) 0 0 64 59 1 : tunables 120 60 0 : slabdata 0 0 0
-size-64 23094 25783 64 59 1 : tunables 120 60 0 : slabdata 437 437 0
-size-32(DMA) 0 0 32 112 1 : tunables 120 60 0 : slabdata 0 0 0
-size-128 3271 3450 128 30 1 : tunables 120 60 0 : slabdata 115 115 0
-size-32 352497 352576 32 112 1 : tunables 120 60 0 : slabdata 3148 3148 0
-kmem_cache 183 183 32896 1 16 : tunables 8 4 0 : slabdata 183 183 0
+DirectMap4k: 144572 kB
+DirectMap2M: 16322560 kB
Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
- lo: 5243413 23981 0 0 0 0 0 0 5243413 23981 0 0 0 0 0 0
- eth0:25465657 318897 0 0 0 0 0 0 2043751 16011 0 0 0 0 0 0
- eth1: 1386405 18972 0 0 0 0 0 0 95634 1485 0 0 0 0 0 0
+virbr1-nic: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ vnet0: 128666 393 0 0 0 0 0 0 317141 3975 0 0 0 0 0 0
+ vnet5: 43924 524 0 0 0 0 0 0 221634 3858 0 0 0 0 0 0
+enp0s25: 31338290 49183 0 0 0 0 0 1035 10708826 44319 0 0 0 0 0 0
+virbr0-nic: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ vnet2: 69293 283 0 0 0 0 0 0 364158 3769 0 0 0 0 0 0
+ vnet4: 59178 194 0 0 0 0 0 0 238335 3593 0 0 0 0 0 0
+virbr0: 5345737 5274 0 0 0 0 0 0 1408922 5318 0 0 0 0 0 0
+ vnet1: 5034219 3505 0 0 0 0 0 0 1151061 7192 0 0 0 0 0 0
+ lo: 20864 210 0 0 0 0 0 0 20864 210 0 0 0 0 0 0
+virbr1: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+wlp3s0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ vnet3: 84293 375 0 0 0 0 0 0 279505 3663 0 0 0 0 0 0
subject=/O=example.org/CN=clica Signing Cert
issuer=/O=example.org/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA4WhcNMzgw
-MTAxMTIzNDA4WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrlUzB
-ANKQi0cI+jOYOVy2EYu2LOXihiMHi3dX/boaZ2+rIwbWaaAy7gMXLvfay/ml+pyY
-hnxQbnfADZN0xXQoHZ3AjBIU6YP2CWpOk/3jrnjW7P84fCie/6SXhfH2l6ZZFaro
-yRw10jnO/kgEtFKBQpN7eZ2oPDaGGwuyBVaXqQIDAQABo1owWDAOBgNVHQ8BAf8E
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM5WhcNMzgw
+MTAxMTIzNDM5WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCpoeV
+zjmqBMOrYxP7rj6aXYODfaD1lZTsnopvtoNJu2BBZO9sa2bVPBcF4uyMFBG1oiMs
+ojP+is6A30KLytVq+N04/jj9rpDUhVKet7upKwvj29ltl/8l9/jx00pJDunSHt8h
+OQaWSz/SZAqW9fA+xVqEZ9RCSv/Ugo2mdGb4xQIDAQABo1owWDAOBgNVHQ8BAf8E
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw
-Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA
-n2I9uY34QxYLfMCIwI3oMkR+v0ehEmjLcF3S2SILybtKFOxHUvFx10IiYJOCjPKr
-vTwbprTp4R9HffQyiGoe9jLYu+8Tfjf86hDcoChOg8SZm1u3rXCgXPus+19XON0g
-UWiJmIBAWDhz8+0vQ3QyrgtLuweoX4tTcbYOlTzO5KU=
+Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA
+IddoaqJ/H9Ya+Iz1wRpWziTi3z7goy9Rxd6Q8f85Nra4M/3Ax2irXtgQINRho37l
+RmoaXVy+pTU1ncQfRiVfQML2ce9+OCQ4p5rZFxZDhh0OxKaHKrfFTvHbeNB1FH8Z
+SH0mRVgnK1F+8TTkThNZctKe0jhqzsp41sRBPrYIEUk=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: Certificate Authority
subject=/O=example.org/CN=clica CA
issuer=/O=example.org/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA4WhcNMzgw
-MTAxMTIzNDA4WjApMRQwEgYDVQQKEwtleGFtcGxlLm9yZzERMA8GA1UEAxMIY2xp
-Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmGE/1NBbn57y9RAMTa
-/jWgErk9jUKo+z0vzO5me7MUE+C3Jhk2YFF+w3ryEny3DikQOZEdRU4NFrQKZKu5
-1jjYg5ilg8EJTP6h9GzZmacH9olW3hdMvVqMkiLuZF97H41AYx95XPDibxwrpMgD
-oDVoYTQIPBwdjj8d88SdbgYjAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
-DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBAINsDZLZin7u8iOLguRG
-37mUDNhAQ9qUAtiFV8JnjJU9DZGb0TvSpYmOkjK2iH4cH6AsEXptB6duvkkpp6ly
-+aGvlqy69D/MfPpLjLX7e6WOISshaWCGB7/rQqbRtAePFpa07gijUqxM22LfiHXz
-YHJSTjLx4idfdLNS+U5iir1Y
------END CERTIFICATE-----
-Bag Attributes
- friendlyName: expired1.example.org
- localKeyID: 99 C2 8F 9C 7D C1 19 76 88 B2 B0 83 4D 00 ED C9 E9 2B 7E EB
-subject=/CN=expired1.example.org
-issuer=/O=example.org/CN=clica Signing Cert
------BEGIN CERTIFICATE-----
-MIICiTCCAfKgAwIBAgIBZzANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt
-cGxlLm9yZzEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
-MzQwOVoXDTEyMTIwMTEyMzQwOVowHzEdMBsGA1UEAxMUZXhwaXJlZDEuZXhhbXBs
-ZS5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL3J/GWAVGm/d/nUnwDr
-3zeq85l1l1Zmp9r9XLUcw9cDbLM1hg4Ej557Cg9bXDZ7yCoa9tZnMUr6yKw1AxiV
-6DaoRt2HcPdAdge448/s96F8TtpfU9FOOm4iW2gAhhQVy/L0py76SPxadjI+IxwL
-MoaaIHevy6v+8wdafJVHe3cNAgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
-A1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAj
-hiFodHRwOi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEE
-KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLm9yZy8wHwYDVR0R
-BBgwFoIUZXhwaXJlZDEuZXhhbXBsZS5vcmcwDQYJKoZIhvcNAQEFBQADgYEAChRl
-3S8Jylp0qbbYnIfnGFYgmzExHYuBkJv81j19n74NeD6cwmIE+rBL2+g459o1f3TZ
-ngfnX16kXvG2xCRozPbv8VAOiF7kGHg4RdQqS3GTlnxeDuGqTTZXhMkRHeEHNp1N
-J7d7YZlHna/txyMBbrg4oUESHhtUBzHC7zixHzo=
+MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM5WhcNMzgw
+MTAxMTIzNDM5WjApMRQwEgYDVQQKEwtleGFtcGxlLm9yZzERMA8GA1UEAxMIY2xp
+Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMmC4zNWYntPtKW8nuwo
+JbC14Cwuck7DufEvR6WAtos3NUxjWpS4rQl7bW62AoaSdX0bSIxpyS2wtgQxIoFJ
+yU0Ukseh5lTpAvXEgKyjutRJswbQj0w94O0487KcyBqd1ZDJHJYs9VJ+BfrETwwc
+74Tk8FUQHaH6EQJ28GIJUIJfAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
+DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBAISxe2t3sJCPBKD6wyb/
+lAsOu+Llby0cXetGKzGhC+HFHvI5OsjhMtOE5uGp7UYlJzbRrfMx/gSR9pjaXxah
+Bt7JFvcPI6wSDU4bBClsuvMTisenANOOscWHSEvB/YQes3OLnqC2RGSppKshjwVF
+fdbkhlMTV2Oyub2TvrscntOV
-----END CERTIFICATE-----
Bag Attributes
friendlyName: expired1.example.org
- localKeyID: 99 C2 8F 9C 7D C1 19 76 88 B2 B0 83 4D 00 ED C9 E9 2B 7E EB
+ localKeyID: CB AF 4D EC E3 18 F0 8C C5 C7 C1 CB 9C 06 DD F8 FC B4 FD C5
subject=/CN=expired1.example.org
issuer=/O=example.org/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICiTCCAfKgAwIBAgIBZzANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt
+MIICiTCCAfKgAwIBAgIBZzANBgkqhkiG9w0BAQsFADAzMRQwEgYDVQQKEwtleGFt
cGxlLm9yZzEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
-MzQwOVoXDTEyMTIwMTEyMzQwOVowHzEdMBsGA1UEAxMUZXhwaXJlZDEuZXhhbXBs
-ZS5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL3J/GWAVGm/d/nUnwDr
-3zeq85l1l1Zmp9r9XLUcw9cDbLM1hg4Ej557Cg9bXDZ7yCoa9tZnMUr6yKw1AxiV
-6DaoRt2HcPdAdge448/s96F8TtpfU9FOOm4iW2gAhhQVy/L0py76SPxadjI+IxwL
-MoaaIHevy6v+8wdafJVHe3cNAgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
+MzQzOVoXDTEyMTIwMTEyMzQzOVowHzEdMBsGA1UEAxMUZXhwaXJlZDEuZXhhbXBs
+ZS5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANBmkKDiZXSdKAc+3NsU
+eI3pcP31d5jcJehg9ighxXb9OHsALIZ9am/6x/rodBGBw5NckTtk11AQqrhjMxZr
+LgA973bLVK94VO57ZUipz3Kfb0zRiQzBy2qwAsEs70GSwT18sMOck0HavG1bQzxg
+OTlj2W1uNBYSO5XCBUOtCkOPAgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
A1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAj
hiFodHRwOi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEE
KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLm9yZy8wHwYDVR0R
-BBgwFoIUZXhwaXJlZDEuZXhhbXBsZS5vcmcwDQYJKoZIhvcNAQEFBQADgYEAChRl
-3S8Jylp0qbbYnIfnGFYgmzExHYuBkJv81j19n74NeD6cwmIE+rBL2+g459o1f3TZ
-ngfnX16kXvG2xCRozPbv8VAOiF7kGHg4RdQqS3GTlnxeDuGqTTZXhMkRHeEHNp1N
-J7d7YZlHna/txyMBbrg4oUESHhtUBzHC7zixHzo=
+BBgwFoIUZXhwaXJlZDEuZXhhbXBsZS5vcmcwDQYJKoZIhvcNAQELBQADgYEAQLkO
+5jBmejXkJLrCMPQBPQWFyG2jeNcvz+Nw5eP1bd8cKxyVaVk7ZnQrJS0BerNl4yIZ
+J54nxqJVbFFMq4OGVMzVdvkrvrkfEM60Xx9qkYawhIj1zQT0AbrbOqJSVJAxadUp
+GB6iqXETQykIg1VuhHzX5XQ9PH5ppKJEGMFiZVw=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA4WhcNMzgw\r
-MTAxMTIzNDA4WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp\r
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrlUzB\r
-ANKQi0cI+jOYOVy2EYu2LOXihiMHi3dX/boaZ2+rIwbWaaAy7gMXLvfay/ml+pyY\r
-hnxQbnfADZN0xXQoHZ3AjBIU6YP2CWpOk/3jrnjW7P84fCie/6SXhfH2l6ZZFaro\r
-yRw10jnO/kgEtFKBQpN7eZ2oPDaGGwuyBVaXqQIDAQABo1owWDAOBgNVHQ8BAf8E\r
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM5WhcNMzgw\r
+MTAxMTIzNDM5WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp\r
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCpoeV\r
+zjmqBMOrYxP7rj6aXYODfaD1lZTsnopvtoNJu2BBZO9sa2bVPBcF4uyMFBG1oiMs\r
+ojP+is6A30KLytVq+N04/jj9rpDUhVKet7upKwvj29ltl/8l9/jx00pJDunSHt8h\r
+OQaWSz/SZAqW9fA+xVqEZ9RCSv/Ugo2mdGb4xQIDAQABo1owWDAOBgNVHQ8BAf8E\r
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw\r
-Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA\r
-n2I9uY34QxYLfMCIwI3oMkR+v0ehEmjLcF3S2SILybtKFOxHUvFx10IiYJOCjPKr\r
-vTwbprTp4R9HffQyiGoe9jLYu+8Tfjf86hDcoChOg8SZm1u3rXCgXPus+19XON0g\r
-UWiJmIBAWDhz8+0vQ3QyrgtLuweoX4tTcbYOlTzO5KU=
+Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA\r
+IddoaqJ/H9Ya+Iz1wRpWziTi3z7goy9Rxd6Q8f85Nra4M/3Ax2irXtgQINRho37l\r
+RmoaXVy+pTU1ncQfRiVfQML2ce9+OCQ4p5rZFxZDhh0OxKaHKrfFTvHbeNB1FH8Z\r
+SH0mRVgnK1F+8TTkThNZctKe0jhqzsp41sRBPrYIEUk=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: expired1.example.org
- localKeyID: 99 C2 8F 9C 7D C1 19 76 88 B2 B0 83 4D 00 ED C9 E9 2B 7E EB
+ localKeyID: CB AF 4D EC E3 18 F0 8C C5 C7 C1 CB 9C 06 DD F8 FC B4 FD C5
Key Attributes: <No Attributes>
-----BEGIN ENCRYPTED PRIVATE KEY-----
-MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIEOl5NEvFezQCAggA
-MBQGCCqGSIb3DQMHBAgdwEOOYf+K8ASCAoCngEY2Iy7JaI0Pq/wcmj5CBp1cTDS3
-+CvdphRSw9W2LBNbCNjwQmyZptgDva4umoS3ex0vhiDiak+XzeBtHTdkDBhI5yW1
-H8+4+JgvEBphHYDOtMu6c27DeshuWUhh5xSJ42E+P7WDQXRB3ZbSPeR/WwpQWuc1
-Kf39b8M9dSNeOFkWuZ6lZSLVapNxZsQ1YmdOFIbzC31B94jdvKs5WL17sOO5P50b
-lUomYEs981S09uyt/Jaot7fNR6AAgZR8tZtA/Lf5sEr2H2OxLhyhX5GGHuM6kY1B
-BbX85yg2eZjw/XVREdmUHd7dO4eLAtYYY2wNOBllwfVY0+3Bi8YjAUJwwlgPwBmO
-0/MGDAYluRh8xApI/gdKxOnDhqY4Q85n3o7iczEyJDw5FtXORPaEGQ01zie2RT86
-LyUd2e6w6wtC+GNBPb15LwNMPmFFhhBfW/LnqFhb9xydquUPeH6Vs2veDWaqflnf
-cHR0ZXqfs3l/QWFtDOuvUoPxZoRSoKPxQtTsc3b8Mh6b69MgFsIu84vJHDGi2fbw
-vLFXscoEanMP2BRhBSjHHcIcoMcZHOgT915zDJArolc3aDhmf/qU1lOr7hXcPyW4
-ijixkJSRJV8Cvx3Qx62ToNzmXVYc2P/b1dG7wgms6vl+GFk5HUCrkV+D3OABuaKi
-f2BqzuoKTp5AUjPdFC9kFQ+7dApR6YI+MqWqAvBvSZmTYyGRuYVtuvvNxNK5qlKF
-pJMDA49V3WA2Dr3DLhOPo2ZbFUjj+1Ojm667Z+ls6TWinMoQKx+VbbBudbYHMj5h
-JLSjR9Y67quErC/yogcWfTdgQ/yN5LE4UPm7GaQEcvwQAzt6BQtN/U9i
+MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIhbmaWkVx36ICAggA
+MBQGCCqGSIb3DQMHBAgEMsxsOXFO7QSCAoAIjXzp+weJKxbB6RqHQGzbb2QBoHHk
+aBU+M/aochrN4/7p1Urj9t+c7bGZR7O4JjeJwbsI+LSh/FzR07RPWWr7amPOZ8lj
+5NZGtENPOdZK5o6giIpMJtW6QKzfkt3mwLCqrKACpRmqBv07BMs46yIzH+lGCt7U
+Y+Z/7x0mCK8OHBSAJmUTGslsEDwOKJoRRJj/XCUTRSK4W0IcQDNM24TRcq8jKh0U
+Ah3JpV1G8lc2aX0tsN3PFSV52pju9qSwdCwB8rJPM2kkpyh9dh3UzxC1WQJWGoLG
+8HebhOqLs60dDc4W0oZ+EPojgeKvL6phEA8LyEFkIUDmGCZnRgU+kE5KngQfgF2c
+q4I3lKHah1UIpzIQA8FUBB6kYvpsedEdgnJYn1ag3+FiMCRvO/QsplX1XH+g5bll
+IWsj+IosrOnKFPNTywk5Hly3IVRhG11u13NqP4kDXGYDDqPeOtTAqhcE3HGwHGIv
+6eaCrJHzSfvCaVugLnY1o07DCp4v4TaTsOHTjwe45Fe/lsdbhpf1t8hW8gRFoI/A
+BQFqosRedTzsxOVzc/lgZ2RXrh6abEoBSwguIL77sMdbRAH8p4sxaiyfuVwhjtws
+kKCP/Zj4SDctSZsIX+eZyd2zCY4yRhHp7ZuFVWSlDv6bkm1qWxEe+DgrRxQ60mdu
+s+naavKtXf0MjjbCgWq22eGPWDF9ZxbY4ZYbpCE06z02s9x4WHpqJ+jYH4v5dczo
+FLOWwBxWHDk8llDToLKuWJlLL9X91cTsZKGOexesZTndeZElzyhSo2S58XmW5gzf
+aMDTiUZrtkFmg1B7kO7FVpDhGKwsahZWnfkUAhxuP7UA4/29UA7zYIm7
-----END ENCRYPTED PRIVATE KEY-----
Bag Attributes
friendlyName: expired1.example.org
- localKeyID: 99 C2 8F 9C 7D C1 19 76 88 B2 B0 83 4D 00 ED C9 E9 2B 7E EB
+ localKeyID: CB AF 4D EC E3 18 F0 8C C5 C7 C1 CB 9C 06 DD F8 FC B4 FD C5
subject=/CN=expired1.example.org
issuer=/O=example.org/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICiTCCAfKgAwIBAgIBZzANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt
+MIICiTCCAfKgAwIBAgIBZzANBgkqhkiG9w0BAQsFADAzMRQwEgYDVQQKEwtleGFt
cGxlLm9yZzEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
-MzQwOVoXDTEyMTIwMTEyMzQwOVowHzEdMBsGA1UEAxMUZXhwaXJlZDEuZXhhbXBs
-ZS5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL3J/GWAVGm/d/nUnwDr
-3zeq85l1l1Zmp9r9XLUcw9cDbLM1hg4Ej557Cg9bXDZ7yCoa9tZnMUr6yKw1AxiV
-6DaoRt2HcPdAdge448/s96F8TtpfU9FOOm4iW2gAhhQVy/L0py76SPxadjI+IxwL
-MoaaIHevy6v+8wdafJVHe3cNAgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
+MzQzOVoXDTEyMTIwMTEyMzQzOVowHzEdMBsGA1UEAxMUZXhwaXJlZDEuZXhhbXBs
+ZS5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANBmkKDiZXSdKAc+3NsU
+eI3pcP31d5jcJehg9ighxXb9OHsALIZ9am/6x/rodBGBw5NckTtk11AQqrhjMxZr
+LgA973bLVK94VO57ZUipz3Kfb0zRiQzBy2qwAsEs70GSwT18sMOck0HavG1bQzxg
+OTlj2W1uNBYSO5XCBUOtCkOPAgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
A1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAj
hiFodHRwOi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEE
KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLm9yZy8wHwYDVR0R
-BBgwFoIUZXhwaXJlZDEuZXhhbXBsZS5vcmcwDQYJKoZIhvcNAQEFBQADgYEAChRl
-3S8Jylp0qbbYnIfnGFYgmzExHYuBkJv81j19n74NeD6cwmIE+rBL2+g459o1f3TZ
-ngfnX16kXvG2xCRozPbv8VAOiF7kGHg4RdQqS3GTlnxeDuGqTTZXhMkRHeEHNp1N
-J7d7YZlHna/txyMBbrg4oUESHhtUBzHC7zixHzo=
+BBgwFoIUZXhwaXJlZDEuZXhhbXBsZS5vcmcwDQYJKoZIhvcNAQELBQADgYEAQLkO
+5jBmejXkJLrCMPQBPQWFyG2jeNcvz+Nw5eP1bd8cKxyVaVk7ZnQrJS0BerNl4yIZ
+J54nxqJVbFFMq4OGVMzVdvkrvrkfEM60Xx9qkYawhIj1zQT0AbrbOqJSVJAxadUp
+GB6iqXETQykIg1VuhHzX5XQ9PH5ppKJEGMFiZVw=
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
-MIICWwIBAAKBgQC9yfxlgFRpv3f51J8A6983qvOZdZdWZqfa/Vy1HMPXA2yzNYYO
-BI+eewoPW1w2e8gqGvbWZzFK+sisNQMYleg2qEbdh3D3QHYHuOPP7PehfE7aX1PR
-TjpuIltoAIYUFcvy9Kcu+kj8WnYyPiMcCzKGmiB3r8ur/vMHWnyVR3t3DQIDAQAB
-AoGAE9BUk1w0c93Tbret6fC2Gx+z0t+d7x1EhO5SkW3xXC81V/hMiIYdYFREFppZ
-JC8EFLE/995KHSPVc3UNX7G2zl/j5ArHzer4E3AcFPGmp1VbY0rhzN+quoK5ihzQ
-u58vR2XzIv1XPxZcfgCy7IB7Hq2kiq2dFwpK5VBlBpLuI8ECQQDp9bVXD4V9XQ/+
-YNsI7APATQpg9CXQS3tIkwCJE1hDMYT6rFrYFg6qmSlSKeYvcJKFQ4qdC/vUmaJ0
-/N8nXqn1AkEAz6sIXDzmeJCu/Cg4jIHQUgShvMeyBbGBRrx5fOEYKxh/4+Jl9pAn
-LCzKxEcj68krND8rGmPrdJW5LwvCsufxuQJAePDRGv4lDVcMK305/PS0Q7YPhWrw
-GSrLwgprnnBnkeSJT2PFWiqczkd6esS5/w/8TfNKNkC5n38D4eHOIXXn+QJARExp
-2XwmCGz9P+0ye/ONwgvH7cB3qiuw6sS95/ZX7oSGOzqQckECwSKSJW+IPtnQncRQ
-tsM6AwPi/bgOdqyV8QJAcCGZoUWDmiMpnYl5XScX/5oVlEdD+PvFn6DAH6Y/IYtV
-5GM7VZpSvK9pZi0JpgdHEOIz3FjVyIV8U9RD1LGqZw==
+MIICXAIBAAKBgQDQZpCg4mV0nSgHPtzbFHiN6XD99XeY3CXoYPYoIcV2/Th7ACyG
+fWpv+sf66HQRgcOTXJE7ZNdQEKq4YzMWay4APe92y1SveFTue2VIqc9yn29M0YkM
+wctqsALBLO9BksE9fLDDnJNB2rxtW0M8YDk5Y9ltbjQWEjuVwgVDrQpDjwIDAQAB
+AoGAR9mEtaM4fWsNeOoIdRPquGqqhTRTJoWIIEUFuTJjhTGqfmXB9CBbSP46Ylww
+YDTP/AdnHwYWYclNQsMYwvry4YyRglSnhQrHgoI7C9qGVu8d/vNiqHfTKkzBxZW1
+KGSb2+6vFs4rJjYJx5E+o+wtArzcDfSu2IdKIgwDDAgmdYECQQD8iwUMRkCZMH2m
+1OGidbHlSYpHFq5bkuyYINPu3LIRJV3fBOKWLfctGAPhOSX+EA4/aERgXMRrglhv
+Pp3RqN9PAkEA00Dbre1dS6d9q4scRG2ZArGjeyrGybOi4erONzWgJxGHX0b1Kqy2
+G04JelTlqrIjHGOIVJwyab/rnxrOYcVHwQJAHn4GoQHGgPia407m43/EeAPWH1k8
+ui/WQ1QLYtbg5TMWz3u+hBWOt7IjnckRrkhv//Xt85if2r9FQEFWOt9h/wJBALgs
+Y1lPB3ddnoJf1VUS98MRe6V1tblDk03Cl+YqKmXlMlAuXK/Hwzwq3Lh6K4CVrWai
+n8ikJI9tcs5TYHp8tAECQAMHdSMuqtW5kS+hWYpufUIbEpej9iznAynH+XNK+E6p
++LdfUdiHdAFS4b6j83YgnTYD/QwyEjV0r7vmmn1A8Eg=
-----END RSA PRIVATE KEY-----
subject=/O=example.org/CN=clica Signing Cert
issuer=/O=example.org/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA4WhcNMzgw
-MTAxMTIzNDA4WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrlUzB
-ANKQi0cI+jOYOVy2EYu2LOXihiMHi3dX/boaZ2+rIwbWaaAy7gMXLvfay/ml+pyY
-hnxQbnfADZN0xXQoHZ3AjBIU6YP2CWpOk/3jrnjW7P84fCie/6SXhfH2l6ZZFaro
-yRw10jnO/kgEtFKBQpN7eZ2oPDaGGwuyBVaXqQIDAQABo1owWDAOBgNVHQ8BAf8E
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM5WhcNMzgw
+MTAxMTIzNDM5WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCpoeV
+zjmqBMOrYxP7rj6aXYODfaD1lZTsnopvtoNJu2BBZO9sa2bVPBcF4uyMFBG1oiMs
+ojP+is6A30KLytVq+N04/jj9rpDUhVKet7upKwvj29ltl/8l9/jx00pJDunSHt8h
+OQaWSz/SZAqW9fA+xVqEZ9RCSv/Ugo2mdGb4xQIDAQABo1owWDAOBgNVHQ8BAf8E
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw
-Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA
-n2I9uY34QxYLfMCIwI3oMkR+v0ehEmjLcF3S2SILybtKFOxHUvFx10IiYJOCjPKr
-vTwbprTp4R9HffQyiGoe9jLYu+8Tfjf86hDcoChOg8SZm1u3rXCgXPus+19XON0g
-UWiJmIBAWDhz8+0vQ3QyrgtLuweoX4tTcbYOlTzO5KU=
+Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA
+IddoaqJ/H9Ya+Iz1wRpWziTi3z7goy9Rxd6Q8f85Nra4M/3Ax2irXtgQINRho37l
+RmoaXVy+pTU1ncQfRiVfQML2ce9+OCQ4p5rZFxZDhh0OxKaHKrfFTvHbeNB1FH8Z
+SH0mRVgnK1F+8TTkThNZctKe0jhqzsp41sRBPrYIEUk=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: Certificate Authority
subject=/O=example.org/CN=clica CA
issuer=/O=example.org/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA4WhcNMzgw
-MTAxMTIzNDA4WjApMRQwEgYDVQQKEwtleGFtcGxlLm9yZzERMA8GA1UEAxMIY2xp
-Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmGE/1NBbn57y9RAMTa
-/jWgErk9jUKo+z0vzO5me7MUE+C3Jhk2YFF+w3ryEny3DikQOZEdRU4NFrQKZKu5
-1jjYg5ilg8EJTP6h9GzZmacH9olW3hdMvVqMkiLuZF97H41AYx95XPDibxwrpMgD
-oDVoYTQIPBwdjj8d88SdbgYjAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
-DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBAINsDZLZin7u8iOLguRG
-37mUDNhAQ9qUAtiFV8JnjJU9DZGb0TvSpYmOkjK2iH4cH6AsEXptB6duvkkpp6ly
-+aGvlqy69D/MfPpLjLX7e6WOISshaWCGB7/rQqbRtAePFpa07gijUqxM22LfiHXz
-YHJSTjLx4idfdLNS+U5iir1Y
------END CERTIFICATE-----
-Bag Attributes
- friendlyName: expired2.example.org
- localKeyID: BB 61 99 E6 F7 7B 14 59 32 E1 10 99 42 D0 42 05 CB 5C E4 7F
-subject=/CN=expired2.example.org
-issuer=/O=example.org/CN=clica Signing Cert
------BEGIN CERTIFICATE-----
-MIICijCCAfOgAwIBAgICAMswDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhh
-bXBsZS5vcmcxGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDEx
-MjM0MTFaFw0xMjEyMDExMjM0MTFaMB8xHTAbBgNVBAMTFGV4cGlyZWQyLmV4YW1w
-bGUub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUaWxrKTL6SzYcTEyX
-FVJZqEYxiTWmks5kA//fGFICyMaOIeBUgk4m+8jHrXqfSZh7hnzk9RuTp+/bbROh
-pUKnJWbMvjbQ2bxuCeRgzvvJYtGfVRqYA7dARY0cQuTa1lo9YsGFW6ojLUvbrhMp
-gXxrrOQx2+omKoYulM76Une5sQIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
-BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
-I4YhaHR0cDovL2NybC5leGFtcGxlLm9yZy9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
-BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5vcmcvMB8GA1Ud
-EQQYMBaCFGV4cGlyZWQyLmV4YW1wbGUub3JnMA0GCSqGSIb3DQEBBQUAA4GBAJE7
-jNxIZvZcwM6UIWS8qYG93YfOdNNvzk6JfxGA4jyUFmdbTYYThKK7X6q+cStAWcpd
-8AQsYqlfuUqwwXgeEDkdtMKdB4N/sz8Cbj0UfuHJSVxIiJ/22QNnUk8lrH2+llQz
-y3Ahp9noeQCXD/eplTuTSlksu8rvMddKMvSA9p3C
+MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM5WhcNMzgw
+MTAxMTIzNDM5WjApMRQwEgYDVQQKEwtleGFtcGxlLm9yZzERMA8GA1UEAxMIY2xp
+Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMmC4zNWYntPtKW8nuwo
+JbC14Cwuck7DufEvR6WAtos3NUxjWpS4rQl7bW62AoaSdX0bSIxpyS2wtgQxIoFJ
+yU0Ukseh5lTpAvXEgKyjutRJswbQj0w94O0487KcyBqd1ZDJHJYs9VJ+BfrETwwc
+74Tk8FUQHaH6EQJ28GIJUIJfAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
+DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBAISxe2t3sJCPBKD6wyb/
+lAsOu+Llby0cXetGKzGhC+HFHvI5OsjhMtOE5uGp7UYlJzbRrfMx/gSR9pjaXxah
+Bt7JFvcPI6wSDU4bBClsuvMTisenANOOscWHSEvB/YQes3OLnqC2RGSppKshjwVF
+fdbkhlMTV2Oyub2TvrscntOV
-----END CERTIFICATE-----
Bag Attributes
friendlyName: expired2.example.org
- localKeyID: BB 61 99 E6 F7 7B 14 59 32 E1 10 99 42 D0 42 05 CB 5C E4 7F
+ localKeyID: 38 7A 92 D7 7E DA 54 41 9B AD 17 1C 7C C4 DC 21 56 A2 7B BC
subject=/CN=expired2.example.org
issuer=/O=example.org/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICijCCAfOgAwIBAgICAMswDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhh
+MIICijCCAfOgAwIBAgICAMswDQYJKoZIhvcNAQELBQAwMzEUMBIGA1UEChMLZXhh
bXBsZS5vcmcxGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDEx
-MjM0MTFaFw0xMjEyMDExMjM0MTFaMB8xHTAbBgNVBAMTFGV4cGlyZWQyLmV4YW1w
-bGUub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUaWxrKTL6SzYcTEyX
-FVJZqEYxiTWmks5kA//fGFICyMaOIeBUgk4m+8jHrXqfSZh7hnzk9RuTp+/bbROh
-pUKnJWbMvjbQ2bxuCeRgzvvJYtGfVRqYA7dARY0cQuTa1lo9YsGFW6ojLUvbrhMp
-gXxrrOQx2+omKoYulM76Une5sQIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
+MjM0NDBaFw0xMjEyMDExMjM0NDBaMB8xHTAbBgNVBAMTFGV4cGlyZWQyLmV4YW1w
+bGUub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDQ+5aNT2L7hnoAMQeA
+RfTbno6NCWYB5PdJSAMguibxmax0hgU2k0fdmnVhd5w4Y6IDGLd6wFW5WVba5YCM
+LizGvoz8x7tPz/XvODi3uUYgXev7bAOlKXYFeCLwvu4W/Jp1pO0sPn+jW8B/idBB
+JoVc3Lq9QdMqJ6ItzMlUHKS32QIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
I4YhaHR0cDovL2NybC5leGFtcGxlLm9yZy9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5vcmcvMB8GA1Ud
-EQQYMBaCFGV4cGlyZWQyLmV4YW1wbGUub3JnMA0GCSqGSIb3DQEBBQUAA4GBAJE7
-jNxIZvZcwM6UIWS8qYG93YfOdNNvzk6JfxGA4jyUFmdbTYYThKK7X6q+cStAWcpd
-8AQsYqlfuUqwwXgeEDkdtMKdB4N/sz8Cbj0UfuHJSVxIiJ/22QNnUk8lrH2+llQz
-y3Ahp9noeQCXD/eplTuTSlksu8rvMddKMvSA9p3C
+EQQYMBaCFGV4cGlyZWQyLmV4YW1wbGUub3JnMA0GCSqGSIb3DQEBCwUAA4GBAFRy
+WES/CS3uN3SUPueFsg5wd/dQMKEjlwlNE+f2kzoJJxswrUB6whlPWR0jQwlde4/5
+TVJsgW3iviP5PVH10Pg+kEk9CCJKha0pTyaKEatnyb4igrt6pLf5KcPjWMTo9gxW
+WAFUb6Zih2/saGCqM31rPArlNwOwkgE+Vjrhd7MR
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA4WhcNMzgw\r
-MTAxMTIzNDA4WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp\r
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrlUzB\r
-ANKQi0cI+jOYOVy2EYu2LOXihiMHi3dX/boaZ2+rIwbWaaAy7gMXLvfay/ml+pyY\r
-hnxQbnfADZN0xXQoHZ3AjBIU6YP2CWpOk/3jrnjW7P84fCie/6SXhfH2l6ZZFaro\r
-yRw10jnO/kgEtFKBQpN7eZ2oPDaGGwuyBVaXqQIDAQABo1owWDAOBgNVHQ8BAf8E\r
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM5WhcNMzgw\r
+MTAxMTIzNDM5WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp\r
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCpoeV\r
+zjmqBMOrYxP7rj6aXYODfaD1lZTsnopvtoNJu2BBZO9sa2bVPBcF4uyMFBG1oiMs\r
+ojP+is6A30KLytVq+N04/jj9rpDUhVKet7upKwvj29ltl/8l9/jx00pJDunSHt8h\r
+OQaWSz/SZAqW9fA+xVqEZ9RCSv/Ugo2mdGb4xQIDAQABo1owWDAOBgNVHQ8BAf8E\r
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw\r
-Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA\r
-n2I9uY34QxYLfMCIwI3oMkR+v0ehEmjLcF3S2SILybtKFOxHUvFx10IiYJOCjPKr\r
-vTwbprTp4R9HffQyiGoe9jLYu+8Tfjf86hDcoChOg8SZm1u3rXCgXPus+19XON0g\r
-UWiJmIBAWDhz8+0vQ3QyrgtLuweoX4tTcbYOlTzO5KU=
+Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA\r
+IddoaqJ/H9Ya+Iz1wRpWziTi3z7goy9Rxd6Q8f85Nra4M/3Ax2irXtgQINRho37l\r
+RmoaXVy+pTU1ncQfRiVfQML2ce9+OCQ4p5rZFxZDhh0OxKaHKrfFTvHbeNB1FH8Z\r
+SH0mRVgnK1F+8TTkThNZctKe0jhqzsp41sRBPrYIEUk=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: expired2.example.org
- localKeyID: BB 61 99 E6 F7 7B 14 59 32 E1 10 99 42 D0 42 05 CB 5C E4 7F
+ localKeyID: 38 7A 92 D7 7E DA 54 41 9B AD 17 1C 7C C4 DC 21 56 A2 7B BC
Key Attributes: <No Attributes>
-----BEGIN ENCRYPTED PRIVATE KEY-----
-MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQISqiwtlVu2dUCAggA
-MBQGCCqGSIb3DQMHBAgI9HkegsmvpQSCAoA3dgmkiQthpGrdWwOEUqZpajmMqivG
-RQv9Qxg4JoTSoHm9WkR+0x4vHahAaqYKDq6ca9uIHFx2dOTXH589F0lrGf+osmiB
-L44C1z8aqYjJcYBPmeVHtSJsr5XFpBSWv88OQ85Z/qqtXL3jdRC98IywmDRqjYa/
-xoJyfGlLuz530Rv1iLcNQ3XGkoxmxlbV1WrmhkRythD7psUVHClt/InkFX4I6iQl
-msOkNP5RBIn8BED4mHhZ2PTDAIyANgpWTeBwBOEilb/mVdctzqM1XgyzZ2469zJ+
-ZFoPTN7gtXmuNXSOBCvAJQT0vL8GYQNIkdfWi+cfhC3azq2MZcdWzIPjvSyht42c
-4O4of89tUqrgLkvUiVaO74WqLtmwtTdgQg4ZIin8HPXNsVm7tYB5LMvHPKdoFOZ8
-FTD0XWWgDwoZ5tTOp31Kz5Tczab3eJ+lgPK4bqqtLusobwfI8YmCZGYrS6V+S6RZ
-Qk0xrYo8mYjpjmjmpr2xkEiQ4YQiEwmuwzw4eNT1bAGL2V+hwDuxjD7f+pMQfKai
-5VChf0VEHb+1pwIjnMfY4ua99IhP5bj/7Z2327CkehtzLF4ineRkVnVXy9ELomn+
-8bIFt5qBeaHfijX1MPn2Lugs8bY0xhQaRR15yBI4fQ62ekvxntLSmp5BLnaSLFsW
-gjxjzRL5X4jtjSZtoxypHWBxKMW7fdxbqxAVKba1rLygqAt5QmsS5kKUDjEJBv0q
-0yrdjo2Tb8UtY75oNw59cF9hgfV6xtyGLgyjw8f3eQQ88i8nKBQ+iLpHOF5t/waf
-1vopHqu/zJEDskIwJpkEM3L3/wy//NMDCpop3BF7Si/aqy/j7mZUtUFV
+MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQINRAqyFrpUUsCAggA
+MBQGCCqGSIb3DQMHBAhH+bOO/ETpdgSCAoBBsrXfvxAGbG/fUB1XqSwhzLDw37V9
+yBA9Hel4O+kDfkkRBMWT+vX3472QeRXRjnaDm57OTFSwq9kDXOu2Xn/wcbyYre2N
+hIkQUwxblza05FgNlwSDtkXbhGSj6A7m1nL/5DSZIfi1vw+tAxR8l5ed1Zrxl9Mf
+kaAAKMazbessK4hbgjvU39X56JVpL1UE9ITnPdTtoPZLMO0iYT6VwkQDK6yAj5gQ
+v3il1RTUhqqfTsrDZcL+Pj8nT++9R5uIxDmto6iWFRCObur9zV6VjKoR8du3Arbl
+fSr/GeKA8ToEFS9ssa0hctkrQkFyhWPUNbSmeMmp+cpS5h8j8ULFb6bTtjDbYUU+
+vryAb7UFD2JVdF66yPBlvsO2FEQLpAF9BbgTlw8h1ULkrmquOmReCzCv1j7y5S/X
+CfOW+9I7O7dHu1NNJT5dA2IRXvhoq9mFoP3cF19fgfYgmOSZYBRFpwf3zTzo1MPj
+ewMGdz6+pwWU+YGZZRbuGxqGCl2kr/SJOeex+BDxLd2cPyLBINnOE2eJ4BigRAad
+9KNEUYnGB/7OluRJLwqFoFGtk5VIRMphZVcxQSmXv8rHebMXlVeSCHZ6wtw0VBGS
+Ibwou6ujzAffMAISx7SfBMPRpzhkkqUL+WWTWwTwyITexCym+X4EsxRxGfKKifRW
+unmRGZWFYOUF8f/zURT7eeCNC9K+Ud3aICQixcYsaew8hPB1kYawZ7WOMgJ3Q1Y4
+5BNdnhwtmdEyqRAsB2p0KjfTpM+cg5VR4H0AYcJNlX6F41hWsspwc3DOfUDqDMIU
+DsARGxauT7xT38MtXGa3iiI71TJ07uVywIMATMQoILh3lE0bqr8MGYwT
-----END ENCRYPTED PRIVATE KEY-----
Bag Attributes
friendlyName: expired2.example.org
- localKeyID: BB 61 99 E6 F7 7B 14 59 32 E1 10 99 42 D0 42 05 CB 5C E4 7F
+ localKeyID: 38 7A 92 D7 7E DA 54 41 9B AD 17 1C 7C C4 DC 21 56 A2 7B BC
subject=/CN=expired2.example.org
issuer=/O=example.org/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICijCCAfOgAwIBAgICAMswDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhh
+MIICijCCAfOgAwIBAgICAMswDQYJKoZIhvcNAQELBQAwMzEUMBIGA1UEChMLZXhh
bXBsZS5vcmcxGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDEx
-MjM0MTFaFw0xMjEyMDExMjM0MTFaMB8xHTAbBgNVBAMTFGV4cGlyZWQyLmV4YW1w
-bGUub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUaWxrKTL6SzYcTEyX
-FVJZqEYxiTWmks5kA//fGFICyMaOIeBUgk4m+8jHrXqfSZh7hnzk9RuTp+/bbROh
-pUKnJWbMvjbQ2bxuCeRgzvvJYtGfVRqYA7dARY0cQuTa1lo9YsGFW6ojLUvbrhMp
-gXxrrOQx2+omKoYulM76Une5sQIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
+MjM0NDBaFw0xMjEyMDExMjM0NDBaMB8xHTAbBgNVBAMTFGV4cGlyZWQyLmV4YW1w
+bGUub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDQ+5aNT2L7hnoAMQeA
+RfTbno6NCWYB5PdJSAMguibxmax0hgU2k0fdmnVhd5w4Y6IDGLd6wFW5WVba5YCM
+LizGvoz8x7tPz/XvODi3uUYgXev7bAOlKXYFeCLwvu4W/Jp1pO0sPn+jW8B/idBB
+JoVc3Lq9QdMqJ6ItzMlUHKS32QIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
I4YhaHR0cDovL2NybC5leGFtcGxlLm9yZy9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5vcmcvMB8GA1Ud
-EQQYMBaCFGV4cGlyZWQyLmV4YW1wbGUub3JnMA0GCSqGSIb3DQEBBQUAA4GBAJE7
-jNxIZvZcwM6UIWS8qYG93YfOdNNvzk6JfxGA4jyUFmdbTYYThKK7X6q+cStAWcpd
-8AQsYqlfuUqwwXgeEDkdtMKdB4N/sz8Cbj0UfuHJSVxIiJ/22QNnUk8lrH2+llQz
-y3Ahp9noeQCXD/eplTuTSlksu8rvMddKMvSA9p3C
+EQQYMBaCFGV4cGlyZWQyLmV4YW1wbGUub3JnMA0GCSqGSIb3DQEBCwUAA4GBAFRy
+WES/CS3uN3SUPueFsg5wd/dQMKEjlwlNE+f2kzoJJxswrUB6whlPWR0jQwlde4/5
+TVJsgW3iviP5PVH10Pg+kEk9CCJKha0pTyaKEatnyb4igrt6pLf5KcPjWMTo9gxW
+WAFUb6Zih2/saGCqM31rPArlNwOwkgE+Vjrhd7MR
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
-MIICXAIBAAKBgQCUaWxrKTL6SzYcTEyXFVJZqEYxiTWmks5kA//fGFICyMaOIeBU
-gk4m+8jHrXqfSZh7hnzk9RuTp+/bbROhpUKnJWbMvjbQ2bxuCeRgzvvJYtGfVRqY
-A7dARY0cQuTa1lo9YsGFW6ojLUvbrhMpgXxrrOQx2+omKoYulM76Une5sQIDAQAB
-AoGAGASPpS//rf3p/d5jLrgmoZfX9EBOTGzJtennyMT40LaJW4sj8Mk9uJVawuXS
-SGDyqlrzb2IzWkv9Rzd5y9kg1gjiJ675pVl1Z0vDhZZWYGVI3VKJh1TmYC2lPra3
-53t9N788B7fgT6bTW8KRfk2rCp0UU+hIffDgmv9wK9l/RPkCQQDEbF9VoFlVFRxX
-nLBdU9IHLSZQzIgUV/OVvL8gAIJycTupT3H6CINMDfFZHcFfaKNytzzXBS2jKzSh
-Fzl2s+ofAkEAwW0dMnz4VhlG84cKhxdFCjic2dneWMNACc/GnfopGIlkrSQW3AGz
-yjDFQj8BIqwhPhyFGpu7nxfgtBBOW/SCLwJACMXKUDm0I6+or2UJH3Hx7G4gyvUH
-ktkGwQZIBvbe3JugDYTF02Pz8T6iK9e/XjJ/Mk1qwzOxARuZ4yP1Zg7NAwJAO6mj
-gupHU49ycjWqSqcj1ZZG02+/hNOdEimz0xDR0k627i0em/guc+R9RATZHc/IZTc4
-209EHTupRQFumjCeYwJBAI38tud4nIYB2/x53KOG18eBtc+QQM8gX7XwRaiK936V
-mvNng2HahharF0WKqhkmLNCOR4c7nGhUs2OHoi7vDNQ=
+MIICXQIBAAKBgQDQ+5aNT2L7hnoAMQeARfTbno6NCWYB5PdJSAMguibxmax0hgU2
+k0fdmnVhd5w4Y6IDGLd6wFW5WVba5YCMLizGvoz8x7tPz/XvODi3uUYgXev7bAOl
+KXYFeCLwvu4W/Jp1pO0sPn+jW8B/idBBJoVc3Lq9QdMqJ6ItzMlUHKS32QIDAQAB
+AoGAe/Q+ICLuOvJQeryaDmNwELPDKbRhZM5CPp0P/eFsJ/FWcObtQKmq/q4W4XDo
+oCm4ds26Rny+W+m5sqxdyse4ljccOjf+tlrYKHlqD7KeLex4G8WY2XAV6oR0pS5a
+siFbpNsRZ6CwMaNFn/qXtd+XX7auCCFGDqfdB92QNcait4ECQQDoSq502bkiu2aQ
+R/mYCNgTiKlOqvSgub/NWn99WgOO/OTwXYlp16FX4TDp6YmHyEFc/zCV8CXEbuB5
+9I6lVEktAkEA5k/j3unsfdI/M6VyjDSV7pHXNsNicpyXQv9iAp6pm8hpGBiMbOtT
+LleDuvvXV2ubbshcJwZ5oICYA81SF4c83QJBAJtU1TPuI47GId95Qb4Yq+TkDdM9
+Hjgb/dYkHfyEpLyI/857vde5CXrqavr/36eckZjOTH73B0pDmnfywTBtHEECQQDh
+z3KcHL7CnmFZQd4NmYFnZ5abGvZraRzlk3+FEgs5skVYWrlUEWZ9CVEfA80e6WJ8
+O/YeTTrzIyHomGbkqrQBAkBMR8RICK61Gl8bHxv3NsKvvZiUH9H7rPPdBzMPGHll
+4YFtO29mdpHuprE+bpiEfNG4+ouCqEJOfydGBy1qEKqx
-----END RSA PRIVATE KEY-----
subject=/O=example.org/CN=clica Signing Cert
issuer=/O=example.org/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA4WhcNMzgw
-MTAxMTIzNDA4WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrlUzB
-ANKQi0cI+jOYOVy2EYu2LOXihiMHi3dX/boaZ2+rIwbWaaAy7gMXLvfay/ml+pyY
-hnxQbnfADZN0xXQoHZ3AjBIU6YP2CWpOk/3jrnjW7P84fCie/6SXhfH2l6ZZFaro
-yRw10jnO/kgEtFKBQpN7eZ2oPDaGGwuyBVaXqQIDAQABo1owWDAOBgNVHQ8BAf8E
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM5WhcNMzgw
+MTAxMTIzNDM5WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCpoeV
+zjmqBMOrYxP7rj6aXYODfaD1lZTsnopvtoNJu2BBZO9sa2bVPBcF4uyMFBG1oiMs
+ojP+is6A30KLytVq+N04/jj9rpDUhVKet7upKwvj29ltl/8l9/jx00pJDunSHt8h
+OQaWSz/SZAqW9fA+xVqEZ9RCSv/Ugo2mdGb4xQIDAQABo1owWDAOBgNVHQ8BAf8E
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw
-Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA
-n2I9uY34QxYLfMCIwI3oMkR+v0ehEmjLcF3S2SILybtKFOxHUvFx10IiYJOCjPKr
-vTwbprTp4R9HffQyiGoe9jLYu+8Tfjf86hDcoChOg8SZm1u3rXCgXPus+19XON0g
-UWiJmIBAWDhz8+0vQ3QyrgtLuweoX4tTcbYOlTzO5KU=
+Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA
+IddoaqJ/H9Ya+Iz1wRpWziTi3z7goy9Rxd6Q8f85Nra4M/3Ax2irXtgQINRho37l
+RmoaXVy+pTU1ncQfRiVfQML2ce9+OCQ4p5rZFxZDhh0OxKaHKrfFTvHbeNB1FH8Z
+SH0mRVgnK1F+8TTkThNZctKe0jhqzsp41sRBPrYIEUk=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: Certificate Authority
subject=/O=example.org/CN=clica CA
issuer=/O=example.org/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA4WhcNMzgw
-MTAxMTIzNDA4WjApMRQwEgYDVQQKEwtleGFtcGxlLm9yZzERMA8GA1UEAxMIY2xp
-Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmGE/1NBbn57y9RAMTa
-/jWgErk9jUKo+z0vzO5me7MUE+C3Jhk2YFF+w3ryEny3DikQOZEdRU4NFrQKZKu5
-1jjYg5ilg8EJTP6h9GzZmacH9olW3hdMvVqMkiLuZF97H41AYx95XPDibxwrpMgD
-oDVoYTQIPBwdjj8d88SdbgYjAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
-DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBAINsDZLZin7u8iOLguRG
-37mUDNhAQ9qUAtiFV8JnjJU9DZGb0TvSpYmOkjK2iH4cH6AsEXptB6duvkkpp6ly
-+aGvlqy69D/MfPpLjLX7e6WOISshaWCGB7/rQqbRtAePFpa07gijUqxM22LfiHXz
-YHJSTjLx4idfdLNS+U5iir1Y
------END CERTIFICATE-----
-Bag Attributes
- friendlyName: revoked1.example.org
- localKeyID: BD BF 30 04 34 2D 03 C9 AA FE 25 10 2C DB 7C 74 89 B0 9A C9
-subject=/CN=revoked1.example.org
-issuer=/O=example.org/CN=clica Signing Cert
------BEGIN CERTIFICATE-----
-MIICiTCCAfKgAwIBAgIBZjANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt
-cGxlLm9yZzEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
-MzQwOVoXDTM4MDEwMTEyMzQwOVowHzEdMBsGA1UEAxMUcmV2b2tlZDEuZXhhbXBs
-ZS5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMOKMcTBoKYBCz8Sxb/B
-5/RGvTdDMmkNO/e91ni4S/3OjvvksMmg38fv1e4DQOazkE4dp9ttllheaw0O6lEO
-cpuFSFC6BLDlaDEaJqDAlm9++vTZ+azhM1nUIKbUhmlPSMnagL1GhWBX1w3EVP2F
-n02386NEAY/kPJMoR2r/4Kb5AgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
-A1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAj
-hiFodHRwOi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEE
-KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLm9yZy8wHwYDVR0R
-BBgwFoIUcmV2b2tlZDEuZXhhbXBsZS5vcmcwDQYJKoZIhvcNAQEFBQADgYEAc4B0
-aoj+H7UoNbV39uIQIV3Z//V+AqQuOaBtUTf3izNDG/r3tpJ+La6s6FxH55dRvQdc
-lvF6WdHgD++J5Vx7MUVcXMyVmpJrLpnJk4BBSFMn/fgvoPFfONL1p9Z33HnIUrY1
-hCmJrHtAqS0pztH5YioEH97ihYz5Teoc6mws/Yc=
+MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM5WhcNMzgw
+MTAxMTIzNDM5WjApMRQwEgYDVQQKEwtleGFtcGxlLm9yZzERMA8GA1UEAxMIY2xp
+Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMmC4zNWYntPtKW8nuwo
+JbC14Cwuck7DufEvR6WAtos3NUxjWpS4rQl7bW62AoaSdX0bSIxpyS2wtgQxIoFJ
+yU0Ukseh5lTpAvXEgKyjutRJswbQj0w94O0487KcyBqd1ZDJHJYs9VJ+BfrETwwc
+74Tk8FUQHaH6EQJ28GIJUIJfAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
+DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBAISxe2t3sJCPBKD6wyb/
+lAsOu+Llby0cXetGKzGhC+HFHvI5OsjhMtOE5uGp7UYlJzbRrfMx/gSR9pjaXxah
+Bt7JFvcPI6wSDU4bBClsuvMTisenANOOscWHSEvB/YQes3OLnqC2RGSppKshjwVF
+fdbkhlMTV2Oyub2TvrscntOV
-----END CERTIFICATE-----
Bag Attributes
friendlyName: revoked1.example.org
- localKeyID: BD BF 30 04 34 2D 03 C9 AA FE 25 10 2C DB 7C 74 89 B0 9A C9
+ localKeyID: 92 C5 45 B6 00 77 BA 8B F9 80 EA 9D E1 C8 CF 26 8E 4A AB 64
subject=/CN=revoked1.example.org
issuer=/O=example.org/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICiTCCAfKgAwIBAgIBZjANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt
+MIICiTCCAfKgAwIBAgIBZjANBgkqhkiG9w0BAQsFADAzMRQwEgYDVQQKEwtleGFt
cGxlLm9yZzEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
-MzQwOVoXDTM4MDEwMTEyMzQwOVowHzEdMBsGA1UEAxMUcmV2b2tlZDEuZXhhbXBs
-ZS5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMOKMcTBoKYBCz8Sxb/B
-5/RGvTdDMmkNO/e91ni4S/3OjvvksMmg38fv1e4DQOazkE4dp9ttllheaw0O6lEO
-cpuFSFC6BLDlaDEaJqDAlm9++vTZ+azhM1nUIKbUhmlPSMnagL1GhWBX1w3EVP2F
-n02386NEAY/kPJMoR2r/4Kb5AgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
+MzQzOVoXDTM4MDEwMTEyMzQzOVowHzEdMBsGA1UEAxMUcmV2b2tlZDEuZXhhbXBs
+ZS5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMFKQOMflyggZWs8aPiS
+zZ2CH47ISXmXJNKk5/nTZZ+NgyOpV34fDOjLBsw9UT1NMCLiec3z7qCMT4eeFXWm
+g9d3mC4Gwlaw1Kn+DdFFQxvpGb5C22K7tHafoefdtprGTpcGQ90FDtmUCY6fGSbW
+A8UyxttXLmTE/pPz9OkfvQlxAgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
A1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAj
hiFodHRwOi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEE
KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLm9yZy8wHwYDVR0R
-BBgwFoIUcmV2b2tlZDEuZXhhbXBsZS5vcmcwDQYJKoZIhvcNAQEFBQADgYEAc4B0
-aoj+H7UoNbV39uIQIV3Z//V+AqQuOaBtUTf3izNDG/r3tpJ+La6s6FxH55dRvQdc
-lvF6WdHgD++J5Vx7MUVcXMyVmpJrLpnJk4BBSFMn/fgvoPFfONL1p9Z33HnIUrY1
-hCmJrHtAqS0pztH5YioEH97ihYz5Teoc6mws/Yc=
+BBgwFoIUcmV2b2tlZDEuZXhhbXBsZS5vcmcwDQYJKoZIhvcNAQELBQADgYEASoDf
+KWa0eBRyOr/s6iYBE/92HwEYzYRJTQ72WYOyWzgxgEQFNUGSoPDm5/Uz8RtCN7WA
+jP3izpoDT9RljW/381kJjfcyhApK6P20d9Wh6jTbVNEyh2MU8GaU5Yx7q2MWuxCW
+LUxer4bHOOBFsKtScIJJ/5FIUxV2X/jTvXdX9uU=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA4WhcNMzgw\r
-MTAxMTIzNDA4WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp\r
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrlUzB\r
-ANKQi0cI+jOYOVy2EYu2LOXihiMHi3dX/boaZ2+rIwbWaaAy7gMXLvfay/ml+pyY\r
-hnxQbnfADZN0xXQoHZ3AjBIU6YP2CWpOk/3jrnjW7P84fCie/6SXhfH2l6ZZFaro\r
-yRw10jnO/kgEtFKBQpN7eZ2oPDaGGwuyBVaXqQIDAQABo1owWDAOBgNVHQ8BAf8E\r
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM5WhcNMzgw\r
+MTAxMTIzNDM5WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp\r
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCpoeV\r
+zjmqBMOrYxP7rj6aXYODfaD1lZTsnopvtoNJu2BBZO9sa2bVPBcF4uyMFBG1oiMs\r
+ojP+is6A30KLytVq+N04/jj9rpDUhVKet7upKwvj29ltl/8l9/jx00pJDunSHt8h\r
+OQaWSz/SZAqW9fA+xVqEZ9RCSv/Ugo2mdGb4xQIDAQABo1owWDAOBgNVHQ8BAf8E\r
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw\r
-Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA\r
-n2I9uY34QxYLfMCIwI3oMkR+v0ehEmjLcF3S2SILybtKFOxHUvFx10IiYJOCjPKr\r
-vTwbprTp4R9HffQyiGoe9jLYu+8Tfjf86hDcoChOg8SZm1u3rXCgXPus+19XON0g\r
-UWiJmIBAWDhz8+0vQ3QyrgtLuweoX4tTcbYOlTzO5KU=
+Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA\r
+IddoaqJ/H9Ya+Iz1wRpWziTi3z7goy9Rxd6Q8f85Nra4M/3Ax2irXtgQINRho37l\r
+RmoaXVy+pTU1ncQfRiVfQML2ce9+OCQ4p5rZFxZDhh0OxKaHKrfFTvHbeNB1FH8Z\r
+SH0mRVgnK1F+8TTkThNZctKe0jhqzsp41sRBPrYIEUk=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: revoked1.example.org
- localKeyID: BD BF 30 04 34 2D 03 C9 AA FE 25 10 2C DB 7C 74 89 B0 9A C9
+ localKeyID: 92 C5 45 B6 00 77 BA 8B F9 80 EA 9D E1 C8 CF 26 8E 4A AB 64
Key Attributes: <No Attributes>
-----BEGIN ENCRYPTED PRIVATE KEY-----
-MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIT05M1SXZo7oCAggA
-MBQGCCqGSIb3DQMHBAgKjXdFWgevnASCAoDJx6CMm3lv2+3DdMJOrODuXYc04hqm
-OYUHWPas6aMaE9ZU2WQ+05envov/obUhJ3T1laRTnAhbMIrIuQDDkR4Tx+njdpS0
-WwEmGxlv4JL7bW+TG2g9LfpMUGTcK+pTNmM7pNSylnN6E1EvqTrMLqc6VaPG2Ohc
-KCPbWiqDKyM3WHxrgRkhg3sQmW0KyyU1QT9nNHZAW2ip1sJVzRKbiIsx+t020kH2
-abemY+ZDpfwKJKZpzm5CjeWLP/zO0q07ZkEgLjjhXAtLwCEfkt7SiShOOYFaYQUo
-psk9WSDU/ieF1Uywz6nrqWSH/TBDbbqrYXPshTXeFE2UzCvSdPYHPEvOnQTIVya5
-T9P54rWQKIo3GnPxJaEXo+tzCnV9B4kyFcEtjwKrh9jWu2MMLzLMdRrm1VKcjgts
-kXHbeyfrZouWOdoPUNRSdc004oWYvvweG3DmObUQBxKh+PojMCbaBpJFkE+bbfxo
-JZ49baXcqXx7vph8PszJBzS2FgmN/r3eMgYQDqzydfnoTPhyjsU8ompeHVbH53VU
-PKUkNyeac7lAwj6JwcXOMDnc51KFQ80i+/0gHwrRSd+bmgmnpwO1TTiEeIUaYCQa
-/Ic7LxXhi/gWrQg4U8bIsibXBHEefcwtWWuDD1uUlxezuqdFrSUUC0Da5AmD516Q
-8aznlBljvQUpiQQHH3KB7eQEp+bbgYZJagFeZIn9FiLlHzPpIZetsB+ynPSvjz/V
-zVszLHuLaswKcC1N66LAOqyCKcPYI35+OqE8/6SCe9iJFOoIYlJkxDBKwZk/NhvD
-/CRD6hsaeUnAHpNEuus5qrRICbDAoi1LoK8hDadb7Zv+wSLY/uo0JzxL
+MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQINwKIYat5xm0CAggA
+MBQGCCqGSIb3DQMHBAiAyXqFcnQatgSCAoA0oKUYqXC149u/VeKeqbKXi6fwO7tG
+cS9AwgTHkBNtfrvrL+9eWCfy/qlCPNI/VUGnW9iyspBYBQeUvn84NzhJrhdipMU+
+PfCoIYG9eI2gTpuAgrd9jKxS2pf7M9Aw1WZlH8DWU6r5yjWRSJHqdZs5snK37D0N
+tJ/1xQdKGLpi3OQwvaHNpVrQp5FgmkHaDVRwSaCmIbsIPbwS4Z5JW5f0KOcpoRFJ
+BeNaZcVrDq7lQUEQB777qS1Y82qnMEvQGzs2ZOYNOIS/wSe+LkcLaOpm2Zk0SQDa
+ZwFpcm4X8vIKFdCfXc7DLennynnsppI13KXzzkZA4xFqkuwzhzG8HrclqULg02db
+tMECAeqNzZ+fSAOUHU7Y5UL/XVuTNqZ1jL0MsUGMmfme3Am0me2eo2WH4gukeneI
+rirTr+brVu56yi+4MhrHdQn2R6ZHLy0FS2rZmrr/4LOeMOfIRpmxTpG6hYumO4ie
+TdmKr/YMz/8hXlQsMe0klY2D5+ulh7JJn1G6CMqGdNOTtFll7zfwLFT0DgO58sll
+8oekFLt2ms4hu82FXkHvhIucOMPF+dGKsiCQmhqCH5wyEhbuQGqqyOxeEz8/oQ5q
+1e9E6iQCi2gI502QukaS7WG3OhoxGZ9oaLpPnWmy2hDzWtJAMLnq7SNwM1uggzWa
+hchlbjxTXWOUcrJgi5plPIz4dp5eHdwC4wXef0e6HWBKC5c0mWi/aO3RQWEikQdu
+NhZmIKgTcYFntWn71Q9XKJfvF0cuej+e1/wa9cwIGGXOH9QHzRT3SDYFqKgQJCKR
+uUlxTbYcazh9WFxM1F1kJE3DydioSM7DEHsBAqipOW4EaxRtksi4tU5t
-----END ENCRYPTED PRIVATE KEY-----
Bag Attributes
friendlyName: revoked1.example.org
- localKeyID: BD BF 30 04 34 2D 03 C9 AA FE 25 10 2C DB 7C 74 89 B0 9A C9
+ localKeyID: 92 C5 45 B6 00 77 BA 8B F9 80 EA 9D E1 C8 CF 26 8E 4A AB 64
subject=/CN=revoked1.example.org
issuer=/O=example.org/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICiTCCAfKgAwIBAgIBZjANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt
+MIICiTCCAfKgAwIBAgIBZjANBgkqhkiG9w0BAQsFADAzMRQwEgYDVQQKEwtleGFt
cGxlLm9yZzEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
-MzQwOVoXDTM4MDEwMTEyMzQwOVowHzEdMBsGA1UEAxMUcmV2b2tlZDEuZXhhbXBs
-ZS5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMOKMcTBoKYBCz8Sxb/B
-5/RGvTdDMmkNO/e91ni4S/3OjvvksMmg38fv1e4DQOazkE4dp9ttllheaw0O6lEO
-cpuFSFC6BLDlaDEaJqDAlm9++vTZ+azhM1nUIKbUhmlPSMnagL1GhWBX1w3EVP2F
-n02386NEAY/kPJMoR2r/4Kb5AgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
+MzQzOVoXDTM4MDEwMTEyMzQzOVowHzEdMBsGA1UEAxMUcmV2b2tlZDEuZXhhbXBs
+ZS5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMFKQOMflyggZWs8aPiS
+zZ2CH47ISXmXJNKk5/nTZZ+NgyOpV34fDOjLBsw9UT1NMCLiec3z7qCMT4eeFXWm
+g9d3mC4Gwlaw1Kn+DdFFQxvpGb5C22K7tHafoefdtprGTpcGQ90FDtmUCY6fGSbW
+A8UyxttXLmTE/pPz9OkfvQlxAgMBAAGjgcAwgb0wDgYDVR0PAQH/BAQDAgTwMCAG
A1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAj
hiFodHRwOi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEE
KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLm9yZy8wHwYDVR0R
-BBgwFoIUcmV2b2tlZDEuZXhhbXBsZS5vcmcwDQYJKoZIhvcNAQEFBQADgYEAc4B0
-aoj+H7UoNbV39uIQIV3Z//V+AqQuOaBtUTf3izNDG/r3tpJ+La6s6FxH55dRvQdc
-lvF6WdHgD++J5Vx7MUVcXMyVmpJrLpnJk4BBSFMn/fgvoPFfONL1p9Z33HnIUrY1
-hCmJrHtAqS0pztH5YioEH97ihYz5Teoc6mws/Yc=
+BBgwFoIUcmV2b2tlZDEuZXhhbXBsZS5vcmcwDQYJKoZIhvcNAQELBQADgYEASoDf
+KWa0eBRyOr/s6iYBE/92HwEYzYRJTQ72WYOyWzgxgEQFNUGSoPDm5/Uz8RtCN7WA
+jP3izpoDT9RljW/381kJjfcyhApK6P20d9Wh6jTbVNEyh2MU8GaU5Yx7q2MWuxCW
+LUxer4bHOOBFsKtScIJJ/5FIUxV2X/jTvXdX9uU=
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
-MIICXgIBAAKBgQDDijHEwaCmAQs/EsW/wef0Rr03QzJpDTv3vdZ4uEv9zo775LDJ
-oN/H79XuA0Dms5BOHafbbZZYXmsNDupRDnKbhUhQugSw5WgxGiagwJZvfvr02fms
-4TNZ1CCm1IZpT0jJ2oC9RoVgV9cNxFT9hZ9Nt/OjRAGP5DyTKEdq/+Cm+QIDAQAB
-AoGBAKShEB/QybmZ/WcAHh/BWNHwUNRbLfEGZGvDl/ORbuFkbDulojZPzLjfsySt
-9pGFssQh8bYrwL3r2INpAFx4JoJRjdBOrFsrB+xZhW+GyHJamd7dDEOqFz8zW/z+
-yhELiLeifXcJBBRrC5X4+rgbYVVb6A2y36SJTf5TPjo1PRoVAkEA845G/VVs66X9
-h1XmHM58kU2qOrLypTT4c6UrXKZrN7KFfl9BCWQSOShLW5S5/Oz/3ypkrDZSqggj
-30y0goZjzwJBAM2H3arwjg8mxJnkShmrTHamtdpzByEyF5hM+SDsdb/onWETf8M+
-BIj1J/x8r/rXx4r0ZQ5BbnMDsoCxpDd5UrcCQQCVdIFrg7hLApkJK1UB6FPYdmg3
-jQgJCPBNRtXNDPJOQ2ZXnewy7w2ftXJIyIM5CdYaA9GzO8KORGB+7nr2fbFRAkBQ
-YaWo+AGnHVNgmG7+kQcLlHGk6L3OFsgxkVERtkjq8C+0yqp6EmQ1qCOmVKGCqidp
-SeHH7IEkzDpgqJj/9RwLAkEAlu/rjtfcW3PRsSqNGbwvtPreeM/TWSfBH2wwMb0l
-9kd1lEpfJeqUkX9B9qCVighX7pJ6y1FJbwuW9xgvbo9mbA==
+MIICWgIBAAKBgQDBSkDjH5coIGVrPGj4ks2dgh+OyEl5lyTSpOf502WfjYMjqVd+
+HwzoywbMPVE9TTAi4nnN8+6gjE+HnhV1poPXd5guBsJWsNSp/g3RRUMb6Rm+Qtti
+u7R2n6Hn3baaxk6XBkPdBQ7ZlAmOnxkm1gPFMsbbVy5kxP6T8/TpH70JcQIDAQAB
+AoGAewZ48FbeDdM42h1ULsq5hoQY8/c1FOgHru75G4Da0MfwbRVOs96th8oZpItu
+ltb3SWze3CBjhNppkEclH4IBrVnd6QesKygRZTJ0jTiu34vjsiO9pmif556cgInr
+eMlXE18LUsbcVQCKEEIbj9ZGaWWdxNbrshEgsemkNBNPXbUCQQDv6niIArEMEyB1
+XWZgBhGfPqQ117CTLygodIdhpPGmOUBxajbEgO6QQe4Mgo/QlBXnS0blCZ0CjQ8J
+eklXczwDAkEAzj+SZJ2E7lTKfzJLYS8rNCD3maYrrDRFDdgbJn+Pk9GteIj+6jD9
+YMOEPgsqeVj6rXfFoyIqe7UzIT8W0m+8ewJAd3gf+0Kz3Vps8GTJRQngnpb3+KPm
+lvSFn9efTt1vRCIAWDnW+fVmVsmt++bMLMaBPcM7k3Q9DnclxMdzXCvS9wI/Nfpt
+Vefj4nxOgvumvsiZhgsawhu7UlZbvEPS10CLUySNQf6YuLIZnjmNYq+JbjjbYor2
+LrvCYp4Jw6m/T1PvAkAbdprMpbU502lJQ6V27XQmBXo4w7Ea56DefbsB5d6heBCM
+godeig9Ax7DiRSOwxv3OzMeKgg1N3YxBDkNuwuJa
-----END RSA PRIVATE KEY-----
subject=/O=example.org/CN=clica Signing Cert
issuer=/O=example.org/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA4WhcNMzgw
-MTAxMTIzNDA4WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrlUzB
-ANKQi0cI+jOYOVy2EYu2LOXihiMHi3dX/boaZ2+rIwbWaaAy7gMXLvfay/ml+pyY
-hnxQbnfADZN0xXQoHZ3AjBIU6YP2CWpOk/3jrnjW7P84fCie/6SXhfH2l6ZZFaro
-yRw10jnO/kgEtFKBQpN7eZ2oPDaGGwuyBVaXqQIDAQABo1owWDAOBgNVHQ8BAf8E
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM5WhcNMzgw
+MTAxMTIzNDM5WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCpoeV
+zjmqBMOrYxP7rj6aXYODfaD1lZTsnopvtoNJu2BBZO9sa2bVPBcF4uyMFBG1oiMs
+ojP+is6A30KLytVq+N04/jj9rpDUhVKet7upKwvj29ltl/8l9/jx00pJDunSHt8h
+OQaWSz/SZAqW9fA+xVqEZ9RCSv/Ugo2mdGb4xQIDAQABo1owWDAOBgNVHQ8BAf8E
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw
-Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA
-n2I9uY34QxYLfMCIwI3oMkR+v0ehEmjLcF3S2SILybtKFOxHUvFx10IiYJOCjPKr
-vTwbprTp4R9HffQyiGoe9jLYu+8Tfjf86hDcoChOg8SZm1u3rXCgXPus+19XON0g
-UWiJmIBAWDhz8+0vQ3QyrgtLuweoX4tTcbYOlTzO5KU=
+Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA
+IddoaqJ/H9Ya+Iz1wRpWziTi3z7goy9Rxd6Q8f85Nra4M/3Ax2irXtgQINRho37l
+RmoaXVy+pTU1ncQfRiVfQML2ce9+OCQ4p5rZFxZDhh0OxKaHKrfFTvHbeNB1FH8Z
+SH0mRVgnK1F+8TTkThNZctKe0jhqzsp41sRBPrYIEUk=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: Certificate Authority
subject=/O=example.org/CN=clica CA
issuer=/O=example.org/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA4WhcNMzgw
-MTAxMTIzNDA4WjApMRQwEgYDVQQKEwtleGFtcGxlLm9yZzERMA8GA1UEAxMIY2xp
-Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmGE/1NBbn57y9RAMTa
-/jWgErk9jUKo+z0vzO5me7MUE+C3Jhk2YFF+w3ryEny3DikQOZEdRU4NFrQKZKu5
-1jjYg5ilg8EJTP6h9GzZmacH9olW3hdMvVqMkiLuZF97H41AYx95XPDibxwrpMgD
-oDVoYTQIPBwdjj8d88SdbgYjAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
-DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBAINsDZLZin7u8iOLguRG
-37mUDNhAQ9qUAtiFV8JnjJU9DZGb0TvSpYmOkjK2iH4cH6AsEXptB6duvkkpp6ly
-+aGvlqy69D/MfPpLjLX7e6WOISshaWCGB7/rQqbRtAePFpa07gijUqxM22LfiHXz
-YHJSTjLx4idfdLNS+U5iir1Y
------END CERTIFICATE-----
-Bag Attributes
- friendlyName: revoked2.example.org
- localKeyID: 0E 81 86 02 8B 4D 55 65 C2 E8 26 F3 9B C2 9F 15 B0 6C 9C F1
-subject=/CN=revoked2.example.org
-issuer=/O=example.org/CN=clica Signing Cert
------BEGIN CERTIFICATE-----
-MIICijCCAfOgAwIBAgICAMowDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhh
-bXBsZS5vcmcxGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDEx
-MjM0MTBaFw0zODAxMDExMjM0MTBaMB8xHTAbBgNVBAMTFHJldm9rZWQyLmV4YW1w
-bGUub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcWJ1VXZJIIYfk/S5f
-VL5bDZdjajlmC/gSkq8Q8hm5oKG72+VvGaZzwphT86Sc66BLauR4wcazmHO+TJvF
-1AIKFA+yzd48iux3Rb1StoPqdSdJ1BplPQuJgWg2DG/Mglhgc2IDbWSbNhnVqLrQ
-kc0HiOMZGktm0CaL6IjayzFFEQIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
-BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
-I4YhaHR0cDovL2NybC5leGFtcGxlLm9yZy9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
-BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5vcmcvMB8GA1Ud
-EQQYMBaCFHJldm9rZWQyLmV4YW1wbGUub3JnMA0GCSqGSIb3DQEBBQUAA4GBAAlw
-6O54t5HfF6TqyO1C4PX7Cibt1qFXR1fFPeExBoWlLhowWzTLUipwG2DqT6s04Lcz
-HodtDZ4pTUO6mt65VvudvZDmLjvvmTWtaFtDLnm5E+Y5BV3yLwqcjL9ztdH+P5r7
-qMFLL3hqlFvOVisbDfOP85ALGAjew1pNMWX9P0VC
+MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM5WhcNMzgw
+MTAxMTIzNDM5WjApMRQwEgYDVQQKEwtleGFtcGxlLm9yZzERMA8GA1UEAxMIY2xp
+Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMmC4zNWYntPtKW8nuwo
+JbC14Cwuck7DufEvR6WAtos3NUxjWpS4rQl7bW62AoaSdX0bSIxpyS2wtgQxIoFJ
+yU0Ukseh5lTpAvXEgKyjutRJswbQj0w94O0487KcyBqd1ZDJHJYs9VJ+BfrETwwc
+74Tk8FUQHaH6EQJ28GIJUIJfAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
+DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBAISxe2t3sJCPBKD6wyb/
+lAsOu+Llby0cXetGKzGhC+HFHvI5OsjhMtOE5uGp7UYlJzbRrfMx/gSR9pjaXxah
+Bt7JFvcPI6wSDU4bBClsuvMTisenANOOscWHSEvB/YQes3OLnqC2RGSppKshjwVF
+fdbkhlMTV2Oyub2TvrscntOV
-----END CERTIFICATE-----
Bag Attributes
friendlyName: revoked2.example.org
- localKeyID: 0E 81 86 02 8B 4D 55 65 C2 E8 26 F3 9B C2 9F 15 B0 6C 9C F1
+ localKeyID: A3 A0 ED 35 B4 59 E0 6E 23 7B D1 A8 7B CE 0E 67 DA 8F B3 72
subject=/CN=revoked2.example.org
issuer=/O=example.org/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICijCCAfOgAwIBAgICAMowDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhh
+MIICijCCAfOgAwIBAgICAMowDQYJKoZIhvcNAQELBQAwMzEUMBIGA1UEChMLZXhh
bXBsZS5vcmcxGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDEx
-MjM0MTBaFw0zODAxMDExMjM0MTBaMB8xHTAbBgNVBAMTFHJldm9rZWQyLmV4YW1w
-bGUub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcWJ1VXZJIIYfk/S5f
-VL5bDZdjajlmC/gSkq8Q8hm5oKG72+VvGaZzwphT86Sc66BLauR4wcazmHO+TJvF
-1AIKFA+yzd48iux3Rb1StoPqdSdJ1BplPQuJgWg2DG/Mglhgc2IDbWSbNhnVqLrQ
-kc0HiOMZGktm0CaL6IjayzFFEQIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
+MjM0NDBaFw0zODAxMDExMjM0NDBaMB8xHTAbBgNVBAMTFHJldm9rZWQyLmV4YW1w
+bGUub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDICO4Ac31eD1JPcg3f
+sZkA2ca3PXYlOx9lochRiJeZkIWJCEsfGDC5kESEI5w88XJ4b73kZdicJfxCyRZM
+qjinifY+J9Hx51Q1eyhK0OU/3y1mcz8xBTIYKXcQEcxLpFcjrxSh0JA9VDWFlZMw
+2iOOCFwyV0hOJqilOGZUqVuTjwIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
I4YhaHR0cDovL2NybC5leGFtcGxlLm9yZy9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5vcmcvMB8GA1Ud
-EQQYMBaCFHJldm9rZWQyLmV4YW1wbGUub3JnMA0GCSqGSIb3DQEBBQUAA4GBAAlw
-6O54t5HfF6TqyO1C4PX7Cibt1qFXR1fFPeExBoWlLhowWzTLUipwG2DqT6s04Lcz
-HodtDZ4pTUO6mt65VvudvZDmLjvvmTWtaFtDLnm5E+Y5BV3yLwqcjL9ztdH+P5r7
-qMFLL3hqlFvOVisbDfOP85ALGAjew1pNMWX9P0VC
+EQQYMBaCFHJldm9rZWQyLmV4YW1wbGUub3JnMA0GCSqGSIb3DQEBCwUAA4GBADnf
+cBedQm4PI6op1YDJMPCuJ0lpexHDF4Md6F8RmhSxAU1+fIC6CD8snQtEWRuEq/TR
+nI6RQ4qCBFZi4vGAn5m8NDA89xX4uv101uYPrvymRbDiFhpSOCJ45Ia83LLtS58z
+dF1i8AuksC7Oy+3ou5pcg7Hl3mpgyIoj2FnGrHnG
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA4WhcNMzgw\r
-MTAxMTIzNDA4WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp\r
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrlUzB\r
-ANKQi0cI+jOYOVy2EYu2LOXihiMHi3dX/boaZ2+rIwbWaaAy7gMXLvfay/ml+pyY\r
-hnxQbnfADZN0xXQoHZ3AjBIU6YP2CWpOk/3jrnjW7P84fCie/6SXhfH2l6ZZFaro\r
-yRw10jnO/kgEtFKBQpN7eZ2oPDaGGwuyBVaXqQIDAQABo1owWDAOBgNVHQ8BAf8E\r
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM5WhcNMzgw\r
+MTAxMTIzNDM5WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp\r
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCpoeV\r
+zjmqBMOrYxP7rj6aXYODfaD1lZTsnopvtoNJu2BBZO9sa2bVPBcF4uyMFBG1oiMs\r
+ojP+is6A30KLytVq+N04/jj9rpDUhVKet7upKwvj29ltl/8l9/jx00pJDunSHt8h\r
+OQaWSz/SZAqW9fA+xVqEZ9RCSv/Ugo2mdGb4xQIDAQABo1owWDAOBgNVHQ8BAf8E\r
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw\r
-Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA\r
-n2I9uY34QxYLfMCIwI3oMkR+v0ehEmjLcF3S2SILybtKFOxHUvFx10IiYJOCjPKr\r
-vTwbprTp4R9HffQyiGoe9jLYu+8Tfjf86hDcoChOg8SZm1u3rXCgXPus+19XON0g\r
-UWiJmIBAWDhz8+0vQ3QyrgtLuweoX4tTcbYOlTzO5KU=
+Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA\r
+IddoaqJ/H9Ya+Iz1wRpWziTi3z7goy9Rxd6Q8f85Nra4M/3Ax2irXtgQINRho37l\r
+RmoaXVy+pTU1ncQfRiVfQML2ce9+OCQ4p5rZFxZDhh0OxKaHKrfFTvHbeNB1FH8Z\r
+SH0mRVgnK1F+8TTkThNZctKe0jhqzsp41sRBPrYIEUk=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: revoked2.example.org
- localKeyID: 0E 81 86 02 8B 4D 55 65 C2 E8 26 F3 9B C2 9F 15 B0 6C 9C F1
+ localKeyID: A3 A0 ED 35 B4 59 E0 6E 23 7B D1 A8 7B CE 0E 67 DA 8F B3 72
Key Attributes: <No Attributes>
-----BEGIN ENCRYPTED PRIVATE KEY-----
-MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIrlpJvn2t12oCAggA
-MBQGCCqGSIb3DQMHBAjluKGzhc3i+QSCAoCwOwH/u1apPvqKoEcKjI2lED1f3rs5
-yGDzUuQpHbQhWByTtOW5wF1GvO2J8tA35wbWvLlxWt3+fLzRk2rPju0mncVskOyK
-vhu362BkOPODTRmoEQEVXSthQQWFuWicM/DgWgD5rSkDmy8A3YH2lPd0z+0ngIbC
-jl5VtDJoBw1zZPK8K+REw4bZI2Ok+SemtWMfO4krTcq4BltfOfIWky2hwPjPUzB3
-l32ioabUIxes5QaPekclFfqg54QNgInygQv5w7UOAJdfNyM952RycyTfS0YdTuhM
-a72VWT50nQzypNMK1giXlRq+qTfTZGeRAsYFdknMbq8UEYHDOG9XJP94+JushawI
-b1L6+Pv284bRPaTfdxDBn8cPj/mck3wIPiyh3wEVr3ozi9EDh2H0X3y98WtnCfHI
-VBIbZaTq6wuTjtdFMNA4gdkgry36sXOH3K9e0+iCqG3BKKjYi8oIPxj/mSdTdSiU
-TePpjZFWvScWZiq57g31pX4rZnw7wdXKhNtEdC6uifM73PuwlNO52t42Zy+n9GZ7
-+jalk+c4pe4bw58SBT/vIS9H4RUiGjAaNKfcesRYh7LYkTKRLF6CH5Q3I8yh61Mo
-e0tvr+pliI7OqbwVyYxiqf7r1XCU8FfXyQPs8YROwKhe1MtFH5xYPa37FVIPkn1D
-1zm6IrKw/CGbS+5MASC2ALyiadvDhNijfYtuVzuAzJDH1C+daGwh17oNnYMzGUUy
-yEOIyQvGU0to8dyS0ngPXK6kTc0XvPaqhH8wgu5nNVnFaZjZYkzVOF77cYQMBmFx
-S/Ypn+OoKON/PNG6/MuWP1fg3WdgzAW/xcgZrUSVjeIu6u1VgyApDZJd
+MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIT4udedrNkGwCAggA
+MBQGCCqGSIb3DQMHBAgLZwHx6XtwoQSCAoC5OzCUa4Y7cgjEaa7cHlt9tAVvIrMv
+R+bQiaXJmCWLtscST1fincREqgpQJJu2JDIWvGfg08E9lPWML2KS6bxE/PxVr+aA
+ZKanoID3uZY5kTmGKFkgk8y5fuEzSIpVkgBUe1i6dyC+Fo5+j19jNJgG2mqfsY+e
+Fye6dEmxPUIU/vRU4DowqNRqTh3unaoUkkymqmHiqQqYOnUguo6FSHZhhVaMNn2F
+tpjadGliehd5HtPoVsv3ns9wbbaS7EtPjDm1DnDx2DtzsYIOEUuvLFoE6vgZZB+9
+PHTW9jeOEM+I5fblavI0PHAYTYDp/FjL3CwgysLPPc0s3VeErs9Lz/oFSHns4+dd
+bA9cLPHdq5VZNmPgXP34wup2gX0DmuMB71XaRG1VCsM6hMyNT18pQNZ5UJoDnwru
+3tRie0W8isVC0Bpr4T4Mrhb/CtV/DMsz86WE8Jk2YdpgzfxtTnAtFT8qvPN5RXUG
+9jieHv1KMBek3i7pNmabNODM0T+P1w2kE9Cm4OlxjniDuUS2uIWVLWCrrup6ikhX
+5Qq89pdAoGuK7SM/vzNKxTjrWBEYF4ZVol6LpEtuPFFJqUZLUWdjOUAmebc6xzcl
+HoOvwqgCyVdF+BFSIEhw28Q3panQ3vemikOKoQI2V2wvW4H+jnAycXE7Jr7vgUEg
+lYPwDmQGxzQXT3nTZRLHi9k0wDHs+QFy0Z5k4HrZ7XIGEi45bgvIG64x9HqhNgb+
+dnQA8CUBhCFyTp53UNpis0ksVpBh/2tKtLSi7jYvPW2yjFpD2yVUg4K5grNtIb02
++Sqj1eR5nq51Yqb0P668l7PhO/zjeKFpJi9cvtYYVMfK9gO6t2nAm0/G
-----END ENCRYPTED PRIVATE KEY-----
Bag Attributes
friendlyName: revoked2.example.org
- localKeyID: 0E 81 86 02 8B 4D 55 65 C2 E8 26 F3 9B C2 9F 15 B0 6C 9C F1
+ localKeyID: A3 A0 ED 35 B4 59 E0 6E 23 7B D1 A8 7B CE 0E 67 DA 8F B3 72
subject=/CN=revoked2.example.org
issuer=/O=example.org/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICijCCAfOgAwIBAgICAMowDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhh
+MIICijCCAfOgAwIBAgICAMowDQYJKoZIhvcNAQELBQAwMzEUMBIGA1UEChMLZXhh
bXBsZS5vcmcxGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDEx
-MjM0MTBaFw0zODAxMDExMjM0MTBaMB8xHTAbBgNVBAMTFHJldm9rZWQyLmV4YW1w
-bGUub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcWJ1VXZJIIYfk/S5f
-VL5bDZdjajlmC/gSkq8Q8hm5oKG72+VvGaZzwphT86Sc66BLauR4wcazmHO+TJvF
-1AIKFA+yzd48iux3Rb1StoPqdSdJ1BplPQuJgWg2DG/Mglhgc2IDbWSbNhnVqLrQ
-kc0HiOMZGktm0CaL6IjayzFFEQIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
+MjM0NDBaFw0zODAxMDExMjM0NDBaMB8xHTAbBgNVBAMTFHJldm9rZWQyLmV4YW1w
+bGUub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDICO4Ac31eD1JPcg3f
+sZkA2ca3PXYlOx9lochRiJeZkIWJCEsfGDC5kESEI5w88XJ4b73kZdicJfxCyRZM
+qjinifY+J9Hx51Q1eyhK0OU/3y1mcz8xBTIYKXcQEcxLpFcjrxSh0JA9VDWFlZMw
+2iOOCFwyV0hOJqilOGZUqVuTjwIDAQABo4HAMIG9MA4GA1UdDwEB/wQEAwIE8DAg
BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
I4YhaHR0cDovL2NybC5leGFtcGxlLm9yZy9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5vcmcvMB8GA1Ud
-EQQYMBaCFHJldm9rZWQyLmV4YW1wbGUub3JnMA0GCSqGSIb3DQEBBQUAA4GBAAlw
-6O54t5HfF6TqyO1C4PX7Cibt1qFXR1fFPeExBoWlLhowWzTLUipwG2DqT6s04Lcz
-HodtDZ4pTUO6mt65VvudvZDmLjvvmTWtaFtDLnm5E+Y5BV3yLwqcjL9ztdH+P5r7
-qMFLL3hqlFvOVisbDfOP85ALGAjew1pNMWX9P0VC
+EQQYMBaCFHJldm9rZWQyLmV4YW1wbGUub3JnMA0GCSqGSIb3DQEBCwUAA4GBADnf
+cBedQm4PI6op1YDJMPCuJ0lpexHDF4Md6F8RmhSxAU1+fIC6CD8snQtEWRuEq/TR
+nI6RQ4qCBFZi4vGAn5m8NDA89xX4uv101uYPrvymRbDiFhpSOCJ45Ia83LLtS58z
+dF1i8AuksC7Oy+3ou5pcg7Hl3mpgyIoj2FnGrHnG
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
-MIICWwIBAAKBgQDcWJ1VXZJIIYfk/S5fVL5bDZdjajlmC/gSkq8Q8hm5oKG72+Vv
-GaZzwphT86Sc66BLauR4wcazmHO+TJvF1AIKFA+yzd48iux3Rb1StoPqdSdJ1Bpl
-PQuJgWg2DG/Mglhgc2IDbWSbNhnVqLrQkc0HiOMZGktm0CaL6IjayzFFEQIDAQAB
-AoGAFWS5Kd+i40P2KMJ4LSNSNA72wt0+Y20IEe2R98g5vS8eZNntxcKsyZJ8LbJ7
-Kg0qjAf91Mejni5QForjmOqDo/6odwLAaBaUZjfGMQ5hwUZOHZSF95Nkq6f6ek3J
-5berAyW5wdju+n5SpcxdTxhZ6s34JtKKR5uOIT4DYDW25gECQQD8Thv4aIqGyJd1
-mJwCerJrKbugla1hJJ7xxXyryHIamAGsq3qzMwwt72uTZR+LobPsVGfH3FpSN3Vh
-MGCGdcVhAkEA35Kw+e8VZCfdjZUMxydyiOiZUemJfx2hbq4EpFtp89oqr4CuCQ51
-bo1NHYmxmdzTmJN9HMy0TwiF7U9036ntsQJAV67tmY77VYww1vWKgnIRv5xpUI20
-C6amdm+jvC+VOBjLvC58HfsHqI8kW70xEV3JIcDTsGmsGhab/ILLiO81AQJASnlr
-+KW6w3VAKTSYYBL05UROJmocAjsVlm/jXfiRj8iB5ZqA3sVxOtVY9djzT2SvG6kt
-yRUrjxQwwL9yGDtb0QJAfgt36rEFyKnmP+rOqXE6P1/iq+5n/fxvlsHsAFitavvp
-30+KhXbetYydYaOsJQbN779gSdyAYLyhmMpUCRA3aw==
+MIICXAIBAAKBgQDICO4Ac31eD1JPcg3fsZkA2ca3PXYlOx9lochRiJeZkIWJCEsf
+GDC5kESEI5w88XJ4b73kZdicJfxCyRZMqjinifY+J9Hx51Q1eyhK0OU/3y1mcz8x
+BTIYKXcQEcxLpFcjrxSh0JA9VDWFlZMw2iOOCFwyV0hOJqilOGZUqVuTjwIDAQAB
+AoGAaKGDHGlMYi7RdwzJhQB4b6F5988GRWMvgRGmnj88TO7zakIUSSd2FRoJPLUD
+vDzvC2Ani5haPRMBaE2WhHNlPhAyJIU6dSCPFhGHl89HOq4ROGBwUDDwyl23wkdS
+yu6iIbrXDkKWPcNYiIX+VwKha0Fw/Pn3zTWQIetrPoSRXQECQQDuobW9iHkUPHRY
+32FB0Y4t+VxExGD8CdPBHvfhFBPwNu9zn3eeOa6l00gqmfT4QOBg9z9YWEth8zYG
+8jXHV3HxAkEA1pgRO2VqC6NifvbQp4TknRm0YLf8LTwjFPyCD/FBbl4Yahx/YNgy
+mtxEPVaTR5C58IxU8+i6cF79Ww5dBG3dfwJAH47dNQqGUKnKDTLFbunirqvKiwGZ
+fdti2KhaybZZCKyLMDRHonIoaZ+ubIvdvLL/uXMZOnq6xWJfo72GZS1oUQJAFdmb
+/5E+7/pt4AGfkz8LzBc+744sRirWY5+mWps1D1jTYZKPQbwhwvTkmd5D1sictiqD
+x+YNfb2eTHQ08muBXwJBAJxD+8SWPppwX9oMprp4beBP6s2S+02kJGw+MmMpbs2i
+tX4cT89Pca/xgnQPwDoWR/WFlAGSQj/RWq3WhoFSbCo=
-----END RSA PRIVATE KEY-----
subject=/O=example.org/CN=clica Signing Cert
issuer=/O=example.org/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA4WhcNMzgw
-MTAxMTIzNDA4WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrlUzB
-ANKQi0cI+jOYOVy2EYu2LOXihiMHi3dX/boaZ2+rIwbWaaAy7gMXLvfay/ml+pyY
-hnxQbnfADZN0xXQoHZ3AjBIU6YP2CWpOk/3jrnjW7P84fCie/6SXhfH2l6ZZFaro
-yRw10jnO/kgEtFKBQpN7eZ2oPDaGGwuyBVaXqQIDAQABo1owWDAOBgNVHQ8BAf8E
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM5WhcNMzgw
+MTAxMTIzNDM5WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCpoeV
+zjmqBMOrYxP7rj6aXYODfaD1lZTsnopvtoNJu2BBZO9sa2bVPBcF4uyMFBG1oiMs
+ojP+is6A30KLytVq+N04/jj9rpDUhVKet7upKwvj29ltl/8l9/jx00pJDunSHt8h
+OQaWSz/SZAqW9fA+xVqEZ9RCSv/Ugo2mdGb4xQIDAQABo1owWDAOBgNVHQ8BAf8E
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw
-Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA
-n2I9uY34QxYLfMCIwI3oMkR+v0ehEmjLcF3S2SILybtKFOxHUvFx10IiYJOCjPKr
-vTwbprTp4R9HffQyiGoe9jLYu+8Tfjf86hDcoChOg8SZm1u3rXCgXPus+19XON0g
-UWiJmIBAWDhz8+0vQ3QyrgtLuweoX4tTcbYOlTzO5KU=
+Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA
+IddoaqJ/H9Ya+Iz1wRpWziTi3z7goy9Rxd6Q8f85Nra4M/3Ax2irXtgQINRho37l
+RmoaXVy+pTU1ncQfRiVfQML2ce9+OCQ4p5rZFxZDhh0OxKaHKrfFTvHbeNB1FH8Z
+SH0mRVgnK1F+8TTkThNZctKe0jhqzsp41sRBPrYIEUk=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: Certificate Authority
subject=/O=example.org/CN=clica CA
issuer=/O=example.org/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA4WhcNMzgw
-MTAxMTIzNDA4WjApMRQwEgYDVQQKEwtleGFtcGxlLm9yZzERMA8GA1UEAxMIY2xp
-Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmGE/1NBbn57y9RAMTa
-/jWgErk9jUKo+z0vzO5me7MUE+C3Jhk2YFF+w3ryEny3DikQOZEdRU4NFrQKZKu5
-1jjYg5ilg8EJTP6h9GzZmacH9olW3hdMvVqMkiLuZF97H41AYx95XPDibxwrpMgD
-oDVoYTQIPBwdjj8d88SdbgYjAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
-DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBAINsDZLZin7u8iOLguRG
-37mUDNhAQ9qUAtiFV8JnjJU9DZGb0TvSpYmOkjK2iH4cH6AsEXptB6duvkkpp6ly
-+aGvlqy69D/MfPpLjLX7e6WOISshaWCGB7/rQqbRtAePFpa07gijUqxM22LfiHXz
-YHJSTjLx4idfdLNS+U5iir1Y
------END CERTIFICATE-----
-Bag Attributes
- friendlyName: server1.example.org
- localKeyID: 88 14 08 19 07 0E 31 A2 11 CA 6A F9 94 D0 81 D2 E2 C4 6C A0
-subject=/CN=server1.example.org
-issuer=/O=example.org/CN=clica Signing Cert
------BEGIN CERTIFICATE-----
-MIIC0DCCAjmgAwIBAgIBZTANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt
-cGxlLm9yZzEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
-MzQwOVoXDTM4MDEwMTEyMzQwOVowHjEcMBoGA1UEAxMTc2VydmVyMS5leGFtcGxl
-Lm9yZzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqEYtZQEwUPQUjTUDYJDb
-mFhMifuXoKfmFsGIYoy99JG36tQLzgFET+lkEoKXmXf/MRecneA0TtiL3bac/ZT5
-us46SnYCqpIhw9PAuvjUjpfe0gc7KOAv9DDdVr5n11XOuNYPak/SThICGOlAQlkk
-ih47uzqcuTpnJb/t+kuuNMsCAwEAAaOCAQcwggEDMA4GA1UdDwEB/wQEAwIE8DAg
-BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
-I4YhaHR0cDovL2NybC5leGFtcGxlLm9yZy9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
-BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5vcmcvMGUGA1Ud
-EQReMFyCImFsdGVybmF0ZW5hbWUyLnNlcnZlcjEuZXhhbXBsZS5vcmeCE3NlcnZl
-cjEuZXhhbXBsZS5vcmeCIWFsdGVybmF0ZW5hbWUuc2VydmVyMS5leGFtcGxlLm9y
-ZzANBgkqhkiG9w0BAQUFAAOBgQBDuJv1EXKwOrrY2CShqo9tUuB6rzAItWbLFEmW
-kbTkmeG3W2IlHUco86NJPKu70CEmAkxEUTbWYoJLSVkq1LSgc8NGbuXPiQxQdiAc
-QXUrDYWeFYMuejZmFRd4gHOHRUQ07YmFr2IXEEitq5UG/AZTYoSIVF3UI7jL4gHS
-fpDLrg==
+MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM5WhcNMzgw
+MTAxMTIzNDM5WjApMRQwEgYDVQQKEwtleGFtcGxlLm9yZzERMA8GA1UEAxMIY2xp
+Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMmC4zNWYntPtKW8nuwo
+JbC14Cwuck7DufEvR6WAtos3NUxjWpS4rQl7bW62AoaSdX0bSIxpyS2wtgQxIoFJ
+yU0Ukseh5lTpAvXEgKyjutRJswbQj0w94O0487KcyBqd1ZDJHJYs9VJ+BfrETwwc
+74Tk8FUQHaH6EQJ28GIJUIJfAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
+DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBAISxe2t3sJCPBKD6wyb/
+lAsOu+Llby0cXetGKzGhC+HFHvI5OsjhMtOE5uGp7UYlJzbRrfMx/gSR9pjaXxah
+Bt7JFvcPI6wSDU4bBClsuvMTisenANOOscWHSEvB/YQes3OLnqC2RGSppKshjwVF
+fdbkhlMTV2Oyub2TvrscntOV
-----END CERTIFICATE-----
--- /dev/null
+Bag Attributes
+ friendlyName: server1.example.org
+ localKeyID: 9F 34 37 BE 94 61 34 9B 09 60 34 72 70 F3 CC 59 C3 4C CA 62
+subject=/CN=server1.example.org
+issuer=/O=example.org/CN=clica Signing Cert
+-----BEGIN CERTIFICATE-----
+MIIC2zCCAkSgAwIBAgIBZTANBgkqhkiG9w0BAQsFADAzMRQwEgYDVQQKEwtleGFt
+cGxlLm9yZzEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
+MzQzOVoXDTM4MDEwMTEyMzQzOVowHjEcMBoGA1UEAxMTc2VydmVyMS5leGFtcGxl
+Lm9yZzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1cRJSx9NEPXBa1WUPmas
+rmsJJiz2XerQaxGYkgBOeE4xGUjlGDrL38g2bl7iI2trNYEQZfouKl/u3RmOoy63
+I3DnEXJtir8YeqlWKwN8v6vYqJY8Dg4F4SxxCxfREcQmPRsK5iI/ooBylRcxiQsz
+OacYB5JDNpSCi3bNmDobKwUCAwEAAaOCARIwggEOMA4GA1UdDwEB/wQEAwIE8DAg
+BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
+I4YhaHR0cDovL2NybC5leGFtcGxlLm9yZy9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
+BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5vcmcvMHAGA1Ud
+EQRpMGeCImFsdGVybmF0ZW5hbWUyLnNlcnZlcjEuZXhhbXBsZS5vcmeCIWFsdGVy
+bmF0ZW5hbWUuc2VydmVyMS5leGFtcGxlLm9yZ4ITc2VydmVyMS5leGFtcGxlLm9y
+Z4IJKi50ZXN0LmV4MA0GCSqGSIb3DQEBCwUAA4GBACtUUNjJzARl0cPfxC9uERbp
+g81Ig3+W0gyZCaU6VX8VB/w2k7sQZGWfYCWAOHqXmTdwGZ80aSjgZRBpPRdx8z7S
+KKBoicjvTLJZIm4GrNKlvmlANhqrXD/JIzpqCHgC57Ly37Ro9JAYcFCOCvGx2Y2t
+MJKULq5mBRLVrKPJtaXU
+-----END CERTIFICATE-----
+Bag Attributes
+ friendlyName: Signing Cert
+subject=/O=example.org/CN=clica Signing Cert
+issuer=/O=example.org/CN=clica CA
+-----BEGIN CERTIFICATE-----
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM5WhcNMzgw
+MTAxMTIzNDM5WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCpoeV
+zjmqBMOrYxP7rj6aXYODfaD1lZTsnopvtoNJu2BBZO9sa2bVPBcF4uyMFBG1oiMs
+ojP+is6A30KLytVq+N04/jj9rpDUhVKet7upKwvj29ltl/8l9/jx00pJDunSHt8h
+OQaWSz/SZAqW9fA+xVqEZ9RCSv/Ugo2mdGb4xQIDAQABo1owWDAOBgNVHQ8BAf8E
+BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw
+Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA
+IddoaqJ/H9Ya+Iz1wRpWziTi3z7goy9Rxd6Q8f85Nra4M/3Ax2irXtgQINRho37l
+RmoaXVy+pTU1ncQfRiVfQML2ce9+OCQ4p5rZFxZDhh0OxKaHKrfFTvHbeNB1FH8Z
+SH0mRVgnK1F+8TTkThNZctKe0jhqzsp41sRBPrYIEUk=
+-----END CERTIFICATE-----
+Bag Attributes
+ friendlyName: Certificate Authority
+subject=/O=example.org/CN=clica CA
+issuer=/O=example.org/CN=clica CA
+-----BEGIN CERTIFICATE-----
+MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM5WhcNMzgw
+MTAxMTIzNDM5WjApMRQwEgYDVQQKEwtleGFtcGxlLm9yZzERMA8GA1UEAxMIY2xp
+Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMmC4zNWYntPtKW8nuwo
+JbC14Cwuck7DufEvR6WAtos3NUxjWpS4rQl7bW62AoaSdX0bSIxpyS2wtgQxIoFJ
+yU0Ukseh5lTpAvXEgKyjutRJswbQj0w94O0487KcyBqd1ZDJHJYs9VJ+BfrETwwc
+74Tk8FUQHaH6EQJ28GIJUIJfAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
+DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBAISxe2t3sJCPBKD6wyb/
+lAsOu+Llby0cXetGKzGhC+HFHvI5OsjhMtOE5uGp7UYlJzbRrfMx/gSR9pjaXxah
+Bt7JFvcPI6wSDU4bBClsuvMTisenANOOscWHSEvB/YQes3OLnqC2RGSppKshjwVF
+fdbkhlMTV2Oyub2TvrscntOV
+-----END CERTIFICATE-----
Bag Attributes
friendlyName: server1.example.org
- localKeyID: 88 14 08 19 07 0E 31 A2 11 CA 6A F9 94 D0 81 D2 E2 C4 6C A0
+ localKeyID: 9F 34 37 BE 94 61 34 9B 09 60 34 72 70 F3 CC 59 C3 4C CA 62
subject=/CN=server1.example.org
issuer=/O=example.org/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIIC0DCCAjmgAwIBAgIBZTANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt
+MIIC2zCCAkSgAwIBAgIBZTANBgkqhkiG9w0BAQsFADAzMRQwEgYDVQQKEwtleGFt
cGxlLm9yZzEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
-MzQwOVoXDTM4MDEwMTEyMzQwOVowHjEcMBoGA1UEAxMTc2VydmVyMS5leGFtcGxl
-Lm9yZzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqEYtZQEwUPQUjTUDYJDb
-mFhMifuXoKfmFsGIYoy99JG36tQLzgFET+lkEoKXmXf/MRecneA0TtiL3bac/ZT5
-us46SnYCqpIhw9PAuvjUjpfe0gc7KOAv9DDdVr5n11XOuNYPak/SThICGOlAQlkk
-ih47uzqcuTpnJb/t+kuuNMsCAwEAAaOCAQcwggEDMA4GA1UdDwEB/wQEAwIE8DAg
+MzQzOVoXDTM4MDEwMTEyMzQzOVowHjEcMBoGA1UEAxMTc2VydmVyMS5leGFtcGxl
+Lm9yZzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1cRJSx9NEPXBa1WUPmas
+rmsJJiz2XerQaxGYkgBOeE4xGUjlGDrL38g2bl7iI2trNYEQZfouKl/u3RmOoy63
+I3DnEXJtir8YeqlWKwN8v6vYqJY8Dg4F4SxxCxfREcQmPRsK5iI/ooBylRcxiQsz
+OacYB5JDNpSCi3bNmDobKwUCAwEAAaOCARIwggEOMA4GA1UdDwEB/wQEAwIE8DAg
BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
I4YhaHR0cDovL2NybC5leGFtcGxlLm9yZy9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
-BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5vcmcvMGUGA1Ud
-EQReMFyCImFsdGVybmF0ZW5hbWUyLnNlcnZlcjEuZXhhbXBsZS5vcmeCE3NlcnZl
-cjEuZXhhbXBsZS5vcmeCIWFsdGVybmF0ZW5hbWUuc2VydmVyMS5leGFtcGxlLm9y
-ZzANBgkqhkiG9w0BAQUFAAOBgQBDuJv1EXKwOrrY2CShqo9tUuB6rzAItWbLFEmW
-kbTkmeG3W2IlHUco86NJPKu70CEmAkxEUTbWYoJLSVkq1LSgc8NGbuXPiQxQdiAc
-QXUrDYWeFYMuejZmFRd4gHOHRUQ07YmFr2IXEEitq5UG/AZTYoSIVF3UI7jL4gHS
-fpDLrg==
+BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5vcmcvMHAGA1Ud
+EQRpMGeCImFsdGVybmF0ZW5hbWUyLnNlcnZlcjEuZXhhbXBsZS5vcmeCIWFsdGVy
+bmF0ZW5hbWUuc2VydmVyMS5leGFtcGxlLm9yZ4ITc2VydmVyMS5leGFtcGxlLm9y
+Z4IJKi50ZXN0LmV4MA0GCSqGSIb3DQEBCwUAA4GBACtUUNjJzARl0cPfxC9uERbp
+g81Ig3+W0gyZCaU6VX8VB/w2k7sQZGWfYCWAOHqXmTdwGZ80aSjgZRBpPRdx8z7S
+KKBoicjvTLJZIm4GrNKlvmlANhqrXD/JIzpqCHgC57Ly37Ro9JAYcFCOCvGx2Y2t
+MJKULq5mBRLVrKPJtaXU
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA4WhcNMzgw\r
-MTAxMTIzNDA4WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp\r
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrlUzB\r
-ANKQi0cI+jOYOVy2EYu2LOXihiMHi3dX/boaZ2+rIwbWaaAy7gMXLvfay/ml+pyY\r
-hnxQbnfADZN0xXQoHZ3AjBIU6YP2CWpOk/3jrnjW7P84fCie/6SXhfH2l6ZZFaro\r
-yRw10jnO/kgEtFKBQpN7eZ2oPDaGGwuyBVaXqQIDAQABo1owWDAOBgNVHQ8BAf8E\r
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM5WhcNMzgw\r
+MTAxMTIzNDM5WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp\r
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCpoeV\r
+zjmqBMOrYxP7rj6aXYODfaD1lZTsnopvtoNJu2BBZO9sa2bVPBcF4uyMFBG1oiMs\r
+ojP+is6A30KLytVq+N04/jj9rpDUhVKet7upKwvj29ltl/8l9/jx00pJDunSHt8h\r
+OQaWSz/SZAqW9fA+xVqEZ9RCSv/Ugo2mdGb4xQIDAQABo1owWDAOBgNVHQ8BAf8E\r
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw\r
-Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA\r
-n2I9uY34QxYLfMCIwI3oMkR+v0ehEmjLcF3S2SILybtKFOxHUvFx10IiYJOCjPKr\r
-vTwbprTp4R9HffQyiGoe9jLYu+8Tfjf86hDcoChOg8SZm1u3rXCgXPus+19XON0g\r
-UWiJmIBAWDhz8+0vQ3QyrgtLuweoX4tTcbYOlTzO5KU=
+Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA\r
+IddoaqJ/H9Ya+Iz1wRpWziTi3z7goy9Rxd6Q8f85Nra4M/3Ax2irXtgQINRho37l\r
+RmoaXVy+pTU1ncQfRiVfQML2ce9+OCQ4p5rZFxZDhh0OxKaHKrfFTvHbeNB1FH8Z\r
+SH0mRVgnK1F+8TTkThNZctKe0jhqzsp41sRBPrYIEUk=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: server1.example.org
- localKeyID: 88 14 08 19 07 0E 31 A2 11 CA 6A F9 94 D0 81 D2 E2 C4 6C A0
+ localKeyID: 9F 34 37 BE 94 61 34 9B 09 60 34 72 70 F3 CC 59 C3 4C CA 62
Key Attributes: <No Attributes>
-----BEGIN ENCRYPTED PRIVATE KEY-----
-MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQI6QbC42AGV6YCAggA
-MBQGCCqGSIb3DQMHBAjv7nw+WSc5QwSCAoAHFMKm+elgjvRxlzMIxSgLKDyo/Npr
-aiodIy+5/YM0QkvpYpkZIExjgpaUovVFKHxvBOgNX7+mjofDixNjRkBwOFbY0v8j
-e5rsuO4LlKkRf30wAqJZOUCNDU9KrthdfsgF7QXj3fv2crQzolZ8Ab7vH8+S/FpR
-edS4mK7klvm08Dy4zzF1T+RIzcl0hJjpk4Lnqx8xdLUOKeTotV1kF4S1kKeRiV9T
-zAVZtnj8iA2QFKBM2Kz8Npcu3965EPdTQl8ZCRSbzvqKcCvRNZF6RWcp2qxgoNF8
-6ghEOZeRni74dvnoafXrqQE8LmF2lARQkT/zU0OCULvihBQ85eRkxzk/fe5ndUZ2
-LuH/Zd9E0cDj+qiqlYbfb4LmL30E/cq6r76prz8HPK2JTYONgV8efGZrLb3UfAle
-jSfJu1LyZtAAIT+2AXWIDH2GmGTB3X2MLeBjwPnKgiPH7uzW7aRFMMnCExBAmORE
-KnYRnOVIuN9IlMYMf4YIX3PTrjqO4OIhgh7kBPO5wzgMcp8KseJCFlQG1h5JWgFN
-31Po6IHdp8/gR05QPBWgJ9l2DMNnhuJmvrcpsNq5kLkN8cKBS+xGeXKrHJoGEWIq
-f5X50QqWw/poUrArRW3K3SsAImLOMi7SMypBofRt7f0N8FlC/25+Vgd+ZCrETKlS
-Hz4c21CyV1qxtSy19i8RUrhUDj8Mn/nRYbIOsX/Et1Rpe/QVyqRaf8unjwp7bJPj
-eTDuEKEuAZ5dbHBVYBKHF0kPF7ha92h78wzQKDKr7gmx/QS2iXTx+Xy0yfdNuijr
-HEBPUmLZpE5fhuKdIKNCm7MAwmCm5jusPyPNga5c1p1Mq1GqUfyhvjGu
+MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIWFsB796OzDICAggA
+MBQGCCqGSIb3DQMHBAiKH0PsNTKf+ASCAoDpIiasiiHh2zZlrmZx+Zfsk/r+lQIJ
+5qcXy8gpGceJIRiI7eaY9MF8P19G1O8z69O7RRlJj84nLIETErPB4ypt0flyeRqR
+dvz3EGsIu2OmJjM6MFiIJDtNQtjqsBOimpCAnirDCCOzpNLGrK7K9NuMd4johuex
+NrwYrC31Uc09YDXF2BmhKWO9WTUQbmX+3msZVWVfWkIpZHfzfo9P6yfQR7cHF7d4
+HSPpGyFdPNwqMmNGKsoLzdAcU+u7JW9q7eUPeuWpmu2wEvqg4SFBWBHFSYJJAtbK
+y5+vhsQyXbzYbkEF8bLJjQHYMPPc+wOSVMJW5b40bdqweiSr8k9O16qj4kBdS40f
+iSAgzgUkKzQjuO0aYUk6n/3YjbSVHNAhtLGb3nsxsWBinJCXLFSYZ9zmwmjSL/0A
+HIG68RnzgF+Wh3O14eoTyUkEX9gKLZrKbaDfGqO2rI4zXEM/fhK0pP5D1t01KT2L
+Ff+SrqJV0vr+RbzqHjOnHjUMcR1MdF+jNG/VgcYA7UZ37chA9531STDHIeeaXJSx
+r9ENM8Kg2OkRenvCPsyCVL/u36ae2EWlBZJjrH9jSrWu+1W90LozDtXi9PEe3zuw
+oY88zgACDZQLrAzxbs3eQx6CnROw57IqUyFlcKft98axIQ/6J3A7EX7yRJIfqwX0
+w0ir/JxU70SUKuhahMy2ECakKhJWR04Sexw766jcXe9Wg1yqB//aWaUB8s0j3oe3
+Emcmbx0Tx0SCuBOhGlf8jxxavHeWkDA2FSZz3EjkkZUmXc/PKaQs8BMR1lXdehbr
+4ElEmHGTmMwSq2UO0YGI4YLN3/DNiqFykGdeWyG5Q47vteWVVBlwbdJ/
-----END ENCRYPTED PRIVATE KEY-----
Bag Attributes
friendlyName: server1.example.org
- localKeyID: 88 14 08 19 07 0E 31 A2 11 CA 6A F9 94 D0 81 D2 E2 C4 6C A0
+ localKeyID: 9F 34 37 BE 94 61 34 9B 09 60 34 72 70 F3 CC 59 C3 4C CA 62
subject=/CN=server1.example.org
issuer=/O=example.org/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIIC0DCCAjmgAwIBAgIBZTANBgkqhkiG9w0BAQUFADAzMRQwEgYDVQQKEwtleGFt
+MIIC2zCCAkSgAwIBAgIBZTANBgkqhkiG9w0BAQsFADAzMRQwEgYDVQQKEwtleGFt
cGxlLm9yZzEbMBkGA1UEAxMSY2xpY2EgU2lnbmluZyBDZXJ0MB4XDTEyMTEwMTEy
-MzQwOVoXDTM4MDEwMTEyMzQwOVowHjEcMBoGA1UEAxMTc2VydmVyMS5leGFtcGxl
-Lm9yZzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqEYtZQEwUPQUjTUDYJDb
-mFhMifuXoKfmFsGIYoy99JG36tQLzgFET+lkEoKXmXf/MRecneA0TtiL3bac/ZT5
-us46SnYCqpIhw9PAuvjUjpfe0gc7KOAv9DDdVr5n11XOuNYPak/SThICGOlAQlkk
-ih47uzqcuTpnJb/t+kuuNMsCAwEAAaOCAQcwggEDMA4GA1UdDwEB/wQEAwIE8DAg
+MzQzOVoXDTM4MDEwMTEyMzQzOVowHjEcMBoGA1UEAxMTc2VydmVyMS5leGFtcGxl
+Lm9yZzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1cRJSx9NEPXBa1WUPmas
+rmsJJiz2XerQaxGYkgBOeE4xGUjlGDrL38g2bl7iI2trNYEQZfouKl/u3RmOoy63
+I3DnEXJtir8YeqlWKwN8v6vYqJY8Dg4F4SxxCxfREcQmPRsK5iI/ooBylRcxiQsz
+OacYB5JDNpSCi3bNmDobKwUCAwEAAaOCARIwggEOMA4GA1UdDwEB/wQEAwIE8DAg
BgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMgYDVR0fBCswKTAnoCWg
I4YhaHR0cDovL2NybC5leGFtcGxlLm9yZy9sYXRlc3QuY3JsMDQGCCsGAQUFBwEB
-BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5vcmcvMGUGA1Ud
-EQReMFyCImFsdGVybmF0ZW5hbWUyLnNlcnZlcjEuZXhhbXBsZS5vcmeCE3NlcnZl
-cjEuZXhhbXBsZS5vcmeCIWFsdGVybmF0ZW5hbWUuc2VydmVyMS5leGFtcGxlLm9y
-ZzANBgkqhkiG9w0BAQUFAAOBgQBDuJv1EXKwOrrY2CShqo9tUuB6rzAItWbLFEmW
-kbTkmeG3W2IlHUco86NJPKu70CEmAkxEUTbWYoJLSVkq1LSgc8NGbuXPiQxQdiAc
-QXUrDYWeFYMuejZmFRd4gHOHRUQ07YmFr2IXEEitq5UG/AZTYoSIVF3UI7jL4gHS
-fpDLrg==
+BCgwJjAkBggrBgEFBQcwAYYYaHR0cDovL29zY3AvZXhhbXBsZS5vcmcvMHAGA1Ud
+EQRpMGeCImFsdGVybmF0ZW5hbWUyLnNlcnZlcjEuZXhhbXBsZS5vcmeCIWFsdGVy
+bmF0ZW5hbWUuc2VydmVyMS5leGFtcGxlLm9yZ4ITc2VydmVyMS5leGFtcGxlLm9y
+Z4IJKi50ZXN0LmV4MA0GCSqGSIb3DQEBCwUAA4GBACtUUNjJzARl0cPfxC9uERbp
+g81Ig3+W0gyZCaU6VX8VB/w2k7sQZGWfYCWAOHqXmTdwGZ80aSjgZRBpPRdx8z7S
+KKBoicjvTLJZIm4GrNKlvmlANhqrXD/JIzpqCHgC57Ly37Ro9JAYcFCOCvGx2Y2t
+MJKULq5mBRLVrKPJtaXU
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
-MIICXAIBAAKBgQCoRi1lATBQ9BSNNQNgkNuYWEyJ+5egp+YWwYhijL30kbfq1AvO
-AURP6WQSgpeZd/8xF5yd4DRO2Ivdtpz9lPm6zjpKdgKqkiHD08C6+NSOl97SBzso
-4C/0MN1WvmfXVc641g9qT9JOEgIY6UBCWSSKHju7Opy5Omclv+36S640ywIDAQAB
-AoGBAJ4OvNjg0vdXLG6uWuu7ZOimF86LqZLX4kGBq4+Vz18H+I70edoYSogdG0hf
-rfITSnpcSVnpnHhq4oVw3+k4o5ATbgCcDsYuxbB5hd28ZDW9L97KO+67ruaAdJe+
-et+tACJooOhVgbQIfhv22vMe2q9+/wzgkXpdHJwYc9L6nwORAkEA2svVm0NeOtO0
-BFohczUU7PU/Zde5WyWe2a8CvoErO/5jhfFCNYGKMiLnGsLAhZIxetIr0XPLXprD
-3+QgPOZ21QJBAMTjH7e992fy0K0mApo3in8D1s6wqIUoiG2u5aPzOPbSzlPOI8BH
-qNee1Tr6ZHNKbLFbuHvFzIlrUFAS2oFJDR8CQGKhNlZ6ZPTx0BmSI7gSeq9i0sRv
-HaBn8hbBHOSRx9KQl36exjDmh0yYjUNz/WN5BpMOQTB3GXs5GwlHhfzOC00CQAHE
-N+iiH7IjD5Q+Hw/bJ7b0Bd1c4GYxcufpBc5uxDgStB80XkW/XthwaGFbFcOjC06c
-EA+sOqWQ/Ot6/9LhIOkCQCIb1PetefpIBtCEx4AIVibiIuwnQGlS0786nSWTxskD
-SAE8HLJwbdsohGK0iSTE840gvUtaH+57TSg6YAVTFPo=
+MIICXwIBAAKBgQDVxElLH00Q9cFrVZQ+ZqyuawkmLPZd6tBrEZiSAE54TjEZSOUY
+OsvfyDZuXuIja2s1gRBl+i4qX+7dGY6jLrcjcOcRcm2Kvxh6qVYrA3y/q9ioljwO
+DgXhLHELF9ERxCY9GwrmIj+igHKVFzGJCzM5pxgHkkM2lIKLds2YOhsrBQIDAQAB
+AoGBAMi+6XmTroLT100d8/ZZ46Z0PAZOyRpPjmROBPJvOUG/ZFpzWzlS1eyUj5E8
+p69NjEOVrbmmpT4EE0QtYQcbsrzs+lRpaIY1FC5AuKZ9QsSItrB/2WF9Ms2sVXt2
+1ouMaKAEZHyKXF48l853w/igyzFPxRqcF3lk9aOOFVDpHlmBAkEA8qafFxistngj
+uFWqlMTf+uBN2sYVaTbhBA9ZZ6VdqyZUCWeZHb2X2xghcGbK8hDR7GEERNUBhzou
+9RkrMTXcYQJBAOGG3+3Oc+qtB2+fm6pdgQv/OaHmnWbGoMH4/7UpgoMCaac66sHL
+D2VzKdeKR79MCJrFnIK6ACx8zpzhNS678SUCQQDesNA8sCaB58xQdj5w/iXY5lZN
+O5GW2Ai2YyfYGUnXsvtZDjzVsJRXPNQjhhMnCQy/dWInkZ0vb9R8mDatmRLBAkEA
+kR6T21ccueaLQWWH6lFup4Sc1jQqFqc7bHXIPQ+v3pNf3u8HfpomlxZK11ownsTT
+SJxeALSlRfstjD9SVHc1TQJBAOuSFkzS6+c+bWpp9ZPjrk7lzWhqTZ9sKzMkIcaz
+nMghBJmiZ6BvxfZEO2DZ5OVFkb+QxX7qCiHbQTTNNL1tgsU=
-----END RSA PRIVATE KEY-----
subject=/O=example.org/CN=clica Signing Cert
issuer=/O=example.org/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA4WhcNMzgw
-MTAxMTIzNDA4WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrlUzB
-ANKQi0cI+jOYOVy2EYu2LOXihiMHi3dX/boaZ2+rIwbWaaAy7gMXLvfay/ml+pyY
-hnxQbnfADZN0xXQoHZ3AjBIU6YP2CWpOk/3jrnjW7P84fCie/6SXhfH2l6ZZFaro
-yRw10jnO/kgEtFKBQpN7eZ2oPDaGGwuyBVaXqQIDAQABo1owWDAOBgNVHQ8BAf8E
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM5WhcNMzgw
+MTAxMTIzNDM5WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCpoeV
+zjmqBMOrYxP7rj6aXYODfaD1lZTsnopvtoNJu2BBZO9sa2bVPBcF4uyMFBG1oiMs
+ojP+is6A30KLytVq+N04/jj9rpDUhVKet7upKwvj29ltl/8l9/jx00pJDunSHt8h
+OQaWSz/SZAqW9fA+xVqEZ9RCSv/Ugo2mdGb4xQIDAQABo1owWDAOBgNVHQ8BAf8E
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw
-Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA
-n2I9uY34QxYLfMCIwI3oMkR+v0ehEmjLcF3S2SILybtKFOxHUvFx10IiYJOCjPKr
-vTwbprTp4R9HffQyiGoe9jLYu+8Tfjf86hDcoChOg8SZm1u3rXCgXPus+19XON0g
-UWiJmIBAWDhz8+0vQ3QyrgtLuweoX4tTcbYOlTzO5KU=
+Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA
+IddoaqJ/H9Ya+Iz1wRpWziTi3z7goy9Rxd6Q8f85Nra4M/3Ax2irXtgQINRho37l
+RmoaXVy+pTU1ncQfRiVfQML2ce9+OCQ4p5rZFxZDhh0OxKaHKrfFTvHbeNB1FH8Z
+SH0mRVgnK1F+8TTkThNZctKe0jhqzsp41sRBPrYIEUk=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: Certificate Authority
subject=/O=example.org/CN=clica CA
issuer=/O=example.org/CN=clica CA
-----BEGIN CERTIFICATE-----
-MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt
-cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA4WhcNMzgw
-MTAxMTIzNDA4WjApMRQwEgYDVQQKEwtleGFtcGxlLm9yZzERMA8GA1UEAxMIY2xp
-Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmGE/1NBbn57y9RAMTa
-/jWgErk9jUKo+z0vzO5me7MUE+C3Jhk2YFF+w3ryEny3DikQOZEdRU4NFrQKZKu5
-1jjYg5ilg8EJTP6h9GzZmacH9olW3hdMvVqMkiLuZF97H41AYx95XPDibxwrpMgD
-oDVoYTQIPBwdjj8d88SdbgYjAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
-DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBAINsDZLZin7u8iOLguRG
-37mUDNhAQ9qUAtiFV8JnjJU9DZGb0TvSpYmOkjK2iH4cH6AsEXptB6duvkkpp6ly
-+aGvlqy69D/MfPpLjLX7e6WOISshaWCGB7/rQqbRtAePFpa07gijUqxM22LfiHXz
-YHJSTjLx4idfdLNS+U5iir1Y
------END CERTIFICATE-----
-Bag Attributes
- friendlyName: server2.example.org
- localKeyID: 86 EB 3E FE 4D A0 AA B2 44 D0 9C 33 41 91 11 0F E4 B5 77 94
-subject=/CN=server2.example.org
-issuer=/O=example.org/CN=clica Signing Cert
------BEGIN CERTIFICATE-----
-MIICiDCCAfGgAwIBAgICAMkwDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhh
-bXBsZS5vcmcxGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDEx
-MjM0MTBaFw0zODAxMDExMjM0MTBaMB4xHDAaBgNVBAMTE3NlcnZlcjIuZXhhbXBs
-ZS5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALLE1hEpg5JGIpYSHMWN
-E/s8UpUxBYBqQI0cecr5uwwoNfBybw6cpEwP1XMHlVqlz4nP9Gfo7XLI3dE/GQ0H
-4/Urlw8tP/hydlP8LxXG3ZDyL7f4yYvoHCxsUy7jC3yv9Z0lQx59gvdTho3OZkIW
-he3mmSY/aH7pXrP+Y0CcPdNvAgMBAAGjgb8wgbwwDgYDVR0PAQH/BAQDAgTwMCAG
-A1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAj
-hiFodHRwOi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEE
-KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLm9yZy8wHgYDVR0R
-BBcwFYITc2VydmVyMi5leGFtcGxlLm9yZzANBgkqhkiG9w0BAQUFAAOBgQCOfWb9
-Dt+2W6GH3500f4QJ8ORluURIEn1rtZaT+Nz9AliREjhBgMInwYhkvzESGqbpeZHG
-mnE8zGHlXBs2H8BAp0jpXpm0BCrCe9B2NPa98CLUuNlraTr+eWoMmf85DHmML/rl
-8N6BKUMgUFBP1KKvDthUFbQ/S+IcsuP2tRH6tg==
+MIIB7jCCAVegAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt
+cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM5WhcNMzgw
+MTAxMTIzNDM5WjApMRQwEgYDVQQKEwtleGFtcGxlLm9yZzERMA8GA1UEAxMIY2xp
+Y2EgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMmC4zNWYntPtKW8nuwo
+JbC14Cwuck7DufEvR6WAtos3NUxjWpS4rQl7bW62AoaSdX0bSIxpyS2wtgQxIoFJ
+yU0Ukseh5lTpAvXEgKyjutRJswbQj0w94O0487KcyBqd1ZDJHJYs9VJ+BfrETwwc
+74Tk8FUQHaH6EQJ28GIJUIJfAgMBAAGjJjAkMBIGA1UdEwEB/wQIMAYBAf8CAQEw
+DgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4GBAISxe2t3sJCPBKD6wyb/
+lAsOu+Llby0cXetGKzGhC+HFHvI5OsjhMtOE5uGp7UYlJzbRrfMx/gSR9pjaXxah
+Bt7JFvcPI6wSDU4bBClsuvMTisenANOOscWHSEvB/YQes3OLnqC2RGSppKshjwVF
+fdbkhlMTV2Oyub2TvrscntOV
-----END CERTIFICATE-----
Bag Attributes
friendlyName: server2.example.org
- localKeyID: 86 EB 3E FE 4D A0 AA B2 44 D0 9C 33 41 91 11 0F E4 B5 77 94
+ localKeyID: E4 FD 7A D4 85 73 D1 21 1D D7 BE 02 53 6C 15 75 E9 85 B7 23
subject=/CN=server2.example.org
issuer=/O=example.org/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICiDCCAfGgAwIBAgICAMkwDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhh
+MIICiDCCAfGgAwIBAgICAMkwDQYJKoZIhvcNAQELBQAwMzEUMBIGA1UEChMLZXhh
bXBsZS5vcmcxGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDEx
-MjM0MTBaFw0zODAxMDExMjM0MTBaMB4xHDAaBgNVBAMTE3NlcnZlcjIuZXhhbXBs
-ZS5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALLE1hEpg5JGIpYSHMWN
-E/s8UpUxBYBqQI0cecr5uwwoNfBybw6cpEwP1XMHlVqlz4nP9Gfo7XLI3dE/GQ0H
-4/Urlw8tP/hydlP8LxXG3ZDyL7f4yYvoHCxsUy7jC3yv9Z0lQx59gvdTho3OZkIW
-he3mmSY/aH7pXrP+Y0CcPdNvAgMBAAGjgb8wgbwwDgYDVR0PAQH/BAQDAgTwMCAG
+MjM0MzlaFw0zODAxMDExMjM0MzlaMB4xHDAaBgNVBAMTE3NlcnZlcjIuZXhhbXBs
+ZS5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMj2LV9J8BpcT0gz+/BB
+rRhEgWfaR+WDr2BYv8p026j6S8UOyi23b1dcVz7IabD26tiXFqn5k5l3/PPU6LrF
+mmevNugh+FRT9kQGN8fgJ8/tE6K5M9FEY3ZzZD0pWK2UIAqR/hLKYjWXr1tozyYK
+cpkvdGqj1Cvdecy8S1j9zIRfAgMBAAGjgb8wgbwwDgYDVR0PAQH/BAQDAgTwMCAG
A1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAj
hiFodHRwOi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEE
KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLm9yZy8wHgYDVR0R
-BBcwFYITc2VydmVyMi5leGFtcGxlLm9yZzANBgkqhkiG9w0BAQUFAAOBgQCOfWb9
-Dt+2W6GH3500f4QJ8ORluURIEn1rtZaT+Nz9AliREjhBgMInwYhkvzESGqbpeZHG
-mnE8zGHlXBs2H8BAp0jpXpm0BCrCe9B2NPa98CLUuNlraTr+eWoMmf85DHmML/rl
-8N6BKUMgUFBP1KKvDthUFbQ/S+IcsuP2tRH6tg==
+BBcwFYITc2VydmVyMi5leGFtcGxlLm9yZzANBgkqhkiG9w0BAQsFAAOBgQB2SpQL
+x4vUKOk6O4fqkYpTEFzVrsYSC35u9ZyLO/gjZfiornVOz8MWQofQmBtb8s4PCRqe
+wqGCLWEb4dkVkEFbJ3AyZsJUYRK4as08dy/zDi9PRG0AgRer6JFNJ81kmFVg+fnA
+wKpgAeZXCEx1KRG5v84b20NWl740gUXpigAWAQ==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADApMRQwEgYDVQQKEwtleGFt\r
-cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDA4WhcNMzgw\r
-MTAxMTIzNDA4WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp\r
-Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrlUzB\r
-ANKQi0cI+jOYOVy2EYu2LOXihiMHi3dX/boaZ2+rIwbWaaAy7gMXLvfay/ml+pyY\r
-hnxQbnfADZN0xXQoHZ3AjBIU6YP2CWpOk/3jrnjW7P84fCie/6SXhfH2l6ZZFaro\r
-yRw10jnO/kgEtFKBQpN7eZ2oPDaGGwuyBVaXqQIDAQABo1owWDAOBgNVHQ8BAf8E\r
+MIICLDCCAZWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADApMRQwEgYDVQQKEwtleGFt\r
+cGxlLm9yZzERMA8GA1UEAxMIY2xpY2EgQ0EwHhcNMTIxMTAxMTIzNDM5WhcNMzgw\r
+MTAxMTIzNDM5WjAzMRQwEgYDVQQKEwtleGFtcGxlLm9yZzEbMBkGA1UEAxMSY2xp\r
+Y2EgU2lnbmluZyBDZXJ0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCpoeV\r
+zjmqBMOrYxP7rj6aXYODfaD1lZTsnopvtoNJu2BBZO9sa2bVPBcF4uyMFBG1oiMs\r
+ojP+is6A30KLytVq+N04/jj9rpDUhVKet7upKwvj29ltl/8l9/jx00pJDunSHt8h\r
+OQaWSz/SZAqW9fA+xVqEZ9RCSv/Ugo2mdGb4xQIDAQABo1owWDAOBgNVHQ8BAf8E\r
BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAyBgNVHR8EKzApMCegJaAjhiFodHRw\r
-Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQEFBQADgYEA\r
-n2I9uY34QxYLfMCIwI3oMkR+v0ehEmjLcF3S2SILybtKFOxHUvFx10IiYJOCjPKr\r
-vTwbprTp4R9HffQyiGoe9jLYu+8Tfjf86hDcoChOg8SZm1u3rXCgXPus+19XON0g\r
-UWiJmIBAWDhz8+0vQ3QyrgtLuweoX4tTcbYOlTzO5KU=
+Oi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwDQYJKoZIhvcNAQELBQADgYEA\r
+IddoaqJ/H9Ya+Iz1wRpWziTi3z7goy9Rxd6Q8f85Nra4M/3Ax2irXtgQINRho37l\r
+RmoaXVy+pTU1ncQfRiVfQML2ce9+OCQ4p5rZFxZDhh0OxKaHKrfFTvHbeNB1FH8Z\r
+SH0mRVgnK1F+8TTkThNZctKe0jhqzsp41sRBPrYIEUk=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: server2.example.org
- localKeyID: 86 EB 3E FE 4D A0 AA B2 44 D0 9C 33 41 91 11 0F E4 B5 77 94
+ localKeyID: E4 FD 7A D4 85 73 D1 21 1D D7 BE 02 53 6C 15 75 E9 85 B7 23
Key Attributes: <No Attributes>
-----BEGIN ENCRYPTED PRIVATE KEY-----
-MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQI/rBIbDk6nrECAggA
-MBQGCCqGSIb3DQMHBAjeDfpn4LPrpgSCAoAqkEeSEHhFDrXw2s6WkSJurj4Pr7+J
-ZliDli+SjbfZfx6aDUEzYmkqQqi2emuNmPirCzE/Ue42+Gd4WA2Yiyj8Rm+oAym6
-y528ujQNEP3w4ItkDT1W2E5IqgXrFfTsnXhFUegDVt2XY//ByYSJTQqn3/Fjm0bC
-ttNoRdnpVhmJYwKJOfrvPLuyZEA0Y/zcY0hJ8oFGWZkvJ6aPx3FqDy1o30i3tJax
-t+plehWN6pxOMwNIwOLZRsMjn1gX+d4XzTlDEk+foX8bSNi1AzClPsF/haU5kjfr
-lcnww7VOU5rXz6r8RJhlLDqyYyNGPrl4oxORoVtBZGBJHqkHB0pPdC39gdrtc8P1
-IDY2GC0hd+QAQCTwb/wmqLTmJXRFQSmvQFGB0/jym2GQxeZHzuXYftY/oGaoOIll
-dy8vrtsMEzz37PZxsT8vJs/aPkqULBI30PpHLiPsJqUd2MeB+w0LNzZokkg44XQU
-o208UXKD90UjyUplv1XdvTHW2uIkL9X5ssVZOcQC1eHZ2Z2ahphDx3mU9hqqW8aI
-43ToptxzxlBMbRU5SJtOWKSzUqXpXAha1T5LDwqE0tgF5H99s6qvdaLN1iTUsCav
-+DfkrniH34WzmeE+u5SxvKT0h4XsRW4TOLEdTnoaAF4qIK/1rzcp/X7XxgDsJd3z
-RJBxAogwmaKoxa3GQJjJSjg5qw9EFHUnI9g8Ct+rm5lgHFR0amBHGumqwzTelJ09
-/IZfEMkpgJYJkWkDbvT1NNHNiAgh1VGOUmVsLCoQNhurdHKrF7Uw5QrVOlsrj/pz
-ojArIa6IkJJ85RyzGNToZTwlXHxGyltsosEOt0R5pn176ILRFcWDhguk
+MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIK56kTGU+QxMCAggA
+MBQGCCqGSIb3DQMHBAghqiBxmn7UnASCAoBEeu1CflSYGV/PqgxGzfx5wJJrA4cD
+ZpMO6MiTHPFtc0InHbTbktgCSV+PCKaxrGlEcFFMIxZEtXrAkDe12saApfwfM3D8
+l+vEhBmxl+VQoUMCbgp1ujlNQ2QKvcjXFrcX29KG3k6NANFyFjmdCLXXWcfWhIFT
+7oQbmKpr7giq3cOFjj8X/hSQSH7S0rNEH7NrPB33OVfaRbJqNoIvBk9u/7/Bo3mi
+nLck2lxiRqiqqlRmYT3PDk3EAXM+gIFXTsfblP6c3XrUcLoTj2FVkDdzRrr5f4u5
+W2b5IbeErVeCBst0sV5chB+YW2gmglQNnUZEdRDQX2R3V7j1o8zuQRRUWlL9NcV6
+yr3v8Wn5RKaLH6Uy1FEqF5fDF/CwqZxBvj3FdKzGFgRsqBmOXBcPbNcSYghlhIND
+3vk9+IRPTGjYu0H6gfLKNQsr1QrEbGtTtugJZgo3YJgt3xib/rmb561ZYDFKjY0L
+79hOiIhikqZRaWqXWNyvnTwAtQ4kiF82neBX8Qjo0mwn8DOFX0qTbLEpXhW7Tex/
+tFeI+20VTzJek0J2xBapxp74NL6JFaiRNLLJwdfPmAJ8fjBey4TrZhpiyfsZJtnf
+sHN0QMxfrQBzyEbWr3vgYg0NsR/2ZW5ozH/BVPdtDsQU1y1iIH8nrV0uNa/O7WzO
+qvmQKw/BXCbdouZbVPF6O2Gc07kDJTqmZT5tfMKdBpehwOu9KENPAJwZAUUXj08z
+N2Tec1BZApFcQrKPqfRA5LPnvYXdsxeArdeJwNMpGBP5wyX71aYUK7TiV4cQo3gs
+sLDMbdWR5zsFPUzSgAQ+H8Uv6ylpv1JqCBPzEIESsJymgoyqmVrQKSdg
-----END ENCRYPTED PRIVATE KEY-----
Bag Attributes
friendlyName: server2.example.org
- localKeyID: 86 EB 3E FE 4D A0 AA B2 44 D0 9C 33 41 91 11 0F E4 B5 77 94
+ localKeyID: E4 FD 7A D4 85 73 D1 21 1D D7 BE 02 53 6C 15 75 E9 85 B7 23
subject=/CN=server2.example.org
issuer=/O=example.org/CN=clica Signing Cert
-----BEGIN CERTIFICATE-----
-MIICiDCCAfGgAwIBAgICAMkwDQYJKoZIhvcNAQEFBQAwMzEUMBIGA1UEChMLZXhh
+MIICiDCCAfGgAwIBAgICAMkwDQYJKoZIhvcNAQELBQAwMzEUMBIGA1UEChMLZXhh
bXBsZS5vcmcxGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDEx
-MjM0MTBaFw0zODAxMDExMjM0MTBaMB4xHDAaBgNVBAMTE3NlcnZlcjIuZXhhbXBs
-ZS5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALLE1hEpg5JGIpYSHMWN
-E/s8UpUxBYBqQI0cecr5uwwoNfBybw6cpEwP1XMHlVqlz4nP9Gfo7XLI3dE/GQ0H
-4/Urlw8tP/hydlP8LxXG3ZDyL7f4yYvoHCxsUy7jC3yv9Z0lQx59gvdTho3OZkIW
-he3mmSY/aH7pXrP+Y0CcPdNvAgMBAAGjgb8wgbwwDgYDVR0PAQH/BAQDAgTwMCAG
+MjM0MzlaFw0zODAxMDExMjM0MzlaMB4xHDAaBgNVBAMTE3NlcnZlcjIuZXhhbXBs
+ZS5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMj2LV9J8BpcT0gz+/BB
+rRhEgWfaR+WDr2BYv8p026j6S8UOyi23b1dcVz7IabD26tiXFqn5k5l3/PPU6LrF
+mmevNugh+FRT9kQGN8fgJ8/tE6K5M9FEY3ZzZD0pWK2UIAqR/hLKYjWXr1tozyYK
+cpkvdGqj1Cvdecy8S1j9zIRfAgMBAAGjgb8wgbwwDgYDVR0PAQH/BAQDAgTwMCAG
A1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAj
hiFodHRwOi8vY3JsLmV4YW1wbGUub3JnL2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEE
KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLm9yZy8wHgYDVR0R
-BBcwFYITc2VydmVyMi5leGFtcGxlLm9yZzANBgkqhkiG9w0BAQUFAAOBgQCOfWb9
-Dt+2W6GH3500f4QJ8ORluURIEn1rtZaT+Nz9AliREjhBgMInwYhkvzESGqbpeZHG
-mnE8zGHlXBs2H8BAp0jpXpm0BCrCe9B2NPa98CLUuNlraTr+eWoMmf85DHmML/rl
-8N6BKUMgUFBP1KKvDthUFbQ/S+IcsuP2tRH6tg==
+BBcwFYITc2VydmVyMi5leGFtcGxlLm9yZzANBgkqhkiG9w0BAQsFAAOBgQB2SpQL
+x4vUKOk6O4fqkYpTEFzVrsYSC35u9ZyLO/gjZfiornVOz8MWQofQmBtb8s4PCRqe
+wqGCLWEb4dkVkEFbJ3AyZsJUYRK4as08dy/zDi9PRG0AgRer6JFNJ81kmFVg+fnA
+wKpgAeZXCEx1KRG5v84b20NWl740gUXpigAWAQ==
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
-MIICWwIBAAKBgQCyxNYRKYOSRiKWEhzFjRP7PFKVMQWAakCNHHnK+bsMKDXwcm8O
-nKRMD9VzB5Vapc+Jz/Rn6O1yyN3RPxkNB+P1K5cPLT/4cnZT/C8Vxt2Q8i+3+MmL
-6BwsbFMu4wt8r/WdJUMefYL3U4aNzmZCFoXt5pkmP2h+6V6z/mNAnD3TbwIDAQAB
-AoGAHxMYIuOUe1i1qmB7n9tmHcXelRBwZGIT1nOcuCuw1+wldCZwJ5oS9SXLdLNc
-wuUPrmT3lxhmLg28gSL2t80nUqxTiVGBJhP17hHlOpVqVYSuJTSk9nAPOh21WfOo
-ghHEwK6bUiMvrOo9jzNzYozqZ1aJsFc7kh3WugXvsBLGvAECQQDeTIyF5EDPBkgx
-8Uhznw5kzn/UfcFGQIbAUupSo9hSlGtxIQl6nZZx7lZpUbQz/IGrx9avrG0x8CGf
-kRh5XN5LAkEAzd7gviJg3zZ46uLqNaaIr9B1M+NF2GHj8WgBfDb5WOloo68CWSW8
-WALKbabBp0eHiNEn/X1MHKBfY6LrrScY7QJAJA56hIUfVfUI5MDkJYzZAtTTux2i
-qchxkuRgCYN15P8Z5kGbjf3dlyE3duG/vuboCXrigaAQHhd6/KzGMXk0vQJAFmKD
-oWjvi5XKtA+UU90Vw7gw5kFyGMMcG+WpM65ukmJexF2FLdhSkGdNR3r4V44JiLDl
-XkS/f+VYOec/JQa5SQJAPaND0R38kuFxDDngET/1Lh2vXTpza7Xi0/1ec3i4jXe0
-HckZVHpVE7PWt1iqKRShoZmXI+ccIGLDdFTDYPSMMg==
+MIICXgIBAAKBgQDI9i1fSfAaXE9IM/vwQa0YRIFn2kflg69gWL/KdNuo+kvFDsot
+t29XXFc+yGmw9urYlxap+ZOZd/zz1Oi6xZpnrzboIfhUU/ZEBjfH4CfP7ROiuTPR
+RGN2c2Q9KVitlCAKkf4SymI1l69baM8mCnKZL3Rqo9Qr3XnMvEtY/cyEXwIDAQAB
+AoGBAIU+XHUKtAz2WYbZGNmC4j7t5RMzsmnl9xkdnwSgmKggVK6ykLDhKAy3aA1z
+mkhAXxP+kYNfvFKMMQaGi0yTCj04MlfoCp/6sfwFRERKX1SXsXTVqe52sphPILc8
+Hh/XnnsDQ5moXl4V4nmHJjKvbAJ0QYEEs5ub7vC+s/W+m6fxAkEA/oybxxK/8vTJ
+BTrhAeCKsS9kwvrU67JhsL5gBQNSqsq8tlqUphIlBeEImC9sPga4HSi1Tdb+6UJp
+P4IIg9u6ZwJBAMobYi42jp1/xs6sZ27bLMFEZ5WBJiX12IKpOEV8/Kl34hBpD+PT
+OQlH3HJZ2r7feDnkaZOuJW7udGdg8fZ4m0kCQQDXvmEBtziNOT9veVnf92pVhq/G
+OkZghk4aOSC03v4f17lebSN0JgjPFM3t/rOlVpiRzkDsen6PQURnGVUSPRedAkEA
+qvKYi/A3lv6CIUPwRPL8GwkJ+IoBw2/7zyDk6Nm8OHefbjP/bbu2baQr0UkxXetV
+HNqXdoOBRCBLszlr0AbZiQJAIuP9czE0POJZgJ6vZdl/DUg6GVT91fRfOOj5LX7u
+tiunxTLUIuSqHgBGrHTEMbyarUW8XzuqsV0h2mfagorMlQ==
-----END RSA PRIVATE KEY-----
#!/bin/bash
#
+set -e
+set -x
+
echo Ensure time is set to 2012/11/01 12:34
echo use - date -u 110112342012
echo hit return when ready
read junk
for tld in com org net
do
- clica -D example.$tld -p password -B 1024 -I -N example.$tld -F \
+ idir="example.$tld"
+ rm -fr "$idir"
+ clica -D "$idir" -p password -B 1024 -I -N example.$tld -F \
-C http://crl.example.$tld/latest.crl -O http://oscp/example.$tld/
clica -D example.$tld -p password -s 101 -S server1.example.$tld \
- -8 alternatename.server1.example.$tld,alternatename2.server1.example.$tld
+ -8 alternatename.server1.example.$tld,alternatename2.server1.example.$tld,*.test.ex
clica -D example.$tld -p password -s 102 -S revoked1.example.$tld
clica -D example.$tld -p password -s 103 -S expired1.example.$tld -m 1
clica -D example.$tld -p password -s 201 -S server2.example.$tld
# cannot then use (the key applies to the first cert in the file?).
# Generate a shuffled one.
cd example.$tld/server1.example.$tld
- openssl pkcs12 -in server1.example.com.p12 -passin file:pwdfile -cacerts -out cacerts.pem -nokeys
- cat server1.example.com.pem cacerts.pem > fullchain.pem
+ openssl pkcs12 -in server1.example.$tld.p12 -passin file:pwdfile -cacerts -out cacerts.pem -nokeys
+ cat server1.example.$tld.pem cacerts.pem > fullchain.pem
rm cacerts.pem
cd ../..
done
done
echo Please to reset date to now.
-echo service ntpdate start
+echo 'service ntpdate start (not on a systemd though...)'
echo
echo Then hit return
read junk
# Finally, a single certificate-directory
cd example.com/server1.example.com
-mkdir -f certdir
+mkdir -p certdir
cd certdir
f=../../CA/CA.pem
h=`openssl x509 -hash -noout -in $f`
+rm -f $h.0
ln -s $f $h.0
f=../../CA/Signer.pem
h=`openssl x509 -hash -noout -in $f`
+rm -f $h.0
ln -s $f $h.0
-cd ../..
+cd ../../..
+
+pwd
+ls -l
find example.* -type d -print0 | xargs -0 chmod 755
find example.* -type f -print0 | xargs -0 chmod 644
dnl Checks for header files.
+AC_CHECK_HEADERS(sys/socket.h)
AC_CHECK_HEADERS(openssl/crypto.h,[CLIENT_SSL=bin/client-ssl])
AC_CHECK_HEADERS(gnutls/gnutls.h,[CLIENT_GNUTLS=bin/client-gnutls])
AC_SEARCH_LIBS([inet_addr], [nsl])
AC_SEARCH_LIBS([connect], [socket])
+AC_SEARCH_LIBS([inet_pton], [nsl socket resolv])
+AC_SEARCH_LIBS([inet_ntop], [nsl socket resolv])
dnl "Export" these variables
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# End
tcp_nodelay = false
timeout_frozen_after = 7d
timezone = EDT
+tls_advertise_hosts =
trusted_groups = 42
trusted_users = ${readfile{DIR/aux-fixed/TESTNUM.trusted}{:}}
unknown_login = unknownlogin
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
acl_smtp_rcpt = check_recipient
domainlist local_domains = test.ex
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
acl_smtp_rcpt = check_recipient
domainlist local_domains = test.ex
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
acl_smtp_rcpt = accept
trusted_users = CALLER
+log_selector = +smtp_no_mail
# ----- Routers -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/SERVER%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/SERVER%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
+disable_ipv6 = true
+
addresslist ok_senders = ok@ok.ok
domainlist local_domains = test.ex : *.test.ex
acl_V4NET_0_0:
require verify = reverse_host_lookup
accept
+acl_V4NET_99_99:
+ accept local_parts = defer_ok
+ verify = reverse_host_lookup/defer_ok
+ accept verify = reverse_host_lookup
acl_V4NET_11_12:
deny message = host in DNS list $dnslist_domain: $dnslist_text
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
acl_data:
deny log_message = body contains trigger
condition = ${if match{$message_body}{trigger}{yes}{no}}
+ warn logwrite = \$h_from: '$h_from:'
require verify = header_syntax
warn message = X-warning: this is a test warning
accept senders = ! :
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/SERVER%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/SERVER%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
trusted_users = CALLER
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
trusted_users = CALLER
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
trusted_users = CALLER
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
trusted_users = CALLER
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
trusted_users = CALLER
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
+disable_ipv6 = true
+
domainlist local_domains = test.ex : myhost.ex
acl_smtp_rcpt = check_recipient$local_part
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
begin acl
check_message:
- require verify = header_syntax
+ deny !verify = header_syntax
+ logwrite = acl_verify_message: '$acl_verify_message'
accept
# End
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
begin routers
+bydns:
+ driver = dnslookup
+ domains = mxt2.test.ex
+ transport = smtp
+ fail_defer_domains = *
+
all:
driver = manualroute
route_list = simple thishost.test.ex byname \
; complex thisloop.test.ex byname \
+ ; nonexist nonexist.test.ex byname \
; * 127.0.0.1 byname
self = send
+ host_find_failed = defer
transport = smtp
rcpt45x.test.ex rcpt_45x F,10d,2m
rcpt463.test.ex rcpt_463 F,10d,3m
rcpt4xx.test.ex rcpt_4xx F,10d,1m
+* lookup F,10d,30m
*@\N^\d * F,5d,1m
*@*.abcd.ex * F,5d,2m
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/SERVER%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
driver = smtp
port = PORT_S
transport_filter = \
- /bin/sh -c "cat >/dev/null; /bin/echo -n Line without end"
+ /bin/sh -c \
+ "cat >/dev/null; printf Line-without-end || /bin/echo -n Line-without-end"
# End
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
queue_run_in_order
trusted_users = CALLER
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
queue_run_in_order
trusted_users = CALLER
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
others:
driver = manualroute
domains = ! +local_domains
- route_list = * 127.0.0.1 byname
+ route_list = * localhost4.test.ex byname
self = send
transport = smtp
no_more
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/SERVER%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/SERVER%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
begin routers
+.ifdef RT
+to_server:
+ driver = manualroute
+ transport = remote
+ route_list = * 127.0.0.1
+ self = send
+.endif
+
fail_remote_domains:
driver = redirect
domains = ! +local_domains
headers_add = Port: $sender_host_port
user = CALLER
+remote:
+ driver = smtp
+ port = PORT_D
# ----- Retry -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/SERVER%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
# Exim test configuration 0288
+# serialize_hosts option on smtp transport
exim_path = EXIM_PATH
host_lookup_order = bydns
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
trusted_users = CALLER
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
trusted_users = CALLER
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
trusted_users = CALLER
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
trusted_users = CALLER
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
trusted_users = CALLER
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
trusted_users = CALLER
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
trusted_users = CALLER
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/SERVER%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
spool_directory = DIR/spool
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/SERVER%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/SERVER%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
driver = redirect
headers_remove = Remove-Me-Also:
headers_remove = Remove-Me:
+ headers_remove = <; Remove-Me-Too ; Remove-Me-Too2
data = $local_part@domain
r3:
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/SERVER%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
warn set acl_c1 = ${eval:$acl_c1+1}
accept
+q_sub:
+ deny
+
check_quit:
warn logwrite = Messages received: $acl_c1
logwrite = Messages accepted: $acl_c0
logwrite = Recipients: $acl_c2
logwrite = Accepted: $acl_c3
+
+ require !acl = q_sub
+
LAST
check_rcpt:
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
gecos_pattern = ""
gecos_name = CALLER_NAME
log_selector = +smtp_mailauth
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/SERVER%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
begin retry
-thishost.test.ex * F,15s,1s
+thishost.test.ex * F,20s,2s
* * F,1s,1s; F,1s,5s
# End
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/SERVER%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/SERVER%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
# Exim test configuration 0563
+tls_advertise_hosts =
qualify_domain = testexim.test.ex
localpartlist aliases = joe:sam:tom
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_selector = +8bitmime
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
--- /dev/null
+# Exim test configuration 0571
+
+LOG_SELECTOR=
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+primary_hostname = myhost.test.ex
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+tls_advertise_hosts =
+
+# ----- Main settings -----
+
+disable_ipv6 = true
+
+addresslist ok_senders = ok@ok.ok
+
+domainlist local_domains = test.ex : *.test.ex
+
+qualify_domain = test.ex
+trusted_users = CALLER
+
+# Use first three components of from_domain to select ACL
+acl_not_smtp = ${if def:sender_address \
+ {acl_${sg{${tr{$sender_address_domain}{.}{_}}}{^(.*)_.*\$}{\$1}}} \
+ {accept control=queue_only}}
+
+# ----- ACLs -----
+
+begin acl
+
+acl_29_29_29:
+ deny dnslists = test.ex/$sender_address_domain
+ accept
+
+acl_29_29_0:
+ deny dnslists = test.ex
+ accept
+
+# ----- Transports -----
+
+begin transports
+
+t1:
+ driver = appendfile
+ file = DIR/test-mail/$local_part
+ user = CALLER
+
+t2:
+ driver = appendfile
+ file = DIR/test-mail/okbatch
+ user = CALLER
+ batch_max = 100
+ envelope_to_add
+
+# ----- Routers -----
+
+begin routers
+
+r0:
+ driver = accept
+ local_parts = ^ok
+ transport = t2
+
+r1:
+ driver = accept
+ local_parts = ^userx : ^cond-
+ transport = t1
+
+r2:
+ driver = redirect
+ local_parts = fail
+ allow_fail
+ data = :fail: here is a fail message
+
+# End
--- /dev/null
+4020
\ No newline at end of file
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
exim_path = EXIM_PATH
spool_directory = DIR/spool
log_file_path = DIR/spool/log/%slog
+tls_advertise_hosts =
queue_only
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
--- /dev/null
+# Exim test configuration 0603
+# Add several messages going to the same location
+# And change smtp output based on senders domain
+
+hostlist loopback = <; 127.0.0.0/8 ; 0.0.0.0 ; ::1 ; 0000:0000:0000:0000:0000:ffff
+untrusted_set_sender = *
+
+SERVER =
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+#primary_hostname = myhost.test.ex
+rfc1413_query_timeout = 0s
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/SERVER%slog
+log_selector = +sender_on_delivery
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+tls_advertise_hosts =
+
+# ----- Main settings -----
+
+acl_smtp_rcpt = accept
+
+queue_only
+queue_run_in_order
+
+# ----- Routers -----
+
+begin routers
+
+client:
+ driver = accept
+ condition = ${if eq {SERVER}{server}{no}{yes}}
+ transport = send_to_server
+
+server:
+ driver = accept
+ transport = send_to_server
+
+
+# ----- Transports -----
+
+begin transports
+
+send_to_server:
+ driver = smtp
+ connection_max_messages = 0
+ allow_localhost
+ hosts = 127.0.0.1
+ port = PORT_D
+ interface = ${if eq {$sender_address_domain}{dustybelt.tld} {127.0.0.1}{127.0.0.2}}
+
+# ----- Retry -----
+
+begin retry
+
+* * F,5d,10s
+
+# End
+
--- /dev/null
+# Exim test configuration 0604
+# Send many messages in hopes of tripping continuation records code
+
+hostlist loopback = <; 127.0.0.0/8 ; 0.0.0.0 ; ::1 ; 0000:0000:0000:0000:0000:ffff
+untrusted_set_sender = *
+
+SERVER =
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+#primary_hostname = myhost.test.ex
+rfc1413_query_timeout = 0s
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/SERVER%slog
+log_selector = +sender_on_delivery
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+tls_advertise_hosts =
+
+# ----- Main settings -----
+
+acl_smtp_rcpt = accept
+
+queue_only
+queue_run_in_order
+
+# ----- Routers -----
+
+begin routers
+
+client:
+ driver = accept
+ condition = ${if eq {SERVER}{server}{no}{yes}}
+ transport = send_to_server
+
+server:
+ driver = accept
+ transport = send_to_server
+
+
+# ----- Transports -----
+
+begin transports
+
+send_to_server:
+ driver = smtp
+ connection_max_messages = 0
+ allow_localhost
+ hosts = 127.0.0.1
+ port = PORT_D
+ interface = ${if eq {$sender_address_domain}{dustybelt.tld} {127.0.0.1}{127.0.0.2}}
+
+# ----- Retry -----
+
+begin retry
+
+* * F,5d,10s
+
+# End
+
--- /dev/null
+# Exim test configuration 0605
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/SERVER%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+tls_advertise_hosts =
+
+# ----- Main settings -----
+
+disable_ipv6 = true
+
+acl_smtp_rcpt = accept hosts = test.again.dns
+
+queue_only
+
+# End
+
--- /dev/null
+# Exim test configuration 0606
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/SERVER%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+tls_advertise_hosts =
+
+slow_lookup_log = 1000
+
+acl_smtp_rcpt = accept verify = recipient
+
+queue_only
+
+begin routers
+
+all:
+ driver = dnslookup
+ verify_only
+ self = send
+
+# End
+
--- /dev/null
+# Exim test configuration 0607
+
+SERVER =
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/SERVER%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+tls_advertise_hosts =
+
+log_selector = +received_recipients +sender_on_delivery
+
+acl_smtp_rcpt = accept
+queue_only
+queue_run_in_order
+
+#---------------
+
+begin routers
+
+dump:
+ driver = redirect
+ condition = ${if eq {SERVER}{server}{yes}{no}}
+ data = :blackhole:
+
+all:
+ driver = dnslookup
+ self = send
+ transport = out
+
+#---------------
+
+begin transports
+
+out:
+ driver = smtp
+ port = PORT_D
+
+# End
+
--- /dev/null
+# Exim test configuration 0608
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+primary_hostname = myhost.test.ex
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+tls_advertise_hosts =
+
+# ----- Main settings -----
+
+acl_smtp_helo = check_helo
+
+
+# ----- ACLs -----
+
+begin acl
+
+check_helo:
+ require verify = helo
+ accept logwrite = helo $sender_helo_name dnssec <$sender_helo_dnssec>
+
+# End
--- /dev/null
+# Exim test configuration 0609
+# Long ACL delays
+
+SERVER=
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+primary_hostname = myhost.test.ex
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/SERVER%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+tls_advertise_hosts =
+
+# ----- Main settings -----
+
+disable_ipv6 = true
+
+acl_smtp_rcpt = delay4_accept
+log_selector = +smtp_connection
+#hosts_connection_nolog = : 127.0.0.1
+
+
+# ----- ACLs -----
+
+begin acl
+
+delay4_accept:
+ accept delay = 4s
+
+# ----- Routers -----
+
+begin routers
+
+accept:
+ driver = accept
+ transport = appendfile
+
+# ----- Transports -----
+
+begin transports
+
+appendfile:
+ driver = appendfile
+ file = DIR/test-mail/$local_part
+ user = CALLER
+
+# End
--- /dev/null
+# Exim test configuration 0610
+
+SERVER =
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+#primary_hostname = myhost.test.ex
+rfc1413_query_timeout = 0s
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/SERVER%slog
+log_selector = +sender_on_delivery
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+tls_advertise_hosts =
+
+# ----- Main settings -----
+
+acl_smtp_connect = conn_chk
+acl_smtp_rcpt = accept
+
+untrusted_set_sender = *
+queue_only
+queue_run_in_order
+
+# ----- ACL -----
+
+begin acl
+
+conn_chk:
+ defer condition = ${if eq {SERVER}{server}}
+ accept
+
+# ----- Routers -----
+
+begin routers
+
+client:
+ driver = accept
+ transport = $sender_address_local_part
+
+# ----- Transports -----
+
+begin transports
+
+t1:
+ driver = smtp
+ allow_localhost
+ hosts = 127.0.0.1
+ port = PORT_D
+ interface = 127.0.0.1
+
+t2:
+ driver = smtp
+ allow_localhost
+ hosts = 127.0.0.1
+ port = PORT_D
+ interface = 127.0.0.2
+
+# ----- Retry -----
+
+begin retry
+
+* * F,5d,10s
+
+# End
+
--- /dev/null
+# Exim test configuration 0611
+# max_parallel on transport
+
+SERVER=
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+primary_hostname = myhost.test.ex
+spool_directory = DIR/spool
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+tls_advertise_hosts =
+
+# ----- Main settings -----
+
+log_file_path = DIR/spool/log/${if eq {SERVER}{server} {server_}{}}%slog
+
+qualify_domain = test.ex
+queue_run_in_order
+log_selector = +received_recipients
+
+acl_smtp_rcpt = accept ${if eq {SERVER}{server} {delay = 2s}}
+
+# ----- Routers -----
+
+begin routers
+
+server:
+ condition = ${if eq {SERVER}{server} {yes}{no}}
+ driver = redirect
+ data = :blackhole:
+
+rmt_client:
+ local_parts = a:b:c
+ driver = manualroute
+ route_list = * 127.0.0.1
+ self = send
+ transport = smtp
+
+lcl_client:
+ local_parts = x:y:z
+ driver = accept
+ transport = pipe
+
+# ----- Transports -----
+
+begin transports
+
+smtp:
+ driver = smtp
+ port = PORT_D
+ max_rcpt = 1
+ connection_max_messages = 1
+ max_parallel = 2
+
+pipe:
+ driver = pipe
+ command = "sleep 2; cat > /dev/null"
+ use_shell = true
+ max_parallel = 1
+
+# ----- Retry -----
+
+
+begin retry
+
+* * F,1h,10m
+
+
+# End
--- /dev/null
+# Exim test configuration 0612
+# log_defer_output on pipe transport
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+primary_hostname = myhost.test.ex
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+tls_advertise_hosts =
+
+# ----- Main settings -----
+
+log_selector = +received_recipients
+
+#acl_smtp_rcpt = accept
+
+# ----- Routers -----
+
+begin routers
+
+client:
+ driver = accept
+ transport = pipe
+
+# ----- Transports -----
+
+begin transports
+
+pipe:
+ driver = pipe
+ temp_errors = *
+ command = perl -e "print 'Hi from pipe'; exit 5;"
+ log_defer_output = true
+
+# ----- Retry -----
+
+
+begin retry
+
+* * F,1h,10m
+
+
+# End
--- /dev/null
+# Exim test configuration 0613
+# manualroute, hosts_randomize and multiple recipients
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+primary_hostname = myhost.test.ex
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+tls_advertise_hosts =
+
+# ----- Main settings -----
+
+mua_wrapper = true
+log_selector = +received_recipients
+
+# ----- Routers -----
+
+begin routers
+
+smarthost:
+ driver = manualroute
+ hosts_randomize = true
+ route_list = * "</ ten-2.test.ex:15600 / ten-3.test.ex:15600"
+ transport = remote_smtp
+ no_more
+
+# ----- Transports -----
+
+begin transports
+
+remote_smtp:
+ driver = smtp
+
+# End
--- /dev/null
+# Exim test configuration 0614
+# hosts_connection_nolog versus sender_host lists caching
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+primary_hostname = myhost.test.ex
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+tls_advertise_hosts =
+
+# ----- Main settings -----
+
+log_selector = +smtp_connection
+hostlist nolog = 127.0.0.1
+hosts_connection_nolog = +nolog
+queue_only
+
+# End
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/SERVER%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/SERVER%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/SERVER%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
DES-CBC3-SHA : \
DHE_RSA_AES_256_CBC_SHA1 : \
DHE_RSA_3DES_EDE_CBC_SHA : \
- RSA_AES_256_CBC_SHA1
+ RSA_AES_256_CBC_SHA1 : \
+ ECDHE_RSA_AES_256_GCM_SHA384
warn logwrite = ${if def:tls_in_ourcert \
{Our cert SN: <${certextract{subject}{$tls_in_ourcert}}>} \
{We did not present a cert}}
# ----- Main settings -----
+log_selector = +outgoing_port
+
acl_smtp_rcpt = accept
queue_only
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
DES-CBC3-SHA:\
DHE_RSA_AES_256_CBC_SHA1:\
DHE_RSA_3DES_EDE_CBC_SHA:\
- RSA_AES_256_CBC_SHA1
+ RSA_AES_256_CBC_SHA1 :\
+ ECDHE_RSA_AES_256_GCM_SHA384
accept
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
qualify_domain = test.ex
tls_advertise_hosts = *
+tls_certificate = DIR/aux-fixed/cert1
trusted_users = CALLER
--- /dev/null
+# Exim test configuration 2033
+# TLS client: verify certificate from server - name-fails
+
+SERVER=
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+primary_hostname = myhost.test.ex
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/SERVER%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+
+FX = DIR/aux-fixed
+S1 = FX/exim-ca/example.com/server1.example.com
+
+CA1 = S1/ca_chain.pem
+CERT1 = S1/server1.example.com.pem
+KEY1 = S1/server1.example.com.unlocked.key
+CA2 = FX/cert2
+CERT2 = FX/cert2
+KEY2 = FX/cert2
+
+# ----- Main settings -----
+
+disable_ipv6 = true
+
+acl_smtp_rcpt = accept
+
+log_selector = +tls_peerdn+tls_certificate_verified
+
+queue_only
+queue_run_in_order
+
+tls_advertise_hosts = *
+
+# Set certificate only if server
+
+tls_certificate = ${if eq {SERVER}{server}{CERT1}fail}
+tls_privatekey = ${if eq {SERVER}{server}{KEY1}fail}
+
+tls_verify_hosts = *
+tls_verify_certificates = ${if eq {SERVER}{server}{CERT2}fail}
+
+
+# ----- Routers -----
+
+begin routers
+
+server_dump:
+ driver = redirect
+ condition = ${if eq {SERVER}{server}{yes}{no}}
+ data = :blackhole:
+
+client_x:
+ driver = accept
+ local_parts = userx
+ retry_use_local_part
+ transport = send_to_server_failcert
+ errors_to = ""
+
+client_y:
+ driver = accept
+ local_parts = usery
+ retry_use_local_part
+ transport = send_to_server_retry
+
+client_z:
+ driver = accept
+ local_parts = userz
+ retry_use_local_part
+ transport = send_to_server_crypt
+
+client_q:
+ driver = accept
+ local_parts = userq
+ retry_use_local_part
+ transport = send_to_server_req_fail
+
+client_r:
+ driver = accept
+ local_parts = userr
+ retry_use_local_part
+ transport = send_to_server_req_failname
+
+client_s:
+ driver = accept
+ local_parts = users
+ retry_use_local_part
+ transport = send_to_server_req_passname
+
+client_t:
+ driver = accept
+ local_parts = usert
+ retry_use_local_part
+ transport = send_to_server_req_failcarryon
+
+# ----- Transports -----
+
+begin transports
+
+# this will fail to verify the cert at HOSTIPV4 so fail the crypt requirement
+send_to_server_failcert:
+ driver = smtp
+ allow_localhost
+ hosts = HOSTIPV4
+ hosts_require_tls = HOSTIPV4
+ port = PORT_D
+ tls_certificate = CERT2
+ tls_privatekey = CERT2
+
+ tls_verify_certificates = CA2
+
+# this will fail to verify the cert at HOSTIPV4 so fail the crypt, then retry on 127.1; ok
+send_to_server_retry:
+ driver = smtp
+ allow_localhost
+ hosts = HOSTIPV4 : 127.0.0.1
+ hosts_require_tls = HOSTIPV4
+ port = PORT_D
+ tls_certificate = CERT2
+ tls_privatekey = CERT2
+
+ tls_verify_certificates = \
+ ${if eq{$host_address}{127.0.0.1}{CA1}{CA2}}
+
+# this will fail to verify the cert but continue unverified though crypted
+send_to_server_crypt:
+ driver = smtp
+ allow_localhost
+ hosts = HOSTIPV4
+ hosts_require_tls = HOSTIPV4
+ port = PORT_D
+ tls_certificate = CERT2
+ tls_privatekey = CERT2
+
+ tls_verify_certificates = CA2
+ tls_try_verify_hosts = *
+
+# this will fail to verify the cert at HOSTNAME and fallback to unencrypted
+# Fail due to lack of correct CA
+send_to_server_req_fail:
+ driver = smtp
+ allow_localhost
+ hosts = HOSTNAME
+ port = PORT_D
+ tls_certificate = CERT2
+ tls_privatekey = CERT2
+
+ tls_verify_certificates = CA2
+ tls_verify_hosts = *
+
+# this will fail to verify the cert name and fallback to unencrypted
+# fail because the cert is "server1.example.com" and the test system is something else
+send_to_server_req_failname:
+ driver = smtp
+ allow_localhost
+ hosts = HOSTNAME
+ port = PORT_D
+ tls_certificate = CERT2
+ tls_privatekey = CERT2
+
+ tls_verify_certificates = CA1
+ tls_verify_cert_hostnames = *
+ tls_verify_hosts = *
+
+# this will pass the cert verify including name check
+# our stunt DNS has an A record for server1.example.com -> HOSTIPV4
+send_to_server_req_passname:
+ driver = smtp
+ allow_localhost
+ hosts = server1.example.com
+ port = PORT_D
+ tls_certificate = CERT2
+ tls_privatekey = CERT2
+
+ tls_verify_certificates = CA1
+ tls_verify_cert_hostnames = *
+ tls_verify_hosts = *
+
+# this will fail to verify the cert name but carry on (try-verify mode)
+# fail because the cert is "server1.example.com" and the test system is something else
+send_to_server_req_failcarryon:
+ driver = smtp
+ allow_localhost
+ hosts = HOSTNAME
+ port = PORT_D
+ tls_certificate = CERT2
+ tls_privatekey = CERT2
+
+ tls_verify_certificates = CA1
+ tls_verify_cert_hostnames = *
+ tls_try_verify_hosts = *
+
+# End
DHE-RSA-AES256-SHA : \
DHE-RSA-AES256-GCM-SHA384 : \
DHE_RSA_AES_256_CBC_SHA1 : \
- DHE_RSA_3DES_EDE_CBC_SHA
+ DHE_RSA_3DES_EDE_CBC_SHA : \
+ ECDHE-RSA-AES256-GCM-SHA384 : \
+ ECDHE-RSA-AES128-GCM-SHA256
warn logwrite = ${if def:tls_in_ourcert \
{Our cert SN: <${certextract{subject}{$tls_in_ourcert}}>} \
{We did not present a cert}}
# ----- Main settings -----
+log_selector = +outgoing_port
+
acl_smtp_rcpt = accept
queue_only
acl_smtp_rcpt = accept
-log_selector = +tls_peerdn+tls_certificate_verified
+log_selector = +tls_peerdn+tls_certificate_verified +received_recipients
queue_only
queue_run_in_order
tls_verify_hosts = *
tls_verify_cert_hostnames =
- # this will fail to verify the cert name and fallback to unencrypted
- send_to_server_req_failname:
+# this will fail to verify the cert name and fallback to unencrypted
+send_to_server_req_failname:
driver = smtp
allow_localhost
hosts = HOSTIPV4
tls_verify_cert_hostnames = server1.example.net : server1.example.org
tls_verify_hosts = *
- # this will pass the cert verify including name check
- send_to_server_req_passname:
+# this will pass the cert verify including name check
+send_to_server_req_passname:
driver = smtp
allow_localhost
hosts = HOSTIPV4
begin acl
check_recipient:
- deny message = certificate not verified: peerdn=$tls_peerdn
+ deny message = certificate not verified: peerdn=$tls_in_peerdn
! verify = certificate
accept
local_delivery:
driver = appendfile
file = DIR/test-mail/$local_part
- headers_add = TLS: cipher=$tls_cipher peerdn=$tls_peerdn
+ headers_add = TLS: cipher=$tls_cipher peerdn=$tls_in_peerdn
user = CALLER
# End
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
DHE-RSA-AES256-SHA:\
DHE-RSA-AES256-GCM-SHA384:\
DHE_RSA_AES_256_CBC_SHA1:\
- DHE_RSA_3DES_EDE_CBC_SHA
+ DHE_RSA_3DES_EDE_CBC_SHA:\
+ ECDHE-RSA-AES256-GCM-SHA384:\
+ ECDHE-RSA-AES128-GCM-SHA256
accept
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
qualify_domain = test.ex
tls_advertise_hosts = *
+tls_certificate = DIR/aux-fixed/cert1
trusted_users = CALLER
domainlist local_domains = test.ex : *.test.ex
acl_smtp_rcpt = acl_log_sni
-log_selector = +tls_peerdn +tls_sni
+log_selector = +tls_peerdn +tls_sni +received_recipients
remote_max_parallel = 1
tls_advertise_hosts = *
DHE-RSA-AES256-SHA : \
DHE-RSA-AES256-GCM-SHA384 : \
DHE_RSA_AES_256_CBC_SHA1 : \
- DHE_RSA_3DES_EDE_CBC_SHA
+ DHE_RSA_3DES_EDE_CBC_SHA : \
+ ECDHE-RSA-AES256-GCM-SHA384 : \
+ ECDHE-RSA-AES128-GCM-SHA256
warn logwrite = ${if def:tls_in_ourcert \
{Our cert SN: <${certextract{subject}{$tls_in_ourcert}}>} \
{We did not present a cert}}
--- /dev/null
+# Exim test configuration 2133
+# TLS client: verify certificate from server - name-fails
+
+SERVER=
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+primary_hostname = myhost.test.ex
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/SERVER%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+
+FX = DIR/aux-fixed
+S1 = FX/exim-ca/example.com/server1.example.com
+
+CA1 = S1/ca_chain.pem
+CERT1 = S1/server1.example.com.pem
+KEY1 = S1/server1.example.com.unlocked.key
+CA2 = FX/cert2
+CERT2 = FX/cert2
+KEY2 = FX/cert2
+
+# ----- Main settings -----
+
+disable_ipv6 = true
+
+acl_smtp_rcpt = accept
+
+log_selector = +tls_peerdn+tls_certificate_verified
+
+queue_only
+queue_run_in_order
+
+tls_advertise_hosts = *
+
+# Set certificate only if server
+
+tls_certificate = ${if eq {SERVER}{server}{CERT1}fail}
+tls_privatekey = ${if eq {SERVER}{server}{KEY1}fail}
+
+tls_verify_hosts = *
+tls_verify_certificates = ${if eq {SERVER}{server}{CERT2}fail}
+
+
+# ----- Routers -----
+
+begin routers
+
+server_dump:
+ driver = redirect
+ condition = ${if eq {SERVER}{server}{yes}{no}}
+ data = :blackhole:
+
+client_x:
+ driver = accept
+ local_parts = userx
+ retry_use_local_part
+ transport = send_to_server_failcert
+ errors_to = ""
+
+client_y:
+ driver = accept
+ local_parts = usery
+ retry_use_local_part
+ transport = send_to_server_retry
+
+client_z:
+ driver = accept
+ local_parts = userz
+ retry_use_local_part
+ transport = send_to_server_crypt
+
+client_q:
+ driver = accept
+ local_parts = userq
+ retry_use_local_part
+ transport = send_to_server_req_fail
+
+client_r:
+ driver = accept
+ local_parts = userr
+ retry_use_local_part
+ transport = send_to_server_req_failname
+
+client_s:
+ driver = accept
+ local_parts = users
+ retry_use_local_part
+ transport = send_to_server_req_passname
+
+client_t:
+ driver = accept
+ local_parts = usert
+ retry_use_local_part
+ transport = send_to_server_req_failcarryon
+
+
+# ----- Transports -----
+
+begin transports
+
+# this will fail to verify the cert at HOSTIPV4 so fail the crypt requirement
+send_to_server_failcert:
+ driver = smtp
+ allow_localhost
+ hosts = HOSTIPV4
+ hosts_require_tls = HOSTIPV4
+ port = PORT_D
+ tls_certificate = CERT2
+ tls_privatekey = CERT2
+
+ tls_verify_certificates = CA2
+
+# this will fail to verify the cert at HOSTIPV4 so fail the crypt, then retry on 127.1; ok
+send_to_server_retry:
+ driver = smtp
+ allow_localhost
+ hosts = HOSTIPV4 : 127.0.0.1
+ hosts_require_tls = HOSTIPV4
+ port = PORT_D
+ tls_certificate = CERT2
+ tls_privatekey = CERT2
+
+ tls_verify_certificates = \
+ ${if eq{$host_address}{127.0.0.1}{CA1}{CA2}}
+
+# this will fail to verify the cert but continue unverified though crypted
+send_to_server_crypt:
+ driver = smtp
+ allow_localhost
+ hosts = HOSTIPV4
+ hosts_require_tls = HOSTIPV4
+ port = PORT_D
+ tls_certificate = CERT2
+ tls_privatekey = CERT2
+
+ tls_verify_certificates = CA2
+ tls_try_verify_hosts = *
+
+# this will fail to verify the cert at HOSTNAME and fallback to unencrypted
+# Fail due to lack of correct CA
+send_to_server_req_fail:
+ driver = smtp
+ allow_localhost
+ hosts = HOSTNAME
+ port = PORT_D
+ tls_certificate = CERT2
+ tls_privatekey = CERT2
+
+ tls_verify_certificates = CA2
+ tls_verify_hosts = *
+
+# this will fail to verify the cert name and fallback to unencrypted
+# fail because the cert is "server1.example.com" and the test system is something else
+send_to_server_req_failname:
+ driver = smtp
+ allow_localhost
+ hosts = HOSTNAME
+ port = PORT_D
+ tls_certificate = CERT2
+ tls_privatekey = CERT2
+
+ tls_verify_certificates = CA1
+ tls_verify_cert_hostnames = *
+ tls_verify_hosts = *
+
+# this will pass the cert verify including name check
+# our stunt DNS has an A record for server1.example.com -> HOSTIPV4
+send_to_server_req_passname:
+ driver = smtp
+ allow_localhost
+ hosts = server1.example.com
+ port = PORT_D
+ tls_certificate = CERT2
+ tls_privatekey = CERT2
+
+ tls_verify_certificates = CA1
+ tls_verify_cert_hostnames = *
+ tls_verify_hosts = *
+
+send_to_server_req_failcarryon:
+ driver = smtp
+ allow_localhost
+ hosts = HOSTNAME
+ port = PORT_D
+ tls_certificate = CERT2
+ tls_privatekey = CERT2
+
+ tls_verify_certificates = CA1
+ tls_verify_cert_hostnames = *
+ tls_try_verify_hosts = *
+
+# End
# Exim test configuration 2200
+# Check for dnsdb cache TTL handling
exim_path = EXIM_PATH
host_lookup_order = bydns
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
+
+# ----- Main settings -----
+
+acl_not_smtp = check_rcpt
+queue_only
+
+begin acl
+
+check_rcpt:
+ warn
+ set acl_m1 = ${map {<,$recipients} \
+ {${lookup dnsdb{a=${domain:$item}}{$value}fail}}}
+ delay = 4s
+ set acl_m1 = ${map {<,$recipients} \
+ {${lookup dnsdb{a=${domain:$item}}{$value}fail}}}
+ accept
# End
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
trusted_users = CALLER
+disable_ipv6
+
+acl_smtp_rcpt = check_rcpt
+acl_not_smtp = check_sndr
+queue_only
+
+# - ACL --
+begin acl
+
+check_rcpt:
+ # Do not care about result, looking at debug output
+ # expect an original lookup, a cached lookup avoidance
+ # then a TTL-required repeat lookup
+ warn dnslists = rbl.test.ex/V4NET.11.12.14
+ dnslists = rbl.test.ex/V4NET.11.12.14
+ delay = 4s
+ dnslists = rbl.test.ex/V4NET.11.12.14
+ accept
+
+check_sndr:
+ # Do not care about result, looking at debug output
+ # expect an original lookup, a cached lookup avoidance
+ # then a TTL-required repeat lookup
+ warn sender_domains = dnsdb;a=$sender_address_domain
+ sender_domains = dnsdb;a=$sender_address_domain
+ delay = 4s
+ sender_domains = dnsdb;a=$sender_address_domain
+ accept
# ----- Routers -----
begin routers
+r0:
+ driver = accept
+ senders = a@shorthost.test.ex
+ transport = remote_delivery
+
r1:
driver = accept
domains = dnsdb;$domain
file = DIR/test-mail/$local_part
user = CALLER
+remote_delivery:
+ driver = smtp
+ hosts = 127.0.0.1
+ allow_localhost
+ port = PORT_D
# ----- Retry -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# End
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
--- /dev/null
+# Exim test configuration 2700
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+primary_hostname = myhost.test.ex
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/SERVER%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+tls_advertise_hosts =
+
+# ----- Main settings -----
+
+redis_servers = 127.0.0.1//
+
+# End
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
log_selector = +smtp_mailauth
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/SERVER%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/SERVER%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
--- /dev/null
+# Exim test configuration 3700
+
+SERVER=
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+primary_hostname = myhost.test.ex
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/SERVER%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+
+log_selector = +received_recipients +outgoing_port
+
+# ----- Main settings -----
+
+acl_smtp_mail = check_authd
+acl_smtp_rcpt = check_authd
+queue_only
+queue_run_in_order
+trusted_users = CALLER
+
+tls_on_connect_ports = PORT_S
+tls_advertise_hosts = *
+tls_certificate = DIR/aux-fixed/cert1
+
+tls_verify_hosts = *
+tls_verify_certificates = DIR/aux-fixed/cert2
+
+
+# ----- ACL -----
+
+begin acl
+
+check_authd:
+ deny message = authentication required
+ !authenticated = *
+ accept
+
+
+# ----- Authentication -----
+
+begin authenticators
+
+tls:
+ driver = tls
+ server_debug_print = +++TLS \$auth1="$auth1"
+ server_param1 = ${quote:${certextract {subject,CN,>:} \
+ {$tls_in_peercert}}}
+ server_condition = ${if def:auth1}
+ server_set_id = $auth1
+
+
+# ----- Routers -----
+
+begin routers
+
+r1:
+ driver = accept
+ transport = ${if eq {$local_part}{smtps} {t2}{t1}}
+
+
+# ----- Transports -----
+
+begin transports
+
+t1:
+ driver = smtp
+ hosts = 127.0.0.1
+ port = PORT_D
+ allow_localhost
+ tls_certificate = DIR/aux-fixed/cert2
+ tls_verify_certificates = DIR/aux-fixed/cert1
+ tls_verify_cert_hostnames = :
+
+t2:
+ driver = smtp
+ hosts = 127.0.0.1
+ port = PORT_S
+ protocol = smtps
+ allow_localhost
+ tls_certificate = DIR/aux-fixed/cert2
+ tls_verify_certificates = DIR/aux-fixed/cert1
+ tls_verify_cert_hostnames = :
+
+# End
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+log_selector = +subject
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
-av_scanner = f-protd : localhost PORT_S
+av_scanner = f-protd : localhost4 PORT_S
# ----- Main settings -----
c_data:
accept !malware = * OPT
- deny logwrite = malware_name $malware_name
+ deny logwrite = $callout_address malware_name $malware_name
# ----- Routers -----
gecos_pattern = ""
gecos_name = CALLER_NAME
log_selector = +subject
+tls_advertise_hosts =
av_scanner = aveserver : DIR/eximdir/aveserver_sock
gecos_pattern = ""
gecos_name = CALLER_NAME
log_selector = +subject
+tls_advertise_hosts =
av_scanner = fsecure : DIR/eximdir/fsec_sock
gecos_pattern = ""
gecos_name = CALLER_NAME
log_selector = +subject
+tls_advertise_hosts =
av_scanner = sophie : DIR/eximdir/sophie_sock
# Exim test configuration 4005
# Content-scan: clamav interface
+OPT=
+CONTROL=
+
exim_path = EXIM_PATH
host_lookup_order = bydns
primary_hostname = myhost.test.ex
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
log_selector = +subject
-av_scanner = clamd : DIR/eximdir/clam_sock
+#XXX we need an additional test for tcp-connected clamd
+av_scanner = clamd : DIR/eximdir/clam_sock CONTROL
# ----- Main settings -----
gecos_pattern = ""
gecos_name = CALLER_NAME
log_selector = +subject
+tls_advertise_hosts =
av_scanner = avast : DIR/eximdir/avast_sock : OPTION
gecos_pattern = ""
gecos_name = CALLER_NAME
log_selector = +subject
+tls_advertise_hosts =
av_scanner = cmdline : DIR/aux-fixed/TESTNUM.script -o OPT %s : found in file : ^(\S*)
--- /dev/null
+# Exim test configuration 4008
+# Content-scan: rspamd interface
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+primary_hostname = myhost.test.ex
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+tls_advertise_hosts =
+log_selector = +subject
+
+spamd_address = 127.0.0.1 11333 variant=rspamd
+
+# ----- Main settings -----
+
+acl_smtp_rcpt = accept
+acl_smtp_data = c_data
+
+begin acl
+
+c_data:
+ warn
+ spam = nobody
+ warn
+ log_message = $spam_action $spam_report
+ accept
+
+# ----- Routers -----
+
+begin routers
+
+r:
+ driver = redirect
+ data = :blackhole:
+
+# End
--- /dev/null
+# Exim test configuration 4009
+# Content-scan: spamassassin interface
+
+OPT= 127.0.0.1 7833
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+primary_hostname = myhost.test.ex
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+tls_advertise_hosts =
+log_selector = +subject
+
+spamd_address = OPT
+
+# ----- Main settings -----
+
+acl_smtp_rcpt = accept
+acl_smtp_data = c_data
+
+begin acl
+
+c_data:
+ warn
+ spam = nobody
+ warn
+ log_message = $callout_address $spam_action $spam_report
+ accept
+
+# ----- Routers -----
+
+begin routers
+
+r:
+ driver = redirect
+ data = :blackhole:
+
+# End
--- /dev/null
+# Exim test configuration 0568: ACL regex=
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+primary_hostname = myhost.test.ex
+rfc1413_query_timeout = 0s
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+tls_advertise_hosts =
+
+
+# ----- Main settings -----
+
+acl_smtp_rcpt = check_rcpt
+acl_smtp_data = check_data
+acl_not_smtp = check_data
+
+
+# ----- ACL -----
+
+begin acl
+
+check_rcpt:
+ accept
+
+check_data:
+ warn regex = \N(THIS\s((\w+)\s)?REGEX)\N
+ message = X-Regex: Regex matched <$regex1> <$regex3>
+
+ warn condition = ${if !eq{$h_fakereject:}{}}
+ control = fakereject
+
+ warn condition = ${if !eq{$h_fakedefer:}{}}
+ control = fakedefer
+
+ accept
+
+# ----- Routers -----
+
+begin routers
+
+r1:
+ driver = accept
+ transport = t1
+
+# ----- Transports -----
+
+begin transports
+
+t1:
+ driver = appendfile
+ file = DIR/test-mail/$local_part
+ user = CALLER
+
+
+# End
--- /dev/null
+4009
\ No newline at end of file
--- /dev/null
+# Exim test configuration 4020
+
+OPT =
+
+exim_path = EXIM_PATH
+hide host_lookup_order = bydns
+primary_hostname = myhost.test.ex
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+tls_advertise_hosts =
+
+# ----- Main settings -----
+
+log_selector = +proxy +outgoing_port
+
+domainlist local_domains = test.ex : *.test.ex
+acl_smtp_rcpt = accept
+
+
+# ----- Routers -----
+
+begin routers
+
+my_main_router:
+ driver = manualroute
+ route_list = * 127.0.0.1
+ self = send
+ transport = my_smtp
+ debug_print = router_name <$router_name>
+ no_more
+
+
+# ----- Transports -----
+
+begin transports
+
+my_smtp:
+ driver = smtp
+ interface = HOSTIPV4
+ port = PORT_S
+ hide socks_proxy = 127.0.0.1 port=PORT_D OPT
+ debug_print = transport_name <$transport_name>
+
+
+# End
--- /dev/null
+# Exim test configuration 4028
+# starttls over socks
+
+OPT =
+SERVER=
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+primary_hostname = myhost.test.ex
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/SERVER%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+
+# ----- Main settings -----
+
+log_selector = +tls_peerdn
+domainlist local_domains = test.ex : *.test.ex
+acl_smtp_rcpt = accept
+
+tls_advertise_hosts = *
+
+# Set certificate only if server
+
+tls_certificate = ${if eq {SERVER}{server}{DIR/aux-fixed/cert1}fail}
+tls_privatekey = ${if eq {SERVER}{server}{DIR/aux-fixed/cert1}fail}
+
+tls_verify_hosts = *
+tls_verify_certificates = ${if eq {SERVER}{server}{DIR/aux-fixed/cert2}fail}
+
+# ----- Routers -----
+
+begin routers
+
+client:
+ driver = manualroute
+ condition = ${if eq {SERVER}{server}{no}{yes}}
+ route_list = * 127.0.0.1
+ self = send
+ transport = my_smtp
+ no_more
+
+server:
+ driver = redirect
+ data = :blackhole:
+
+
+# ----- Transports -----
+
+begin transports
+
+my_smtp:
+ driver = smtp
+ port = PORT_D
+ socks_proxy = 127.0.0.1 port=1080 OPT
+ tls_certificate = DIR/aux-fixed/cert2
+ tls_privatekey = DIR/aux-fixed/cert2
+ tls_verify_certificates = DIR/aux-fixed/cert2
+ tls_try_verify_hosts = *
+
+
+
+# End
--- /dev/null
+# Exim test configuration 4029
+# starttls over socks
+
+OPT =
+SERVER=
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+primary_hostname = myhost.test.ex
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/SERVER%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+
+# ----- Main settings -----
+
+log_selector = +tls_peerdn
+domainlist local_domains = test.ex : *.test.ex
+acl_smtp_rcpt = accept
+
+tls_advertise_hosts = *
+
+# Set certificate only if server
+
+tls_certificate = ${if eq {SERVER}{server}{DIR/aux-fixed/cert1}fail}
+tls_privatekey = ${if eq {SERVER}{server}{DIR/aux-fixed/cert1}fail}
+
+tls_verify_hosts = *
+tls_verify_certificates = ${if eq {SERVER}{server}{DIR/aux-fixed/cert2}fail}
+
+# ----- Routers -----
+
+begin routers
+
+client:
+ driver = manualroute
+ condition = ${if eq {SERVER}{server}{no}{yes}}
+ route_list = * 127.0.0.1
+ self = send
+ transport = my_smtp
+ no_more
+
+server:
+ driver = redirect
+ data = :blackhole:
+
+
+# ----- Transports -----
+
+begin transports
+
+my_smtp:
+ driver = smtp
+ port = PORT_D
+ socks_proxy = 127.0.0.1 port=1080 OPT
+ tls_certificate = DIR/aux-fixed/cert2
+ tls_privatekey = DIR/aux-fixed/cert2
+ tls_verify_certificates = DIR/aux-fixed/cert2
+ tls_try_verify_hosts = *
+
+
+
+# End
+
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
--- /dev/null
+# Exim test configuration 4200
+
+exim_path = EXIM_PATH
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/%slog
+gecos_name = CALLER_NAME
+tls_advertise_hosts =
+
+# ----- Main settings -----
+
+headers_charset = UTF8
+
+# ----- ACL -----
+
+# End
--- /dev/null
+# Exim test configuration 4201
+# SMTPUTF8 handling
+
+OPTION = *
+CONTROL =
+INSERT =
+SUB =
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+tls_advertise_hosts =
+
+# ----- Main settings -----
+
+domainlist local_domains = test.ex : cname
+
+acl_smtp_rcpt = check_recipient
+acl_not_smtp = non_smtp
+
+trusted_users = CALLER
+log_selector = +received_recipients +sender_on_delivery
+
+.ifdef SERVER
+queue_only
+queue_run_in_order
+.endif
+
+smtputf8_advertise_hosts = OPTION
+
+SUB
+
+
+# ----- ACL -----
+
+begin acl
+
+
+.ifdef SERVER
+
+check_recipient:
+ accept hosts = :
+ accept domains = +local_domains
+ local_parts = ^(xn--)?user.*\$
+ deny message = relay not permitted
+
+.else
+
+sub:
+.ifdef INSERT
+ require INSERT
+.endif
+.ifdef CONTROL
+ require CONTROL
+.endif
+ accept
+
+check_recipient:
+ accept domains = *
+ acl = sub
+
+non_smtp:
+ accept senders = :
+ control = queue_only
+ accept
+
+.endif
+
+# ----- Routers -----
+
+begin routers
+
+.ifdef SERVER
+
+fail_remote_domains:
+ driver = redirect
+ domains = ! +local_domains
+ data = :fail: unrouteable mail domain "$domain"
+
+bounces:
+ driver = redirect
+ condition = ${if eq {} {$sender_address}}
+ data = DIR/test-mail/$local_part
+ file_transport = local_delivery
+
+localuser:
+ driver = redirect
+ data = :blackhole:
+
+.else
+
+bounces:
+ driver = redirect
+ domains = *.local
+ data = DIR/test-mail/$local_part
+ file_transport = local_delivery
+
+rmt:
+ driver = manualroute
+ domains = +local_domains
+ route_data = <;[127.0.0.1]:PORT_D
+ transport = rmt_smtp
+ self = send
+
+.endif
+
+# ----- Transports -----
+
+begin transports
+
+local_delivery:
+ driver = appendfile
+ user = CALLER
+ delivery_date_add
+ envelope_to_add
+ file = DIR/test-mail/$local_part
+ headers_add = "X-body-linecount: $body_linecount\n\
+ X-message-linecount: $message_linecount\n\
+ X-received-count: $received_count"
+ return_path_add
+
+rmt_smtp:
+ driver = smtp
+
+# End
--- /dev/null
+4201
\ No newline at end of file
--- /dev/null
+4201
\ No newline at end of file
--- /dev/null
+4201
\ No newline at end of file
--- /dev/null
+4201
\ No newline at end of file
--- /dev/null
+4201
\ No newline at end of file
--- /dev/null
+4201
\ No newline at end of file
--- /dev/null
+4201
\ No newline at end of file
--- /dev/null
+4201
\ No newline at end of file
--- /dev/null
+# Exim test configuration 4201
+# SMTPUTF8 handling
+
+OPTION = *
+CONTROL =
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+
+# ----- Main settings -----
+
+domainlist local_domains = test.ex : cname
+
+acl_smtp_rcpt = check_recipient
+acl_not_smtp = non_smtp
+
+trusted_users = CALLER
+log_selector = +received_recipients +sender_on_delivery
+
+.ifdef SERVER
+queue_only
+queue_run_in_order
+.endif
+
+tls_certificate = ${if eq {SERVER}{server}{DIR/aux-fixed/cert1}fail}
+tls_privatekey = ${if eq {SERVER}{server}{DIR/aux-fixed/cert1}fail}
+tls_advertise_hosts = *
+
+smtputf8_advertise_hosts = OPTION
+
+
+# ----- ACL -----
+
+begin acl
+
+
+.ifdef SERVER
+
+check_recipient:
+ accept hosts = :
+ accept domains = +local_domains
+ local_parts = ^user.*\$
+ deny message = relay not permitted
+
+.else
+
+sub:
+.ifdef CONTROL
+ require CONTROL
+.endif
+ accept
+
+check_recipient:
+ accept domains = *
+ acl = sub
+
+non_smtp:
+ accept senders = :
+ control = queue_only
+ accept
+
+.endif
+
+# ----- Routers -----
+
+begin routers
+
+.ifdef SERVER
+
+fail_remote_domains:
+ driver = redirect
+ domains = ! +local_domains
+ data = :fail: unrouteable mail domain "$domain"
+
+bounces:
+ driver = redirect
+ condition = ${if eq {} {$sender_address}}
+ data = DIR/test-mail/$local_part
+ file_transport = local_delivery
+
+localuser:
+ driver = redirect
+ data = :blackhole:
+
+.else
+
+bounces:
+ driver = redirect
+ domains = *.local
+ data = DIR/test-mail/$local_part
+ file_transport = local_delivery
+
+rmt:
+ driver = manualroute
+ domains = +local_domains
+ route_data = <;[127.0.0.1]:PORT_D
+ transport = rmt_smtp
+ self = send
+
+.endif
+
+# ----- Transports -----
+
+begin transports
+
+local_delivery:
+ driver = appendfile
+ user = CALLER
+ delivery_date_add
+ envelope_to_add
+ file = DIR/test-mail/$local_part
+ headers_add = "X-body-linecount: $body_linecount\n\
+ X-message-linecount: $message_linecount\n\
+ X-received-count: $received_count"
+ return_path_add
+
+rmt_smtp:
+ driver = smtp
+ hosts_require_tls = *
+ tls_try_verify_hosts = :
+
+# End
--- /dev/null
+4211
\ No newline at end of file
--- /dev/null
+4211
\ No newline at end of file
--- /dev/null
+4211
\ No newline at end of file
--- /dev/null
+4211
\ No newline at end of file
--- /dev/null
+# Exim test configuration 4201
+# SMTPUTF8 handling
+
+OPTION = *
+CONTROL =
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+
+# ----- Main settings -----
+
+domainlist local_domains = test.ex : cname
+
+acl_smtp_rcpt = check_recipient
+acl_not_smtp = non_smtp
+
+trusted_users = CALLER
+log_selector = +received_recipients +sender_on_delivery
+
+.ifdef SERVER
+queue_only
+queue_run_in_order
+.endif
+
+tls_certificate = ${if eq {SERVER}{server}{DIR/aux-fixed/cert1}fail}
+tls_privatekey = ${if eq {SERVER}{server}{DIR/aux-fixed/cert1}fail}
+tls_advertise_hosts = *
+
+smtputf8_advertise_hosts = OPTION
+
+
+# ----- ACL -----
+
+begin acl
+
+
+.ifdef SERVER
+
+check_recipient:
+ accept hosts = :
+ accept domains = +local_domains
+ local_parts = ^user.*\$
+ deny message = relay not permitted
+
+.else
+
+sub:
+.ifdef CONTROL
+ require CONTROL
+.endif
+ accept
+
+check_recipient:
+ accept domains = *
+ acl = sub
+
+non_smtp:
+ accept senders = :
+ control = queue_only
+ accept
+
+.endif
+
+# ----- Routers -----
+
+begin routers
+
+.ifdef SERVER
+
+fail_remote_domains:
+ driver = redirect
+ domains = ! +local_domains
+ data = :fail: unrouteable mail domain "$domain"
+
+bounces:
+ driver = redirect
+ condition = ${if eq {} {$sender_address}}
+ data = DIR/test-mail/$local_part
+ file_transport = local_delivery
+
+localuser:
+ driver = redirect
+ data = :blackhole:
+
+.else
+
+bounces:
+ driver = redirect
+ domains = *.local
+ data = DIR/test-mail/$local_part
+ file_transport = local_delivery
+
+rmt:
+ driver = manualroute
+ domains = +local_domains
+ route_data = <;[127.0.0.1]:PORT_D
+ transport = rmt_smtp
+ self = send
+
+.endif
+
+# ----- Transports -----
+
+begin transports
+
+local_delivery:
+ driver = appendfile
+ user = CALLER
+ delivery_date_add
+ envelope_to_add
+ file = DIR/test-mail/$local_part
+ headers_add = "X-body-linecount: $body_linecount\n\
+ X-message-linecount: $message_linecount\n\
+ X-received-count: $received_count"
+ return_path_add
+
+rmt_smtp:
+ driver = smtp
+ hosts_require_tls = *
+ tls_try_verify_hosts = :
+
+# End
--- /dev/null
+4221
\ No newline at end of file
--- /dev/null
+4221
\ No newline at end of file
--- /dev/null
+4221
\ No newline at end of file
--- /dev/null
+4221
\ No newline at end of file
--- /dev/null
+# Exim test configuration 4500
+
+SERVER=
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+primary_hostname = myhost.test.ex
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/SERVER%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+tls_advertise_hosts =
+
+# ----- Main settings -----
+
+acl_smtp_rcpt = accept
+acl_smtp_dkim = accept logwrite = signer: $dkim_cur_signer bits: $dkim_key_length
+
+queue_only
+queue_run_in_order
+
+# End
--- /dev/null
+4500
\ No newline at end of file
--- /dev/null
+4500
\ No newline at end of file
--- /dev/null
+# Exim test configuration 0211
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+tls_advertise_hosts =
+
+# ----- Main settings -----
+
+domainlist local_domains = test.ex
+
+acl_smtp_rcpt = check_recipient
+
+log_selector = +sender_on_delivery
+qualify_domain = test.ex
+
+
+# ----- ACLs -----
+
+begin acl
+
+check_recipient:
+ accept hosts = :
+ accept domains = +local_domains
+ deny message = relay not permitted
+
+
+# ----- Routers -----
+
+begin routers
+
+others:
+ driver = manualroute
+ domains = ! +local_domains
+ route_list = * localhost4.test.ex byname
+ self = send
+ transport = smtp
+ no_more
+
+all:
+ driver = accept
+ retry_use_local_part
+ transport = local_delivery
+
+
+# ----- Transports -----
+
+begin transports
+
+smtp:
+ driver = smtp
+ port = PORT_S
+
+local_delivery:
+ driver = appendfile
+ file = DIR/test-mail/$local_part
+ return_path_add
+ user = CALLER
+
+
+# ----- Retry -----
+
+
+begin retry
+
+* * F,5d,8h
+
+
+# End
--- /dev/null
+tls_advertise_hosts =
+
+begin routers
+ dnslookup:
+ driver = dnslookup
+ dnssec_request_domains = *
+ transport = smtp
+
+begin transports
+ smtp:
+ driver = smtp
--- /dev/null
+tls_advertise_hosts =
+
+begin routers
+ dnslookup:
+ driver = dnslookup
+ dnssec_require_domains = *
+ transport = smtp
+
+begin transports
+ smtp:
+ driver = smtp
--- /dev/null
+tls_advertise_hosts =
+
+begin routers
+ dnslookup:
+ driver = dnslookup
+ dnssec_request_domains = *
+ transport = smtp
+
+begin transports
+ smtp:
+ driver = smtp
--- /dev/null
+tls_advertise_hosts =
+dns_trust_aa = *
+
+begin routers
+ dnslookup:
+ driver = dnslookup
+ dnssec_require_domains = *
+ transport = smtp
+
+begin transports
+ smtp:
+ driver = smtp
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
+
+log_selector = +received_recipients
# ----- Main settings -----
begin routers
+dns:
+ driver = dnslookup
+ domains = localhost.test.ex : localhost4.test.ex : thishost.test.ex
+ self = send
+ transport = smtp
+
all:
driver = manualroute
domains = ! +local_domains
- route_list = * 127.0.0.1
+ route_list = special.com HOSTIPV4 ; * 127.0.0.1
self = send
- transport = smtp
+ transport = ${if eq {special_tpt}{$local_part} {smtp2}{smtp}}
headers_remove = X-hdr-rtr
headers_add = X-hdr-rtr-new: $h_X-hdr-rtr:+++
no_more
port = PORT_S
headers_add = ${if def:h_X-hdr-rtr {X-hdr-tpt-new: new} {}}
+smtp2:
+ driver = smtp
+ interface = HOSTIPV4
+ port = PORT_S
+
# End
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
+++ /dev/null
-# Exim test configuration 5440
-# TLS client: verify certificate from server - name-fails
-
-SERVER=
-
-exim_path = EXIM_PATH
-host_lookup_order = bydns
-primary_hostname = myhost.test.ex
-spool_directory = DIR/spool
-log_file_path = DIR/spool/log/SERVER%slog
-gecos_pattern = ""
-gecos_name = CALLER_NAME
-
-FX = DIR/aux-fixed
-S1 = FX/exim-ca/example.com/server1.example.com
-
-CA1 = S1/ca_chain.pem
-CERT1 = S1/server1.example.com.pem
-KEY1 = S1/server1.example.com.unlocked.key
-CA2 = FX/cert2
-CERT2 = FX/cert2
-KEY2 = FX/cert2
-
-# ----- Main settings -----
-
-acl_smtp_rcpt = accept
-
-log_selector = +tls_peerdn+tls_certificate_verified
-
-queue_only
-queue_run_in_order
-
-tls_advertise_hosts = *
-
-# Set certificate only if server
-
-tls_certificate = ${if eq {SERVER}{server}{CERT1}fail}
-tls_privatekey = ${if eq {SERVER}{server}{KEY1}fail}
-
-tls_verify_hosts = *
-tls_verify_certificates = ${if eq {SERVER}{server}{CERT2}fail}
-
-
-# ----- Routers -----
-
-begin routers
-
-server_dump:
- driver = redirect
- condition = ${if eq {SERVER}{server}{yes}{no}}
- data = :blackhole:
-
-client_x:
- driver = accept
- local_parts = userx
- retry_use_local_part
- transport = send_to_server_failcert
- errors_to = ""
-
-client_y:
- driver = accept
- local_parts = usery
- retry_use_local_part
- transport = send_to_server_retry
-
-client_z:
- driver = accept
- local_parts = userz
- retry_use_local_part
- transport = send_to_server_crypt
-
-client_q:
- driver = accept
- local_parts = userq
- retry_use_local_part
- transport = send_to_server_req_fail
-
-client_r:
- driver = accept
- local_parts = userr
- retry_use_local_part
- transport = send_to_server_req_failname
-
-client_s:
- driver = accept
- local_parts = users
- retry_use_local_part
- transport = send_to_server_req_passname
-
-client_t:
- driver = accept
- local_parts = usert
- retry_use_local_part
- transport = send_to_server_req_failcarryon
-
-# ----- Transports -----
-
-begin transports
-
-# this will fail to verify the cert at HOSTIPV4 so fail the crypt requirement
-send_to_server_failcert:
- driver = smtp
- allow_localhost
- hosts = HOSTIPV4
- hosts_require_tls = HOSTIPV4
- port = PORT_D
- tls_certificate = CERT2
- tls_privatekey = CERT2
-
- tls_verify_certificates = CA2
-
-# this will fail to verify the cert at HOSTIPV4 so fail the crypt, then retry on 127.1; ok
-send_to_server_retry:
- driver = smtp
- allow_localhost
- hosts = HOSTIPV4 : 127.0.0.1
- hosts_require_tls = HOSTIPV4
- port = PORT_D
- tls_certificate = CERT2
- tls_privatekey = CERT2
-
- tls_verify_certificates = \
- ${if eq{$host_address}{127.0.0.1}{CA1}{CA2}}
-
-# this will fail to verify the cert but continue unverified though crypted
-send_to_server_crypt:
- driver = smtp
- allow_localhost
- hosts = HOSTIPV4
- hosts_require_tls = HOSTIPV4
- port = PORT_D
- tls_certificate = CERT2
- tls_privatekey = CERT2
-
- tls_verify_certificates = CA2
- tls_try_verify_hosts = *
-
-# this will fail to verify the cert at HOSTNAME and fallback to unencrypted
-# Fail due to lack of correct CA
-send_to_server_req_fail:
- driver = smtp
- allow_localhost
- hosts = HOSTNAME
- port = PORT_D
- tls_certificate = CERT2
- tls_privatekey = CERT2
-
- tls_verify_certificates = CA2
- tls_verify_hosts = *
-
-# this will fail to verify the cert name and fallback to unencrypted
-# fail because the cert is "server1.example.com" and the test system is something else
-send_to_server_req_failname:
- driver = smtp
- allow_localhost
- hosts = HOSTNAME
- port = PORT_D
- tls_certificate = CERT2
- tls_privatekey = CERT2
-
- tls_verify_certificates = CA1
- tls_verify_cert_hostnames = *
- tls_verify_hosts = *
-
-# this will pass the cert verify including name check
-# our stunt DNS has an A record for server1.example.com -> HOSTIPV4
-send_to_server_req_passname:
- driver = smtp
- allow_localhost
- hosts = server1.example.com
- port = PORT_D
- tls_certificate = CERT2
- tls_privatekey = CERT2
-
- tls_verify_certificates = CA1
- tls_verify_cert_hostnames = *
- tls_verify_hosts = *
-
-# this will fail to verify the cert name but carry on (try-verify mode)
-# fail because the cert is "server1.example.com" and the test system is something else
-send_to_server_req_failcarryon:
- driver = smtp
- allow_localhost
- hosts = HOSTNAME
- port = PORT_D
- tls_certificate = CERT2
- tls_privatekey = CERT2
-
- tls_verify_certificates = CA1
- tls_verify_cert_hostnames = *
- tls_try_verify_hosts = *
-
-# End
+++ /dev/null
-# Exim test configuration 5450
-# TLS client: verify certificate from server - name-fails
-
-SERVER=
-
-exim_path = EXIM_PATH
-host_lookup_order = bydns
-primary_hostname = myhost.test.ex
-spool_directory = DIR/spool
-log_file_path = DIR/spool/log/SERVER%slog
-gecos_pattern = ""
-gecos_name = CALLER_NAME
-
-FX = DIR/aux-fixed
-S1 = FX/exim-ca/example.com/server1.example.com
-
-CA1 = S1/ca_chain.pem
-CERT1 = S1/server1.example.com.pem
-KEY1 = S1/server1.example.com.unlocked.key
-CA2 = FX/cert2
-CERT2 = FX/cert2
-KEY2 = FX/cert2
-
-# ----- Main settings -----
-
-acl_smtp_rcpt = accept
-
-log_selector = +tls_peerdn+tls_certificate_verified
-
-queue_only
-queue_run_in_order
-
-tls_advertise_hosts = *
-
-# Set certificate only if server
-
-tls_certificate = ${if eq {SERVER}{server}{CERT1}fail}
-tls_privatekey = ${if eq {SERVER}{server}{KEY1}fail}
-
-tls_verify_hosts = *
-tls_verify_certificates = ${if eq {SERVER}{server}{CERT2}fail}
-
-
-# ----- Routers -----
-
-begin routers
-
-server_dump:
- driver = redirect
- condition = ${if eq {SERVER}{server}{yes}{no}}
- data = :blackhole:
-
-client_x:
- driver = accept
- local_parts = userx
- retry_use_local_part
- transport = send_to_server_failcert
- errors_to = ""
-
-client_y:
- driver = accept
- local_parts = usery
- retry_use_local_part
- transport = send_to_server_retry
-
-client_z:
- driver = accept
- local_parts = userz
- retry_use_local_part
- transport = send_to_server_crypt
-
-client_q:
- driver = accept
- local_parts = userq
- retry_use_local_part
- transport = send_to_server_req_fail
-
-client_r:
- driver = accept
- local_parts = userr
- retry_use_local_part
- transport = send_to_server_req_failname
-
-client_s:
- driver = accept
- local_parts = users
- retry_use_local_part
- transport = send_to_server_req_passname
-
-client_t:
- driver = accept
- local_parts = usert
- retry_use_local_part
- transport = send_to_server_req_failcarryon
-
-
-# ----- Transports -----
-
-begin transports
-
-# this will fail to verify the cert at HOSTIPV4 so fail the crypt requirement
-send_to_server_failcert:
- driver = smtp
- allow_localhost
- hosts = HOSTIPV4
- hosts_require_tls = HOSTIPV4
- port = PORT_D
- tls_certificate = CERT2
- tls_privatekey = CERT2
-
- tls_verify_certificates = CA2
-
-# this will fail to verify the cert at HOSTIPV4 so fail the crypt, then retry on 127.1; ok
-send_to_server_retry:
- driver = smtp
- allow_localhost
- hosts = HOSTIPV4 : 127.0.0.1
- hosts_require_tls = HOSTIPV4
- port = PORT_D
- tls_certificate = CERT2
- tls_privatekey = CERT2
-
- tls_verify_certificates = \
- ${if eq{$host_address}{127.0.0.1}{CA1}{CA2}}
-
-# this will fail to verify the cert but continue unverified though crypted
-send_to_server_crypt:
- driver = smtp
- allow_localhost
- hosts = HOSTIPV4
- hosts_require_tls = HOSTIPV4
- port = PORT_D
- tls_certificate = CERT2
- tls_privatekey = CERT2
-
- tls_verify_certificates = CA2
- tls_try_verify_hosts = *
-
-# this will fail to verify the cert at HOSTNAME and fallback to unencrypted
-# Fail due to lack of correct CA
-send_to_server_req_fail:
- driver = smtp
- allow_localhost
- hosts = HOSTNAME
- port = PORT_D
- tls_certificate = CERT2
- tls_privatekey = CERT2
-
- tls_verify_certificates = CA2
- tls_verify_hosts = *
-
-# this will fail to verify the cert name and fallback to unencrypted
-# fail because the cert is "server1.example.com" and the test system is something else
-send_to_server_req_failname:
- driver = smtp
- allow_localhost
- hosts = HOSTNAME
- port = PORT_D
- tls_certificate = CERT2
- tls_privatekey = CERT2
-
- tls_verify_certificates = CA1
- tls_verify_cert_hostnames = *
- tls_verify_hosts = *
-
-# this will pass the cert verify including name check
-# our stunt DNS has an A record for server1.example.com -> HOSTIPV4
-send_to_server_req_passname:
- driver = smtp
- allow_localhost
- hosts = server1.example.com
- port = PORT_D
- tls_certificate = CERT2
- tls_privatekey = CERT2
-
- tls_verify_certificates = CA1
- tls_verify_cert_hostnames = *
- tls_verify_hosts = *
-
-send_to_server_req_failcarryon:
- driver = smtp
- allow_localhost
- hosts = HOSTNAME
- port = PORT_D
- tls_certificate = CERT2
- tls_privatekey = CERT2
-
- tls_verify_certificates = CA1
- tls_verify_cert_hostnames = *
- tls_try_verify_hosts = *
-
-# End
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
prdr_enable = true
+acl_smtp_mail = mail_acl
acl_smtp_rcpt = accept
acl_smtp_data_prdr = prdr_acl
acl_smtp_data = data_acl
begin acl
+mail_acl:
+ accept logwrite = prdr_requested: <$prdr_requested>
+
prdr_acl:
defer local_parts = usery
deny local_parts = userz
driver = accept
transport = t1
-# ----- Retry -----
-
-begin retry
-
-* * F,5d,5m
-
# End
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
+++ /dev/null
-# Exim test configuration 5608
-# OCSP stapling, client, events
-
-SERVER =
-
-exim_path = EXIM_PATH
-host_lookup_order = bydns
-primary_hostname = server1.example.com
-spool_directory = DIR/spool
-log_file_path = DIR/spool/log/SERVER%slog
-gecos_pattern = ""
-gecos_name = CALLER_NAME
-
-
-# ----- Main settings -----
-
-domainlist local_domains = test.ex : *.test.ex
-
-acl_smtp_rcpt = check_recipient
-acl_smtp_data = check_data
-
-log_selector = +tls_peerdn
-remote_max_parallel = 1
-
-tls_advertise_hosts = *
-
-# Set certificate only if server
-
-tls_certificate = ${if eq {SERVER}{server}\
-{DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.chain.pem}\
-fail\
-}
-
-#{DIR/aux-fixed/exim-ca/example.com/CA/CA.pem}\
-
-tls_privatekey = ${if eq {SERVER}{server}\
-{DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.unlocked.key}\
-fail}
-
-tls_ocsp_file = OCSP
-
-
-# ------ ACL ------
-
-begin acl
-
-check_recipient:
- accept domains = +local_domains
- deny message = relay not permitted
-
-check_data:
- warn condition = ${if def:h_X-TLS-out:}
- logwrite = client claims: $h_X-TLS-out:
- accept
-
-logger:
- accept condition = ${if !eq {msg} {${listextract{1}{$event_name}}}}
- warn logwrite = client ocsp status: $tls_out_ocsp \
- (${listextract {${eval:$tls_out_ocsp+1}} \
- {notreq:notresp:vfynotdone:failed:verified}})
- accept
-
-# ----- Routers -----
-
-begin routers
-
-client:
- driver = accept
- condition = ${if eq {SERVER}{server}{no}{yes}}
- retry_use_local_part
- transport = send_to_server${if eq{$local_part}{nostaple}{1} \
- {${if eq{$local_part}{norequire} {2} \
- {${if eq{$local_part}{smtps} {4}{3}}} \
- }}}
-
-server:
- driver = redirect
- data = :blackhole:
- #retry_use_local_part
- #transport = local_delivery
-
-
-# ----- Transports -----
-
-begin transports
-
-local_delivery:
- driver = appendfile
- file = DIR/test-mail/$local_part
- headers_add = TLS: cipher=$tls_cipher peerdn=$tls_peerdn
- user = CALLER
-
-# nostaple: deliberately do not request cert-status
-send_to_server1:
- driver = smtp
- allow_localhost
- hosts = HOSTIPV4
- port = PORT_D
- tls_verify_certificates = DIR/aux-fixed/exim-ca/example.com/CA/CA.pem
- tls_verify_cert_hostnames =
- hosts_require_tls = *
- hosts_request_ocsp = :
- headers_add = X-TLS-out: ocsp status $tls_out_ocsp
- event_action = ${acl {logger}}
-
-# norequire: request stapling but do not verify
-send_to_server2:
- driver = smtp
- allow_localhost
- hosts = HOSTIPV4
- port = PORT_D
- tls_verify_certificates = DIR/aux-fixed/exim-ca/example.com/CA/CA.pem
- tls_verify_cert_hostnames =
- hosts_require_tls = *
-# note no ocsp mention here
- headers_add = X-TLS-out: ocsp status $tls_out_ocsp
- event_action = ${acl {logger}}
-
-# (any other name): request and verify
-send_to_server3:
- driver = smtp
- allow_localhost
- hosts = 127.0.0.1
- port = PORT_D
- helo_data = helo.data.changed
- tls_verify_certificates = DIR/aux-fixed/exim-ca/example.com/CA/CA.pem
- tls_verify_cert_hostnames =
- hosts_require_tls = *
- hosts_require_ocsp = *
- headers_add = X-TLS-out: ocsp status $tls_out_ocsp
- event_action = ${acl {logger}}
-
-# (any other name): request and verify, ssl-on-connect
-send_to_server4:
- driver = smtp
- allow_localhost
- hosts = 127.0.0.1
- port = PORT_D
- helo_data = helo.data.changed
- tls_verify_certificates = DIR/aux-fixed/exim-ca/example.com/CA/CA.pem
- tls_verify_cert_hostnames =
- protocol = smtps
- hosts_require_tls = *
- hosts_require_ocsp = *
- headers_add = X-TLS-out: ocsp status $tls_out_ocsp
- event_action = ${acl {logger}}
-
-
-# ----- Retry -----
-
-
-begin retry
-
-* * F,5d,1s
-
-
-# End
+++ /dev/null
-# Exim test configuration 5658
-# OCSP stapling, client, events
-
-SERVER =
-
-exim_path = EXIM_PATH
-host_lookup_order = bydns
-primary_hostname = server1.example.com
-spool_directory = DIR/spool
-log_file_path = DIR/spool/log/SERVER%slog
-gecos_pattern = ""
-gecos_name = CALLER_NAME
-
-
-# ----- Main settings -----
-
-domainlist local_domains = test.ex : *.test.ex
-
-acl_smtp_rcpt = check_recipient
-acl_smtp_data = check_data
-
-log_selector = +tls_peerdn
-remote_max_parallel = 1
-
-tls_advertise_hosts = *
-
-# Set certificate only if server
-tls_certificate = ${if eq {SERVER}{server}\
-{DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.chain.pem}\
-fail\
-}
-tls_privatekey = ${if eq {SERVER}{server}\
-{DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.unlocked.key}\
-fail}
-
-# from cmdline define
-tls_ocsp_file = OCSP
-
-
-# ------ ACL ------
-
-begin acl
-
-check_recipient:
- accept domains = +local_domains
- deny message = relay not permitted
-
-check_data:
- warn condition = ${if def:h_X-TLS-out:}
- logwrite = client claims: $h_X-TLS-out:
- accept
-
-logger:
- accept condition = ${if !eq {msg} {${listextract{1}{$event_name}}}}
- warn logwrite = client ocsp status: $tls_out_ocsp \
- (${listextract {${eval:$tls_out_ocsp+1}} \
- {notreq:notresp:vfynotdone:failed:verified}})
- accept
-
-
-# ----- Routers -----
-
-begin routers
-
-client:
- driver = accept
- condition = ${if eq {SERVER}{server}{no}{yes}}
- retry_use_local_part
- transport = send_to_server${if eq{$local_part}{nostaple}{1} \
- {${if eq{$local_part}{norequire} {2} \
- {${if eq{$local_part}{smtps} {4}{3}}} \
- }}}
-
-server:
- driver = redirect
- data = :blackhole:
- #retry_use_local_part
- #transport = local_delivery
-
-
-# ----- Transports -----
-
-begin transports
-
-local_delivery:
- driver = appendfile
- file = DIR/test-mail/$local_part
- headers_add = TLS: cipher=$tls_cipher peerdn=$tls_peerdn
- user = CALLER
-
-send_to_server1:
- driver = smtp
- allow_localhost
- hosts = HOSTIPV4
- port = PORT_D
- tls_verify_certificates = DIR/aux-fixed/exim-ca/example.com/CA/CA.pem
- tls_verify_cert_hostnames =
- hosts_require_tls = *
- hosts_request_ocsp = :
- headers_add = X-TLS-out: OCSP status $tls_out_ocsp \
- (${listextract {${eval:$tls_out_ocsp+1}} \
- {notreq:notresp:vfynotdone:failed:verified}})
- event_action = ${acl {logger}}
-
-send_to_server2:
- driver = smtp
- allow_localhost
- hosts = HOSTIPV4
- port = PORT_D
- tls_verify_certificates = DIR/aux-fixed/exim-ca/example.com/CA/CA.pem
- tls_verify_cert_hostnames =
- hosts_require_tls = *
-# note no ocsp mention here
- headers_add = X-TLS-out: OCSP status $tls_out_ocsp \
- (${listextract {${eval:$tls_out_ocsp+1}} \
- {notreq:notresp:vfynotdone:failed:verified}})
- event_action = ${acl {logger}}
-
-send_to_server3:
- driver = smtp
- allow_localhost
- hosts = 127.0.0.1
- port = PORT_D
- helo_data = helo.data.changed
- #tls_verify_certificates = DIR/aux-fixed/exim-ca/example.com/server1.example.com/ca_chain.pem
- tls_verify_certificates = DIR/aux-fixed/exim-ca/example.com/CA/CA.pem
- tls_try_verify_hosts =
- tls_verify_cert_hostnames =
- hosts_require_tls = *
- hosts_require_ocsp = *
- headers_add = X-TLS-out: OCSP status $tls_out_ocsp \
- (${listextract {${eval:$tls_out_ocsp+1}} \
- {notreq:notresp:vfynotdone:failed:verified}})
- event_action = ${acl {logger}}
-
-send_to_server4:
- driver = smtp
- allow_localhost
- hosts = 127.0.0.1
- port = PORT_D
- helo_data = helo.data.changed
- #tls_verify_certificates = DIR/aux-fixed/exim-ca/example.com/server1.example.com/ca_chain.pem
- tls_verify_certificates = DIR/aux-fixed/exim-ca/example.com/CA/CA.pem
- tls_verify_cert_hostnames =
- protocol = smtps
- hosts_require_tls = *
- hosts_require_ocsp = *
- headers_add = X-TLS-out: OCSP status $tls_out_ocsp \
- (${listextract {${eval:$tls_out_ocsp+1}} \
- {notreq:notresp:vfynotdone:failed:verified}})
- event_action = ${acl {logger}}
-
-
-# ----- Retry -----
-
-
-begin retry
-
-* * F,5d,1s
-
-
-# End
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
domain <$domain> \
reason <$event_data>
+ev_msg_log:
+ accept logwrite = . \
+ $acl_arg1 \
+ ip <$host_address> \
+ port <$host_port> \
+ fqdn <$host> \
+ local_part <$local_part> \
+ domain <$domain> \
+ $acl_arg2 \
+ router <$router_name> \
+ transport <$transport_name>
+
ev_msg:
accept condition = ${if eq {fail} {${listextract{2}{$event_name}}}}
acl = ev_msg_fail
logwrite = $this_expansion_will_fail
accept condition = ${if eq {$event_name}{msg:delivery}}
- logwrite = . \
- delivery \
- ip <$host_address> \
- port <$host_port> \
- fqdn <$host> \
- local_part <$local_part> \
- domain <$domain> \
- confirmation <$event_data> \
- router <$router_name> \
- transport <$transport_name>
+ acl = ev_msg_log delivery "confirmation <$event_data>"
accept condition = ${if eq {$event_name}{msg:host:defer}}
- logwrite = . \
- deferral \
- ip <$host_address> \
- port <$host_port> \
- fqdn <$host> \
- local_part <$local_part> \
- domain <$domain> \
- errno <$event_defer_errno> \
- errstr <$event_data> \
- router <$router_name> \
- transport <$transport_name>
+ acl = ev_msg_log "host deferral" \
+ "errno <$event_defer_errno> errstr <$event_data>"
+
+ accept condition = ${if eq {$event_name}{msg:rcpt:defer}}
+ set acl_m_ev_lkup = ${eval:$event_defer_errno & 0xff}
+ set acl_m_ev_lkup = ${if = {$acl_m_ev_lkup}{65} {A} \
+ { ${if = {$acl_m_ev_lkup}{77} {MX} \
+ {$acl_m_ev_lkup}}}}
+ set acl_m_ev_code = 4${eval:$event_defer_errno >>8}
+ acl = ev_msg_log "rcpt deferral" \
+ "err <$event_defer_errno>:<$acl_m_ev_lkup:$acl_m_ev_code> \
+ errstr <$event_data>"
logger:
warn logwrite = event $event_name
route_list = * 127.0.0.1 byname
self = send
transport = smtp
+ errors_to = ""
no_more
--- /dev/null
+# Exim test configuration 5710 (dup of 5720)
+# $tls_out_peercert - GnuTLS
+
+SERVER=
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+primary_hostname = myhost.test.ex
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/SERVER%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+timezone = UTC
+
+# ----- Main settings -----
+
+acl_smtp_rcpt = accept
+
+log_selector = +tls_peerdn
+
+queue_only
+queue_run_in_order
+
+tls_advertise_hosts = *
+
+tls_certificate = DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.pem
+tls_privatekey = DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.unlocked.key
+
+tls_verify_hosts = *
+tls_verify_certificates = DIR/aux-fixed/exim-ca/example.com/server2.example.com/ca_chain.pem
+
+event_action = ${acl {server_cert_log}}
+
+#
+
+begin acl
+
+server_cert_log:
+ accept condition = ${if eq {tls:cert}{$event_name}}
+ logwrite = [$sender_host_address] \
+ depth=$event_data \
+ ${certextract{subject}{$tls_in_peercert}}
+ accept
+
+ev_tls:
+ accept logwrite = $event_name depth=$event_data \
+ <${certextract {subject} {$tls_out_peercert}}>
+# message = noooo
+
+ev_msg:
+ warn logwrite = $acl_arg1 $local_part
+ warn logwrite = ${if !def:tls_out_ourcert \
+ {NO CLIENT CERT presented} \
+ {Our cert SN: ${certextract{subject}{$tls_out_ourcert}}}}
+ accept condition = ${if !def:tls_out_peercert}
+ logwrite = No Peer cert
+ accept logwrite = Peer cert:
+ logwrite = ver <${certextract {version} {$tls_out_peercert}}>
+ logwrite = SN <${certextract {subject} {$tls_out_peercert}}>
+ logwrite = SN; <${certextract {subject,>;} {$tls_out_peercert}}>
+ logwrite = SNCN<${certextract {subject,CN} {$tls_out_peercert}}>
+ logwrite = IN <${certextract {issuer} {$tls_out_peercert}}>
+ logwrite = NB <${certextract {notbefore} {$tls_out_peercert}}>
+ logwrite = NA <${certextract {notafter} {$tls_out_peercert}}>
+ logwrite = SA <${certextract {sig_algorithm} {$tls_out_peercert}}>
+ logwrite = SG <${certextract {signature} {$tls_out_peercert}}>
+ logwrite = ${certextract {subj_altname} {$tls_out_peercert}{SAN <$value>}{(no SAN)}}
+# logwrite = ${certextract {ocsp_uri} {$tls_out_peercert} {OCU <$value>}{(no OCU)}}
+ logwrite = ${certextract {crl_uri} {$tls_out_peercert} {CRU <$value>}{(no CRU)}}
+
+logger:
+ accept condition = ${if eq {msg} {${listextract{1}{$event_name}}}}
+ acl = ev_msg $event_name $acl_arg2
+ accept condition = ${if eq {tls} {${listextract{1}{$event_name}}}}
+ message = ${acl {ev_tls}}
+ accept
+
+# ----- Routers -----
+
+begin routers
+
+client:
+ driver = accept
+ condition = ${if eq {SERVER}{server}{no}{yes}}
+ retry_use_local_part
+ transport = send_to_server
+
+
+# ----- Transports -----
+
+begin transports
+
+send_to_server:
+ driver = smtp
+ allow_localhost
+ hosts = 127.0.0.1
+ port = PORT_D
+
+ tls_certificate = DIR/aux-fixed/exim-ca/example.com/server2.example.com/server2.example.com.pem
+ tls_privatekey = DIR/aux-fixed/exim-ca/example.com/server2.example.com/server2.example.com.unlocked.key
+
+ tls_verify_certificates = DIR/aux-fixed/exim-ca/\
+ ${if eq {$local_part}{good}\
+{example.com/server1.example.com/ca_chain.pem}\
+{example.net/server1.example.net/ca_chain.pem}}
+ tls_try_verify_hosts =
+ tls_verify_cert_hostnames =
+
+ event_action = ${acl {logger} {$event_name} {$domain} }
+
+# ----- Retry -----
+
+
+begin retry
+
+* * F,5d,10s
+
+
+# End
--- /dev/null
+# Exim test configuration 5720 (dup of 5710)
+# $tls_out_peercert - OpenSSL
+
+SERVER=
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+primary_hostname = myhost.test.ex
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/SERVER%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+timezone = UTC
+
+# ----- Main settings -----
+
+acl_smtp_rcpt = accept
+
+log_selector = +tls_peerdn
+
+queue_only
+queue_run_in_order
+
+tls_advertise_hosts = *
+
+tls_certificate = DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.pem
+tls_privatekey = DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.unlocked.key
+
+tls_verify_hosts = *
+tls_verify_certificates = DIR/aux-fixed/exim-ca/example.com/server2.example.com/ca_chain.pem
+
+event_action = ${acl {server_cert_log}}
+
+#
+
+begin acl
+
+server_cert_log:
+ accept condition = ${if eq {tls:cert}{$event_name}}
+ logwrite = [$sender_host_address] \
+ depth=$event_data \
+ ${certextract{subject}{$tls_in_peercert}}
+ accept
+
+ev_tls:
+ accept logwrite = $event_name depth=$event_data \
+ <${certextract {subject} {$tls_out_peercert}}>
+# message = nooooo
+
+ev_msg:
+ warn logwrite = $acl_arg1 $local_part
+ warn logwrite = ${if !def:tls_out_ourcert \
+ {NO CLIENT CERT presented} \
+ {Our cert SN: ${certextract{subject}{$tls_out_ourcert}}}}
+ accept condition = ${if !def:tls_out_peercert}
+ logwrite = No Peer cert
+ accept logwrite = Peer cert:
+ logwrite = ver <${certextract {version} {$tls_out_peercert}}>
+ logwrite = SN <${certextract {subject} {$tls_out_peercert}}>
+ logwrite = SN; <${certextract {subject,>;} {$tls_out_peercert}}>
+ logwrite = SNO <${certextract {subject,O} {$tls_out_peercert}}>
+ logwrite = IN <${certextract {issuer} {$tls_out_peercert}}>
+ logwrite = NB <${certextract {notbefore} {$tls_out_peercert}}>
+ logwrite = NA <${certextract {notafter} {$tls_out_peercert}}>
+ logwrite = SA <${certextract {sig_algorithm} {$tls_out_peercert}}>
+ logwrite = SG <${certextract {signature} {$tls_out_peercert}}>
+ logwrite = ${certextract {subj_altname,>;}{$tls_out_peercert}{SAN <$value>}{(no SAN)}}
+ logwrite = ${certextract {ocsp_uri} {$tls_out_peercert} {OCU <$value>}{(no OCU)}}
+ logwrite = ${certextract {crl_uri} {$tls_out_peercert} {CRU <$value>}{(no CRU)}}
+
+logger:
+ accept condition = ${if eq {msg} {${listextract{1}{$event_name}}}}
+ acl = ev_msg $event_name $acl_arg2
+ accept condition = ${if eq {tls} {${listextract{1}{$event_name}}}}
+ message = ${acl {ev_tls}}
+ accept
+
+# ----- Routers -----
+
+begin routers
+
+client:
+ driver = accept
+ condition = ${if eq {SERVER}{server}{no}{yes}}
+ retry_use_local_part
+ transport = send_to_server
+
+
+# ----- Transports -----
+
+begin transports
+
+send_to_server:
+ driver = smtp
+ allow_localhost
+ hosts = 127.0.0.1
+ port = PORT_D
+
+ tls_certificate = DIR/aux-fixed/exim-ca/example.com/server2.example.com/server2.example.com.pem
+ tls_privatekey = DIR/aux-fixed/exim-ca/example.com/server2.example.com/server2.example.com.unlocked.key
+
+ tls_verify_certificates = DIR/aux-fixed/exim-ca/\
+ ${if eq {$local_part}{good}\
+{example.com/server1.example.com/ca_chain.pem}\
+{example.net/server1.example.net/ca_chain.pem}}
+ tls_verify_cert_hostnames =
+ tls_try_verify_hosts =
+
+ event_action = ${acl {logger} {$event_name} {$domain} }
+
+# ----- Retry -----
+
+
+begin retry
+
+* * F,5d,10s
+
+
+# End
--- /dev/null
+# Exim test configuration 5730
+# OCSP stapling, client, events
+
+SERVER =
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+primary_hostname = server1.example.com
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/SERVER%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+
+
+# ----- Main settings -----
+
+domainlist local_domains = test.ex : *.test.ex
+
+acl_smtp_rcpt = check_recipient
+acl_smtp_data = check_data
+
+log_selector = +tls_peerdn
+remote_max_parallel = 1
+
+tls_advertise_hosts = *
+
+# Set certificate only if server
+tls_certificate = ${if eq {SERVER}{server}\
+{DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.chain.pem}\
+fail\
+}
+tls_privatekey = ${if eq {SERVER}{server}\
+{DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.unlocked.key}\
+fail}
+
+# from cmdline define
+tls_ocsp_file = OCSP
+
+
+# ------ ACL ------
+
+begin acl
+
+check_recipient:
+ accept domains = +local_domains
+ deny message = relay not permitted
+
+check_data:
+ warn condition = ${if def:h_X-TLS-out:}
+ logwrite = client claims: $h_X-TLS-out:
+ accept
+
+logger:
+ accept condition = ${if !eq {msg} {${listextract{1}{$event_name}}}}
+ warn logwrite = client ocsp status: $tls_out_ocsp \
+ (${listextract {${eval:$tls_out_ocsp+1}} \
+ {notreq:notresp:vfynotdone:failed:verified}})
+ accept
+
+
+# ----- Routers -----
+
+begin routers
+
+client:
+ driver = accept
+ condition = ${if eq {SERVER}{server}{no}{yes}}
+ retry_use_local_part
+ transport = send_to_server${if eq{$local_part}{nostaple}{1} \
+ {${if eq{$local_part}{norequire} {2} \
+ {${if eq{$local_part}{smtps} {4}{3}}} \
+ }}}
+
+server:
+ driver = redirect
+ data = :blackhole:
+ #retry_use_local_part
+ #transport = local_delivery
+
+
+# ----- Transports -----
+
+begin transports
+
+local_delivery:
+ driver = appendfile
+ file = DIR/test-mail/$local_part
+ headers_add = TLS: cipher=$tls_cipher peerdn=$tls_peerdn
+ user = CALLER
+
+send_to_server1:
+ driver = smtp
+ allow_localhost
+ hosts = HOSTIPV4
+ port = PORT_D
+ tls_verify_certificates = DIR/aux-fixed/exim-ca/example.com/CA/CA.pem
+ tls_verify_cert_hostnames =
+ hosts_require_tls = *
+ hosts_request_ocsp = :
+ headers_add = X-TLS-out: OCSP status $tls_out_ocsp \
+ (${listextract {${eval:$tls_out_ocsp+1}} \
+ {notreq:notresp:vfynotdone:failed:verified}})
+ event_action = ${acl {logger}}
+
+send_to_server2:
+ driver = smtp
+ allow_localhost
+ hosts = HOSTIPV4
+ port = PORT_D
+ tls_verify_certificates = DIR/aux-fixed/exim-ca/example.com/CA/CA.pem
+ tls_verify_cert_hostnames =
+ hosts_require_tls = *
+# note no ocsp mention here
+ headers_add = X-TLS-out: OCSP status $tls_out_ocsp \
+ (${listextract {${eval:$tls_out_ocsp+1}} \
+ {notreq:notresp:vfynotdone:failed:verified}})
+ event_action = ${acl {logger}}
+
+send_to_server3:
+ driver = smtp
+ allow_localhost
+ hosts = 127.0.0.1
+ port = PORT_D
+ helo_data = helo.data.changed
+ #tls_verify_certificates = DIR/aux-fixed/exim-ca/example.com/server1.example.com/ca_chain.pem
+ tls_verify_certificates = DIR/aux-fixed/exim-ca/example.com/CA/CA.pem
+ tls_try_verify_hosts =
+ tls_verify_cert_hostnames =
+ hosts_require_tls = *
+ hosts_require_ocsp = *
+ headers_add = X-TLS-out: OCSP status $tls_out_ocsp \
+ (${listextract {${eval:$tls_out_ocsp+1}} \
+ {notreq:notresp:vfynotdone:failed:verified}})
+ event_action = ${acl {logger}}
+
+send_to_server4:
+ driver = smtp
+ allow_localhost
+ hosts = 127.0.0.1
+ port = PORT_D
+ helo_data = helo.data.changed
+ #tls_verify_certificates = DIR/aux-fixed/exim-ca/example.com/server1.example.com/ca_chain.pem
+ tls_verify_certificates = DIR/aux-fixed/exim-ca/example.com/CA/CA.pem
+ tls_verify_cert_hostnames =
+ protocol = smtps
+ hosts_require_tls = *
+ hosts_require_ocsp = *
+ headers_add = X-TLS-out: OCSP status $tls_out_ocsp \
+ (${listextract {${eval:$tls_out_ocsp+1}} \
+ {notreq:notresp:vfynotdone:failed:verified}})
+ event_action = ${acl {logger}}
+
+
+# ----- Retry -----
+
+
+begin retry
+
+* * F,5d,1s
+
+
+# End
--- /dev/null
+# Exim test configuration 5740
+# OCSP stapling, client, events
+
+SERVER =
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+primary_hostname = server1.example.com
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/SERVER%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+
+
+# ----- Main settings -----
+
+domainlist local_domains = test.ex : *.test.ex
+
+acl_smtp_rcpt = check_recipient
+acl_smtp_data = check_data
+
+log_selector = +tls_peerdn
+remote_max_parallel = 1
+
+tls_advertise_hosts = *
+
+# Set certificate only if server
+
+tls_certificate = ${if eq {SERVER}{server}\
+{DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.chain.pem}\
+fail\
+}
+
+#{DIR/aux-fixed/exim-ca/example.com/CA/CA.pem}\
+
+tls_privatekey = ${if eq {SERVER}{server}\
+{DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.unlocked.key}\
+fail}
+
+tls_ocsp_file = OCSP
+
+
+# ------ ACL ------
+
+begin acl
+
+check_recipient:
+ accept domains = +local_domains
+ deny message = relay not permitted
+
+check_data:
+ warn condition = ${if def:h_X-TLS-out:}
+ logwrite = client claims: $h_X-TLS-out:
+ accept
+
+logger:
+ accept condition = ${if !eq {msg} {${listextract{1}{$event_name}}}}
+ warn logwrite = client ocsp status: $tls_out_ocsp \
+ (${listextract {${eval:$tls_out_ocsp+1}} \
+ {notreq:notresp:vfynotdone:failed:verified}})
+ accept
+
+# ----- Routers -----
+
+begin routers
+
+client:
+ driver = accept
+ condition = ${if eq {SERVER}{server}{no}{yes}}
+ retry_use_local_part
+ transport = send_to_server${if eq{$local_part}{nostaple}{1} \
+ {${if eq{$local_part}{norequire} {2} \
+ {${if eq{$local_part}{smtps} {4}{3}}} \
+ }}}
+
+server:
+ driver = redirect
+ data = :blackhole:
+ #retry_use_local_part
+ #transport = local_delivery
+
+
+# ----- Transports -----
+
+begin transports
+
+local_delivery:
+ driver = appendfile
+ file = DIR/test-mail/$local_part
+ headers_add = TLS: cipher=$tls_cipher peerdn=$tls_peerdn
+ user = CALLER
+
+# nostaple: deliberately do not request cert-status
+send_to_server1:
+ driver = smtp
+ allow_localhost
+ hosts = HOSTIPV4
+ port = PORT_D
+ tls_verify_certificates = DIR/aux-fixed/exim-ca/example.com/CA/CA.pem
+ tls_verify_cert_hostnames =
+ hosts_require_tls = *
+ hosts_request_ocsp = :
+ headers_add = X-TLS-out: ocsp status $tls_out_ocsp
+ event_action = ${acl {logger}}
+
+# norequire: request stapling but do not verify
+send_to_server2:
+ driver = smtp
+ allow_localhost
+ hosts = HOSTIPV4
+ port = PORT_D
+ tls_verify_certificates = DIR/aux-fixed/exim-ca/example.com/CA/CA.pem
+ tls_verify_cert_hostnames =
+ hosts_require_tls = *
+# note no ocsp mention here
+ headers_add = X-TLS-out: ocsp status $tls_out_ocsp
+ event_action = ${acl {logger}}
+
+# (any other name): request and verify
+send_to_server3:
+ driver = smtp
+ allow_localhost
+ hosts = 127.0.0.1
+ port = PORT_D
+ helo_data = helo.data.changed
+ tls_verify_certificates = DIR/aux-fixed/exim-ca/example.com/CA/CA.pem
+ tls_verify_cert_hostnames =
+ hosts_require_tls = *
+ hosts_require_ocsp = *
+ headers_add = X-TLS-out: ocsp status $tls_out_ocsp
+ event_action = ${acl {logger}}
+
+# (any other name): request and verify, ssl-on-connect
+send_to_server4:
+ driver = smtp
+ allow_localhost
+ hosts = 127.0.0.1
+ port = PORT_D
+ helo_data = helo.data.changed
+ tls_verify_certificates = DIR/aux-fixed/exim-ca/example.com/CA/CA.pem
+ tls_verify_cert_hostnames =
+ protocol = smtps
+ hosts_require_tls = *
+ hosts_require_ocsp = *
+ headers_add = X-TLS-out: ocsp status $tls_out_ocsp
+ event_action = ${acl {logger}}
+
+
+# ----- Retry -----
+
+
+begin retry
+
+* * F,5d,1s
+
+
+# End
+++ /dev/null
-# Exim test configuration 5750 (dup of 5760)
-# $tls_out_peercert - GnuTLS
-
-SERVER=
-
-exim_path = EXIM_PATH
-host_lookup_order = bydns
-primary_hostname = myhost.test.ex
-spool_directory = DIR/spool
-log_file_path = DIR/spool/log/SERVER%slog
-gecos_pattern = ""
-gecos_name = CALLER_NAME
-timezone = UTC
-
-# ----- Main settings -----
-
-acl_smtp_rcpt = accept
-
-log_selector = +tls_peerdn
-
-queue_only
-queue_run_in_order
-
-tls_advertise_hosts = *
-
-tls_certificate = DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.pem
-tls_privatekey = DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.unlocked.key
-
-tls_verify_hosts = *
-tls_verify_certificates = DIR/aux-fixed/exim-ca/example.com/server2.example.com/ca_chain.pem
-
-event_action = ${acl {server_cert_log}}
-
-#
-
-begin acl
-
-server_cert_log:
- accept condition = ${if eq {tls:cert}{$event_name}}
- logwrite = [$sender_host_address] \
- depth=$event_data \
- ${certextract{subject}{$tls_in_peercert}}
- accept
-
-ev_tls:
- accept logwrite = $event_name depth=$event_data \
- <${certextract {subject} {$tls_out_peercert}}>
-# message = noooo
-
-ev_msg:
- warn logwrite = $acl_arg1 $local_part
- warn logwrite = ${if !def:tls_out_ourcert \
- {NO CLIENT CERT presented} \
- {Our cert SN: ${certextract{subject}{$tls_out_ourcert}}}}
- accept condition = ${if !def:tls_out_peercert}
- logwrite = No Peer cert
- accept logwrite = Peer cert:
- logwrite = ver <${certextract {version} {$tls_out_peercert}}>
- logwrite = SN <${certextract {subject} {$tls_out_peercert}}>
- logwrite = IN <${certextract {issuer} {$tls_out_peercert}}>
- logwrite = NB <${certextract {notbefore} {$tls_out_peercert}}>
- logwrite = NA <${certextract {notafter} {$tls_out_peercert}}>
- logwrite = SA <${certextract {sig_algorithm} {$tls_out_peercert}}>
- logwrite = SG <${certextract {signature} {$tls_out_peercert}}>
- logwrite = ${certextract {subj_altname} {$tls_out_peercert}{SAN <$value>}{(no SAN)}}
-# logwrite = ${certextract {ocsp_uri} {$tls_out_peercert} {OCU <$value>}{(no OCU)}}
- logwrite = ${certextract {crl_uri} {$tls_out_peercert} {CRU <$value>}{(no CRU)}}
-
-logger:
- accept condition = ${if eq {msg} {${listextract{1}{$event_name}}}}
- acl = ev_msg $event_name $acl_arg2
- accept condition = ${if eq {tls} {${listextract{1}{$event_name}}}}
- message = ${acl {ev_tls}}
- accept
-
-# ----- Routers -----
-
-begin routers
-
-client:
- driver = accept
- condition = ${if eq {SERVER}{server}{no}{yes}}
- retry_use_local_part
- transport = send_to_server
-
-
-# ----- Transports -----
-
-begin transports
-
-send_to_server:
- driver = smtp
- allow_localhost
- hosts = 127.0.0.1
- port = PORT_D
-
- tls_certificate = DIR/aux-fixed/exim-ca/example.com/server2.example.com/server2.example.com.pem
- tls_privatekey = DIR/aux-fixed/exim-ca/example.com/server2.example.com/server2.example.com.unlocked.key
-
- tls_verify_certificates = DIR/aux-fixed/exim-ca/\
- ${if eq {$local_part}{good}\
-{example.com/server1.example.com/ca_chain.pem}\
-{example.net/server1.example.net/ca_chain.pem}}
- tls_try_verify_hosts =
- tls_verify_cert_hostnames =
-
- event_action = ${acl {logger} {$event_name} {$domain} }
-
-# ----- Retry -----
-
-
-begin retry
-
-* * F,5d,10s
-
-
-# End
+++ /dev/null
-# Exim test configuration 5760 (dup of 5750)
-# $tls_out_peercert - OpenSSL
-
-SERVER=
-
-exim_path = EXIM_PATH
-host_lookup_order = bydns
-primary_hostname = myhost.test.ex
-spool_directory = DIR/spool
-log_file_path = DIR/spool/log/SERVER%slog
-gecos_pattern = ""
-gecos_name = CALLER_NAME
-timezone = UTC
-
-# ----- Main settings -----
-
-acl_smtp_rcpt = accept
-
-log_selector = +tls_peerdn
-
-queue_only
-queue_run_in_order
-
-tls_advertise_hosts = *
-
-tls_certificate = DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.pem
-tls_privatekey = DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.unlocked.key
-
-tls_verify_hosts = *
-tls_verify_certificates = DIR/aux-fixed/exim-ca/example.com/server2.example.com/ca_chain.pem
-
-event_action = ${acl {server_cert_log}}
-
-#
-
-begin acl
-
-server_cert_log:
- accept condition = ${if eq {tls:cert}{$event_name}}
- logwrite = [$sender_host_address] \
- depth=$event_data \
- ${certextract{subject}{$tls_in_peercert}}
- accept
-
-ev_tls:
- accept logwrite = $event_name depth=$event_data \
- <${certextract {subject} {$tls_out_peercert}}>
-# message = nooooo
-
-ev_msg:
- warn logwrite = $acl_arg1 $local_part
- warn logwrite = ${if !def:tls_out_ourcert \
- {NO CLIENT CERT presented} \
- {Our cert SN: ${certextract{subject}{$tls_out_ourcert}}}}
- accept condition = ${if !def:tls_out_peercert}
- logwrite = No Peer cert
- accept logwrite = Peer cert:
- logwrite = ver <${certextract {version} {$tls_out_peercert}}>
- logwrite = SN <${certextract {subject} {$tls_out_peercert}}>
- logwrite = IN <${certextract {issuer} {$tls_out_peercert}}>
- logwrite = NB <${certextract {notbefore} {$tls_out_peercert}}>
- logwrite = NA <${certextract {notafter} {$tls_out_peercert}}>
- logwrite = SA <${certextract {sig_algorithm} {$tls_out_peercert}}>
- logwrite = SG <${certextract {signature} {$tls_out_peercert}}>
- logwrite = ${certextract {subj_altname,>;}{$tls_out_peercert}{SAN <$value>}{(no SAN)}}
- logwrite = ${certextract {ocsp_uri} {$tls_out_peercert} {OCU <$value>}{(no OCU)}}
- logwrite = ${certextract {crl_uri} {$tls_out_peercert} {CRU <$value>}{(no CRU)}}
-
-logger:
- accept condition = ${if eq {msg} {${listextract{1}{$event_name}}}}
- acl = ev_msg $event_name $acl_arg2
- accept condition = ${if eq {tls} {${listextract{1}{$event_name}}}}
- message = ${acl {ev_tls}}
- accept
-
-# ----- Routers -----
-
-begin routers
-
-client:
- driver = accept
- condition = ${if eq {SERVER}{server}{no}{yes}}
- retry_use_local_part
- transport = send_to_server
-
-
-# ----- Transports -----
-
-begin transports
-
-send_to_server:
- driver = smtp
- allow_localhost
- hosts = 127.0.0.1
- port = PORT_D
-
- tls_certificate = DIR/aux-fixed/exim-ca/example.com/server2.example.com/server2.example.com.pem
- tls_privatekey = DIR/aux-fixed/exim-ca/example.com/server2.example.com/server2.example.com.unlocked.key
-
- tls_verify_certificates = DIR/aux-fixed/exim-ca/\
- ${if eq {$local_part}{good}\
-{example.com/server1.example.com/ca_chain.pem}\
-{example.net/server1.example.net/ca_chain.pem}}
- tls_verify_cert_hostnames =
- tls_try_verify_hosts =
-
- event_action = ${acl {logger} {$event_name} {$domain} }
-
-# ----- Retry -----
-
-
-begin retry
-
-* * F,5d,10s
-
-
-# End
host_lookup_order = bydns
primary_hostname = myhost.test.ex
spool_directory = DIR/spool
+tls_advertise_hosts =
# ----- Main settings -----
# ----- Main settings -----
+.ifndef OPT
acl_smtp_rcpt = accept
+.else
+acl_smtp_rcpt = accept verify = recipient/callout
+.endif
log_selector = +received_recipients +tls_peerdn +tls_certificate_verified
-queue_only
queue_run_in_order
tls_advertise_hosts = *
CDIR2 = DIR/aux-fixed/exim-ca/example.com/server1.example.com
tls_certificate = ${if eq {SERVER}{server} \
- {${if eq {DETAILS}{ta} \
+ {${if or {{eq {DETAILS}{ta}} {eq {DETAILS}{ca}}} \
{CDIR2/fullchain.pem}\
{CDIR1/cert1}}}\
fail}
tls_privatekey = ${if eq {SERVER}{server} \
- {${if eq {DETAILS}{ta} \
+ {${if or {{eq {DETAILS}{ta}} {eq {DETAILS}{ca}}} \
{CDIR2/server1.example.com.unlocked.key}\
{CDIR1/cert1}}}\
fail}
-
# ----- Routers -----
begin routers
allow_localhost
port = PORT_D
-# hosts_try_dane = *
- hosts_require_dane = *
- hosts_request_ocsp = ${if or { {= {4}{$tls_out_tlsa_usage}} \
- {= {0}{$tls_out_tlsa_usage}} } \
- {*}{}}
+ hosts_try_dane = *
+ hosts_require_dane = !thishost.test.ex
+ tls_verify_cert_hostnames = ${if eq {OPT}{no_certname} {}{*}}
+ tls_try_verify_hosts = thishost.test.ex
+ tls_verify_certificates = CDIR2/ca_chain.pem
+
# ----- Retry -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
trusted_users = CALLER
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/SERVER%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/SERVER%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+tls_advertise_hosts =
# ----- Main settings -----
; This is a testing zone file for use when testing DNS handling in Exim. This
-; is a fake zone of no real use - hence no SOA record. The zone name is
+; is a fake zone of no real use. The zone name is
; test.ex. This file is passed through the substitution mechanism before being
; used by the fakens auxiliary program. This inserts the actual IP addresses
; of the local host into the zone.
; NOTE (3): the top-level networks for testing addresses are parameterized by
; the use of V4NET and V6NET. These networks should be such that no real
; host ever uses them.
+;
+; Several prefixes may be used, see the source in src/fakens.c for a complete list
+; and description.
test.ex. NS exim.test.ex.
+test.ex. SOA exim.test.ex. hostmaster.exim.test.ex 1430683638 1200 120 604800 3600
test.ex. TXT "A TXT record for test.ex."
s/lash TXT "A TXT record for s/lash.test.ex."
UpperCase A 127.0.0.1
-; A host with UTF-8 characters in its name
+; A host with punycoded UTF-8 characters used for its lookup ( mx.π.test.ex )
-mx.π A V4NET.255.255.255
+mx.xn--1xa A V4NET.255.255.255
; A non-standard name for localhost
thishost A 127.0.0.1
+localhost4 A 127.0.0.1
+
+; A localhost with short TTL
+
+TTL=2 shorthost A 127.0.0.1
+
; Something that gives both the IP and the loopback
recurse.test.ex A V4NET.99.0.2
+; a CNAME pointing to a name with both ipv4 and ipv6 A-records
+; and one with only ipv4
+
+cname46 CNAME localhost
+cname4 CNAME thishost
+
; -------- Testing RBL records -------
; V4NET.11.12.13 is deliberately not reverse-registered
13.12.11.V4NET.rbl A 127.0.0.2
TXT "This is a test blacklisting message"
-14.12.11.V4NET.rbl A 127.0.0.2
+TTL=2 14.12.11.V4NET.rbl A 127.0.0.2
TXT "This is a test blacklisting message"
15.12.11.V4NET.rbl A 127.0.0.2
TXT "This is a very long blacklisting message, continuing for ages and ages and certainly being longer than 128 characters which was a previous limit on the length that Exim was prepared to handle."
mxt1c MX 1 dontqualify.
-; MX with UTF-8 characters in its name
+; MX with punycoded UTF-8 characters used for its lookup ( π.test.ex )
+
+xn--1xa MX 0 mx.π.test.ex.
-π MX 0 mx.π.test.ex.
+; MX with actual UTF-8 characters in its name, for allow_utf8_domains mode test
+
+π MX 0 mx.xn--1xa.test.ex.
; -------- Testing SRV records --------
csa1 A V4NET.9.8.7
csa2 A V4NET.9.8.8
+; ------- Testing DNSSEC ----------
+
+mx-unsec-a-unsec MX 5 a-unsec
+mx-unsec-a-sec MX 5 a-sec
+DNSSEC mx-sec-a-unsec MX 5 a-unsec
+DNSSEC mx-sec-a-sec MX 5 a-sec
+DNSSEC mx-sec-a-aa MX 5 a-aa
+AA mx-aa-a-sec MX 5 a-sec
+
+a-unsec A V4NET.0.0.100
+DNSSEC a-sec A V4NET.0.0.100
+DNSSEC l-sec A 127.0.0.1
+
+AA a-aa A V4NET.0.0.100
+
; ------- Testing DANE ------------
; full suite dns chain, sha512
-DNSSEC mxdane512ee MX 1 dane512ee.
-DNSSEC dane512ee A HOSTIPV4
+;
+; openssl x509 -in aux-fixed/cert1 -noout -pubkey \
+; | openssl pkey -pubin -outform DER \
+; | openssl dgst -sha512 \
+; | awk '{print $2}'
+;
+DNSSEC mxdane512ee MX 1 dane512ee
+DNSSEC dane512ee A HOSTIPV4
DNSSEC _1225._tcp.dane512ee TLSA 3 1 2 3d5eb81b1dfc3f93c1fa8819e3fb3fdb41bb590441d5f3811db17772f4bc6de29bdd7c4f4b723750dda871b99379192b3f979f03db1252c4f08b03ef7176528d
; A-only, sha256
-DNSSEC dane256ee A HOSTIPV4
+;
+; openssl x509 -in aux-fixed/cert1 -noout -pubkey \
+; | openssl pkey -pubin -outform DER \
+; | openssl dgst -sha256 \
+; | awk '{print $2}'
+;
+DNSSEC dane256ee A HOSTIPV4
DNSSEC _1225._tcp.dane256ee TLSA 3 1 1 2bb55f418bb03411a5007cecbfcd3ec1c94404312c0d53a44bb2166b32654db3
; full MX, sha256, TA-mode
-DNSSEC mxdane256ta MX 1 dane256ta.
-DNSSEC dane256ta A HOSTIPV4
-DNSSEC _1225._tcp.dane256ta TLSA 2 0 1 b2c6f27f2d16390b4f71cacc69742bf610d750534fab240516c0f2deb4042ad4
+;
+; openssl x509 -in aux-fixed/exim-ca/example.com/CA/CA.pem -fingerprint -sha256 -noout \
+; | awk -F= '{print $2}' | tr -d : | tr '[A-F]' '[a-f]'
+;
+DNSSEC mxdane256ta MX 1 dane256ta
+DNSSEC dane256ta A HOSTIPV4
+DNSSEC _1225._tcp.dane256ta TLSA 2 0 1 882be5ac06deafdc021a69daa457226153bfde6da7914813b0144b0fd31bf7ae
+
+
+; A multiple-return MX where all TLSA lookups defer
+DNSSEC mxdanelazy MX 1 danelazy
+DNSSEC MX 2 danelazy2
+
+DNSSEC danelazy A HOSTIPV4
+DNSSEC danelazy2 A 127.0.0.1
+
+DNSSEC _1225._tcp.danelazy CNAME test.again.dns.
+DNSSEC _1225._tcp.danelazy2 CNAME test.again.dns.
+
+; hosts with no TLSA
+DNSSEC dane.no.1 A HOSTIPV4
+DNSSEC dane.no.2 A 127.0.0.1
+
+; ------- Testing delays ------------
+
+DELAY=500 delay500 A HOSTIPV4
+DELAY=1500 delay1500 A HOSTIPV4
+
+; ------- DKIM ---------
+
+; public key, base64 - matches private key in aux-fixed/dkim/dkim/private
+; openssl genrsa -out aux-fixed/dkim/dkim.private 1024
+; openssl rsa -in aux-fixed/dkim/dkim.private -out /dev/stdout -pubout -outform PEM
+;
+; Another, 512-bit (with a Notes field)
+;
+sel._domainkey TXT "v=DKIM1; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXRFf+VhT+lCgFhhSkinZKcFNeRzjYdW8vT29Rbb3NadvTFwAd+cVLPFwZL8H5tUD/7JbUPqNTCPxmpgIL+V5T4tEZMorHatvvUM2qfcpQ45IfsZ+YdhbIiAslHCpy4xNxIR3zylgqRUF4+Dtsaqy3a5LhwMiKCLrnzhXk1F1hxwIDAQAB"
+
+ses._domainkey TXT "v=DKIM1; n=halfkilo; p=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL6eAQxd9didJ0/+05iDwJOqT6ly826Vi8aGPecsBiYK5/tAT97fxXk+dPWMZp9kQxtknEzYjYjAydzf+HQ2yJMCAwEAAQ=="
+
; End
-1999-03-02 09:44:33 10HmbC-0005vi-00 <= x@y U=CALLER P=local-smtp S=sss
+1999-03-02 09:44:33 10HmbD-0005vi-00 $h_from: 'x@y'
+1999-03-02 09:44:33 10HmbD-0005vi-00 <= x@y U=CALLER P=local-smtp S=sss
+1999-03-02 09:44:33 10HmaX-0005vi-00 $h_from: '@'
1999-03-02 09:44:33 10HmaX-0005vi-00 U=CALLER F=<x@y> rejected after DATA: domain missing or malformed: failing address in "From:" header is: @
-1999-03-02 09:44:33 10HmaY-0005vi-00 U=CALLER F=<> rejected after DATA: domain missing or malformed: failing address in "From:" header is: @
-1999-03-02 09:44:33 10HmaZ-0005vi-00 U=CALLER F=<> rejected after DATA: there is no valid sender in any header line
-1999-03-02 09:44:33 10HmbD-0005vi-00 <= <> U=CALLER P=local-smtp S=sss
-1999-03-02 09:44:33 10HmbA-0005vi-00 U=CALLER F=<x@y> rejected after DATA: body contains trigger
-1999-03-02 09:44:33 10HmbE-0005vi-00 <= x@y U=CALLER P=local-smtp S=sss
-1999-03-02 09:44:33 10HmbE-0005vi-00 => userx <userx@test.ex> R=r2 T=local_delivery
-1999-03-02 09:44:33 10HmbE-0005vi-00 Completed
+1999-03-02 09:44:33 10HmaY-0005vi-00 $h_from: '<forged@sender.com'
+1999-03-02 09:44:33 10HmaY-0005vi-00 U=CALLER F=<x@y> rejected after DATA: '>' missing at end of address: failing address in "To:" header is: <dummy@gmail.com
+1999-03-02 09:44:33 10HmaZ-0005vi-00 $h_from: '<x@y>, @'
+1999-03-02 09:44:33 10HmaZ-0005vi-00 U=CALLER F=<> rejected after DATA: domain missing or malformed: failing address in "From:" header is: @
+1999-03-02 09:44:33 10HmbA-0005vi-00 $h_from: '<x@y>'
+1999-03-02 09:44:33 10HmbA-0005vi-00 U=CALLER F=<> rejected after DATA: there is no valid sender in any header line
+1999-03-02 09:44:33 10HmbE-0005vi-00 $h_from: '<postmaster@test.ex>'
+1999-03-02 09:44:33 10HmbE-0005vi-00 <= <> U=CALLER P=local-smtp S=sss
+1999-03-02 09:44:33 10HmbB-0005vi-00 U=CALLER F=<x@y> rejected after DATA: body contains trigger
+1999-03-02 09:44:33 10HmbF-0005vi-00 $h_from: 'x@y'
1999-03-02 09:44:33 10HmbF-0005vi-00 <= x@y U=CALLER P=local-smtp S=sss
1999-03-02 09:44:33 10HmbF-0005vi-00 => userx <userx@test.ex> R=r2 T=local_delivery
1999-03-02 09:44:33 10HmbF-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbG-0005vi-00 <= <> U=CALLER P=local-smtp S=sss
+1999-03-02 09:44:33 10HmbG-0005vi-00 $h_from: 'x@y'
+1999-03-02 09:44:33 10HmbG-0005vi-00 <= x@y U=CALLER P=local-smtp S=sss
1999-03-02 09:44:33 10HmbG-0005vi-00 => userx <userx@test.ex> R=r2 T=local_delivery
1999-03-02 09:44:33 10HmbG-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbB-0005vi-00 U=CALLER F=<> rejected after DATA: there is no valid sender in any header line
+1999-03-02 09:44:33 10HmbH-0005vi-00 $h_from: 'userx@test.ex'
+1999-03-02 09:44:33 10HmbH-0005vi-00 <= <> U=CALLER P=local-smtp S=sss
+1999-03-02 09:44:33 10HmbH-0005vi-00 => userx <userx@test.ex> R=r2 T=local_delivery
+1999-03-02 09:44:33 10HmbH-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbC-0005vi-00 $h_from: ''
+1999-03-02 09:44:33 10HmbC-0005vi-00 U=CALLER F=<> rejected after DATA: there is no valid sender in any header line
1999-03-02 09:44:33 10HmaX-0005vi-00 <= jc@rome H=forum.rome [1.1.1.1] U=jc44bc P=latin S=sss for userx@test.ex
1999-03-02 09:44:33 10HmaX-0005vi-00 => userx <userx@test.ex> R=localuser T=local_delivery
1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= jc@rome R=10HmaZ-0005vi-00 U=jc44bc P=local S=sss for userx@test.x
+1999-03-02 09:44:33 10HmaY-0005vi-00 => userx <userx@test.x> R=localuser T=local_delivery
+1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
1999-03-02 09:44:33 10HmbB-0005vi-00 H=thisloop.test.ex [ip4.ip4.ip4.ip4] Connection refused
1999-03-02 09:44:33 10HmbB-0005vi-00 H=thisloop.test.ex [127.0.0.1] Connection refused
1999-03-02 09:44:33 10HmbB-0005vi-00 == without@complex R=all T=smtp defer (dd): Connection refused
+1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss for userx@nonexist
+1999-03-02 09:44:33 10HmbC-0005vi-00 no IP address found for host nonexist.test.ex
+1999-03-02 09:44:33 10HmbC-0005vi-00 == userx@nonexist R=all defer (-32): lookup of host "nonexist.test.ex" failed in all router
+1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss for userx@mxt2.test.ex
+1999-03-02 09:44:33 10HmbD-0005vi-00 == userx@mxt2.test.ex R=bydns defer (-32): all relevant MX records point to non-existent hosts
+1999-03-02 09:44:33 Test: temp-rej connect
1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmaX-0005vi-00 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after initial connection: 450 I'm busy
-1999-03-02 09:44:33 10HmaX-0005vi-00 == userx@domain1 R=others T=smtp defer (0) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after initial connection: 450 I'm busy
+1999-03-02 09:44:33 10HmaX-0005vi-00 H=localhost4.test.ex [127.0.0.1]: SMTP error from remote mail server after initial connection: 450 I'm busy
+1999-03-02 09:44:33 10HmaX-0005vi-00 == userx@domain1 R=others T=smtp defer (0) H=localhost4.test.ex [127.0.0.1]: SMTP error from remote mail server after initial connection: 450 I'm busy
+1999-03-02 09:44:33 Test: temp-rej helo
1999-03-02 09:44:33 Start queue run: pid=pppp -qf
-1999-03-02 09:44:33 10HmaX-0005vi-00 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after HELO the.local.host.name: 450 I'm busy
-1999-03-02 09:44:33 10HmaX-0005vi-00 == userx@domain1 R=others T=smtp defer (0) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after HELO the.local.host.name: 450 I'm busy
+1999-03-02 09:44:33 10HmaX-0005vi-00 H=localhost4.test.ex [127.0.0.1]: SMTP error from remote mail server after HELO the.local.host.name: 450 I'm busy
+1999-03-02 09:44:33 10HmaX-0005vi-00 == userx@domain1 R=others T=smtp defer (0) H=localhost4.test.ex [127.0.0.1]: SMTP error from remote mail server after HELO the.local.host.name: 450 I'm busy
1999-03-02 09:44:33 End queue run: pid=pppp -qf
+1999-03-02 09:44:33 Test: drop conn after banner
1999-03-02 09:44:33 Start queue run: pid=pppp -qf
-1999-03-02 09:44:33 10HmaX-0005vi-00 ** userx@domain1 F=<CALLER@test.ex> R=others T=smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after initial connection: 550 Go away
+1999-03-02 09:44:33 10HmaX-0005vi-00 H=localhost4.test.ex [127.0.0.1]: Remote host closed connection in response to EHLO the.local.host.name
+1999-03-02 09:44:33 10HmaX-0005vi-00 == userx@domain1 R=others T=smtp defer (-18) H=localhost4.test.ex [127.0.0.1]: Remote host closed connection in response to EHLO the.local.host.name
+1999-03-02 09:44:33 End queue run: pid=pppp -qf
+1999-03-02 09:44:33 Test: reject connect
+1999-03-02 09:44:33 Start queue run: pid=pppp -qf
+1999-03-02 09:44:33 10HmaX-0005vi-00 ** userx@domain1 F=<CALLER@test.ex> R=others T=smtp H=localhost4.test.ex [127.0.0.1]: SMTP error from remote mail server after initial connection: 550 Go away
1999-03-02 09:44:33 10HmaY-0005vi-00 <= <> R=10HmaX-0005vi-00 U=EXIMUSER P=local S=sss
1999-03-02 09:44:33 10HmaY-0005vi-00 => CALLER <CALLER@test.ex> F=<> R=all T=local_delivery
1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
1999-03-02 09:44:33 End queue run: pid=pppp -qf
+1999-03-02 09:44:33 Test: reject helo
1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmaZ-0005vi-00 ** userx@domain1 F=<CALLER@test.ex> R=others T=smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after HELO the.local.host.name: 550 Go away
-1999-03-02 09:44:33 10HmaZ-0005vi-00 ** usery@domain2 F=<CALLER@test.ex> R=others T=smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after HELO the.local.host.name: 550 Go away
+1999-03-02 09:44:33 10HmaZ-0005vi-00 ** userx@domain1 F=<CALLER@test.ex> R=others T=smtp H=localhost4.test.ex [127.0.0.1]: SMTP error from remote mail server after HELO the.local.host.name: 550 Go away
+1999-03-02 09:44:33 10HmaZ-0005vi-00 ** usery@domain2 F=<CALLER@test.ex> R=others T=smtp H=localhost4.test.ex [127.0.0.1]: SMTP error from remote mail server after HELO the.local.host.name: 550 Go away
1999-03-02 09:44:33 10HmbA-0005vi-00 <= <> R=10HmaZ-0005vi-00 U=EXIMUSER P=local S=sss
1999-03-02 09:44:33 10HmbA-0005vi-00 => CALLER <CALLER@test.ex> F=<> R=all T=local_delivery
1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
1999-03-02 09:44:33 10HmaX-0005vi-00 => x <x@test.ex> R=server T=local_delivery
1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
1999-03-02 09:44:33 End queue run: pid=pppp -qf
+1999-03-02 09:44:33 SMTP connection from root
+1999-03-02 09:44:33 10HmbB-0005vi-00 <= x@y.x H=[V4NET.9.8.7]:1112 U=root P=smtp S=sss
+1999-03-02 09:44:33 SMTP connection from root closed by QUIT
+1999-03-02 09:44:33 Start queue run: pid=pppp -qf
+1999-03-02 09:44:33 10HmbB-0005vi-00 => x@test.ex R=to_server T=remote H=127.0.0.1 [127.0.0.1] I=[127.0.0.1] C="250 OK id=10HmbC-0005vi-00"
+1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp -qf
******** SERVER ********
1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
-1999-03-02 09:44:33 SMTP connection from [ip4.ip4.ip4.ip4]:1112 I=[ip4.ip4.ip4.ip4]:1225 (TCP/IP connection count = 1)
-1999-03-02 09:44:33 10HmaY-0005vi-00 <= x@y.x H=[ip4.ip4.ip4.ip4]:1112 I=[ip4.ip4.ip4.ip4]:1225 P=smtp S=sss
-1999-03-02 09:44:33 SMTP connection from [ip4.ip4.ip4.ip4]:1112 I=[ip4.ip4.ip4.ip4]:1225 closed by QUIT
-1999-03-02 09:44:33 SMTP connection from [127.0.0.1]:1113 I=[127.0.0.1]:1225 (TCP/IP connection count = 1)
-1999-03-02 09:44:33 10HmaZ-0005vi-00 <= x@y.x H=[127.0.0.1]:1113 I=[127.0.0.1]:1225 P=smtp S=sss
-1999-03-02 09:44:33 SMTP connection from [127.0.0.1]:1113 I=[127.0.0.1]:1225 closed by QUIT
-1999-03-02 09:44:33 SMTP connection from [ip4.ip4.ip4.ip4]:1114 I=[ip4.ip4.ip4.ip4]:1225 (TCP/IP connection count = 1)
-1999-03-02 09:44:33 10HmbA-0005vi-00 <= x@y.x H=(rhubarb) [ip4.ip4.ip4.ip4]:1114 I=[ip4.ip4.ip4.ip4]:1225 P=smtp S=sss
-1999-03-02 09:44:33 SMTP connection from (rhubarb) [ip4.ip4.ip4.ip4]:1114 I=[ip4.ip4.ip4.ip4]:1225 closed by QUIT
+1999-03-02 09:44:33 SMTP connection from [ip4.ip4.ip4.ip4]:1113 I=[ip4.ip4.ip4.ip4]:1225 (TCP/IP connection count = 1)
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= x@y.x H=[ip4.ip4.ip4.ip4]:1113 I=[ip4.ip4.ip4.ip4]:1225 P=smtp S=sss
+1999-03-02 09:44:33 SMTP connection from [ip4.ip4.ip4.ip4]:1113 I=[ip4.ip4.ip4.ip4]:1225 closed by QUIT
+1999-03-02 09:44:33 SMTP connection from [127.0.0.1]:1114 I=[127.0.0.1]:1225 (TCP/IP connection count = 1)
+1999-03-02 09:44:33 10HmaZ-0005vi-00 <= x@y.x H=[127.0.0.1]:1114 I=[127.0.0.1]:1225 P=smtp S=sss
+1999-03-02 09:44:33 SMTP connection from [127.0.0.1]:1114 I=[127.0.0.1]:1225 closed by QUIT
+1999-03-02 09:44:33 SMTP connection from [ip4.ip4.ip4.ip4]:1115 I=[ip4.ip4.ip4.ip4]:1225 (TCP/IP connection count = 1)
+1999-03-02 09:44:33 10HmbA-0005vi-00 <= x@y.x H=(rhubarb) [ip4.ip4.ip4.ip4]:1115 I=[ip4.ip4.ip4.ip4]:1225 P=smtp S=sss
+1999-03-02 09:44:33 SMTP connection from (rhubarb) [ip4.ip4.ip4.ip4]:1115 I=[ip4.ip4.ip4.ip4]:1225 closed by QUIT
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 SMTP connection from [127.0.0.1]:1116 I=[127.0.0.1]:1225 (TCP/IP connection count = 1)
+1999-03-02 09:44:33 10HmbC-0005vi-00 <= x@y.x H=localhost (myhost.test.ex) [127.0.0.1]:1116 I=[127.0.0.1]:1225 P=esmtp S=sss
+1999-03-02 09:44:33 SMTP connection from localhost (myhost.test.ex) [127.0.0.1]:1116 I=[127.0.0.1]:1225 closed by QUIT
1999-03-02 09:44:33 10HmaX-0005vi-00 == b@test.ex R=all T=smtp defer (-53): connection limit reached for all hosts
1999-03-02 09:44:33 10HmaX-0005vi-00 => a@test.ex R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
1999-03-02 09:44:33 End queue run: pid=pppp
+1999-03-02 09:44:33 Start queue run: pid=pppp
+1999-03-02 09:44:33 10HmaX-0005vi-00 => b@test.ex R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
+1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmaX-0005vi-00 => userx <userx@test.ex> R=r1 T=t1
+1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
1999-03-02 09:44:33 10HmaY-0005vi-00 => userx <userx@test.ex> R=r1 T=t1
1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmaX-0005vi-00 == userx@test.ex R=r1 T=t1 defer (-24): transport filter process failed (127) while writing to TESTSUITE/test-mail/userx: unable to execute command
+1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmaZ-0005vi-00 => userx <userx@test.ex> R=r1 T=t1
+1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss for x@y
1999-03-02 09:44:33 10HmaX-0005vi-00 => blackhole (non-SMTP ACL discarded recipients)
1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
-1999-03-02 09:44:33 U=CALLER F=<discard@x.y> rejected RCPT <a@b>: discarded by MAIL ACL: discard message 2
-1999-03-02 09:44:33 U=CALLER F=<discard@x.y> rejected RCPT <discard@p.q>: discarded by MAIL ACL: discard message 2
+1999-03-02 09:44:33 U=CALLER F=<discard@x.y> RCPT <a@b>: discarded by MAIL ACL: discard message 2
+1999-03-02 09:44:33 U=CALLER F=<discard@x.y> RCPT <discard@p.q>: discarded by MAIL ACL: discard message 2
1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@test.ex U=CALLER P=local-smtp S=sss
1999-03-02 09:44:33 10HmaY-0005vi-00 => blackhole (MAIL ACL discarded recipients)
1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
-1999-03-02 09:44:33 U=CALLER F=<ok@x.y> rejected RCPT <discard@p.q>: discarded by RCPT ACL: discard message 1
-1999-03-02 09:44:33 U=CALLER F=<ok@x.y> rejected RCPT <nested_discard@p.q>: discarded by RCPT ACL
+1999-03-02 09:44:33 U=CALLER F=<ok@x.y> RCPT <discard@p.q>: discarded by RCPT ACL: discard message 1
+1999-03-02 09:44:33 U=CALLER F=<ok@x.y> RCPT <nested_discard@p.q>: discarded by RCPT ACL
1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@test.ex U=CALLER P=local-smtp S=sss for a@b
-1999-03-02 09:44:33 U=CALLER F=<ok@x.y> rejected RCPT <discard@p.q>: discarded by RCPT ACL: discard message 1
+1999-03-02 09:44:33 U=CALLER F=<ok@x.y> RCPT <discard@p.q>: discarded by RCPT ACL: discard message 1
1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@test.ex U=CALLER P=local-smtp S=sss
1999-03-02 09:44:33 10HmbA-0005vi-00 => blackhole (RCPT ACL discarded recipients)
1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
1999-03-02 09:44:33 Messages accepted:
1999-03-02 09:44:33 Recipients:
1999-03-02 09:44:33 Accepted:
-1999-03-02 09:44:33 ACL for QUIT returned ERROR: "deny" is not allowed in a QUIT or not-QUIT ACL
+1999-03-02 09:44:33 ACL for QUIT returned ERROR: QUIT or not-QUIT teplevel ACL may not fail ('deny' verb used incorrectly)
1999-03-02 09:44:33 Messages received: 1
1999-03-02 09:44:33 Messages accepted:
1999-03-02 09:44:33 Recipients:
******** SERVER ********
1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
-1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
1999-03-02 09:44:33 SMTP connection from localhost (myhost.test.ex) [127.0.0.1] lost while reading message data (header)
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmaX-0005vi-00@myhost.test.ex
1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
1999-03-02 09:44:33 Start queue run: pid=pppp
-1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> rejected RCPT <userx@domA.ex>: discarded by RCPT ACL
-1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> rejected RCPT <usery@domB.ex>: discarded by RCPT ACL
+1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> RCPT <userx@domA.ex>: discarded by RCPT ACL
+1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> RCPT <usery@domB.ex>: discarded by RCPT ACL
1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@test.ex H=localhost (primary.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmaX-0005vi-00@primary.test.ex
1999-03-02 09:44:33 10HmaY-0005vi-00 => blackhole (RCPT ACL discarded recipients)
1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
1999-03-02 09:44:33 End queue run: pid=pppp
1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
1999-03-02 09:44:33 Start queue run: pid=pppp
-1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> rejected RCPT <userx@domA.ex>: discarded by RCPT ACL
-1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> rejected RCPT <usery@domB.ex>: discarded by RCPT ACL
+1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> RCPT <userx@domA.ex>: discarded by RCPT ACL
+1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> RCPT <usery@domB.ex>: discarded by RCPT ACL
1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@test.ex H=localhost (primary.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmaZ-0005vi-00@primary.test.ex
1999-03-02 09:44:33 10HmbA-0005vi-00 => blackhole (RCPT ACL discarded recipients)
1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
1999-03-02 09:44:33 End queue run: pid=pppp
1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
1999-03-02 09:44:33 Start queue run: pid=pppp
-1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> rejected RCPT <userx@domA.ex>: discarded by RCPT ACL
+1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> RCPT <userx@domA.ex>: discarded by RCPT ACL
1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@test.ex H=localhost (primary.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmbB-0005vi-00@primary.test.ex
1999-03-02 09:44:33 10HmbC-0005vi-00 => blackhole (RCPT ACL discarded recipients)
1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
-1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> rejected RCPT <usery@domB.ex>: discarded by RCPT ACL
+1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> RCPT <usery@domB.ex>: discarded by RCPT ACL
1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@test.ex H=localhost (primary.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmbB-0005vi-00@primary.test.ex
1999-03-02 09:44:33 10HmbD-0005vi-00 => blackhole (RCPT ACL discarded recipients)
1999-03-02 09:44:33 10HmbD-0005vi-00 Completed
1999-03-02 09:44:33 End queue run: pid=pppp
1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
1999-03-02 09:44:33 Start queue run: pid=pppp
-1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> rejected RCPT <userx@domA.ex>: discarded by RCPT ACL
+1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> RCPT <userx@domA.ex>: discarded by RCPT ACL
1999-03-02 09:44:33 10HmbF-0005vi-00 <= CALLER@test.ex H=localhost (primary.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmbE-0005vi-00@primary.test.ex
1999-03-02 09:44:33 10HmbF-0005vi-00 => blackhole (RCPT ACL discarded recipients)
1999-03-02 09:44:33 10HmbF-0005vi-00 Completed
-1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> rejected RCPT <usery@domB.ex>: discarded by RCPT ACL
+1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> RCPT <usery@domB.ex>: discarded by RCPT ACL
1999-03-02 09:44:33 10HmbG-0005vi-00 <= CALLER@test.ex H=localhost (primary.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmbE-0005vi-00@primary.test.ex
1999-03-02 09:44:33 10HmbG-0005vi-00 => blackhole (RCPT ACL discarded recipients)
1999-03-02 09:44:33 10HmbG-0005vi-00 Completed
1999-03-02 09:44:33 End queue run: pid=pppp
1999-03-02 09:44:33 10HmbH-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
1999-03-02 09:44:33 Start queue run: pid=pppp
-1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> rejected RCPT <userx@domA.ex>: discarded by RCPT ACL
+1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> RCPT <userx@domA.ex>: discarded by RCPT ACL
1999-03-02 09:44:33 10HmbI-0005vi-00 <= CALLER@test.ex H=localhost (primary.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmbH-0005vi-00@primary.test.ex
1999-03-02 09:44:33 10HmbI-0005vi-00 => blackhole (RCPT ACL discarded recipients)
1999-03-02 09:44:33 10HmbI-0005vi-00 Completed
-1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> rejected RCPT <usery@domB.ex>: discarded by RCPT ACL
+1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> RCPT <usery@domB.ex>: discarded by RCPT ACL
1999-03-02 09:44:33 10HmbJ-0005vi-00 <= CALLER@test.ex H=localhost (primary.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmbH-0005vi-00@primary.test.ex
1999-03-02 09:44:33 10HmbJ-0005vi-00 => blackhole (RCPT ACL discarded recipients)
1999-03-02 09:44:33 10HmbJ-0005vi-00 Completed
1999-03-02 09:44:33 End queue run: pid=pppp
1999-03-02 09:44:33 10HmbK-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
1999-03-02 09:44:33 Start queue run: pid=pppp
-1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> rejected RCPT <userx@domA.ex>: discarded by RCPT ACL
-1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> rejected RCPT <usery@domA.ex>: discarded by RCPT ACL
+1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> RCPT <userx@domA.ex>: discarded by RCPT ACL
+1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> RCPT <usery@domA.ex>: discarded by RCPT ACL
1999-03-02 09:44:33 10HmbL-0005vi-00 <= CALLER@test.ex H=localhost (primary.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmbK-0005vi-00@primary.test.ex
1999-03-02 09:44:33 10HmbL-0005vi-00 => blackhole (RCPT ACL discarded recipients)
1999-03-02 09:44:33 10HmbL-0005vi-00 Completed
-1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> rejected RCPT <userz@domC.ex>: discarded by RCPT ACL
+1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> RCPT <userz@domC.ex>: discarded by RCPT ACL
1999-03-02 09:44:33 10HmbM-0005vi-00 <= CALLER@test.ex H=localhost (primary.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmbK-0005vi-00@primary.test.ex
1999-03-02 09:44:33 10HmbM-0005vi-00 => blackhole (RCPT ACL discarded recipients)
1999-03-02 09:44:33 10HmbM-0005vi-00 Completed
******** SERVER ********
1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 (IPv6 and IPv4)
1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtp S=sss id=E10HmaY-0005vi-00@myhost.test.ex
-1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@myhost.test.ex H=(myhost.test.ex) [ip6:ip6:ip6:ip6:ip6:ip6:ip6:ip6] P=esmtp S=sss id=E10HmaZ-0005vi-00@myhost.test.ex
+1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip6:ip6:ip6:ip6:ip6:ip6:ip6:ip6] P=esmtp S=sss id=E10HmaZ-0005vi-00@myhost.test.ex
1999-03-02 09:44:33 no host name found for IP address ::1
1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@myhost.test.ex H=(myhost.test.ex) [::1] P=esmtp S=sss id=E10HmbA-0005vi-00@myhost.test.ex
1999-03-02 09:44:33 no host name found for IP address ::1
1999-03-02 09:44:33 SN <CN=server2.example.com>
1999-03-02 09:44:33 IN <O=example.com,CN=clica Signing Cert>
1999-03-02 09:44:33 IN/O <example.com>
-1999-03-02 09:44:33 NB <Nov 1 12:34:06 2012 GMT>
-1999-03-02 09:44:33 NB/i <1351773246>
-1999-03-02 09:44:33 NA <Jan 1 12:34:06 2038 GMT>
-1999-03-02 09:44:33 SA <RSA-SHA>
-1999-03-02 09:44:33 SG <6c 37 41 26 4d 5d f4 b5 31 10 67 ca fb 64 b6 22 98 62 f7 1e 95 7b 6c e6 74 47 21 f4 5e 89 36 3e b9 9c 8a c5 52 bb c4 af 12 93 26 3b d7 3d e0 56 71 1e 1d 21 20 02 ed f0 4e d5 5e 45 42 fd 3c 38 41 54 83 86 0b 3b bf c5 47 39 ff 15 ea 93 dc fd c7 3d 18 58 59 ca dd 2a d8 b9 f9 2f b9 76 93 f4 ae e3 91 56 80 2f 8c 04 2f ad 57 ef d2 51 19 f4 b4 ef 32 9c ac 3a 7c 0d b8 39 db b1 e3 30 73 1a>
+1999-03-02 09:44:33 NB <Nov 1 12:34:38 2012 GMT>
+1999-03-02 09:44:33 NB/i <1351773278>
+1999-03-02 09:44:33 NA <Jan 1 12:34:38 2038 GMT>
+1999-03-02 09:44:33 SA <RSA-SHA256>
+1999-03-02 09:44:33 SG <99 09 ea 53 5b f2 51 45 99 71 c4 42 1c 41 59 50 2e 97 5c c6 e2 67 62 f3 5b 67 0c e7 ec eb 34 2b ba 20 d5 2e e3 97 83 c3 9d c6 a8 e8 03 e4 e9 fe 16 01 f1 63 6f 86 59 73 53 72 b5 21 cf 2e ea 1d 59 3a 18 d5 b5 33 20 13 0a c2 4f 49 a1 fd b2 c3 69 ab ff 71 25 cb 34 43 95 59 97 ae 2f ba 6f 45 f9 5a 67 cc 79 62 3b 9e 97 9b e8 f9 7a 9f 5f 2d 4d 82 a4 18 67 05 c2 c1 6c 0b e0 9e b8 b3 b3 37>
1999-03-02 09:44:33 SAN <DNS=server2.example.com>
1999-03-02 09:44:33 CRU <http://crl.example.com/latest.crl>
-1999-03-02 09:44:33 md5 fingerprint C5FA6C8B1BE926DBC4E436AF08F92B55
-1999-03-02 09:44:33 sha1 fingerprint 40B2135E6B67AE36A397696DA328423685E74CE3
-1999-03-02 09:44:33 sha256 fingerprint 6064D93E235FBA6FC66788F2AAC087752D856ECC7901FFCB8B53B21A09D232D2
+1999-03-02 09:44:33 md5 fingerprint 33728C89BBE99028425D137F7508F74A
+1999-03-02 09:44:33 sha1 fingerprint 1A420D865B90068FB822E71567A456A3578D26AA
+1999-03-02 09:44:33 sha256 fingerprint 7E194665AE12FD9AF8E604427D512E846E75EC96032BF78BAD707426F01CFF17
1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@test.ex H=[ip4.ip4.ip4.ip4] P=smtps X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=yes DN="CN=server2.example.com" S=sss
1999-03-02 09:44:33 Start queue run: pid=pppp -qf
1999-03-02 09:44:33 10HmaX-0005vi-00 => CALLER <CALLER@test.ex> R=abc T=local_delivery
1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
1999-03-02 09:44:33 Start queue run: pid=pppp -qf
-1999-03-02 09:44:33 10HmaX-0005vi-00 H=127.0.0.1 [127.0.0.1]: a TLS session is required, but the server did not offer TLS support
-1999-03-02 09:44:33 10HmaX-0005vi-00 => userx@test.ex R=client T=send_to_server H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no C="250 OK id=10HmaY-0005vi-00"
+1999-03-02 09:44:33 10HmaX-0005vi-00 H=127.0.0.1 [127.0.0.1]:1111: a TLS session is required, but the server did not offer TLS support
+1999-03-02 09:44:33 10HmaX-0005vi-00 => userx@test.ex R=client T=send_to_server H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4]:1225 X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no C="250 OK id=10HmaY-0005vi-00"
1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
1999-03-02 09:44:33 End queue run: pid=pppp -qf
1999-03-02 09:44:33 Start queue run: pid=pppp -qf
-1999-03-02 09:44:33 10HmaY-0005vi-00 H=127.0.0.1 [127.0.0.1]: a TLS session is required, but the server did not offer TLS support
-1999-03-02 09:44:33 10HmaY-0005vi-00 == userx@test.ex R=client T=send_to_server defer (-38) H=127.0.0.1 [127.0.0.1]: a TLS session is required, but the server did not offer TLS support
+1999-03-02 09:44:33 10HmaY-0005vi-00 H=127.0.0.1 [127.0.0.1]:1111: a TLS session is required, but the server did not offer TLS support
+1999-03-02 09:44:33 10HmaY-0005vi-00 == userx@test.ex R=client T=send_to_server defer (-38) H=127.0.0.1 [127.0.0.1]:1111: a TLS session is required, but the server did not offer TLS support
1999-03-02 09:44:33 10HmaY-0005vi-00 ** userx@test.ex: retry timeout exceeded
1999-03-02 09:44:33 10HmaZ-0005vi-00 <= <> R=10HmaY-0005vi-00 U=EXIMUSER P=local S=sss
1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
+1999-03-02 09:44:33 Warning: No server certificate defined; TLS connections will fail.
+ Suggested action: either install a certificate or change tls_advertise_hosts option
1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
+1999-03-02 09:44:33 Warning: No server certificate defined; TLS connections will fail.
+ Suggested action: either install a certificate or change tls_advertise_hosts option
1999-03-02 09:44:33 Start queue run: pid=pppp -qf
1999-03-02 09:44:33 10HmaX-0005vi-00 => userx@myhost.test.ex R=abc T=t1 H=127.0.0.1 [127.0.0.1] C="250 OK id=10HmaY-0005vi-00"
1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
1999-03-02 09:44:33 End queue run: pid=pppp -qf
******** SERVER ********
+1999-03-02 09:44:33 Warning: No server certificate defined; TLS connections will fail.
+ Suggested action: either install a certificate or change tls_advertise_hosts option
1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
1999-03-02 09:44:33 TLS error on connection from localhost (myhost.test.ex) [127.0.0.1] (no TLS server certificate is specified)
1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmaX-0005vi-00@myhost.test.ex
1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
1999-03-02 09:44:33 Start queue run: pid=pppp -qf
-1999-03-02 09:44:33 10HmaX-0005vi-00 SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
+1999-03-02 09:44:33 10HmaX-0005vi-00 [127.0.0.1] SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
1999-03-02 09:44:33 10HmaX-0005vi-00 H=127.0.0.1 [127.0.0.1] TLS error on connection (SSL_connect): error: <<detail omitted>>
1999-03-02 09:44:33 10HmaX-0005vi-00 == CALLER@test.ex R=client T=send_to_server defer (-37) H=127.0.0.1 [127.0.0.1]: failure while setting up TLS session
1999-03-02 09:44:33 End queue run: pid=pppp -qf
1999-03-02 09:44:33 Start queue run: pid=pppp -qf
-1999-03-02 09:44:33 10HmaX-0005vi-00 SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
+1999-03-02 09:44:33 10HmaX-0005vi-00 [127.0.0.1] SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
1999-03-02 09:44:33 10HmaX-0005vi-00 H=127.0.0.1 [127.0.0.1] TLS error on connection (SSL_connect): error: <<detail omitted>>
1999-03-02 09:44:33 10HmaX-0005vi-00 == CALLER@test.ex R=client T=send_to_server defer (-37) H=127.0.0.1 [127.0.0.1]: failure while setting up TLS session
1999-03-02 09:44:33 End queue run: pid=pppp -qf
1999-03-02 09:44:33 SN <CN=server2.example.com>
1999-03-02 09:44:33 IN <CN=clica Signing Cert,O=example.com>
1999-03-02 09:44:33 IN/O <example.com>
-1999-03-02 09:44:33 NB/r <Nov 1 12:34:06 2012 GMT>
-1999-03-02 09:44:33 NB <Nov 1 12:34:06 2012 +0000>
-1999-03-02 09:44:33 NB/i <1351773246>
-1999-03-02 09:44:33 NA <Jan 1 12:34:06 2038 +0000>
-1999-03-02 09:44:33 SA <sha1WithRSAEncryption>
-1999-03-02 09:44:33 SG < 6c:37:41:26:4d:5d:f4:b5:31:10:67:ca:fb:64:b6:22:98:62:\n f7:1e:95:7b:6c:e6:74:47:21:f4:5e:89:36:3e:b9:9c:8a:c5:\n 52:bb:c4:af:12:93:26:3b:d7:3d:e0:56:71:1e:1d:21:20:02:\n ed:f0:4e:d5:5e:45:42:fd:3c:38:41:54:83:86:0b:3b:bf:c5:\n 47:39:ff:15:ea:93:dc:fd:c7:3d:18:58:59:ca:dd:2a:d8:b9:\n f9:2f:b9:76:93:f4:ae:e3:91:56:80:2f:8c:04:2f:ad:57:ef:\n d2:51:19:f4:b4:ef:32:9c:ac:3a:7c:0d:b8:39:db:b1:e3:30:\n 73:1a\n>
+1999-03-02 09:44:33 NB/r <Nov 1 12:34:38 2012 GMT>
+1999-03-02 09:44:33 NB <Nov 1 12:34:38 2012 +0000>
+1999-03-02 09:44:33 NB/i <1351773278>
+1999-03-02 09:44:33 NA <Jan 1 12:34:38 2038 +0000>
+1999-03-02 09:44:33 SA <sha256WithRSAEncryption>
+1999-03-02 09:44:33 SG < 99:09:ea:53:5b:f2:51:45:99:71:c4:42:1c:41:59:50:2e:97:\n 5c:c6:e2:67:62:f3:5b:67:0c:e7:ec:eb:34:2b:ba:20:d5:2e:\n e3:97:83:c3:9d:c6:a8:e8:03:e4:e9:fe:16:01:f1:63:6f:86:\n 59:73:53:72:b5:21:cf:2e:ea:1d:59:3a:18:d5:b5:33:20:13:\n 0a:c2:4f:49:a1:fd:b2:c3:69:ab:ff:71:25:cb:34:43:95:59:\n 97:ae:2f:ba:6f:45:f9:5a:67:cc:79:62:3b:9e:97:9b:e8:f9:\n 7a:9f:5f:2d:4d:82:a4:18:67:05:c2:c1:6c:0b:e0:9e:b8:b3:\n b3:37\n>
1999-03-02 09:44:33 SAN <DNS=server2.example.com>
1999-03-02 09:44:33 OCU <http://oscp/example.com/>
1999-03-02 09:44:33 CRU <http://crl.example.com/latest.crl>
-1999-03-02 09:44:33 md5 fingerprint C5FA6C8B1BE926DBC4E436AF08F92B55
-1999-03-02 09:44:33 sha1 fingerprint 40B2135E6B67AE36A397696DA328423685E74CE3
-1999-03-02 09:44:33 sha256 fingerprint 6064D93E235FBA6FC66788F2AAC087752D856ECC7901FFCB8B53B21A09D232D2
+1999-03-02 09:44:33 md5 fingerprint 33728C89BBE99028425D137F7508F74A
+1999-03-02 09:44:33 sha1 fingerprint 1A420D865B90068FB822E71567A456A3578D26AA
+1999-03-02 09:44:33 sha256 fingerprint 7E194665AE12FD9AF8E604427D512E846E75EC96032BF78BAD707426F01CFF17
1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@test.ex H=[ip4.ip4.ip4.ip4] P=smtps X=TLSv1:AES256-SHA:256 CV=yes DN="/CN=server2.example.com" S=sss
1999-03-02 09:44:33 Start queue run: pid=pppp -qf
1999-03-02 09:44:33 10HmaX-0005vi-00 => CALLER <CALLER@test.ex> R=abc T=local_delivery
1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
1999-03-02 09:44:33 Start queue run: pid=pppp -qf
-1999-03-02 09:44:33 10HmaX-0005vi-00 SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
-1999-03-02 09:44:33 10HmaX-0005vi-00 SSL verify error: certificate name mismatch: "/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock"
-
+1999-03-02 09:44:33 10HmaX-0005vi-00 [127.0.0.1] SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
+1999-03-02 09:44:33 10HmaX-0005vi-00 [127.0.0.1] SSL verify error: certificate name mismatch: "/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock"
1999-03-02 09:44:33 10HmaX-0005vi-00 => userx@test.ex R=client T=send_to_server1 H=127.0.0.1 [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" C="250 OK id=10HmaY-0005vi-00"
1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
1999-03-02 09:44:33 End queue run: pid=pppp -qf
1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
1999-03-02 09:44:33 Start queue run: pid=pppp -qf
-1999-03-02 09:44:33 10HmaX-0005vi-00 SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
-1999-03-02 09:44:33 10HmaX-0005vi-00 SSL verify error: certificate name mismatch: "/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock"
-
+1999-03-02 09:44:33 10HmaX-0005vi-00 [127.0.0.1] SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
+1999-03-02 09:44:33 10HmaX-0005vi-00 [127.0.0.1] SSL verify error: certificate name mismatch: "/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock"
1999-03-02 09:44:33 10HmaX-0005vi-00 => CALLER@test.ex R=client T=send_to_server1 H=127.0.0.1 [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" C="250 OK id=10HmaZ-0005vi-00"
1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaY-0005vi-00 SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
-1999-03-02 09:44:33 10HmaY-0005vi-00 SSL verify error: certificate name mismatch: "/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock"
-
+1999-03-02 09:44:33 10HmaY-0005vi-00 [127.0.0.1] SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
+1999-03-02 09:44:33 10HmaY-0005vi-00 [127.0.0.1] SSL verify error: certificate name mismatch: "/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock"
1999-03-02 09:44:33 10HmaY-0005vi-00 => CALLER@test.ex R=client T=send_to_server1 H=127.0.0.1 [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" C="250 OK id=10HmbA-0005vi-00"
1999-03-02 09:44:33 10HmaY-0005vi-00 -> xyz@test.ex R=client T=send_to_server1 H=127.0.0.1 [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" C="250 OK id=10HmbA-0005vi-00"
-1999-03-02 09:44:33 10HmaY-0005vi-00 SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
-1999-03-02 09:44:33 10HmaY-0005vi-00 SSL verify error: certificate name mismatch: "/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock"
-
+1999-03-02 09:44:33 10HmaY-0005vi-00 [ip4.ip4.ip4.ip4] SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
+1999-03-02 09:44:33 10HmaY-0005vi-00 [ip4.ip4.ip4.ip4] SSL verify error: certificate name mismatch: "/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock"
1999-03-02 09:44:33 10HmaY-0005vi-00 => abcd@test.ex R=client T=send_to_server2 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLSv1:AES256-SHA:256 CV=no DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" C="250 OK id=10HmbB-0005vi-00"
1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
1999-03-02 09:44:33 End queue run: pid=pppp -qf
1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
1999-03-02 09:44:33 Start queue run: pid=pppp -qf
-1999-03-02 09:44:33 10HmaX-0005vi-00 H=127.0.0.1 [127.0.0.1]: a TLS session is required, but the server did not offer TLS support
-1999-03-02 09:44:33 10HmaX-0005vi-00 SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
-1999-03-02 09:44:33 10HmaX-0005vi-00 SSL verify error: certificate name mismatch: "/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock"
-
-1999-03-02 09:44:33 10HmaX-0005vi-00 => userx@test.ex R=client T=send_to_server H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLSv1:AES256-SHA:256 CV=no C="250 OK id=10HmaY-0005vi-00"
+1999-03-02 09:44:33 10HmaX-0005vi-00 H=127.0.0.1 [127.0.0.1]:1111: a TLS session is required, but the server did not offer TLS support
+1999-03-02 09:44:33 10HmaX-0005vi-00 [ip4.ip4.ip4.ip4] SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
+1999-03-02 09:44:33 10HmaX-0005vi-00 [ip4.ip4.ip4.ip4] SSL verify error: certificate name mismatch: "/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock"
+1999-03-02 09:44:33 10HmaX-0005vi-00 => userx@test.ex R=client T=send_to_server H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4]:1225 X=TLSv1:AES256-SHA:256 CV=no C="250 OK id=10HmaY-0005vi-00"
1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
1999-03-02 09:44:33 End queue run: pid=pppp -qf
1999-03-02 09:44:33 Start queue run: pid=pppp -qf
-1999-03-02 09:44:33 10HmaY-0005vi-00 H=127.0.0.1 [127.0.0.1]: a TLS session is required, but the server did not offer TLS support
-1999-03-02 09:44:33 10HmaY-0005vi-00 == userx@test.ex R=client T=send_to_server defer (-38) H=127.0.0.1 [127.0.0.1]: a TLS session is required, but the server did not offer TLS support
+1999-03-02 09:44:33 10HmaY-0005vi-00 H=127.0.0.1 [127.0.0.1]:1111: a TLS session is required, but the server did not offer TLS support
+1999-03-02 09:44:33 10HmaY-0005vi-00 == userx@test.ex R=client T=send_to_server defer (-38) H=127.0.0.1 [127.0.0.1]:1111: a TLS session is required, but the server did not offer TLS support
1999-03-02 09:44:33 10HmaY-0005vi-00 ** userx@test.ex: retry timeout exceeded
1999-03-02 09:44:33 10HmaZ-0005vi-00 <= <> R=10HmaY-0005vi-00 U=EXIMUSER P=local S=sss
1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
1999-03-02 09:44:33 Start queue run: pid=pppp -qf
1999-03-02 09:44:33 10HmaX-0005vi-00 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] TLS error on connection (SSL_connect): error: <<detail omitted>>
-1999-03-02 09:44:33 10HmaX-0005vi-00 SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
-1999-03-02 09:44:33 10HmaX-0005vi-00 SSL verify error: certificate name mismatch: "/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock"
-
+1999-03-02 09:44:33 10HmaX-0005vi-00 [127.0.0.1] SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
+1999-03-02 09:44:33 10HmaX-0005vi-00 [127.0.0.1] SSL verify error: certificate name mismatch: "/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock"
1999-03-02 09:44:33 10HmaX-0005vi-00 => userx@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1] X=TLSv1:DES-CBC3-SHA:168 CV=no DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" C="250 OK id=10HmaY-0005vi-00"
1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
1999-03-02 09:44:33 End queue run: pid=pppp -qf
-1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
+1999-03-02 09:44:33 this will fail to verify the cert at ip4.ip4.ip4.ip4 so fail the crypt requirement
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for userx@test.ex
+1999-03-02 09:44:33 this will fail to verify the cert at ip4.ip4.ip4.ip4 so fail the crypt, then retry on 127.1; ok
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for usery@test.ex
+1999-03-02 09:44:33 this will fail to verify the cert but continue unverified though crypted
+1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for userz@test.ex
+1999-03-02 09:44:33 this will fail to verify the cert at ip4.ip4.ip4.ip4 and fallback to unencrypted
+1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for userq@test.ex
+1999-03-02 09:44:33 this will fail to verify the cert name and fallback to unencrypted
+1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for userr@test.ex
+1999-03-02 09:44:33 this will pass the cert verify including name check
+1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for users@test.ex
1999-03-02 09:44:33 Start queue run: pid=pppp -qf
-1999-03-02 09:44:33 10HmaX-0005vi-00 SSL verify error: depth=0 error=unable to get local issuer certificate cert=/CN=server1.example.com
+1999-03-02 09:44:33 10HmaX-0005vi-00 [ip4.ip4.ip4.ip4] SSL verify error: depth=0 error=unable to get local issuer certificate cert=/CN=server1.example.com
1999-03-02 09:44:33 10HmaX-0005vi-00 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] TLS error on connection (SSL_connect): error: <<detail omitted>>
1999-03-02 09:44:33 10HmaX-0005vi-00 == userx@test.ex R=client_x T=send_to_server_failcert defer (-37) H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4]: failure while setting up TLS session
1999-03-02 09:44:33 10HmaX-0005vi-00 ** userx@test.ex: retry timeout exceeded
1999-03-02 09:44:33 10HmaX-0005vi-00 userx@test.ex: error ignored
1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaY-0005vi-00 SSL verify error: depth=0 error=unable to get local issuer certificate cert=/CN=server1.example.com
+1999-03-02 09:44:33 10HmaY-0005vi-00 [ip4.ip4.ip4.ip4] SSL verify error: depth=0 error=unable to get local issuer certificate cert=/CN=server1.example.com
1999-03-02 09:44:33 10HmaY-0005vi-00 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] TLS error on connection (SSL_connect): error: <<detail omitted>>
1999-03-02 09:44:33 10HmaY-0005vi-00 => usery@test.ex R=client_y T=send_to_server_retry H=127.0.0.1 [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=yes DN="/CN=server1.example.com" C="250 OK id=10HmbD-0005vi-00"
1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaZ-0005vi-00 SSL verify error: depth=0 error=unable to get local issuer certificate cert=/CN=server1.example.com
-1999-03-02 09:44:33 10HmaZ-0005vi-00 SSL verify error: depth=0 error=certificate not trusted cert=/CN=server1.example.com
-1999-03-02 09:44:33 10HmaZ-0005vi-00 SSL verify error: depth=0 error=unable to verify the first certificate cert=/CN=server1.example.com
+1999-03-02 09:44:33 10HmaZ-0005vi-00 [ip4.ip4.ip4.ip4] SSL verify error: depth=0 error=unable to get local issuer certificate cert=/CN=server1.example.com
+1999-03-02 09:44:33 10HmaZ-0005vi-00 [ip4.ip4.ip4.ip4] SSL verify error: depth=0 error=unable to verify the first certificate cert=/CN=server1.example.com
1999-03-02 09:44:33 10HmaZ-0005vi-00 => userz@test.ex R=client_z T=send_to_server_crypt H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLSv1:AES256-SHA:256 CV=no DN="/CN=server1.example.com" C="250 OK id=10HmbE-0005vi-00"
1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbA-0005vi-00 SSL verify error: depth=0 error=unable to get local issuer certificate cert=/CN=server1.example.com
+1999-03-02 09:44:33 10HmbA-0005vi-00 [ip4.ip4.ip4.ip4] SSL verify error: depth=0 error=unable to get local issuer certificate cert=/CN=server1.example.com
1999-03-02 09:44:33 10HmbA-0005vi-00 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] TLS error on connection (SSL_connect): error: <<detail omitted>>
1999-03-02 09:44:33 10HmbA-0005vi-00 TLS session failure: delivering unencrypted to ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] (not in hosts_require_tls)
1999-03-02 09:44:33 10HmbA-0005vi-00 => userq@test.ex R=client_q T=send_to_server_req_fail H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] C="250 OK id=10HmbF-0005vi-00"
1999-03-02 09:44:33 TLS client disconnected cleanly (rejected our certificate?)
1999-03-02 09:44:33 TLS error on connection from the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] (SSL_accept): error: <<detail omitted>>
1999-03-02 09:44:33 TLS client disconnected cleanly (rejected our certificate?)
-1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtps X=TLSv1:AES256-SHA:256 CV=yes DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" S=sss id=E10HmaY-0005vi-00@myhost.test.ex
-1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLSv1:AES256-SHA:256 CV=yes DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" S=sss id=E10HmaZ-0005vi-00@myhost.test.ex
+1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtps X=TLSv1:AES256-SHA:256 CV=yes DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" S=sss id=E10HmaY-0005vi-00@myhost.test.ex for usery@test.ex
+1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLSv1:AES256-SHA:256 CV=yes DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" S=sss id=E10HmaZ-0005vi-00@myhost.test.ex for userz@test.ex
1999-03-02 09:44:33 TLS error on connection from the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] (SSL_accept): error: <<detail omitted>>
1999-03-02 09:44:33 TLS client disconnected cleanly (rejected our certificate?)
-1999-03-02 09:44:33 10HmbF-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtp S=sss id=E10HmbA-0005vi-00@myhost.test.ex
-1999-03-02 09:44:33 10HmbG-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLSv1:AES256-SHA:256 CV=yes DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" S=sss id=E10HmbB-0005vi-00@myhost.test.ex
-1999-03-02 09:44:33 10HmbH-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLSv1:AES256-SHA:256 CV=yes DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" S=sss id=E10HmbC-0005vi-00@myhost.test.ex
+1999-03-02 09:44:33 10HmbF-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtp S=sss id=E10HmbA-0005vi-00@myhost.test.ex for userq@test.ex
+1999-03-02 09:44:33 10HmbG-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLSv1:AES256-SHA:256 CV=yes DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" S=sss id=E10HmbB-0005vi-00@myhost.test.ex for userr@test.ex
+1999-03-02 09:44:33 10HmbH-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLSv1:AES256-SHA:256 CV=yes DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" S=sss id=E10HmbC-0005vi-00@myhost.test.ex for users@test.ex
1999-03-02 09:44:33 TLS error on connection from (rhu.barb) [ip4.ip4.ip4.ip4] (SSL_accept): error: <<detail omitted>>
1999-03-02 09:44:33 TLS client disconnected cleanly (rejected our certificate?)
1999-03-02 09:44:33 H=(rhu.barb) [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no F=<userx@test.ex> rejected RCPT <userx@test.ex>: certificate not verified: peerdn=
-1999-03-02 09:44:33 SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
+1999-03-02 09:44:33 [ip4.ip4.ip4.ip4] SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
1999-03-02 09:44:33 TLS error on connection from (rhu.barb) [ip4.ip4.ip4.ip4] (SSL_accept): error: <<detail omitted>>
1999-03-02 09:44:33 TLS client disconnected cleanly (rejected our certificate?)
-1999-03-02 09:44:33 SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
+1999-03-02 09:44:33 [127.0.0.1] SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
1999-03-02 09:44:33 H=[127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" F=<userx@test.ex> rejected RCPT <userx@test.ex>: certificate not verified: peerdn=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
-1999-03-02 09:44:33 SSL verify error: depth=0 error=certificate revoked cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
+1999-03-02 09:44:33 [ip4.ip4.ip4.ip4] SSL verify error: depth=0 error=certificate revoked cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
1999-03-02 09:44:33 TLS error on connection from (rhu.barb) [ip4.ip4.ip4.ip4] (SSL_accept): error: <<detail omitted>>
1999-03-02 09:44:33 TLS client disconnected cleanly (rejected our certificate?)
-1999-03-02 09:44:33 SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
-1999-03-02 09:44:33 SSL verify error: depth=0 error=CRL signature failure cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
+1999-03-02 09:44:33 [127.0.0.1] SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
+1999-03-02 09:44:33 [127.0.0.1] SSL verify error: depth=0 error=CRL signature failure cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
1999-03-02 09:44:33 H=[127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" F=<userx@test.ex> rejected RCPT <userx@test.ex>: certificate not verified: peerdn=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
+1999-03-02 09:44:33 Warning: No server certificate defined; TLS connections will fail.
+ Suggested action: either install a certificate or change tls_advertise_hosts option
1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
+1999-03-02 09:44:33 Warning: No server certificate defined; TLS connections will fail.
+ Suggested action: either install a certificate or change tls_advertise_hosts option
1999-03-02 09:44:33 Start queue run: pid=pppp -qf
1999-03-02 09:44:33 10HmaX-0005vi-00 H=127.0.0.1 [127.0.0.1] TLS error on connection (SSL_connect): error: <<detail omitted>>
1999-03-02 09:44:33 10HmaX-0005vi-00 TLS session failure: delivering unencrypted to 127.0.0.1 [127.0.0.1] (not in hosts_require_tls)
1999-03-02 09:44:33 End queue run: pid=pppp -qf
******** SERVER ********
+1999-03-02 09:44:33 Warning: No server certificate defined; TLS connections will fail.
+ Suggested action: either install a certificate or change tls_advertise_hosts option
1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
1999-03-02 09:44:33 TLS error on connection from localhost (myhost.test.ex) [127.0.0.1] (SSL_accept): error: <<detail omitted>>
1999-03-02 09:44:33 TLS client disconnected cleanly (rejected our certificate?)
1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
-1999-03-02 09:44:33 SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
+1999-03-02 09:44:33 [ip4.ip4.ip4.ip4] SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
1999-03-02 09:44:33 TLS error on connection from (rhu.barb) [ip4.ip4.ip4.ip4] (SSL_accept): error: <<detail omitted>>
1999-03-02 09:44:33 TLS client disconnected cleanly (rejected our certificate?)
1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
-1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for CALLER@test.ex
1999-03-02 09:44:33 10HmaX-0005vi-00 => CALLER@test.ex R=client T=send_to_server1 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLSv1:AES256-SHA:256 CV=no DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" C="250 OK id=10HmaY-0005vi-00"
1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for abcd@test.ex
1999-03-02 09:44:33 10HmaZ-0005vi-00 => abcd@test.ex R=client T=send_to_server2 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLSv1:AES256-SHA:256 CV=no DN="/CN=server1.example.com" C="250 OK id=10HmbA-0005vi-00"
1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
******** SERVER ********
1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
1999-03-02 09:44:33 SNI <fred>
-1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLSv1:AES256-SHA:256 CV=no SNI="fred" S=sss id=E10HmaX-0005vi-00@myhost.test.ex
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLSv1:AES256-SHA:256 CV=no SNI="fred" S=sss id=E10HmaX-0005vi-00@myhost.test.ex for CALLER@test.ex
1999-03-02 09:44:33 10HmaY-0005vi-00 => :blackhole: <CALLER@test.ex> R=server
1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
1999-03-02 09:44:33 SNI <bill>
-1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLSv1:AES256-SHA:256 CV=no SNI="bill" S=sss id=E10HmaZ-0005vi-00@myhost.test.ex
+1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLSv1:AES256-SHA:256 CV=no SNI="bill" S=sss id=E10HmaZ-0005vi-00@myhost.test.ex for abcd@test.ex
1999-03-02 09:44:33 10HmbA-0005vi-00 => :blackhole: <abcd@test.ex> R=server
1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss id=20041217133501.GA3058@test.ex
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss id=20041217133501.GA3058@test.ex T="[exim] Re: Bug#286074: eximstats: uses message count as data for\n the \"volume\" charts"
1999-03-02 09:44:33 10HmaX-0005vi-00 => userx <userx@test.ex> R=r1 T=t1
1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss id=20041217133501.GA3058@test.ex
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss id=20041217133501.GA3058@test.ex T="Nasty"
1999-03-02 09:44:33 10HmaY-0005vi-00 => userx <userx@test.ex> R=r1 T=t1
1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
+1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss id=20041217133501.GA3059@test.ex T="Nasty"
+1999-03-02 09:44:33 10HmaZ-0005vi-00 => userx <userx@test.ex> R=r1 T=t1
+1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss id=20041217133501.GA3059@test.ex T="Nasty3"
+1999-03-02 09:44:33 10HmbA-0005vi-00 => userx <userx@test.ex> R=r1 T=t1
+1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss id=20041217133501.GA3059@test.ex T="Nasty4"
+1999-03-02 09:44:33 10HmbB-0005vi-00 => userx <userx@test.ex> R=r1 T=t1
+1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss id=20041217133501.GA3058@test.ex T="Nasty5"
+1999-03-02 09:44:33 10HmbC-0005vi-00 => userx <userx@test.ex> R=r1 T=t1
+1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss id=20041217133502.GA3059@test.ex T="Nasty6"
+1999-03-02 09:44:33 10HmbD-0005vi-00 => userx <userx@test.ex> R=r1 T=t1
+1999-03-02 09:44:33 10HmbD-0005vi-00 Completed
1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss
1999-03-02 09:44:33 10HmaZ-0005vi-00 => :blackhole: <userx@test.ex> R=r
1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaX-0005vi-00 malware_name wibble
+1999-03-02 09:44:33 10HmaX-0005vi-00 [127.0.0.1]:1111 malware_name wibble
1999-03-02 09:44:33 10HmaX-0005vi-00 U=CALLER F=<CALLER@myhost.test.ex> rejected after DATA
1999-03-02 09:44:33 10HmaY-0005vi-00 U=CALLER F=<CALLER@myhost.test.ex> temporarily rejected after DATA
1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss
1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss T="message should be accepted"
1999-03-02 09:44:33 10HmbD-0005vi-00 => :blackhole: <userx@test.ex> R=r
1999-03-02 09:44:33 10HmbD-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: aveserver: unable to scan file TESTSUITE/spool/scan/10HmaX-0005vi-00/10HmaX-0005vi-00.eml (Responded: 5xx defer).
+1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: aveserver TESTSUITE/eximdir/aveserver_sock : unable to scan file TESTSUITE/spool/scan/10HmaX-0005vi-00/10HmaX-0005vi-00.eml (Responded: 5xx defer).
1999-03-02 09:44:33 10HmaX-0005vi-00 U=CALLER F=<CALLER@myhost.test.ex> temporarily rejected after DATA
1999-03-02 09:44:33 10HmbB-0005vi-00 malware_name VNAME
1999-03-02 09:44:33 10HmbB-0005vi-00 U=CALLER F=<CALLER@myhost.test.ex> rejected after DATA
-1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: aveserver: unavailable (Responded: nothing).
+1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: aveserver TESTSUITE/eximdir/aveserver_sock : unavailable (Responded: nothing).
1999-03-02 09:44:33 10HmaY-0005vi-00 U=CALLER F=<CALLER@myhost.test.ex> temporarily rejected after DATA
-1999-03-02 09:44:33 10HmaZ-0005vi-00 malware acl condition: aveserver: unavailable (Responded: nothing).
+1999-03-02 09:44:33 10HmaZ-0005vi-00 malware acl condition: aveserver TESTSUITE/eximdir/aveserver_sock : unavailable (Responded: nothing).
1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss T="message should be accepted despite timeout"
1999-03-02 09:44:33 10HmaZ-0005vi-00 => :blackhole: <userx@test.ex> R=r
1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbA-0005vi-00 malware acl condition: aveserver: unable to scan file TESTSUITE/spool/scan/10HmbA-0005vi-00/10HmbA-0005vi-00.eml (Responded: 5xx defer).
+1999-03-02 09:44:33 10HmbA-0005vi-00 malware acl condition: aveserver TESTSUITE/eximdir/aveserver_sock : unable to scan file TESTSUITE/spool/scan/10HmbA-0005vi-00/10HmbA-0005vi-00.eml (Responded: 5xx defer).
1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss T="accept this, overriding the scan daemon temp-error"
1999-03-02 09:44:33 10HmbA-0005vi-00 => :blackhole: <userx@test.ex> R=r
1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
1999-03-02 09:44:33 10HmaZ-0005vi-00 malware_name VNAME
1999-03-02 09:44:33 10HmaZ-0005vi-00 U=CALLER F=<CALLER@myhost.test.ex> rejected after DATA
-1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: fsecure: unable to read answer 0 (Connection timed out)
+1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: fsecure TESTSUITE/eximdir/fsec_sock : unable to read answer 0 (Connection timed out)
1999-03-02 09:44:33 10HmaX-0005vi-00 U=CALLER F=<CALLER@myhost.test.ex> temporarily rejected after DATA
-1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: fsecure: unable to read answer 0 (Connection timed out)
+1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: fsecure TESTSUITE/eximdir/fsec_sock : unable to read answer 0 (Connection timed out)
1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss T="message should be accepted despite timeout"
1999-03-02 09:44:33 10HmaY-0005vi-00 => :blackhole: <userx@test.ex> R=r
1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss T="message should be accepted"
1999-03-02 09:44:33 10HmbB-0005vi-00 => :blackhole: <userx@test.ex> R=r
1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: sophie: scanner reported error
+1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: sophie TESTSUITE/eximdir/sophie_sock : scanner reported error
1999-03-02 09:44:33 10HmaX-0005vi-00 U=CALLER F=<CALLER@myhost.test.ex> temporarily rejected after DATA
1999-03-02 09:44:33 10HmbA-0005vi-00 malware_name VNAME
1999-03-02 09:44:33 10HmbA-0005vi-00 U=CALLER F=<CALLER@myhost.test.ex> rejected after DATA
-1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: sophie: unable to read from UNIX socket (TESTSUITE/eximdir/sophie_sock)
+1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: sophie TESTSUITE/eximdir/sophie_sock : unable to read from UNIX socket (TESTSUITE/eximdir/sophie_sock)
1999-03-02 09:44:33 10HmaY-0005vi-00 U=CALLER F=<CALLER@myhost.test.ex> temporarily rejected after DATA
-1999-03-02 09:44:33 10HmaZ-0005vi-00 malware acl condition: sophie: unable to read from UNIX socket (TESTSUITE/eximdir/sophie_sock)
+1999-03-02 09:44:33 10HmaZ-0005vi-00 malware acl condition: sophie TESTSUITE/eximdir/sophie_sock : unable to read from UNIX socket (TESTSUITE/eximdir/sophie_sock)
1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss T="message should be accepted destpite timeout"
1999-03-02 09:44:33 10HmaZ-0005vi-00 => :blackhole: <userx@test.ex> R=r
1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss T="message should be accepted"
1999-03-02 09:44:33 10HmbB-0005vi-00 => :blackhole: <userx@test.ex> R=r
1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: clamd: ClamAV returned: scanned_file_name: 666 ERROR
+1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: clamd TESTSUITE/eximdir/clam_sock : ClamAV returned: scanned_file_name: 666 ERROR
1999-03-02 09:44:33 10HmaX-0005vi-00 U=CALLER F=<CALLER@myhost.test.ex> temporarily rejected after DATA
1999-03-02 09:44:33 10HmbA-0005vi-00 malware_name VNAME
1999-03-02 09:44:33 10HmbA-0005vi-00 U=CALLER F=<CALLER@myhost.test.ex> rejected after DATA
-1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: clamd: unable to read from socket (Connection timed out)
+1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: clamd TESTSUITE/eximdir/clam_sock : unable to read from socket (Connection timed out)
1999-03-02 09:44:33 10HmaY-0005vi-00 U=CALLER F=<CALLER@myhost.test.ex> temporarily rejected after DATA
-1999-03-02 09:44:33 10HmaZ-0005vi-00 malware acl condition: clamd: unable to read from socket (Connection timed out)
+1999-03-02 09:44:33 10HmaZ-0005vi-00 malware acl condition: clamd TESTSUITE/eximdir/clam_sock : unable to read from socket (Connection timed out)
1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss T="accept this one despite timeout"
1999-03-02 09:44:33 10HmaZ-0005vi-00 => :blackhole: <userx@test.ex> R=r
1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss T="message should be accepted after a retry"
+1999-03-02 09:44:33 10HmbC-0005vi-00 => :blackhole: <userx@test.ex> R=r
+1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss T="message should be accepted"
1999-03-02 09:44:33 10HmbB-0005vi-00 => :blackhole: <userx@test.ex> R=r
1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: avast: invalid response from scanner: 'blah [E]'
+1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: avast TESTSUITE/eximdir/avast_sock : invalid response from scanner: 'blah [E]'
1999-03-02 09:44:33 10HmaX-0005vi-00 U=CALLER F=<CALLER@myhost.test.ex> temporarily rejected after DATA
1999-03-02 09:44:33 10HmbA-0005vi-00 malware_name VNAME
1999-03-02 09:44:33 10HmbA-0005vi-00 U=CALLER F=<CALLER@myhost.test.ex> rejected after DATA
-1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: avast: timeout from scanner
+1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: avast TESTSUITE/eximdir/avast_sock : timeout from scanner
1999-03-02 09:44:33 10HmaY-0005vi-00 U=CALLER F=<CALLER@myhost.test.ex> temporarily rejected after DATA
-1999-03-02 09:44:33 10HmaZ-0005vi-00 malware acl condition: avast: timeout from scanner
+1999-03-02 09:44:33 10HmaZ-0005vi-00 malware acl condition: avast TESTSUITE/eximdir/avast_sock : timeout from scanner
1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss T="message should be accepted despite timeout"
1999-03-02 09:44:33 10HmaZ-0005vi-00 => :blackhole: <userx@test.ex> R=r
1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
1999-03-02 09:44:33 10HmaZ-0005vi-00 malware_name VNAME
1999-03-02 09:44:33 10HmaZ-0005vi-00 U=CALLER F=<CALLER@myhost.test.ex> rejected after DATA
-1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: cmdline: unable to read from scanner (TESTSUITE/aux-fixed/4007.script -o pause3 TESTSUITE/spool/scan/10HmaX-0005vi-00 2>&1): Connection timed out
+1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: cmdline : unable to read from scanner (TESTSUITE/aux-fixed/4007.script -o pause3 TESTSUITE/spool/scan/10HmaX-0005vi-00 2>&1): Connection timed out
1999-03-02 09:44:33 10HmaX-0005vi-00 U=CALLER F=<CALLER@myhost.test.ex> temporarily rejected after DATA
-1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: cmdline: unable to read from scanner (TESTSUITE/aux-fixed/4007.script -o pause3 TESTSUITE/spool/scan/10HmaY-0005vi-00 2>&1): Connection timed out
+1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: cmdline : unable to read from scanner (TESTSUITE/aux-fixed/4007.script -o pause3 TESTSUITE/spool/scan/10HmaY-0005vi-00 2>&1): Connection timed out
1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss T="message should be accepted despite a timeout"
1999-03-02 09:44:33 10HmaY-0005vi-00 => :blackhole: <userx@test.ex> R=r
1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss id=41C2F849.3060203@projectile.test.ex
+1999-03-02 09:44:33 10HmaX-0005vi-00 => userx <userx@test.ex> R=r1 T=t1
+1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss id=41C2F849.3060203@projectile.test.ex
1999-03-02 09:44:33 10HmaY-0005vi-00 => userx <userx@test.ex> R=r1 T=t1
1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss id=41C2F849.3060203@projectile.test.ex
-1999-03-02 09:44:33 10HmaZ-0005vi-00 => userx <userx@test.ex> R=r1 T=t1
-1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss id=abcde
-1999-03-02 09:44:33 10HmbA-0005vi-00 => userx <userx@test.ex> R=r1 T=t1
-1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss id=41C2F849.3060203@projectile.test.ex
-1999-03-02 09:44:33 10HmbB-0005vi-00 => userx <userx@test.ex> R=r1 T=t1
-1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss id=20041217133501.GA3058@test.ex
-1999-03-02 09:44:33 10HmbC-0005vi-00 => userx <userx@test.ex> R=r1 T=t1
-1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbD-0005vi-00 => userx <userx@test.ex> R=r1 T=t1
-1999-03-02 09:44:33 10HmbD-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss id=20041217133501.GA3058@test.ex
-1999-03-02 09:44:33 10HmbE-0005vi-00 => userx <userx@test.ex> R=r1 T=t1
-1999-03-02 09:44:33 10HmbE-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbF-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss id=41C2F849.3060203@projectile.test.ex
-1999-03-02 09:44:33 10HmbF-0005vi-00 => userx <userx@test.ex> R=r1 T=t1
-1999-03-02 09:44:33 10HmbF-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaX-0005vi-00 U=CALLER F=<CALLER@myhost.test.ex> rejected after DATA: Found Eicar-Test-Signature
QUIT
<<< QUIT
250 OK
-1999-03-02 09:44:33 10HmaZ-0005vi-00 => userx <userx@myhost.test.ex> R=smartuser T=lmtp ST=local_delivery (mailbox TESTSUITE/test-mail/ has too many links (2)) C="250 Number 1 is OK"
+1999-03-02 09:44:33 10HmaZ-0005vi-00 => userx <userx@myhost.test.ex> R=smartuser T=lmtp ST=local_delivery (mailbox TESTSUITE/test-mail/ not a regular file or too many links) C="250 Number 1 is OK"
1999-03-02 09:44:33 10HmaZ-0005vi-00 ** jack@myhost.test.ex R=smartuser T=lmtp: LMTP error after end of data: 550 Number 2 fails
-1999-03-02 09:44:33 10HmaZ-0005vi-00 -> jill <jill@myhost.test.ex> R=smartuser T=lmtp ST=local_delivery (mailbox TESTSUITE/test-mail/ has too many links (2)) C="250 Number 3 is OK"
+1999-03-02 09:44:33 10HmaZ-0005vi-00 -> jill <jill@myhost.test.ex> R=smartuser T=lmtp ST=local_delivery (mailbox TESTSUITE/test-mail/ not a regular file or too many links) C="250 Number 3 is OK"
1999-03-02 09:44:33 10HmbA-0005vi-00 <= <> R=10HmaZ-0005vi-00 U=EXIMUSER P=local S=sss
1999-03-02 09:44:33 10HmbA-0005vi-00 => CALLER <CALLER@myhost.test.ex> R=bounces T=local_delivery
1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
1999-03-02 09:44:33 rcpt for userx@domain.com
1999-03-02 09:44:33 10HmaX-0005vi-00 >> userx@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
-1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss for userx@domain.com
1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
1999-03-02 09:44:33 rcpt for userz@domain.com
1999-03-02 09:44:33 10HmaY-0005vi-00 >> userz@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
-1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss for userz@domain.com
1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
1999-03-02 09:44:33 rcpt for usery@domain.com
1999-03-02 09:44:33 rcpt for userx@domain.com
-1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss
-1999-03-02 09:44:33 10HmaZ-0005vi-00 => usery@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
-1999-03-02 09:44:33 10HmaZ-0005vi-00 -> userx@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
+1999-03-02 09:44:33 10HmaZ-0005vi-00 >> userx@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
+1999-03-02 09:44:33 10HmaZ-0005vi-00 >> usery@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
+1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss for usery@domain.com userx@domain.com
1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
1999-03-02 09:44:33 rcpt for userx@domain.com
1999-03-02 09:44:33 10HmbA-0005vi-00 >> userx@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
-1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss
+1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss for userx@domain.com
1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
+1999-03-02 09:44:33 rcpt for no@domain.com
+1999-03-02 09:44:33 rcpt for userx@domain.com
+1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss for no@domain.com userx@domain.com
+1999-03-02 09:44:33 10HmbB-0005vi-00 => no@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
+1999-03-02 09:44:33 10HmbB-0005vi-00 -> userx@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
+1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
+1999-03-02 09:44:33 rcpt for userx@domain.com
+1999-03-02 09:44:33 rcpt for no@domain.com
+1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss for userx@domain.com no@domain.com
+1999-03-02 09:44:33 10HmbC-0005vi-00 => userx@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
+1999-03-02 09:44:33 10HmbC-0005vi-00 -> no@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
+1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
+1999-03-02 09:44:33 rcpt for userx@domain.com
+1999-03-02 09:44:33 rcpt for special_tpt@domain.com
+1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss for userx@domain.com special_tpt@domain.com
+1999-03-02 09:44:33 10HmbD-0005vi-00 => userx@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
+1999-03-02 09:44:33 10HmbD-0005vi-00 => special_tpt@domain.com R=all T=smtp2 H=127.0.0.1 [127.0.0.1] C="250 OK"
+1999-03-02 09:44:33 10HmbD-0005vi-00 Completed
+1999-03-02 09:44:33 rcpt for userx@domain1.com
+1999-03-02 09:44:33 rcpt for usery@domain2.com
+1999-03-02 09:44:33 10HmbE-0005vi-00 >> usery@domain2.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
+1999-03-02 09:44:33 10HmbE-0005vi-00 >> userx@domain1.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
+1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss for userx@domain1.com usery@domain2.com
+1999-03-02 09:44:33 10HmbE-0005vi-00 Completed
+1999-03-02 09:44:33 rcpt for userx@domain.com
+1999-03-02 09:44:33 rcpt for usery@special.com
+1999-03-02 09:44:33 10HmbF-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss for userx@domain.com usery@special.com
+1999-03-02 09:44:33 10HmbF-0005vi-00 => userx@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
+1999-03-02 09:44:33 10HmbF-0005vi-00 => usery@special.com R=all T=smtp H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] C="250 OK"
+1999-03-02 09:44:33 10HmbF-0005vi-00 Completed
+1999-03-02 09:44:33 rcpt for userx@localhost4.test.ex
+1999-03-02 09:44:33 rcpt for usery@thishost.test.ex
+1999-03-02 09:44:33 10HmbG-0005vi-00 >> usery@thishost.test.ex R=dns T=smtp H=localhost4.test.ex [127.0.0.1] C="250 OK"
+1999-03-02 09:44:33 10HmbG-0005vi-00 >> userx@localhost4.test.ex R=dns T=smtp H=localhost4.test.ex [127.0.0.1] C="250 OK"
+1999-03-02 09:44:33 10HmbG-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss for userx@localhost4.test.ex usery@thishost.test.ex
+1999-03-02 09:44:33 10HmbG-0005vi-00 Completed
+++ /dev/null
-1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 Start queue run: pid=pppp -qf
-1999-03-02 09:44:33 10HmaX-0005vi-00 H=the.local.host.name [ip4.ip4.ip4.ip4] TLS error on connection (certificate verification failed)
-1999-03-02 09:44:33 10HmaX-0005vi-00 TLS session failure: delivering unencrypted to the.local.host.name [ip4.ip4.ip4.ip4] (not in hosts_require_tls)
-1999-03-02 09:44:33 10HmaX-0005vi-00 => userr@test.ex R=client_r T=send_to_server_req_failname H=the.local.host.name [ip4.ip4.ip4.ip4] C="250 OK id=10HmbA-0005vi-00"
-1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaY-0005vi-00 => users@test.ex R=client_s T=send_to_server_req_passname H=server1.example.com [ip4.ip4.ip4.ip4] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=yes DN="CN=server1.example.com" C="250 OK id=10HmbB-0005vi-00"
-1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaZ-0005vi-00 => usert@test.ex R=client_t T=send_to_server_req_failcarryon H=the.local.host.name [ip4.ip4.ip4.ip4] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no DN="CN=server1.example.com" C="250 OK id=10HmbC-0005vi-00"
-1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
-1999-03-02 09:44:33 End queue run: pid=pppp -qf
-
-******** SERVER ********
-1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
-1999-03-02 09:44:33 TLS error on connection from the.local.host.name [ip4.ip4.ip4.ip4] (recv): A TLS fatal alert has been received.: Certificate is bad
-1999-03-02 09:44:33 TLS error on connection from the.local.host.name [ip4.ip4.ip4.ip4] (send): The specified session has been invalidated for some reason.
-1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtp S=sss id=E10HmaX-0005vi-00@myhost.test.ex
-1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=yes DN="C=UK,O=The Exim Maintainers,OU=Test Suite,CN=Phil Pennock" S=sss id=E10HmaY-0005vi-00@myhost.test.ex
-1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=yes DN="C=UK,O=The Exim Maintainers,OU=Test Suite,CN=Phil Pennock" S=sss id=E10HmaZ-0005vi-00@myhost.test.ex
+++ /dev/null
-1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 Start queue run: pid=pppp -qf
-1999-03-02 09:44:33 10HmaX-0005vi-00 SSL verify error: depth=0 error=unable to get local issuer certificate cert=/CN=server1.example.com
-1999-03-02 09:44:33 10HmaX-0005vi-00 H=the.local.host.name [ip4.ip4.ip4.ip4] TLS error on connection (SSL_connect): error: <<detail omitted>>
-1999-03-02 09:44:33 10HmaX-0005vi-00 TLS session failure: delivering unencrypted to the.local.host.name [ip4.ip4.ip4.ip4] (not in hosts_require_tls)
-1999-03-02 09:44:33 10HmaX-0005vi-00 => userq@test.ex R=client_q T=send_to_server_req_fail H=the.local.host.name [ip4.ip4.ip4.ip4] C="250 OK id=10HmbB-0005vi-00"
-1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaY-0005vi-00 SSL verify error: certificate name mismatch: "/CN=server1.example.com"
-
-1999-03-02 09:44:33 10HmaY-0005vi-00 H=the.local.host.name [ip4.ip4.ip4.ip4] TLS error on connection (SSL_connect): error: <<detail omitted>>
-1999-03-02 09:44:33 10HmaY-0005vi-00 TLS session failure: delivering unencrypted to the.local.host.name [ip4.ip4.ip4.ip4] (not in hosts_require_tls)
-1999-03-02 09:44:33 10HmaY-0005vi-00 => userr@test.ex R=client_r T=send_to_server_req_failname H=the.local.host.name [ip4.ip4.ip4.ip4] C="250 OK id=10HmbC-0005vi-00"
-1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaZ-0005vi-00 => users@test.ex R=client_s T=send_to_server_req_passname H=server1.example.com [ip4.ip4.ip4.ip4] X=TLSv1:AES256-SHA:256 CV=yes DN="/CN=server1.example.com" C="250 OK id=10HmbD-0005vi-00"
-1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbA-0005vi-00 SSL verify error: certificate name mismatch: "/CN=server1.example.com"
-
-1999-03-02 09:44:33 10HmbA-0005vi-00 => usert@test.ex R=client_t T=send_to_server_req_failcarryon H=the.local.host.name [ip4.ip4.ip4.ip4] X=TLSv1:AES256-SHA:256 CV=no DN="/CN=server1.example.com" C="250 OK id=10HmbE-0005vi-00"
-1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
-1999-03-02 09:44:33 End queue run: pid=pppp -qf
-
-******** SERVER ********
-1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
-1999-03-02 09:44:33 TLS error on connection from the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] (SSL_accept): error: <<detail omitted>>
-1999-03-02 09:44:33 TLS client disconnected cleanly (rejected our certificate?)
-1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtp S=sss id=E10HmaX-0005vi-00@myhost.test.ex
-1999-03-02 09:44:33 TLS error on connection from the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] (SSL_accept): error: <<detail omitted>>
-1999-03-02 09:44:33 TLS client disconnected cleanly (rejected our certificate?)
-1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtp S=sss id=E10HmaY-0005vi-00@myhost.test.ex
-1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLSv1:AES256-SHA:256 CV=yes DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" S=sss id=E10HmaZ-0005vi-00@myhost.test.ex
-1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLSv1:AES256-SHA:256 CV=yes DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" S=sss id=E10HmbA-0005vi-00@myhost.test.ex
1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 prdr_requested: <yes>
1999-03-02 09:44:33 10HmaY-0005vi-00 PRDR R=<userx@test.ex> acceptance
1999-03-02 09:44:33 10HmaY-0005vi-00 PRDR R=<usery@test.ex> temporary refusal
1999-03-02 09:44:33 10HmaY-0005vi-00 PRDR R=<userz@test.ex> refusal
1999-03-02 09:44:33 10HmaY-0005vi-00 <= <> H=(rhu.barb) [127.0.0.1] P=esmtp PRDR S=sss
1999-03-02 09:44:33 10HmaY-0005vi-00 => userx <userx@test.ex> R=r0 T=t1
1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
+1999-03-02 09:44:33 prdr_requested: <yes>
1999-03-02 09:44:33 10HmaX-0005vi-00 PRDR R=<userp@test.ex> acceptance
1999-03-02 09:44:33 10HmaX-0005vi-00 PRDR R=<userq@test.ex> acceptance
1999-03-02 09:44:33 10HmaX-0005vi-00 H=(rhu.barb) [127.0.0.1] F=<> rejected after DATA
+1999-03-02 09:44:33 prdr_requested: <yes>
1999-03-02 09:44:33 10HmaZ-0005vi-00 <= <> H=(rhu.barb) [127.0.0.1] P=esmtp S=sss
1999-03-02 09:44:33 10HmaZ-0005vi-00 => user1 <user1@test.ex> R=r0 T=t1
1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
+1999-03-02 09:44:33 prdr_requested: <yes>
1999-03-02 09:44:33 10HmbA-0005vi-00 PRDR R=<usery@test.ex> temporary refusal
1999-03-02 09:44:33 10HmbA-0005vi-00 PRDR R=<usery@test.ex> temporary refusal
+1999-03-02 09:44:33 prdr_requested: <yes>
1999-03-02 09:44:33 10HmbB-0005vi-00 PRDR R=<userz@test.ex> refusal
1999-03-02 09:44:33 10HmbB-0005vi-00 PRDR R=<userz@test.ex> refusal
+1999-03-02 09:44:33 prdr_requested: <no>
+1999-03-02 09:44:33 10HmbC-0005vi-00 <= <> H=(rhu.barb) [127.0.0.1] P=esmtp S=sss
+1999-03-02 09:44:33 10HmbC-0005vi-00 => userx <userx@test.ex> R=r0 T=t1
+1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
+1999-03-02 09:44:33 1: Server sends good staple on request
1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
1999-03-02 09:44:33 acl_conn: ocsp in status: 0 (notreq)
1999-03-02 09:44:33 acl_mail: ocsp in status: 4 (verified)
+1999-03-02 09:44:33 2: Server does not staple an outdated response
1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
1999-03-02 09:44:33 acl_conn: ocsp in status: 0 (notreq)
+1999-03-02 09:44:33 3: Server does not staple a response for a revoked cert
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 acl_conn: ocsp in status: 0 (notreq)
+1999-03-02 09:44:33 4: Connection functions when server is prepared to staple but client does not request it
1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
1999-03-02 09:44:33 acl_conn: ocsp in status: 0 (notreq)
+++ /dev/null
-1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmaX-0005vi-00 => norequire@test.ex R=client T=send_to_server2 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLSv1:AES256-SHA:256 CV=yes DN="/CN=server1.example.com" C="250 OK id=10HmaY-0005vi-00"
-1999-03-02 09:44:33 10HmaX-0005vi-00 client ocsp status: 1 (notresp)
-1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmaZ-0005vi-00 => norequire@test.ex R=client T=send_to_server2 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLSv1:AES256-SHA:256 CV=yes DN="/CN=server1.example.com" C="250 OK id=10HmbA-0005vi-00"
-1999-03-02 09:44:33 10HmaZ-0005vi-00 client ocsp status: 4 (verified)
-1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbB-0005vi-00 => nostaple@test.ex R=client T=send_to_server1 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLSv1:AES256-SHA:256 CV=yes DN="/CN=server1.example.com" C="250 OK id=10HmbC-0005vi-00"
-1999-03-02 09:44:33 10HmbB-0005vi-00 client ocsp status: 0 (notreq)
-1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbD-0005vi-00 => good@test.ex R=client T=send_to_server3 H=127.0.0.1 [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=yes DN="/CN=server1.example.com" C="250 OK id=10HmbE-0005vi-00"
-1999-03-02 09:44:33 10HmbD-0005vi-00 client ocsp status: 4 (verified)
-1999-03-02 09:44:33 10HmbD-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbF-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbF-0005vi-00 Received TLS status callback, null content
-1999-03-02 09:44:33 10HmbF-0005vi-00 H=127.0.0.1 [127.0.0.1] TLS error on connection (SSL_connect): error: <<detail omitted>>
-1999-03-02 09:44:33 10HmbF-0005vi-00 client ocsp status: 1 (notresp)
-1999-03-02 09:44:33 10HmbF-0005vi-00 == failrequire@test.ex R=client T=send_to_server3 defer (-37) H=127.0.0.1 [127.0.0.1]: failure while setting up TLS session
-1999-03-02 09:44:33 10HmbG-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbG-0005vi-00 Server certificate revoked; reason: superseded
-1999-03-02 09:44:33 10HmbG-0005vi-00 H=127.0.0.1 [127.0.0.1] TLS error on connection (SSL_connect): error: <<detail omitted>>
-1999-03-02 09:44:33 10HmbG-0005vi-00 client ocsp status: 3 (failed)
-1999-03-02 09:44:33 10HmbG-0005vi-00 == failrevoked@test.ex R=client T=send_to_server3 defer (-37) H=127.0.0.1 [127.0.0.1]: failure while setting up TLS session
-1999-03-02 09:44:33 10HmbH-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbH-0005vi-00 Server OSCP dates invalid
-1999-03-02 09:44:33 10HmbH-0005vi-00 H=127.0.0.1 [127.0.0.1] TLS error on connection (SSL_connect): error: <<detail omitted>>
-1999-03-02 09:44:33 10HmbH-0005vi-00 client ocsp status: 3 (failed)
-1999-03-02 09:44:33 10HmbH-0005vi-00 == failexpired@test.ex R=client T=send_to_server3 defer (-37) H=127.0.0.1 [127.0.0.1]: failure while setting up TLS session
-
-******** SERVER ********
-1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
-1999-03-02 09:44:33 10HmaY-0005vi-00 client claims: ocsp status 1
-1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@server1.example.com H=the.local.host.name (server1.example.com) [ip4.ip4.ip4.ip4] P=esmtps X=TLSv1:AES256-SHA:256 CV=no S=sss id=E10HmaX-0005vi-00@server1.example.com
-1999-03-02 09:44:33 10HmaY-0005vi-00 => :blackhole: <norequire@test.ex> R=server
-1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
-1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
-1999-03-02 09:44:33 10HmbA-0005vi-00 client claims: ocsp status 4
-1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@server1.example.com H=the.local.host.name (server1.example.com) [ip4.ip4.ip4.ip4] P=esmtps X=TLSv1:AES256-SHA:256 CV=no S=sss id=E10HmaZ-0005vi-00@server1.example.com
-1999-03-02 09:44:33 10HmbA-0005vi-00 => :blackhole: <norequire@test.ex> R=server
-1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbC-0005vi-00 client claims: ocsp status 0
-1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@server1.example.com H=the.local.host.name (server1.example.com) [ip4.ip4.ip4.ip4] P=esmtps X=TLSv1:AES256-SHA:256 CV=no S=sss id=E10HmbB-0005vi-00@server1.example.com
-1999-03-02 09:44:33 10HmbC-0005vi-00 => :blackhole: <nostaple@test.ex> R=server
-1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbE-0005vi-00 client claims: ocsp status 4
-1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@server1.example.com H=(helo.data.changed) [127.0.0.1] P=esmtps X=TLSv1:AES256-SHA:256 CV=no S=sss id=E10HmbD-0005vi-00@server1.example.com
-1999-03-02 09:44:33 10HmbE-0005vi-00 => :blackhole: <good@test.ex> R=server
-1999-03-02 09:44:33 10HmbE-0005vi-00 Completed
-1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
-1999-03-02 09:44:33 TLS error on connection from (helo.data.changed) [127.0.0.1] (SSL_accept): error: <<detail omitted>>
-1999-03-02 09:44:33 TLS client disconnected cleanly (rejected our certificate?)
-1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
-1999-03-02 09:44:33 TLS error on connection from (helo.data.changed) [127.0.0.1] (SSL_accept): error: <<detail omitted>>
-1999-03-02 09:44:33 TLS client disconnected cleanly (rejected our certificate?)
-1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
-1999-03-02 09:44:33 TLS error on connection from (helo.data.changed) [127.0.0.1] (SSL_accept): error: <<detail omitted>>
-1999-03-02 09:44:33 TLS client disconnected cleanly (rejected our certificate?)
+1999-03-02 09:44:33 1: Server sends good staple on request
1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
1999-03-02 09:44:33 acl_conn: ocsp in status: 0 (notreq)
1999-03-02 09:44:33 acl_mail: ocsp in status: 2 (vfynotdone)
+1999-03-02 09:44:33 2: Server does not staple an outdated response
1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
1999-03-02 09:44:33 acl_conn: ocsp in status: 0 (notreq)
1999-03-02 09:44:33 TLS error on connection from [ip4.ip4.ip4.ip4] (recv): The TLS connection was non-properly terminated.
1999-03-02 09:44:33 TLS error on connection from [ip4.ip4.ip4.ip4] (send): The specified session has been invalidated for some reason.
+1999-03-02 09:44:33 3: Server does not staple a response for a revoked cert
1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
1999-03-02 09:44:33 acl_conn: ocsp in status: 0 (notreq)
1999-03-02 09:44:33 TLS error on connection from [ip4.ip4.ip4.ip4] (recv): The TLS connection was non-properly terminated.
1999-03-02 09:44:33 TLS error on connection from [ip4.ip4.ip4.ip4] (send): The specified session has been invalidated for some reason.
+1999-03-02 09:44:33 4: Connection functions when server is prepared to staple but client does not request it
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 acl_conn: ocsp in status: 0 (notreq)
+++ /dev/null
-1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmaX-0005vi-00 => norequire@test.ex R=client T=send_to_server2 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=yes DN="CN=server1.example.com" C="250 OK id=10HmaY-0005vi-00"
-1999-03-02 09:44:33 10HmaX-0005vi-00 client ocsp status: 1 (notresp)
-1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmaZ-0005vi-00 => norequire@test.ex R=client T=send_to_server2 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=yes DN="CN=server1.example.com" C="250 OK id=10HmbA-0005vi-00"
-1999-03-02 09:44:33 10HmaZ-0005vi-00 client ocsp status: 1 (notresp)
-1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbB-0005vi-00 => nostaple@test.ex R=client T=send_to_server1 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=yes DN="CN=server1.example.com" C="250 OK id=10HmbC-0005vi-00"
-1999-03-02 09:44:33 10HmbB-0005vi-00 client ocsp status: 0 (notreq)
-1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbD-0005vi-00 => good@test.ex R=client T=send_to_server3 H=127.0.0.1 [127.0.0.1] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=yes DN="CN=server1.example.com" C="250 OK id=10HmbE-0005vi-00"
-1999-03-02 09:44:33 10HmbD-0005vi-00 client ocsp status: 4 (verified)
-1999-03-02 09:44:33 10HmbD-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbF-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbF-0005vi-00 H=127.0.0.1 [127.0.0.1] TLS error on connection (certificate status check failed)
-1999-03-02 09:44:33 10HmbF-0005vi-00 client ocsp status: 3 (failed)
-1999-03-02 09:44:33 10HmbF-0005vi-00 == failrequire@test.ex R=client T=send_to_server3 defer (-37) H=127.0.0.1 [127.0.0.1]: failure while setting up TLS session
-1999-03-02 09:44:33 10HmbG-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbG-0005vi-00 H=127.0.0.1 [127.0.0.1] TLS error on connection (certificate verification failed): certificate revoked
-1999-03-02 09:44:33 10HmbG-0005vi-00 client ocsp status: 1 (notresp)
-1999-03-02 09:44:33 10HmbG-0005vi-00 == failrevoked@test.ex R=client T=send_to_server3 defer (-37) H=127.0.0.1 [127.0.0.1]: failure while setting up TLS session
-1999-03-02 09:44:33 10HmbH-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbH-0005vi-00 H=127.0.0.1 [127.0.0.1] TLS error on connection (certificate status check failed)
-1999-03-02 09:44:33 10HmbH-0005vi-00 client ocsp status: 3 (failed)
-1999-03-02 09:44:33 10HmbH-0005vi-00 == failexpired@test.ex R=client T=send_to_server3 defer (-37) H=127.0.0.1 [127.0.0.1]: failure while setting up TLS session
-
-******** SERVER ********
-1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
-1999-03-02 09:44:33 10HmaY-0005vi-00 client claims: OCSP status 1 (notresp)
-1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@server1.example.com H=the.local.host.name (server1.example.com) [ip4.ip4.ip4.ip4] P=esmtps X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no S=sss id=E10HmaX-0005vi-00@server1.example.com
-1999-03-02 09:44:33 10HmaY-0005vi-00 => :blackhole: <norequire@test.ex> R=server
-1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
-1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
-1999-03-02 09:44:33 10HmbA-0005vi-00 client claims: OCSP status 1 (notresp)
-1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@server1.example.com H=the.local.host.name (server1.example.com) [ip4.ip4.ip4.ip4] P=esmtps X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no S=sss id=E10HmaZ-0005vi-00@server1.example.com
-1999-03-02 09:44:33 10HmbA-0005vi-00 => :blackhole: <norequire@test.ex> R=server
-1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbC-0005vi-00 client claims: OCSP status 0 (notreq)
-1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@server1.example.com H=the.local.host.name (server1.example.com) [ip4.ip4.ip4.ip4] P=esmtps X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no S=sss id=E10HmbB-0005vi-00@server1.example.com
-1999-03-02 09:44:33 10HmbC-0005vi-00 => :blackhole: <nostaple@test.ex> R=server
-1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbE-0005vi-00 client claims: OCSP status 4 (verified)
-1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@server1.example.com H=(helo.data.changed) [127.0.0.1] P=esmtps X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no S=sss id=E10HmbD-0005vi-00@server1.example.com
-1999-03-02 09:44:33 10HmbE-0005vi-00 => :blackhole: <good@test.ex> R=server
-1999-03-02 09:44:33 10HmbE-0005vi-00 Completed
-1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
-1999-03-02 09:44:33 TLS error on connection from [127.0.0.1] (recv): The TLS connection was non-properly terminated.
-1999-03-02 09:44:33 TLS error on connection from [127.0.0.1] (send): The specified session has been invalidated for some reason.
-1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
-1999-03-02 09:44:33 TLS error on connection from [127.0.0.1] (recv): A TLS fatal alert has been received.: Certificate is bad
-1999-03-02 09:44:33 TLS error on connection from [127.0.0.1] (send): The specified session has been invalidated for some reason.
-1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
-1999-03-02 09:44:33 TLS error on connection from [127.0.0.1] (recv): The TLS connection was non-properly terminated.
-1999-03-02 09:44:33 TLS error on connection from [127.0.0.1] (send): The specified session has been invalidated for some reason.
1999-03-02 09:44:33 10HmaZ-0005vi-00 . [127.0.0.1] -> [127.0.0.1]:1224
1999-03-02 09:44:33 10HmaZ-0005vi-00 H=127.0.0.1 [127.0.0.1]: SMTP timeout after EHLO the.local.host.name: Connection timed out
1999-03-02 09:44:33 10HmaZ-0005vi-00 event msg:host:defer
-1999-03-02 09:44:33 10HmaZ-0005vi-00 . deferral ip <127.0.0.1> port <1224> fqdn <127.0.0.1> local_part <userx> domain <domain1> errno <110> errstr <SMTP timeout after EHLO the.local.host.name: Connection timed out> router <others> transport <smtp>
+1999-03-02 09:44:33 10HmaZ-0005vi-00 . host deferral ip <127.0.0.1> port <1224> fqdn <127.0.0.1> local_part <userx> domain <domain1> errno <110> errstr <SMTP timeout after EHLO the.local.host.name: Connection timed out> router <others> transport <smtp>
1999-03-02 09:44:33 10HmaZ-0005vi-00 == userx@domain1 R=others T=smtp defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after EHLO the.local.host.name
1999-03-02 09:44:33 10HmaZ-0005vi-00 ** userx@domain1: retry timeout exceeded
-1999-03-02 09:44:33 10HmbA-0005vi-00 <= <> R=10HmaZ-0005vi-00 U=EXIMUSER P=local S=sss
-1999-03-02 09:44:33 10HmbA-0005vi-00 => :blackhole: <CALLER@the.local.host.name> R=dump_bounces
-1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbA-0005vi-00 event msg:complete
-1999-03-02 09:44:33 10HmbA-0005vi-00 . finished: 10HmbA-0005vi-00
+1999-03-02 09:44:33 10HmaZ-0005vi-00 userx@domain1: error ignored
1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
1999-03-02 09:44:33 10HmaZ-0005vi-00 event msg:complete
1999-03-02 09:44:33 10HmaZ-0005vi-00 . finished: 10HmaZ-0005vi-00
+1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss
+1999-03-02 09:44:33 Start queue run: pid=pppp -qqf
+1999-03-02 09:44:33 10HmbA-0005vi-00 event tcp:connect
+1999-03-02 09:44:33 10HmbA-0005vi-00 . [127.0.0.1]:1111
+1999-03-02 09:44:33 10HmbA-0005vi-00 event smtp:connect
+1999-03-02 09:44:33 10HmbA-0005vi-00 . [127.0.0.1] -> [127.0.0.1]:1224
+1999-03-02 09:44:33 10HmbA-0005vi-00 . banner <220 ESMTP>
+1999-03-02 09:44:33 10HmbA-0005vi-00 event msg:rcpt:host:defer
+1999-03-02 09:44:33 10HmbA-0005vi-00 event msg:rcpt:defer
+1999-03-02 09:44:33 10HmbA-0005vi-00 . rcpt deferral ip <127.0.0.1> port <1224> fqdn <127.0.0.1> local_part <userx> domain <domain1> err <12865>:<A:450> errstr <SMTP error from remote mail server after RCPT TO:<userx@domain1>: 450 NOT RIGHT NOW> router <others> transport <smtp>
+1999-03-02 09:44:33 10HmbA-0005vi-00 event tcp:close
+1999-03-02 09:44:33 10HmbA-0005vi-00 . [127.0.0.1] -> [127.0.0.1]:1224
+1999-03-02 09:44:33 10HmbA-0005vi-00 == userx@domain1 R=others T=smtp defer (-44) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:<userx@domain1>: 450 NOT RIGHT NOW
+1999-03-02 09:44:33 10HmbA-0005vi-00 ** userx@domain1: retry timeout exceeded
+1999-03-02 09:44:33 10HmbA-0005vi-00 userx@domain1: error ignored
+1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbA-0005vi-00 event msg:complete
+1999-03-02 09:44:33 10HmbA-0005vi-00 . finished: 10HmbA-0005vi-00
+1999-03-02 09:44:33 End queue run: pid=pppp -qqf
1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss
1999-03-02 09:44:33 Start queue run: pid=pppp -qqf
1999-03-02 09:44:33 10HmbB-0005vi-00 event tcp:connect
1999-03-02 09:44:33 10HmbB-0005vi-00 ** userx@domain1 R=others T=smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:<userx@domain1>: 550 GO AWAY
1999-03-02 09:44:33 10HmbB-0005vi-00 event msg:fail:delivery
1999-03-02 09:44:33 10HmbB-0005vi-00 . refused by fdqn <127.0.0.1> local_part <userx> domain <domain1>
-1999-03-02 09:44:33 10HmbC-0005vi-00 <= <> R=10HmbB-0005vi-00 U=EXIMUSER P=local S=sss
-1999-03-02 09:44:33 10HmbC-0005vi-00 => :blackhole: <CALLER@the.local.host.name> R=dump_bounces
-1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbC-0005vi-00 event msg:complete
-1999-03-02 09:44:33 10HmbC-0005vi-00 . finished: 10HmbC-0005vi-00
+1999-03-02 09:44:33 10HmbB-0005vi-00 userx@domain1: error ignored
1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
1999-03-02 09:44:33 10HmbB-0005vi-00 event msg:complete
1999-03-02 09:44:33 10HmbB-0005vi-00 . finished: 10HmbB-0005vi-00
1999-03-02 09:44:33 End queue run: pid=pppp -qqf
-1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbD-0005vi-00 cancelled by CALLER
-1999-03-02 09:44:33 10HmbD-0005vi-00 event msg:fail:internal
-1999-03-02 09:44:33 10HmbD-0005vi-00 . local_part <userx> domain <domain1> reason <delivery cancelled by administrator>
-1999-03-02 09:44:33 10HmbE-0005vi-00 <= <> R=10HmbD-0005vi-00 U=EXIMUSER P=local S=sss
-1999-03-02 09:44:33 10HmbE-0005vi-00 => :blackhole: <CALLER@the.local.host.name> R=dump_bounces
-1999-03-02 09:44:33 10HmbE-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbE-0005vi-00 event msg:complete
-1999-03-02 09:44:33 10HmbE-0005vi-00 . finished: 10HmbE-0005vi-00
+1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmbC-0005vi-00 cancelled by CALLER
+1999-03-02 09:44:33 10HmbC-0005vi-00 event msg:fail:internal
+1999-03-02 09:44:33 10HmbC-0005vi-00 . local_part <userx> domain <domain1> reason <delivery cancelled by administrator>
+1999-03-02 09:44:33 10HmbD-0005vi-00 <= <> R=10HmbC-0005vi-00 U=EXIMUSER P=local S=sss
+1999-03-02 09:44:33 10HmbD-0005vi-00 => :blackhole: <CALLER@the.local.host.name> R=dump_bounces
1999-03-02 09:44:33 10HmbD-0005vi-00 Completed
1999-03-02 09:44:33 10HmbD-0005vi-00 event msg:complete
1999-03-02 09:44:33 10HmbD-0005vi-00 . finished: 10HmbD-0005vi-00
+1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbC-0005vi-00 event msg:complete
+1999-03-02 09:44:33 10HmbC-0005vi-00 . finished: 10HmbC-0005vi-00
+++ /dev/null
-1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 Start queue run: pid=pppp -qf
-1999-03-02 09:44:33 10HmaX-0005vi-00 tls:cert depth=0 <CN=server1.example.com>
-1999-03-02 09:44:33 10HmaX-0005vi-00 H=127.0.0.1 [127.0.0.1] TLS error on connection (certificate verification failed): certificate invalid
-1999-03-02 09:44:33 10HmaX-0005vi-00 msg:host:defer bad
-1999-03-02 09:44:33 10HmaX-0005vi-00 NO CLIENT CERT presented
-1999-03-02 09:44:33 10HmaX-0005vi-00 Peer cert:
-1999-03-02 09:44:33 10HmaX-0005vi-00 ver <3>
-1999-03-02 09:44:33 10HmaX-0005vi-00 SN <CN=server1.example.com>
-1999-03-02 09:44:33 10HmaX-0005vi-00 IN <O=example.com,CN=clica Signing Cert>
-1999-03-02 09:44:33 10HmaX-0005vi-00 NB <Nov 1 12:34:05 2012 GMT>
-1999-03-02 09:44:33 10HmaX-0005vi-00 NA <Jan 1 12:34:05 2038 GMT>
-1999-03-02 09:44:33 10HmaX-0005vi-00 SA <RSA-SHA>
-1999-03-02 09:44:33 10HmaX-0005vi-00 SG <56 3a a4 3c cb eb b8 27 c2 90 08 74 13 88 dc 48 c6 b5 2c e5 26 be 5b 91 d4 67 e7 3c 49 12 d7 47 30 df 98 db 58 ed 18 a8 7d 4b db 97 48 f5 5c 7f 70 b9 37 63 33 f1 24 62 72 92 60 f5 6e da b6 bc 73 c8 c2 dc d6 95 9a bd 16 16 a2 ef 0a f1 d7 41 68 f6 ad 98 5a d0 ff d9 1b 51 9f 59 ce 2f 3d 84 d0 ee e8 2b eb 9b 32 1a 0e 02 3e cc 30 89 44 09 2a 75 81 46 a7 b6 ed 7d 41 eb 5a 63 fa 9c 58 ef>
-1999-03-02 09:44:33 10HmaX-0005vi-00 SAN <DNS=alternatename.server1.example.com\nDNS=alternatename2.server1.example.com\nDNS=server1.example.com>
-1999-03-02 09:44:33 10HmaX-0005vi-00 CRU <http://crl.example.com/latest.crl>
-1999-03-02 09:44:33 10HmaX-0005vi-00 TLS session failure: delivering unencrypted to 127.0.0.1 [127.0.0.1] (not in hosts_require_tls)
-1999-03-02 09:44:33 10HmaX-0005vi-00 => bad@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1] C="250 OK id=10HmaZ-0005vi-00"
-1999-03-02 09:44:33 10HmaX-0005vi-00 msg:delivery bad
-1999-03-02 09:44:33 10HmaX-0005vi-00 NO CLIENT CERT presented
-1999-03-02 09:44:33 10HmaX-0005vi-00 No Peer cert
-1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaY-0005vi-00 tls:cert depth=0 <CN=server1.example.com>
-1999-03-02 09:44:33 10HmaY-0005vi-00 => good@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=yes DN="CN=server1.example.com" C="250 OK id=10HmbA-0005vi-00"
-1999-03-02 09:44:33 10HmaY-0005vi-00 msg:delivery good
-1999-03-02 09:44:33 10HmaY-0005vi-00 Our cert SN: CN=server2.example.com
-1999-03-02 09:44:33 10HmaY-0005vi-00 Peer cert:
-1999-03-02 09:44:33 10HmaY-0005vi-00 ver <3>
-1999-03-02 09:44:33 10HmaY-0005vi-00 SN <CN=server1.example.com>
-1999-03-02 09:44:33 10HmaY-0005vi-00 IN <O=example.com,CN=clica Signing Cert>
-1999-03-02 09:44:33 10HmaY-0005vi-00 NB <Nov 1 12:34:05 2012 GMT>
-1999-03-02 09:44:33 10HmaY-0005vi-00 NA <Jan 1 12:34:05 2038 GMT>
-1999-03-02 09:44:33 10HmaY-0005vi-00 SA <RSA-SHA>
-1999-03-02 09:44:33 10HmaY-0005vi-00 SG <56 3a a4 3c cb eb b8 27 c2 90 08 74 13 88 dc 48 c6 b5 2c e5 26 be 5b 91 d4 67 e7 3c 49 12 d7 47 30 df 98 db 58 ed 18 a8 7d 4b db 97 48 f5 5c 7f 70 b9 37 63 33 f1 24 62 72 92 60 f5 6e da b6 bc 73 c8 c2 dc d6 95 9a bd 16 16 a2 ef 0a f1 d7 41 68 f6 ad 98 5a d0 ff d9 1b 51 9f 59 ce 2f 3d 84 d0 ee e8 2b eb 9b 32 1a 0e 02 3e cc 30 89 44 09 2a 75 81 46 a7 b6 ed 7d 41 eb 5a 63 fa 9c 58 ef>
-1999-03-02 09:44:33 10HmaY-0005vi-00 SAN <DNS=alternatename.server1.example.com\nDNS=alternatename2.server1.example.com\nDNS=server1.example.com>
-1999-03-02 09:44:33 10HmaY-0005vi-00 CRU <http://crl.example.com/latest.crl>
-1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
-1999-03-02 09:44:33 End queue run: pid=pppp -qf
-
-******** SERVER ********
-1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
-1999-03-02 09:44:33 [127.0.0.1] depth=0 CN=server2.example.com
-1999-03-02 09:44:33 TLS error on connection from localhost [127.0.0.1] (recv): A TLS fatal alert has been received.: Certificate is bad
-1999-03-02 09:44:33 TLS error on connection from localhost [127.0.0.1] (send): The specified session has been invalidated for some reason.
-1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmaX-0005vi-00@myhost.test.ex
-1999-03-02 09:44:33 [127.0.0.1] depth=0 CN=server2.example.com
-1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtps X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=yes DN="CN=server2.example.com" S=sss id=E10HmaY-0005vi-00@myhost.test.ex
+++ /dev/null
-1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 Start queue run: pid=pppp -qf
-1999-03-02 09:44:33 10HmaX-0005vi-00 SSL verify error: depth=2 error=self signed certificate in certificate chain cert=/O=example.com/CN=clica CA
-1999-03-02 09:44:33 10HmaX-0005vi-00 H=127.0.0.1 [127.0.0.1] TLS error on connection (SSL_connect): error: <<detail omitted>>
-1999-03-02 09:44:33 10HmaX-0005vi-00 msg:host:defer bad
-1999-03-02 09:44:33 10HmaX-0005vi-00 NO CLIENT CERT presented
-1999-03-02 09:44:33 10HmaX-0005vi-00 Peer cert:
-1999-03-02 09:44:33 10HmaX-0005vi-00 ver <2>
-1999-03-02 09:44:33 10HmaX-0005vi-00 SN <CN=clica CA,O=example.com>
-1999-03-02 09:44:33 10HmaX-0005vi-00 IN <CN=clica CA,O=example.com>
-1999-03-02 09:44:33 10HmaX-0005vi-00 NB <Nov 1 12:34:04 2012 +0000>
-1999-03-02 09:44:33 10HmaX-0005vi-00 NA <Jan 1 12:34:04 2038 +0000>
-1999-03-02 09:44:33 10HmaX-0005vi-00 SA <sha1WithRSAEncryption>
-1999-03-02 09:44:33 10HmaX-0005vi-00 SG < 89:fd:fb:cb:b2:42:d6:aa:f2:c0:44:a2:14:e5:ab:22:50:41:\n e6:64:e7:1c:5a:20:b6:0f:fe:b0:88:c5:cf:b3:e5:f8:0e:87:\n eb:ac:07:d6:9d:6a:20:f6:dd:13:ee:b8:3f:cf:d9:cd:d4:a8:\n 72:50:5a:a2:14:4e:ee:3a:78:e2:a7:f4:ae:d7:ee:77:48:1f:\n 75:a7:68:2f:ee:e2:7c:ac:2f:e4:88:02:e8:3b:db:f9:35:04:\n 05:46:35:0b:f2:35:03:21:b6:1e:82:7d:94:e0:63:4b:60:71:\n 2d:19:45:21:f2:85:b4:c3:d0:77:a2:24:32:36:f3:50:68:38:\n 98:e6\n>
-1999-03-02 09:44:33 10HmaX-0005vi-00 (no SAN)
-1999-03-02 09:44:33 10HmaX-0005vi-00 (no OCU)
-1999-03-02 09:44:33 10HmaX-0005vi-00 (no CRU)
-1999-03-02 09:44:33 10HmaX-0005vi-00 TLS session failure: delivering unencrypted to 127.0.0.1 [127.0.0.1] (not in hosts_require_tls)
-1999-03-02 09:44:33 10HmaX-0005vi-00 => bad@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1] C="250 OK id=10HmaZ-0005vi-00"
-1999-03-02 09:44:33 10HmaX-0005vi-00 msg:delivery bad
-1999-03-02 09:44:33 10HmaX-0005vi-00 NO CLIENT CERT presented
-1999-03-02 09:44:33 10HmaX-0005vi-00 No Peer cert
-1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaY-0005vi-00 tls:cert depth=2 <CN=clica CA,O=example.com>
-1999-03-02 09:44:33 10HmaY-0005vi-00 tls:cert depth=1 <CN=clica Signing Cert,O=example.com>
-1999-03-02 09:44:33 10HmaY-0005vi-00 tls:cert depth=0 <CN=server1.example.com>
-1999-03-02 09:44:33 10HmaY-0005vi-00 => good@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=yes DN="/CN=server1.example.com" C="250 OK id=10HmbA-0005vi-00"
-1999-03-02 09:44:33 10HmaY-0005vi-00 msg:delivery good
-1999-03-02 09:44:33 10HmaY-0005vi-00 Our cert SN: CN=server2.example.com
-1999-03-02 09:44:33 10HmaY-0005vi-00 Peer cert:
-1999-03-02 09:44:33 10HmaY-0005vi-00 ver <2>
-1999-03-02 09:44:33 10HmaY-0005vi-00 SN <CN=server1.example.com>
-1999-03-02 09:44:33 10HmaY-0005vi-00 IN <CN=clica Signing Cert,O=example.com>
-1999-03-02 09:44:33 10HmaY-0005vi-00 NB <Nov 1 12:34:05 2012 +0000>
-1999-03-02 09:44:33 10HmaY-0005vi-00 NA <Jan 1 12:34:05 2038 +0000>
-1999-03-02 09:44:33 10HmaY-0005vi-00 SA <sha1WithRSAEncryption>
-1999-03-02 09:44:33 10HmaY-0005vi-00 SG < 56:3a:a4:3c:cb:eb:b8:27:c2:90:08:74:13:88:dc:48:c6:b5:\n 2c:e5:26:be:5b:91:d4:67:e7:3c:49:12:d7:47:30:df:98:db:\n 58:ed:18:a8:7d:4b:db:97:48:f5:5c:7f:70:b9:37:63:33:f1:\n 24:62:72:92:60:f5:6e:da:b6:bc:73:c8:c2:dc:d6:95:9a:bd:\n 16:16:a2:ef:0a:f1:d7:41:68:f6:ad:98:5a:d0:ff:d9:1b:51:\n 9f:59:ce:2f:3d:84:d0:ee:e8:2b:eb:9b:32:1a:0e:02:3e:cc:\n 30:89:44:09:2a:75:81:46:a7:b6:ed:7d:41:eb:5a:63:fa:9c:\n 58:ef\n>
-1999-03-02 09:44:33 10HmaY-0005vi-00 SAN <DNS=server1.example.com;DNS=alternatename2.server1.example.com;DNS=alternatename.server1.example.com>
-1999-03-02 09:44:33 10HmaY-0005vi-00 OCU <http://oscp/example.com/>
-1999-03-02 09:44:33 10HmaY-0005vi-00 CRU <http://crl.example.com/latest.crl>
-1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
-1999-03-02 09:44:33 End queue run: pid=pppp -qf
-
-******** SERVER ********
-1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
-1999-03-02 09:44:33 TLS error on connection from localhost (myhost.test.ex) [127.0.0.1] (SSL_accept): error: <<detail omitted>>
-1999-03-02 09:44:33 TLS client disconnected cleanly (rejected our certificate?)
-1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmaX-0005vi-00@myhost.test.ex
-1999-03-02 09:44:33 [127.0.0.1] depth=2 CN=clica CA,O=example.com
-1999-03-02 09:44:33 [127.0.0.1] depth=1 CN=clica Signing Cert,O=example.com
-1999-03-02 09:44:33 [127.0.0.1] depth=0 CN=server2.example.com
-1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtps X=TLSv1:AES256-SHA:256 CV=yes DN="/CN=server2.example.com" S=sss id=E10HmaY-0005vi-00@myhost.test.ex
1999-03-02 09:44:33 10HmbB-0005vi-00 => CALLER@mxdane256ta.test.ex R=client T=send_to_server H=dane256ta.test.ex [ip4.ip4.ip4.ip4] X=TLSv1:AES256-SHA:256 CV=dane DN="/CN=server1.example.com" C="250 OK id=10HmbC-0005vi-00"
1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
1999-03-02 09:44:33 End queue run: pid=pppp -qf
+1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for CALLER@thishost.test.ex
+1999-03-02 09:44:33 Start queue run: pid=pppp -qf
+1999-03-02 09:44:33 10HmbD-0005vi-00 [127.0.0.1] SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
+1999-03-02 09:44:33 10HmbD-0005vi-00 [127.0.0.1] SSL verify error: certificate name mismatch: "/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock"
+1999-03-02 09:44:33 10HmbD-0005vi-00 => CALLER@thishost.test.ex R=client T=send_to_server H=thishost.test.ex [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" C="250 OK id=10HmbE-0005vi-00"
+1999-03-02 09:44:33 10HmbD-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp -qf
+1999-03-02 09:44:33 10HmbF-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for CALLER@thishost.test.ex
+1999-03-02 09:44:33 Start queue run: pid=pppp -qf
+1999-03-02 09:44:33 10HmbF-0005vi-00 => CALLER@thishost.test.ex R=client T=send_to_server H=thishost.test.ex [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=yes DN="/CN=server1.example.com" C="250 OK id=10HmbG-0005vi-00"
+1999-03-02 09:44:33 10HmbF-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp -qf
+1999-03-02 09:44:33 10HmbH-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for CALLER@mxdanelazy.test.ex
+1999-03-02 09:44:33 10HmbI-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for CALLER@dane.no.1.test.ex
+1999-03-02 09:44:33 10HmbJ-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for CALLER@dane.no.2.test.ex
+1999-03-02 09:44:33 Start queue run: pid=pppp -qf
+1999-03-02 09:44:33 10HmbH-0005vi-00 H=danelazy.test.ex [ip4.ip4.ip4.ip4]: DANE error: tlsa lookup DEFER
+1999-03-02 09:44:33 10HmbH-0005vi-00 [127.0.0.1] SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
+1999-03-02 09:44:33 10HmbH-0005vi-00 [127.0.0.1] SSL verify error: certificate name mismatch: "/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock"
+1999-03-02 09:44:33 10HmbH-0005vi-00 => CALLER@mxdanelazy.test.ex R=client T=send_to_server H=danelazy2.test.ex [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" C="250 OK id=10HmbK-0005vi-00"
+1999-03-02 09:44:33 10HmbH-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbI-0005vi-00 ** CALLER@dane.no.1.test.ex R=client T=send_to_server: DANE error: tlsa lookup FAIL
+1999-03-02 09:44:33 10HmbL-0005vi-00 <= <> R=10HmbI-0005vi-00 U=EXIMUSER P=local S=sss for CALLER@myhost.test.ex
+1999-03-02 09:44:33 10HmbL-0005vi-00 H=myhost.test.ex [V4NET.10.10.10] Network Error
+1999-03-02 09:44:33 10HmbL-0005vi-00 == CALLER@myhost.test.ex R=client T=send_to_server defer (dd): Network Error
+1999-03-02 09:44:33 10HmbI-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbJ-0005vi-00 [127.0.0.1] SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
+1999-03-02 09:44:33 10HmbJ-0005vi-00 [127.0.0.1] SSL verify error: certificate name mismatch: "/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock"
+1999-03-02 09:44:33 10HmbJ-0005vi-00 => CALLER@dane.no.2.test.ex R=client T=send_to_server H=dane.no.2.test.ex [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no DN="/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" C="250 OK id=10HmbM-0005vi-00"
+1999-03-02 09:44:33 10HmbJ-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp -qf
******** SERVER ********
1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLSv1:AES256-SHA:256 CV=no S=sss id=E10HmaX-0005vi-00@myhost.test.ex for CALLER@dane256ee.test.ex
-1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLSv1:AES256-SHA:256 CV=no S=sss id=E10HmaY-0005vi-00@myhost.test.ex for CALLER@mxdane512ee.test.ex
-1999-03-02 09:44:33 Start queue run: pid=pppp -qf
1999-03-02 09:44:33 10HmaZ-0005vi-00 => :blackhole: <CALLER@dane256ee.test.ex> R=server
1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLSv1:AES256-SHA:256 CV=no S=sss id=E10HmaY-0005vi-00@myhost.test.ex for CALLER@mxdane512ee.test.ex
1999-03-02 09:44:33 10HmbA-0005vi-00 => :blackhole: <CALLER@mxdane512ee.test.ex> R=server
1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
-1999-03-02 09:44:33 End queue run: pid=pppp -qf
1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLSv1:AES256-SHA:256 CV=no S=sss id=E10HmbB-0005vi-00@myhost.test.ex for CALLER@mxdane256ta.test.ex
-1999-03-02 09:44:33 Start queue run: pid=pppp -qf
1999-03-02 09:44:33 10HmbC-0005vi-00 => :blackhole: <CALLER@mxdane256ta.test.ex> R=server
1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
-1999-03-02 09:44:33 End queue run: pid=pppp -qf
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtps X=TLSv1:AES256-SHA:256 CV=no S=sss id=E10HmbD-0005vi-00@myhost.test.ex for CALLER@thishost.test.ex
+1999-03-02 09:44:33 10HmbE-0005vi-00 => :blackhole: <CALLER@thishost.test.ex> R=server
+1999-03-02 09:44:33 10HmbE-0005vi-00 Completed
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 10HmbG-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtps X=TLSv1:AES256-SHA:256 CV=no S=sss id=E10HmbF-0005vi-00@myhost.test.ex for CALLER@thishost.test.ex
+1999-03-02 09:44:33 10HmbG-0005vi-00 => :blackhole: <CALLER@thishost.test.ex> R=server
+1999-03-02 09:44:33 10HmbG-0005vi-00 Completed
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 10HmbK-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtps X=TLSv1:AES256-SHA:256 CV=no S=sss id=E10HmbH-0005vi-00@myhost.test.ex for CALLER@mxdanelazy.test.ex
+1999-03-02 09:44:33 10HmbK-0005vi-00 => :blackhole: <CALLER@mxdanelazy.test.ex> R=server
+1999-03-02 09:44:33 10HmbK-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbM-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtps X=TLSv1:AES256-SHA:256 CV=no S=sss id=E10HmbJ-0005vi-00@myhost.test.ex for CALLER@dane.no.2.test.ex
+1999-03-02 09:44:33 10HmbM-0005vi-00 => :blackhole: <CALLER@dane.no.2.test.ex> R=server
+1999-03-02 09:44:33 10HmbM-0005vi-00 Completed
1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for CALLER@mxdane256ta.test.ex
1999-03-02 09:44:33 Start queue run: pid=pppp -qf
1999-03-02 09:44:33 10HmbB-0005vi-00 tls:cert depth = 2 <CN=clica CA,O=example.com>
-1999-03-02 09:44:33 10HmbB-0005vi-00 tls:cert depth = 0 <CN=server1.example.com>
-1999-03-02 09:44:33 10HmbB-0005vi-00 tls:cert depth = 2 <CN=clica CA,O=example.com>
1999-03-02 09:44:33 10HmbB-0005vi-00 tls:cert depth = 1 <CN=clica Signing Cert,O=example.com>
1999-03-02 09:44:33 10HmbB-0005vi-00 tls:cert depth = 0 <CN=server1.example.com>
1999-03-02 09:44:33 10HmbB-0005vi-00 => CALLER@mxdane256ta.test.ex R=client T=send_to_server H=dane256ta.test.ex [ip4.ip4.ip4.ip4] X=TLSv1:AES256-SHA:256 CV=dane DN="/CN=server1.example.com" C="250 OK id=10HmbC-0005vi-00"
From x@y Tue Mar 02 09:44:33 1999
Received: from CALLER by myhost.test.ex with local-smtp (Exim x.yz)
(envelope-from <x@y>)
- id 10HmbE-0005vi-00
+ id 10HmbF-0005vi-00
for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-Message-Id: <E10HmbE-0005vi-00@myhost.test.ex>
+Message-Id: <E10HmbF-0005vi-00@myhost.test.ex>
From: x@y
Date: Tue, 2 Mar 1999 09:44:33 +0000
X-warning: this is a test warning
From x@y Tue Mar 02 09:44:33 1999
Received: from CALLER by myhost.test.ex with local-smtp (Exim x.yz)
(envelope-from <x@y>)
- id 10HmbF-0005vi-00
+ id 10HmbG-0005vi-00
for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
to: group name: x@y, p@q;
reply-to: group name: a@b, c@d;
-Message-Id: <E10HmbF-0005vi-00@myhost.test.ex>
+Message-Id: <E10HmbG-0005vi-00@myhost.test.ex>
From: x@y
Date: Tue, 2 Mar 1999 09:44:33 +0000
X-warning: this is a test warning
From MAILER-DAEMON Tue Mar 02 09:44:33 1999
Received: from CALLER by myhost.test.ex with local-smtp (Exim x.yz)
- id 10HmbG-0005vi-00
+ id 10HmbH-0005vi-00
for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
to: group name: x@y, p@q;
reply-to: group name:;
from: userx@test.ex
-Message-Id: <E10HmbG-0005vi-00@myhost.test.ex>
+Message-Id: <E10HmbH-0005vi-00@myhost.test.ex>
Date: Tue, 2 Mar 1999 09:44:33 +0000
X-warning: this is a test warning
Action: failed
Final-Recipient: rfc822;userx@test.ex
Status: 5.0.0
+
Action: failed
Final-Recipient: rfc822;abcd@test.ex
Status: 5.0.0
+
Action: failed
Final-Recipient: rfc822;usery@test.ex
Status: 5.0.0
This is a test message.
+From jc@rome Tue Mar 02 09:44:33 1999
+Return-path: <jc@rome>
+Envelope-to: userx@test.x
+Delivery-date: Tue, 2 Mar 1999 09:44:33 +0000
+Received: from jc44bc by the.local.host.name with local (Exim x.yz)
+ (envelope-from <jc@rome>)
+ id 10HmaY-0005vi-00
+ for userx@test.x; Tue, 2 Mar 1999 09:44:33 +0000
+Message-Id: <E10HmaY-0005vi-00@the.local.host.name>
+From: Julius Caesar <jc@rome>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+X-interface:
+
+This is a test message.
+
Action: delayed
Final-Recipient: rfc822;|/non/existing/file
Status: 4.0.0
+
Action: delayed
Final-Recipient: rfc822;defer@test.ex
Status: 4.0.0
Action: delayed
Final-Recipient: rfc822;defer@test.ex
Status: 4.0.0
+
Action: delayed
Final-Recipient: rfc822;defer@another.test.ex
Status: 4.0.0
Action: delayed
Final-Recipient: rfc822;|/non/existing/file
Status: 4.0.0
+
Action: delayed
Final-Recipient: rfc822;defer@test.ex
Status: 4.0.0
Action: delayed
Final-Recipient: rfc822;|/non/existing/file
Status: 4.0.0
+
Action: delayed
Final-Recipient: rfc822;defer@test.ex
Status: 4.0.0
Action: delayed
Final-Recipient: rfc822;defer@test.ex
Status: 4.0.0
+
Action: delayed
Final-Recipient: rfc822;defer@another.test.ex
Status: 4.0.0
Action: failed
Final-Recipient: rfc822;userz@myhost.test.ex
Status: 5.0.0
+
Action: failed
Final-Recipient: rfc822;usery@myhost.test.ex
Status: 5.0.0
+
Action: failed
Final-Recipient: rfc822;userx@myhost.test.ex
Status: 5.0.0
Action: failed
Final-Recipient: rfc822;three@myhost.test.ex
Status: 5.0.0
+
Action: failed
Final-Recipient: rfc822;two@myhost.test.ex
Status: 5.0.0
+
Action: failed
Final-Recipient: rfc822;one@myhost.test.ex
Status: 5.0.0
+
Action: failed
Final-Recipient: rfc822;six@myhost.test.ex
Status: 5.0.0
+
Action: failed
Final-Recipient: rfc822;five@myhost.test.ex
Status: 5.0.0
+
Action: failed
Final-Recipient: rfc822;four@myhost.test.ex
Status: 5.0.0
+
Action: failed
Final-Recipient: rfc822;seven@myhost.test.ex
Status: 5.0.0
Action: failed
Final-Recipient: rfc822;userz@myhost.test.ex
Status: 5.0.0
+
Action: failed
Final-Recipient: rfc822;usery@myhost.test.ex
Status: 5.0.0
+
Action: failed
Final-Recipient: rfc822;userx@myhost.test.ex
Status: 5.0.0
recipients. This is a permanent error. The following address(es) failed:
userx@domain1
- host 127.0.0.1 [127.0.0.1]
+ host localhost4.test.ex [127.0.0.1]
SMTP error from remote mail server after initial connection:
550 Go away
Action: failed
Final-Recipient: rfc822;userx@domain1
Status: 5.0.0
-Remote-MTA: dns; 127.0.0.1
+Remote-MTA: dns; localhost4.test.ex
Diagnostic-Code: smtp; 550 Go away
--NNNNNNNNNN-eximdsn-MMMMMMMMMM
recipients. This is a permanent error. The following address(es) failed:
usery@domain2
- host 127.0.0.1 [127.0.0.1]
+ host localhost4.test.ex [127.0.0.1]
SMTP error from remote mail server after HELO the.local.host.name:
550 Go away
userx@domain1
- host 127.0.0.1 [127.0.0.1]
+ host localhost4.test.ex [127.0.0.1]
SMTP error from remote mail server after HELO the.local.host.name:
550 Go away
Action: failed
Final-Recipient: rfc822;userx@domain1
Status: 5.0.0
-Remote-MTA: dns; 127.0.0.1
+Remote-MTA: dns; localhost4.test.ex
Diagnostic-Code: smtp; 550 Go away
+
Action: failed
Final-Recipient: rfc822;usery@domain2
Status: 5.0.0
-Remote-MTA: dns; 127.0.0.1
+Remote-MTA: dns; localhost4.test.ex
Diagnostic-Code: smtp; 550 Go away
--NNNNNNNNNN-eximdsn-MMMMMMMMMM
Action: failed
Final-Recipient: rfc822;hbounce@test.ex
Status: 5.0.0
+
Action: failed
Final-Recipient: rfc822;bounce@test.ex
Status: 5.0.0
Action: delayed
Final-Recipient: rfc822;/no/such/file
Status: 4.0.0
+
Action: delayed
Final-Recipient: rfc822;defer@test.ex
Status: 4.0.0
+
Action: delayed
Final-Recipient: rfc822;hdefer@test.ex
Status: 4.0.0
Action: failed
Final-Recipient: rfc822;/a/b/c
Status: 5.0.0
+
Action: failed
Final-Recipient: rfc822;|/p/q/r
Status: 5.0.0
From x@y.x Tue Mar 02 09:44:33 1999
-Received: from [ip4.ip4.ip4.ip4] (port=1112)
+Received: from [ip4.ip4.ip4.ip4] (port=1113)
by myhost.test.ex with smtp (Exim x.yz)
(envelope-from <x@y.x>)
id 10HmaY-0005vi-00
for x@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-Port: 1112
+Port: 1113
From x@y.x Tue Mar 02 09:44:33 1999
-Received: from [127.0.0.1] (port=1113)
+Received: from [127.0.0.1] (port=1114)
by myhost.test.ex with smtp (Exim x.yz)
(envelope-from <x@y.x>)
id 10HmaZ-0005vi-00
for x@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-Port: 1113
+Port: 1114
From x@y.x Tue Mar 02 09:44:33 1999
-Received: from [ip4.ip4.ip4.ip4] (port=1114 helo=rhubarb)
+Received: from [ip4.ip4.ip4.ip4] (port=1115 helo=rhubarb)
by myhost.test.ex with smtp (Exim x.yz)
(envelope-from <x@y.x>)
id 10HmbA-0005vi-00
for x@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-Port: 1114
+Port: 1115
From x@y.x Tue Mar 02 09:44:33 1999
Action: failed
Final-Recipient: rfc822;/a/b/c
Status: 5.0.0
+
Action: failed
Final-Recipient: rfc822;|/p/q/r
Status: 5.0.0
Action: failed
Final-Recipient: rfc822;50@myhost.test.ex
Status: 5.0.0
+
Action: failed
Final-Recipient: rfc822;55@myhost.test.ex
Status: 5.0.0
+
Action: failed
Final-Recipient: rfc822;1k@myhost.test.ex
Status: 5.0.0
Action: failed
Final-Recipient: rfc822;b1@myhost.test.ex
Status: 5.0.0
+
Action: failed
Final-Recipient: rfc822;d3@myhost.test.ex
Status: 5.0.0
+From CALLER@test.ex Tue Mar 02 09:44:33 1999
+Received: from CALLER by the.local.host.name with local (Exim x.yz)
+ (envelope-from <CALLER@test.ex>)
+ id 10HmaX-0005vi-00
+ for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
+Message-Id: <E10HmaX-0005vi-00@the.local.host.name>
+From: CALLER_NAME <CALLER@test.ex>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+Testing with filter
+
From CALLER@test.ex Tue Mar 02 09:44:33 1999
Received: from CALLER by the.local.host.name with local (Exim x.yz)
(envelope-from <CALLER@test.ex>)
From: CALLER_NAME <CALLER@test.ex>
Date: Tue, 2 Mar 1999 09:44:33 +0000
-Testing with filter
+Testing without filter
+
+From CALLER@test.ex Tue Mar 02 09:44:33 1999
+Received: from CALLER by the.local.host.name with local (Exim x.yz)
+ (envelope-from <CALLER@test.ex>)
+ id 10HmaZ-0005vi-00
+ for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
+Message-Id: <E10HmaZ-0005vi-00@the.local.host.name>
+From: CALLER_NAME <CALLER@test.ex>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+Testing with expand-to-empty filter
--T4sUOijqQbZv57TR--
+From CALLER@myhost.test.ex Tue Mar 02 09:44:33 1999
+Received: from CALLER (helo=test.ex)
+ by myhost.test.ex with local-esmtp (Exim x.yz)
+ (envelope-from <CALLER@myhost.test.ex>)
+ id 10HmaZ-0005vi-00
+ for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+From: J Caesar <jcaesar@test.ex>
+To: a-list00@exim.org
+Message-ID: <20041217133501.GA3059@test.ex>
+Mime-Version: 1.0
+Content-Type: text/html;
+ charset=UTF-8;
+ name=""
+Content-Disposition: inline
+Subject: Nasty
+Sender: CALLER_NAME <CALLER@myhost.test.ex>
+X-0-content-type: text/html
+X-0-filename:
+X-0-charset: UTF-8
+X-0-boundary:
+X-0-content-disposition: inline
+X-0-content-transfer-encoding:
+X-0-content-id:
+X-0-content-description:
+X-0-is-multipart: 0
+X-0-is-coverletter: 1
+X-0-is-rfc822: 0
+X-0-decode-filename: TESTSUITE/spool/scan/10HmaZ-0005vi-00/10HmaZ-0005vi-00-00000
+X-0-content-size: 1
+
+--T4sUOijqQbZv57TR
+Content-Type: text/plain;
+
+foobar
+
+--T4sUOijqQbZv57TR--
+
+From CALLER@myhost.test.ex Tue Mar 02 09:44:33 1999
+Received: from CALLER (helo=test.ex)
+ by myhost.test.ex with local-esmtp (Exim x.yz)
+ (envelope-from <CALLER@myhost.test.ex>)
+ id 10HmbA-0005vi-00
+ for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+From: J Caesar <jcaesar@test.ex>
+To: a-list00@exim.org
+Message-ID: <20041217133501.GA3059@test.ex>
+Mime-Version: 1.0
+Content-Type: text/plain; charset="utf-8""
+Content-Disposition: inline
+Subject: Nasty3
+Sender: CALLER_NAME <CALLER@myhost.test.ex>
+X-0-content-type: text/plain
+X-0-filename:
+X-0-charset: utf-8;
+X-0-boundary:
+X-0-content-disposition: inline
+X-0-content-transfer-encoding:
+X-0-content-id:
+X-0-content-description:
+X-0-is-multipart: 0
+X-0-is-coverletter: 1
+X-0-is-rfc822: 0
+X-0-decode-filename: TESTSUITE/spool/scan/10HmbA-0005vi-00/10HmbA-0005vi-00-00000
+X-0-content-size: 1
+
+--T4sUOijqQbZv57TR
+Content-Type: text/plain;
+
+foobar
+
+--T4sUOijqQbZv57TR--
+
+From CALLER@myhost.test.ex Tue Mar 02 09:44:33 1999
+Received: from CALLER (helo=test.ex)
+ by myhost.test.ex with local-esmtp (Exim x.yz)
+ (envelope-from <CALLER@myhost.test.ex>)
+ id 10HmbB-0005vi-00
+ for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+From: J Caesar <jcaesar@test.ex>
+To: a-list00@exim.org
+Message-ID: <20041217133501.GA3059@test.ex>
+Mime-Version: 1.0
+Content-Type: text/plain;
+ garbage1;
+ garbage2=foo;
+ garbage3="bar"foo;
+ charset=UTF-8;
+ garbage4=";
+Content-Disposition: inline
+Subject: Nasty4
+Sender: CALLER_NAME <CALLER@myhost.test.ex>
+X-0-content-type: text/plain
+X-0-filename:
+X-0-charset: UTF-8
+X-0-boundary:
+X-0-content-disposition: inline
+X-0-content-transfer-encoding:
+X-0-content-id:
+X-0-content-description:
+X-0-is-multipart: 0
+X-0-is-coverletter: 1
+X-0-is-rfc822: 0
+X-0-decode-filename: TESTSUITE/spool/scan/10HmbB-0005vi-00/10HmbB-0005vi-00-00000
+X-0-content-size: 1
+
+--T4sUOijqQbZv57TR
+Content-Type: text/plain;
+
+foobar
+
+--T4sUOijqQbZv57TR--
+
+From CALLER@myhost.test.ex Tue Mar 02 09:44:33 1999
+Received: from CALLER (helo=test.ex)
+ by myhost.test.ex with local-esmtp (Exim x.yz)
+ (envelope-from <CALLER@myhost.test.ex>)
+ id 10HmbC-0005vi-00
+ for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+Message-ID: <20041217133501.GA3058@test.ex>
+Subject: Nasty5
+Mime-Version: 1.0
+Content-Type: multipart/mixed; boundary="T4sUOijqQbZv57TR"
+From: CALLER_NAME <CALLER@myhost.test.ex>
+X-0-content-type: multipart/mixed
+X-0-filename:
+X-0-charset:
+X-0-boundary: T4sUOijqQbZv57TR
+X-0-content-disposition:
+X-0-content-transfer-encoding:
+X-0-content-id:
+X-0-content-description:
+X-0-is-multipart: 1
+X-0-is-coverletter: 1
+X-0-is-rfc822: 0
+X-0-decode-filename: TESTSUITE/spool/scan/10HmbC-0005vi-00/10HmbC-0005vi-00-00000
+X-0-content-size: 1
+X-1-content-type: text/plain
+X-1-filename: test ä test1
+X-1-charset: us-ascii
+X-1-boundary:
+X-1-content-disposition: attachment
+X-1-content-transfer-encoding:
+X-1-content-id:
+X-1-content-description:
+X-1-is-multipart: 0
+X-1-is-coverletter: 1
+X-1-is-rfc822: 0
+X-1-decode-filename: TESTSUITE/spool/scan/10HmbC-0005vi-00/10HmbC-0005vi-00-00001
+X-1-content-size: 1
+X-2-content-type: text/plain
+X-2-filename: test ä test2
+X-2-charset: us-ascii
+X-2-boundary:
+X-2-content-disposition: attachment
+X-2-content-transfer-encoding:
+X-2-content-id:
+X-2-content-description:
+X-2-is-multipart: 0
+X-2-is-coverletter: 0
+X-2-is-rfc822: 0
+X-2-decode-filename: TESTSUITE/spool/scan/10HmbC-0005vi-00/10HmbC-0005vi-00-00002
+X-2-content-size: 1
+
+--T4sUOijqQbZv57TR
+Content-Type: text/plain; charset=us-ascii
+Content-Disposition: attachment; filename="=?iso-8859-1?Q?test_=E4_test1?="
+
+(content 1: filename is rfc2047 encoded)
+
+--T4sUOijqQbZv57TR
+Content-Type: text/plain; charset=us-ascii
+Content-Disposition: attachment; filename*=ISO-8859-1''%74%65%73%74%20%E4%20%74%65%73%74%32
+
+(content 2: filename is rfc2231 encoded)
+
+--T4sUOijqQbZv57TR--
+
+From CALLER@myhost.test.ex Tue Mar 02 09:44:33 1999
+Received: from CALLER (helo=test.ex)
+ by myhost.test.ex with local-esmtp (Exim x.yz)
+ (envelope-from <CALLER@myhost.test.ex>)
+ id 10HmbD-0005vi-00
+ for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+From: J Caesar <jcaesar@test.ex>
+To: a-list00@exim.org
+Message-ID: <20041217133502.GA3059@test.ex>
+Mime-Version: 1.0
+Content-Type: application/pdf;
+ name*=''2015.11.13%20-%20Pr%C3%A4sentation%20GI%20-%20LK.PDF
+Content-Disposition: attachment;
+ filename*=''2015.11.13%20-%20Pr%C3%A4sentation%20GI%20-%20LK.PDF
+Subject: Nasty6
+Sender: CALLER_NAME <CALLER@myhost.test.ex>
+X-0-content-type: application/pdf
+X-0-filename: 2015.11.13 - Präsentation GI - LK.PDF
+X-0-charset:
+X-0-boundary:
+X-0-content-disposition: attachment
+X-0-content-transfer-encoding:
+X-0-content-id:
+X-0-content-description:
+X-0-is-multipart: 0
+X-0-is-coverletter: 1
+X-0-is-rfc822: 0
+X-0-decode-filename: TESTSUITE/spool/scan/10HmbD-0005vi-00/10HmbD-0005vi-00-00000
+X-0-content-size: 1
+
+--T4sUOijqQbZv57TR
+Content-Type: text/plain;
+
+foobar
+
+--T4sUOijqQbZv57TR--
+
Received: from CALLER (helo=test.ex)
by myhost.test.ex with local-esmtp (Exim x.yz)
(envelope-from <CALLER@myhost.test.ex>)
- id 10HmaY-0005vi-00
- for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-Message-Id: <E10HmaY-0005vi-00@myhost.test.ex>
-From: CALLER_NAME <CALLER@myhost.test.ex>
-Date: Tue, 2 Mar 1999 09:44:33 +0000
-X-Router-SSint: was preserved
-
-A message without any headers.
-
-From CALLER@myhost.test.ex Tue Mar 02 09:44:33 1999
-Received: from CALLER (helo=test.ex)
- by myhost.test.ex with local-esmtp (Exim x.yz)
- (envelope-from <CALLER@myhost.test.ex>)
- id 10HmaZ-0005vi-00
+ id 10HmaX-0005vi-00
for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
From: Test person <tp@cam.ac.uk>
To: Me <userx@test.ex>
Date: Tue, 2 Mar 1999 09:44:33 +0000
Message-ID: <41C2F849.3060203@projectile.test.ex>
Sender: CALLER_NAME <CALLER@myhost.test.ex>
-X-Router-SSint: was preserved
OK, this should look like a genuine message.
Received: from CALLER (helo=test.ex)
by myhost.test.ex with local-esmtp (Exim x.yz)
(envelope-from <CALLER@myhost.test.ex>)
- id 10HmbA-0005vi-00
- for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-From: 99Junk99@somewhere.com
-To:
-Subject: MAKE MONEY FAST!!!!
-Message-id: abcde
-Sender: CALLER_NAME <CALLER@myhost.test.ex>
-Date: Tue, 2 Mar 1999 09:44:33 +0000
-X-Router-SSint: was preserved
-
-This should be enough to trip the threshold.
-
-From CALLER@myhost.test.ex Tue Mar 02 09:44:33 1999
-Received: from CALLER (helo=test.ex)
- by myhost.test.ex with local-esmtp (Exim x.yz)
- (envelope-from <CALLER@myhost.test.ex>)
- id 10HmbB-0005vi-00
+ id 10HmaY-0005vi-00
for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
From: Test person <tp@cam.ac.uk>
To: Me <userx@test.ex>
Message-ID: <41C2F849.3060203@projectile.test.ex>
FakeReject: test fakereject
Sender: CALLER_NAME <CALLER@myhost.test.ex>
-X-Regex: Regex matched
-X-Router-SSint: was preserved
-
-OK, this should look like a genuine message, but
-it will trip on THIS REGEX.
-
-From CALLER@myhost.test.ex Tue Mar 02 09:44:33 1999
-Received: from CALLER (helo=test.ex)
- by myhost.test.ex with local-esmtp (Exim x.yz)
- (envelope-from <CALLER@myhost.test.ex>)
- id 10HmbC-0005vi-00
- for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-Date: Tue, 2 Mar 1999 09:44:33 +0000
-From: J Caesar <jcaesar@test.ex>
-To: a-list00@exim.org
-Message-ID: <20041217133501.GA3058@test.ex>
-Mime-Version: 1.0
-Content-Type: multipart/mixed; boundary="T4sUOijqQbZv57TR"
-Content-Disposition: inline
-Subject: [exim] Re: Bug#286074: eximstats: uses message count as data for
- the "volume" charts
-X-BeenThere: a-list00@exim.org
-X-Mailman-Version: 2.1.5
-Precedence: list
-Sender: CALLER_NAME <CALLER@myhost.test.ex>
-X-0-content-type: multipart/mixed
-X-0-filename:
-X-0-charset:
-X-0-boundary: T4sUOijqQbZv57TR
-X-0-content-disposition: inline
-X-0-content-transfer-encoding:
-X-0-content-id:
-X-0-content-description:
-X-0-is-multipart: 1
-X-0-is-coverletter: 1
-X-0-is-rfc822: 0
-X-0-decode-filename: TESTSUITE/spool/scan/10HmbC-0005vi-00/10HmbC-0005vi-00-00000
-X-0-content-size: 2
-X-1-content-type: text/plain
-X-1-filename:
-X-1-charset: US-ASCII
-X-1-boundary:
-X-1-content-disposition: inline
-X-1-content-transfer-encoding: quoted-printable
-X-1-content-id:
-X-1-content-description:
-X-1-is-multipart: 0
-X-1-is-coverletter: 1
-X-1-is-rfc822: 0
-X-1-decode-filename: TESTSUITE/spool/scan/10HmbC-0005vi-00/10HmbC-0005vi-00-00001
-X-1-content-size: 1
-X-mime-regex: matched
-X-2-content-type: text/plain
-X-2-filename:
-X-2-charset: us-ascii
-X-2-boundary:
-X-2-content-disposition: inline
-X-2-content-transfer-encoding:
-X-2-content-id:
-X-2-content-description:
-X-2-is-multipart: 0
-X-2-is-coverletter: 0
-X-2-is-rfc822: 0
-X-2-decode-filename: TESTSUITE/spool/scan/10HmbC-0005vi-00/10HmbC-0005vi-00-00002
-X-2-content-size: 1
-X-3-content-type: text/plain
-X-3-filename: working-patch
-X-3-charset: us-ascii
-X-3-boundary:
-X-3-content-disposition: attachment
-X-3-content-transfer-encoding:
-X-3-content-id:
-X-3-content-description:
-X-3-is-multipart: 0
-X-3-is-coverletter: 0
-X-3-is-rfc822: 0
-X-3-decode-filename: TESTSUITE/spool/scan/10HmbC-0005vi-00/10HmbC-0005vi-00-00003
-X-3-content-size: 1
-X-4-content-type: text/plain
-X-4-filename:
-X-4-charset: us-ascii
-X-4-boundary:
-X-4-content-disposition: inline
-X-4-content-transfer-encoding: 7bit
-X-4-content-id:
-X-4-content-description:
-X-4-is-multipart: 0
-X-4-is-coverletter: 0
-X-4-is-rfc822: 0
-X-4-decode-filename: TESTSUITE/spool/scan/10HmbC-0005vi-00/10HmbC-0005vi-00-00004
-X-4-content-size: 1
-X-Router-SSint: was preserved
-
---T4sUOijqQbZv57TR
-Content-Type: text/plain; charset=US-ASCII
-Content-Transfer-Encoding: quoted-printable
-Content-Disposition: inline
-
-Test quoted-printable =3D
-Space at end of line=40
-Continued line =
-with this text.
-
---T4sUOijqQbZv57TR
-Content-Type: text/plain; charset=us-ascii
-Content-Disposition: inline
-
-There was a part of the patch missing, complete one is attached.
- sorry for wasting your time
-
---T4sUOijqQbZv57TR
-Content-Type: text/plain; charset=us-ascii
-Content-Disposition: attachment; filename=working-patch
-
---- /usr/sbin/eximstats 2004-12-17 13:36:44.381983753 +0100
-+++ eximstats 2004-12-17 13:47:37.763185260 +0100
-@@ -1107,11 +1107,11 @@
- if (scalar @chartdatanames < $ntopchart)
- {
- push(@chartdatanames, $key);
-- push(@chartdatavals, $$m_count{$key});
-+ push(@chartdatavals, $$m_data{$key});
- }
- else
- {
-- $chartotherval += $$m_count{$key};
-+ $chartotherval += $$m_data{$key};
- }
- }
- push(@chartdatanames, "Other");
-
---T4sUOijqQbZv57TR
-Content-Type: text/plain; charset="us-ascii"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Content-Disposition: inline
-
---
-
---T4sUOijqQbZv57TR--
-
-From CALLER@myhost.test.ex Tue Mar 02 09:44:33 1999
-Received: from CALLER by myhost.test.ex with local (Exim x.yz)
- (envelope-from <CALLER@myhost.test.ex>)
- id 10HmbD-0005vi-00
- for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-Message-Id: <E10HmbD-0005vi-00@myhost.test.ex>
-From: CALLER_NAME <CALLER@myhost.test.ex>
-Date: Tue, 2 Mar 1999 09:44:33 +0000
-X-Router-SSint: was preserved
-
-A message without any headers.
-
-From CALLER@myhost.test.ex Tue Mar 02 09:44:33 1999
-Received: from CALLER by myhost.test.ex with local (Exim x.yz)
- (envelope-from <CALLER@myhost.test.ex>)
- id 10HmbE-0005vi-00
- for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-Date: Tue, 2 Mar 1999 09:44:33 +0000
-From: J Caesar <jcaesar@test.ex>
-To: a-list00@exim.org
-Message-ID: <20041217133501.GA3058@test.ex>
-Mime-Version: 1.0
-Content-Type: multipart/mixed; boundary="T4sUOijqQbZv57TR"
-Content-Disposition: inline
-Subject: [exim] Re: Bug#286074: eximstats: uses message count as data for
- the "volume" charts
-X-BeenThere: a-list00@exim.org
-X-Mailman-Version: 2.1.5
-Precedence: list
-Sender: CALLER_NAME <CALLER@myhost.test.ex>
-X-0-content-type: multipart/mixed
-X-0-filename:
-X-0-charset:
-X-0-boundary: T4sUOijqQbZv57TR
-X-0-content-disposition: inline
-X-0-content-transfer-encoding:
-X-0-content-id:
-X-0-content-description:
-X-0-is-multipart: 1
-X-0-is-coverletter: 1
-X-0-is-rfc822: 0
-X-0-decode-filename: TESTSUITE/spool/scan/10HmbE-0005vi-00/10HmbE-0005vi-00-00000
-X-0-content-size: 1
-X-1-content-type: text/plain
-X-1-filename:
-X-1-charset: us-ascii
-X-1-boundary:
-X-1-content-disposition: inline
-X-1-content-transfer-encoding:
-X-1-content-id:
-X-1-content-description:
-X-1-is-multipart: 0
-X-1-is-coverletter: 1
-X-1-is-rfc822: 0
-X-1-decode-filename: TESTSUITE/spool/scan/10HmbE-0005vi-00/10HmbE-0005vi-00-00001
-X-1-content-size: 1
-X-2-content-type: text/plain
-X-2-filename: working-patch
-X-2-charset: us-ascii
-X-2-boundary:
-X-2-content-disposition: attachment
-X-2-content-transfer-encoding:
-X-2-content-id:
-X-2-content-description:
-X-2-is-multipart: 0
-X-2-is-coverletter: 0
-X-2-is-rfc822: 0
-X-2-decode-filename: TESTSUITE/spool/scan/10HmbE-0005vi-00/10HmbE-0005vi-00-00002
-X-2-content-size: 1
-X-3-content-type: text/plain
-X-3-filename:
-X-3-charset: us-ascii
-X-3-boundary:
-X-3-content-disposition: inline
-X-3-content-transfer-encoding: 7bit
-X-3-content-id:
-X-3-content-description:
-X-3-is-multipart: 0
-X-3-is-coverletter: 0
-X-3-is-rfc822: 0
-X-3-decode-filename: TESTSUITE/spool/scan/10HmbE-0005vi-00/10HmbE-0005vi-00-00003
-X-3-content-size: 1
-X-Router-SSint: was preserved
-
---T4sUOijqQbZv57TR
-Content-Type: text/plain; charset=us-ascii
-Content-Disposition: inline
-
-There was a part of the patch missing, complete one is attached.
- sorry for wasting your time
-
---T4sUOijqQbZv57TR
-Content-Type: text/plain; charset=us-ascii
-Content-Disposition: attachment; filename=working-patch
-
---- /usr/sbin/eximstats 2004-12-17 13:36:44.381983753 +0100
-+++ eximstats 2004-12-17 13:47:37.763185260 +0100
-@@ -1107,11 +1107,11 @@
- if (scalar @chartdatanames < $ntopchart)
- {
- push(@chartdatanames, $key);
-- push(@chartdatavals, $$m_count{$key});
-+ push(@chartdatavals, $$m_data{$key});
- }
- else
- {
-- $chartotherval += $$m_count{$key};
-+ $chartotherval += $$m_data{$key};
- }
- }
- push(@chartdatanames, "Other");
-
---T4sUOijqQbZv57TR
-Content-Type: text/plain; charset="us-ascii"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Content-Disposition: inline
-
---
-
---T4sUOijqQbZv57TR--
-
-From CALLER@myhost.test.ex Tue Mar 02 09:44:33 1999
-Received: from CALLER (helo=test.ex)
- by myhost.test.ex with local-esmtp (Exim x.yz)
- (envelope-from <CALLER@myhost.test.ex>)
- id 10HmbF-0005vi-00
- for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-From: Test person <tp@cam.ac.uk>
-To: Me <userx@test.ex>
-Subject: A real test message
-Date: Tue, 2 Mar 1999 09:44:33 +0000
-Message-ID: <41C2F849.3060203@projectile.test.ex>
-FakeDefer: test fakedefer
-Sender: CALLER_NAME <CALLER@myhost.test.ex>
-X-Regex: Regex matched
-X-Router-SSint: was preserved
+X-Regex: Regex matched <THIS gazornenplaz REGEX> <gazornenplaz>
OK, this should look like a genuine message, but
-it will trip on THIS REGEX.
+it will trip on THIS gazornenplaz REGEX.
Sender: sender@some.where
+From MAILER-DAEMON Tue Mar 02 09:44:33 1999
+Received: from [127.0.0.1] (helo=rhu.barb)
+ by myhost.test.ex with esmtp (Exim x.yz)
+ id 10HmbC-0005vi-00
+ for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
+Sender: sender@some.where
+
+
+++ /dev/null
-1999-03-02 09:44:33 Received from CALLER@test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 H=thishost.test.ex [127.0.0.1] Connection refused
-1999-03-02 09:44:33 userx@simple R=all T=smtp defer (dd): Connection refused
-1999-03-02 09:44:33 H=thishost.test.ex [127.0.0.1] Connection refused
-1999-03-02 09:44:33 userx@simple R=all T=smtp defer (dd): Connection refused
+++ /dev/null
-1999-03-02 09:44:33 Received from CALLER@test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 H=thisloop.test.ex [ip4.ip4.ip4.ip4] Connection refused
-1999-03-02 09:44:33 H=thisloop.test.ex [127.0.0.1] Connection refused
-1999-03-02 09:44:33 usery@complex R=all T=smtp defer (dd): Connection refused
+++ /dev/null
-1999-03-02 09:44:33 Received from CALLER@test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 H=thishost.test.ex [127.0.0.1] Connection refused
-1999-03-02 09:44:33 userz@simple R=all T=smtp defer (dd): Connection refused
+++ /dev/null
-1999-03-02 09:44:33 Received from CALLER@test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 with@complex R=all T=smtp defer (-53): retry time not reached for any host
+++ /dev/null
-1999-03-02 09:44:33 Received from CALLER@test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 H=thisloop.test.ex [ip4.ip4.ip4.ip4] Connection refused
-1999-03-02 09:44:33 H=thisloop.test.ex [127.0.0.1] Connection refused
-1999-03-02 09:44:33 without@complex R=all T=smtp defer (dd): Connection refused
+++ /dev/null
-1999-03-02 09:44:33 Received from CALLER@test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 userx@test.ex R=r1 T=t1 defer (-24): transport filter process failed (127) while writing to TESTSUITE/test-mail/userx: unable to execute command
-1999-03-02 09:44:33 Exim configuration error in line 14 of TESTSUITE/test-config:
+1999-03-02 09:44:33 Exim configuration error in line 15 of TESTSUITE/test-config:
extra characters follow string value for relay_hosts
-1999-03-02 09:44:33 Exim configuration error in line 16 of TESTSUITE/test-config:
+1999-03-02 09:44:33 Exim configuration error in line 17 of TESTSUITE/test-config:
missing quote at end of string value for hold_domains
-1999-03-02 09:44:33 Exim configuration error in line 14 of TESTSUITE/test-config:
+1999-03-02 09:44:33 Exim configuration error in line 15 of TESTSUITE/test-config:
macro name too long (maximum is 63 characters)
-1999-03-02 09:44:33 Exim configuration error in line 26 of TESTSUITE/test-config:
+1999-03-02 09:44:33 Exim configuration error in line 27 of TESTSUITE/test-config:
.include specifies a non-absolute path "non/absolute"
-1999-03-02 09:44:33 Exim configuration error in line 24 of TESTSUITE/test-config:
+1999-03-02 09:44:33 Exim configuration error in line 25 of TESTSUITE/test-config:
bad parameters for retry rule
-1999-03-02 09:44:33 Exim configuration error in line 24 of TESTSUITE/test-config:
+1999-03-02 09:44:33 Exim configuration error in line 25 of TESTSUITE/test-config:
bad parameters for retry rule
-1999-03-02 09:44:33 Exim configuration error in line 24 of TESTSUITE/test-config:
+1999-03-02 09:44:33 Exim configuration error in line 25 of TESTSUITE/test-config:
bad parameters for retry rule
-1999-03-02 09:44:33 Exim configuration error in line 24 of TESTSUITE/test-config:
+1999-03-02 09:44:33 Exim configuration error in line 25 of TESTSUITE/test-config:
bad parameters for retry rule
+++ /dev/null
-1999-03-02 09:44:33 10HmaX-0005vi-00 == userx@test.ex R=r1 T=t1 defer (-24): transport filter process failed (127) while writing to TESTSUITE/test-mail/userx: unable to execute command
-1999-03-02 09:44:33 Exim configuration error in line 19 of TESTSUITE/test-config:
+1999-03-02 09:44:33 Exim configuration error in line 20 of TESTSUITE/test-config:
absolute value of integer "4000000M" is too large (overflow)
-1999-03-02 09:44:33 Exim configuration error in line 19 of TESTSUITE/test-config:
- extra characters follow integer value for check_spool_space
1999-03-02 09:44:33 Exim configuration error in line 20 of TESTSUITE/test-config:
+ extra characters follow integer value for check_spool_space
+1999-03-02 09:44:33 Exim configuration error in line 21 of TESTSUITE/test-config:
integer "4000000000.123" is too large (overflow)
-1999-03-02 09:44:33 Exim configuration error in line 20 of TESTSUITE/test-config:
+1999-03-02 09:44:33 Exim configuration error in line 21 of TESTSUITE/test-config:
integer "4000000.123" is too large (overflow)
-1999-03-02 09:44:33 Exim configuration error in line 22 of TESTSUITE/test-config:
+1999-03-02 09:44:33 Exim configuration error in line 23 of TESTSUITE/test-config:
absolute value of integer "999999999999999999" is too large (overflow)
-1999-03-02 09:44:33 Exim configuration error in line 22 of TESTSUITE/test-config:
+1999-03-02 09:44:33 Exim configuration error in line 23 of TESTSUITE/test-config:
absolute value of integer "999999999K" is too large (overflow)
-1999-03-02 09:44:33 Exim configuration error in line 22 of TESTSUITE/test-config:
+1999-03-02 09:44:33 Exim configuration error in line 23 of TESTSUITE/test-config:
absolute value of integer "999999M" is too large (overflow)
-1999-03-02 09:44:33 Exim configuration error in line 22 of TESTSUITE/test-config:
+1999-03-02 09:44:33 Exim configuration error in line 23 of TESTSUITE/test-config:
extra characters follow integer value for finduser_retries
-1999-03-02 09:44:33 Exim configuration error in line 22 of TESTSUITE/test-config:
+1999-03-02 09:44:33 Exim configuration error in line 23 of TESTSUITE/test-config:
integer expected for finduser_retries
-1999-03-02 09:44:33 Exim configuration error in line 22 of TESTSUITE/test-config:
+1999-03-02 09:44:33 Exim configuration error in line 23 of TESTSUITE/test-config:
extra characters follow integer value for finduser_retries
-1999-03-02 09:44:33 Exim configuration error in line 42 of TESTSUITE/test-config:
+1999-03-02 09:44:33 Exim configuration error in line 43 of TESTSUITE/test-config:
failed to open included configuration file /non/existent
-1999-03-02 09:44:33 ACL for QUIT returned ERROR: "deny" is not allowed in a QUIT or not-QUIT ACL
+1999-03-02 09:44:33 ACL for QUIT returned ERROR: QUIT or not-QUIT teplevel ACL may not fail ('deny' verb used incorrectly)
-1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: aveserver: unable to scan file TESTSUITE/spool/scan/10HmaX-0005vi-00/10HmaX-0005vi-00.eml (Responded: 5xx defer).
-1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: aveserver: unavailable (Responded: nothing).
-1999-03-02 09:44:33 10HmaZ-0005vi-00 malware acl condition: aveserver: unavailable (Responded: nothing).
-1999-03-02 09:44:33 10HmbA-0005vi-00 malware acl condition: aveserver: unable to scan file TESTSUITE/spool/scan/10HmbA-0005vi-00/10HmbA-0005vi-00.eml (Responded: 5xx defer).
+1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: aveserver TESTSUITE/eximdir/aveserver_sock : unable to scan file TESTSUITE/spool/scan/10HmaX-0005vi-00/10HmaX-0005vi-00.eml (Responded: 5xx defer).
+1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: aveserver TESTSUITE/eximdir/aveserver_sock : unavailable (Responded: nothing).
+1999-03-02 09:44:33 10HmaZ-0005vi-00 malware acl condition: aveserver TESTSUITE/eximdir/aveserver_sock : unavailable (Responded: nothing).
+1999-03-02 09:44:33 10HmbA-0005vi-00 malware acl condition: aveserver TESTSUITE/eximdir/aveserver_sock : unable to scan file TESTSUITE/spool/scan/10HmbA-0005vi-00/10HmbA-0005vi-00.eml (Responded: 5xx defer).
-1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: fsecure: unable to read answer 0 (Connection timed out)
-1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: fsecure: unable to read answer 0 (Connection timed out)
+1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: fsecure TESTSUITE/eximdir/fsec_sock : unable to read answer 0 (Connection timed out)
+1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: fsecure TESTSUITE/eximdir/fsec_sock : unable to read answer 0 (Connection timed out)
-1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: sophie: scanner reported error
-1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: sophie: unable to read from UNIX socket (TESTSUITE/eximdir/sophie_sock)
-1999-03-02 09:44:33 10HmaZ-0005vi-00 malware acl condition: sophie: unable to read from UNIX socket (TESTSUITE/eximdir/sophie_sock)
+1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: sophie TESTSUITE/eximdir/sophie_sock : scanner reported error
+1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: sophie TESTSUITE/eximdir/sophie_sock : unable to read from UNIX socket (TESTSUITE/eximdir/sophie_sock)
+1999-03-02 09:44:33 10HmaZ-0005vi-00 malware acl condition: sophie TESTSUITE/eximdir/sophie_sock : unable to read from UNIX socket (TESTSUITE/eximdir/sophie_sock)
-1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: clamd: ClamAV returned: scanned_file_name: 666 ERROR
-1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: clamd: unable to read from socket (Connection timed out)
-1999-03-02 09:44:33 10HmaZ-0005vi-00 malware acl condition: clamd: unable to read from socket (Connection timed out)
+1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: clamd TESTSUITE/eximdir/clam_sock : ClamAV returned: scanned_file_name: 666 ERROR
+1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: clamd TESTSUITE/eximdir/clam_sock : unable to read from socket (Connection timed out)
+1999-03-02 09:44:33 10HmaZ-0005vi-00 malware acl condition: clamd TESTSUITE/eximdir/clam_sock : unable to read from socket (Connection timed out)
-1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: avast: invalid response from scanner: 'blah [E]'
-1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: avast: timeout from scanner
-1999-03-02 09:44:33 10HmaZ-0005vi-00 malware acl condition: avast: timeout from scanner
+1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: avast TESTSUITE/eximdir/avast_sock : invalid response from scanner: 'blah [E]'
+1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: avast TESTSUITE/eximdir/avast_sock : timeout from scanner
+1999-03-02 09:44:33 10HmaZ-0005vi-00 malware acl condition: avast TESTSUITE/eximdir/avast_sock : timeout from scanner
-1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: cmdline: unable to read from scanner (TESTSUITE/aux-fixed/4007.script -o pause3 TESTSUITE/spool/scan/10HmaX-0005vi-00 2>&1): Connection timed out
-1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: cmdline: unable to read from scanner (TESTSUITE/aux-fixed/4007.script -o pause3 TESTSUITE/spool/scan/10HmaY-0005vi-00 2>&1): Connection timed out
+1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: cmdline : unable to read from scanner (TESTSUITE/aux-fixed/4007.script -o pause3 TESTSUITE/spool/scan/10HmaX-0005vi-00 2>&1): Connection timed out
+1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: cmdline : unable to read from scanner (TESTSUITE/aux-fixed/4007.script -o pause3 TESTSUITE/spool/scan/10HmaY-0005vi-00 2>&1): Connection timed out
F From: @
I Message-Id: <E10HmaX-0005vi-00@myhost.test.ex>
Date: Tue, 2 Mar 1999 09:44:33 +0000
-1999-03-02 09:44:33 10HmaY-0005vi-00 U=CALLER F=<> rejected after DATA: domain missing or malformed: failing address in "From:" header is: @
-Envelope-from: <>
+1999-03-02 09:44:33 10HmaY-0005vi-00 U=CALLER F=<x@y> rejected after DATA: '>' missing at end of address: failing address in "To:" header is: <dummy@gmail.com
+Envelope-from: <x@y>
Envelope-to: <x@y>
P Received: from CALLER by myhost.test.ex with local-smtp (Exim x.yz)
+ (envelope-from <x@y>)
id 10HmaY-0005vi-00
for x@y; Tue, 2 Mar 1999 09:44:33 +0000
-F From: <x@y>, @
+T To: <dummy@gmail.com
+ Subject: incomprehensible
+F From: <forged@sender.com
I Message-Id: <E10HmaY-0005vi-00@myhost.test.ex>
Date: Tue, 2 Mar 1999 09:44:33 +0000
-1999-03-02 09:44:33 10HmaZ-0005vi-00 U=CALLER F=<> rejected after DATA: there is no valid sender in any header line
+1999-03-02 09:44:33 10HmaZ-0005vi-00 U=CALLER F=<> rejected after DATA: domain missing or malformed: failing address in "From:" header is: @
Envelope-from: <>
Envelope-to: <x@y>
P Received: from CALLER by myhost.test.ex with local-smtp (Exim x.yz)
id 10HmaZ-0005vi-00
for x@y; Tue, 2 Mar 1999 09:44:33 +0000
-F From: <x@y>
+F From: <x@y>, @
I Message-Id: <E10HmaZ-0005vi-00@myhost.test.ex>
Date: Tue, 2 Mar 1999 09:44:33 +0000
+1999-03-02 09:44:33 10HmbA-0005vi-00 U=CALLER F=<> rejected after DATA: there is no valid sender in any header line
+Envelope-from: <>
+Envelope-to: <x@y>
+P Received: from CALLER by myhost.test.ex with local-smtp (Exim x.yz)
+ id 10HmbA-0005vi-00
+ for x@y; Tue, 2 Mar 1999 09:44:33 +0000
+F From: <x@y>
+I Message-Id: <E10HmbA-0005vi-00@myhost.test.ex>
+ Date: Tue, 2 Mar 1999 09:44:33 +0000
X-warning: this is a test warning
-1999-03-02 09:44:33 10HmbA-0005vi-00 U=CALLER F=<x@y> rejected after DATA: body contains trigger
+1999-03-02 09:44:33 10HmbB-0005vi-00 U=CALLER F=<x@y> rejected after DATA: body contains trigger
Envelope-from: <x@y>
Envelope-to: <x@y>
P Received: from CALLER by myhost.test.ex with local-smtp (Exim x.yz)
(envelope-from <x@y>)
- id 10HmbA-0005vi-00
+ id 10HmbB-0005vi-00
for x@y; Tue, 2 Mar 1999 09:44:33 +0000
-I Message-Id: <E10HmbA-0005vi-00@myhost.test.ex>
+I Message-Id: <E10HmbB-0005vi-00@myhost.test.ex>
F From: x@y
Date: Tue, 2 Mar 1999 09:44:33 +0000
-1999-03-02 09:44:33 10HmbB-0005vi-00 U=CALLER F=<> rejected after DATA: there is no valid sender in any header line
+1999-03-02 09:44:33 10HmbC-0005vi-00 U=CALLER F=<> rejected after DATA: there is no valid sender in any header line
Envelope-from: <>
Envelope-to: <userx@test.ex>
P Received: from CALLER by myhost.test.ex with local-smtp (Exim x.yz)
- id 10HmbB-0005vi-00
+ id 10HmbC-0005vi-00
for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
T to: group name: x@y, p@q;
R reply-to: group name:;
-I Message-Id: <E10HmbB-0005vi-00@myhost.test.ex>
+I Message-Id: <E10HmbC-0005vi-00@myhost.test.ex>
Date: Tue, 2 Mar 1999 09:44:33 +0000
X-warning: this is a test warning
1999-03-02 09:44:33 U=CALLER temporarily rejected EHLO or HELO xxx
-1999-03-02 09:44:33 U=CALLER F=<discard@x.y> rejected RCPT <a@b>: discarded by MAIL ACL: discard message 2
-1999-03-02 09:44:33 U=CALLER F=<discard@x.y> rejected RCPT <discard@p.q>: discarded by MAIL ACL: discard message 2
-1999-03-02 09:44:33 U=CALLER F=<ok@x.y> rejected RCPT <discard@p.q>: discarded by RCPT ACL: discard message 1
-1999-03-02 09:44:33 U=CALLER F=<ok@x.y> rejected RCPT <nested_discard@p.q>: discarded by RCPT ACL
-1999-03-02 09:44:33 U=CALLER F=<ok@x.y> rejected RCPT <discard@p.q>: discarded by RCPT ACL: discard message 1
+1999-03-02 09:44:33 U=CALLER F=<discard@x.y> RCPT <a@b>: discarded by MAIL ACL: discard message 2
+1999-03-02 09:44:33 U=CALLER F=<discard@x.y> RCPT <discard@p.q>: discarded by MAIL ACL: discard message 2
+1999-03-02 09:44:33 U=CALLER F=<ok@x.y> RCPT <discard@p.q>: discarded by RCPT ACL: discard message 1
+1999-03-02 09:44:33 U=CALLER F=<ok@x.y> RCPT <nested_discard@p.q>: discarded by RCPT ACL
+1999-03-02 09:44:33 U=CALLER F=<ok@x.y> RCPT <discard@p.q>: discarded by RCPT ACL: discard message 1
-1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> rejected RCPT <userx@domA.ex>: discarded by RCPT ACL
-1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> rejected RCPT <usery@domB.ex>: discarded by RCPT ACL
-1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> rejected RCPT <userx@domA.ex>: discarded by RCPT ACL
-1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> rejected RCPT <usery@domB.ex>: discarded by RCPT ACL
-1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> rejected RCPT <userx@domA.ex>: discarded by RCPT ACL
-1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> rejected RCPT <usery@domB.ex>: discarded by RCPT ACL
-1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> rejected RCPT <userx@domA.ex>: discarded by RCPT ACL
-1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> rejected RCPT <usery@domB.ex>: discarded by RCPT ACL
-1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> rejected RCPT <userx@domA.ex>: discarded by RCPT ACL
-1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> rejected RCPT <usery@domB.ex>: discarded by RCPT ACL
-1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> rejected RCPT <userx@domA.ex>: discarded by RCPT ACL
-1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> rejected RCPT <usery@domA.ex>: discarded by RCPT ACL
-1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> rejected RCPT <userz@domC.ex>: discarded by RCPT ACL
+1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> RCPT <userx@domA.ex>: discarded by RCPT ACL
+1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> RCPT <usery@domB.ex>: discarded by RCPT ACL
+1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> RCPT <userx@domA.ex>: discarded by RCPT ACL
+1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> RCPT <usery@domB.ex>: discarded by RCPT ACL
+1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> RCPT <userx@domA.ex>: discarded by RCPT ACL
+1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> RCPT <usery@domB.ex>: discarded by RCPT ACL
+1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> RCPT <userx@domA.ex>: discarded by RCPT ACL
+1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> RCPT <usery@domB.ex>: discarded by RCPT ACL
+1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> RCPT <userx@domA.ex>: discarded by RCPT ACL
+1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> RCPT <usery@domB.ex>: discarded by RCPT ACL
+1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> RCPT <userx@domA.ex>: discarded by RCPT ACL
+1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> RCPT <usery@domA.ex>: discarded by RCPT ACL
+1999-03-02 09:44:33 H=localhost (primary.test.ex) [127.0.0.1] F=<CALLER@test.ex> RCPT <userz@domC.ex>: discarded by RCPT ACL
+++ /dev/null
-1999-03-02 09:44:33 10HmaX-0005vi-00 U=CALLER F=<CALLER@myhost.test.ex> rejected after DATA: Found Eicar-Test-Signature
-Envelope-from: <CALLER@myhost.test.ex>
-Envelope-to: <userx@test.ex>
-P Received: from CALLER by myhost.test.ex with local-smtp (Exim x.yz)
- (envelope-from <CALLER@myhost.test.ex>)
- id 10HmaX-0005vi-00
- for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
- Subject: a virus test
-I Message-Id: <E10HmaX-0005vi-00@myhost.test.ex>
-F From: CALLER_NAME <CALLER@myhost.test.ex>
- Date: Tue, 2 Mar 1999 09:44:33 +0000
###############################################################################
#use strict;
-require Cwd;
use Errno;
use FileHandle;
use Socket;
use Time::Local;
+use Cwd;
+use File::Basename;
+use if $ENV{DEBUG} && $ENV{DEBUG} =~ /\bruntest\b/ => ('Smart::Comments' => '####');
# Start by initializing some global variables
$optargs = "";
$save_output = 0;
$server_opts = "";
+$flavour = 'FOO';
$have_ipv4 = 1;
$have_ipv6 = 1;
# Manually set locale
$ENV{'LC_ALL'} = 'C';
+# In some environments USER does not exists, but we
+# need it for some test(s)
+$ENV{USER} = getpwuid($>)
+ if not exists $ENV{USER};
###############################################################################
my($yield) = 0;
my(@saved) = ();
+local $_;
+
open(IN, "$file") || tests_exit(-1, "Failed to open $file: $!");
my($is_log) = $file =~ /log/;
# Random local part in callout cache testing
s/myhost.test.ex-\d+-testing/myhost.test.ex-dddddddd-testing/;
+ s/the.local.host.name-\d+-testing/the.local.host.name-dddddddd-testing/;
# File descriptor numbers may vary
s/^writing data block fd=\d+/writing data block fd=dddd/;
s/Exim\sstatistics\sfrom\s\d{4}-\d\d-\d\d\s\d\d:\d\d:\d\d\sto\s
\d{4}-\d\d-\d\d\s\d\d:\d\d:\d\d/Exim statistics from <time> to <time>/x;
+ # Treat ECONNRESET the same as ECONNREFUSED. At least some systems give
+ # us the former on a new connection.
+ s/(could not connect to .*: Connection) reset by peer$/$1 refused/;
# ======== TLS certificate algorithms ========
# Test machines might have various different TLS library versions supporting
# ======== Other error numbers ========
s/errno=\d+/errno=dd/g;
+ # ======== System Error Messages ======
+ # depending on the underlaying file system the error message seems to differ
+ s/(?: is not a regular file)|(?: has too many links \(\d+\))/ not a regular file or too many links/;
# ======== Output from ls ========
# Different operating systems use different spacing on long output
s/this message = \d+\b/this message = sss/;
s/Size of headers = \d+/Size of headers = sss/;
s/sum=(?!0)\d+/sum=dddd/;
- s/(?<=sum=dddd )count=(?!0)\d+\b/count=dd/;
- s/(?<=sum=0 )count=(?!0)\d+\b/count=dd/;
+ s/(?<=sum=dddd )count=\d+\b/count=dd/;
+ s/(?<=sum=0 )count=\d+\b/count=dd/;
s/,S is \d+\b/,S is ddddd/;
s/\+0100,\d+;/+0100,ddd;/;
s/\(\d+ bytes written\)/(ddd bytes written)/;
# different wording in the error messages, so we cannot compare them.
s/(TLS error on connection (?:from .* )?\(SSL_\w+\): error:)(.*)/$1 <<detail omitted>>/;
+ next if /SSL verify error: depth=0 error=certificate not trusted/;
# ======== Maildir things ========
# timestamp output in maildir processing
next if /^SSL info: unknown state/;
next if /^SSL info: SSLv2\/v3 write client hello A/;
next if /^SSL info: SSLv3 read server key exchange A/;
+ next if /SSL verify error: depth=0 error=certificate not trusted/;
+ s/SSL3_READ_BYTES/ssl3_read_bytes/;
+ # gnutls version variances
+ next if /^Error in the pull function./;
}
# ======== stderr ========
# IP address lookups use gethostbyname() when IPv6 is not supported,
# and gethostbyname2() or getipnodebyname() when it is.
- s/\bgethostbyname2?|\bgetipnodebyname/get[host|ipnode]byname[2]/;
+ s/\b(gethostbyname2?|\bgetipnodebyname)(\(af=inet\))?/get[host|ipnode]byname[2]/;
# drop gnutls version strings
next if /GnuTLS compile-time version: \d+[\.\d]+$/;
# are unset, because tls ain't always there.
next if /in\s(?:tls_advertise_hosts\?|hosts_require_tls\?)
- \sno\s\(option\sunset\)/x;
+ \sno\s\((option\sunset|end\sof\slist)\)/x;
# Skip auxiliary group lists because they will vary.
@saved = ();
}
+ # remote port numbers vary
+ s/(Connection request from 127.0.0.1 port) \d{1,5}/$1 sssss/;
+
# Skip hosts_require_dane checks when the options
# are unset, because dane ain't always there.
next if /in\shosts_require_dane\?\sno\s\(option\sunset\)/x;
+ # SUPPORT_PROXY
+ next if /host in hosts_proxy\?/;
+
+ # Experimental_International
+ next if / in smtputf8_advertise_hosts\? no \(option unset\)/;
+
# Skip some lines that Exim puts out at the start of debugging output
# because they will be different in different binaries.
/^Fixed never_users:/ ||
/^Size of off_t:/
);
+
+
}
next;
# Arguments: [0] the prompt string
# [1] if there is a U in the prompt and $force_update is true
# [2] if there is a C in the prompt and $force_continue is true
-# Returns: nothing (it sets $_)
+# Returns: returns the answer
sub interact{
print $_[0];
# If there is no saved file, the raw files must either not exist, or be
# empty. The test ! -s is TRUE if the file does not exist or is empty.
-if (! -e $sf)
+# we check if there is a flavour specific file, but we remember
+# the original file name as "generic"
+$sf_generic = $sf;
+$sf_flavour = "$sf_generic.$flavour";
+$sf_current = -e $sf_flavour ? $sf_flavour : $sf_generic;
+
+if (! -e $sf_current)
{
return 0 if (! -s $rf && (! defined $rsf || ! -s $rsf));
}
}
+#### $_
+
# Control reaches here if either (a) there is a saved file ($sf), or (b) there
# was a request to create a saved file. First, create the munged file from any
# data that does exist.
# a result of parallel deliveries. We load the munged file and sort sequences
# of delivery lines.
-if (-e $sf)
+if (-e $sf_current)
{
# Deal with truncated text items
open(MUNGED, "$mf") || tests_exit(-1, "Failed to open $mf: $!");
@munged = <MUNGED>;
close(MUNGED);
- open(SAVED, "$sf") || tests_exit(-1, "Failed to open $sf: $!");
+ open(SAVED, $sf_current) || tests_exit(-1, "Failed to open $sf_current: $!");
@saved = <SAVED>;
close(SAVED);
# Do the comparison
- return 0 if (system("$cf '$mf' '$sf' >test-cf") == 0);
+ return 0 if (system("$cf '$mf' '$sf_current' >test-cf") == 0);
# Handle comparison failure
- print "** Comparison of $mf with $sf failed";
+ print "** Comparison of $mf with $sf_current failed";
system("$more test-cf");
print "\n";
for (;;)
{
- interact("Continue, Retry, Update & retry, Quit? [Q] ", $force_update, $force_continue);
+ interact("Continue, Retry, Update current"
+ . ($sf_current ne $sf_flavour ? "/Save for flavour '$flavour'" : "")
+ . " & retry, Quit? [Q] ", $force_update, $force_continue);
tests_exit(1) if /^q?$/i;
- log_failure($log_failed_filename, $testno, $sf) if (/^c$/i && $force_continue);
+ log_failure($log_failed_filename, $testno, $sf_current) if (/^c$/i && $force_continue);
return 0 if /^c$/i;
return 1 if /^r$/i;
- last if (/^u$/i);
+ last if (/^[us]$/i);
}
}
# Update or delete the saved file, and give the appropriate return code.
if (-s $mf)
- { tests_exit(-1, "Failed to cp $mf $sf") if system("cp '$mf' '$sf'") != 0; }
+ {
+ my $sf = /^u/i ? $sf_current : $sf_flavour;
+ tests_exit(-1, "Failed to cp $mf $sf") if system("cp '$mf' '$sf'") != 0;
+ }
else
- { tests_exit(-1, "Failed to unlink $sf") if !unlink($sf); }
+ {
+ # if we deal with a flavour file, we can't delete it, because next time the generic
+ # file would be used again
+ if ($sf_current eq $sf_flavour) {
+ open(FOO, ">$sf_current");
+ close(FOO);
+ }
+ else {
+ tests_exit(-1, "Failed to unlink $sf_current") if !unlink($sf_current);
+ }
+ }
return 1;
}
'optional_ocsp' =>
{ 'stderr' => '/127.0.0.1 in hosts_requ(ire|est)_ocsp/' },
- 'no_tpt_filter_epipe' =>
- { 'stderr' => '/^writing error 32: Broken pipe$/' },
-
'optional_cert_hostnames' =>
{ 'stderr' => '/in tls_verify_cert_hostnames\? no/' },
+ 'loopback' =>
+ { 'stdout' => 's/[[](127\.0\.0\.1|::1)]/[IP_LOOPBACK_ADDR]/' },
+
+ 'scanfile_size' =>
+ { 'stdout' => 's/(Content-length:) \d\d\d/$1 ddd/' },
+
+ 'delay_1500' =>
+ { 'stderr' => 's/(1[5-9]|23\d)\d\d msec/ssss msec/' },
+
+ 'tls_anycipher' =>
+ { 'mainlog' => 's/ X=TLS\S+ / X=TLS_proto_and_cipher /' },
+
+ 'debug_pid' =>
+ { 'stderr' => 's/(^\s{0,4}|(?<=Process )|(?<=child ))\d{1,5}/ppppp/g' },
+
+ 'optional_dsn_info' =>
+ { 'mail' => '/^(X-(Remote-MTA-(smtp-greeting|helo-response)|Exim-Diagnostic|(body|message)-linecount):|Remote-MTA: X-ip;)/'
+ },
+
+ 'sys_bindir' =>
+ { 'mainlog' => 's%/(usr/)?bin/%SYSBINDIR/%' },
+
};
# [4] TRUE if this is a log file whose deliveries must be sorted
# [5] an optional custom munge command
#
-# Arguments: Optionally, name of a custom munge to run.
+# Arguments: Optionally, name of a single custom munge to run.
# Returns: 0 if the output compared equal
# 1 if re-run needed (files may have been updated)
foreach $item (@temp)
{
- $item =~ s/^\s*(.*)\n(.*)\n?\s*$/\1\n\2/m;
+ $item =~ s/^\s*(.*)\n(.*)\n?\s*$/$1\n$2/m;
print OUT " $item\n";
}
}
if (/^server\s+(.*)$/)
{
- $cmd = "./bin/server $server_opts $1 >>test-stdout-server";
+ $pidfile = "$parm_cwd/aux-var/server-daemon.pid";
+ $cmd = "./bin/server $server_opts -oP $pidfile $1 >>test-stdout-server";
print ">> $cmd\n" if ($debug);
$server_pid = open SERVERCMD, "|$cmd" || tests_exit(-1, "Failed to run $cmd");
SERVERCMD->autoflush(1);
print SERVERCMD "++++\n"; # Send end to server; can't send EOF yet
# because close() waits for the process.
- # This gives the server time to get started; otherwise the next
+ # Interlock the server startup; otherwise the next
# process may not find it there when it expects it.
-
- select(undef, undef, undef, 0.5);
+ while (! stat("$pidfile") ) { select(undef, undef, undef, 0.3); }
return 3;
}
# not drop privilege when -C and -D options are present. To run the exim
# command as root, we use sudo.
-elsif (/^([A-Z_]+=\S+\s+)?(\d+)?\s*(sudo\s+)?exim(_\S+)?\s+(.*)$/)
+elsif (/^([A-Z_]+=\S+\s+)?(\d+)?\s*(sudo(?:\s+-u\s+(\w+))?\s+)?exim(_\S+)?\s+(.*)$/)
{
- $args = $5;
+ $args = $6;
my($envset) = (defined $1)? $1 : "";
- my($sudo) = (defined $3)? "sudo " : "";
- my($special)= (defined $4)? $4 : "";
+ my($sudo) = (defined $3)? "sudo " . (defined $4 ? "-u $4 ":"") : "";
+ my($special)= (defined $5)? $5 : "";
$wait_time = (defined $2)? $2 : 0;
# Return 2 rather than 1 afterwards
"-DEXIM_PATH=$parm_cwd/eximdir/exim$special " .
"-C $parm_cwd/test-config $args " .
">>test-stdout 2>>test-stderr";
-
# If the command is starting an Exim daemon, we run it in the same
# way as the "server" command above, that is, we don't want to wait
# for the process to finish. That happens when "killdaemon" is obeyed later
if ($cmd =~ /\s-DSERVER=server\s/ && $cmd !~ /\s-DNOTDAEMON\s/)
{
+ $pidfile = "$parm_cwd/spool/exim-daemon.pid";
if ($debug) { printf ">> daemon: $cmd\n"; }
run_system("sudo mkdir spool/log 2>/dev/null");
run_system("sudo chown $parm_eximuser:$parm_eximgroup spool/log");
# file is written to the spool directory, in case the Exim binary was
# built with PID_FILE_PATH pointing somewhere else.
- $cmd =~ s!\s-bd\s! -bdf -oP $parm_cwd/spool/exim-daemon.pid !;
+ if ($cmd =~ /\s-oP\s/)
+ {
+ ($pidfile = $cmd) =~ s/^.*-oP ([^ ]+).*$/$1/;
+ $cmd =~ s!\s-bd\s! -bdf !;
+ }
+ else
+ {
+ $pidfile = "$parm_cwd/spool/exim-daemon.pid";
+ $cmd =~ s!\s-bd\s! -bdf -oP $pidfile !;
+ }
print ">> |${cmd}-server\n" if ($debug);
open DAEMONCMD, "|${cmd}-server" || tests_exit(-1, "Failed to run $cmd");
DAEMONCMD->autoflush(1);
while (<SCRIPT>) { $lineno++; last if /^\*{4}\s*$/; } # Ignore any input
- select(undef, undef, undef, 0.3); # Let the daemon get going
+
+ # Interlock with daemon startup
+ while (! stat("$pidfile") ) { select(undef, undef, undef, 0.3); }
return 3; # Don't wait
}
elsif ($cmd =~ /\s-DSERVER=wait:(\d+)\s/)
}
}
+# The "background" command is run but not waited-for, like exim -DSERVER=server.
+# One script line is read and fork-exec'd. The PID is stored for a later
+# killdaemon.
+
+elsif (/^background$/)
+ {
+ my $line;
+# $pidfile = "$parm_cwd/aux-var/server-daemon.pid";
+
+ $_ = <SCRIPT>; $lineno++;
+ chomp;
+ $line = $_;
+ if ($debug) { printf ">> daemon: $line >>test-stdout 2>>test-stderr\n"; }
+
+ my $pid = fork();
+ if (not defined $pid) { die "** fork failed: $!\n" }
+ if (not $pid) {
+ print "[$$]>> ${line}\n" if ($debug);
+ close(STDIN);
+ open(STDIN, "<", "test-stdout");
+ close(STDOUT);
+ open(STDOUT, ">>", "test-stdout");
+ close(STDERR);
+ open(STDERR, ">>", "test-stderr-server");
+ exec "exec ${line}";
+ exit(1);
+ }
+
+# open(my $fh, ">", $pidfile) ||
+# tests_exit(-1, "Failed to open $pidfile: $!");
+# printf($fh, "%d\n", $pid);
+# close($fh);
+
+ while (<SCRIPT>) { $lineno++; last if /^\*{4}\s*$/; } # Ignore any input
+ select(undef, undef, undef, 0.3); # Let the daemon get going
+ return (3, { exim_pid => $pid }); # Don't wait
+ }
+
+
# Unknown command
autoflush STDOUT 1;
print "Exim tester $testversion\n";
+# extend the PATH with .../sbin
+# we map all (.../bin) to (.../sbin:.../bin)
+$ENV{PATH} = do {
+ my %seen = map { $_, 1 } split /:/, $ENV{PATH};
+ join ':' => map { m{(.*)/bin$}
+ ? ( $seen{"$1/sbin"} ? () : ("$1/sbin"), $_)
+ : ($_) }
+ split /:/, $ENV{PATH};
+};
##################################################
# Some tests check created file modes #
##################################################
# If the first character of the first argument is '/', the argument is taken
-# as the path to the binary.
+# as the path to the binary. If the first argument does not start with a
+# '/' but exists in the file system, it's assumed to be the Exim binary.
-$parm_exim = (@ARGV > 0 && $ARGV[0] =~ m?^/?)? shift @ARGV : "";
+$parm_exim = (@ARGV > 0 && (-x $ARGV[0] or $ARGV[0] =~ m?^/?))? Cwd::abs_path(shift @ARGV) : "";
print "Exim binary is $parm_exim\n" if $parm_exim ne "";
if ($arg eq "-NOIPV4") { $have_ipv4 = 0; next; }
if ($arg eq "-NOIPV6") { $have_ipv6 = 0; next; }
if ($arg eq "-KEEP") { $save_output = 1; next; }
+ if ($arg =~ /^-FLAVOU?R$/) { $flavour = shift; next; }
}
$optargs .= " $arg";
}
# directory. Thus, we should choose the highest version of Exim that has
# been compiled.
- if ($f eq "exim4" || $f eq "exim-snapshot")
+ if ($f eq "exim4" || $f eq "exim-snapshot" || $f eq 'src')
{ $srcdir = $f; }
else
{ $srcdir = $f
# deal with TRUSTED_CONFIG_LIST restrictions
unlink("$parm_cwd/test-config") if -e "$parm_cwd/test-config";
-symlink("$parm_cwd/confs/0000", "$parm_cwd/test-config")
- or die "Unable to link initial config into place: $!\n";
+open (IN, "$parm_cwd/confs/0000") ||
+ tests_exit(-1, "Couldn't open $parm_cwd/confs/0000: $!\n");
+open (OUT, ">test-config") ||
+ tests_exit(-1, "Couldn't open test-config: $!\n");
+while (<IN>) { print OUT; }
+close(IN);
+close(OUT);
print("Probing with config file: $parm_cwd/test-config\n");
open(EXIMINFO, "$parm_exim -d -C $parm_cwd/test-config -DDIR=$parm_cwd " .
- "-bP exim_user exim_group|") ||
+ "-bP exim_user exim_group 2>&1|") ||
die "** Cannot run $parm_exim: $!\n";
while(<EXIMINFO>)
{
$parm_eximuser = $1 if /^exim_user = (.*)$/;
$parm_eximgroup = $1 if /^exim_group = (.*)$/;
+ $parm_trusted_config_list = $1 if /^TRUSTED_CONFIG_LIST:.*?"(.*?)"$/;
+ print "$_" if /wrong owner/;
}
close(EXIMINFO);
else { $parm_exim_gid = getgrnam($parm_eximgroup); }
}
+# check the permissions on the TRUSTED_CONFIG_LIST
+if (defined $parm_trusted_config_list)
+ {
+ die "TRUSTED_CONFIG_LIST: $parm_trusted_config_list: $!\n"
+ if not -f $parm_trusted_config_list;
+
+ die "TRUSTED_CONFIG_LIST $parm_trusted_config_list must not be world writable!\n"
+ if 02 & (stat _)[2];
+
+ die sprintf "TRUSTED_CONFIG_LIST: $parm_trusted_config_list %d is group writable, but not owned by group '%s' or '%s'.\n",
+ (stat _)[1],
+ scalar(getgrgid 0), scalar(getgrgid $>)
+ if (020 & (stat _)[2]) and not ((stat _)[5] == $> or (stat _)[5] == 0);
+
+ die sprintf "TRUSTED_CONFIG_LIST: $parm_trusted_config_list is not owned by user '%s' or '%s'.\n",
+ scalar(getpwuid 0), scalar(getpwuid $>)
+ if (not (-o _ or (stat _)[4] == 0));
+
+ open(TCL, $parm_trusted_config_list) or die "Can't open $parm_trusted_config_list: $!\n";
+ my $test_config = getcwd() . '/test-config';
+ die "Can't find '$test_config' in TRUSTED_CONFIG_LIST $parm_trusted_config_list."
+ if not grep { /^$test_config$/ } <TCL>;
+ }
+else
+ {
+ die "Unable to check the TRUSTED_CONFIG_LIST, seems to be empty?\n";
+ }
+
open(EXIMINFO, "$parm_exim -bV -C $parm_cwd/test-config -DDIR=$parm_cwd |") ||
die "** Cannot run $parm_exim: $!\n";
}
+##################################################
+# Check for redis #
+##################################################
+if (defined $parm_lookups{'redis'})
+ {
+ if (system("redis-server -v 2>/dev/null >/dev/null") == 0)
+ {
+ print "The redis-server command works\n";
+ $parm_running{'redis'} = ' ';
+ }
+ else
+ {
+ print "The redis-server command failed: assume Redis not installed\n";
+ }
+ }
+
##################################################
# Test for the basic requirements #
##################################################
$_ =~ /^\s*inet(?:\saddr)?:?\s?(\d+\.\d+\.\d+\.\d+)\s/i)
{
$ip = $1;
- next if ($ip =~ /^127\./);
+ next if ($ip =~ /^127\./ || $ip =~ /^10\./);
$parm_ipv4 = $ip;
}
# because the current binary does not support the right facilities, and also
# those that are outside the numerical range selected.
-print "\nTest range is $test_start to $test_end\n";
+print "\nTest range is $test_start to $test_end (flavour $flavour)\n";
print "Omitting \${dlfunc expansion tests (loadable module not present)\n"
if $dlfunc_deleted;
print "Omitting dbm tests (unable to copy exim_dbmbuild)\n"
foreach $test (@testlist)
{
- next if $test !~ /^\d{4}$/;
+ next if $test !~ /^\d{4}(?:\.\d+)?$/;
next if $test < $test_start || $test > $test_end;
push @test_list, "$testdir/$test";
}
local($lineno) = 0;
local($commandno) = 0;
local($subtestno) = 0;
- local($testno) = substr($test, -4);
+ (local $testno = $test) =~ s|.*/||;
local($sortlog) = 0;
my($gnutls) = 0;
$stdout_skip = 0;
$rmfiltertest = 0;
$is_ipv6test = 0;
+ $TEST_STATE->{munge} = "";
# Remove the associative arrays used to hold checked mail files and msglogs
my($rc, $run_extra) = run_command($testno, \$subtestno, \$expectrc, \$commandname, $TEST_STATE);
my($cmdrc) = $?;
+$0 = "[runtest $testno]";
+
if ($debug) {
print ">> rc=$rc cmdrc=$cmdrc\n";
if (defined $run_extra) {
# The script has finished. Check the all the output that was generated. The
# function returns 0 if all is well, 1 if we should rerun the test (the files
+ # function returns 0 if all is well, 1 if we should rerun the test (the files
# have been updated). It does not return if the user responds Q to a prompt.
if ($retry)
mask: ${mask:192.168.10.206/0}
mask: ${mask:192.168.10.206}
mask: ${mask:a.b.c.d}
+ipv6denorm: ${ipv6denorm:::1}
+ipv6denorm: ${ipv6denorm:fe00::1}
+ipv6denorm: ${ipv6denorm:192.168.0.1}
+ipv6denorm: ${ipv6denorm:fe80::192.168.0.1}
+ipv6norm: ${ipv6norm:0:0:0::1}
+ipv6norm: ${ipv6norm:2a00::0}
+ipv6norm: ${ipv6norm:2a00::1}
+ipv6norm: ${ipv6norm:2a00:eadf:0000:0000:0000:0000:0001:0000}
+ipv6norm: ${ipv6norm:2a00:eadf:0000:0001:0000:0000:0000:0000}
+ipv6norm: ${ipv6norm:2a00:0:0:0::}
+ipv6norm: ${ipv6norm:2a00:2:3:4:5:6:7:8}
nhash: ${nhash_24:monty} ${nhash_8_63:monty python}
lc/uc: ${lc:The Quick} ${uc: Brown Fox}
length: ${length_10:The quick brown fox} ${l_10:abc}
${if ={1}{1} {true}{${if ={1}{1} {true}{${if ={1}{1}{true}fail}}}}}
+# Environment access
+
+${env {USER}}
+${env {NO_SUCH_VARIABLE} {oops, success} {correct}}
+
****
# Test "escape" with print_topbitchars
exim -be -DPTBC=print_topbitchars
****
# Sender host name and address etc, all unset
exim -be
+-be Sender host name and address etc, all unset
-oMa sender_host_address = $sender_host_address
sender_host_port = $sender_host_port
-oMaa sender_host_authenticated = $sender_host_authenticated
****
# Sender host name and address etc, all set except host name.
exim -d-all+expand -be -oMa V4NET.0.0.1.1234 -oMaa AAA -oMai philip -oMas xx@yy.zz -oMi 1.1.1.1.99 -oMr special -oMt me
+-be Sender host name and address etc, all set except host name.
-oMa sender_host_address = $sender_host_address
sender_host_port = $sender_host_port
-oMaa sender_host_authenticated = $sender_host_authenticated
****
# Sender host name explicitly set
exim -be -oMa V4NET.0.0.1.1234 -oMs my.host.name
+-be Sender host name explicitly set
-oMa sender_host_address = $sender_host_address
sender_host_port = $sender_host_port
-oMs sender_host_name = $sender_host_name
****
# Sender host name lookup fails (V4NET.11.12.13 is not reverse registered)
exim -be -oMa V4NET.11.12.13
+be Sender host name lookup fails (V4NET.11.12.13 is not reverse registered)
-oMs sender_host_name = $sender_host_name
host_lookup_failed = $host_lookup_failed
****
# Sender host name and protocol set by Sendmail-compatible option
exim -be -pspecial:host.name
+-be Sender host name and protocol set by Sendmail-compatible option
-p received_protocol = $received_protocol
-p sender_host_name = $sender_host_name
****
# we are skipping. The debug output for this test will show when
# the lookup occurs.
exim -d-all+host_lookup+expand -be -oMa V4NET.0.0.1.1234 -oMaa AAA -oMai philip -oMas xx@yy.zz -oMi 1.1.1.1.99 -oMr special -oMt me
+-be Sender host name and address etc, all set except host name
-oMa sender_host_address = $sender_host_address
sender_host_port = $sender_host_port
-oMaa sender_host_authenticated = $sender_host_authenticated
# ACL basic tests
+need_ipv4
+#
exim -bh 1.2.3.4
mail from:<x@y>
rcpt to:<postmaster@test.ex>
rcpt to:<x@y>
quit
****
+# This resolves to a name which will give `try again' when looked up
+exim -bh V4NET.99.99.96
+mail from:<>
+rcpt to:<x@y>
+quit
+****
+exim -bh V4NET.99.99.96
+mail from:<>
+rcpt to:<defer_ok@y>
+quit
+****
exim -bh 29.29.29.29
mail from:<a@localhost>
rcpt to:<x@y>
.
quit
****
+# Syntax error (version 2) in header => should fail
+exim -odq -bs
+mail from:<x@y>
+rcpt to:<x@y>
+data
+To: <dummy@gmail.com
+Subject: incomprehensible
+From: <forged@sender.com
+
+Message 2a
+.
+quit
+****
# Syntax error in header => should fail even with null sender
exim -odq -bs
mail from:<>
exim -odi -f jc@rome -F 'Julius Caesar' -oMa 1.1.1.1 -oMi 2.2.2.2 -oMr latin -oMs forum.rome -oMt jc44bc userx@test.ex
This is a test message.
****
+#
+# fail on bad -oMm message id
1
exim -odi -f jc@rome -F 'Julius Caesar' -oMm 123456-67890-11 -oMt jc44bc userx@test.x
This is a test message.
****
-1
+#
+# do not fail on good -oMm message id
exim -odi -f jc@rome -F 'Julius Caesar' -oMm 10HmaX-0005vi-00 -oMt jc44bc userx@test.x
This is a test message.
****
# +include_unknown, +ignore_unknown, +include_defer, +ignore_defer
+need_ipv4
+#
exim -bh V4NET.0.0.1
mail from:<x@y>
rcpt to:<x@test.ex>
****
dump retry
#
+# one for a lookup-failure (in manualroute)
+exim -odi userx@nonexist
+Test message
+****
+# one for a lookup-failure (in dnslookup)
+exim -odi userx@mxt2.test.ex
+Test message
+****
+dump retry
+#
#
exim -brt x@dark.star.ex
****
****
exim -brt x@not.not.ex
****
+exim -brt x@nonexist.test.ex lookup
+****
+#
+#
+no_msglog_check
-# Sender verification (envelope and header)
+# Sender verification SMTP (envelope and header)
exim -bh 127.0.0.1
mail from:<unknown@test.ex>
rcpt to:<userx@test.ex>
.
quit
****
+# Sender verification (ESMTP)
+exim -bh 127.0.0.1
+ehlo foo.bar
+mail from:<ab@localhost1>
+rset
+ehlo foo.bar
+mail from:<"a b"@localhost2>
+rset
+ehlo foo.bar
+mail from:<"a b"@localhost3> SIZE=1234
+rset
+ehlo foo.bar
+mail from:"a b"@localhost4 SIZE=1234
+rset
+ehlo foo.bar
+mail from:<"a b"@localhost5> PRDR
+quit
+****
# SMTP connection & EHLO/HELO error responses (+log_sender_on_delivery)
need_ipv4
+munge optional_dsn_info
#
+exim -z "Test: temp-rej connect"
+****
server PORT_S
450 I'm busy
QUIT
exim -odi userx@domain1
Test message 1
****
+#
+exim -z "Test: temp-rej helo"
+****
server PORT_S
220 Connected OK
EHLO
****
exim -qf
****
+#
+exim -z "Test: drop conn after banner"
+****
+server PORT_S
+220 Connected OK
+****
+exim -qf
+****
+#
+exim -z "Test: reject connect"
+****
server PORT_S
550 Go away
QUIT
****
exim -qf
****
+#
+exim -z "Test: reject helo"
+****
server PORT_S
220 Connected OK
EHLO
exim -bh 192.168.1.2.99
quit
****
+#
+#
+#
+#
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+sudo exim -DRT -bs -oMa V4NET.9.8.7.1225
+mail from:<x@y.x>
+rcpt to:<x@test.ex>
+data
+this is a message
+.
+quit
+****
+exim -DRT -odi -qf
+****
+#
+#
+killdaemon
# return_path on appendfile and smtp transports
need_ipv4
+munge optional_dsn_info
#
exim -odi -f abc@x.y.z userx
Test message
# serialize_hosts
need_ipv4
#
+# preload the spool
exim -odq a b
.
****
+#
+# a slow server as a test target
server PORT_S
220 ESMTP
EHLO
QUIT
250 OK
****
+#
+# First message should go; second does not wait for 1st complete
+# on same conn due to connection_max_messages, then is deferred
+# as second transport run aborted by serialize_hosts.
+exim -q
+****
+#
+# a server as a test target
+server PORT_S
+220 ESMTP
+EHLO
+250-OK
+250 HELP
+MAIL FROM:
+250 Sender OK
+RCPT TO:
+250 Recipient OK
+DATA
+354 Send data
+.
+250 OK
+QUIT
+250 OK
+****
+#
+# Remaining message on queue should go immediately; no delay
+# associated with retry rules
exim -q
****
-no_msglog_check
# unseen without disable_logging and errors_to = ""
need_ipv4
+munge optional_dsn_info
#
server -t 10 PORT_S 3
220
# unseen with disable_logging and errors_to = "" or forced fail
need_ipv4
+munge optional_dsn_info
#
server -t 10 PORT_S 7
220
# empty transport filter
#
-munge no_tpt_filter_epipe
-#
exim -d-all+transport -odi userx
Testing with filter
****
exim -DFILTER= -d-all+transport -odi userx
Testing without filter
****
+exim -DFILTER='${if={1}{1}{}{}}' -d-all+transport -odi userx
+Testing with expand-to-empty filter
+****
# null reverse lookup result; errors for verify items with no options
exim -DOPT=reverse_host_lookup -bh V4NET.255.255.255
****
-exim -DOPT=reverse_host_lookup/defer_ok -bh V4NET.255.255.255
-****
exim -DOPT=certificate/defer_ok -bh V4NET.255.255.255
****
exim -DOPT=helo/defer_ok -bh V4NET.255.255.255
quit
****
dump callout
+#
+# callout target dumps after random-reject
+server PORT_S 2
+220 Server ready
+EHLO
+250 OK
+MAIL FROM
+250 OK
+RCPT TO
+550 Bad receipient, dropping conn
+>*eof
+220 Server ready
+EHLO
+250 OK
+MAIL FROM
+250 OK
+RCPT TO
+250 OK
+QUIT
+250 OK
+****
+exim -DUSE_SENDER=,random -bs
+ehlo xxxx
+mail from: x12@three.test.ex
+rcpt to: r12@three.test.ex
+quit
+****
+dump callout
server PORT_S
220 Server ready
EHLO
Remove-Me: this header is to be removed
Another: This is another header
Remove-Me-Also: me too!
+Remove-Me-Too: me too!
+Remove-Me-Too2: me too!
****
# Timeout while actually writing the data for a message
need_ipv4
#
-server PORT_S
+server -t 20 PORT_S
220 Welcome
EHLO
250 Hi
# LMTP over TCP/IP - temporary error handling
need_ipv4
+munge optional_dsn_info
# This one has no retry time, so will be bounced immediately.
#
server PORT_S
exim -odi userx@test.ex
Test message
****
+# defers from both
dump retry
-sleep 2
-# At this point, the secondary host should have timed out
+millisleep 2100
+# At this point, the primary host retry rule ehould have timed out
+# and the secondary is ready for a retry
exim -q
****
dump retry
-sleep 1
+millisleep 2100
+# This should be similar
exim -q
****
dump retry
+# with luck this is tried within a second after the previous
+# so the primary gets tried (it's a new RCPT so the existing retry record is irrelevant)
+# but the secondary is not yet ready for a retry (host record)
exim -odi usery@test.ex
Test message 2.
****
-sleep 1
+dump retry
+millisleep 2000
exim -q
****
killdaemon
exim -qf
****
killdaemon
+sleep 1
# This daemon should flush before delaying
exim -DSERVER=server -bd -oX PORT_D
****
--- /dev/null
+# ACL - dnslists in non-smtp ACL
+#
+1
+exim -f ted@29.29.0.com -odq ok1@test.ex
+should fail
+.
+****
+#
+exim -f bill@29.29.29.com -odq ok1@test.ex
+should pass
+.
+****
+#
+no_msglog_check
--- /dev/null
+# -bP
+#
+# Ought to test a non-priv user, checking "hide", but
+# the testsuite cannot do that...
+#
+exim -bP spool_directory
+****
+perl -e 'print "\n";'
+****
+#
+exim -bP host_lookup_order
+****
+perl -e 'print "\n";'
+****
+#
+exim -bP +local_domains
+****
+perl -e 'print "\n";'
+****
+#
+exim -bP transport my_smtp
+****
+perl -e 'print "\n";'
+****
+#
+exim -bP config
+****
--- /dev/null
+# retry: transport identity depending on sender
+# Exim test configuration 0603
+#
+# Add several messages going to the same location
+# And change smtp output based on senders domain
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+exim -bs
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+This is a test message.
+It has three lines.
+This is the last line.
+.
+RSET
+mail from:peter@dustybelt.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: second
+
+This is a second test message.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: third
+Reply-to: some@body
+
+This is a third test message.
+.
+RSET
+mail from:peter@dustybelt.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: secondA
+
+This is a secondA test message.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: third
+Reply-to: some@body
+
+This is a fourth test message.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: third
+Reply-to: some@body
+
+This is a fifth test message.
+.
+quit
+****
+#
+#
+exim -qq
+****
+#
+#
+killdaemon
+no_msglog_check
+
--- /dev/null
+# retry: database continuation record
+# Exim test configuration 0604
+#
+echo Note this takes 3 minutes to run
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+exim -bs
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+This is a test message.
+It has three lines.
+This is the last line.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 1
+
+This is message number 1.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 2
+
+This is message number 2.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 3
+
+This is message number 3.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 4
+
+This is message number 4.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 5
+
+This is message number 5.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 6
+
+This is message number 6.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 7
+
+This is message number 7.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 8
+
+This is message number 8.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 9
+
+This is message number 9.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 10
+
+This is message number 10.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 11
+
+This is message number 11.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 12
+
+This is message number 12.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 13
+
+This is message number 13.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 14
+
+This is message number 14.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 15
+
+This is message number 15.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 16
+
+This is message number 16.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 17
+
+This is message number 17.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 18
+
+This is message number 18.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 19
+
+This is message number 19.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 20
+
+This is message number 20.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 21
+
+This is message number 21.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 22
+
+This is message number 22.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 23
+
+This is message number 23.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 24
+
+This is message number 24.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 25
+
+This is message number 25.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 26
+
+This is message number 26.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 27
+
+This is message number 27.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 28
+
+This is message number 28.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 29
+
+This is message number 29.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 30
+
+This is message number 30.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 31
+
+This is message number 31.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 32
+
+This is message number 32.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 33
+
+This is message number 33.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 34
+
+This is message number 34.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 35
+
+This is message number 35.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 36
+
+This is message number 36.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 37
+
+This is message number 37.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 38
+
+This is message number 38.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 39
+
+This is message number 39.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 40
+
+This is message number 40.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 41
+
+This is message number 41.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 42
+
+This is message number 42.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 43
+
+This is message number 43.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 44
+
+This is message number 44.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 45
+
+This is message number 45.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 46
+
+This is message number 46.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 47
+
+This is message number 47.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 48
+
+This is message number 48.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 49
+
+This is message number 49.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 50
+
+This is message number 50.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 51
+
+This is message number 51.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 52
+
+This is message number 52.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 53
+
+This is message number 53.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 54
+
+This is message number 54.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 55
+
+This is message number 55.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 56
+
+This is message number 56.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 57
+
+This is message number 57.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 58
+
+This is message number 58.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 59
+
+This is message number 59.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 60
+
+This is message number 60.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 61
+
+This is message number 61.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 62
+
+This is message number 62.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 63
+
+This is message number 63.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 64
+
+This is message number 64.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 65
+
+This is message number 65.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 66
+
+This is message number 66.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 67
+
+This is message number 67.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 68
+
+This is message number 68.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 69
+
+This is message number 69.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 70
+
+This is message number 70.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 71
+
+This is message number 71.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 72
+
+This is message number 72.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 73
+
+This is message number 73.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 74
+
+This is message number 74.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 75
+
+This is message number 75.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 76
+
+This is message number 76.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 77
+
+This is message number 77.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 78
+
+This is message number 78.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 79
+
+This is message number 79.
+.
+RSET
+mail from:ralph@dustyshoes.tld
+rcpt to:bob@anotherone.tld
+data
+Subject: message_id 80
+
+This is message number 80.
+.
+quit
+****
+#
+#
+exim -qq
+****
+#
+#
+killdaemon
+no_msglog_check
+
--- /dev/null
+# dns retry in hostlist
+# Exim test configuration 0605
+#
+need_ipv4
+#
+exim -bh HOSTIPV4
+helo test
+mail from:<ralph@dustyshoes.tld>
+rcpt to:<bob@anotherone.tld>
+quit
+****
--- /dev/null
+# dns log long lookups
+# Exim test configuration 0606
+#
+munge delay_1500
+#
+exim -bh 127.0.0.1
+helo test
+mail from:<ralph@dustyshoes.tld>
+rcpt to:<should_log@delay1500.test.ex>
+quit
+****
+#
+#
+exim -bh 127.0.0.1
+helo test
+mail from:<ralph@dustyshoes.tld>
+rcpt to:<should_not_log@delay500.test.ex>
+quit
+****
--- /dev/null
+# delivery to cname
+# Exim test configuration 0607
+#
+need_ipv6
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+exim -bs
+MAIL FROM:<CALLER@myhost.test.ex>
+RCPT TO: <testx@cname46.test.ex>
+DATA
+Subject: test
+
+foo
+.
+RSET
+MAIL FROM:<CALLER@myhost.test.ex>
+RCPT TO: <testx@cname4.test.ex>
+DATA
+Subject: test
+
+foo
+.
+QUIT
+****
+#
+exim -qq
+****
+#
+killdaemon
+no_msglog_check
--- /dev/null
+# HELO verify dnssec
+# Exim test configuration 0608
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+client 127.0.0.1 PORT_D
+??? 220
+HELO localhost
+??? 250
+****
+#
+client 127.0.0.1 PORT_D
+??? 220
+HELO l-sec
+??? 250
+****
+#
+killdaemon
+no_msglog_check
--- /dev/null
+# Long ACL delay, truncated
+munge debug_pid
+need_ipv4
+#
+# We want the debug note of a truncated delay
+exim -d-all+acl -DSERVER=server -odq -bd -oX PORT_D
+****
+#
+# Server delays 4s before accepting RCPT
+client 127.0.0.1 PORT_D
+??? 220
+mail from:<x@y.test.ex>
+??? 250
+rcpt to:<delay4_accept@y.test.ex>
+??? 250
+quit
+??? 221
+****
+#
+# Server delays 4s before accepting RCPT
+# but client closes connection
+client 127.0.0.1 PORT_D
+??? 220
+mail from:<x@y.test.ex>
+??? 250
+rcpt to:<delay4_accept@y.test.ex>
+****
+killdaemon
+no_msglog_check
--- /dev/null
+# retry: transport with fixed interface
+# Exim test configuration 0610
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+exim -bs
+MAIL FROM:<t1@dustyshoes.tld>
+RCPT TO:<fred@anotherone.tld>
+DATA
+This is a test message.
+.
+RSET
+MAIL FROM:<t2@dustybelt.tld>
+RCPT TO:<fred@anotherone.tld>
+DATA
+Subject: second
+
+This is a second test message.
+.
+QUIT
+****
+#
+#
+exim -qq
+****
+#
+# Should get two separate retry records.
+dump retry
+#
+#
+killdaemon
+no_msglog_check
--- /dev/null
+# max_parallel on transport
+need_ipv4
+#
+# Remote transport:
+# preload the spool
+exim -odq a b c
+.
+****
+#
+# a slow server as a test target
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+# First and second messages should go, as separate conns due to
+# connection_max_messages, third is deferred
+# as third transport run denied by max_parallel
+exim -q
+****
+#
+#
+# Remaining message on queue should go immediately; no delay
+# associated with retry rules
+exim -q
+****
+killdaemon
+#
+########
+#
+#
+# Local transport:
+# Only one message should go as the transport takes a long
+# time and we set max_parallel=1 to serialize it
+exim y
+****
+exim z
+****
+#
+#
+sleep 3
+#
+# Remaining message on queue should go immediately; no delay
+# associated with retry rules
+exim -q
--- /dev/null
+# log_defer_output on pipe transport
+#
+#XXX maybe collapse into 0048?
+#
+munge sys_bindir
+#
+exim a
+****
+sleep 1
+no_msglog_check
--- /dev/null
+# manualroute, hosts_randomize and multiple recipients
+#
+#
+exim -z '"Network error" here is expected. We must not get an mua_wrapper fault.'
+****
+#
+1
+exim -bm a b c d
+Subject: test
+
+data
+.
+****
+no_msglog_check
--- /dev/null
+# hosts_connection_nolog versus sender_host lists caching
+exim -bd -DSERVER=server -oX PORT_D
+****
+#
+# Will not log connection due to hosts_connection_nolog
+client 127.0.0.1 PORT_D
+??? 220
+QUIT
+****
+#
+# Connection should be logged
+client HOSTIPV4 PORT_D
+??? 220
+QUIT
+****
+#
+killdaemon
# TLS client: TLS setup fails - retry in clear
#
# For this first GnuTLS test, we do not obey "gnutls", so that Exim has to
-# create the GnuTLS paramter data for itself.
+# create the GnuTLS parameter data for itself.
#
echo ==> Creating GnuTLS parameter data ...
exim -DSERVER=server -bd -oX PORT_D
-# TLS: ACL encryption test
+# TLS ACL encryption test
gnutls
exim -DSERVER=server -bd -oX PORT_D
****
--- /dev/null
+# TLS client: verify certificate from server - name-fails
+gnutls
+exim -DSERVER=server -bd -oX PORT_D
+****
+# this will fail to verify the cert name and fallback to unencrypted
+exim userr@test.ex
+Testing
+****
+# this will pass the cert verify including name check
+exim users@test.ex
+Testing
+****
+# this will fail to verify the cert name but carry on (try-verify mode)
+exim usert@test.ex
+Testing
+****
+exim -qf
+****
+killdaemon
+no_msglog_check
# TLS client: verify certificate from server - fails
exim -DSERVER=server -bd -oX PORT_D
****
+#
+#
+exim -z 'this will fail to verify the cert at HOSTIPV4 so fail the crypt requirement'
+****
exim userx@test.ex
Testing
****
+#
+#
+exim -z 'this will fail to verify the cert at HOSTIPV4 so fail the crypt, then retry on 127.1; ok'
+****
exim usery@test.ex
Testing
****
+#
+#
+exim -z 'this will fail to verify the cert but continue unverified though crypted'
+****
exim userz@test.ex
Testing
****
+#
+#
+exim -z 'this will fail to verify the cert at HOSTIPV4 and fallback to unencrypted'
+****
exim userq@test.ex
Testing
****
+#
+#
+exim -z 'this will fail to verify the cert name and fallback to unencrypted'
+****
exim userr@test.ex
Testing
****
+#
+#
+exim -z 'this will pass the cert verify including name check'
+****
exim users@test.ex
Testing
****
+#
+#
exim -qf
****
killdaemon
****
millisleep 500
killdaemon
+sleep 2
exim CALLER@test.ex
Test message.
****
-millisleep 500
+sleep 2
#
#
# Extended: server uses SNI to change certificate
#
#
killdaemon
+sleep 2
--- /dev/null
+# TLS client: verify certificate from server - name-fails
+exim -DSERVER=server -bd -oX PORT_D
+****
+# this will fail to verify the cert at HOSTIPV4 and fallback to unencrypted
+exim userq@test.ex
+Testing
+****
+# this will fail to verify the cert name and fallback to unencrypted
+exim userr@test.ex
+Testing
+****
+# this will pass the cert verify including name check
+exim users@test.ex
+Testing
+****
+# this will fail to verify the cert name but carry on (try-verify mode)
+exim usert@test.ex
+Testing
+****
+exim -qf
+****
+killdaemon
+no_msglog_check
csa=csa1.test.ex ${lookup dnsdb{csa=csa1.test.ex}}
csa=csa2.test.ex ${lookup dnsdb{csa=csa2.test.ex}}
+soa=test.ex ${lookup dnsdb{soa=test.ex}{$value}{fail}}
+soa=a.test.ex ${lookup dnsdb{>:, soa=test.ex}{$value}{fail}}
+
# DNS lookups with multiple items
ten-1:ten2 ${lookup dnsdb{a=ten-1.test.ex:ten-2.test.ex}}
defer_never:ten-1 ${lookup dnsdb{defer_never,a=test.again.dns:ten-1.test.ex}}
defer_never:defer ${lookup dnsdb{defer_never,a=test.again.dns:test.again.dns}}
defer_strict:ten-1 ${lookup dnsdb{defer_strict,a=test.again.dns:ten-1.test.ex}}
+
+# Retry timeout and count. This only tests the syntax; we do not
+# have any good way of testing the function.
+
+delay1500 ${lookup dnsdb{retrans_1s,retry_2,a=delay1500.test.ex}}
+****
+#
+# Cacheability
+exim -d-all+lookup -be
+a=localhost.test.ex ${lookup dnsdb{a=localhost.test.ex}{$value}fail}
+a=localhost.test.ex ${lookup dnsdb{a=localhost.test.ex}{$value}fail}
+****
+#
+# TTL-limited noncacheability
+exim -d-all+lookup -odq user@shorthost.test.ex
****
+#
+no_msglog_check
+#
# query-style lookup in domains, local_parts, senders
+need_ipv4
+munge debug_pid
exim -d -bt test.ex@test.ex unknown@test.ex
****
2
exim -f a@b.c -bt test.ex@test.ex unknown@test.ex
****
+#
+#
+# lookup non/cacheability, lookup done as a list item
+exim -d-all+lookup -odq -f a@shorthost.test.ex t@test.ex
+****
+#
+#
+# lookup non/cacheability, lookup done for a dnslists= ACL condition
+exim -DSERVER=server -d-all+dnsbl -bd -oX PORT_D
+****
+exim -q
+****
+#
+killdaemon
+millisleep 500
+no_msglog_check
+#
--- /dev/null
+# Redis lookups and quoting
+#
+background
+redis-server
+****
+exim -be -d-all+expand+lookup
+${lookup redis{set keyname ${quote_redis:objvalue plus}}}
+${lookup redis{get keyname}}
+****
+#
+killdaemon
+no_stderr_check
--- /dev/null
+lookup redis
+running redis
${perl{return_scalar}}
${perl{return_list}}
${perl{return_variable_vector}}
-${perl{return_hash}}
+${sg{${perl{return_hash}}}{\\d+}{X}}
$tod_full // ${perl{change_locale}} // $tod_full
****
--- /dev/null
+# TLS authentication (server only)
+munge tls_anycipher
+#
+exim -DSERVER=server -bd -oX PORT_D:PORT_S
+****
+exim -f ok@test.ex x@y
+****
+exim -f ok@test.ex smtps@y
+****
+exim -q
+****
+killdaemon
+no_msglog_check
--- /dev/null
+authenticator tls
+running IPv4
.
quit
****
+#
+#
+# This one has a different rotten parameter, but should not induce a crash
+#
+exim -odi -bs
+ehlo test.ex
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+Date: Fri, 17 Dec 2004 14:35:01 +0100
+From: J Caesar <jcaesar@test.ex>
+To: a-list00@exim.org
+Message-ID: <20041217133501.GA3059@test.ex>
+Mime-Version: 1.0
+Content-Type: text/html;
+ charset=UTF-8;
+ name=""
+Content-Disposition: inline
+Subject: Nasty
+
+--T4sUOijqQbZv57TR
+Content-Type: text/plain;
+
+foobar
+
+--T4sUOijqQbZv57TR--
+.
+quit
+****
+#
+#
+# This one has a 3rd rotten parameter style
+#
+exim -odi -bs
+ehlo test.ex
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+Date: Fri, 17 Dec 2004 14:35:01 +0100
+From: J Caesar <jcaesar@test.ex>
+To: a-list00@exim.org
+Message-ID: <20041217133501.GA3059@test.ex>
+Mime-Version: 1.0
+Content-Type: text/plain; charset="utf-8""
+Content-Disposition: inline
+Subject: Nasty3
+
+--T4sUOijqQbZv57TR
+Content-Type: text/plain;
+
+foobar
+
+--T4sUOijqQbZv57TR--
+.
+quit
+****
+#
+#
+# This one has a some unrecognised params
+#
+exim -odi -bs
+ehlo test.ex
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+Date: Fri, 17 Dec 2004 14:35:01 +0100
+From: J Caesar <jcaesar@test.ex>
+To: a-list00@exim.org
+Message-ID: <20041217133501.GA3059@test.ex>
+Mime-Version: 1.0
+Content-Type: text/plain;
+ garbage1;
+ garbage2=foo;
+ garbage3="bar"foo;
+ charset=UTF-8;
+ garbage4=";
+Content-Disposition: inline
+Subject: Nasty4
+
+--T4sUOijqQbZv57TR
+Content-Type: text/plain;
+
+foobar
+
+--T4sUOijqQbZv57TR--
+.
+quit
+****
+#
+# This one has two attachments, using different encodings
+exim -odi -bs
+ehlo test.ex
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+Date: Fri, 17 Dec 2004 14:35:01 +0100
+Message-ID: <20041217133501.GA3058@test.ex>
+Subject: Nasty5
+Mime-Version: 1.0
+Content-Type: multipart/mixed; boundary="T4sUOijqQbZv57TR"
+
+--T4sUOijqQbZv57TR
+Content-Type: text/plain; charset=us-ascii
+Content-Disposition: attachment; filename="=?iso-8859-1?Q?test_=E4_test1?="
+
+(content 1: filename is rfc2047 encoded)
+
+--T4sUOijqQbZv57TR
+Content-Type: text/plain; charset=us-ascii
+Content-Disposition: attachment; filename*=ISO-8859-1''%74%65%73%74%20%E4%20%74%65%73%74%32
+
+(content 2: filename is rfc2231 encoded)
+
+--T4sUOijqQbZv57TR--
+.
+quit
+****
+#
+#
+# This one has a legit param; empty charset
+#
+exim -odi -bs
+ehlo test.ex
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+Date: Fri, 17 Dec 2004 14:35:01 +0100
+From: J Caesar <jcaesar@test.ex>
+To: a-list00@exim.org
+Message-ID: <20041217133502.GA3059@test.ex>
+Mime-Version: 1.0
+Content-Type: application/pdf;
+ name*=''2015.11.13%20-%20Pr%C3%A4sentation%20GI%20-%20LK.PDF
+Content-Disposition: attachment;
+ filename*=''2015.11.13%20-%20Pr%C3%A4sentation%20GI%20-%20LK.PDF
+Subject: Nasty6
+
+--T4sUOijqQbZv57TR
+Content-Type: text/plain;
+
+foobar
+
+--T4sUOijqQbZv57TR--
+.
+quit
+****
# content scan interface: f-protd
+need_ipv4
+munge loopback
#
server PORT_S
<GET
****
#
#
-# Need to additionally test the timeout / defer_ok case
+#
+#
+server -i 2 DIR/eximdir/clam_sock
+<SCAN
+>LF>scanned_file_name: OK
+<*eof
+****
+#
+exim -odi -bs -DCONTROL="retry=4s"
+ehlo test.ex
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+Date: Fri, 17 Dec 2004 14:35:01 +0100
+Subject: message should be accepted after a retry
+
+.
+quit
+****
+#
>LF>220 ready
<SCAN
>LF>210 SCAN DATA
->LF>b\ l\ a\ h [L]9.9 9 VNAME
+>LF>b\\ l\\ a\\ h [L]9.9 9 VNAME
>LF>200 SCAN OK
<QUIT
<*eof
--- /dev/null
+# content scan interface: rspamd
+#
+# The spooled file for scanning includes the test-runner's user name
+# hence size varies. Munge that.
+munge scanfile_size
+#
+server 11333
+<CHECK RSPAMC/1.3\r
+<Content-length:
+<Queue-Id:
+<From:
+<Recipient-Number: 1\r
+<Rcpt:
+<Helo:
+<User:
+<\r
+<From
+<X-Envelope-From
+<X-Envelope-To
+<Received:
+< by
+< (envelope
+< id
+< for
+<From:
+<Content-type: text/plain
+<Message-Id:
+<Sender:
+<Date:
+<
+<test
+>RSPAMD/1.3 0 EX_OK\r
+>Metric: default; True; 15.00 / 15.00 / 0.0\r
+>Action: reject\r
+>Symbol: FAKE_SYMBOL_A(15.00)\r
+>Symbol: FAKE_SYMBOL_B(0.00)\r
+>Message-ID: undef\r
+*eof
+****
+exim -odi -bs
+ehlo test.ex
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+From: MAILER_DAEMON <>
+Content-type: text/plain
+
+test
+.
+quit
+****
--- /dev/null
+# content scan interface: spamassassin
+#
+# The spooled file for scanning includes the test-runner's user name
+# hence size varies. Munge that.
+munge scanfile_size
+#
+#
+# A good-comms test, returning not-spam.
+# (we could use a second one that returns is-spam...)
+server 7833
+<REPORT SPAMC
+<User:
+<Content-length:
+<
+<From
+<X-Envelope-From
+<X-Envelope-To
+<Received:
+< by
+< (envelope
+< id
+< for
+<Content-type: text/plain
+<Message-Id:
+<From:
+<Date:
+<
+<test
+>SPAMD/1.1 0 EX_OK
+>Spam: False ; 4.5 / 5.0
+>
+>Spam detection software, running on the system "demo",
+>has NOT identified this incoming email as spam. The original
+>message has been attached to this so you can view it or label
+>similar future email. If you have any questions, see
+>@@CONTACT_ADDRESS@@ for details.
+>
+>Content preview: test [...]
+>
+>Content analysis details: (4.5 points, 5.0 required)
+>
+> pts rule name description
+>---- ---------------------- --------------------------------------------------
+>-1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP
+> 1.2 MISSING_HEADERS Missing To: header
+> 1.0 MISSING_FROM Missing From: header
+> 1.8 MISSING_SUBJECT Missing Subject: header
+> 1.4 MISSING_DATE Missing Date: header
+> 0.1 MISSING_MID Missing Message-Id: header
+>
+*eof
+****
+exim -odi -bs
+ehlo test.ex
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+Content-type: text/plain
+
+test
+.
+quit
+****
+#
+#
+#
+#
+# Server spec line with timeout option, not exercised
+# (could we cut down the massive content?)
+server 7833
+<REPORT SPAMC
+<User:
+<Content-length:
+<
+<From
+<X-Envelope-From
+<X-Envelope-To
+<Received:
+< by
+< (envelope
+< id
+< for
+<Content-type: text/plain
+<Message-Id:
+<From:
+<Date:
+<
+<test
+>SPAMD/1.1 0 EX_OK
+>Spam: False ; 4.5 / 5.0
+>
+>Spam detection software, running on the system "demo",
+>has NOT identified this incoming email as spam. The original
+>message has been attached to this so you can view it or label
+>similar future email. If you have any questions, see
+>@@CONTACT_ADDRESS@@ for details.
+>
+>Content preview: test [...]
+>
+>Content analysis details: (4.5 points, 5.0 required)
+>
+> pts rule name description
+>---- ---------------------- --------------------------------------------------
+>-1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP
+> 1.2 MISSING_HEADERS Missing To: header
+> 1.0 MISSING_FROM Missing From: header
+> 1.8 MISSING_SUBJECT Missing Subject: header
+> 1.4 MISSING_DATE Missing Date: header
+> 0.1 MISSING_MID Missing Message-Id: header
+>
+*eof
+****
+exim -odi -bs -DOPT='127.0.0.1 7833 retry=10s'
+ehlo test.ex
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+Content-type: text/plain
+
+test
+.
+quit
+****
+#
+#
+#
+# Server spec line with timeout option, exercised
+server -i 2 7833
+<REPORT SPAMC
+<User:
+<Content-length:
+<
+<From
+<X-Envelope-From
+<X-Envelope-To
+<Received:
+< by
+< (envelope
+< id
+< for
+<Content-type: text/plain
+<Message-Id:
+<From:
+<Date:
+<
+<test
+>SPAMD/1.1 0 EX_OK
+>Spam: False ; 4.5 / 5.0
+>
+>Spam detection software, running on the system "demo",
+>has NOT identified this incoming email as spam. The original
+>message has been attached to this so you can view it or label
+>similar future email. If you have any questions, see
+>@@CONTACT_ADDRESS@@ for details.
+>
+>Content preview: test [...]
+>
+>Content analysis details: (4.5 points, 5.0 required)
+>
+> pts rule name description
+>---- ---------------------- --------------------------------------------------
+>-1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP
+> 1.2 MISSING_HEADERS Missing To: header
+> 1.0 MISSING_FROM Missing From: header
+> 1.8 MISSING_SUBJECT Missing Subject: header
+> 1.4 MISSING_DATE Missing Date: header
+> 0.1 MISSING_MID Missing Message-Id: header
+>
+*eof
+****
+exim -odi -bs -DOPT='127.0.0.1 7833 retry=4s'
+ehlo test.ex
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+Content-type: text/plain
+
+test
+.
+quit
+****
+#
+#
+#
+# Multiple servers, prioritised, with timeout spec; first one fails
+# List separator changed
+server 7833
+<REPORT SPAMC
+<User:
+<Content-length:
+<
+<From
+<X-Envelope-From
+<X-Envelope-To
+<Received:
+< by
+< (envelope
+< id
+< for
+<Content-type: text/plain
+<Message-Id:
+<From:
+<Date:
+<
+<test
+>SPAMD/1.1 0 EX_OK
+>Spam: False ; 4.5 / 5.0
+>
+>Spam detection software, running on the system "demo",
+>has NOT identified this incoming email as spam. The original
+>message has been attached to this so you can view it or label
+>similar future email. If you have any questions, see
+>@@CONTACT_ADDRESS@@ for details.
+>
+>Content preview: test [...]
+>
+>Content analysis details: (4.5 points, 5.0 required)
+>
+> pts rule name description
+>---- ---------------------- --------------------------------------------------
+>-1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP
+> 1.2 MISSING_HEADERS Missing To: header
+> 1.0 MISSING_FROM Missing From: header
+> 1.8 MISSING_SUBJECT Missing Subject: header
+> 1.4 MISSING_DATE Missing Date: header
+> 0.1 MISSING_MID Missing Message-Id: header
+>
+*eof
+****
+exim -odi -bs -DOPT='<; 127.0.0.1 7833 ; 127.0.0.2 7834 pri=2 tmo=2s'
+ehlo test.ex
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+Content-type: text/plain
+
+test
+.
+quit
+****
+#
+#
--- /dev/null
+# ACL regex= test
+#
+# These tests are copies from testcase 4000;
+# they should be removed from there but I don't
+# run spamassassin so can't verify the change.
+#
+exim -odi -bs
+ehlo test.ex
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+From: Test person <tp@cam.ac.uk>
+To: Me <userx@test.ex>
+Subject: A real test message
+Date: Fri, 17 Dec 2004 16:13:04 +0100
+Message-ID: <41C2F849.3060203@projectile.test.ex>
+
+OK, this should look like a genuine message.
+.
+quit
+****
+exim -odi -bs
+ehlo test.ex
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+From: Test person <tp@cam.ac.uk>
+To: Me <userx@test.ex>
+Subject: A real test message
+Date: Fri, 17 Dec 2004 16:13:04 +0100
+Message-ID: <41C2F849.3060203@projectile.test.ex>
+FakeReject: test fakereject
+
+OK, this should look like a genuine message, but
+it will trip on THIS gazornenplaz REGEX.
+.
+quit
+****
+++ /dev/null
-# Basic exiscan feature tests
-echo ==> This test may take a bit of time, depending on exactly
-echo ==> how your SpamAssassin is configured.
-exim -odi -bs
-ehlo test.ex
-mail from:<>
-rcpt to:<userx@test.ex>
-data
-A message without any headers.
-.
-quit
-****
-exim -odi -bs
-ehlo test.ex
-mail from:<>
-rcpt to:<userx@test.ex>
-data
-From: Test person <tp@cam.ac.uk>
-To: Me <userx@test.ex>
-Subject: A real test message
-Date: Fri, 17 Dec 2004 16:13:04 +0100
-Message-ID: <41C2F849.3060203@projectile.test.ex>
-
-OK, this should look like a genuine message.
-.
-quit
-****
-exim -odi -bs
-ehlo test.ex
-mail from:<>
-rcpt to:<userx@test.ex>
-data
-From: 99Junk99@somewhere.com
-To:
-Subject: MAKE MONEY FAST!!!!
-Message-id: abcde
-
-This should be enough to trip the threshold.
-.
-quit
-****
-exim -odi -bs
-ehlo test.ex
-mail from:<>
-rcpt to:<userx@test.ex>
-data
-From: Test person <tp@cam.ac.uk>
-To: Me <userx@test.ex>
-Subject: A real test message
-Date: Fri, 17 Dec 2004 16:13:04 +0100
-Message-ID: <41C2F849.3060203@projectile.test.ex>
-FakeReject: test fakereject
-
-OK, this should look like a genuine message, but
-it will trip on THIS REGEX.
-.
-quit
-****
-exim -odi -bs
-ehlo test.ex
-mail from:<>
-rcpt to:<userx@test.ex>
-data
-Date: Fri, 17 Dec 2004 14:35:01 +0100
-From: J Caesar <jcaesar@test.ex>
-To: a-list00@exim.org
-Message-ID: <20041217133501.GA3058@test.ex>
-Mime-Version: 1.0
-Content-Type: multipart/mixed; boundary="T4sUOijqQbZv57TR"
-Content-Disposition: inline
-Subject: [exim] Re: Bug#286074: eximstats: uses message count as data for
- the "volume" charts
-X-BeenThere: a-list00@exim.org
-X-Mailman-Version: 2.1.5
-Precedence: list
-
---T4sUOijqQbZv57TR
-Content-Type: text/plain; charset=US-ASCII
-Content-Transfer-Encoding: quoted-printable
-Content-Disposition: inline
-
-Test quoted-printable =3D
-Space at end of line=40
-Continued line =
-with this text.
-
---T4sUOijqQbZv57TR
-Content-Type: text/plain; charset=us-ascii
-Content-Disposition: inline
-
-There was a part of the patch missing, complete one is attached.
- sorry for wasting your time
-
---T4sUOijqQbZv57TR
-Content-Type: text/plain; charset=us-ascii
-Content-Disposition: attachment; filename=working-patch
-
---- /usr/sbin/eximstats 2004-12-17 13:36:44.381983753 +0100
-+++ eximstats 2004-12-17 13:47:37.763185260 +0100
-@@ -1107,11 +1107,11 @@
- if (scalar @chartdatanames < $ntopchart)
- {
- push(@chartdatanames, $key);
-- push(@chartdatavals, $$m_count{$key});
-+ push(@chartdatavals, $$m_data{$key});
- }
- else
- {
-- $chartotherval += $$m_count{$key};
-+ $chartotherval += $$m_data{$key};
- }
- }
- push(@chartdatanames, "Other");
-
---T4sUOijqQbZv57TR
-Content-Type: text/plain; charset="us-ascii"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Content-Disposition: inline
-
---
-
---T4sUOijqQbZv57TR--
-.
-quit
-****
-# Non-smtp message
-exim -odi userx@test.ex
-A message without any headers.
-.
-****
-# Non-smtp MIME message
-exim -odi userx@test.ex
-Date: Fri, 17 Dec 2004 14:35:01 +0100
-From: J Caesar <jcaesar@test.ex>
-To: a-list00@exim.org
-Message-ID: <20041217133501.GA3058@test.ex>
-Mime-Version: 1.0
-Content-Type: multipart/mixed; boundary="T4sUOijqQbZv57TR"
-Content-Disposition: inline
-Subject: [exim] Re: Bug#286074: eximstats: uses message count as data for
- the "volume" charts
-X-BeenThere: a-list00@exim.org
-X-Mailman-Version: 2.1.5
-Precedence: list
-
---T4sUOijqQbZv57TR
-Content-Type: text/plain; charset=us-ascii
-Content-Disposition: inline
-
-There was a part of the patch missing, complete one is attached.
- sorry for wasting your time
-
---T4sUOijqQbZv57TR
-Content-Type: text/plain; charset=us-ascii
-Content-Disposition: attachment; filename=working-patch
-
---- /usr/sbin/eximstats 2004-12-17 13:36:44.381983753 +0100
-+++ eximstats 2004-12-17 13:47:37.763185260 +0100
-@@ -1107,11 +1107,11 @@
- if (scalar @chartdatanames < $ntopchart)
- {
- push(@chartdatanames, $key);
-- push(@chartdatavals, $$m_count{$key});
-+ push(@chartdatavals, $$m_data{$key});
- }
- else
- {
-- $chartotherval += $$m_count{$key};
-+ $chartotherval += $$m_data{$key};
- }
- }
- push(@chartdatanames, "Other");
-
---T4sUOijqQbZv57TR
-Content-Type: text/plain; charset="us-ascii"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Content-Disposition: inline
-
---
-
---T4sUOijqQbZv57TR--
-****
-exim -odi -bs
-ehlo test.ex
-mail from:<>
-rcpt to:<userx@test.ex>
-data
-From: Test person <tp@cam.ac.uk>
-To: Me <userx@test.ex>
-Subject: A real test message
-Date: Fri, 17 Dec 2004 16:13:04 +0100
-Message-ID: <41C2F849.3060203@projectile.test.ex>
-FakeDefer: test fakedefer
-
-OK, this should look like a genuine message, but
-it will trip on THIS REGEX.
-.
-quit
-****
-# Very simple virus test
-exim -odi -bs
-mail from:<>
-rcpt to:<userx@test.ex>
-data
-Subject: a virus test
-
-X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*
-.
-quit
-****
+++ /dev/null
-support Content_Scanning
-running SpamAssassin
-running ClamAV
--- /dev/null
+# content scan interface: spamassassin / ipv6
+#
+# Multiple servers, prioritised, with timeout spec; first one fails
+# List separator changed
+server 7833
+<REPORT SPAMC
+<User:
+<Content-length:
+<
+<From
+<X-Envelope-From
+<X-Envelope-To
+<Received:
+< by
+< (envelope
+< id
+< for
+<Content-type: text/plain
+<Message-Id:
+<From:
+<Date:
+<
+<test
+>SPAMD/1.1 0 EX_OK
+>Spam: False ; 4.5 / 5.0
+>
+>Spam detection software, running on the system "demo",
+>has NOT identified this incoming email as spam. The original
+>message has been attached to this so you can view it or label
+>similar future email. If you have any questions, see
+>@@CONTACT_ADDRESS@@ for details.
+>
+>Content preview: test [...]
+>
+>Content analysis details: (4.5 points, 5.0 required)
+>
+> pts rule name description
+>---- ---------------------- --------------------------------------------------
+>-1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP
+> 1.2 MISSING_HEADERS Missing To: header
+> 1.0 MISSING_FROM Missing From: header
+> 1.8 MISSING_SUBJECT Missing Subject: header
+> 1.4 MISSING_DATE Missing Date: header
+> 0.1 MISSING_MID Missing Message-Id: header
+>
+*eof
+****
+exim -odi -bs -DOPT='<; 127.0.0.1 7833 ; ::1 7834 pri=2 tmo=2s'
+ehlo test.ex
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+Content-type: text/plain
+
+test
+.
+quit
+****
+#
+#
--- /dev/null
+support Content_Scanning
+support IPv6
--- /dev/null
+# Basic exiscan feature tests
+echo ==> This test may take a bit of time, depending on exactly
+echo ==> how your SpamAssassin is configured.
+exim -odi -bs
+ehlo test.ex
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+A message without any headers.
+.
+quit
+****
+exim -odi -bs
+ehlo test.ex
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+From: Test person <tp@cam.ac.uk>
+To: Me <userx@test.ex>
+Subject: A real test message
+Date: Fri, 17 Dec 2004 16:13:04 +0100
+Message-ID: <41C2F849.3060203@projectile.test.ex>
+
+OK, this should look like a genuine message.
+.
+quit
+****
+exim -odi -bs
+ehlo test.ex
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+From: 99Junk99@somewhere.com
+To:
+Subject: MAKE MONEY FAST!!!!
+Message-id: abcde
+
+This should be enough to trip the threshold.
+.
+quit
+****
+exim -odi -bs
+ehlo test.ex
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+From: Test person <tp@cam.ac.uk>
+To: Me <userx@test.ex>
+Subject: A real test message
+Date: Fri, 17 Dec 2004 16:13:04 +0100
+Message-ID: <41C2F849.3060203@projectile.test.ex>
+FakeReject: test fakereject
+
+OK, this should look like a genuine message, but
+it will trip on THIS REGEX.
+.
+quit
+****
+exim -odi -bs
+ehlo test.ex
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+Date: Fri, 17 Dec 2004 14:35:01 +0100
+From: J Caesar <jcaesar@test.ex>
+To: a-list00@exim.org
+Message-ID: <20041217133501.GA3058@test.ex>
+Mime-Version: 1.0
+Content-Type: multipart/mixed; boundary="T4sUOijqQbZv57TR"
+Content-Disposition: inline
+Subject: [exim] Re: Bug#286074: eximstats: uses message count as data for
+ the "volume" charts
+X-BeenThere: a-list00@exim.org
+X-Mailman-Version: 2.1.5
+Precedence: list
+
+--T4sUOijqQbZv57TR
+Content-Type: text/plain; charset=US-ASCII
+Content-Transfer-Encoding: quoted-printable
+Content-Disposition: inline
+
+Test quoted-printable =3D
+Space at end of line=40
+Continued line =
+with this text.
+
+--T4sUOijqQbZv57TR
+Content-Type: text/plain; charset=us-ascii
+Content-Disposition: inline
+
+There was a part of the patch missing, complete one is attached.
+ sorry for wasting your time
+
+--T4sUOijqQbZv57TR
+Content-Type: text/plain; charset=us-ascii
+Content-Disposition: attachment; filename=working-patch
+
+--- /usr/sbin/eximstats 2004-12-17 13:36:44.381983753 +0100
++++ eximstats 2004-12-17 13:47:37.763185260 +0100
+@@ -1107,11 +1107,11 @@
+ if (scalar @chartdatanames < $ntopchart)
+ {
+ push(@chartdatanames, $key);
+- push(@chartdatavals, $$m_count{$key});
++ push(@chartdatavals, $$m_data{$key});
+ }
+ else
+ {
+- $chartotherval += $$m_count{$key};
++ $chartotherval += $$m_data{$key};
+ }
+ }
+ push(@chartdatanames, "Other");
+
+--T4sUOijqQbZv57TR
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Content-Disposition: inline
+
+--
+
+--T4sUOijqQbZv57TR--
+.
+quit
+****
+# Non-smtp message
+exim -odi userx@test.ex
+A message without any headers.
+.
+****
+# Non-smtp MIME message
+exim -odi userx@test.ex
+Date: Fri, 17 Dec 2004 14:35:01 +0100
+From: J Caesar <jcaesar@test.ex>
+To: a-list00@exim.org
+Message-ID: <20041217133501.GA3058@test.ex>
+Mime-Version: 1.0
+Content-Type: multipart/mixed; boundary="T4sUOijqQbZv57TR"
+Content-Disposition: inline
+Subject: [exim] Re: Bug#286074: eximstats: uses message count as data for
+ the "volume" charts
+X-BeenThere: a-list00@exim.org
+X-Mailman-Version: 2.1.5
+Precedence: list
+
+--T4sUOijqQbZv57TR
+Content-Type: text/plain; charset=us-ascii
+Content-Disposition: inline
+
+There was a part of the patch missing, complete one is attached.
+ sorry for wasting your time
+
+--T4sUOijqQbZv57TR
+Content-Type: text/plain; charset=us-ascii
+Content-Disposition: attachment; filename=working-patch
+
+--- /usr/sbin/eximstats 2004-12-17 13:36:44.381983753 +0100
++++ eximstats 2004-12-17 13:47:37.763185260 +0100
+@@ -1107,11 +1107,11 @@
+ if (scalar @chartdatanames < $ntopchart)
+ {
+ push(@chartdatanames, $key);
+- push(@chartdatavals, $$m_count{$key});
++ push(@chartdatavals, $$m_data{$key});
+ }
+ else
+ {
+- $chartotherval += $$m_count{$key};
++ $chartotherval += $$m_data{$key};
+ }
+ }
+ push(@chartdatanames, "Other");
+
+--T4sUOijqQbZv57TR
+Content-Type: text/plain; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Content-Disposition: inline
+
+--
+
+--T4sUOijqQbZv57TR--
+****
+exim -odi -bs
+ehlo test.ex
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+From: Test person <tp@cam.ac.uk>
+To: Me <userx@test.ex>
+Subject: A real test message
+Date: Fri, 17 Dec 2004 16:13:04 +0100
+Message-ID: <41C2F849.3060203@projectile.test.ex>
+FakeDefer: test fakedefer
+
+OK, this should look like a genuine message, but
+it will trip on THIS REGEX.
+.
+quit
+****
+# Very simple virus test
+exim -odi -bs
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+Subject: a virus test
+
+X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*
+.
+quit
+****
--- /dev/null
+support Content_Scanning
+running SpamAssassin
+running ClamAV
--- /dev/null
+# socks5 proxy on smtp transport
+#
+munge loopback
+#
+# auth: null
+server PORT_D
+<<\x05\x01\x00
+>>\x05\x00
+<<\x05\x01\x00\x01\x7f\x00\x00\x01\x04\xc8
+>>\x05\x00\x00\x01\x7f\x00\x00\x01\xbe\xef
+220 Connected OK
+EHLO
+250-server id
+250
+MAIL FROM
+250
+RCPT TO
+250
+DATA
+354 hit me
+.
+250 accepted OK
+QUIT
+250 bye
+****
+#
+#
+#
+exim -odi -bs -DOPT=
+ehlo test.ex
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+Date: Fri, 17 Dec 2004 14:35:01 +0100
+Subject: message should be sent
+
+via null-auth proxy
+.
+quit
+****
+#
+#
+#
+# auth: username/password
+server PORT_D
+<<\x05\x01\x02
+>>\x05\x02
+<<\x01\x04fred\x05fubar
+>>\x01\x00
+<<\x05\x01\x00\x01\x7f\x00\x00\x01\x04\xc8
+>>\x05\x00\x00\x01\x7f\x00\x00\x01\xbe\xef
+220 Connected OK
+EHLO
+250-server id
+250
+MAIL FROM
+250
+RCPT TO
+250
+DATA
+354 hit me
+.
+250 accepted OK
+QUIT
+250 bye
+****
+#
+#
+#
+exim -odi -bs -DOPT="auth=name name=fred pass=fubar"
+ehlo test.ex
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+Date: Fri, 17 Dec 2004 14:35:01 +0100
+Subject: message should be sent
+
+via name/pwd-auth proxy
+.
+quit
+****
+#
+#
+#
+
--- /dev/null
+support SOCKS
--- /dev/null
+# socks5 proxy on smtp/starttls transport
+#
+munge loopback
+gnutls
+#
+# a TLS-capable server to receive the mail
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+#
+# THIS TEST ASSUMES we have a socks proxy
+# running and listening on 1080
+#
+# a mail sender
+exim -odi -bs -DOPT=
+ehlo test.ex
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+Date: Fri, 17 Dec 2004 14:35:01 +0100
+Subject: message should be sent
+
+via null-auth proxy
+.
+quit
+****
+#
+#
+killdaemon
+no_msglog_check
--- /dev/null
+support SOCKS
+support GnuTLS
+running IPv4
+running socks
--- /dev/null
+# socks5 proxy on smtp/starttls transport
+#
+munge loopback
+#
+#
+# a TLS-capable server to receive the mail
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+#
+# THIS TEST ASSUMES we have a socks proxy
+# running and listening on 1080
+#
+# a mail sender
+exim -odi -bs -DOPT=
+ehlo test.ex
+mail from:<>
+rcpt to:<userx@test.ex>
+data
+Date: Fri, 17 Dec 2004 14:35:01 +0100
+Subject: message should be sent
+
+via null-auth proxy
+.
+quit
+****
+#
+#
+killdaemon
+no_msglog_check
--- /dev/null
+support SOCKS
+support OpenSSL
+running IPv4
+running socks
--- /dev/null
+# Internationalisation: expansions
+#
+# Sample strings taken from RFC3942
+
+exim -be
+
+utf-8 localpart to a-label:
+
+${utf8_localpart_to_alabel:\xD9\x84}
+xn--ghb
+
+${utf8_localpart_to_alabel:\xD9\x84\xD9\x8A\xD9\x87\xD9\x85\xD8\xA7\xD8\xA8\xD8\xAA\xD9\x83\xD9\x84\
+\xD9\x85\xD9\x88\xD8\xB4\xD8\xB9\xD8\xB1\xD8\xA8\xD9\x8A\xD8\x9F}
+xn--egbpdaj6bu4bxfgehfvwxn
+
+a-label localpart to utf-8:
+
+${utf8_localpart_from_alabel:xn--ghb}
+${utf8_localpart_from_alabel:xn--egbpdaj6bu4bxfgehfvwxn}
+
+utf-8 domain to a-label:
+
+${utf8_domain_to_alabel:bogus.\xD9\x84.com}
+bogus.xn--ghb.com
+
+${utf8_domain_to_alabel:arabic.\xD9\x84\xD9\x8A\xD9\x87\xD9\x85\xD8\xA7\xD8\xA8\xD8\xAA\xD9\x83\xD9\x84\
+\xD9\x85\xD9\x88\xD8\xB4\xD8\xB9\xD8\xB1\xD8\xA8\xD9\x8A\xD8\x9F.com}
+arabic.xn--egbpdaj6bu4bxfgehfvwxn.com
+
+${utf8_domain_to_alabel:simpl.chinese.\xE4\xBB\x96\xE4\xBB\xAC\xE4\xB8\xBA\xE4\xBB\x80\
+\xE4\xB9\x88\xE4\xB8\x8D\xE8\xAF\xB4\xE4\xB8\xAD\xE6\x96\x87.com}
+simpl.chinese.xn--ihqwcrb4cv8a8dqg056pqjye.com
+
+${utf8_domain_to_alabel:trad.chinese.\xE4\xBB\x96\xE5\x80\x91\xE7\x88\xB2\xE4\xBB\x80\
+\xE9\xBA\xBD\xE4\xB8\x8D\xE8\xAA\xAA\xE4\xB8\xAD\xE6\x96\x87.com}
+trad.chinese.xn--ihqwctvzc91f659drss3x8bo0yb.com
+
+${utf8_domain_to_alabel:czech.\x50\x72\x6F\xC4\x8D\x70\x72\x6F\x73\x74\xC4\x9B\x6E\x65\
+\x6D\x6C\x75\x76\xC3\xAD\xC4\x8D\x65\x73\x6B\x79.com}
+czech.xn--Proprostnemluvesky-uyb24dma41a.com
+
+${utf8_domain_to_alabel:hebrew.\xD7\x9C\xD7\x9E\xD7\x94\xD7\x94\xD7\x9D\xD7\xA4\xD7\xA9\
+\xD7\x95\xD7\x98\xD7\x9C\xD7\x90\xD7\x9E\xD7\x93\xD7\x91\xD7\xA8\xD7\x99\xD7\x9D\xD7\xA2\
+\xD7\x91\xD7\xA8\xD7\x99\xD7\xAA.com}
+hebrew.xn--4dbcagdahymbxekheh6e0a7fei0b.com
+
+${utf8_domain_to_alabel:hindi.\xE0\xA4\xAF\xE0\xA4\xB9\xE0\xA4\xB2\xE0\xA5\x8B\xE0\xA4\x97\
+\xE0\xA4\xB9\xE0\xA4\xBF\xE0\xA4\xA8\xE0\xA5\x8D\xE0\xA4\xA6\xE0\xA5\x80\xE0\xA4\x95\xE0\xA5\x8D\
+\xE0\xA4\xAF\xE0\xA5\x8B\xE0\xA4\x82\xE0\xA4\xA8\xE0\xA4\xB9\xE0\xA5\x80\xE0\xA4\x82\xE0\xA4\xAC\
+\xE0\xA5\x8B\xE0\xA4\xB2\xE0\xA4\xB8\xE0\xA4\x95\xE0\xA4\xA4\xE0\xA5\x87\xE0\xA4\xB9\xE0\xA5\x88\
+\xE0\xA4\x82.com}
+hindi.xn--i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd.com
+
+${utf8_domain_to_alabel:japanese.\xE3\x81\xAA\xE3\x81\x9C\xE3\x81\xBF\xE3\x82\x93\xE3\x81\xAA\
+\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E\xE3\x82\x92\xE8\xA9\xB1\xE3\x81\x97\xE3\x81\xA6\xE3\x81\x8F\
+\xE3\x82\x8C\xE3\x81\xAA\xE3\x81\x84\xE3\x81\xAE\xE3\x81\x8B.com}
+japanese.xn--n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa.com
+
+# the a-label for the phrase in korean is too long for a domain label (63 byte limit)
+korean: ${utf8_localpart_to_alabel:\xEC\x84\xB8\xEA\xB3\x84\xEC\x9D\x98\xEB\xAA\xA8\xEB\x93\xA0\
+\xEC\x82\xAC\xEB\x9E\x8C\xEB\x93\xA4\xEC\x9D\xB4\xED\x95\x9C\xEA\xB5\xAD\xEC\x96\xB4\xEB\xA5\xBC\
+\xEC\x9D\xB4\xED\x95\xB4\xED\x95\x9C\xEB\x8B\xA4\xEB\xA9\xB4\xEC\x96\xBC\xEB\xA7\x88\xEB\x82\x98\
+\xEC\xA2\x8B\xEC\x9D\x84\xEA\xB9\x8C}
+korean: xn--989aomsvi5e83db1d2a355cv1e0vak1dwrv93d5xbh15a0dt30a5jpsd879ccm6fea98c
+
+${utf8_domain_to_alabel:russian.\xD0\xBF\xD0\xBE\xD1\x87\xD0\xB5\xD0\xBC\xD1\x83\xD0\xB6\
+\xD0\xB5\xD0\xBE\xD0\xBD\xD0\xB8\xD0\xBD\xD0\xB5\xD0\xB3\xD0\xBE\xD0\xB2\xD0\xBE\xD1\x80\
+\xD1\x8F\xD1\x82\xD0\xBF\xD0\xBE\xD1\x80\xD1\x83\xD1\x81\xD1\x81\xD0\xBA\xD0\xB8.com}
+russian.xn--b1abfaaepdrnnbgefbaDotcwatmq2g4l.com
+
+${utf8_domain_to_alabel:spanish.\x50\x6F\x72\x71\x75\xC3\xA9\x6E\x6F\x70\x75\x65\x64\x65\
+\x6E\x73\x69\x6D\x70\x6C\x65\x6D\x65\x6E\x74\x65\x68\x61\x62\x6C\x61\x72\x65\x6E\x45\x73\
+\x70\x61\xC3\xB1\x6F\x6C.com}
+spanish.xn--PorqunopuedensimplementehablarenEspaol-fmd56a.com
+
+${utf8_domain_to_alabel:vietnamese.\x54\xE1\xBA\xA1\x69\x73\x61\x6F\x68\xE1\xBB\x8D\x6B\x68\
+\xC3\xB4\x6E\x67\x74\x68\xE1\xBB\x83\x63\x68\xE1\xBB\x89\x6E\xC3\xB3\x69\x74\x69\xE1\xBA\xBF\
+\x6E\x67\x56\x69\xE1\xBB\x87\x74.com}
+vietnamese.xn--TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g.com
+
+a-label domain to utf-8:
+
+${utf8_domain_from_alabel:arab.xn--ghb.com}
+${utf8_domain_from_alabel:arab.xn--egbpdaj6bu4bxfgehfvwxn.com}
+${utf8_domain_from_alabel:simpl.chinese.xn--ihqwcrb4cv8a8dqg056pqjye.com}
+${utf8_domain_from_alabel:trad.chinese.xn--ihqwctvzc91f659drss3x8bo0yb.com}
+${utf8_domain_from_alabel:czech.xn--Proprostnemluvesky-uyb24dma41a.com}
+${utf8_domain_from_alabel:hebrew.xn--4dbcagdahymbxekheh6e0a7fei0b.com}
+${utf8_domain_from_alabel:hindi.xn--i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd.com}
+${utf8_domain_from_alabel:japanese.xn--n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa.com}
+korean: ${utf8_localpart_from_alabel:xn--989aomsvi5e83db1d2a355cv1e0vak1dwrv93d5xbh15a0dt30a5jpsd879ccm6fea98c}
+${utf8_domain_from_alabel:russian.xn--b1abfaaepdrnnbgefbaDotcwatmq2g4l.com}
+${utf8_domain_from_alabel:spanish.xn--PorqunopuedensimplementehablarenEspaol-fmd56a.com}
+${utf8_domain_from_alabel:vietnamese.xn--TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g.com}
+
+===========
+
+${imapfolder {Foo/Bar}}
+Foo.Bar
+
+${imapfolder {Foo/Bar} {.} {/}}
+Foo&AC8-Bar
+
+${imapfolder{Räksmörgås}}
+R&AOQ-ksm&APY-rg&AOU-s
+
+
+****
--- /dev/null
+# Internationalised mail: smtp input and forwarding
+# Exim test configuration 4201
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+#
+# Basic smtp input, no delivery
+client 127.0.0.1 PORT_D
+??? 220
+EHLO client
+??? 250-
+??? 250-SIZE
+??? 250-8BITMIME
+??? 250-PIPELINING
+??? 250-SMTPUTF8
+??? 250 HELP
+MAIL FROM: <someone@some.domain> SMTPUTF8
+??? 250
+RCPT TO: <userx@test.ex>
+??? 250
+DATA
+??? 354
+Subject: test
+
+body
+.
+??? 250
+QUIT
+??? 221
+****
+#
+#
+# utf-8 from, Basic smtp input, no delivery
+client 127.0.0.1 PORT_D
+??? 220
+EHLO client
+??? 250-
+??? 250-SIZE
+??? 250-8BITMIME
+??? 250-PIPELINING
+??? 250-SMTPUTF8
+??? 250 HELP
+MAIL FROM: <ليهمابتكلموشعربي؟@czech.Pročprostěnemluvíčesky.com> SMTPUTF8
+??? 250
+RCPT TO: <userx@test.ex>
+??? 250
+DATA
+??? 354
+Subject: test
+
+body
+.
+??? 250
+QUIT
+??? 221
+****
+#
+#
+# utf-8 from, -bs input and forwarding
+exim -bs -odi
+EHLO client.bh
+MAIL FROM: <他们为什么不说中文@hebrew.למההםפשוטלאמדבריםעברית.com> SMTPUTF8
+RCPT TO: <usery@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+killdaemon
+exim -DSERVER=server -DNOTDAEMON -qqff
+****
+no_msglog_check
--- /dev/null
+# Internationalised mail: stdin input
+# Exim test configuration 4202
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+#
+# commandline/stdin input, normal rcpt & sender, forwarded
+exim -odi -f user.dontcare@test1.com userx@test.ex
+Test message 1.
+.
+****
+# commandline/stdin input, utf-8 rcpt, forwarded
+exim -odi -f user.dontcare@test1.com user.他们为什么不说中文@test.ex
+Test message 2.
+.
+****
+# commandline/stdin input, utf-8 sender, forwarded
+exim -odi -f 他们为什么不说中文@test1.com userx@test.ex
+Test message 3.
+.
+****
+#
+#
+killdaemon
+exim -DSERVER=server -DNOTDAEMON -qqff
+****
+no_msglog_check
--- /dev/null
+# Internationalised mail: forwarding fail
+# Exim test configuration 4203
+munge optional_dsn_info
+#
+exim -DSERVER=server -DOPTION="" -bd -oX PORT_D
+****
+#
+# forwarding fails when target does not support SMTPUTF8
+exim -bs -odi
+EHLO client.ffail
+MAIL FROM: <यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local> SMTPUTF8
+RCPT TO: <userz@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+#
+#
+killdaemon
+#
+exim -qfl
+****
+#
--- /dev/null
+# Internationalised mail: recipient verify callout
+# Exim test configuration 4204
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+# Recipient verify callout, pass
+exim -bs -odi -DCONTROL="verify=recipient/callout"
+EHLO client.bh
+MAIL FROM: <세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com> SMTPUTF8
+RCPT TO: <userQ@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+# Recipient+random verify callout, pass
+exim -bs -odi -DCONTROL="verify=recipient/callout=random"
+EHLO client.bh
+MAIL FROM: <세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com> SMTPUTF8
+RCPT TO: <userR@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+killdaemon
+exim -DSERVER=server -DNOTDAEMON -qqff
+****
+#
+#
+#
+#
+#
+exim -DSERVER=server -DOPTION="" -bd -oX PORT_D
+****
+#
+# Recipient verify callout, fail
+exim -bs -odi -DCONTROL="verify=recipient/callout"
+EHLO client.ffail
+MAIL FROM: <CALLER@spanish.PorquénopuedensimplementehablarenEspañol.local> SMTPUTF8
+RCPT TO: <userS@test.ex>
+QUIT
+****
+#
+# Recipient+random verify callout, fail
+exim -bs -odi -DCONTROL="verify=recipient/callout=random"
+EHLO client.ffail
+MAIL FROM: <CALLER@vietnamese.TạisaohọkhôngthểchỉnóitiếngViệt.local> SMTPUTF8
+RCPT TO: <userT@test.ex>
+QUIT
+****
+#
+killdaemon
--- /dev/null
+# Internationalised mail: utf8 recipient
+# Exim test configuration 4205
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+# utf-8 to, -bs input and forwarding
+exim -bs -odi
+EHLO client.bh
+MAIL FROM: <userU@test.ex> SMTPUTF8
+RCPT TO: <user.γλυκύρριζα@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+killdaemon
+exim -DSERVER=server -DNOTDAEMON -qqff
+****
--- /dev/null
+# Internationalised mail: sender verify callout
+# Exim test configuration 4206
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+# sender verify callout, pass
+exim -bs -odi -DCONTROL="verify=sender/callout"
+EHLO client.bh
+MAIL FROM: <userV.වැල්_මී@test.ex> SMTPUTF8
+RCPT TO: <user.அதிமதுரம்@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+# sender+random verify callout, pass
+exim -bs -odi -DCONTROL="verify=sender/callout=random"
+EHLO client.bh
+MAIL FROM: <userW@test.ex> SMTPUTF8
+RCPT TO: <user.ഇരട്ടിമധുരം@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+killdaemon
+exim -DSERVER=server -DNOTDAEMON -qqff
+****
+#
+#
+#
+#
+exim -DSERVER=server -DOPTION="" -bd -oX PORT_D
+****
+# sender verify callout, fail
+exim -bs -odi -DCONTROL="verify=sender/callout"
+EHLO client.sfail
+MAIL FROM: <userA@test.ex> SMTPUTF8
+RCPT TO: <user.यष्टिमधु@test.ex>
+QUIT
+****
+# sender+random verify callout, fail
+exim -bs -odi -DCONTROL="verify=sender/callout=random"
+EHLO client.sfail
+MAIL FROM: <userB.જેઠીમધ@test.ex> SMTPUTF8
+RCPT TO: <user.ქართული@test.ex>
+QUIT
+****
+#
+killdaemon
--- /dev/null
+# Internationalised mail: control = utf8_downconvert
+# Exim test configuration 4207
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+#
+# utf-8 from, mandatory downconvert
+exim -bs -odi -DCONTROL="control=utf8_downconvert"
+EHLO client.bh
+MAIL FROM: <他们为什么不说中文@hebrew.למההםפשוטלאמדבריםעברית.com> SMTPUTF8
+RCPT TO: <user.세계의모든사람들이한국어를이해한다면얼마나좋을까@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+killdaemon
+exim -DSERVER=server -DNOTDAEMON -qqff
+****
+no_msglog_check
--- /dev/null
+# Internationalised mail: utf8_downconvert and callouts
+# Exim test configuration 4208
+#
+exim -DSERVER=server -DOPTION="" -bd -oX PORT_D
+****
+#
+# Recipient verify callout, pass only due to downconvert
+exim -bs -odi -DINSERT="control=utf8_downconvert" -DCONTROL="verify=recipient/callout"
+EHLO client.ffail
+MAIL FROM: <CALLER@spanish.PorquénopuedensimplementehablarenEspañol.local> SMTPUTF8
+RCPT TO: <userS@test.ex>
+QUIT
+****
+
+# Recipient+random verify callout, pass only due to downconvert
+exim -bs -odi -DINSERT="control=utf8_downconvert" -DCONTROL="verify=recipient/callout=random"
+EHLO client.ffail
+MAIL FROM: <CALLER@vietnamese.TạisaohọkhôngthểchỉnóitiếngViệt.local> SMTPUTF8
+RCPT TO: <userT@test.ex>
+QUIT
+****
+#
+killdaemon
--- /dev/null
+# Internationalised mail: mua_wrapper
+# Exim test configuration 4209
+#
+# featurefull server
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+# commandline/stdin input, utf-8 rcpt & sender, forwarded
+# should not downconvert
+exim -DSUB=mua_wrapper -odi -f 他们为什么不说中文@test1.com user.他们为什么不说中文@test.ex
+Test message 1.
+.
+****
+#
+#
+killdaemon
+exim -DSERVER=server -DNOTDAEMON -qqff
+****
+#
+#
+#
+# featureless server
+exim -DSERVER=server -DOPTION="" -bd -oX PORT_D
+****
+#
+# commandline/stdin input, utf-8 rcpt & sender, forwarded
+# should downconvert
+exim -DSUB=mua_wrapper -odi -f 他们为什么不说中文@test1.com user.他们为什么不说中文@test.ex
+Test message 1.
+.
+****
+#
+#
+killdaemon
+exim -DSERVER=server -DNOTDAEMON -qqff
+****
+#
+#
+#
+no_msglog_check
--- /dev/null
+support I18N
--- /dev/null
+# Internationalised mail: smtp input and forwarding
+# Exim test configuration 4211
+gnutls
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+#
+# Basic smtp input, no delivery
+client 127.0.0.1 PORT_D
+??? 220
+EHLO client
+??? 250-
+??? 250-SIZE
+??? 250-8BITMIME
+??? 250-PIPELINING
+??? 250-STARTTLS
+??? 250-SMTPUTF8
+??? 250 HELP
+MAIL FROM: <someone@some.domain> SMTPUTF8
+??? 250
+RCPT TO: <userx@test.ex>
+??? 250
+DATA
+??? 354
+Subject: test
+
+body
+.
+??? 250
+QUIT
+??? 221
+****
+#
+#
+# utf-8 from, Basic smtp input, no delivery
+client 127.0.0.1 PORT_D
+??? 220
+EHLO client
+??? 250-
+??? 250-SIZE
+??? 250-8BITMIME
+??? 250-PIPELINING
+??? 250-STARTTLS
+??? 250-SMTPUTF8
+??? 250 HELP
+MAIL FROM: <ليهمابتكلموشعربي؟@czech.Pročprostěnemluvíčesky.com> SMTPUTF8
+??? 250
+RCPT TO: <userx@test.ex>
+??? 250
+DATA
+??? 354
+Subject: test
+
+body
+.
+??? 250
+QUIT
+??? 221
+****
+#
+#
+# utf-8 from, -bs input and forwarding
+exim -bs -odi
+EHLO client.bh
+MAIL FROM: <他们为什么不说中文@hebrew.למההםפשוטלאמדבריםעברית.com> SMTPUTF8
+RCPT TO: <usery@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+#
+#
+killdaemon
+exim -DSERVER=server -DNOTDAEMON -qqff
+****
+no_msglog_check
--- /dev/null
+# Internationalised mail: forwarding fail
+# Exim test configuration 4213
+gnutls
+munge optional_dsn_info
+#
+exim -DSERVER=server -DOPTION="" -bd -oX PORT_D
+****
+#
+# forwarding fails when target does not support SMTPUTF8
+exim -bs -odi
+EHLO client.ffail
+MAIL FROM: <यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local> SMTPUTF8
+RCPT TO: <userz@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+#
+#
+killdaemon
+#
+exim -qfl
+****
--- /dev/null
+# Internationalised mail: recipient verify callout
+# Exim test configuration 4214
+gnutls
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+# Recipient verify callout, pass
+exim -bs -odi -DCONTROL="verify=recipient/callout"
+EHLO client.bh
+MAIL FROM: <세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com> SMTPUTF8
+RCPT TO: <userQ@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+# Recipient+random verify callout, pass
+exim -bs -odi -DCONTROL="verify=recipient/callout=random"
+EHLO client.bh
+MAIL FROM: <세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com> SMTPUTF8
+RCPT TO: <userR@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+killdaemon
+exim -DSERVER=server -DNOTDAEMON -qqff
+****
+#
+#
+#
+#
+#
+exim -DSERVER=server -DOPTION="" -bd -oX PORT_D
+****
+#
+# Recipient verify callout, fail
+exim -bs -odi -DCONTROL="verify=recipient/callout"
+EHLO client.ffail
+MAIL FROM: <CALLER@spanish.PorquénopuedensimplementehablarenEspañol.local> SMTPUTF8
+RCPT TO: <userS@test.ex>
+QUIT
+****
+#
+# Recipient+random verify callout, fail
+exim -bs -odi -DCONTROL="verify=recipient/callout=random"
+EHLO client.ffail
+MAIL FROM: <CALLER@vietnamese.TạisaohọkhôngthểchỉnóitiếngViệt.local> SMTPUTF8
+RCPT TO: <userT@test.ex>
+QUIT
+****
+#
+killdaemon
--- /dev/null
+# Internationalised mail: utf8 recipient
+# Exim test configuration 4215
+gnutls
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+# utf-8 to, -bs input and forwarding
+exim -bs -odi
+EHLO client.bh
+MAIL FROM: <userU@test.ex> SMTPUTF8
+RCPT TO: <user.γλυκύρριζα@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+killdaemon
+exim -DSERVER=server -DNOTDAEMON -qqff
+****
--- /dev/null
+# Internationalised mail: sender verify callout
+# Exim test configuration 4216
+gnutls
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+# sender verify callout, pass
+exim -bs -odi -DCONTROL="verify=sender/callout"
+EHLO client.bh
+MAIL FROM: <userV.වැල්_මී@test.ex> SMTPUTF8
+RCPT TO: <user.அதிமதுரம்@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+# sender+random verify callout, pass
+exim -bs -odi -DCONTROL="verify=sender/callout=random"
+EHLO client.bh
+MAIL FROM: <userW@test.ex> SMTPUTF8
+RCPT TO: <user.ഇരട്ടിമധുരം@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+killdaemon
+exim -DSERVER=server -DNOTDAEMON -qqff
+****
+#
+#
+#
+#
+exim -DSERVER=server -DOPTION="" -bd -oX PORT_D
+****
+# sender verify callout, fail
+exim -bs -odi -DCONTROL="verify=sender/callout"
+EHLO client.sfail
+MAIL FROM: <userA@test.ex> SMTPUTF8
+RCPT TO: <user.यष्टिमधु@test.ex>
+QUIT
+****
+# sender+random verify callout, fail
+exim -bs -odi -DCONTROL="verify=sender/callout=random"
+EHLO client.sfail
+MAIL FROM: <userB.જેઠીમધ@test.ex> SMTPUTF8
+RCPT TO: <user.ქართული@test.ex>
+QUIT
+****
+#
+killdaemon
--- /dev/null
+support I18N
+support GnuTLS
--- /dev/null
+# Internationalised mail: smtp input and forwarding
+# Exim test configuration 4221
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+#
+# Basic smtp input, no delivery
+client 127.0.0.1 PORT_D
+??? 220
+EHLO client
+??? 250-
+??? 250-SIZE
+??? 250-8BITMIME
+??? 250-PIPELINING
+??? 250-STARTTLS
+??? 250-SMTPUTF8
+??? 250 HELP
+MAIL FROM: <someone@some.domain> SMTPUTF8
+??? 250
+RCPT TO: <userx@test.ex>
+??? 250
+DATA
+??? 354
+Subject: test
+
+body
+.
+??? 250
+QUIT
+??? 221
+****
+#
+#
+# utf-8 from, Basic smtp input, no delivery
+client 127.0.0.1 PORT_D
+??? 220
+EHLO client
+??? 250-
+??? 250-SIZE
+??? 250-8BITMIME
+??? 250-PIPELINING
+??? 250-STARTTLS
+??? 250-SMTPUTF8
+??? 250 HELP
+MAIL FROM: <ليهمابتكلموشعربي؟@czech.Pročprostěnemluvíčesky.com> SMTPUTF8
+??? 250
+RCPT TO: <userx@test.ex>
+??? 250
+DATA
+??? 354
+Subject: test
+
+body
+.
+??? 250
+QUIT
+??? 221
+****
+#
+#
+# utf-8 from, -bs input and forwarding
+exim -bs -odi
+EHLO client.bh
+MAIL FROM: <他们为什么不说中文@hebrew.למההםפשוטלאמדבריםעברית.com> SMTPUTF8
+RCPT TO: <usery@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+#
+#
+killdaemon
+exim -DSERVER=server -DNOTDAEMON -qqff
+****
--- /dev/null
+# Internationalised mail: forwarding fail
+# Exim test configuration 4223
+munge optional_dsn_info
+#
+exim -DSERVER=server -DOPTION="" -bd -oX PORT_D
+****
+#
+# forwarding fails when target does not support SMTPUTF8
+exim -bs -odi
+EHLO client.ffail
+MAIL FROM: <यहलोगहिन्दीक्योंनहींबोलसकतेहैं@japanese.なぜみんな日本語を話してくれないのか.local> SMTPUTF8
+RCPT TO: <userz@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+#
+#
+killdaemon
+#
+exim -qfl
+****
+#
--- /dev/null
+# Internationalised mail: recipient verify callout
+# Exim test configuration 4224
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+# Recipient verify callout, pass
+exim -bs -odi -DCONTROL="verify=recipient/callout"
+EHLO client.bh
+MAIL FROM: <세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com> SMTPUTF8
+RCPT TO: <userQ@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+# Recipient+random verify callout, pass
+exim -bs -odi -DCONTROL="verify=recipient/callout=random"
+EHLO client.bh
+MAIL FROM: <세계의모든사람들이한국어를이해한다면얼마나좋을까@russian.почемужеонинеговорятпорусски.com> SMTPUTF8
+RCPT TO: <userR@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+killdaemon
+exim -DSERVER=server -DNOTDAEMON -qqff
+****
+#
+#
+#
+#
+#
+exim -DSERVER=server -DOPTION="" -bd -oX PORT_D
+****
+#
+# Recipient verify callout, fail
+exim -bs -odi -DCONTROL="verify=recipient/callout"
+EHLO client.ffail
+MAIL FROM: <CALLER@spanish.PorquénopuedensimplementehablarenEspañol.local> SMTPUTF8
+RCPT TO: <userS@test.ex>
+QUIT
+****
+#
+# Recipient+random verify callout, fail
+exim -bs -odi -DCONTROL="verify=recipient/callout=random"
+EHLO client.ffail
+MAIL FROM: <CALLER@vietnamese.TạisaohọkhôngthểchỉnóitiếngViệt.local> SMTPUTF8
+RCPT TO: <userT@test.ex>
+QUIT
+****
+#
+killdaemon
--- /dev/null
+# Internationalised mail: utf8 recipient
+# Exim test configuration 4225
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+# utf-8 to, -bs input and forwarding
+exim -bs -odi
+EHLO client.bh
+MAIL FROM: <userU@test.ex> SMTPUTF8
+RCPT TO: <user.γλυκύρριζα@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+killdaemon
+exim -DSERVER=server -DNOTDAEMON -qqff
+****
--- /dev/null
+# Internationalised mail: sender verify callout
+# Exim test configuration 4226
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+# sender verify callout, pass
+exim -bs -odi -DCONTROL="verify=sender/callout"
+EHLO client.bh
+MAIL FROM: <userV.වැල්_මී@test.ex> SMTPUTF8
+RCPT TO: <user.அதிமதுரம்@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+# sender+random verify callout, pass
+exim -bs -odi -DCONTROL="verify=sender/callout=random"
+EHLO client.bh
+MAIL FROM: <userW@test.ex> SMTPUTF8
+RCPT TO: <user.ഇരട്ടിമധുരം@test.ex>
+DATA
+Subject: test
+
+body
+.
+QUIT
+****
+#
+killdaemon
+exim -DSERVER=server -DNOTDAEMON -qqff
+****
+#
+#
+#
+#
+exim -DSERVER=server -DOPTION="" -bd -oX PORT_D
+****
+# sender verify callout, fail
+exim -bs -odi -DCONTROL="verify=sender/callout"
+EHLO client.sfail
+MAIL FROM: <userA@test.ex> SMTPUTF8
+RCPT TO: <user.यष्टिमधु@test.ex>
+QUIT
+****
+# sender+random verify callout, fail
+exim -bs -odi -DCONTROL="verify=sender/callout=random"
+EHLO client.sfail
+MAIL FROM: <userB.જેઠીમધ@test.ex> SMTPUTF8
+RCPT TO: <user.ქართული@test.ex>
+QUIT
+****
+#
+killdaemon
--- /dev/null
+support I18N
+support OpenSSL
--- /dev/null
+# DKIM simple canonicalisation
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+# This should pass.
+# Mail original in aux-fixed/4500.msg1.txt
+# Sig generated by: perl aux-fixed/dkim/sign.pl --method=simple/simple < aux-fixed/4500.msg1.txt
+client 127.0.0.1 PORT_D
+??? 220
+HELO xxx
+??? 250
+MAIL FROM:<CALLER@bloggs.com>
+??? 250
+RCPT TO:<a@test.ex>
+??? 250
+DATA
+??? 354
+DKIM-Signature: v=1; a=rsa-sha1; c=simple/simple; d=test.ex; h=from:to
+ :date:message-id:subject; s=sel; bh=OB9dZVu7+5/ufs3TH9leIcEpXSo=; b=
+ PeUA8iBGfStWv+9/BBKkvCEYj/AVMl4e9k+AqWOXKyuEUfHxqAnV+sPnOejpmvT8
+ 41kuM4u0bICvK371YvB/yO61vtliRhyqU76Y2e55p2uvMADb3UyDhLyzpco4+yBo
+ 1w0AuIxu0VU4TK8UmOLyCw/1hxrh1DcEInbEMEKJ7kI=
+From: mrgus@text.ex
+To: bakawolf@yahoo.com
+Date: Thu, 19 Nov 2015 17:00:07 -0700
+Message-ID: <qwerty1234@disco-zombie.net>
+Subject: simple test
+
+This is a simple test.
+.
+??? 250
+QUIT
+??? 221
+****
+#
+# This should pass.
+# Mail original in aux-fixed/4500.msg1.txt
+# Sig generated by: perl aux-fixed/dkim/sign.pl --method=simple/simple --selector=ses \
+# --keyfile=aux-fixed/dkim/dkim512.private < aux-fixed/4500.msg1.txt
+client 127.0.0.1 PORT_D
+??? 220
+HELO xxx
+??? 250
+MAIL FROM:<CALLER@bloggs.com>
+??? 250
+RCPT TO:<a@test.ex>
+??? 250
+DATA
+??? 354
+DKIM-Signature: v=1; a=rsa-sha1; c=simple/simple; d=test.ex; h=from:to
+ :date:message-id:subject; s=ses; bh=OB9dZVu7+5/ufs3TH9leIcEpXSo=; b=
+ cIErF1eueIT9AU4qG54FyT3yrlVDDM7RZnuU6fWTevZpAuMqhYcRO8tU3U4vtKWB
+ +I2vd+F1gzqCzBcRtfLhZg==
+From: mrgus@text.ex
+To: bakawolf@yahoo.com
+Date: Thu, 19 Nov 2015 17:00:07 -0700
+Message-ID: <qwerty1234@disco-zombie.net>
+Subject: simple test
+
+This is a simple test.
+.
+??? 250
+QUIT
+??? 221
+****
+#
+#
+killdaemon
+no_stdout_check
+no_msglog_check
--- /dev/null
+# DKIM simple canonicalisation, with spaces
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+# this should pass verification
+# Mail original in aux-fixed/4501.msg1.txt
+# Sig generated by: perl aux-fixed/dkim/sign.pl --method=simple/simple < aux-fixed/4501.msg1.txt
+client 127.0.0.1 PORT_D
+??? 220
+HELO xxx
+??? 250
+MAIL FROM:<pass@bloggs.com>
+??? 250
+RCPT TO:<a@test.ex>
+??? 250
+DATA
+??? 354
+DKIM-Signature: v=1; a=rsa-sha1; c=simple/simple; d=test.ex; h=from:to
+ :date:message-id:subject; s=sel; bh=pdsXC6mnKSmAYjraebHb2Tt2xqw=; b=
+ bE9pnPdz5eDwz58PFMAsiFqpcsel33p5+pnvhwY5D6B6suGFbvku+LC1pi77z3lq
+ 45mFRxT4Dr4rW4612jYi5WpNk8ed28BkNMowUCgkM2TDoktiRClFpXTUX00hCico
+ KWcgcvORf6L8txhtICsHsl94ERKXxgptXHQk8XwMEuU=
+From: mrgus@test.ex
+To: bakawolf@yahoo.com
+Date: Thu, 19 Nov 2015 17:00:07 -0700
+Message-ID: <qwerty1234@disco-zombie.net>
+Subject: simple space test
+
+This is a test of simple with spaces.
+
+
+
+End of content (spaced line two lines down).
+.
+??? 250
+QUIT
+??? 221
+****
+#
+# this should fail verification
+# Same message and sig as above, but body extended with (emptyline) (line with only spaces) (emptyline)
+client 127.0.0.1 PORT_D
+??? 220
+HELO xxx
+??? 250
+MAIL FROM:<fail@bloggs.com>
+??? 250
+RCPT TO:<a@test.ex>
+??? 250
+DATA
+??? 354
+DKIM-Signature: v=1; a=rsa-sha1; c=simple/simple; d=test.ex; h=from:to
+ :date:message-id:subject; s=sel; bh=pdsXC6mnKSmAYjraebHb2Tt2xqw=; b=
+ bE9pnPdz5eDwz58PFMAsiFqpcsel33p5+pnvhwY5D6B6suGFbvku+LC1pi77z3lq
+ 45mFRxT4Dr4rW4612jYi5WpNk8ed28BkNMowUCgkM2TDoktiRClFpXTUX00hCico
+ KWcgcvORf6L8txhtICsHsl94ERKXxgptXHQk8XwMEuU=
+From: mrgus@test.ex
+To: bakawolf@yahoo.com
+Date: Thu, 19 Nov 2015 17:00:07 -0700
+Message-ID: <qwerty1234@disco-zombie.net>
+Subject: simple space test
+
+This is a test of simple with spaces.
+
+
+
+End of content (spaced line two lines down).
+
+
+
+.
+??? 250
+QUIT
+??? 221
+****
+#
+killdaemon
+no_stdout_check
+no_msglog_check
--- /dev/null
+# DKIM relaxed canonicalisation
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+# This should pass.
+# Mail original in aux-fixed/4502.msg1.txt
+# Sig generated by: perl aux-fixed/dkim/sign.pl --method=relaxed/relaxed < aux_fixed/4502.msg1.txt
+client 127.0.0.1 PORT_D
+??? 220
+HELO xxx
+??? 250
+MAIL FROM:<CALLER@bloggs.com>
+??? 250
+RCPT TO:<a@test.ex>
+??? 250
+DATA
+??? 354
+DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=test.ex; h=
+ message-id:date:from:mime-version:to:subject:content-type
+ :content-transfer-encoding; s=sel; bh=rn0kk3aPKyhYbxzfi3WG8dAxhN
+ M=; b=Tsi3kJtTNmIP0LAkEXR201R/alr7FwaWRAP+V9qQZf7MzAFrkfKAhkT3UQ
+ zPTJsZowOZaM1UoeeDQCvfvHG5YG8YCFwU3tuLgdDvbCmYJvR+jPNntN27BXcrVH
+ fyQLstR8eQPUopT7vmdYwsMlXz0Jv7iLM1MyxsWn6z1LTlvYA=
+Message-ID: <564CFC9B.1040905@yahoo.com>
+Date: Wed, 18 Nov 2015 14:32:59 -0800
+From: Joaquin Lopez <bakawolf@test.ex>
+User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:24.0) Gecko/20100101 Thunderbird/24.0
+MIME-Version: 1.0
+To: bakawolf@yahoo.com
+Subject: test
+Content-Type: text/plain; charset=ISO-8859-1; format=flowed
+Content-Transfer-Encoding: 7bit
+Content-Length: 13
+
+
+
+test
+
+
+
+
+
+
+
+
+.
+??? 250
+QUIT
+??? 221
+****
+#
+# This should pass.
+# Mail original in aux-fixed/4502.msg2.txt
+# Sig generated by: perl aux-fixed/dkim/sign.pl --method=relaxed < aux_fixed/4502.msg2.txt
+client 127.0.0.1 PORT_D
+??? 220
+HELO xxx
+??? 250
+MAIL FROM:<CALLER@bloggs.com>
+??? 250
+RCPT TO:<a@test.ex>
+??? 250
+DATA
+??? 354
+DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=test.ex; h=from:to:subject
+ :date:mime-version:content-type; s=sel; bh=uoq1oCgLlTqpdDX/iUbLy
+ 7J1Wic=; b=R8INFWPcNpQCsFaaflR6DMlxeSiNyJzOhC6cd56blJf1Ko4pgXnPP
+ /iZk1GVEUVvrCg/PUSQZGbXfukFf3iiPeKuq3xLtFHLZ23BcWTBUTK/mBPNQrB6p
+ YSQAYzZC/3x4DzTlkqgQgBcm78x8SkO2TdaUK/3Ja6HloNp2spUgLQ=
+Received: from xxxxxxxx.sproing.at ([127.0.0.1]:6225 helo=xxxxxxxx.sproing.at)
+ by yyyyyyyyyy.sproing.at with esmtp (Exim 4.86)
+ (envelope-from <postmaster@sproing.at>)
+ id 1a2FuN-0007pz-HD
+ for eximdkimtest@sproing.at; Fri, 27 Nov 2015 11:05:39 +0100
+From: <postmaster@test.ex>
+To: <eximdkimtest@sproing.at>
+Subject: test
+Date: Fri, 27 Nov 2015 11:05:38 +0100
+MIME-Version: 1.0
+Content-Type: text/plain;
+
+
+
+
+
+
+.
+??? 250
+QUIT
+??? 221
+****
+#
+# This should pass.
+# Mail original in aux-fixed/4502.msg3.txt
+# Sig generated by: perl aux-fixed/dkim/sign.pl --method=relaxed < aux_fixed/4502.msg3.txt
+client 127.0.0.1 PORT_D
+??? 220
+HELO xxx
+??? 250
+MAIL FROM:<CALLER@bloggs.com>
+??? 250
+RCPT TO:<a@test.ex>
+??? 250
+DATA
+??? 354
+DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=test.ex; h=from:to:subject
+ :date:mime-version:content-type; s=sel; bh=nlP/3EB0g/eKjl7+VInpZ
+ PDwELc=; b=TDZikuksDQgvVnkU+ZD7XZFhkfuf73WV9NcLRp7R/ADkBh2ZWzoKc
+ 1wST+dRBSt9m27BPx3EeUy1rZHryChKoTDy9XzLqo4mLOH4dC5pU5MWGD+bdtdeC
+ s3kEaYt3+l+7fsVdHFTu+2WwQUcQlvmUbENRn1k8sbpe9CGPrtvcAg=
+Received: from xxxxxxxx.sproing.at ([127.0.0.1]:6225 helo=xxxxxxxx.sproing.at)
+ by yyyyyyyyyy.sproing.at with esmtp (Exim 4.86)
+ (envelope-from <postmaster@sproing.at>)
+ id 1a2FuN-0007pz-HD
+ for eximdkimtest@sproing.at; Fri, 27 Nov 2015 11:05:39 +0100
+From: <postmaster@test.ex>
+To: <eximdkimtest@sproing.at>
+Subject: test
+Date: Fri, 27 Nov 2015 11:05:38 +0100
+MIME-Version: 1.0
+Content-Type: text/plain;
+
+Some content, then two blank lines.
+
+
+.
+??? 250
+QUIT
+??? 221
+****
+#
+killdaemon
+no_stdout_check
+no_msglog_check
--- /dev/null
+support DKIM
--- /dev/null
+# DSN extra information
+need_ipv4
+#
+server PORT_S
+450 I'm busy
+QUIT
+250 OK
+****
+exim -odi userx@domain1
+Test message 1
+****
+server PORT_S
+220 Connected OK
+EHLO
+450 I'm busy
+HELO
+450 I'm busy
+QUIT
+250 OK
+****
+exim -qf
+****
+server PORT_S
+550 Go away
+QUIT
+250 OK
+****
+exim -qf
+****
+server PORT_S
+220 Connected OK
+EHLO
+550 Go away
+HELO
+550 Go away
+QUIT
+250 OK
+****
+exim -odi userx@domain1 usery@domain2
+Test message 2
+****
--- /dev/null
+support Experimental_DSN_info
--- /dev/null
+# dnssec_request_domains
+exim -bt user@mx-unsec-a-unsec.test.ex
+****
+exim -bt user@mx-unsec-a-sec.test.ex
+****
+exim -bt user@mx-sec-a-unsec.test.ex
+****
+exim -bt user@mx-sec-a-sec.test.ex
+****
--- /dev/null
+# dnssec_require_domains
+1
+exim -bt user@mx-unsec-a-unsec.test.ex
+****
+1
+exim -bt user@mx-unsec-a-sec.test.ex
+****
+2
+exim -bt user@mx-sec-a-unsec.test.ex
+****
+exim -bt user@mx-sec-a-sec.test.ex
+****
--- /dev/null
+# check debug output if we request AD but get AA
+exim -d-all+dns -bt foo@mx-sec-a-aa.test.ex
+****
+exim -d-all+dns -bt foo@mx-aa-a-sec.test.ex
--- /dev/null
+# check debug output AD/AA and dns_trust_aa
+exim -d-all+dns -bt foo@mx-sec-a-aa.test.ex
+****
+exim -d-all+dns -bt foo@mx-aa-a-sec.test.ex
--- /dev/null
+support DNSSEC
+router dnslookup
# cutthrough_delivery basic operation
need_ipv4
+munge loopback
#
server PORT_S
220 ESMTP
QUIT
250 OK
****
-exim -d-all+acl+transport -bs
+exim -bs
EHLO myhost.test.ex
MAIL FROM:<CALLER@myhost.test.ex>
RCPT TO:<userx@domain.com>
QUIT
250 OK
****
-exim -d-all+acl+transport -bs
+exim -bs
EHLO myhost.test.ex
MAIL FROM:<CALLER@myhost.test.ex>
RCPT TO:<userz@domain.com>
.
QUIT
****
-# cutthrough cancelled by multiple recipients
-server PORT_S 2
+# cutthrough for 2 recipients in one domain
+server PORT_S
220 ESMTP
EHLO
250 OK
250 Sender OK
RCPT TO:
250 Recipient OK
+RCPT TO:
+250 Recipient OK
+DATA
+354 Send data
+.
+250 OK
QUIT
-*eof
+250 OK
+****
+exim -bs
+EHLO myhost.test.ex
+MAIL FROM:<CALLER@myhost.test.ex>
+RCPT TO:<usery@domain.com>
+RCPT TO:<userx@domain.com>
+DATA
+
+.
+QUIT
+****
+#
+#
+#
+#
+#
+# cutthrough_delivery basic operation, again
+server PORT_S
220 ESMTP
EHLO
250 OK
250 Sender OK
RCPT TO:
250 Recipient OK
+DATA
+354 Send data
+.
+250 OK
+QUIT
+250 OK
+****
+exim -bs
+EHLO myhost.test.ex
+MAIL FROM:<CALLER@myhost.test.ex>
+RCPT TO:<userx@domain.com>
+DATA
+X-hdr-rtr: qqq
+X-hdr-tpt: zzz
+
+body
+.
+QUIT
+****
+#
+#
+#
+#
+# cutthrough for 2 recipients in one domain
+# first one denied
+# so we get a 2nd conn with the traditional delivery
+# (for both because it's not a real verify=recipient)
+server PORT_S 2
+220 ESMTP
+EHLO
+250 OK
+MAIL FROM:
+250 Sender OK
RCPT TO:
-250 Recipient OK
+550 Not that one
+QUIT
+250 OK
+*eof
+220 ESMTP
+EHLO
+250 OK
+MAIL FROM:
+250 Sender OK
+RCPT TO:
+250 ok rcpt-1
+RCPT TO:
+250 ok rcpt-2
DATA
354 Send data
.
QUIT
250 OK
****
-exim -d-all+acl+transport -bs
+#
+# Foregound delivery needed else the following subtest reception logging happens before this ones
+# delivery process logs and terminates; the interlock is only on the parent exim terminating.
+exim -bs -odf
+EHLO myhost.test.ex
+MAIL FROM:<CALLER@myhost.test.ex>
+RCPT TO:<no@domain.com>
+RCPT TO:<userx@domain.com>
+DATA
+
+.
+QUIT
+****
+#
+#
+#
+#
+# cutthrough for 2 recipients in one domain
+# second one denied
+# so we get a 2nd conn with the traditional delivery
+# (for both because it's not a real verify=recipient)
+server PORT_S 2
+220 ESMTP
+EHLO
+250 OK
+MAIL FROM:
+250 Sender OK
+RCPT TO:
+250 first recipient ok
+RCPT TO:
+550 Not that one
+QUIT
+250 OK
+*eof
+220 ESMTP
+EHLO
+250 OK
+MAIL FROM:
+250 Sender OK
+RCPT TO:
+250 ok rcpt-1
+RCPT TO:
+250 ok rcpt-2
+DATA
+354 Send data
+.
+250 OK
+QUIT
+250 OK
+****
+exim -bs -odf
EHLO myhost.test.ex
MAIL FROM:<CALLER@myhost.test.ex>
-RCPT TO:<usery@domain.com>
RCPT TO:<userx@domain.com>
+RCPT TO:<no@domain.com>
DATA
.
QUIT
****
-sleep 1
#
#
#
#
#
-# cutthrough_delivery basic operation, again
+# cutthrough for 2 recipients in one domain
+# second one uses a different transport
+# so we get a 2nd conn with 2nd rcpt, doing the fake verify
+# then 3rd & 4th conns with the traditional deliveries on the different transports
+server PORT_S 4
+220 ESMTP
+EHLO
+250 OK
+MAIL FROM:
+250 Sender OK
+RCPT TO:
+250 first recipient ok
+QUIT
+250 OK
+*eof
+220 ESMTP
+EHLO
+250 OK
+MAIL FROM:
+250 Sender OK
+RCPT TO:
+250 second recipient ok
+QUIT
+250 OK
+*eof
+220 ESMTP
+EHLO
+250 OK
+MAIL FROM:
+250 Sender OK
+RCPT TO:
+250 ok rcpt-1
+DATA
+354 Send data
+.
+250 OK
+QUIT
+250 OK
+*eof
+220 ESMTP
+EHLO
+250 OK
+MAIL FROM:
+250 Sender OK
+RCPT TO:
+250 ok rcpt-2
+DATA
+354 Send data
+.
+250 OK
+QUIT
+250 OK
+****
+exim -bs -odf
+EHLO myhost.test.ex
+MAIL FROM:<CALLER@myhost.test.ex>
+RCPT TO:<userx@domain.com>
+RCPT TO:<special_tpt@domain.com>
+DATA
+
+.
+QUIT
+****
+#
+#
+#
+#
+#
+# cutthrough for 2 recipients in different domains, handled by the same tpt & host
server PORT_S
220 ESMTP
EHLO
MAIL FROM:
250 Sender OK
RCPT TO:
-250 Recipient OK
+250 ok rcpt-1
+RCPT TO:
+250 ok rcpt-2
DATA
354 Send data
.
QUIT
250 OK
****
-exim -d-all+acl+transport -bs
+exim -bs
+EHLO myhost.test.ex
+MAIL FROM:<CALLER@myhost.test.ex>
+RCPT TO:<userx@domain1.com>
+RCPT TO:<usery@domain2.com>
+DATA
+
+.
+QUIT
+****
+#
+#
+#
+#
+#
+# cutthrough for 2 recipients in different domains, handled by the same tpt but different hosts
+# so we get a 2nd conn with 2nd rcpt, doing the fake verify
+# then 3rd & 4th conns with the traditional deliveries on the different transports
+server PORT_S 4
+220 ESMTP
+EHLO
+250 OK
+MAIL FROM:
+250 Sender OK
+RCPT TO:
+250 first recipient ok
+QUIT
+250 OK
+*eof
+220 ESMTP
+EHLO
+250 OK
+MAIL FROM:
+250 Sender OK
+RCPT TO:
+250 second recipient ok
+QUIT
+250 OK
+*eof
+220 ESMTP
+EHLO
+250 OK
+MAIL FROM:
+250 Sender OK
+RCPT TO:
+250 ok rcpt-1
+DATA
+354 Send data
+.
+250 OK
+QUIT
+250 OK
+*eof
+220 ESMTP
+EHLO
+250 OK
+MAIL FROM:
+250 Sender OK
+RCPT TO:
+250 ok rcpt-2
+DATA
+354 Send data
+.
+250 OK
+QUIT
+250 OK
+****
+exim -bs -odf
EHLO myhost.test.ex
MAIL FROM:<CALLER@myhost.test.ex>
RCPT TO:<userx@domain.com>
+RCPT TO:<usery@special.com>
DATA
-X-hdr-rtr: qqq
-X-hdr-tpt: zzz
-body
.
QUIT
****
+#
+#
+#
+#
+#
+# cutthrough for 2 recipients in different domains, handled by the same tpt & host
+# but via a dnslookup router (all previous were manualroute)
+server PORT_S
+220 ESMTP
+EHLO
+250 OK
+MAIL FROM:
+250 Sender OK
+RCPT TO:
+250 ok rcpt-1
+RCPT TO:
+250 ok rcpt-2
+DATA
+354 Send data
+.
+250 OK
+QUIT
+250 OK
+****
+exim -bs -odf
+EHLO myhost.test.ex
+MAIL FROM:<CALLER@myhost.test.ex>
+RCPT TO:<userx@localhost4.test.ex>
+RCPT TO:<usery@thishost.test.ex>
+DATA
+
+.
+QUIT
+****
+#
+#
+#
+#
+# End
+++ /dev/null
-# TLS client: verify certificate from server - name-fails
-gnutls
-exim -DSERVER=server -bd -oX PORT_D
-****
-# this will fail to verify the cert name and fallback to unencrypted
-exim userr@test.ex
-Testing
-****
-# this will pass the cert verify including name check
-exim users@test.ex
-Testing
-****
-# this will fail to verify the cert name but carry on (try-verify mode)
-exim usert@test.ex
-Testing
-****
-exim -qf
-****
-killdaemon
-no_msglog_check
+++ /dev/null
-support GnuTLS
-support Experimental_Certnames
-running IPv4
+++ /dev/null
-# TLS client: verify certificate from server - name-fails
-exim -DSERVER=server -bd -oX PORT_D
-****
-# this will fail to verify the cert at HOSTIPV4 and fallback to unencrypted
-exim userq@test.ex
-Testing
-****
-# this will fail to verify the cert name and fallback to unencrypted
-exim userr@test.ex
-Testing
-****
-# this will pass the cert verify including name check
-exim users@test.ex
-Testing
-****
-# this will fail to verify the cert name but carry on (try-verify mode)
-exim usert@test.ex
-Testing
-****
-exim -qf
-****
-killdaemon
-no_msglog_check
+++ /dev/null
-support OpenSSL
-support Experimental_Certnames
-running IPv4
quit
??? 221
****
-sleep 1
+millisleep 500
#
#
# 2: traditional data acl should be called, resulting in an overall reject
quit
??? 221
****
-sleep 1
+millisleep 500
#
#
# 3: PRDR should be avoided for a single-recipient message
quit
??? 221
****
-sleep 1
+millisleep 500
#
# 4: double temp-reject
client 127.0.0.1 PORT_D
quit
??? 221
****
-sleep 1
+millisleep 500
#
# 5: double reject
client 127.0.0.1 PORT_D
quit
??? 221
****
-sleep 1
+millisleep 500
+#
+# 6: no PRDR request
+client 127.0.0.1 PORT_D
+??? 220
+ehlo rhu.barb
+??? 250-
+??? 250-
+??? 250-
+??? 250-
+??? 250-PRDR
+??? 250
+mail from:<>
+??? 250
+rcpt to:<userx@test.ex>
+??? 250
+data
+??? 354
+Sender: sender@some.where
+.
+??? 250
+quit
+??? 221
+****
+millisleep 500
#
killdaemon
#
#
#
#
-# 1: Server sends good staple on request
+exim -z '1: Server sends good staple on request'
+****
+#
exim -bd -oX PORT_D -DSERVER=server \
-DOCSP=DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.ocsp.good.resp
****
#
#
#
-# 2: Server does not staple an outdated response
+exim -z '2: Server does not staple an outdated response'
+****
+#
exim -bd -oX PORT_D -DSERVER=server \
-DOCSP=DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.ocsp.dated.resp
****
#
#
#
-# 3: Server does not staple a response for a revoked cert
+exim -z '3: Server does not staple a response for a revoked cert'
+****
+#
exim -bd -oX PORT_D -DSERVER=server \
-DOCSP=DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.ocsp.revoked.resp
****
#
#
#
+exim -z '4: Connection functions when server is prepared to staple but client does not request it'
+****
+#
+exim -bd -oX PORT_D -DSERVER=server \
+ -DOCSP=DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.ocsp.good.resp
+****
+#
+client-ssl \
+ HOSTIPV4 PORT_D aux-fixed/cert2 aux-fixed/cert2
+??? 220
+ehlo rhu.barb
+??? 250-
+??? 250-
+??? 250-
+??? 250-
+??? 250-
+??? 250
+starttls
+??? 220
+ehlo rhu.barb.tls
+??? 250-
+??? 250-
+??? 250-
+??? 250-
+??? 250
+quit
+****
+killdaemon
+#
+#
+#
+#
+#
+++ /dev/null
-# OCSP stapling, client, tpda
-# duplicate of 5601
-#
-#
-# Client works when we request but don't require OCSP stapling and none comes
-exim -bd -oX PORT_D -DSERVER=server -DOCSP=/dev/null
-****
-exim norequire@test.ex
-test message.
-****
-sleep 1
-killdaemon
-#
-#
-#
-#
-# Client works when we request but don't require OCSP stapling and some arrives
-exim -bd -oX PORT_D -DSERVER=server \
- -DOCSP=DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.ocsp.good.resp
-****
-exim norequire@test.ex
-test message.
-****
-millisleep 500
-#
-#
-#
-#
-# Client works when we don't request OCSP stapling
-exim nostaple@test.ex
-test message.
-****
-millisleep 500
-#
-#
-#
-#
-# Client accepts good stapled info
-exim good@test.ex
-test message.
-****
-sleep 1
-killdaemon
-#
-#
-#
-# Client fails on lack of required stapled info
-exim -bd -oX PORT_D -DSERVER=server -DOCSP=/dev/null
-****
-exim failrequire@test.ex
-test message.
-****
-sleep 1
-killdaemon
-no_msglog_check
-#
-#
-#
-# Client fails on revoked stapled info
-EXIM_TESTHARNESS_DISABLE_OCSPVALIDITYCHECK=y exim -bd -oX PORT_D -DSERVER=server \
- -DOCSP=DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.ocsp.revoked.resp
-****
-exim failrevoked@test.ex
-test message.
-****
-sleep 1
-killdaemon
-#
-#
-#
-#
-# Client fails on expired stapled info
-EXIM_TESTHARNESS_DISABLE_OCSPVALIDITYCHECK=y exim -bd -oX PORT_D -DSERVER=server \
- -DOCSP=DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.ocsp.dated.resp
-****
-exim failexpired@test.ex
-test message.
-****
-sleep 1
-killdaemon
-#
-#
-#
-#
+++ /dev/null
-support OpenSSL
-support OCSP
-support Experimental_Event
-running IPv4
#
#
#
-# 1: Server sends good staple on request
+exim -z '1: Server sends good staple on request'
+****
+#
exim -bd -oX PORT_D -DSERVER=server \
-DOCSP=DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.ocsp.good.resp
****
#
#
#
-# 2: Server does not staple an outdated response
+exim -z '2: Server does not staple an outdated response'
+****
+#
exim -bd -oX PORT_D -DSERVER=server \
-DOCSP=DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.ocsp.dated.resp
****
#
#
#
-# 3: Server does not staple a response for a revoked cert
+exim -z '3: Server does not staple a response for a revoked cert'
+****
+#
exim -bd -oX PORT_D -DSERVER=server \
-DOCSP=DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.ocsp.revoked.resp
****
#
#
#
+exim -z '4: Connection functions when server is prepared to staple but client does not request it'
+****
+#
+exim -bd -oX PORT_D -DSERVER=server \
+ -DOCSP=DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.ocsp.good.resp
+****
+#
+client-gnutls \
+ HOSTIPV4 PORT_D aux-fixed/cert2 aux-fixed/cert2
+??? 220
+ehlo rhu.barb
+??? 250-
+??? 250-
+??? 250-
+??? 250-
+??? 250-
+??? 250
+starttls
+??? 220
+ehlo rhu.barb.tls
+??? 250-
+??? 250-
+??? 250-
+??? 250-
+??? 250
+quit
+****
+killdaemon
+#
+#
+#
+#
+#
+++ /dev/null
-# OCSP stapling, client, tpda
-# duplicate of 5651
-#
-#
-# Client works when we request but don't require OCSP stapling and none comes
-exim -bd -oX PORT_D -DSERVER=server -DOCSP=""
-****
-exim norequire@test.ex
-test message.
-****
-sleep 1
-killdaemon
-#
-#
-#
-#
-# Client works when we request but don't require OCSP stapling and some arrives
-exim -bd -oX PORT_D -DSERVER=server \
- -DOCSP=DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.ocsp.good.resp
-****
-exim norequire@test.ex
-test message.
-****
-millisleep 500
-#
-#
-#
-#
-# Client works when we don't request OCSP stapling
-exim nostaple@test.ex
-test message.
-****
-millisleep 500
-#
-#
-#
-#
-# Client accepts good stapled info
-exim good@test.ex
-test message.
-****
-sleep 1
-killdaemon
-#
-#
-#
-# Client fails on lack of required stapled info
-exim -bd -oX PORT_D -DSERVER=server -DOCSP=""
-****
-exim failrequire@test.ex
-test message.
-****
-sleep 1
-killdaemon
-no_msglog_check
-#
-#
-#
-# Client fails on revoked stapled info
-EXIM_TESTHARNESS_DISABLE_OCSPVALIDITYCHECK=y exim -bd -oX PORT_D -DSERVER=server \
- -DOCSP=DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.ocsp.revoked.resp
-****
-exim failrevoked@test.ex
-test message.
-****
-sleep 1
-killdaemon
-#
-#
-#
-#
-# Client fails on expired stapled info
-EXIM_TESTHARNESS_DISABLE_OCSPVALIDITYCHECK=y exim -bd -oX PORT_D -DSERVER=server \
- -DOCSP=DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.ocsp.dated.resp
-****
-exim failexpired@test.ex
-test message.
-****
-sleep 1
-killdaemon
-#
-#
-#
-#
+++ /dev/null
-support GnuTLS
-support OCSP
-support Experimental_Event
-running IPv4
--- /dev/null
+# Arbitrary expansion after transport
+# (EXPERIMENTAL_EVENT)
+#
+need_ipv4
+#
+exim -odq userx@domain1
+A deliverable message
+****
+server PORT_S
+220 ESMTP
+EHLO
+250-OK
+250 HELP
+MAIL
+250 OK
+RCPT
+250 OK
+DATA
+354 More...
+.
+250 OK
+QUIT
+220 OK
+****
+exim -qqf
+****
+#
+#
+#
+#
+exim -odq userx@domain2
+A deliverable message which will hit a coding error in the config
+****
+server PORT_S
+220 ESMTP
+EHLO
+250-OK
+250 HELP
+MAIL
+250 OK
+RCPT
+250 OK
+DATA
+354 More...
+.
+250 OK
+QUIT
+220 OK
+****
+exim -qqf
+****
+#
+#
+#
+server PORT_S
+220 ESMTP
+EHLO
+*sleep 4
+****
+exim -odi userx@domain1
+A message which will hit a timeout at the destination server
+.
+****
+#
+#
+#
+#
+#
+exim -odq userx@domain1
+A message which will get deferred
+****
+server PORT_S
+220 ESMTP
+EHLO
+250-OK
+250 HELP
+MAIL
+250 OK
+RCPT
+450 NOT RIGHT NOW
+QUIT
+220 OK
+****
+exim -qqf
+****
+#
+exim -odq userx@domain1
+A message which will get refused
+****
+server PORT_S
+220 ESMTP
+EHLO
+250-OK
+250 HELP
+MAIL
+250 OK
+RCPT
+550 GO AWAY
+QUIT
+220 OK
+****
+exim -qqf
+****
+#
+#
+#
+#
+exim -odq userx@domain1
+A message we will cancel from the queue
+****
+exim -odi -Mg $msg1
+****
--- /dev/null
+support Event
+++ /dev/null
-# Arbitrary expansion after transport
-# (EXPERIMENTAL_TPDA)
-#
-need_ipv4
-#
-exim -odq userx@domain1
-A deliverable message
-****
-server PORT_S
-220 ESMTP
-EHLO
-250-OK
-250 HELP
-MAIL
-250 OK
-RCPT
-250 OK
-DATA
-354 More...
-.
-250 OK
-QUIT
-220 OK
-****
-exim -qqf
-****
-#
-#
-#
-#
-exim -odq userx@domain2
-A deliverable message which will hit a coding error in the config
-****
-server PORT_S
-220 ESMTP
-EHLO
-250-OK
-250 HELP
-MAIL
-250 OK
-RCPT
-250 OK
-DATA
-354 More...
-.
-250 OK
-QUIT
-220 OK
-****
-exim -qqf
-****
-#
-#
-#
-server PORT_S
-220 ESMTP
-EHLO
-*sleep 4
-****
-exim -odi userx@domain1
-A message which will hit a timeout at the destination server
-.
-****
-#
-#
-#
-#
-#
-exim -odq userx@domain1
-A message which will get refused
-****
-server PORT_S
-220 ESMTP
-EHLO
-250-OK
-250 HELP
-MAIL
-250 OK
-RCPT
-550 GO AWAY
-QUIT
-220 OK
-****
-exim -qqf
-****
-#
-#
-#
-#
-exim -odq userx@domain1
-A message we will cancel from the queue
-****
-exim -odi -Mg $msg1
-****
+++ /dev/null
-support Experimental_Event
--- /dev/null
+# TLS client: GnuTLS $tls_out_peercert
+exim -DSERVER=server -bd -oX PORT_D
+****
+exim bad@test.ex
+Testing
+****
+exim good@test.ex
+Testing
+****
+exim -qf
+****
+killdaemon
+no_msglog_check
--- /dev/null
+support Event
+support GnuTLS
--- /dev/null
+# TLS client: OpenSSL certificates and extractions
+exim -DSERVER=server -bd -oX PORT_D
+****
+exim bad@test.ex
+Testing
+****
+exim good@test.ex
+Testing
+****
+exim -qf
+****
+killdaemon
+no_msglog_check
--- /dev/null
+support Event
+support OpenSSL
--- /dev/null
+# OCSP stapling, client, events
+# duplicate of 5651
+#
+#
+# Client works when we request but don't require OCSP stapling and none comes
+exim -bd -oX PORT_D -DSERVER=server -DOCSP=""
+****
+exim norequire@test.ex
+test message.
+****
+sleep 1
+killdaemon
+#
+#
+#
+#
+# Client works when we request but don't require OCSP stapling and some arrives
+exim -bd -oX PORT_D -DSERVER=server \
+ -DOCSP=DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.ocsp.good.resp
+****
+exim norequire@test.ex
+test message.
+****
+millisleep 500
+#
+#
+#
+#
+# Client works when we don't request OCSP stapling
+exim nostaple@test.ex
+test message.
+****
+millisleep 500
+#
+#
+#
+#
+# Client accepts good stapled info
+exim good@test.ex
+test message.
+****
+sleep 1
+killdaemon
+#
+#
+#
+# Client fails on lack of required stapled info
+exim -bd -oX PORT_D -DSERVER=server -DOCSP=""
+****
+exim failrequire@test.ex
+test message.
+****
+sleep 1
+killdaemon
+no_msglog_check
+#
+#
+#
+# Client fails on revoked stapled info
+EXIM_TESTHARNESS_DISABLE_OCSPVALIDITYCHECK=y exim -bd -oX PORT_D -DSERVER=server \
+ -DOCSP=DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.ocsp.revoked.resp
+****
+exim failrevoked@test.ex
+test message.
+****
+sleep 1
+killdaemon
+#
+#
+#
+#
+# Client fails on expired stapled info
+EXIM_TESTHARNESS_DISABLE_OCSPVALIDITYCHECK=y exim -bd -oX PORT_D -DSERVER=server \
+ -DOCSP=DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.ocsp.dated.resp
+****
+exim failexpired@test.ex
+test message.
+****
+sleep 1
+killdaemon
+#
+#
+#
+#
--- /dev/null
+support GnuTLS
+support OCSP
+support Event
+running IPv4
--- /dev/null
+# OCSP stapling, client, events
+# duplicate of 5601
+#
+#
+# Client works when we request but don't require OCSP stapling and none comes
+exim -bd -oX PORT_D -DSERVER=server -DOCSP=/dev/null
+****
+exim norequire@test.ex
+test message.
+****
+sleep 1
+killdaemon
+#
+#
+#
+#
+# Client works when we request but don't require OCSP stapling and some arrives
+exim -bd -oX PORT_D -DSERVER=server \
+ -DOCSP=DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.ocsp.good.resp
+****
+exim norequire@test.ex
+test message.
+****
+millisleep 500
+#
+#
+#
+#
+# Client works when we don't request OCSP stapling
+exim nostaple@test.ex
+test message.
+****
+millisleep 500
+#
+#
+#
+#
+# Client accepts good stapled info
+exim good@test.ex
+test message.
+****
+sleep 1
+killdaemon
+#
+#
+#
+# Client fails on lack of required stapled info
+exim -bd -oX PORT_D -DSERVER=server -DOCSP=/dev/null
+****
+exim failrequire@test.ex
+test message.
+****
+sleep 1
+killdaemon
+no_msglog_check
+#
+#
+#
+# Client fails on revoked stapled info
+EXIM_TESTHARNESS_DISABLE_OCSPVALIDITYCHECK=y exim -bd -oX PORT_D -DSERVER=server \
+ -DOCSP=DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.ocsp.revoked.resp
+****
+exim failrevoked@test.ex
+test message.
+****
+sleep 1
+killdaemon
+#
+#
+#
+#
+# Client fails on expired stapled info
+EXIM_TESTHARNESS_DISABLE_OCSPVALIDITYCHECK=y exim -bd -oX PORT_D -DSERVER=server \
+ -DOCSP=DIR/aux-fixed/exim-ca/example.com/server1.example.com/server1.example.com.ocsp.dated.resp
+****
+exim failexpired@test.ex
+test message.
+****
+sleep 1
+killdaemon
+#
+#
+#
+#
--- /dev/null
+support OpenSSL
+support OCSP
+support Event
+running IPv4
+++ /dev/null
-# TLS client: GnuTLS $tls_out_peercert
-exim -DSERVER=server -bd -oX PORT_D
-****
-exim bad@test.ex
-Testing
-****
-exim good@test.ex
-Testing
-****
-exim -qf
-****
-killdaemon
-no_msglog_check
+++ /dev/null
-support Experimental_Event
-support GnuTLS
+++ /dev/null
-# TLS client: OpenSSL certificates and extractions
-exim -DSERVER=server -bd -oX PORT_D
-****
-exim bad@test.ex
-Testing
-****
-exim good@test.ex
-Testing
-****
-exim -qf
-****
-killdaemon
-no_msglog_check
+++ /dev/null
-support Experimental_Event
-support OpenSSL
support Experimental_DANE
-running IPv4
+lookup dnsdb
exim -DSERVER=server -DDETAILS=ee -bd -oX PORT_D
****
# TLSA (3 1 1)
-exim CALLER@dane256ee.test.ex
+exim -odq CALLER@dane256ee.test.ex
Testing
****
# TLSA (3 1 2)
-exim CALLER@mxdane512ee.test.ex
+exim -odq CALLER@mxdane512ee.test.ex
Testing
****
exim -qf
****
-killdaemon
-exim -DSERVER=server -DDETAILS=ee -DNOTDAEMON -qf
+#
+#
+# Recipient callout
+exim -DOPT=callout -bhc 127.0.0.1
+MAIL FROM: <CALLER@myhost.test.ex>
+RCPT TO: <CALLER@dane256ee.test.ex>
****
+killdaemon
#
#
exim -DSERVER=server -DDETAILS=ta -bd -oX PORT_D
****
# TLSA (2 0 1)
-exim CALLER@mxdane256ta.test.ex
+exim -odq CALLER@mxdane256ta.test.ex
Testing
****
exim -qf
****
killdaemon
-exim -DSERVER=server -DDETAILS=ta -DNOTDAEMON -qf
+#
+# A server with a nonverifying cert and no TLSA
+# Check we get a non-CV but TLS connection, with try_dane but no require_dane
+exim -DSERVER=server -DDETAILS=no -bd -oX PORT_D
+****
+exim -odq CALLER@thishost.test.ex
+Testing
+****
+exim -qf
+****
+killdaemon
+#
+# A server with a verifying cert and no TLSA
+# Check we get a CV and TLS connection, with try_dane but no require_dane
+exim -DSERVER=server -DDETAILS=ca -bd -oX PORT_D
+****
+exim -odq CALLER@thishost.test.ex
+Testing
+****
+exim -DOPT=no_certname -qf
****
+killdaemon
+#
+#
+exim -DSERVER=server -DDETAILS=ee -bd -oX PORT_D
+****
+# A server with two MXs for which both TLSA lookups return defer
+exim -odq CALLER@mxdanelazy.test.ex
+Testing
+****
+# A server lacking a TLSA, required
+exim -odq CALLER@dane.no.1.test.ex
+Testing
+****
+# A server lacking a TLSA, requested only
+exim -odq CALLER@dane.no.2.test.ex
+Testing
+****
+exim -qf
+****
+killdaemon
+no_msglog_check
+++ /dev/null
-# DANE client: TPDA
-#
-exim -DSERVER=server -DDETAILS=ee -bd -oX PORT_D
-****
-# TLSA (3 1 1)
-exim CALLER@dane256ee.test.ex
-Testing
-****
-# TLSA (3 1 2)
-exim CALLER@mxdane512ee.test.ex
-Testing
-****
-exim -qf
-****
-killdaemon
-exim -DSERVER=server -DDETAILS=ee -DNOTDAEMON -qf
-****
-#
-#
-exim -DSERVER=server -DDETAILS=ta -bd -oX PORT_D
-****
-# TLSA (2 0 1)
-exim CALLER@mxdane256ta.test.ex
-Testing
-****
-exim -qf
-****
-killdaemon
-exim -DSERVER=server -DDETAILS=ta -DNOTDAEMON -qf
-****
+++ /dev/null
-support Experimental_DANE
-support Experimental_Event
-support OpenSSL
-running IPv4
--- /dev/null
+# DANE client: events
+#
+exim -DSERVER=server -DDETAILS=ee -bd -oX PORT_D
+****
+# TLSA (3 1 1)
+exim CALLER@dane256ee.test.ex
+Testing
+****
+# TLSA (3 1 2)
+exim CALLER@mxdane512ee.test.ex
+Testing
+****
+exim -qf
+****
+killdaemon
+exim -DSERVER=server -DDETAILS=ee -DNOTDAEMON -qf
+****
+#
+#
+exim -DSERVER=server -DDETAILS=ta -bd -oX PORT_D
+****
+# TLSA (2 0 1)
+exim CALLER@mxdane256ta.test.ex
+Testing
+****
+exim -qf
+****
+killdaemon
+exim -DSERVER=server -DDETAILS=ta -DNOTDAEMON -qf
+****
--- /dev/null
+support Experimental_DANE
+support Event
+support OpenSSL
+running IPv4
# define HAVE_OCSP
# include <gnutls/ocsp.h>
# endif
+# ifndef GNUTLS_NO_EXTENSIONS
+# define GNUTLS_NO_EXTENSIONS 0
+# endif
# define DH_BITS 768
/* Local static variables for GNUTLS */
-static gnutls_dh_params dh_params = NULL;
+static gnutls_dh_params_t dh_params = NULL;
static gnutls_certificate_credentials_t x509_cred = NULL;
-static gnutls_session tls_session = NULL;
+static gnutls_session_t tls_session = NULL;
static int ssl_session_timeout = 200;
/* Priorities for TLS algorithms to use. */
+#if GNUTLS_VERSION_NUMBER < 0x030400
static const int protocol_priority[16] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 };
static const int kx_priority[16] = {
0 };
static const int comp_priority[16] = { GNUTLS_COMP_NULL, 0 };
-static const int cert_type_priority[16] = { GNUTLS_CRT_X509, 0 };
+#endif
#endif /*HAVE_GNUTLS*/
{
int fd;
int ret;
-gnutls_datum m;
+gnutls_datum_t m;
uschar filename[200];
struct stat statbuf;
* Initialize a single GNUTLS session *
*************************************************/
-static gnutls_session
+static gnutls_session_t
tls_session_init(void)
{
-gnutls_session session;
+gnutls_session_t session;
-gnutls_init(&session, GNUTLS_CLIENT);
+gnutls_init(&session, GNUTLS_CLIENT | GNUTLS_NO_EXTENSIONS);
+#if GNUTLS_VERSION_NUMBER < 0x030400
gnutls_cipher_set_priority(session, default_cipher_priority);
gnutls_compression_set_priority(session, comp_priority);
gnutls_kx_set_priority(session, kx_priority);
gnutls_mac_set_priority(session, mac_priority);
gnutls_cred_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);
+#else
+gnutls_set_default_priority(session);
+gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred);
+#endif
gnutls_dh_set_prime_bits(session, DH_BITS);
gnutls_db_set_cache_expiration(session, ssl_session_timeout);
*************************************************/
const char * const HELP_MESSAGE = "\n\
-Usage: client\n\
+Usage: client\n"
+#ifdef HAVE_TLS
+"\
+ [-tls-on-connect]\n\
+ [-ocsp]\n"
+#endif
+"\
+ [-tn] n seconds timeout\n\
<IP address>\n\
<port>\n\
[<outgoing interface>]\n\
if (ocsp_stapling)
gnutls_ocsp_status_request_enable_client(tls_session, NULL, 0, NULL);
#endif
-gnutls_transport_set_ptr(tls_session, (gnutls_transport_ptr)sock);
+gnutls_transport_set_ptr(tls_session, (gnutls_transport_ptr_t)(intptr_t)sock);
/* When the server asks for a certificate and the client does not have one,
there is a SIGPIPE error in the gnutls_handshake() function for some reason
{
printf("Attempting to start TLS\n");
- #ifdef HAVE_OPENSSL
+#ifdef HAVE_OPENSSL
tls_active = tls_start(sock, &ssl, ctx);
- #endif
+#endif
- #ifdef HAVE_GNUTLS
+#ifdef HAVE_GNUTLS
+ {
+ int rc;
sigalrm_seen = FALSE;
alarm(timeout);
- tls_active = gnutls_handshake(tls_session) >= 0;
+ do {
+ rc = gnutls_handshake(tls_session);
+ } while (rc < 0 && gnutls_error_is_fatal(rc) == 0);
+ tls_active = rc >= 0;
alarm(0);
- #endif
+
+ if (!tls_active) printf("%s\n", gnutls_strerror(rc));
+ }
+#endif
if (!tls_active)
printf("Failed to start TLS\n");
- #if defined(HAVE_GNUTLS) && defined(HAVE_OCSP)
+#if defined(HAVE_GNUTLS) && defined(HAVE_OCSP)
else if ( ocsp_stapling
&& gnutls_ocsp_status_request_is_checked(tls_session, 0) == 0)
printf("Failed to verify certificate status\n");
- #endif
+#endif
else
printf("Succeeded in starting TLS\n");
}
while (fgets(CS outbuffer, sizeof(outbuffer), stdin) != NULL)
{
int n = (int)strlen(CS outbuffer);
- while (n > 0 && isspace(outbuffer[n-1])) n--;
- outbuffer[n] = 0;
+
+ /* Strip trailing newline */
+ if (outbuffer[n-1] == '\n') outbuffer[--n] = 0;
/* Expect incoming */
#endif
#ifdef HAVE_GNUTLS
- sigalrm_seen = FALSE;
- alarm(timeout);
- tls_active = gnutls_handshake(tls_session) >= 0;
- alarm(0);
+ {
+ int rc;
+ sigalrm_seen = FALSE;
+ alarm(timeout);
+ do {
+ rc = gnutls_handshake(tls_session);
+ } while (rc < 0 && gnutls_error_is_fatal(rc) == 0);
+ tls_active = rc >= 0;
+ alarm(0);
+
+ if (!tls_active) printf("%s\n", gnutls_strerror(rc));
+ }
#endif
if (!tls_active)
running in its (new) test harness, DNS lookups are first passed to this program
instead of to the real resolver. (With a few exceptions - see the discussion in
the test suite's README file.) The program is also passed the name of the Exim
-spool directory; it expects to find its "zone files" in ../dnszones relative to
-that directory. Note that there is little checking in this program. The fake
+spool directory; it expects to find its "zone files" in dnszones relative to
+exim config_main_directory. Note that there is little checking in this program. The fake
zone files are assumed to be syntactically valid.
The zones that are handled are found by scanning the dnszones directory. A file
and the domain is not found. It converts the the result to PASS_ON instead of
HOST_NOT_FOUND.
-Any DNS record line in a zone file can be prefixed with "DNSSEC" and
-at least one space; if all the records found by a lookup are marked
-as such then the response will have the "AD" bit set. */
+Any DNS record line in a zone file can be prefixed with "DELAY=" and
+a number of milliseconds (followed by one space).
+
+Any DNS record line in a zone file can be prefixed with "DNSSEC ";
+if all the records found by a lookup are marked
+as such then the response will have the "AD" bit set.
+
+Any DNS record line in a zone file can be prefixed with "AA "
+if all the records found by a lookup are marked
+as such then the response will have the "AA" bit set.
+
+Any DNS record line in a zone file can be prefixed with "TTL=" and
+a number of seconds (followed by one space).
+
+*/
#include <ctype.h>
#include <stdarg.h>
#include <string.h>
#include <netdb.h>
#include <errno.h>
+#include <signal.h>
#include <arpa/nameser.h>
+#include <arpa/inet.h>
#include <sys/types.h>
+#include <sys/time.h>
#include <dirent.h>
+#include <unistd.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
#define FALSE 0
#define TRUE 1
#define Ustrlen(s) (int)strlen(CCS(s))
#define Ustrncmp(s,t,n) strncmp(CCS(s),CCS(t),n)
#define Ustrncpy(s,t,n) strncpy(CS(s),CCS(t),n)
+#define Ustrtok(s,t) (uschar*)strtok(CS(s),CCS(t))
typedef struct zoneitem {
uschar *zone;
int value;
} tlist;
+#define DEFAULT_TTL 3600U
+
/* On some (older?) operating systems, the standard ns_t_xxx definitions are
not available, and only the older T_xxx ones exist in nameser.h. If ns_t_a is
not defined, assume we are in this state. A really old system might not even
{ US"A", ns_t_a },
{ US"NS", ns_t_ns },
{ US"CNAME", ns_t_cname },
-/* { US"SOA", ns_t_soa }, Not currently in use */
+ { US"SOA", ns_t_soa },
{ US"PTR", ns_t_ptr },
{ US"MX", ns_t_mx },
{ US"TXT", ns_t_txt },
return pk;
}
+uschar *
+longfield(uschar ** pp, uschar * pk)
+{
+unsigned long value = 0;
+uschar * p = *pp;
+
+while (isdigit(*p)) value = value*10 + *p++ - '0';
+while (isspace(*p)) p++;
+*pp = p;
+*pk++ = (value >> 24) & 255;
+*pk++ = (value >> 16) & 255;
+*pk++ = (value >> 8) & 255;
+*pk++ = value & 255;
+return pk;
+}
+
+
+
+/*************************************************/
+
+static void
+milliwait(struct itimerval *itval)
+{
+sigset_t sigmask;
+sigset_t old_sigmask;
+
+if (itval->it_value.tv_usec < 100 && itval->it_value.tv_sec == 0)
+ return;
+(void)sigemptyset(&sigmask); /* Empty mask */
+(void)sigaddset(&sigmask, SIGALRM); /* Add SIGALRM */
+(void)sigprocmask(SIG_BLOCK, &sigmask, &old_sigmask); /* Block SIGALRM */
+(void)setitimer(ITIMER_REAL, itval, NULL); /* Start timer */
+(void)sigfillset(&sigmask); /* All signals */
+(void)sigdelset(&sigmask, SIGALRM); /* Remove SIGALRM */
+(void)sigsuspend(&sigmask); /* Until SIGALRM */
+(void)sigprocmask(SIG_SETMASK, &old_sigmask, NULL); /* Restore mask */
+}
+
+static void
+millisleep(int msec)
+{
+struct itimerval itval;
+itval.it_interval.tv_sec = 0;
+itval.it_interval.tv_usec = 0;
+itval.it_value.tv_sec = msec/1000;
+itval.it_value.tv_usec = (msec % 1000) * 1000;
+milliwait(&itval);
+}
/*************************************************
qtypelen the length of qtype
pkptr points to the output buffer pointer; this is updated
countptr points to the record count; this is updated
+ dnssec points to the AD flag indicator; this is updated
+ aa points to the AA flag indicator; this is updated
Returns: 0 on success, else HOST_NOT_FOUND or NO_DATA or NO_RECOVERY or
PASS_ON - the latter if a "PASS ON NOT FOUND" line is seen
static int
find_records(FILE *f, uschar *zone, uschar *domain, uschar *qtype,
- int qtypelen, uschar **pkptr, int *countptr, BOOL * dnssec)
+ int qtypelen, uschar **pkptr, int *countptr, BOOL * dnssec, BOOL * aa)
{
int yield = HOST_NOT_FOUND;
int domainlen = Ustrlen(domain);
uschar rrdomain[256];
uschar RRdomain[256];
-/* Decode the required type */
+/* Decode the required type */
for (typeptr = type_list; typeptr->name != NULL; typeptr++)
{ if (Ustrcmp(typeptr->name, qtype) == 0) break; }
if (typeptr->name == NULL)
rrdomain[0] = 0; /* No previous domain */
(void)fseek(f, 0, SEEK_SET); /* Start again at the beginning */
-*dnssec = TRUE; /* cancelled by first nonsecure rec found */
+if (dnssec) *dnssec = TRUE; /* cancelled by first nonsecure rec found */
+if (aa) *aa = TRUE; /* cancelled by first non-aa rec found */
/* Scan for RRs */
uschar *rdlptr;
uschar *p, *ep, *pp;
BOOL found_cname = FALSE;
- int i, plen, value;
+ int i, value;
int tvalue = typeptr->value;
int qtlen = qtypelen;
BOOL rr_sec = FALSE;
+ BOOL rr_aa = FALSE;
+ int delay = 0;
+ uint ttl = DEFAULT_TTL;
p = buffer;
while (isspace(*p)) p++;
*ep = 0;
p = buffer;
- if (Ustrncmp(p, US"DNSSEC ", 7) == 0) /* tagged as secure */
+ for (;;)
{
- rr_sec = TRUE;
- p += 7;
+ if (Ustrncmp(p, US"DNSSEC ", 7) == 0) /* tagged as secure */
+ {
+ rr_sec = TRUE;
+ p += 7;
+ }
+ else if (Ustrncmp(p, US"AA ", 3) == 0) /* tagged as authoritive */
+ {
+ rr_aa = TRUE;
+ p += 3;
+ }
+ else if (Ustrncmp(p, US"DELAY=", 6) == 0) /* delay before response */
+ {
+ for (p += 6; *p >= '0' && *p <= '9'; p++) delay = delay*10 + *p - '0';
+ if (isspace(*p)) p++;
+ }
+ else if (Ustrncmp(p, US"TTL=", 4) == 0) /* TTL for record */
+ {
+ ttl = 0;
+ for (p += 4; *p >= '0' && *p <= '9'; p++) ttl = ttl*10 + *p - '0';
+ if (isspace(*p)) p++;
+ }
+ else
+ break;
}
- if (!isspace(*p))
+ if (!isspace(*p)) /* new domain name */
{
uschar *pp = rrdomain;
uschar *PP = RRdomain;
pp[-1] = 0;
PP[-1] = 0;
}
- }
+ } /* else use previous line's domain name */
/* Compare domain names; first check for a wildcard */
else if (Ustrncmp(p, qtype, qtypelen) != 0 || !isspace(p[qtypelen])) continue;
/* Found a relevant record */
+ if (delay)
+ millisleep(delay);
+
+ if (dnssec && !rr_sec)
+ *dnssec = FALSE; /* cancel AD return */
- if (!rr_sec)
- *dnssec = FALSE; /* cancel AD return */
+ if (aa && !rr_aa)
+ *aa = FALSE; /* cancel AA return */
yield = 0;
*countptr = *countptr + 1;
*pk++ = 0;
*pk++ = 1; /* class = IN */
- pk += 4; /* TTL field; don't care */
+ *pk++ = (ttl >>24) & 255;
+ *pk++ = (ttl >>16) & 255;
+ *pk++ = (ttl >> 8) & 255;
+ *pk++ = ttl & 255;
rdlptr = pk; /* remember rdlength field */
pk += 2;
switch (tvalue)
{
- case ns_t_soa: /* Not currently used */
- break;
+ case ns_t_soa:
+ p = Ustrtok(p, " ");
+ ep = p + Ustrlen(p);
+ if (ep[-1] != '.') sprintf(CS ep, "%s.", zone);
+ pk = packname(p, pk); /* primary ns */
+ p = Ustrtok(NULL, " ");
+ pk = packname(p , pk); /* responsible mailbox */
+ *(p += Ustrlen(p)) = ' ';
+ while (isspace(*p)) p++;
+ pk = longfield(&p, pk); /* serial */
+ pk = longfield(&p, pk); /* refresh */
+ pk = longfield(&p, pk); /* retry */
+ pk = longfield(&p, pk); /* expire */
+ pk = longfield(&p, pk); /* minimum */
+ break;
case ns_t_a:
- for (i = 0; i < 4; i++)
- {
- value = 0;
- while (isdigit(*p)) value = value*10 + *p++ - '0';
- *pk++ = value;
- p++;
- }
- break;
+ inet_pton(AF_INET, CCS p, pk); /* FIXME: error checking */
+ pk += 4;
+ break;
- /* The only occurrence of a double colon is for ::1 */
case ns_t_aaaa:
- if (Ustrcmp(p, "::1") == 0)
- {
- memset(pk, 0, 15);
- pk += 15;
- *pk++ = 1;
- }
- else for (i = 0; i < 8; i++)
- {
- value = 0;
- while (isxdigit(*p))
- {
- value = value * 16 + toupper(*p) - (isdigit(*p)? '0' : '7');
- p++;
- }
- *pk++ = (value >> 8) & 255;
- *pk++ = value & 255;
- p++;
- }
- break;
+ inet_pton(AF_INET6, CCS p, pk); /* FIXME: error checking */
+ pk += 16;
+ break;
case ns_t_mx:
- pk = shortfield(&p, pk);
- if (ep[-1] != '.') sprintf(CS ep, "%s.", zone);
- pk = packname(p, pk);
- plen = Ustrlen(p);
- break;
+ pk = shortfield(&p, pk);
+ if (ep[-1] != '.') sprintf(CS ep, "%s.", zone);
+ pk = packname(p, pk);
+ break;
case ns_t_txt:
- pp = pk++;
- if (*p == '"') p++; /* Should always be the case */
- while (*p != 0 && *p != '"') *pk++ = *p++;
- *pp = pk - pp - 1;
- break;
+ pp = pk++;
+ if (*p == '"') p++; /* Should always be the case */
+ while (*p != 0 && *p != '"') *pk++ = *p++;
+ *pp = pk - pp - 1;
+ break;
case ns_t_tlsa:
- pk = bytefield(&p, pk); /* usage */
- pk = bytefield(&p, pk); /* selector */
- pk = bytefield(&p, pk); /* match type */
- while (isxdigit(*p))
+ pk = bytefield(&p, pk); /* usage */
+ pk = bytefield(&p, pk); /* selector */
+ pk = bytefield(&p, pk); /* match type */
+ while (isxdigit(*p))
{
value = toupper(*p) - (isdigit(*p) ? '0' : '7') << 4;
if (isxdigit(*++p))
- {
- value |= toupper(*p) - (isdigit(*p) ? '0' : '7');
- p++;
- }
+ {
+ value |= toupper(*p) - (isdigit(*p) ? '0' : '7');
+ p++;
+ }
*pk++ = value & 255;
}
- break;
+ break;
case ns_t_srv:
- for (i = 0; i < 3; i++)
- {
- value = 0;
- while (isdigit(*p)) value = value*10 + *p++ - '0';
- while (isspace(*p)) p++;
- *pk++ = (value >> 8) & 255;
- *pk++ = value & 255;
- }
+ for (i = 0; i < 3; i++)
+ {
+ value = 0;
+ while (isdigit(*p)) value = value*10 + *p++ - '0';
+ while (isspace(*p)) p++;
+ *pk++ = (value >> 8) & 255;
+ *pk++ = value & 255;
+ }
/* Fall through */
case ns_t_cname:
case ns_t_ns:
case ns_t_ptr:
- if (ep[-1] != '.') sprintf(CS ep, "%s.", zone);
- pk = packname(p, pk);
- plen = Ustrlen(p);
- break;
+ if (ep[-1] != '.') sprintf(CS ep, "%s.", zone);
+ pk = packname(p, pk);
+ break;
}
/* Fill in the length, and we are done with this RR */
}
+static void
+alarmfn(int sig)
+{
+}
+
+
+/*************************************************
+* Special-purpose domains *
+*************************************************/
+
+static int
+special_manyhome(uschar * packet, uschar * domain)
+{
+uschar *pk = packet + 12;
+uschar *rdlptr;
+int i, j;
+
+memset(packet, 0, 12);
+
+for (i = 104; i <= 111; i++) for (j = 0; j <= 255; j++)
+ {
+ pk = packname(domain, pk);
+ *pk++ = (ns_t_a >> 8) & 255;
+ *pk++ = (ns_t_a) & 255;
+ *pk++ = 0;
+ *pk++ = 1; /* class = IN */
+ pk += 4; /* TTL field; don't care */
+ rdlptr = pk; /* remember rdlength field */
+ pk += 2;
+
+ *pk++ = 10; *pk++ = 250; *pk++ = i; *pk++ = j;
+
+ rdlptr[0] = ((pk - rdlptr - 2) >> 8) & 255;
+ rdlptr[1] = (pk - rdlptr - 2) & 255;
+ }
+
+packet[6] = (2048 >> 8) & 255;
+packet[7] = 2048 & 255;
+packet[10] = 0;
+packet[11] = 0;
+
+(void)fwrite(packet, 1, pk - packet, stdout);
+return 0;
+}
+
+static int
+special_again(uschar * packet, uschar * domain)
+{
+int delay = atoi(CCS domain); /* digits at the start of the name */
+if (delay > 0) sleep(delay);
+return TRY_AGAIN;
+}
+
/*************************************************
* Entry point and main program *
uschar domain[256];
uschar buffer[256];
uschar qtype[12];
-uschar packet[512];
+uschar packet[2048 * 32 + 32];
+HEADER *header = (HEADER *)packet;
uschar *pk = packet;
BOOL dnssec;
+BOOL aa;
+
+signal(SIGALRM, alarmfn);
if (argc != 4)
{
/* Find the zones */
-(void)sprintf(CS buffer, "%s/../dnszones", argv[1]);
+(void)sprintf(CS buffer, "%s/dnszones", argv[1]);
d = opendir(CCS buffer);
if (d == NULL)
qtypelen = Ustrlen(qtype);
for (p = qtype; *p != 0; p++) *p = toupper(*p);
-/* Find the domain, lower case it, check that it is in a zone that we handle,
+/* Find the domain, lower case it, deal with any specials,
+check that it is in a zone that we handle,
and set up the zone file name. The zone names in the table all start with a
dot. */
domain[domlen] = 0;
for (i = 0; i < domlen; i++) domain[i] = tolower(domain[i]);
+if (Ustrcmp(domain, "manyhome.test.ex") == 0 && Ustrcmp(qtype, "A") == 0)
+ return special_manyhome(packet, domain);
+else if (domlen >= 14 && Ustrcmp(domain + domlen - 14, "test.again.dns") == 0)
+ return special_again(packet, domain);
+else if (domlen >= 13 && Ustrcmp(domain + domlen - 13, "test.fail.dns") == 0)
+ return NO_RECOVERY;
+
+
if (Ustrchr(domain, '.') == NULL && qualify != NULL &&
Ustrcmp(domain, "dontqualify") != 0)
{
return PASS_ON;
}
-(void)sprintf(CS buffer, "%s/../dnszones/%s", argv[1], zonefile);
+(void)sprintf(CS buffer, "%s/dnszones/%s", argv[1], zonefile);
/* Initialize the start of the response packet. We don't have to fake up
everything, because we know that Exim will look only at the answer and
/* Find the records we want, and add them to the result. */
count = 0;
-yield = find_records(f, zone, domain, qtype, qtypelen, &pk, &count, &dnssec);
+yield = find_records(f, zone, domain, qtype, qtypelen, &pk, &count, &dnssec, &aa);
if (yield == NO_RECOVERY) goto END_OFF;
+header->ancount = htons(count);
+
+/* If the AA bit should be set (as indicated by the AA prefix in the zone file),
+we are expected to return some records in the authortive section. Bind9: If
+there is data in the answer section, the authoritive section contains the NS
+records, otherwise it contains the SOA record. Currently we mimic this
+behaviour for the first case (there is some answer record).
+*/
-packet[6] = (count >> 8) & 255;
-packet[7] = count & 255;
+if (aa)
+ find_records(f, zone, zone[0] == '.' ? zone+1 : zone, US"NS", 2, &pk, &count, NULL, NULL);
+header->nscount = htons(count - ntohs(header->ancount));
/* There is no need to return any additional records because Exim no longer
(from release 4.61) makes any use of them. */
-
-packet[10] = 0;
-packet[11] = 0;
+header->arcount = 0;
if (dnssec)
- ((HEADER *)packet)->ad = 1;
+ header->ad = 1;
+
+if (aa)
+ header->aa = 1;
/* Close the zone file, write the result, and return. */
return yield;
}
-/* vi: aw ai sw=2
+/* vi: aw ai sw=2 sts=2 ts=8 et
*/
/* End of fakens.c */
typedef struct line {
struct line *next;
+ unsigned len;
char line[1];
} line;
}
+
+static void
+printit(char * s, int n)
+{
+while(n--)
+ {
+ unsigned char c = *s++;
+ if (c == '\\')
+ printf("\\\\");
+ else if (c >= ' ' && c <= '~') /* assumes ascii */
+ putchar(c);
+ else
+ printf("\\x%02x", c);
+ }
+putchar('\n');
+}
+
+
+
/*************************************************
* Main Program *
*************************************************/
int count;
int on = 1;
int timeout = 5;
+int initial_pause = 0;
int use_ipv4 = 1;
int use_ipv6 = 1;
int debug = 0;
line *last = NULL;
line *s;
FILE *in, *out;
+int linebuf = 1;
+char *pidfile = NULL;
char *sockname = NULL;
unsigned char buffer[10240];
/* Sort out the arguments */
+if (argc > 1 && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")))
+ {
+ printf("Usage: %s [options]\n", argv[0]);
+ puts("Options"
+ "\n\t-d debug"
+ "\n\t-i n n seconds initial delay"
+ "\n\t-noipv4 disable ipv4"
+ "\n\t-noipv6 disable ipv6"
+ "\n\t-oP file write PID to file"
+ "\n\t-t n n seconds timeout"
+ );
+ exit(0);
+ }
while (na < argc && argv[na][0] == '-')
{
if (strcmp(argv[na], "-d") == 0) debug = 1;
else if (strcmp(argv[na], "-t") == 0) timeout = atoi(argv[++na]);
+ else if (strcmp(argv[na], "-i") == 0) initial_pause = atoi(argv[++na]);
else if (strcmp(argv[na], "-noipv4") == 0) use_ipv4 = 0;
else if (strcmp(argv[na], "-noipv6") == 0) use_ipv6 = 0;
+ else if (strcmp(argv[na], "-oP") == 0) pidfile = argv[++na];
else
{
- printf("server: unknown option %s\n", argv[na]);
+ printf("server: unknown option %s, try -h or --help\n", argv[na]);
exit(1);
}
na++;
if (na < argc) connection_count = atoi(argv[na]);
+/* Initial pause (before creating listen sockets */
+if (initial_pause > 0)
+ {
+ if (debug)
+ printf("%d: Inital pause of %d seconds\n", time(NULL), initial_pause);
+ else
+ printf("Inital pause of %d seconds\n", initial_pause);
+ while (initial_pause > 0)
+ initial_pause = sleep(initial_pause);
+ }
+
/* Create sockets */
if (port == 0) /* Unix domain */
{
- if (debug) printf("Creating Unix domain socket\n");
+ if (debug) printf("%d: Creating Unix domain socket\n", time(NULL));
listen_socket[udn] = socket(PF_UNIX, SOCK_STREAM, 0);
if (listen_socket[udn] < 0)
{
}
+if (pidfile)
+ {
+ FILE * p;
+ if (!(p = fopen(pidfile, "w")))
+ {
+ fprintf(stderr, "pidfile create failed: %s\n", strerror(errno));
+ exit(1);
+ }
+ fprintf(p, "%ld\n", (long)getpid());
+ fclose(p);
+ }
+
/* This program handles only a fixed number of connections, in sequence. Before
waiting for the first connection, read the standard input, which contains the
script of things to do. A line containing "++++" is treated as end of file.
This is so that the Perl driving script doesn't have to close the pipe -
because that would cause it to wait for this process, which it doesn't yet want
to do. The driving script adds the "++++" automatically - it doesn't actually
-appear in the test script. */
+appear in the test script. Within lines we interpret \xNN and \\ groups */
while (fgets(CS buffer, sizeof(buffer), stdin) != NULL)
{
line *next;
+ char * d;
int n = (int)strlen(CS buffer);
+
+ if (n > 1 && buffer[0] == '>' && buffer[1] == '>')
+ linebuf = 0;
while (n > 0 && isspace(buffer[n-1])) n--;
buffer[n] = 0;
if (strcmp(CS buffer, "++++") == 0) break;
next = malloc(sizeof(line) + n);
next->next = NULL;
- strcpy(next->line, CS buffer);
+ d = next->line;
+ {
+ char * s = CS buffer;
+ do
+ {
+ char ch;
+ char cl = *s;
+ if (cl == '\\' && (cl = *++s) == 'x')
+ {
+ if ((ch = *++s - '0') > 9 && (ch -= 'A'-'9'-1) > 15) ch -= 'a'-'A';
+ if ((cl = *++s - '0') > 9 && (cl -= 'A'-'9'-1) > 15) cl -= 'a'-'A';
+ cl |= ch << 4;
+ }
+ *d++ = cl;
+ }
+ while (*s++);
+ }
+ next->len = d - next->line - 1;
if (last == NULL) script = last = next;
else last->next = next;
last = next;
if (ss[0] == '>')
{
char *end = "\r\n";
- printf("%s\n", ss++);
+ unsigned len = s->len;
+ printit(ss++, len--);
if (strncmp(ss, "*eof", 4) == 0)
{
}
if (*ss == '>')
- { end = ""; ss++; }
+ { end = ""; ss++; len--; }
else if (strncmp(ss, "CR>", 3) == 0)
- { end = "\r"; ss += 3; }
+ { end = "\r"; ss += 3; len -= 3; }
else if (strncmp(ss, "LF>", 3) == 0)
- { end = "\n"; ss += 3; }
+ { end = "\n"; ss += 3; len -= 3; }
- fprintf(out, "%s%s", ss, end);
+ fwrite(ss, 1, len, out);
+ if (*end) fprintf(out, end);
}
else if (isdigit((unsigned char)ss[0]))
connection. Read command line or data lines; the latter are indicated
by the expected line being just ".". If the line starts with '<', that
doesn't form part of the expected input. (This allows for incoming data
- starting with a digit.) */
+ starting with a digit.) If the line starts with '<<' we operate in
+ unbuffered rather than line mode and assume that a single read gets the
+ entire message. */
else
{
int offset;
int data = strcmp(ss, ".") == 0;
- if (ss[0] == '<')
+ if (ss[0] != '<')
+ offset = 0;
+ else
{
buffer[0] = '<';
- offset = 1;
+ if (ss[1] != '<')
+ offset = 1;
+ else
+ {
+ buffer[1] = '<';
+ offset = 2;
+ }
}
- else offset = 0;
fflush(out);
- for (;;)
- {
- int n;
- alarm(timeout);
- if (fgets(CS buffer+offset, sizeof(buffer)-offset, in) == NULL)
- {
- printf("%sxpected EOF read from client\n",
- (strncmp(ss, "*eof", 4) == 0)? "E" : "Une");
- s = s->next;
- goto END_OFF;
- }
- alarm(0);
- n = (int)strlen(CS buffer);
- while (n > 0 && isspace(buffer[n-1])) n--;
- buffer[n] = 0;
- printf("%s\n", buffer);
- if (!data || strcmp(CS buffer, ".") == 0) break;
- }
-
- if (strncmp(ss, CS buffer, (int)strlen(ss)) != 0)
- {
- printf("Comparison failed - bailing out\n");
- printf("Expected: %s\n", ss);
- break;
- }
+ if (!linebuf)
+ {
+ int n;
+ char c;
+
+ alarm(timeout);
+ n = read(dup_accept_socket, CS buffer+offset, s->len - offset);
+ if (n == 0)
+ {
+ printf("%sxpected EOF read from client\n",
+ (strncmp(ss, "*eof", 4) == 0)? "E" : "Une");
+ s = s->next;
+ goto END_OFF;
+ }
+ if (offset != 2)
+ while (read(dup_accept_socket, &c, 1) == 1 && c != '\n') ;
+ alarm(0);
+ n += offset;
+
+ printit(buffer, n);
+
+ if (data) do
+ {
+ n = (read(dup_accept_socket, &c, 1) == 1 && c == '.');
+ while (c != '\n' && read(dup_accept_socket, &c, 1) == 1)
+ ;
+ } while (!n);
+ else if (memcmp(ss, buffer, n) != 0)
+ {
+ printf("Comparison failed - bailing out\nExpected: ");
+ printit(ss, n);
+ break;
+ }
+ }
+ else
+ {
+ for (;;)
+ {
+ int n;
+ alarm(timeout);
+ if (fgets(CS buffer+offset, sizeof(buffer)-offset, in) == NULL)
+ {
+ printf("%sxpected EOF read from client\n",
+ (strncmp(ss, "*eof", 4) == 0)? "E" : "Une");
+ s = s->next;
+ goto END_OFF;
+ }
+ alarm(0);
+ n = (int)strlen(CS buffer);
+ while (n > 0 && isspace(buffer[n-1])) n--;
+ buffer[n] = 0;
+ printf("%s\n", buffer);
+ if (!data || strcmp(CS buffer, ".") == 0) break;
+ }
+
+ if (strncmp(ss, CS buffer, (int)strlen(ss)) != 0)
+ {
+ printf("Comparison failed - bailing out\n");
+ printf("Expected: %s\n", ss);
+ break;
+ }
+ }
}
}
result: ----> No lookup yet: No
looking up host name for V4NET.0.0.1
IP address lookup yielded "ten-1.test.ex"
-using host_fake_gethostbyname for ten-1.test.ex (IPv4)
-MUNGED: ::1 will be omitted in what follows
-get[host|ipnode]byname[2] looked up these IP addresses:
- name=ten-1.test.ex address=V4NET.0.0.1
+ten-1.test.ex V4NET.0.0.1 mx=-1 sort=xx
checking addresses for ten-1.test.ex
V4NET.0.0.1 OK
sender_fullhost = ten-1.test.ex [V4NET.0.0.1]
DNS lookup of 1.0.0.V4NET.in-addr.arpa (PTR) using fakens
DNS lookup of 1.0.0.V4NET.in-addr.arpa (PTR) succeeded
IP address lookup yielded "ten-1.test.ex"
-using host_fake_gethostbyname for ten-1.test.ex (IPv4)
DNS lookup of ten-1.test.ex (A) using fakens
DNS lookup of ten-1.test.ex (A) succeeded
-MUNGED: ::1 will be omitted in what follows
-get[host|ipnode]byname[2] looked up these IP addresses:
- name=ten-1.test.ex address=V4NET.0.0.1
+ten-1.test.ex V4NET.0.0.1 mx=-1 sort=xx
checking addresses for ten-1.test.ex
+Forward DNS security status: unverified
V4NET.0.0.1 OK
sender_fullhost = ten-1.test.ex [V4NET.0.0.1]
sender_rcvhost = ten-1.test.ex ([V4NET.0.0.1])
-1999-03-02 09:44:33 Exim configuration error in line 14 of TESTSUITE/test-config:
+1999-03-02 09:44:33 Exim configuration error in line 15 of TESTSUITE/test-config:
extra characters follow string value for relay_hosts
>>> host in host_lookup? yes (matched "10.250.104.0/21")
>>> looking up host name for 10.250.104.42
>>> IP address lookup yielded "manyhome.test.ex"
-MUNGED: ::1 will be omitted in what follows
->>> get[host|ipnode]byname[2] looked up these IP addresses:
->>> name=manyhome.test.ex address=10.250.104.0
->>> name=manyhome.test.ex address=10.250.104.1
->>> name=manyhome.test.ex address=10.250.104.2
->>> name=manyhome.test.ex address=10.250.104.3
->>> name=manyhome.test.ex address=10.250.104.4
->>> name=manyhome.test.ex address=10.250.104.5
->>> name=manyhome.test.ex address=10.250.104.6
->>> name=manyhome.test.ex address=10.250.104.7
->>> name=manyhome.test.ex address=10.250.104.8
->>> name=manyhome.test.ex address=10.250.104.9
->>> name=manyhome.test.ex address=10.250.104.10
->>> name=manyhome.test.ex address=10.250.104.11
->>> name=manyhome.test.ex address=10.250.104.12
->>> name=manyhome.test.ex address=10.250.104.13
->>> name=manyhome.test.ex address=10.250.104.14
->>> name=manyhome.test.ex address=10.250.104.15
->>> name=manyhome.test.ex address=10.250.104.16
->>> name=manyhome.test.ex address=10.250.104.17
->>> name=manyhome.test.ex address=10.250.104.18
->>> name=manyhome.test.ex address=10.250.104.19
->>> name=manyhome.test.ex address=10.250.104.20
->>> name=manyhome.test.ex address=10.250.104.21
->>> name=manyhome.test.ex address=10.250.104.22
->>> name=manyhome.test.ex address=10.250.104.23
->>> name=manyhome.test.ex address=10.250.104.24
->>> name=manyhome.test.ex address=10.250.104.25
->>> name=manyhome.test.ex address=10.250.104.26
->>> name=manyhome.test.ex address=10.250.104.27
->>> name=manyhome.test.ex address=10.250.104.28
->>> name=manyhome.test.ex address=10.250.104.29
->>> name=manyhome.test.ex address=10.250.104.30
->>> name=manyhome.test.ex address=10.250.104.31
->>> name=manyhome.test.ex address=10.250.104.32
->>> name=manyhome.test.ex address=10.250.104.33
->>> name=manyhome.test.ex address=10.250.104.34
->>> name=manyhome.test.ex address=10.250.104.35
->>> name=manyhome.test.ex address=10.250.104.36
->>> name=manyhome.test.ex address=10.250.104.37
->>> name=manyhome.test.ex address=10.250.104.38
->>> name=manyhome.test.ex address=10.250.104.39
->>> name=manyhome.test.ex address=10.250.104.40
->>> name=manyhome.test.ex address=10.250.104.41
->>> name=manyhome.test.ex address=10.250.104.42
->>> name=manyhome.test.ex address=10.250.104.43
->>> name=manyhome.test.ex address=10.250.104.44
->>> name=manyhome.test.ex address=10.250.104.45
->>> name=manyhome.test.ex address=10.250.104.46
->>> name=manyhome.test.ex address=10.250.104.47
->>> name=manyhome.test.ex address=10.250.104.48
->>> name=manyhome.test.ex address=10.250.104.49
->>> name=manyhome.test.ex address=10.250.104.50
->>> name=manyhome.test.ex address=10.250.104.51
->>> name=manyhome.test.ex address=10.250.104.52
->>> name=manyhome.test.ex address=10.250.104.53
->>> name=manyhome.test.ex address=10.250.104.54
->>> name=manyhome.test.ex address=10.250.104.55
->>> name=manyhome.test.ex address=10.250.104.56
->>> name=manyhome.test.ex address=10.250.104.57
->>> name=manyhome.test.ex address=10.250.104.58
->>> name=manyhome.test.ex address=10.250.104.59
->>> name=manyhome.test.ex address=10.250.104.60
->>> name=manyhome.test.ex address=10.250.104.61
->>> name=manyhome.test.ex address=10.250.104.62
->>> name=manyhome.test.ex address=10.250.104.63
->>> name=manyhome.test.ex address=10.250.104.64
->>> name=manyhome.test.ex address=10.250.104.65
->>> name=manyhome.test.ex address=10.250.104.66
->>> name=manyhome.test.ex address=10.250.104.67
->>> name=manyhome.test.ex address=10.250.104.68
->>> name=manyhome.test.ex address=10.250.104.69
->>> name=manyhome.test.ex address=10.250.104.70
->>> name=manyhome.test.ex address=10.250.104.71
->>> name=manyhome.test.ex address=10.250.104.72
->>> name=manyhome.test.ex address=10.250.104.73
->>> name=manyhome.test.ex address=10.250.104.74
->>> name=manyhome.test.ex address=10.250.104.75
->>> name=manyhome.test.ex address=10.250.104.76
->>> name=manyhome.test.ex address=10.250.104.77
->>> name=manyhome.test.ex address=10.250.104.78
->>> name=manyhome.test.ex address=10.250.104.79
->>> name=manyhome.test.ex address=10.250.104.80
->>> name=manyhome.test.ex address=10.250.104.81
->>> name=manyhome.test.ex address=10.250.104.82
->>> name=manyhome.test.ex address=10.250.104.83
->>> name=manyhome.test.ex address=10.250.104.84
->>> name=manyhome.test.ex address=10.250.104.85
->>> name=manyhome.test.ex address=10.250.104.86
->>> name=manyhome.test.ex address=10.250.104.87
->>> name=manyhome.test.ex address=10.250.104.88
->>> name=manyhome.test.ex address=10.250.104.89
->>> name=manyhome.test.ex address=10.250.104.90
->>> name=manyhome.test.ex address=10.250.104.91
->>> name=manyhome.test.ex address=10.250.104.92
->>> name=manyhome.test.ex address=10.250.104.93
->>> name=manyhome.test.ex address=10.250.104.94
->>> name=manyhome.test.ex address=10.250.104.95
->>> name=manyhome.test.ex address=10.250.104.96
->>> name=manyhome.test.ex address=10.250.104.97
->>> name=manyhome.test.ex address=10.250.104.98
->>> name=manyhome.test.ex address=10.250.104.99
->>> name=manyhome.test.ex address=10.250.104.100
->>> name=manyhome.test.ex address=10.250.104.101
->>> name=manyhome.test.ex address=10.250.104.102
->>> name=manyhome.test.ex address=10.250.104.103
->>> name=manyhome.test.ex address=10.250.104.104
->>> name=manyhome.test.ex address=10.250.104.105
->>> name=manyhome.test.ex address=10.250.104.106
->>> name=manyhome.test.ex address=10.250.104.107
->>> name=manyhome.test.ex address=10.250.104.108
->>> name=manyhome.test.ex address=10.250.104.109
->>> name=manyhome.test.ex address=10.250.104.110
->>> name=manyhome.test.ex address=10.250.104.111
->>> name=manyhome.test.ex address=10.250.104.112
->>> name=manyhome.test.ex address=10.250.104.113
->>> name=manyhome.test.ex address=10.250.104.114
->>> name=manyhome.test.ex address=10.250.104.115
->>> name=manyhome.test.ex address=10.250.104.116
->>> name=manyhome.test.ex address=10.250.104.117
->>> name=manyhome.test.ex address=10.250.104.118
->>> name=manyhome.test.ex address=10.250.104.119
->>> name=manyhome.test.ex address=10.250.104.120
->>> name=manyhome.test.ex address=10.250.104.121
->>> name=manyhome.test.ex address=10.250.104.122
->>> name=manyhome.test.ex address=10.250.104.123
->>> name=manyhome.test.ex address=10.250.104.124
->>> name=manyhome.test.ex address=10.250.104.125
->>> name=manyhome.test.ex address=10.250.104.126
->>> name=manyhome.test.ex address=10.250.104.127
->>> name=manyhome.test.ex address=10.250.104.128
->>> name=manyhome.test.ex address=10.250.104.129
->>> name=manyhome.test.ex address=10.250.104.130
->>> name=manyhome.test.ex address=10.250.104.131
->>> name=manyhome.test.ex address=10.250.104.132
->>> name=manyhome.test.ex address=10.250.104.133
->>> name=manyhome.test.ex address=10.250.104.134
->>> name=manyhome.test.ex address=10.250.104.135
->>> name=manyhome.test.ex address=10.250.104.136
->>> name=manyhome.test.ex address=10.250.104.137
->>> name=manyhome.test.ex address=10.250.104.138
->>> name=manyhome.test.ex address=10.250.104.139
->>> name=manyhome.test.ex address=10.250.104.140
->>> name=manyhome.test.ex address=10.250.104.141
->>> name=manyhome.test.ex address=10.250.104.142
->>> name=manyhome.test.ex address=10.250.104.143
->>> name=manyhome.test.ex address=10.250.104.144
->>> name=manyhome.test.ex address=10.250.104.145
->>> name=manyhome.test.ex address=10.250.104.146
->>> name=manyhome.test.ex address=10.250.104.147
->>> name=manyhome.test.ex address=10.250.104.148
->>> name=manyhome.test.ex address=10.250.104.149
->>> name=manyhome.test.ex address=10.250.104.150
->>> name=manyhome.test.ex address=10.250.104.151
->>> name=manyhome.test.ex address=10.250.104.152
->>> name=manyhome.test.ex address=10.250.104.153
->>> name=manyhome.test.ex address=10.250.104.154
->>> name=manyhome.test.ex address=10.250.104.155
->>> name=manyhome.test.ex address=10.250.104.156
->>> name=manyhome.test.ex address=10.250.104.157
->>> name=manyhome.test.ex address=10.250.104.158
->>> name=manyhome.test.ex address=10.250.104.159
->>> name=manyhome.test.ex address=10.250.104.160
->>> name=manyhome.test.ex address=10.250.104.161
->>> name=manyhome.test.ex address=10.250.104.162
->>> name=manyhome.test.ex address=10.250.104.163
->>> name=manyhome.test.ex address=10.250.104.164
->>> name=manyhome.test.ex address=10.250.104.165
->>> name=manyhome.test.ex address=10.250.104.166
->>> name=manyhome.test.ex address=10.250.104.167
->>> name=manyhome.test.ex address=10.250.104.168
->>> name=manyhome.test.ex address=10.250.104.169
->>> name=manyhome.test.ex address=10.250.104.170
->>> name=manyhome.test.ex address=10.250.104.171
->>> name=manyhome.test.ex address=10.250.104.172
->>> name=manyhome.test.ex address=10.250.104.173
->>> name=manyhome.test.ex address=10.250.104.174
->>> name=manyhome.test.ex address=10.250.104.175
->>> name=manyhome.test.ex address=10.250.104.176
->>> name=manyhome.test.ex address=10.250.104.177
->>> name=manyhome.test.ex address=10.250.104.178
->>> name=manyhome.test.ex address=10.250.104.179
->>> name=manyhome.test.ex address=10.250.104.180
->>> name=manyhome.test.ex address=10.250.104.181
->>> name=manyhome.test.ex address=10.250.104.182
->>> name=manyhome.test.ex address=10.250.104.183
->>> name=manyhome.test.ex address=10.250.104.184
->>> name=manyhome.test.ex address=10.250.104.185
->>> name=manyhome.test.ex address=10.250.104.186
->>> name=manyhome.test.ex address=10.250.104.187
->>> name=manyhome.test.ex address=10.250.104.188
->>> name=manyhome.test.ex address=10.250.104.189
->>> name=manyhome.test.ex address=10.250.104.190
->>> name=manyhome.test.ex address=10.250.104.191
->>> name=manyhome.test.ex address=10.250.104.192
->>> name=manyhome.test.ex address=10.250.104.193
->>> name=manyhome.test.ex address=10.250.104.194
->>> name=manyhome.test.ex address=10.250.104.195
->>> name=manyhome.test.ex address=10.250.104.196
->>> name=manyhome.test.ex address=10.250.104.197
->>> name=manyhome.test.ex address=10.250.104.198
->>> name=manyhome.test.ex address=10.250.104.199
->>> name=manyhome.test.ex address=10.250.104.200
->>> name=manyhome.test.ex address=10.250.104.201
->>> name=manyhome.test.ex address=10.250.104.202
->>> name=manyhome.test.ex address=10.250.104.203
->>> name=manyhome.test.ex address=10.250.104.204
->>> name=manyhome.test.ex address=10.250.104.205
->>> name=manyhome.test.ex address=10.250.104.206
->>> name=manyhome.test.ex address=10.250.104.207
->>> name=manyhome.test.ex address=10.250.104.208
->>> name=manyhome.test.ex address=10.250.104.209
->>> name=manyhome.test.ex address=10.250.104.210
->>> name=manyhome.test.ex address=10.250.104.211
->>> name=manyhome.test.ex address=10.250.104.212
->>> name=manyhome.test.ex address=10.250.104.213
->>> name=manyhome.test.ex address=10.250.104.214
->>> name=manyhome.test.ex address=10.250.104.215
->>> name=manyhome.test.ex address=10.250.104.216
->>> name=manyhome.test.ex address=10.250.104.217
->>> name=manyhome.test.ex address=10.250.104.218
->>> name=manyhome.test.ex address=10.250.104.219
->>> name=manyhome.test.ex address=10.250.104.220
->>> name=manyhome.test.ex address=10.250.104.221
->>> name=manyhome.test.ex address=10.250.104.222
->>> name=manyhome.test.ex address=10.250.104.223
->>> name=manyhome.test.ex address=10.250.104.224
->>> name=manyhome.test.ex address=10.250.104.225
->>> name=manyhome.test.ex address=10.250.104.226
->>> name=manyhome.test.ex address=10.250.104.227
->>> name=manyhome.test.ex address=10.250.104.228
->>> name=manyhome.test.ex address=10.250.104.229
->>> name=manyhome.test.ex address=10.250.104.230
->>> name=manyhome.test.ex address=10.250.104.231
->>> name=manyhome.test.ex address=10.250.104.232
->>> name=manyhome.test.ex address=10.250.104.233
->>> name=manyhome.test.ex address=10.250.104.234
->>> name=manyhome.test.ex address=10.250.104.235
->>> name=manyhome.test.ex address=10.250.104.236
->>> name=manyhome.test.ex address=10.250.104.237
->>> name=manyhome.test.ex address=10.250.104.238
->>> name=manyhome.test.ex address=10.250.104.239
->>> name=manyhome.test.ex address=10.250.104.240
->>> name=manyhome.test.ex address=10.250.104.241
->>> name=manyhome.test.ex address=10.250.104.242
->>> name=manyhome.test.ex address=10.250.104.243
->>> name=manyhome.test.ex address=10.250.104.244
->>> name=manyhome.test.ex address=10.250.104.245
->>> name=manyhome.test.ex address=10.250.104.246
->>> name=manyhome.test.ex address=10.250.104.247
->>> name=manyhome.test.ex address=10.250.104.248
->>> name=manyhome.test.ex address=10.250.104.249
->>> name=manyhome.test.ex address=10.250.104.250
->>> name=manyhome.test.ex address=10.250.104.251
->>> name=manyhome.test.ex address=10.250.104.252
->>> name=manyhome.test.ex address=10.250.104.253
->>> name=manyhome.test.ex address=10.250.104.254
->>> name=manyhome.test.ex address=10.250.104.255
->>> name=manyhome.test.ex address=10.250.105.0
->>> name=manyhome.test.ex address=10.250.105.1
->>> name=manyhome.test.ex address=10.250.105.2
->>> name=manyhome.test.ex address=10.250.105.3
->>> name=manyhome.test.ex address=10.250.105.4
->>> name=manyhome.test.ex address=10.250.105.5
->>> name=manyhome.test.ex address=10.250.105.6
->>> name=manyhome.test.ex address=10.250.105.7
->>> name=manyhome.test.ex address=10.250.105.8
->>> name=manyhome.test.ex address=10.250.105.9
->>> name=manyhome.test.ex address=10.250.105.10
->>> name=manyhome.test.ex address=10.250.105.11
->>> name=manyhome.test.ex address=10.250.105.12
->>> name=manyhome.test.ex address=10.250.105.13
->>> name=manyhome.test.ex address=10.250.105.14
->>> name=manyhome.test.ex address=10.250.105.15
->>> name=manyhome.test.ex address=10.250.105.16
->>> name=manyhome.test.ex address=10.250.105.17
->>> name=manyhome.test.ex address=10.250.105.18
->>> name=manyhome.test.ex address=10.250.105.19
->>> name=manyhome.test.ex address=10.250.105.20
->>> name=manyhome.test.ex address=10.250.105.21
->>> name=manyhome.test.ex address=10.250.105.22
->>> name=manyhome.test.ex address=10.250.105.23
->>> name=manyhome.test.ex address=10.250.105.24
->>> name=manyhome.test.ex address=10.250.105.25
->>> name=manyhome.test.ex address=10.250.105.26
->>> name=manyhome.test.ex address=10.250.105.27
->>> name=manyhome.test.ex address=10.250.105.28
->>> name=manyhome.test.ex address=10.250.105.29
->>> name=manyhome.test.ex address=10.250.105.30
->>> name=manyhome.test.ex address=10.250.105.31
->>> name=manyhome.test.ex address=10.250.105.32
->>> name=manyhome.test.ex address=10.250.105.33
->>> name=manyhome.test.ex address=10.250.105.34
->>> name=manyhome.test.ex address=10.250.105.35
->>> name=manyhome.test.ex address=10.250.105.36
->>> name=manyhome.test.ex address=10.250.105.37
->>> name=manyhome.test.ex address=10.250.105.38
->>> name=manyhome.test.ex address=10.250.105.39
->>> name=manyhome.test.ex address=10.250.105.40
->>> name=manyhome.test.ex address=10.250.105.41
->>> name=manyhome.test.ex address=10.250.105.42
->>> name=manyhome.test.ex address=10.250.105.43
->>> name=manyhome.test.ex address=10.250.105.44
->>> name=manyhome.test.ex address=10.250.105.45
->>> name=manyhome.test.ex address=10.250.105.46
->>> name=manyhome.test.ex address=10.250.105.47
->>> name=manyhome.test.ex address=10.250.105.48
->>> name=manyhome.test.ex address=10.250.105.49
->>> name=manyhome.test.ex address=10.250.105.50
->>> name=manyhome.test.ex address=10.250.105.51
->>> name=manyhome.test.ex address=10.250.105.52
->>> name=manyhome.test.ex address=10.250.105.53
->>> name=manyhome.test.ex address=10.250.105.54
->>> name=manyhome.test.ex address=10.250.105.55
->>> name=manyhome.test.ex address=10.250.105.56
->>> name=manyhome.test.ex address=10.250.105.57
->>> name=manyhome.test.ex address=10.250.105.58
->>> name=manyhome.test.ex address=10.250.105.59
->>> name=manyhome.test.ex address=10.250.105.60
->>> name=manyhome.test.ex address=10.250.105.61
->>> name=manyhome.test.ex address=10.250.105.62
->>> name=manyhome.test.ex address=10.250.105.63
->>> name=manyhome.test.ex address=10.250.105.64
->>> name=manyhome.test.ex address=10.250.105.65
->>> name=manyhome.test.ex address=10.250.105.66
->>> name=manyhome.test.ex address=10.250.105.67
->>> name=manyhome.test.ex address=10.250.105.68
->>> name=manyhome.test.ex address=10.250.105.69
->>> name=manyhome.test.ex address=10.250.105.70
->>> name=manyhome.test.ex address=10.250.105.71
->>> name=manyhome.test.ex address=10.250.105.72
->>> name=manyhome.test.ex address=10.250.105.73
->>> name=manyhome.test.ex address=10.250.105.74
->>> name=manyhome.test.ex address=10.250.105.75
->>> name=manyhome.test.ex address=10.250.105.76
->>> name=manyhome.test.ex address=10.250.105.77
->>> name=manyhome.test.ex address=10.250.105.78
->>> name=manyhome.test.ex address=10.250.105.79
->>> name=manyhome.test.ex address=10.250.105.80
->>> name=manyhome.test.ex address=10.250.105.81
->>> name=manyhome.test.ex address=10.250.105.82
->>> name=manyhome.test.ex address=10.250.105.83
->>> name=manyhome.test.ex address=10.250.105.84
->>> name=manyhome.test.ex address=10.250.105.85
->>> name=manyhome.test.ex address=10.250.105.86
->>> name=manyhome.test.ex address=10.250.105.87
->>> name=manyhome.test.ex address=10.250.105.88
->>> name=manyhome.test.ex address=10.250.105.89
->>> name=manyhome.test.ex address=10.250.105.90
->>> name=manyhome.test.ex address=10.250.105.91
->>> name=manyhome.test.ex address=10.250.105.92
->>> name=manyhome.test.ex address=10.250.105.93
->>> name=manyhome.test.ex address=10.250.105.94
->>> name=manyhome.test.ex address=10.250.105.95
->>> name=manyhome.test.ex address=10.250.105.96
->>> name=manyhome.test.ex address=10.250.105.97
->>> name=manyhome.test.ex address=10.250.105.98
->>> name=manyhome.test.ex address=10.250.105.99
->>> name=manyhome.test.ex address=10.250.105.100
->>> name=manyhome.test.ex address=10.250.105.101
->>> name=manyhome.test.ex address=10.250.105.102
->>> name=manyhome.test.ex address=10.250.105.103
->>> name=manyhome.test.ex address=10.250.105.104
->>> name=manyhome.test.ex address=10.250.105.105
->>> name=manyhome.test.ex address=10.250.105.106
->>> name=manyhome.test.ex address=10.250.105.107
->>> name=manyhome.test.ex address=10.250.105.108
->>> name=manyhome.test.ex address=10.250.105.109
->>> name=manyhome.test.ex address=10.250.105.110
->>> name=manyhome.test.ex address=10.250.105.111
->>> name=manyhome.test.ex address=10.250.105.112
->>> name=manyhome.test.ex address=10.250.105.113
->>> name=manyhome.test.ex address=10.250.105.114
->>> name=manyhome.test.ex address=10.250.105.115
->>> name=manyhome.test.ex address=10.250.105.116
->>> name=manyhome.test.ex address=10.250.105.117
->>> name=manyhome.test.ex address=10.250.105.118
->>> name=manyhome.test.ex address=10.250.105.119
->>> name=manyhome.test.ex address=10.250.105.120
->>> name=manyhome.test.ex address=10.250.105.121
->>> name=manyhome.test.ex address=10.250.105.122
->>> name=manyhome.test.ex address=10.250.105.123
->>> name=manyhome.test.ex address=10.250.105.124
->>> name=manyhome.test.ex address=10.250.105.125
->>> name=manyhome.test.ex address=10.250.105.126
->>> name=manyhome.test.ex address=10.250.105.127
->>> name=manyhome.test.ex address=10.250.105.128
->>> name=manyhome.test.ex address=10.250.105.129
->>> name=manyhome.test.ex address=10.250.105.130
->>> name=manyhome.test.ex address=10.250.105.131
->>> name=manyhome.test.ex address=10.250.105.132
->>> name=manyhome.test.ex address=10.250.105.133
->>> name=manyhome.test.ex address=10.250.105.134
->>> name=manyhome.test.ex address=10.250.105.135
->>> name=manyhome.test.ex address=10.250.105.136
->>> name=manyhome.test.ex address=10.250.105.137
->>> name=manyhome.test.ex address=10.250.105.138
->>> name=manyhome.test.ex address=10.250.105.139
->>> name=manyhome.test.ex address=10.250.105.140
->>> name=manyhome.test.ex address=10.250.105.141
->>> name=manyhome.test.ex address=10.250.105.142
->>> name=manyhome.test.ex address=10.250.105.143
->>> name=manyhome.test.ex address=10.250.105.144
->>> name=manyhome.test.ex address=10.250.105.145
->>> name=manyhome.test.ex address=10.250.105.146
->>> name=manyhome.test.ex address=10.250.105.147
->>> name=manyhome.test.ex address=10.250.105.148
->>> name=manyhome.test.ex address=10.250.105.149
->>> name=manyhome.test.ex address=10.250.105.150
->>> name=manyhome.test.ex address=10.250.105.151
->>> name=manyhome.test.ex address=10.250.105.152
->>> name=manyhome.test.ex address=10.250.105.153
->>> name=manyhome.test.ex address=10.250.105.154
->>> name=manyhome.test.ex address=10.250.105.155
->>> name=manyhome.test.ex address=10.250.105.156
->>> name=manyhome.test.ex address=10.250.105.157
->>> name=manyhome.test.ex address=10.250.105.158
->>> name=manyhome.test.ex address=10.250.105.159
->>> name=manyhome.test.ex address=10.250.105.160
->>> name=manyhome.test.ex address=10.250.105.161
->>> name=manyhome.test.ex address=10.250.105.162
->>> name=manyhome.test.ex address=10.250.105.163
->>> name=manyhome.test.ex address=10.250.105.164
->>> name=manyhome.test.ex address=10.250.105.165
->>> name=manyhome.test.ex address=10.250.105.166
->>> name=manyhome.test.ex address=10.250.105.167
->>> name=manyhome.test.ex address=10.250.105.168
->>> name=manyhome.test.ex address=10.250.105.169
->>> name=manyhome.test.ex address=10.250.105.170
->>> name=manyhome.test.ex address=10.250.105.171
->>> name=manyhome.test.ex address=10.250.105.172
->>> name=manyhome.test.ex address=10.250.105.173
->>> name=manyhome.test.ex address=10.250.105.174
->>> name=manyhome.test.ex address=10.250.105.175
->>> name=manyhome.test.ex address=10.250.105.176
->>> name=manyhome.test.ex address=10.250.105.177
->>> name=manyhome.test.ex address=10.250.105.178
->>> name=manyhome.test.ex address=10.250.105.179
->>> name=manyhome.test.ex address=10.250.105.180
->>> name=manyhome.test.ex address=10.250.105.181
->>> name=manyhome.test.ex address=10.250.105.182
->>> name=manyhome.test.ex address=10.250.105.183
->>> name=manyhome.test.ex address=10.250.105.184
->>> name=manyhome.test.ex address=10.250.105.185
->>> name=manyhome.test.ex address=10.250.105.186
->>> name=manyhome.test.ex address=10.250.105.187
->>> name=manyhome.test.ex address=10.250.105.188
->>> name=manyhome.test.ex address=10.250.105.189
->>> name=manyhome.test.ex address=10.250.105.190
->>> name=manyhome.test.ex address=10.250.105.191
->>> name=manyhome.test.ex address=10.250.105.192
->>> name=manyhome.test.ex address=10.250.105.193
->>> name=manyhome.test.ex address=10.250.105.194
->>> name=manyhome.test.ex address=10.250.105.195
->>> name=manyhome.test.ex address=10.250.105.196
->>> name=manyhome.test.ex address=10.250.105.197
->>> name=manyhome.test.ex address=10.250.105.198
->>> name=manyhome.test.ex address=10.250.105.199
->>> name=manyhome.test.ex address=10.250.105.200
->>> name=manyhome.test.ex address=10.250.105.201
->>> name=manyhome.test.ex address=10.250.105.202
->>> name=manyhome.test.ex address=10.250.105.203
->>> name=manyhome.test.ex address=10.250.105.204
->>> name=manyhome.test.ex address=10.250.105.205
->>> name=manyhome.test.ex address=10.250.105.206
->>> name=manyhome.test.ex address=10.250.105.207
->>> name=manyhome.test.ex address=10.250.105.208
->>> name=manyhome.test.ex address=10.250.105.209
->>> name=manyhome.test.ex address=10.250.105.210
->>> name=manyhome.test.ex address=10.250.105.211
->>> name=manyhome.test.ex address=10.250.105.212
->>> name=manyhome.test.ex address=10.250.105.213
->>> name=manyhome.test.ex address=10.250.105.214
->>> name=manyhome.test.ex address=10.250.105.215
->>> name=manyhome.test.ex address=10.250.105.216
->>> name=manyhome.test.ex address=10.250.105.217
->>> name=manyhome.test.ex address=10.250.105.218
->>> name=manyhome.test.ex address=10.250.105.219
->>> name=manyhome.test.ex address=10.250.105.220
->>> name=manyhome.test.ex address=10.250.105.221
->>> name=manyhome.test.ex address=10.250.105.222
->>> name=manyhome.test.ex address=10.250.105.223
->>> name=manyhome.test.ex address=10.250.105.224
->>> name=manyhome.test.ex address=10.250.105.225
->>> name=manyhome.test.ex address=10.250.105.226
->>> name=manyhome.test.ex address=10.250.105.227
->>> name=manyhome.test.ex address=10.250.105.228
->>> name=manyhome.test.ex address=10.250.105.229
->>> name=manyhome.test.ex address=10.250.105.230
->>> name=manyhome.test.ex address=10.250.105.231
->>> name=manyhome.test.ex address=10.250.105.232
->>> name=manyhome.test.ex address=10.250.105.233
->>> name=manyhome.test.ex address=10.250.105.234
->>> name=manyhome.test.ex address=10.250.105.235
->>> name=manyhome.test.ex address=10.250.105.236
->>> name=manyhome.test.ex address=10.250.105.237
->>> name=manyhome.test.ex address=10.250.105.238
->>> name=manyhome.test.ex address=10.250.105.239
->>> name=manyhome.test.ex address=10.250.105.240
->>> name=manyhome.test.ex address=10.250.105.241
->>> name=manyhome.test.ex address=10.250.105.242
->>> name=manyhome.test.ex address=10.250.105.243
->>> name=manyhome.test.ex address=10.250.105.244
->>> name=manyhome.test.ex address=10.250.105.245
->>> name=manyhome.test.ex address=10.250.105.246
->>> name=manyhome.test.ex address=10.250.105.247
->>> name=manyhome.test.ex address=10.250.105.248
->>> name=manyhome.test.ex address=10.250.105.249
->>> name=manyhome.test.ex address=10.250.105.250
->>> name=manyhome.test.ex address=10.250.105.251
->>> name=manyhome.test.ex address=10.250.105.252
->>> name=manyhome.test.ex address=10.250.105.253
->>> name=manyhome.test.ex address=10.250.105.254
->>> name=manyhome.test.ex address=10.250.105.255
->>> name=manyhome.test.ex address=10.250.106.0
->>> name=manyhome.test.ex address=10.250.106.1
->>> name=manyhome.test.ex address=10.250.106.2
->>> name=manyhome.test.ex address=10.250.106.3
->>> name=manyhome.test.ex address=10.250.106.4
->>> name=manyhome.test.ex address=10.250.106.5
->>> name=manyhome.test.ex address=10.250.106.6
->>> name=manyhome.test.ex address=10.250.106.7
->>> name=manyhome.test.ex address=10.250.106.8
->>> name=manyhome.test.ex address=10.250.106.9
->>> name=manyhome.test.ex address=10.250.106.10
->>> name=manyhome.test.ex address=10.250.106.11
->>> name=manyhome.test.ex address=10.250.106.12
->>> name=manyhome.test.ex address=10.250.106.13
->>> name=manyhome.test.ex address=10.250.106.14
->>> name=manyhome.test.ex address=10.250.106.15
->>> name=manyhome.test.ex address=10.250.106.16
->>> name=manyhome.test.ex address=10.250.106.17
->>> name=manyhome.test.ex address=10.250.106.18
->>> name=manyhome.test.ex address=10.250.106.19
->>> name=manyhome.test.ex address=10.250.106.20
->>> name=manyhome.test.ex address=10.250.106.21
->>> name=manyhome.test.ex address=10.250.106.22
->>> name=manyhome.test.ex address=10.250.106.23
->>> name=manyhome.test.ex address=10.250.106.24
->>> name=manyhome.test.ex address=10.250.106.25
->>> name=manyhome.test.ex address=10.250.106.26
->>> name=manyhome.test.ex address=10.250.106.27
->>> name=manyhome.test.ex address=10.250.106.28
->>> name=manyhome.test.ex address=10.250.106.29
->>> name=manyhome.test.ex address=10.250.106.30
->>> name=manyhome.test.ex address=10.250.106.31
->>> name=manyhome.test.ex address=10.250.106.32
->>> name=manyhome.test.ex address=10.250.106.33
->>> name=manyhome.test.ex address=10.250.106.34
->>> name=manyhome.test.ex address=10.250.106.35
->>> name=manyhome.test.ex address=10.250.106.36
->>> name=manyhome.test.ex address=10.250.106.37
->>> name=manyhome.test.ex address=10.250.106.38
->>> name=manyhome.test.ex address=10.250.106.39
->>> name=manyhome.test.ex address=10.250.106.40
->>> name=manyhome.test.ex address=10.250.106.41
->>> name=manyhome.test.ex address=10.250.106.42
->>> name=manyhome.test.ex address=10.250.106.43
->>> name=manyhome.test.ex address=10.250.106.44
->>> name=manyhome.test.ex address=10.250.106.45
->>> name=manyhome.test.ex address=10.250.106.46
->>> name=manyhome.test.ex address=10.250.106.47
->>> name=manyhome.test.ex address=10.250.106.48
->>> name=manyhome.test.ex address=10.250.106.49
->>> name=manyhome.test.ex address=10.250.106.50
->>> name=manyhome.test.ex address=10.250.106.51
->>> name=manyhome.test.ex address=10.250.106.52
->>> name=manyhome.test.ex address=10.250.106.53
->>> name=manyhome.test.ex address=10.250.106.54
->>> name=manyhome.test.ex address=10.250.106.55
->>> name=manyhome.test.ex address=10.250.106.56
->>> name=manyhome.test.ex address=10.250.106.57
->>> name=manyhome.test.ex address=10.250.106.58
->>> name=manyhome.test.ex address=10.250.106.59
->>> name=manyhome.test.ex address=10.250.106.60
->>> name=manyhome.test.ex address=10.250.106.61
->>> name=manyhome.test.ex address=10.250.106.62
->>> name=manyhome.test.ex address=10.250.106.63
->>> name=manyhome.test.ex address=10.250.106.64
->>> name=manyhome.test.ex address=10.250.106.65
->>> name=manyhome.test.ex address=10.250.106.66
->>> name=manyhome.test.ex address=10.250.106.67
->>> name=manyhome.test.ex address=10.250.106.68
->>> name=manyhome.test.ex address=10.250.106.69
->>> name=manyhome.test.ex address=10.250.106.70
->>> name=manyhome.test.ex address=10.250.106.71
->>> name=manyhome.test.ex address=10.250.106.72
->>> name=manyhome.test.ex address=10.250.106.73
->>> name=manyhome.test.ex address=10.250.106.74
->>> name=manyhome.test.ex address=10.250.106.75
->>> name=manyhome.test.ex address=10.250.106.76
->>> name=manyhome.test.ex address=10.250.106.77
->>> name=manyhome.test.ex address=10.250.106.78
->>> name=manyhome.test.ex address=10.250.106.79
->>> name=manyhome.test.ex address=10.250.106.80
->>> name=manyhome.test.ex address=10.250.106.81
->>> name=manyhome.test.ex address=10.250.106.82
->>> name=manyhome.test.ex address=10.250.106.83
->>> name=manyhome.test.ex address=10.250.106.84
->>> name=manyhome.test.ex address=10.250.106.85
->>> name=manyhome.test.ex address=10.250.106.86
->>> name=manyhome.test.ex address=10.250.106.87
->>> name=manyhome.test.ex address=10.250.106.88
->>> name=manyhome.test.ex address=10.250.106.89
->>> name=manyhome.test.ex address=10.250.106.90
->>> name=manyhome.test.ex address=10.250.106.91
->>> name=manyhome.test.ex address=10.250.106.92
->>> name=manyhome.test.ex address=10.250.106.93
->>> name=manyhome.test.ex address=10.250.106.94
->>> name=manyhome.test.ex address=10.250.106.95
->>> name=manyhome.test.ex address=10.250.106.96
->>> name=manyhome.test.ex address=10.250.106.97
->>> name=manyhome.test.ex address=10.250.106.98
->>> name=manyhome.test.ex address=10.250.106.99
->>> name=manyhome.test.ex address=10.250.106.100
->>> name=manyhome.test.ex address=10.250.106.101
->>> name=manyhome.test.ex address=10.250.106.102
->>> name=manyhome.test.ex address=10.250.106.103
->>> name=manyhome.test.ex address=10.250.106.104
->>> name=manyhome.test.ex address=10.250.106.105
->>> name=manyhome.test.ex address=10.250.106.106
->>> name=manyhome.test.ex address=10.250.106.107
->>> name=manyhome.test.ex address=10.250.106.108
->>> name=manyhome.test.ex address=10.250.106.109
->>> name=manyhome.test.ex address=10.250.106.110
->>> name=manyhome.test.ex address=10.250.106.111
->>> name=manyhome.test.ex address=10.250.106.112
->>> name=manyhome.test.ex address=10.250.106.113
->>> name=manyhome.test.ex address=10.250.106.114
->>> name=manyhome.test.ex address=10.250.106.115
->>> name=manyhome.test.ex address=10.250.106.116
->>> name=manyhome.test.ex address=10.250.106.117
->>> name=manyhome.test.ex address=10.250.106.118
->>> name=manyhome.test.ex address=10.250.106.119
->>> name=manyhome.test.ex address=10.250.106.120
->>> name=manyhome.test.ex address=10.250.106.121
->>> name=manyhome.test.ex address=10.250.106.122
->>> name=manyhome.test.ex address=10.250.106.123
->>> name=manyhome.test.ex address=10.250.106.124
->>> name=manyhome.test.ex address=10.250.106.125
->>> name=manyhome.test.ex address=10.250.106.126
->>> name=manyhome.test.ex address=10.250.106.127
->>> name=manyhome.test.ex address=10.250.106.128
->>> name=manyhome.test.ex address=10.250.106.129
->>> name=manyhome.test.ex address=10.250.106.130
->>> name=manyhome.test.ex address=10.250.106.131
->>> name=manyhome.test.ex address=10.250.106.132
->>> name=manyhome.test.ex address=10.250.106.133
->>> name=manyhome.test.ex address=10.250.106.134
->>> name=manyhome.test.ex address=10.250.106.135
->>> name=manyhome.test.ex address=10.250.106.136
->>> name=manyhome.test.ex address=10.250.106.137
->>> name=manyhome.test.ex address=10.250.106.138
->>> name=manyhome.test.ex address=10.250.106.139
->>> name=manyhome.test.ex address=10.250.106.140
->>> name=manyhome.test.ex address=10.250.106.141
->>> name=manyhome.test.ex address=10.250.106.142
->>> name=manyhome.test.ex address=10.250.106.143
->>> name=manyhome.test.ex address=10.250.106.144
->>> name=manyhome.test.ex address=10.250.106.145
->>> name=manyhome.test.ex address=10.250.106.146
->>> name=manyhome.test.ex address=10.250.106.147
->>> name=manyhome.test.ex address=10.250.106.148
->>> name=manyhome.test.ex address=10.250.106.149
->>> name=manyhome.test.ex address=10.250.106.150
->>> name=manyhome.test.ex address=10.250.106.151
->>> name=manyhome.test.ex address=10.250.106.152
->>> name=manyhome.test.ex address=10.250.106.153
->>> name=manyhome.test.ex address=10.250.106.154
->>> name=manyhome.test.ex address=10.250.106.155
->>> name=manyhome.test.ex address=10.250.106.156
->>> name=manyhome.test.ex address=10.250.106.157
->>> name=manyhome.test.ex address=10.250.106.158
->>> name=manyhome.test.ex address=10.250.106.159
->>> name=manyhome.test.ex address=10.250.106.160
->>> name=manyhome.test.ex address=10.250.106.161
->>> name=manyhome.test.ex address=10.250.106.162
->>> name=manyhome.test.ex address=10.250.106.163
->>> name=manyhome.test.ex address=10.250.106.164
->>> name=manyhome.test.ex address=10.250.106.165
->>> name=manyhome.test.ex address=10.250.106.166
->>> name=manyhome.test.ex address=10.250.106.167
->>> name=manyhome.test.ex address=10.250.106.168
->>> name=manyhome.test.ex address=10.250.106.169
->>> name=manyhome.test.ex address=10.250.106.170
->>> name=manyhome.test.ex address=10.250.106.171
->>> name=manyhome.test.ex address=10.250.106.172
->>> name=manyhome.test.ex address=10.250.106.173
->>> name=manyhome.test.ex address=10.250.106.174
->>> name=manyhome.test.ex address=10.250.106.175
->>> name=manyhome.test.ex address=10.250.106.176
->>> name=manyhome.test.ex address=10.250.106.177
->>> name=manyhome.test.ex address=10.250.106.178
->>> name=manyhome.test.ex address=10.250.106.179
->>> name=manyhome.test.ex address=10.250.106.180
->>> name=manyhome.test.ex address=10.250.106.181
->>> name=manyhome.test.ex address=10.250.106.182
->>> name=manyhome.test.ex address=10.250.106.183
->>> name=manyhome.test.ex address=10.250.106.184
->>> name=manyhome.test.ex address=10.250.106.185
->>> name=manyhome.test.ex address=10.250.106.186
->>> name=manyhome.test.ex address=10.250.106.187
->>> name=manyhome.test.ex address=10.250.106.188
->>> name=manyhome.test.ex address=10.250.106.189
->>> name=manyhome.test.ex address=10.250.106.190
->>> name=manyhome.test.ex address=10.250.106.191
->>> name=manyhome.test.ex address=10.250.106.192
->>> name=manyhome.test.ex address=10.250.106.193
->>> name=manyhome.test.ex address=10.250.106.194
->>> name=manyhome.test.ex address=10.250.106.195
->>> name=manyhome.test.ex address=10.250.106.196
->>> name=manyhome.test.ex address=10.250.106.197
->>> name=manyhome.test.ex address=10.250.106.198
->>> name=manyhome.test.ex address=10.250.106.199
->>> name=manyhome.test.ex address=10.250.106.200
->>> name=manyhome.test.ex address=10.250.106.201
->>> name=manyhome.test.ex address=10.250.106.202
->>> name=manyhome.test.ex address=10.250.106.203
->>> name=manyhome.test.ex address=10.250.106.204
->>> name=manyhome.test.ex address=10.250.106.205
->>> name=manyhome.test.ex address=10.250.106.206
->>> name=manyhome.test.ex address=10.250.106.207
->>> name=manyhome.test.ex address=10.250.106.208
->>> name=manyhome.test.ex address=10.250.106.209
->>> name=manyhome.test.ex address=10.250.106.210
->>> name=manyhome.test.ex address=10.250.106.211
->>> name=manyhome.test.ex address=10.250.106.212
->>> name=manyhome.test.ex address=10.250.106.213
->>> name=manyhome.test.ex address=10.250.106.214
->>> name=manyhome.test.ex address=10.250.106.215
->>> name=manyhome.test.ex address=10.250.106.216
->>> name=manyhome.test.ex address=10.250.106.217
->>> name=manyhome.test.ex address=10.250.106.218
->>> name=manyhome.test.ex address=10.250.106.219
->>> name=manyhome.test.ex address=10.250.106.220
->>> name=manyhome.test.ex address=10.250.106.221
->>> name=manyhome.test.ex address=10.250.106.222
->>> name=manyhome.test.ex address=10.250.106.223
->>> name=manyhome.test.ex address=10.250.106.224
->>> name=manyhome.test.ex address=10.250.106.225
->>> name=manyhome.test.ex address=10.250.106.226
->>> name=manyhome.test.ex address=10.250.106.227
->>> name=manyhome.test.ex address=10.250.106.228
->>> name=manyhome.test.ex address=10.250.106.229
->>> name=manyhome.test.ex address=10.250.106.230
->>> name=manyhome.test.ex address=10.250.106.231
->>> name=manyhome.test.ex address=10.250.106.232
->>> name=manyhome.test.ex address=10.250.106.233
->>> name=manyhome.test.ex address=10.250.106.234
->>> name=manyhome.test.ex address=10.250.106.235
->>> name=manyhome.test.ex address=10.250.106.236
->>> name=manyhome.test.ex address=10.250.106.237
->>> name=manyhome.test.ex address=10.250.106.238
->>> name=manyhome.test.ex address=10.250.106.239
->>> name=manyhome.test.ex address=10.250.106.240
->>> name=manyhome.test.ex address=10.250.106.241
->>> name=manyhome.test.ex address=10.250.106.242
->>> name=manyhome.test.ex address=10.250.106.243
->>> name=manyhome.test.ex address=10.250.106.244
->>> name=manyhome.test.ex address=10.250.106.245
->>> name=manyhome.test.ex address=10.250.106.246
->>> name=manyhome.test.ex address=10.250.106.247
->>> name=manyhome.test.ex address=10.250.106.248
->>> name=manyhome.test.ex address=10.250.106.249
->>> name=manyhome.test.ex address=10.250.106.250
->>> name=manyhome.test.ex address=10.250.106.251
->>> name=manyhome.test.ex address=10.250.106.252
->>> name=manyhome.test.ex address=10.250.106.253
->>> name=manyhome.test.ex address=10.250.106.254
->>> name=manyhome.test.ex address=10.250.106.255
->>> name=manyhome.test.ex address=10.250.107.0
->>> name=manyhome.test.ex address=10.250.107.1
->>> name=manyhome.test.ex address=10.250.107.2
->>> name=manyhome.test.ex address=10.250.107.3
->>> name=manyhome.test.ex address=10.250.107.4
->>> name=manyhome.test.ex address=10.250.107.5
->>> name=manyhome.test.ex address=10.250.107.6
->>> name=manyhome.test.ex address=10.250.107.7
->>> name=manyhome.test.ex address=10.250.107.8
->>> name=manyhome.test.ex address=10.250.107.9
->>> name=manyhome.test.ex address=10.250.107.10
->>> name=manyhome.test.ex address=10.250.107.11
->>> name=manyhome.test.ex address=10.250.107.12
->>> name=manyhome.test.ex address=10.250.107.13
->>> name=manyhome.test.ex address=10.250.107.14
->>> name=manyhome.test.ex address=10.250.107.15
->>> name=manyhome.test.ex address=10.250.107.16
->>> name=manyhome.test.ex address=10.250.107.17
->>> name=manyhome.test.ex address=10.250.107.18
->>> name=manyhome.test.ex address=10.250.107.19
->>> name=manyhome.test.ex address=10.250.107.20
->>> name=manyhome.test.ex address=10.250.107.21
->>> name=manyhome.test.ex address=10.250.107.22
->>> name=manyhome.test.ex address=10.250.107.23
->>> name=manyhome.test.ex address=10.250.107.24
->>> name=manyhome.test.ex address=10.250.107.25
->>> name=manyhome.test.ex address=10.250.107.26
->>> name=manyhome.test.ex address=10.250.107.27
->>> name=manyhome.test.ex address=10.250.107.28
->>> name=manyhome.test.ex address=10.250.107.29
->>> name=manyhome.test.ex address=10.250.107.30
->>> name=manyhome.test.ex address=10.250.107.31
->>> name=manyhome.test.ex address=10.250.107.32
->>> name=manyhome.test.ex address=10.250.107.33
->>> name=manyhome.test.ex address=10.250.107.34
->>> name=manyhome.test.ex address=10.250.107.35
->>> name=manyhome.test.ex address=10.250.107.36
->>> name=manyhome.test.ex address=10.250.107.37
->>> name=manyhome.test.ex address=10.250.107.38
->>> name=manyhome.test.ex address=10.250.107.39
->>> name=manyhome.test.ex address=10.250.107.40
->>> name=manyhome.test.ex address=10.250.107.41
->>> name=manyhome.test.ex address=10.250.107.42
->>> name=manyhome.test.ex address=10.250.107.43
->>> name=manyhome.test.ex address=10.250.107.44
->>> name=manyhome.test.ex address=10.250.107.45
->>> name=manyhome.test.ex address=10.250.107.46
->>> name=manyhome.test.ex address=10.250.107.47
->>> name=manyhome.test.ex address=10.250.107.48
->>> name=manyhome.test.ex address=10.250.107.49
->>> name=manyhome.test.ex address=10.250.107.50
->>> name=manyhome.test.ex address=10.250.107.51
->>> name=manyhome.test.ex address=10.250.107.52
->>> name=manyhome.test.ex address=10.250.107.53
->>> name=manyhome.test.ex address=10.250.107.54
->>> name=manyhome.test.ex address=10.250.107.55
->>> name=manyhome.test.ex address=10.250.107.56
->>> name=manyhome.test.ex address=10.250.107.57
->>> name=manyhome.test.ex address=10.250.107.58
->>> name=manyhome.test.ex address=10.250.107.59
->>> name=manyhome.test.ex address=10.250.107.60
->>> name=manyhome.test.ex address=10.250.107.61
->>> name=manyhome.test.ex address=10.250.107.62
->>> name=manyhome.test.ex address=10.250.107.63
->>> name=manyhome.test.ex address=10.250.107.64
->>> name=manyhome.test.ex address=10.250.107.65
->>> name=manyhome.test.ex address=10.250.107.66
->>> name=manyhome.test.ex address=10.250.107.67
->>> name=manyhome.test.ex address=10.250.107.68
->>> name=manyhome.test.ex address=10.250.107.69
->>> name=manyhome.test.ex address=10.250.107.70
->>> name=manyhome.test.ex address=10.250.107.71
->>> name=manyhome.test.ex address=10.250.107.72
->>> name=manyhome.test.ex address=10.250.107.73
->>> name=manyhome.test.ex address=10.250.107.74
->>> name=manyhome.test.ex address=10.250.107.75
->>> name=manyhome.test.ex address=10.250.107.76
->>> name=manyhome.test.ex address=10.250.107.77
->>> name=manyhome.test.ex address=10.250.107.78
->>> name=manyhome.test.ex address=10.250.107.79
->>> name=manyhome.test.ex address=10.250.107.80
->>> name=manyhome.test.ex address=10.250.107.81
->>> name=manyhome.test.ex address=10.250.107.82
->>> name=manyhome.test.ex address=10.250.107.83
->>> name=manyhome.test.ex address=10.250.107.84
->>> name=manyhome.test.ex address=10.250.107.85
->>> name=manyhome.test.ex address=10.250.107.86
->>> name=manyhome.test.ex address=10.250.107.87
->>> name=manyhome.test.ex address=10.250.107.88
->>> name=manyhome.test.ex address=10.250.107.89
->>> name=manyhome.test.ex address=10.250.107.90
->>> name=manyhome.test.ex address=10.250.107.91
->>> name=manyhome.test.ex address=10.250.107.92
->>> name=manyhome.test.ex address=10.250.107.93
->>> name=manyhome.test.ex address=10.250.107.94
->>> name=manyhome.test.ex address=10.250.107.95
->>> name=manyhome.test.ex address=10.250.107.96
->>> name=manyhome.test.ex address=10.250.107.97
->>> name=manyhome.test.ex address=10.250.107.98
->>> name=manyhome.test.ex address=10.250.107.99
->>> name=manyhome.test.ex address=10.250.107.100
->>> name=manyhome.test.ex address=10.250.107.101
->>> name=manyhome.test.ex address=10.250.107.102
->>> name=manyhome.test.ex address=10.250.107.103
->>> name=manyhome.test.ex address=10.250.107.104
->>> name=manyhome.test.ex address=10.250.107.105
->>> name=manyhome.test.ex address=10.250.107.106
->>> name=manyhome.test.ex address=10.250.107.107
->>> name=manyhome.test.ex address=10.250.107.108
->>> name=manyhome.test.ex address=10.250.107.109
->>> name=manyhome.test.ex address=10.250.107.110
->>> name=manyhome.test.ex address=10.250.107.111
->>> name=manyhome.test.ex address=10.250.107.112
->>> name=manyhome.test.ex address=10.250.107.113
->>> name=manyhome.test.ex address=10.250.107.114
->>> name=manyhome.test.ex address=10.250.107.115
->>> name=manyhome.test.ex address=10.250.107.116
->>> name=manyhome.test.ex address=10.250.107.117
->>> name=manyhome.test.ex address=10.250.107.118
->>> name=manyhome.test.ex address=10.250.107.119
->>> name=manyhome.test.ex address=10.250.107.120
->>> name=manyhome.test.ex address=10.250.107.121
->>> name=manyhome.test.ex address=10.250.107.122
->>> name=manyhome.test.ex address=10.250.107.123
->>> name=manyhome.test.ex address=10.250.107.124
->>> name=manyhome.test.ex address=10.250.107.125
->>> name=manyhome.test.ex address=10.250.107.126
->>> name=manyhome.test.ex address=10.250.107.127
->>> name=manyhome.test.ex address=10.250.107.128
->>> name=manyhome.test.ex address=10.250.107.129
->>> name=manyhome.test.ex address=10.250.107.130
->>> name=manyhome.test.ex address=10.250.107.131
->>> name=manyhome.test.ex address=10.250.107.132
->>> name=manyhome.test.ex address=10.250.107.133
->>> name=manyhome.test.ex address=10.250.107.134
->>> name=manyhome.test.ex address=10.250.107.135
->>> name=manyhome.test.ex address=10.250.107.136
->>> name=manyhome.test.ex address=10.250.107.137
->>> name=manyhome.test.ex address=10.250.107.138
->>> name=manyhome.test.ex address=10.250.107.139
->>> name=manyhome.test.ex address=10.250.107.140
->>> name=manyhome.test.ex address=10.250.107.141
->>> name=manyhome.test.ex address=10.250.107.142
->>> name=manyhome.test.ex address=10.250.107.143
->>> name=manyhome.test.ex address=10.250.107.144
->>> name=manyhome.test.ex address=10.250.107.145
->>> name=manyhome.test.ex address=10.250.107.146
->>> name=manyhome.test.ex address=10.250.107.147
->>> name=manyhome.test.ex address=10.250.107.148
->>> name=manyhome.test.ex address=10.250.107.149
->>> name=manyhome.test.ex address=10.250.107.150
->>> name=manyhome.test.ex address=10.250.107.151
->>> name=manyhome.test.ex address=10.250.107.152
->>> name=manyhome.test.ex address=10.250.107.153
->>> name=manyhome.test.ex address=10.250.107.154
->>> name=manyhome.test.ex address=10.250.107.155
->>> name=manyhome.test.ex address=10.250.107.156
->>> name=manyhome.test.ex address=10.250.107.157
->>> name=manyhome.test.ex address=10.250.107.158
->>> name=manyhome.test.ex address=10.250.107.159
->>> name=manyhome.test.ex address=10.250.107.160
->>> name=manyhome.test.ex address=10.250.107.161
->>> name=manyhome.test.ex address=10.250.107.162
->>> name=manyhome.test.ex address=10.250.107.163
->>> name=manyhome.test.ex address=10.250.107.164
->>> name=manyhome.test.ex address=10.250.107.165
->>> name=manyhome.test.ex address=10.250.107.166
->>> name=manyhome.test.ex address=10.250.107.167
->>> name=manyhome.test.ex address=10.250.107.168
->>> name=manyhome.test.ex address=10.250.107.169
->>> name=manyhome.test.ex address=10.250.107.170
->>> name=manyhome.test.ex address=10.250.107.171
->>> name=manyhome.test.ex address=10.250.107.172
->>> name=manyhome.test.ex address=10.250.107.173
->>> name=manyhome.test.ex address=10.250.107.174
->>> name=manyhome.test.ex address=10.250.107.175
->>> name=manyhome.test.ex address=10.250.107.176
->>> name=manyhome.test.ex address=10.250.107.177
->>> name=manyhome.test.ex address=10.250.107.178
->>> name=manyhome.test.ex address=10.250.107.179
->>> name=manyhome.test.ex address=10.250.107.180
->>> name=manyhome.test.ex address=10.250.107.181
->>> name=manyhome.test.ex address=10.250.107.182
->>> name=manyhome.test.ex address=10.250.107.183
->>> name=manyhome.test.ex address=10.250.107.184
->>> name=manyhome.test.ex address=10.250.107.185
->>> name=manyhome.test.ex address=10.250.107.186
->>> name=manyhome.test.ex address=10.250.107.187
->>> name=manyhome.test.ex address=10.250.107.188
->>> name=manyhome.test.ex address=10.250.107.189
->>> name=manyhome.test.ex address=10.250.107.190
->>> name=manyhome.test.ex address=10.250.107.191
->>> name=manyhome.test.ex address=10.250.107.192
->>> name=manyhome.test.ex address=10.250.107.193
->>> name=manyhome.test.ex address=10.250.107.194
->>> name=manyhome.test.ex address=10.250.107.195
->>> name=manyhome.test.ex address=10.250.107.196
->>> name=manyhome.test.ex address=10.250.107.197
->>> name=manyhome.test.ex address=10.250.107.198
->>> name=manyhome.test.ex address=10.250.107.199
->>> name=manyhome.test.ex address=10.250.107.200
->>> name=manyhome.test.ex address=10.250.107.201
->>> name=manyhome.test.ex address=10.250.107.202
->>> name=manyhome.test.ex address=10.250.107.203
->>> name=manyhome.test.ex address=10.250.107.204
->>> name=manyhome.test.ex address=10.250.107.205
->>> name=manyhome.test.ex address=10.250.107.206
->>> name=manyhome.test.ex address=10.250.107.207
->>> name=manyhome.test.ex address=10.250.107.208
->>> name=manyhome.test.ex address=10.250.107.209
->>> name=manyhome.test.ex address=10.250.107.210
->>> name=manyhome.test.ex address=10.250.107.211
->>> name=manyhome.test.ex address=10.250.107.212
->>> name=manyhome.test.ex address=10.250.107.213
->>> name=manyhome.test.ex address=10.250.107.214
->>> name=manyhome.test.ex address=10.250.107.215
->>> name=manyhome.test.ex address=10.250.107.216
->>> name=manyhome.test.ex address=10.250.107.217
->>> name=manyhome.test.ex address=10.250.107.218
->>> name=manyhome.test.ex address=10.250.107.219
->>> name=manyhome.test.ex address=10.250.107.220
->>> name=manyhome.test.ex address=10.250.107.221
->>> name=manyhome.test.ex address=10.250.107.222
->>> name=manyhome.test.ex address=10.250.107.223
->>> name=manyhome.test.ex address=10.250.107.224
->>> name=manyhome.test.ex address=10.250.107.225
->>> name=manyhome.test.ex address=10.250.107.226
->>> name=manyhome.test.ex address=10.250.107.227
->>> name=manyhome.test.ex address=10.250.107.228
->>> name=manyhome.test.ex address=10.250.107.229
->>> name=manyhome.test.ex address=10.250.107.230
->>> name=manyhome.test.ex address=10.250.107.231
->>> name=manyhome.test.ex address=10.250.107.232
->>> name=manyhome.test.ex address=10.250.107.233
->>> name=manyhome.test.ex address=10.250.107.234
->>> name=manyhome.test.ex address=10.250.107.235
->>> name=manyhome.test.ex address=10.250.107.236
->>> name=manyhome.test.ex address=10.250.107.237
->>> name=manyhome.test.ex address=10.250.107.238
->>> name=manyhome.test.ex address=10.250.107.239
->>> name=manyhome.test.ex address=10.250.107.240
->>> name=manyhome.test.ex address=10.250.107.241
->>> name=manyhome.test.ex address=10.250.107.242
->>> name=manyhome.test.ex address=10.250.107.243
->>> name=manyhome.test.ex address=10.250.107.244
->>> name=manyhome.test.ex address=10.250.107.245
->>> name=manyhome.test.ex address=10.250.107.246
->>> name=manyhome.test.ex address=10.250.107.247
->>> name=manyhome.test.ex address=10.250.107.248
->>> name=manyhome.test.ex address=10.250.107.249
->>> name=manyhome.test.ex address=10.250.107.250
->>> name=manyhome.test.ex address=10.250.107.251
->>> name=manyhome.test.ex address=10.250.107.252
->>> name=manyhome.test.ex address=10.250.107.253
->>> name=manyhome.test.ex address=10.250.107.254
->>> name=manyhome.test.ex address=10.250.107.255
->>> name=manyhome.test.ex address=10.250.108.0
->>> name=manyhome.test.ex address=10.250.108.1
->>> name=manyhome.test.ex address=10.250.108.2
->>> name=manyhome.test.ex address=10.250.108.3
->>> name=manyhome.test.ex address=10.250.108.4
->>> name=manyhome.test.ex address=10.250.108.5
->>> name=manyhome.test.ex address=10.250.108.6
->>> name=manyhome.test.ex address=10.250.108.7
->>> name=manyhome.test.ex address=10.250.108.8
->>> name=manyhome.test.ex address=10.250.108.9
->>> name=manyhome.test.ex address=10.250.108.10
->>> name=manyhome.test.ex address=10.250.108.11
->>> name=manyhome.test.ex address=10.250.108.12
->>> name=manyhome.test.ex address=10.250.108.13
->>> name=manyhome.test.ex address=10.250.108.14
->>> name=manyhome.test.ex address=10.250.108.15
->>> name=manyhome.test.ex address=10.250.108.16
->>> name=manyhome.test.ex address=10.250.108.17
->>> name=manyhome.test.ex address=10.250.108.18
->>> name=manyhome.test.ex address=10.250.108.19
->>> name=manyhome.test.ex address=10.250.108.20
->>> name=manyhome.test.ex address=10.250.108.21
->>> name=manyhome.test.ex address=10.250.108.22
->>> name=manyhome.test.ex address=10.250.108.23
->>> name=manyhome.test.ex address=10.250.108.24
->>> name=manyhome.test.ex address=10.250.108.25
->>> name=manyhome.test.ex address=10.250.108.26
->>> name=manyhome.test.ex address=10.250.108.27
->>> name=manyhome.test.ex address=10.250.108.28
->>> name=manyhome.test.ex address=10.250.108.29
->>> name=manyhome.test.ex address=10.250.108.30
->>> name=manyhome.test.ex address=10.250.108.31
->>> name=manyhome.test.ex address=10.250.108.32
->>> name=manyhome.test.ex address=10.250.108.33
->>> name=manyhome.test.ex address=10.250.108.34
->>> name=manyhome.test.ex address=10.250.108.35
->>> name=manyhome.test.ex address=10.250.108.36
->>> name=manyhome.test.ex address=10.250.108.37
->>> name=manyhome.test.ex address=10.250.108.38
->>> name=manyhome.test.ex address=10.250.108.39
->>> name=manyhome.test.ex address=10.250.108.40
->>> name=manyhome.test.ex address=10.250.108.41
->>> name=manyhome.test.ex address=10.250.108.42
->>> name=manyhome.test.ex address=10.250.108.43
->>> name=manyhome.test.ex address=10.250.108.44
->>> name=manyhome.test.ex address=10.250.108.45
->>> name=manyhome.test.ex address=10.250.108.46
->>> name=manyhome.test.ex address=10.250.108.47
->>> name=manyhome.test.ex address=10.250.108.48
->>> name=manyhome.test.ex address=10.250.108.49
->>> name=manyhome.test.ex address=10.250.108.50
->>> name=manyhome.test.ex address=10.250.108.51
->>> name=manyhome.test.ex address=10.250.108.52
->>> name=manyhome.test.ex address=10.250.108.53
->>> name=manyhome.test.ex address=10.250.108.54
->>> name=manyhome.test.ex address=10.250.108.55
->>> name=manyhome.test.ex address=10.250.108.56
->>> name=manyhome.test.ex address=10.250.108.57
->>> name=manyhome.test.ex address=10.250.108.58
->>> name=manyhome.test.ex address=10.250.108.59
->>> name=manyhome.test.ex address=10.250.108.60
->>> name=manyhome.test.ex address=10.250.108.61
->>> name=manyhome.test.ex address=10.250.108.62
->>> name=manyhome.test.ex address=10.250.108.63
->>> name=manyhome.test.ex address=10.250.108.64
->>> name=manyhome.test.ex address=10.250.108.65
->>> name=manyhome.test.ex address=10.250.108.66
->>> name=manyhome.test.ex address=10.250.108.67
->>> name=manyhome.test.ex address=10.250.108.68
->>> name=manyhome.test.ex address=10.250.108.69
->>> name=manyhome.test.ex address=10.250.108.70
->>> name=manyhome.test.ex address=10.250.108.71
->>> name=manyhome.test.ex address=10.250.108.72
->>> name=manyhome.test.ex address=10.250.108.73
->>> name=manyhome.test.ex address=10.250.108.74
->>> name=manyhome.test.ex address=10.250.108.75
->>> name=manyhome.test.ex address=10.250.108.76
->>> name=manyhome.test.ex address=10.250.108.77
->>> name=manyhome.test.ex address=10.250.108.78
->>> name=manyhome.test.ex address=10.250.108.79
->>> name=manyhome.test.ex address=10.250.108.80
->>> name=manyhome.test.ex address=10.250.108.81
->>> name=manyhome.test.ex address=10.250.108.82
->>> name=manyhome.test.ex address=10.250.108.83
->>> name=manyhome.test.ex address=10.250.108.84
->>> name=manyhome.test.ex address=10.250.108.85
->>> name=manyhome.test.ex address=10.250.108.86
->>> name=manyhome.test.ex address=10.250.108.87
->>> name=manyhome.test.ex address=10.250.108.88
->>> name=manyhome.test.ex address=10.250.108.89
->>> name=manyhome.test.ex address=10.250.108.90
->>> name=manyhome.test.ex address=10.250.108.91
->>> name=manyhome.test.ex address=10.250.108.92
->>> name=manyhome.test.ex address=10.250.108.93
->>> name=manyhome.test.ex address=10.250.108.94
->>> name=manyhome.test.ex address=10.250.108.95
->>> name=manyhome.test.ex address=10.250.108.96
->>> name=manyhome.test.ex address=10.250.108.97
->>> name=manyhome.test.ex address=10.250.108.98
->>> name=manyhome.test.ex address=10.250.108.99
->>> name=manyhome.test.ex address=10.250.108.100
->>> name=manyhome.test.ex address=10.250.108.101
->>> name=manyhome.test.ex address=10.250.108.102
->>> name=manyhome.test.ex address=10.250.108.103
->>> name=manyhome.test.ex address=10.250.108.104
->>> name=manyhome.test.ex address=10.250.108.105
->>> name=manyhome.test.ex address=10.250.108.106
->>> name=manyhome.test.ex address=10.250.108.107
->>> name=manyhome.test.ex address=10.250.108.108
->>> name=manyhome.test.ex address=10.250.108.109
->>> name=manyhome.test.ex address=10.250.108.110
->>> name=manyhome.test.ex address=10.250.108.111
->>> name=manyhome.test.ex address=10.250.108.112
->>> name=manyhome.test.ex address=10.250.108.113
->>> name=manyhome.test.ex address=10.250.108.114
->>> name=manyhome.test.ex address=10.250.108.115
->>> name=manyhome.test.ex address=10.250.108.116
->>> name=manyhome.test.ex address=10.250.108.117
->>> name=manyhome.test.ex address=10.250.108.118
->>> name=manyhome.test.ex address=10.250.108.119
->>> name=manyhome.test.ex address=10.250.108.120
->>> name=manyhome.test.ex address=10.250.108.121
->>> name=manyhome.test.ex address=10.250.108.122
->>> name=manyhome.test.ex address=10.250.108.123
->>> name=manyhome.test.ex address=10.250.108.124
->>> name=manyhome.test.ex address=10.250.108.125
->>> name=manyhome.test.ex address=10.250.108.126
->>> name=manyhome.test.ex address=10.250.108.127
->>> name=manyhome.test.ex address=10.250.108.128
->>> name=manyhome.test.ex address=10.250.108.129
->>> name=manyhome.test.ex address=10.250.108.130
->>> name=manyhome.test.ex address=10.250.108.131
->>> name=manyhome.test.ex address=10.250.108.132
->>> name=manyhome.test.ex address=10.250.108.133
->>> name=manyhome.test.ex address=10.250.108.134
->>> name=manyhome.test.ex address=10.250.108.135
->>> name=manyhome.test.ex address=10.250.108.136
->>> name=manyhome.test.ex address=10.250.108.137
->>> name=manyhome.test.ex address=10.250.108.138
->>> name=manyhome.test.ex address=10.250.108.139
->>> name=manyhome.test.ex address=10.250.108.140
->>> name=manyhome.test.ex address=10.250.108.141
->>> name=manyhome.test.ex address=10.250.108.142
->>> name=manyhome.test.ex address=10.250.108.143
->>> name=manyhome.test.ex address=10.250.108.144
->>> name=manyhome.test.ex address=10.250.108.145
->>> name=manyhome.test.ex address=10.250.108.146
->>> name=manyhome.test.ex address=10.250.108.147
->>> name=manyhome.test.ex address=10.250.108.148
->>> name=manyhome.test.ex address=10.250.108.149
->>> name=manyhome.test.ex address=10.250.108.150
->>> name=manyhome.test.ex address=10.250.108.151
->>> name=manyhome.test.ex address=10.250.108.152
->>> name=manyhome.test.ex address=10.250.108.153
->>> name=manyhome.test.ex address=10.250.108.154
->>> name=manyhome.test.ex address=10.250.108.155
->>> name=manyhome.test.ex address=10.250.108.156
->>> name=manyhome.test.ex address=10.250.108.157
->>> name=manyhome.test.ex address=10.250.108.158
->>> name=manyhome.test.ex address=10.250.108.159
->>> name=manyhome.test.ex address=10.250.108.160
->>> name=manyhome.test.ex address=10.250.108.161
->>> name=manyhome.test.ex address=10.250.108.162
->>> name=manyhome.test.ex address=10.250.108.163
->>> name=manyhome.test.ex address=10.250.108.164
->>> name=manyhome.test.ex address=10.250.108.165
->>> name=manyhome.test.ex address=10.250.108.166
->>> name=manyhome.test.ex address=10.250.108.167
->>> name=manyhome.test.ex address=10.250.108.168
->>> name=manyhome.test.ex address=10.250.108.169
->>> name=manyhome.test.ex address=10.250.108.170
->>> name=manyhome.test.ex address=10.250.108.171
->>> name=manyhome.test.ex address=10.250.108.172
->>> name=manyhome.test.ex address=10.250.108.173
->>> name=manyhome.test.ex address=10.250.108.174
->>> name=manyhome.test.ex address=10.250.108.175
->>> name=manyhome.test.ex address=10.250.108.176
->>> name=manyhome.test.ex address=10.250.108.177
->>> name=manyhome.test.ex address=10.250.108.178
->>> name=manyhome.test.ex address=10.250.108.179
->>> name=manyhome.test.ex address=10.250.108.180
->>> name=manyhome.test.ex address=10.250.108.181
->>> name=manyhome.test.ex address=10.250.108.182
->>> name=manyhome.test.ex address=10.250.108.183
->>> name=manyhome.test.ex address=10.250.108.184
->>> name=manyhome.test.ex address=10.250.108.185
->>> name=manyhome.test.ex address=10.250.108.186
->>> name=manyhome.test.ex address=10.250.108.187
->>> name=manyhome.test.ex address=10.250.108.188
->>> name=manyhome.test.ex address=10.250.108.189
->>> name=manyhome.test.ex address=10.250.108.190
->>> name=manyhome.test.ex address=10.250.108.191
->>> name=manyhome.test.ex address=10.250.108.192
->>> name=manyhome.test.ex address=10.250.108.193
->>> name=manyhome.test.ex address=10.250.108.194
->>> name=manyhome.test.ex address=10.250.108.195
->>> name=manyhome.test.ex address=10.250.108.196
->>> name=manyhome.test.ex address=10.250.108.197
->>> name=manyhome.test.ex address=10.250.108.198
->>> name=manyhome.test.ex address=10.250.108.199
->>> name=manyhome.test.ex address=10.250.108.200
->>> name=manyhome.test.ex address=10.250.108.201
->>> name=manyhome.test.ex address=10.250.108.202
->>> name=manyhome.test.ex address=10.250.108.203
->>> name=manyhome.test.ex address=10.250.108.204
->>> name=manyhome.test.ex address=10.250.108.205
->>> name=manyhome.test.ex address=10.250.108.206
->>> name=manyhome.test.ex address=10.250.108.207
->>> name=manyhome.test.ex address=10.250.108.208
->>> name=manyhome.test.ex address=10.250.108.209
->>> name=manyhome.test.ex address=10.250.108.210
->>> name=manyhome.test.ex address=10.250.108.211
->>> name=manyhome.test.ex address=10.250.108.212
->>> name=manyhome.test.ex address=10.250.108.213
->>> name=manyhome.test.ex address=10.250.108.214
->>> name=manyhome.test.ex address=10.250.108.215
->>> name=manyhome.test.ex address=10.250.108.216
->>> name=manyhome.test.ex address=10.250.108.217
->>> name=manyhome.test.ex address=10.250.108.218
->>> name=manyhome.test.ex address=10.250.108.219
->>> name=manyhome.test.ex address=10.250.108.220
->>> name=manyhome.test.ex address=10.250.108.221
->>> name=manyhome.test.ex address=10.250.108.222
->>> name=manyhome.test.ex address=10.250.108.223
->>> name=manyhome.test.ex address=10.250.108.224
->>> name=manyhome.test.ex address=10.250.108.225
->>> name=manyhome.test.ex address=10.250.108.226
->>> name=manyhome.test.ex address=10.250.108.227
->>> name=manyhome.test.ex address=10.250.108.228
->>> name=manyhome.test.ex address=10.250.108.229
->>> name=manyhome.test.ex address=10.250.108.230
->>> name=manyhome.test.ex address=10.250.108.231
->>> name=manyhome.test.ex address=10.250.108.232
->>> name=manyhome.test.ex address=10.250.108.233
->>> name=manyhome.test.ex address=10.250.108.234
->>> name=manyhome.test.ex address=10.250.108.235
->>> name=manyhome.test.ex address=10.250.108.236
->>> name=manyhome.test.ex address=10.250.108.237
->>> name=manyhome.test.ex address=10.250.108.238
->>> name=manyhome.test.ex address=10.250.108.239
->>> name=manyhome.test.ex address=10.250.108.240
->>> name=manyhome.test.ex address=10.250.108.241
->>> name=manyhome.test.ex address=10.250.108.242
->>> name=manyhome.test.ex address=10.250.108.243
->>> name=manyhome.test.ex address=10.250.108.244
->>> name=manyhome.test.ex address=10.250.108.245
->>> name=manyhome.test.ex address=10.250.108.246
->>> name=manyhome.test.ex address=10.250.108.247
->>> name=manyhome.test.ex address=10.250.108.248
->>> name=manyhome.test.ex address=10.250.108.249
->>> name=manyhome.test.ex address=10.250.108.250
->>> name=manyhome.test.ex address=10.250.108.251
->>> name=manyhome.test.ex address=10.250.108.252
->>> name=manyhome.test.ex address=10.250.108.253
->>> name=manyhome.test.ex address=10.250.108.254
->>> name=manyhome.test.ex address=10.250.108.255
->>> name=manyhome.test.ex address=10.250.109.0
->>> name=manyhome.test.ex address=10.250.109.1
->>> name=manyhome.test.ex address=10.250.109.2
->>> name=manyhome.test.ex address=10.250.109.3
->>> name=manyhome.test.ex address=10.250.109.4
->>> name=manyhome.test.ex address=10.250.109.5
->>> name=manyhome.test.ex address=10.250.109.6
->>> name=manyhome.test.ex address=10.250.109.7
->>> name=manyhome.test.ex address=10.250.109.8
->>> name=manyhome.test.ex address=10.250.109.9
->>> name=manyhome.test.ex address=10.250.109.10
->>> name=manyhome.test.ex address=10.250.109.11
->>> name=manyhome.test.ex address=10.250.109.12
->>> name=manyhome.test.ex address=10.250.109.13
->>> name=manyhome.test.ex address=10.250.109.14
->>> name=manyhome.test.ex address=10.250.109.15
->>> name=manyhome.test.ex address=10.250.109.16
->>> name=manyhome.test.ex address=10.250.109.17
->>> name=manyhome.test.ex address=10.250.109.18
->>> name=manyhome.test.ex address=10.250.109.19
->>> name=manyhome.test.ex address=10.250.109.20
->>> name=manyhome.test.ex address=10.250.109.21
->>> name=manyhome.test.ex address=10.250.109.22
->>> name=manyhome.test.ex address=10.250.109.23
->>> name=manyhome.test.ex address=10.250.109.24
->>> name=manyhome.test.ex address=10.250.109.25
->>> name=manyhome.test.ex address=10.250.109.26
->>> name=manyhome.test.ex address=10.250.109.27
->>> name=manyhome.test.ex address=10.250.109.28
->>> name=manyhome.test.ex address=10.250.109.29
->>> name=manyhome.test.ex address=10.250.109.30
->>> name=manyhome.test.ex address=10.250.109.31
->>> name=manyhome.test.ex address=10.250.109.32
->>> name=manyhome.test.ex address=10.250.109.33
->>> name=manyhome.test.ex address=10.250.109.34
->>> name=manyhome.test.ex address=10.250.109.35
->>> name=manyhome.test.ex address=10.250.109.36
->>> name=manyhome.test.ex address=10.250.109.37
->>> name=manyhome.test.ex address=10.250.109.38
->>> name=manyhome.test.ex address=10.250.109.39
->>> name=manyhome.test.ex address=10.250.109.40
->>> name=manyhome.test.ex address=10.250.109.41
->>> name=manyhome.test.ex address=10.250.109.42
->>> name=manyhome.test.ex address=10.250.109.43
->>> name=manyhome.test.ex address=10.250.109.44
->>> name=manyhome.test.ex address=10.250.109.45
->>> name=manyhome.test.ex address=10.250.109.46
->>> name=manyhome.test.ex address=10.250.109.47
->>> name=manyhome.test.ex address=10.250.109.48
->>> name=manyhome.test.ex address=10.250.109.49
->>> name=manyhome.test.ex address=10.250.109.50
->>> name=manyhome.test.ex address=10.250.109.51
->>> name=manyhome.test.ex address=10.250.109.52
->>> name=manyhome.test.ex address=10.250.109.53
->>> name=manyhome.test.ex address=10.250.109.54
->>> name=manyhome.test.ex address=10.250.109.55
->>> name=manyhome.test.ex address=10.250.109.56
->>> name=manyhome.test.ex address=10.250.109.57
->>> name=manyhome.test.ex address=10.250.109.58
->>> name=manyhome.test.ex address=10.250.109.59
->>> name=manyhome.test.ex address=10.250.109.60
->>> name=manyhome.test.ex address=10.250.109.61
->>> name=manyhome.test.ex address=10.250.109.62
->>> name=manyhome.test.ex address=10.250.109.63
->>> name=manyhome.test.ex address=10.250.109.64
->>> name=manyhome.test.ex address=10.250.109.65
->>> name=manyhome.test.ex address=10.250.109.66
->>> name=manyhome.test.ex address=10.250.109.67
->>> name=manyhome.test.ex address=10.250.109.68
->>> name=manyhome.test.ex address=10.250.109.69
->>> name=manyhome.test.ex address=10.250.109.70
->>> name=manyhome.test.ex address=10.250.109.71
->>> name=manyhome.test.ex address=10.250.109.72
->>> name=manyhome.test.ex address=10.250.109.73
->>> name=manyhome.test.ex address=10.250.109.74
->>> name=manyhome.test.ex address=10.250.109.75
->>> name=manyhome.test.ex address=10.250.109.76
->>> name=manyhome.test.ex address=10.250.109.77
->>> name=manyhome.test.ex address=10.250.109.78
->>> name=manyhome.test.ex address=10.250.109.79
->>> name=manyhome.test.ex address=10.250.109.80
->>> name=manyhome.test.ex address=10.250.109.81
->>> name=manyhome.test.ex address=10.250.109.82
->>> name=manyhome.test.ex address=10.250.109.83
->>> name=manyhome.test.ex address=10.250.109.84
->>> name=manyhome.test.ex address=10.250.109.85
->>> name=manyhome.test.ex address=10.250.109.86
->>> name=manyhome.test.ex address=10.250.109.87
->>> name=manyhome.test.ex address=10.250.109.88
->>> name=manyhome.test.ex address=10.250.109.89
->>> name=manyhome.test.ex address=10.250.109.90
->>> name=manyhome.test.ex address=10.250.109.91
->>> name=manyhome.test.ex address=10.250.109.92
->>> name=manyhome.test.ex address=10.250.109.93
->>> name=manyhome.test.ex address=10.250.109.94
->>> name=manyhome.test.ex address=10.250.109.95
->>> name=manyhome.test.ex address=10.250.109.96
->>> name=manyhome.test.ex address=10.250.109.97
->>> name=manyhome.test.ex address=10.250.109.98
->>> name=manyhome.test.ex address=10.250.109.99
->>> name=manyhome.test.ex address=10.250.109.100
->>> name=manyhome.test.ex address=10.250.109.101
->>> name=manyhome.test.ex address=10.250.109.102
->>> name=manyhome.test.ex address=10.250.109.103
->>> name=manyhome.test.ex address=10.250.109.104
->>> name=manyhome.test.ex address=10.250.109.105
->>> name=manyhome.test.ex address=10.250.109.106
->>> name=manyhome.test.ex address=10.250.109.107
->>> name=manyhome.test.ex address=10.250.109.108
->>> name=manyhome.test.ex address=10.250.109.109
->>> name=manyhome.test.ex address=10.250.109.110
->>> name=manyhome.test.ex address=10.250.109.111
->>> name=manyhome.test.ex address=10.250.109.112
->>> name=manyhome.test.ex address=10.250.109.113
->>> name=manyhome.test.ex address=10.250.109.114
->>> name=manyhome.test.ex address=10.250.109.115
->>> name=manyhome.test.ex address=10.250.109.116
->>> name=manyhome.test.ex address=10.250.109.117
->>> name=manyhome.test.ex address=10.250.109.118
->>> name=manyhome.test.ex address=10.250.109.119
->>> name=manyhome.test.ex address=10.250.109.120
->>> name=manyhome.test.ex address=10.250.109.121
->>> name=manyhome.test.ex address=10.250.109.122
->>> name=manyhome.test.ex address=10.250.109.123
->>> name=manyhome.test.ex address=10.250.109.124
->>> name=manyhome.test.ex address=10.250.109.125
->>> name=manyhome.test.ex address=10.250.109.126
->>> name=manyhome.test.ex address=10.250.109.127
->>> name=manyhome.test.ex address=10.250.109.128
->>> name=manyhome.test.ex address=10.250.109.129
->>> name=manyhome.test.ex address=10.250.109.130
->>> name=manyhome.test.ex address=10.250.109.131
->>> name=manyhome.test.ex address=10.250.109.132
->>> name=manyhome.test.ex address=10.250.109.133
->>> name=manyhome.test.ex address=10.250.109.134
->>> name=manyhome.test.ex address=10.250.109.135
->>> name=manyhome.test.ex address=10.250.109.136
->>> name=manyhome.test.ex address=10.250.109.137
->>> name=manyhome.test.ex address=10.250.109.138
->>> name=manyhome.test.ex address=10.250.109.139
->>> name=manyhome.test.ex address=10.250.109.140
->>> name=manyhome.test.ex address=10.250.109.141
->>> name=manyhome.test.ex address=10.250.109.142
->>> name=manyhome.test.ex address=10.250.109.143
->>> name=manyhome.test.ex address=10.250.109.144
->>> name=manyhome.test.ex address=10.250.109.145
->>> name=manyhome.test.ex address=10.250.109.146
->>> name=manyhome.test.ex address=10.250.109.147
->>> name=manyhome.test.ex address=10.250.109.148
->>> name=manyhome.test.ex address=10.250.109.149
->>> name=manyhome.test.ex address=10.250.109.150
->>> name=manyhome.test.ex address=10.250.109.151
->>> name=manyhome.test.ex address=10.250.109.152
->>> name=manyhome.test.ex address=10.250.109.153
->>> name=manyhome.test.ex address=10.250.109.154
->>> name=manyhome.test.ex address=10.250.109.155
->>> name=manyhome.test.ex address=10.250.109.156
->>> name=manyhome.test.ex address=10.250.109.157
->>> name=manyhome.test.ex address=10.250.109.158
->>> name=manyhome.test.ex address=10.250.109.159
->>> name=manyhome.test.ex address=10.250.109.160
->>> name=manyhome.test.ex address=10.250.109.161
->>> name=manyhome.test.ex address=10.250.109.162
->>> name=manyhome.test.ex address=10.250.109.163
->>> name=manyhome.test.ex address=10.250.109.164
->>> name=manyhome.test.ex address=10.250.109.165
->>> name=manyhome.test.ex address=10.250.109.166
->>> name=manyhome.test.ex address=10.250.109.167
->>> name=manyhome.test.ex address=10.250.109.168
->>> name=manyhome.test.ex address=10.250.109.169
->>> name=manyhome.test.ex address=10.250.109.170
->>> name=manyhome.test.ex address=10.250.109.171
->>> name=manyhome.test.ex address=10.250.109.172
->>> name=manyhome.test.ex address=10.250.109.173
->>> name=manyhome.test.ex address=10.250.109.174
->>> name=manyhome.test.ex address=10.250.109.175
->>> name=manyhome.test.ex address=10.250.109.176
->>> name=manyhome.test.ex address=10.250.109.177
->>> name=manyhome.test.ex address=10.250.109.178
->>> name=manyhome.test.ex address=10.250.109.179
->>> name=manyhome.test.ex address=10.250.109.180
->>> name=manyhome.test.ex address=10.250.109.181
->>> name=manyhome.test.ex address=10.250.109.182
->>> name=manyhome.test.ex address=10.250.109.183
->>> name=manyhome.test.ex address=10.250.109.184
->>> name=manyhome.test.ex address=10.250.109.185
->>> name=manyhome.test.ex address=10.250.109.186
->>> name=manyhome.test.ex address=10.250.109.187
->>> name=manyhome.test.ex address=10.250.109.188
->>> name=manyhome.test.ex address=10.250.109.189
->>> name=manyhome.test.ex address=10.250.109.190
->>> name=manyhome.test.ex address=10.250.109.191
->>> name=manyhome.test.ex address=10.250.109.192
->>> name=manyhome.test.ex address=10.250.109.193
->>> name=manyhome.test.ex address=10.250.109.194
->>> name=manyhome.test.ex address=10.250.109.195
->>> name=manyhome.test.ex address=10.250.109.196
->>> name=manyhome.test.ex address=10.250.109.197
->>> name=manyhome.test.ex address=10.250.109.198
->>> name=manyhome.test.ex address=10.250.109.199
->>> name=manyhome.test.ex address=10.250.109.200
->>> name=manyhome.test.ex address=10.250.109.201
->>> name=manyhome.test.ex address=10.250.109.202
->>> name=manyhome.test.ex address=10.250.109.203
->>> name=manyhome.test.ex address=10.250.109.204
->>> name=manyhome.test.ex address=10.250.109.205
->>> name=manyhome.test.ex address=10.250.109.206
->>> name=manyhome.test.ex address=10.250.109.207
->>> name=manyhome.test.ex address=10.250.109.208
->>> name=manyhome.test.ex address=10.250.109.209
->>> name=manyhome.test.ex address=10.250.109.210
->>> name=manyhome.test.ex address=10.250.109.211
->>> name=manyhome.test.ex address=10.250.109.212
->>> name=manyhome.test.ex address=10.250.109.213
->>> name=manyhome.test.ex address=10.250.109.214
->>> name=manyhome.test.ex address=10.250.109.215
->>> name=manyhome.test.ex address=10.250.109.216
->>> name=manyhome.test.ex address=10.250.109.217
->>> name=manyhome.test.ex address=10.250.109.218
->>> name=manyhome.test.ex address=10.250.109.219
->>> name=manyhome.test.ex address=10.250.109.220
->>> name=manyhome.test.ex address=10.250.109.221
->>> name=manyhome.test.ex address=10.250.109.222
->>> name=manyhome.test.ex address=10.250.109.223
->>> name=manyhome.test.ex address=10.250.109.224
->>> name=manyhome.test.ex address=10.250.109.225
->>> name=manyhome.test.ex address=10.250.109.226
->>> name=manyhome.test.ex address=10.250.109.227
->>> name=manyhome.test.ex address=10.250.109.228
->>> name=manyhome.test.ex address=10.250.109.229
->>> name=manyhome.test.ex address=10.250.109.230
->>> name=manyhome.test.ex address=10.250.109.231
->>> name=manyhome.test.ex address=10.250.109.232
->>> name=manyhome.test.ex address=10.250.109.233
->>> name=manyhome.test.ex address=10.250.109.234
->>> name=manyhome.test.ex address=10.250.109.235
->>> name=manyhome.test.ex address=10.250.109.236
->>> name=manyhome.test.ex address=10.250.109.237
->>> name=manyhome.test.ex address=10.250.109.238
->>> name=manyhome.test.ex address=10.250.109.239
->>> name=manyhome.test.ex address=10.250.109.240
->>> name=manyhome.test.ex address=10.250.109.241
->>> name=manyhome.test.ex address=10.250.109.242
->>> name=manyhome.test.ex address=10.250.109.243
->>> name=manyhome.test.ex address=10.250.109.244
->>> name=manyhome.test.ex address=10.250.109.245
->>> name=manyhome.test.ex address=10.250.109.246
->>> name=manyhome.test.ex address=10.250.109.247
->>> name=manyhome.test.ex address=10.250.109.248
->>> name=manyhome.test.ex address=10.250.109.249
->>> name=manyhome.test.ex address=10.250.109.250
->>> name=manyhome.test.ex address=10.250.109.251
->>> name=manyhome.test.ex address=10.250.109.252
->>> name=manyhome.test.ex address=10.250.109.253
->>> name=manyhome.test.ex address=10.250.109.254
->>> name=manyhome.test.ex address=10.250.109.255
->>> name=manyhome.test.ex address=10.250.110.0
->>> name=manyhome.test.ex address=10.250.110.1
->>> name=manyhome.test.ex address=10.250.110.2
->>> name=manyhome.test.ex address=10.250.110.3
->>> name=manyhome.test.ex address=10.250.110.4
->>> name=manyhome.test.ex address=10.250.110.5
->>> name=manyhome.test.ex address=10.250.110.6
->>> name=manyhome.test.ex address=10.250.110.7
->>> name=manyhome.test.ex address=10.250.110.8
->>> name=manyhome.test.ex address=10.250.110.9
->>> name=manyhome.test.ex address=10.250.110.10
->>> name=manyhome.test.ex address=10.250.110.11
->>> name=manyhome.test.ex address=10.250.110.12
->>> name=manyhome.test.ex address=10.250.110.13
->>> name=manyhome.test.ex address=10.250.110.14
->>> name=manyhome.test.ex address=10.250.110.15
->>> name=manyhome.test.ex address=10.250.110.16
->>> name=manyhome.test.ex address=10.250.110.17
->>> name=manyhome.test.ex address=10.250.110.18
->>> name=manyhome.test.ex address=10.250.110.19
->>> name=manyhome.test.ex address=10.250.110.20
->>> name=manyhome.test.ex address=10.250.110.21
->>> name=manyhome.test.ex address=10.250.110.22
->>> name=manyhome.test.ex address=10.250.110.23
->>> name=manyhome.test.ex address=10.250.110.24
->>> name=manyhome.test.ex address=10.250.110.25
->>> name=manyhome.test.ex address=10.250.110.26
->>> name=manyhome.test.ex address=10.250.110.27
->>> name=manyhome.test.ex address=10.250.110.28
->>> name=manyhome.test.ex address=10.250.110.29
->>> name=manyhome.test.ex address=10.250.110.30
->>> name=manyhome.test.ex address=10.250.110.31
->>> name=manyhome.test.ex address=10.250.110.32
->>> name=manyhome.test.ex address=10.250.110.33
->>> name=manyhome.test.ex address=10.250.110.34
->>> name=manyhome.test.ex address=10.250.110.35
->>> name=manyhome.test.ex address=10.250.110.36
->>> name=manyhome.test.ex address=10.250.110.37
->>> name=manyhome.test.ex address=10.250.110.38
->>> name=manyhome.test.ex address=10.250.110.39
->>> name=manyhome.test.ex address=10.250.110.40
->>> name=manyhome.test.ex address=10.250.110.41
->>> name=manyhome.test.ex address=10.250.110.42
->>> name=manyhome.test.ex address=10.250.110.43
->>> name=manyhome.test.ex address=10.250.110.44
->>> name=manyhome.test.ex address=10.250.110.45
->>> name=manyhome.test.ex address=10.250.110.46
->>> name=manyhome.test.ex address=10.250.110.47
->>> name=manyhome.test.ex address=10.250.110.48
->>> name=manyhome.test.ex address=10.250.110.49
->>> name=manyhome.test.ex address=10.250.110.50
->>> name=manyhome.test.ex address=10.250.110.51
->>> name=manyhome.test.ex address=10.250.110.52
->>> name=manyhome.test.ex address=10.250.110.53
->>> name=manyhome.test.ex address=10.250.110.54
->>> name=manyhome.test.ex address=10.250.110.55
->>> name=manyhome.test.ex address=10.250.110.56
->>> name=manyhome.test.ex address=10.250.110.57
->>> name=manyhome.test.ex address=10.250.110.58
->>> name=manyhome.test.ex address=10.250.110.59
->>> name=manyhome.test.ex address=10.250.110.60
->>> name=manyhome.test.ex address=10.250.110.61
->>> name=manyhome.test.ex address=10.250.110.62
->>> name=manyhome.test.ex address=10.250.110.63
->>> name=manyhome.test.ex address=10.250.110.64
->>> name=manyhome.test.ex address=10.250.110.65
->>> name=manyhome.test.ex address=10.250.110.66
->>> name=manyhome.test.ex address=10.250.110.67
->>> name=manyhome.test.ex address=10.250.110.68
->>> name=manyhome.test.ex address=10.250.110.69
->>> name=manyhome.test.ex address=10.250.110.70
->>> name=manyhome.test.ex address=10.250.110.71
->>> name=manyhome.test.ex address=10.250.110.72
->>> name=manyhome.test.ex address=10.250.110.73
->>> name=manyhome.test.ex address=10.250.110.74
->>> name=manyhome.test.ex address=10.250.110.75
->>> name=manyhome.test.ex address=10.250.110.76
->>> name=manyhome.test.ex address=10.250.110.77
->>> name=manyhome.test.ex address=10.250.110.78
->>> name=manyhome.test.ex address=10.250.110.79
->>> name=manyhome.test.ex address=10.250.110.80
->>> name=manyhome.test.ex address=10.250.110.81
->>> name=manyhome.test.ex address=10.250.110.82
->>> name=manyhome.test.ex address=10.250.110.83
->>> name=manyhome.test.ex address=10.250.110.84
->>> name=manyhome.test.ex address=10.250.110.85
->>> name=manyhome.test.ex address=10.250.110.86
->>> name=manyhome.test.ex address=10.250.110.87
->>> name=manyhome.test.ex address=10.250.110.88
->>> name=manyhome.test.ex address=10.250.110.89
->>> name=manyhome.test.ex address=10.250.110.90
->>> name=manyhome.test.ex address=10.250.110.91
->>> name=manyhome.test.ex address=10.250.110.92
->>> name=manyhome.test.ex address=10.250.110.93
->>> name=manyhome.test.ex address=10.250.110.94
->>> name=manyhome.test.ex address=10.250.110.95
->>> name=manyhome.test.ex address=10.250.110.96
->>> name=manyhome.test.ex address=10.250.110.97
->>> name=manyhome.test.ex address=10.250.110.98
->>> name=manyhome.test.ex address=10.250.110.99
->>> name=manyhome.test.ex address=10.250.110.100
->>> name=manyhome.test.ex address=10.250.110.101
->>> name=manyhome.test.ex address=10.250.110.102
->>> name=manyhome.test.ex address=10.250.110.103
->>> name=manyhome.test.ex address=10.250.110.104
->>> name=manyhome.test.ex address=10.250.110.105
->>> name=manyhome.test.ex address=10.250.110.106
->>> name=manyhome.test.ex address=10.250.110.107
->>> name=manyhome.test.ex address=10.250.110.108
->>> name=manyhome.test.ex address=10.250.110.109
->>> name=manyhome.test.ex address=10.250.110.110
->>> name=manyhome.test.ex address=10.250.110.111
->>> name=manyhome.test.ex address=10.250.110.112
->>> name=manyhome.test.ex address=10.250.110.113
->>> name=manyhome.test.ex address=10.250.110.114
->>> name=manyhome.test.ex address=10.250.110.115
->>> name=manyhome.test.ex address=10.250.110.116
->>> name=manyhome.test.ex address=10.250.110.117
->>> name=manyhome.test.ex address=10.250.110.118
->>> name=manyhome.test.ex address=10.250.110.119
->>> name=manyhome.test.ex address=10.250.110.120
->>> name=manyhome.test.ex address=10.250.110.121
->>> name=manyhome.test.ex address=10.250.110.122
->>> name=manyhome.test.ex address=10.250.110.123
->>> name=manyhome.test.ex address=10.250.110.124
->>> name=manyhome.test.ex address=10.250.110.125
->>> name=manyhome.test.ex address=10.250.110.126
->>> name=manyhome.test.ex address=10.250.110.127
->>> name=manyhome.test.ex address=10.250.110.128
->>> name=manyhome.test.ex address=10.250.110.129
->>> name=manyhome.test.ex address=10.250.110.130
->>> name=manyhome.test.ex address=10.250.110.131
->>> name=manyhome.test.ex address=10.250.110.132
->>> name=manyhome.test.ex address=10.250.110.133
->>> name=manyhome.test.ex address=10.250.110.134
->>> name=manyhome.test.ex address=10.250.110.135
->>> name=manyhome.test.ex address=10.250.110.136
->>> name=manyhome.test.ex address=10.250.110.137
->>> name=manyhome.test.ex address=10.250.110.138
->>> name=manyhome.test.ex address=10.250.110.139
->>> name=manyhome.test.ex address=10.250.110.140
->>> name=manyhome.test.ex address=10.250.110.141
->>> name=manyhome.test.ex address=10.250.110.142
->>> name=manyhome.test.ex address=10.250.110.143
->>> name=manyhome.test.ex address=10.250.110.144
->>> name=manyhome.test.ex address=10.250.110.145
->>> name=manyhome.test.ex address=10.250.110.146
->>> name=manyhome.test.ex address=10.250.110.147
->>> name=manyhome.test.ex address=10.250.110.148
->>> name=manyhome.test.ex address=10.250.110.149
->>> name=manyhome.test.ex address=10.250.110.150
->>> name=manyhome.test.ex address=10.250.110.151
->>> name=manyhome.test.ex address=10.250.110.152
->>> name=manyhome.test.ex address=10.250.110.153
->>> name=manyhome.test.ex address=10.250.110.154
->>> name=manyhome.test.ex address=10.250.110.155
->>> name=manyhome.test.ex address=10.250.110.156
->>> name=manyhome.test.ex address=10.250.110.157
->>> name=manyhome.test.ex address=10.250.110.158
->>> name=manyhome.test.ex address=10.250.110.159
->>> name=manyhome.test.ex address=10.250.110.160
->>> name=manyhome.test.ex address=10.250.110.161
->>> name=manyhome.test.ex address=10.250.110.162
->>> name=manyhome.test.ex address=10.250.110.163
->>> name=manyhome.test.ex address=10.250.110.164
->>> name=manyhome.test.ex address=10.250.110.165
->>> name=manyhome.test.ex address=10.250.110.166
->>> name=manyhome.test.ex address=10.250.110.167
->>> name=manyhome.test.ex address=10.250.110.168
->>> name=manyhome.test.ex address=10.250.110.169
->>> name=manyhome.test.ex address=10.250.110.170
->>> name=manyhome.test.ex address=10.250.110.171
->>> name=manyhome.test.ex address=10.250.110.172
->>> name=manyhome.test.ex address=10.250.110.173
->>> name=manyhome.test.ex address=10.250.110.174
->>> name=manyhome.test.ex address=10.250.110.175
->>> name=manyhome.test.ex address=10.250.110.176
->>> name=manyhome.test.ex address=10.250.110.177
->>> name=manyhome.test.ex address=10.250.110.178
->>> name=manyhome.test.ex address=10.250.110.179
->>> name=manyhome.test.ex address=10.250.110.180
->>> name=manyhome.test.ex address=10.250.110.181
->>> name=manyhome.test.ex address=10.250.110.182
->>> name=manyhome.test.ex address=10.250.110.183
->>> name=manyhome.test.ex address=10.250.110.184
->>> name=manyhome.test.ex address=10.250.110.185
->>> name=manyhome.test.ex address=10.250.110.186
->>> name=manyhome.test.ex address=10.250.110.187
->>> name=manyhome.test.ex address=10.250.110.188
->>> name=manyhome.test.ex address=10.250.110.189
->>> name=manyhome.test.ex address=10.250.110.190
->>> name=manyhome.test.ex address=10.250.110.191
->>> name=manyhome.test.ex address=10.250.110.192
->>> name=manyhome.test.ex address=10.250.110.193
->>> name=manyhome.test.ex address=10.250.110.194
->>> name=manyhome.test.ex address=10.250.110.195
->>> name=manyhome.test.ex address=10.250.110.196
->>> name=manyhome.test.ex address=10.250.110.197
->>> name=manyhome.test.ex address=10.250.110.198
->>> name=manyhome.test.ex address=10.250.110.199
->>> name=manyhome.test.ex address=10.250.110.200
->>> name=manyhome.test.ex address=10.250.110.201
->>> name=manyhome.test.ex address=10.250.110.202
->>> name=manyhome.test.ex address=10.250.110.203
->>> name=manyhome.test.ex address=10.250.110.204
->>> name=manyhome.test.ex address=10.250.110.205
->>> name=manyhome.test.ex address=10.250.110.206
->>> name=manyhome.test.ex address=10.250.110.207
->>> name=manyhome.test.ex address=10.250.110.208
->>> name=manyhome.test.ex address=10.250.110.209
->>> name=manyhome.test.ex address=10.250.110.210
->>> name=manyhome.test.ex address=10.250.110.211
->>> name=manyhome.test.ex address=10.250.110.212
->>> name=manyhome.test.ex address=10.250.110.213
->>> name=manyhome.test.ex address=10.250.110.214
->>> name=manyhome.test.ex address=10.250.110.215
->>> name=manyhome.test.ex address=10.250.110.216
->>> name=manyhome.test.ex address=10.250.110.217
->>> name=manyhome.test.ex address=10.250.110.218
->>> name=manyhome.test.ex address=10.250.110.219
->>> name=manyhome.test.ex address=10.250.110.220
->>> name=manyhome.test.ex address=10.250.110.221
->>> name=manyhome.test.ex address=10.250.110.222
->>> name=manyhome.test.ex address=10.250.110.223
->>> name=manyhome.test.ex address=10.250.110.224
->>> name=manyhome.test.ex address=10.250.110.225
->>> name=manyhome.test.ex address=10.250.110.226
->>> name=manyhome.test.ex address=10.250.110.227
->>> name=manyhome.test.ex address=10.250.110.228
->>> name=manyhome.test.ex address=10.250.110.229
->>> name=manyhome.test.ex address=10.250.110.230
->>> name=manyhome.test.ex address=10.250.110.231
->>> name=manyhome.test.ex address=10.250.110.232
->>> name=manyhome.test.ex address=10.250.110.233
->>> name=manyhome.test.ex address=10.250.110.234
->>> name=manyhome.test.ex address=10.250.110.235
->>> name=manyhome.test.ex address=10.250.110.236
->>> name=manyhome.test.ex address=10.250.110.237
->>> name=manyhome.test.ex address=10.250.110.238
->>> name=manyhome.test.ex address=10.250.110.239
->>> name=manyhome.test.ex address=10.250.110.240
->>> name=manyhome.test.ex address=10.250.110.241
->>> name=manyhome.test.ex address=10.250.110.242
->>> name=manyhome.test.ex address=10.250.110.243
->>> name=manyhome.test.ex address=10.250.110.244
->>> name=manyhome.test.ex address=10.250.110.245
->>> name=manyhome.test.ex address=10.250.110.246
->>> name=manyhome.test.ex address=10.250.110.247
->>> name=manyhome.test.ex address=10.250.110.248
->>> name=manyhome.test.ex address=10.250.110.249
->>> name=manyhome.test.ex address=10.250.110.250
->>> name=manyhome.test.ex address=10.250.110.251
->>> name=manyhome.test.ex address=10.250.110.252
->>> name=manyhome.test.ex address=10.250.110.253
->>> name=manyhome.test.ex address=10.250.110.254
->>> name=manyhome.test.ex address=10.250.110.255
->>> name=manyhome.test.ex address=10.250.111.0
->>> name=manyhome.test.ex address=10.250.111.1
->>> name=manyhome.test.ex address=10.250.111.2
->>> name=manyhome.test.ex address=10.250.111.3
->>> name=manyhome.test.ex address=10.250.111.4
->>> name=manyhome.test.ex address=10.250.111.5
->>> name=manyhome.test.ex address=10.250.111.6
->>> name=manyhome.test.ex address=10.250.111.7
->>> name=manyhome.test.ex address=10.250.111.8
->>> name=manyhome.test.ex address=10.250.111.9
->>> name=manyhome.test.ex address=10.250.111.10
->>> name=manyhome.test.ex address=10.250.111.11
->>> name=manyhome.test.ex address=10.250.111.12
->>> name=manyhome.test.ex address=10.250.111.13
->>> name=manyhome.test.ex address=10.250.111.14
->>> name=manyhome.test.ex address=10.250.111.15
->>> name=manyhome.test.ex address=10.250.111.16
->>> name=manyhome.test.ex address=10.250.111.17
->>> name=manyhome.test.ex address=10.250.111.18
->>> name=manyhome.test.ex address=10.250.111.19
->>> name=manyhome.test.ex address=10.250.111.20
->>> name=manyhome.test.ex address=10.250.111.21
->>> name=manyhome.test.ex address=10.250.111.22
->>> name=manyhome.test.ex address=10.250.111.23
->>> name=manyhome.test.ex address=10.250.111.24
->>> name=manyhome.test.ex address=10.250.111.25
->>> name=manyhome.test.ex address=10.250.111.26
->>> name=manyhome.test.ex address=10.250.111.27
->>> name=manyhome.test.ex address=10.250.111.28
->>> name=manyhome.test.ex address=10.250.111.29
->>> name=manyhome.test.ex address=10.250.111.30
->>> name=manyhome.test.ex address=10.250.111.31
->>> name=manyhome.test.ex address=10.250.111.32
->>> name=manyhome.test.ex address=10.250.111.33
->>> name=manyhome.test.ex address=10.250.111.34
->>> name=manyhome.test.ex address=10.250.111.35
->>> name=manyhome.test.ex address=10.250.111.36
->>> name=manyhome.test.ex address=10.250.111.37
->>> name=manyhome.test.ex address=10.250.111.38
->>> name=manyhome.test.ex address=10.250.111.39
->>> name=manyhome.test.ex address=10.250.111.40
->>> name=manyhome.test.ex address=10.250.111.41
->>> name=manyhome.test.ex address=10.250.111.42
->>> name=manyhome.test.ex address=10.250.111.43
->>> name=manyhome.test.ex address=10.250.111.44
->>> name=manyhome.test.ex address=10.250.111.45
->>> name=manyhome.test.ex address=10.250.111.46
->>> name=manyhome.test.ex address=10.250.111.47
->>> name=manyhome.test.ex address=10.250.111.48
->>> name=manyhome.test.ex address=10.250.111.49
->>> name=manyhome.test.ex address=10.250.111.50
->>> name=manyhome.test.ex address=10.250.111.51
->>> name=manyhome.test.ex address=10.250.111.52
->>> name=manyhome.test.ex address=10.250.111.53
->>> name=manyhome.test.ex address=10.250.111.54
->>> name=manyhome.test.ex address=10.250.111.55
->>> name=manyhome.test.ex address=10.250.111.56
->>> name=manyhome.test.ex address=10.250.111.57
->>> name=manyhome.test.ex address=10.250.111.58
->>> name=manyhome.test.ex address=10.250.111.59
->>> name=manyhome.test.ex address=10.250.111.60
->>> name=manyhome.test.ex address=10.250.111.61
->>> name=manyhome.test.ex address=10.250.111.62
->>> name=manyhome.test.ex address=10.250.111.63
->>> name=manyhome.test.ex address=10.250.111.64
->>> name=manyhome.test.ex address=10.250.111.65
->>> name=manyhome.test.ex address=10.250.111.66
->>> name=manyhome.test.ex address=10.250.111.67
->>> name=manyhome.test.ex address=10.250.111.68
->>> name=manyhome.test.ex address=10.250.111.69
->>> name=manyhome.test.ex address=10.250.111.70
->>> name=manyhome.test.ex address=10.250.111.71
->>> name=manyhome.test.ex address=10.250.111.72
->>> name=manyhome.test.ex address=10.250.111.73
->>> name=manyhome.test.ex address=10.250.111.74
->>> name=manyhome.test.ex address=10.250.111.75
->>> name=manyhome.test.ex address=10.250.111.76
->>> name=manyhome.test.ex address=10.250.111.77
->>> name=manyhome.test.ex address=10.250.111.78
->>> name=manyhome.test.ex address=10.250.111.79
->>> name=manyhome.test.ex address=10.250.111.80
->>> name=manyhome.test.ex address=10.250.111.81
->>> name=manyhome.test.ex address=10.250.111.82
->>> name=manyhome.test.ex address=10.250.111.83
->>> name=manyhome.test.ex address=10.250.111.84
->>> name=manyhome.test.ex address=10.250.111.85
->>> name=manyhome.test.ex address=10.250.111.86
->>> name=manyhome.test.ex address=10.250.111.87
->>> name=manyhome.test.ex address=10.250.111.88
->>> name=manyhome.test.ex address=10.250.111.89
->>> name=manyhome.test.ex address=10.250.111.90
->>> name=manyhome.test.ex address=10.250.111.91
->>> name=manyhome.test.ex address=10.250.111.92
->>> name=manyhome.test.ex address=10.250.111.93
->>> name=manyhome.test.ex address=10.250.111.94
->>> name=manyhome.test.ex address=10.250.111.95
->>> name=manyhome.test.ex address=10.250.111.96
->>> name=manyhome.test.ex address=10.250.111.97
->>> name=manyhome.test.ex address=10.250.111.98
->>> name=manyhome.test.ex address=10.250.111.99
->>> name=manyhome.test.ex address=10.250.111.100
->>> name=manyhome.test.ex address=10.250.111.101
->>> name=manyhome.test.ex address=10.250.111.102
->>> name=manyhome.test.ex address=10.250.111.103
->>> name=manyhome.test.ex address=10.250.111.104
->>> name=manyhome.test.ex address=10.250.111.105
->>> name=manyhome.test.ex address=10.250.111.106
->>> name=manyhome.test.ex address=10.250.111.107
->>> name=manyhome.test.ex address=10.250.111.108
->>> name=manyhome.test.ex address=10.250.111.109
->>> name=manyhome.test.ex address=10.250.111.110
->>> name=manyhome.test.ex address=10.250.111.111
->>> name=manyhome.test.ex address=10.250.111.112
->>> name=manyhome.test.ex address=10.250.111.113
->>> name=manyhome.test.ex address=10.250.111.114
->>> name=manyhome.test.ex address=10.250.111.115
->>> name=manyhome.test.ex address=10.250.111.116
->>> name=manyhome.test.ex address=10.250.111.117
->>> name=manyhome.test.ex address=10.250.111.118
->>> name=manyhome.test.ex address=10.250.111.119
->>> name=manyhome.test.ex address=10.250.111.120
->>> name=manyhome.test.ex address=10.250.111.121
->>> name=manyhome.test.ex address=10.250.111.122
->>> name=manyhome.test.ex address=10.250.111.123
->>> name=manyhome.test.ex address=10.250.111.124
->>> name=manyhome.test.ex address=10.250.111.125
->>> name=manyhome.test.ex address=10.250.111.126
->>> name=manyhome.test.ex address=10.250.111.127
->>> name=manyhome.test.ex address=10.250.111.128
->>> name=manyhome.test.ex address=10.250.111.129
->>> name=manyhome.test.ex address=10.250.111.130
->>> name=manyhome.test.ex address=10.250.111.131
->>> name=manyhome.test.ex address=10.250.111.132
->>> name=manyhome.test.ex address=10.250.111.133
->>> name=manyhome.test.ex address=10.250.111.134
->>> name=manyhome.test.ex address=10.250.111.135
->>> name=manyhome.test.ex address=10.250.111.136
->>> name=manyhome.test.ex address=10.250.111.137
->>> name=manyhome.test.ex address=10.250.111.138
->>> name=manyhome.test.ex address=10.250.111.139
->>> name=manyhome.test.ex address=10.250.111.140
->>> name=manyhome.test.ex address=10.250.111.141
->>> name=manyhome.test.ex address=10.250.111.142
->>> name=manyhome.test.ex address=10.250.111.143
->>> name=manyhome.test.ex address=10.250.111.144
->>> name=manyhome.test.ex address=10.250.111.145
->>> name=manyhome.test.ex address=10.250.111.146
->>> name=manyhome.test.ex address=10.250.111.147
->>> name=manyhome.test.ex address=10.250.111.148
->>> name=manyhome.test.ex address=10.250.111.149
->>> name=manyhome.test.ex address=10.250.111.150
->>> name=manyhome.test.ex address=10.250.111.151
->>> name=manyhome.test.ex address=10.250.111.152
->>> name=manyhome.test.ex address=10.250.111.153
->>> name=manyhome.test.ex address=10.250.111.154
->>> name=manyhome.test.ex address=10.250.111.155
->>> name=manyhome.test.ex address=10.250.111.156
->>> name=manyhome.test.ex address=10.250.111.157
->>> name=manyhome.test.ex address=10.250.111.158
->>> name=manyhome.test.ex address=10.250.111.159
->>> name=manyhome.test.ex address=10.250.111.160
->>> name=manyhome.test.ex address=10.250.111.161
->>> name=manyhome.test.ex address=10.250.111.162
->>> name=manyhome.test.ex address=10.250.111.163
->>> name=manyhome.test.ex address=10.250.111.164
->>> name=manyhome.test.ex address=10.250.111.165
->>> name=manyhome.test.ex address=10.250.111.166
->>> name=manyhome.test.ex address=10.250.111.167
->>> name=manyhome.test.ex address=10.250.111.168
->>> name=manyhome.test.ex address=10.250.111.169
->>> name=manyhome.test.ex address=10.250.111.170
->>> name=manyhome.test.ex address=10.250.111.171
->>> name=manyhome.test.ex address=10.250.111.172
->>> name=manyhome.test.ex address=10.250.111.173
->>> name=manyhome.test.ex address=10.250.111.174
->>> name=manyhome.test.ex address=10.250.111.175
->>> name=manyhome.test.ex address=10.250.111.176
->>> name=manyhome.test.ex address=10.250.111.177
->>> name=manyhome.test.ex address=10.250.111.178
->>> name=manyhome.test.ex address=10.250.111.179
->>> name=manyhome.test.ex address=10.250.111.180
->>> name=manyhome.test.ex address=10.250.111.181
->>> name=manyhome.test.ex address=10.250.111.182
->>> name=manyhome.test.ex address=10.250.111.183
->>> name=manyhome.test.ex address=10.250.111.184
->>> name=manyhome.test.ex address=10.250.111.185
->>> name=manyhome.test.ex address=10.250.111.186
->>> name=manyhome.test.ex address=10.250.111.187
->>> name=manyhome.test.ex address=10.250.111.188
->>> name=manyhome.test.ex address=10.250.111.189
->>> name=manyhome.test.ex address=10.250.111.190
->>> name=manyhome.test.ex address=10.250.111.191
->>> name=manyhome.test.ex address=10.250.111.192
->>> name=manyhome.test.ex address=10.250.111.193
->>> name=manyhome.test.ex address=10.250.111.194
->>> name=manyhome.test.ex address=10.250.111.195
->>> name=manyhome.test.ex address=10.250.111.196
->>> name=manyhome.test.ex address=10.250.111.197
->>> name=manyhome.test.ex address=10.250.111.198
->>> name=manyhome.test.ex address=10.250.111.199
->>> name=manyhome.test.ex address=10.250.111.200
->>> name=manyhome.test.ex address=10.250.111.201
->>> name=manyhome.test.ex address=10.250.111.202
->>> name=manyhome.test.ex address=10.250.111.203
->>> name=manyhome.test.ex address=10.250.111.204
->>> name=manyhome.test.ex address=10.250.111.205
->>> name=manyhome.test.ex address=10.250.111.206
->>> name=manyhome.test.ex address=10.250.111.207
->>> name=manyhome.test.ex address=10.250.111.208
->>> name=manyhome.test.ex address=10.250.111.209
->>> name=manyhome.test.ex address=10.250.111.210
->>> name=manyhome.test.ex address=10.250.111.211
->>> name=manyhome.test.ex address=10.250.111.212
->>> name=manyhome.test.ex address=10.250.111.213
->>> name=manyhome.test.ex address=10.250.111.214
->>> name=manyhome.test.ex address=10.250.111.215
->>> name=manyhome.test.ex address=10.250.111.216
->>> name=manyhome.test.ex address=10.250.111.217
->>> name=manyhome.test.ex address=10.250.111.218
->>> name=manyhome.test.ex address=10.250.111.219
->>> name=manyhome.test.ex address=10.250.111.220
->>> name=manyhome.test.ex address=10.250.111.221
->>> name=manyhome.test.ex address=10.250.111.222
->>> name=manyhome.test.ex address=10.250.111.223
->>> name=manyhome.test.ex address=10.250.111.224
->>> name=manyhome.test.ex address=10.250.111.225
->>> name=manyhome.test.ex address=10.250.111.226
->>> name=manyhome.test.ex address=10.250.111.227
->>> name=manyhome.test.ex address=10.250.111.228
->>> name=manyhome.test.ex address=10.250.111.229
->>> name=manyhome.test.ex address=10.250.111.230
->>> name=manyhome.test.ex address=10.250.111.231
->>> name=manyhome.test.ex address=10.250.111.232
->>> name=manyhome.test.ex address=10.250.111.233
->>> name=manyhome.test.ex address=10.250.111.234
->>> name=manyhome.test.ex address=10.250.111.235
->>> name=manyhome.test.ex address=10.250.111.236
->>> name=manyhome.test.ex address=10.250.111.237
->>> name=manyhome.test.ex address=10.250.111.238
->>> name=manyhome.test.ex address=10.250.111.239
->>> name=manyhome.test.ex address=10.250.111.240
->>> name=manyhome.test.ex address=10.250.111.241
->>> name=manyhome.test.ex address=10.250.111.242
->>> name=manyhome.test.ex address=10.250.111.243
->>> name=manyhome.test.ex address=10.250.111.244
->>> name=manyhome.test.ex address=10.250.111.245
->>> name=manyhome.test.ex address=10.250.111.246
->>> name=manyhome.test.ex address=10.250.111.247
->>> name=manyhome.test.ex address=10.250.111.248
->>> name=manyhome.test.ex address=10.250.111.249
->>> name=manyhome.test.ex address=10.250.111.250
->>> name=manyhome.test.ex address=10.250.111.251
->>> name=manyhome.test.ex address=10.250.111.252
->>> name=manyhome.test.ex address=10.250.111.253
->>> name=manyhome.test.ex address=10.250.111.254
->>> name=manyhome.test.ex address=10.250.111.255
>>> checking addresses for manyhome.test.ex
->>> 10.250.104.0
->>> 10.250.104.1
+>>> 10.250.104.51
+>>> 10.250.104.17
>>> 10.250.104.2
->>> 10.250.104.3
->>> 10.250.104.4
->>> 10.250.104.5
->>> 10.250.104.6
->>> 10.250.104.7
+>>> 10.250.104.26
>>> 10.250.104.8
->>> 10.250.104.9
->>> 10.250.104.10
->>> 10.250.104.11
->>> 10.250.104.12
->>> 10.250.104.13
->>> 10.250.104.14
->>> 10.250.104.15
->>> 10.250.104.16
->>> 10.250.104.17
>>> 10.250.104.18
->>> 10.250.104.19
->>> 10.250.104.20
+>>> 10.250.104.25
>>> 10.250.104.21
->>> 10.250.104.22
+>>> 10.250.104.39
+>>> 10.250.104.32
+>>> 10.250.104.29
>>> 10.250.104.23
->>> 10.250.104.24
->>> 10.250.104.25
->>> 10.250.104.26
->>> 10.250.104.27
+>>> 10.250.104.43
+>>> 10.250.104.46
>>> 10.250.104.28
->>> 10.250.104.29
->>> 10.250.104.30
->>> 10.250.104.31
->>> 10.250.104.32
->>> 10.250.104.33
->>> 10.250.104.34
->>> 10.250.104.35
->>> 10.250.104.36
->>> 10.250.104.37
->>> 10.250.104.38
->>> 10.250.104.39
->>> 10.250.104.40
+>>> 10.250.104.4
>>> 10.250.104.41
+>>> 10.250.104.15
+>>> 10.250.104.14
+>>> 10.250.104.45
>>> 10.250.104.42 OK
>>> host in host_reject_connection? no (option unset)
>>> host in sender_unqualified_hosts? no (option unset)
>>> looking up host name for V4NET.0.0.3
>>> IP address lookup yielded "ten-3.test.ex"
>>> alias "ten-3-alias.test.ex"
-MUNGED: ::1 will be omitted in what follows
->>> get[host|ipnode]byname[2] looked up these IP addresses:
->>> name=ten-3.test.ex address=V4NET.0.0.3
>>> checking addresses for ten-3.test.ex
>>> V4NET.0.0.3 OK
-MUNGED: ::1 will be omitted in what follows
->>> get[host|ipnode]byname[2] looked up these IP addresses:
->>> name=ten-3-alias.test.ex address=V4NET.0.0.3
>>> checking addresses for ten-3-alias.test.ex
>>> V4NET.0.0.3 OK
>>> require: condition test succeeded in ACL "acl_V4NET_0_0"
>>> host in helo_verify_hosts? no (option unset)
>>> host in helo_try_verify_hosts? no (option unset)
>>> host in helo_accept_junk_hosts? no (option unset)
+>>> using ACL "acl_V4NET_99_99"
+>>> processing "accept"
+>>> check local_parts = defer_ok
+>>> x in "defer_ok"? no (end of list)
+>>> accept: condition test failed in ACL "acl_V4NET_99_99"
+>>> processing "accept"
+>>> check verify = reverse_host_lookup
+>>> looking up host name to force name/address consistency check
+>>> looking up host name for V4NET.99.99.96
+>>> IP address lookup yielded "x.test.again.dns"
+>>> x.test.again.dns in dns_again_means_nonexist? no (option unset)
+>>> temporary error for host name lookup
+>>> accept: condition test deferred in ACL "acl_V4NET_99_99"
+LOG: H=[V4NET.99.99.96] F=<> temporarily rejected RCPT <x@y>: host lookup deferred for reverse lookup check
+>>> host in hosts_connection_nolog? no (option unset)
+>>> host in host_lookup? no (option unset)
+>>> host in host_reject_connection? no (option unset)
+>>> host in sender_unqualified_hosts? no (option unset)
+>>> host in recipient_unqualified_hosts? no (option unset)
+>>> host in helo_verify_hosts? no (option unset)
+>>> host in helo_try_verify_hosts? no (option unset)
+>>> host in helo_accept_junk_hosts? no (option unset)
+>>> using ACL "acl_V4NET_99_99"
+>>> processing "accept"
+>>> check local_parts = defer_ok
+>>> defer_ok in "defer_ok"? yes (matched "defer_ok")
+>>> check verify = reverse_host_lookup/defer_ok
+>>> looking up host name to force name/address consistency check
+>>> looking up host name for V4NET.99.99.96
+>>> IP address lookup yielded "x.test.again.dns"
+>>> x.test.again.dns in dns_again_means_nonexist? no (option unset)
+>>> temporary error for host name lookup
+>>> accept: condition test succeeded in ACL "acl_V4NET_99_99"
+>>> end of ACL "acl_V4NET_99_99": ACCEPT
+>>> host in hosts_connection_nolog? no (option unset)
+>>> host in host_lookup? no (option unset)
+>>> host in host_reject_connection? no (option unset)
+>>> host in sender_unqualified_hosts? no (option unset)
+>>> host in recipient_unqualified_hosts? no (option unset)
+>>> host in helo_verify_hosts? no (option unset)
+>>> host in helo_try_verify_hosts? no (option unset)
+>>> host in helo_accept_junk_hosts? no (option unset)
>>> using ACL "acl_29_29_29"
>>> processing "deny"
>>> check dnslists = test.ex/$sender_address_domain
>>> check condition = ${if match{$message_body}{trigger}{yes}{no}}
>>> = no
>>> deny: condition test failed in ACL "acl_data"
+>>> processing "warn"
+>>> check logwrite = \$h_from: '$h_from:'
+>>> = $h_from: '@'
+LOG: 10HmbI-0005vi-00 $h_from: '@'
+>>> warn: condition test succeeded in ACL "acl_data"
>>> processing "require"
>>> check verify = header_syntax
>>> require: condition test failed in ACL "acl_data"
>>> end of ACL "acl_data": not OK
-LOG: 10HmbH-0005vi-00 H=[10.0.0.0] F=<x@y> rejected after DATA: domain missing or malformed: failing address in "From:" header is: @
+LOG: 10HmbI-0005vi-00 H=[10.0.0.0] F=<x@y> rejected after DATA: domain missing or malformed: failing address in "From:" header is: @
>>> host in hosts_connection_nolog? no (option unset)
>>> host in host_lookup? no (option unset)
>>> host in host_reject_connection? no (option unset)
>>> = yes
>>> deny: condition test succeeded in ACL "acl_data"
>>> end of ACL "acl_data": DENY
-LOG: 10HmbI-0005vi-00 H=[10.0.0.0] F=<x@y> rejected after DATA: body contains trigger
+LOG: 10HmbJ-0005vi-00 H=[10.0.0.0] F=<x@y> rejected after DATA: body contains trigger
-oMm must be a valid message ID
--oMm must be called by a trusted user/config
>>> sender host name required, to match against *-2.test.ex
>>> looking up host name for V4NET.0.0.1
>>> IP address lookup yielded "ten-1.test.ex"
-MUNGED: ::1 will be omitted in what follows
->>> get[host|ipnode]byname[2] looked up these IP addresses:
->>> name=ten-1.test.ex address=V4NET.0.0.1
>>> checking addresses for ten-1.test.ex
>>> V4NET.0.0.1 OK
>>> host in "*-2.test.ex : *-3-alias.test.ex"? no (end of list)
>>> sender host name required, to match against *-2.test.ex
>>> looking up host name for V4NET.0.0.2
>>> IP address lookup yielded "ten-2.test.ex"
-MUNGED: ::1 will be omitted in what follows
->>> get[host|ipnode]byname[2] looked up these IP addresses:
->>> name=ten-2.test.ex address=V4NET.0.0.2
>>> checking addresses for ten-2.test.ex
>>> V4NET.0.0.2 OK
>>> host in "*-2.test.ex : *-3-alias.test.ex"? yes (matched "*-2.test.ex")
>>> looking up host name for V4NET.0.0.3
>>> IP address lookup yielded "ten-3.test.ex"
>>> alias "ten-3-alias.test.ex"
-MUNGED: ::1 will be omitted in what follows
->>> get[host|ipnode]byname[2] looked up these IP addresses:
->>> name=ten-3.test.ex address=V4NET.0.0.3
>>> checking addresses for ten-3.test.ex
>>> V4NET.0.0.3 OK
-MUNGED: ::1 will be omitted in what follows
->>> get[host|ipnode]byname[2] looked up these IP addresses:
->>> name=ten-3-alias.test.ex address=V4NET.0.0.3
>>> checking addresses for ten-3-alias.test.ex
>>> V4NET.0.0.3 OK
>>> host in "*-2.test.ex : *-3-alias.test.ex"? yes (matched "*-3-alias.test.ex")
>>> sender host name required, to match against ^[^\d]+2
>>> looking up host name for V4NET.0.0.1
>>> IP address lookup yielded "ten-1.test.ex"
-MUNGED: ::1 will be omitted in what follows
->>> get[host|ipnode]byname[2] looked up these IP addresses:
->>> name=ten-1.test.ex address=V4NET.0.0.1
>>> checking addresses for ten-1.test.ex
>>> V4NET.0.0.1 OK
>>> host in "^[^\d]+2"? no (end of list)
>>> sender host name required, to match against ^[^\d]+2
>>> looking up host name for V4NET.0.0.2
>>> IP address lookup yielded "ten-2.test.ex"
-MUNGED: ::1 will be omitted in what follows
->>> get[host|ipnode]byname[2] looked up these IP addresses:
->>> name=ten-2.test.ex address=V4NET.0.0.2
>>> checking addresses for ten-2.test.ex
>>> V4NET.0.0.2 OK
>>> host in "^[^\d]+2"? yes (matched "^[^\d]+2")
>>> sender host name required, to match against lsearch;TESTSUITE/aux-fixed/0064.hosts
>>> looking up host name for V4NET.0.0.1
>>> IP address lookup yielded "ten-1.test.ex"
-MUNGED: ::1 will be omitted in what follows
->>> get[host|ipnode]byname[2] looked up these IP addresses:
->>> name=ten-1.test.ex address=V4NET.0.0.1
>>> checking addresses for ten-1.test.ex
>>> V4NET.0.0.1 OK
>>> host in "lsearch;TESTSUITE/aux-fixed/0064.hosts"? no (end of list)
>>> sender host name required, to match against lsearch;TESTSUITE/aux-fixed/0064.hosts
>>> looking up host name for V4NET.0.0.2
>>> IP address lookup yielded "ten-2.test.ex"
-MUNGED: ::1 will be omitted in what follows
->>> get[host|ipnode]byname[2] looked up these IP addresses:
->>> name=ten-2.test.ex address=V4NET.0.0.2
>>> checking addresses for ten-2.test.ex
>>> V4NET.0.0.2 OK
>>> host in "lsearch;TESTSUITE/aux-fixed/0064.hosts"? yes (matched "lsearch;TESTSUITE/aux-fixed/0064.hosts")
>>> sender host name required, to match against *-1.test.ex
>>> looking up host name for V4NET.0.0.1
>>> IP address lookup yielded "ten-1.test.ex"
-MUNGED: ::1 will be omitted in what follows
->>> get[host|ipnode]byname[2] looked up these IP addresses:
->>> name=ten-1.test.ex address=V4NET.0.0.1
>>> checking addresses for ten-1.test.ex
>>> V4NET.0.0.1 OK
>>> host in "!TESTSUITE/aux-fixed/0066.nothosts : TESTSUITE/aux-var/0066.hostnets"? yes (matched "*-1.test.ex" in TESTSUITE/aux-var/0066.hostnets)
>>> sender host name required, to match against ^ten-1\.test\.ex
>>> looking up host name for V4NET.0.0.1
>>> IP address lookup yielded "ten-1.test.ex"
-MUNGED: ::1 will be omitted in what follows
->>> get[host|ipnode]byname[2] looked up these IP addresses:
->>> name=ten-1.test.ex address=V4NET.0.0.1
>>> checking addresses for ten-1.test.ex
>>> V4NET.0.0.1 OK
>>> host in sender_unqualified_hosts? yes (matched "^ten-1\.test\.ex")
>>> processing "deny"
>>> check hosts = +include_defer : test.again.dns
>>> test.again.dns in dns_again_means_nonexist? no (option unset)
-LOG: DNS lookup of test.again.dns deferred: accepted by +include_defer
+>>> no IP address found for host test.again.dns (during SMTP connection from [V4NET.0.0.13])
+>>> test.again.dns in dns_again_means_nonexist? no (option unset)
+LOG: DNS lookup of "test.again.dns" deferred: accepted by +include_defer
>>> deny: condition test succeeded in ACL "check_recipienta"
>>> end of ACL "check_recipienta": DENY
LOG: H=[V4NET.0.0.13] F=<userx@myhost.test.ex> rejected RCPT <a@test.ex>
>>> processing "accept"
>>> check hosts = test.again.dns : V4NET.0.0.13
>>> test.again.dns in dns_again_means_nonexist? no (option unset)
+>>> no IP address found for host test.again.dns (during SMTP connection from [V4NET.0.0.13])
+>>> test.again.dns in dns_again_means_nonexist? no (option unset)
>>> host in "test.again.dns : V4NET.0.0.13"? list match deferred for test.again.dns
>>> accept: condition test deferred in ACL "check_recipientb"
-LOG: H=[V4NET.0.0.13] F=<userx@test.ex> temporarily rejected RCPT <b@test.ex>
+LOG: H=[V4NET.0.0.13] F=<userx@test.ex> temporarily rejected RCPT <b@test.ex>: DNS lookup of "test.again.dns" deferred
>>> host in hosts_connection_nolog? no (option unset)
>>> host in host_lookup? no (option unset)
>>> host in host_reject_connection? no (option unset)
>>> processing "accept"
>>> check hosts = +ignore_defer : test.again.dns : V4NET.0.0.13
>>> test.again.dns in dns_again_means_nonexist? no (option unset)
->>> DNS lookup of test.again.dns deferred: item ignored by +ignore_defer
+>>> no IP address found for host test.again.dns (during SMTP connection from [V4NET.0.0.13])
+>>> test.again.dns in dns_again_means_nonexist? no (option unset)
+>>> DNS lookup of "test.again.dns" deferred: item ignored by +ignore_defer
>>> host in "+ignore_defer : test.again.dns : V4NET.0.0.13"? yes (matched "V4NET.0.0.13")
>>> accept: condition test succeeded in ACL "check_recipientc"
>>> end of ACL "check_recipientc": ACCEPT
>>> verifying EHLO/HELO argument "ten-1.test.ex"
>>> looking up host name for V4NET.0.0.1
>>> IP address lookup yielded "ten-1.test.ex"
-MUNGED: ::1 will be omitted in what follows
->>> get[host|ipnode]byname[2] looked up these IP addresses:
->>> name=ten-1.test.ex address=V4NET.0.0.1
>>> checking addresses for ten-1.test.ex
>>> V4NET.0.0.1 OK
>>> matched host name
>>> looking up host name for V4NET.0.0.3
>>> IP address lookup yielded "ten-3.test.ex"
>>> alias "ten-3-alias.test.ex"
-MUNGED: ::1 will be omitted in what follows
->>> get[host|ipnode]byname[2] looked up these IP addresses:
->>> name=ten-3.test.ex address=V4NET.0.0.3
>>> checking addresses for ten-3.test.ex
>>> V4NET.0.0.3 OK
-MUNGED: ::1 will be omitted in what follows
->>> get[host|ipnode]byname[2] looked up these IP addresses:
->>> name=ten-3-alias.test.ex address=V4NET.0.0.3
>>> checking addresses for ten-3-alias.test.ex
>>> V4NET.0.0.3 OK
>>> matched host name
>>> matched alias ten-3-alias.test.ex
>>> verifying EHLO/HELO argument "ten-3xtra.test.ex"
>>> getting IP address for ten-3xtra.test.ex
-MUNGED: ::1 will be omitted in what follows
->>> get[host|ipnode]byname[2] looked up these IP addresses:
->>> name=ten-3xtra.test.ex address=V4NET.0.0.3
+>>> ten-3xtra.test.ex in ""? no (end of list)
+>>> ten-3xtra.test.ex in "*"? yes (matched "*")
>>> IP address for ten-3xtra.test.ex matches calling address
+>>> Forward DNS security status: unverified
>>> host in hosts_connection_nolog? no (option unset)
>>> host in host_lookup? no (option unset)
>>> host in host_reject_connection? no (option unset)
>>> verifying EHLO/HELO argument "rhubarb"
>>> looking up host name for V4NET.0.0.1
>>> IP address lookup yielded "ten-1.test.ex"
-MUNGED: ::1 will be omitted in what follows
->>> get[host|ipnode]byname[2] looked up these IP addresses:
->>> name=ten-1.test.ex address=V4NET.0.0.1
>>> checking addresses for ten-1.test.ex
>>> V4NET.0.0.1 OK
>>> getting IP address for rhubarb
->>> no IP address found for host rhubarb (during SMTP connection from (rhubarb) [V4NET.0.0.1])
+>>> rhubarb in ""? no (end of list)
+>>> rhubarb in "*"? yes (matched "*")
LOG: rejected "EHLO rhubarb" from (rhubarb) [V4NET.0.0.1]
>>> host in hosts_connection_nolog? no (option unset)
>>> host in host_lookup? no (option unset)
>>> looking up host name for 99.99.99.99
>>> Test harness: host name lookup returns DEFER
>>> getting IP address for rhubarb
->>> no IP address found for host rhubarb (during SMTP connection from (rhubarb) [99.99.99.99])
+>>> rhubarb in ""? no (end of list)
+>>> rhubarb in "*"? yes (matched "*")
LOG: temporarily rejected "EHLO rhubarb" from (rhubarb) [99.99.99.99]
>>> host in hosts_connection_nolog? no (option unset)
>>> host in host_lookup? no (option unset)
>>> looking up host name for 99.99.99.99
>>> Test harness: host name lookup returns DEFER
>>> getting IP address for rhubarb
->>> no IP address found for host rhubarb (during SMTP connection from (rhubarb) [99.99.99.99])
+>>> rhubarb in ""? no (end of list)
+>>> rhubarb in "*"? yes (matched "*")
>>> require: condition test failed in ACL "rcpt"
>>> end of ACL "rcpt": not OK
LOG: H=(rhubarb) [99.99.99.99] F=<a@b> rejected RCPT <c@d>: helo not verified
>>> end of inline ACL: ACCEPT
>>> host in ignore_fromline_hosts? no (option unset)
>>> using ACL "check_message"
->>> processing "require"
->>> check verify = header_syntax
->>> require: condition test failed in ACL "check_message"
->>> end of ACL "check_message": not OK
+>>> processing "deny"
+>>> check !verify = header_syntax
+>>> check logwrite = acl_verify_message: '$acl_verify_message'
+>>> = acl_verify_message: ''>' missing at end of address: failing address in "Cc:" header is: <abcd@x.y.z'
+LOG: 10HmaY-0005vi-00 acl_verify_message: ''>' missing at end of address: failing address in "Cc:" header is: <abcd@x.y.z'
+>>> deny: condition test succeeded in ACL "check_message"
+>>> end of ACL "check_message": DENY
LOG: 10HmaY-0005vi-00 H=[V4NET.10.10.10] F=<userx@exim.test.ex> rejected after DATA: '>' missing at end of address: failing address in "Cc:" header is: <abcd@x.y.z
>>> host in hosts_connection_nolog? no (option unset)
>>> host in host_lookup? no (option unset)
>>> end of inline ACL: ACCEPT
>>> host in ignore_fromline_hosts? no (option unset)
>>> using ACL "check_message"
->>> processing "require"
->>> check verify = header_syntax
->>> require: condition test failed in ACL "check_message"
->>> end of ACL "check_message": not OK
+>>> processing "deny"
+>>> check !verify = header_syntax
+>>> check logwrite = acl_verify_message: '$acl_verify_message'
+>>> = acl_verify_message: ''>' missing at end of address: failing address in "Cc:" header is: <abcd@x.y.z'
+LOG: 10HmaZ-0005vi-00 acl_verify_message: ''>' missing at end of address: failing address in "Cc:" header is: <abcd@x.y.z'
+>>> deny: condition test succeeded in ACL "check_message"
+>>> end of ACL "check_message": DENY
LOG: 10HmaZ-0005vi-00 H=[V4NET.10.10.10] F=<userx@exim.test.ex> rejected after DATA: '>' missing at end of address: failing address in "Cc:" header is: <abcd@x.y.z
>>> host in hosts_connection_nolog? no (option unset)
>>> host in host_lookup? no (option unset)
>>> end of inline ACL: ACCEPT
>>> host in ignore_fromline_hosts? no (option unset)
>>> using ACL "check_message"
->>> processing "require"
->>> check verify = header_syntax
->>> require: condition test failed in ACL "check_message"
->>> end of ACL "check_message": not OK
+>>> processing "deny"
+>>> check !verify = header_syntax
+>>> check logwrite = acl_verify_message: '$acl_verify_message'
+>>> = acl_verify_message: ''>' missing at end of address: failing address in "Resent-To:" header is: <xyz@a.b.c.d'
+LOG: 10HmbA-0005vi-00 acl_verify_message: ''>' missing at end of address: failing address in "Resent-To:" header is: <xyz@a.b.c.d'
+>>> deny: condition test succeeded in ACL "check_message"
+>>> end of ACL "check_message": DENY
LOG: 10HmbA-0005vi-00 H=[V4NET.10.10.10] F=<userx@exim.test.ex> rejected after DATA: '>' missing at end of address: failing address in "Resent-To:" header is: <xyz@a.b.c.d
>>> host in hosts_connection_nolog? no (option unset)
>>> host in host_lookup? no (option unset)
>>> end of inline ACL: ACCEPT
>>> host in ignore_fromline_hosts? no (option unset)
>>> using ACL "check_message"
->>> processing "require"
->>> check verify = header_syntax
->>> require: condition test failed in ACL "check_message"
->>> end of ACL "check_message": not OK
+>>> processing "deny"
+>>> check !verify = header_syntax
+>>> check logwrite = acl_verify_message: '$acl_verify_message'
+>>> = acl_verify_message: 'unmatched doublequote in local part: failing address in "Cc:" header begins: "abcd@x.y.z (missing quote),\n longlonglonglonglong@long.long.long.long.long.long.long.long,\n listlistlistlistlist@list.list.list.list.list.list.list.list,\n ofofofofofofofofofof@of.of.of.of.of.of.of.of.of.of.of.of.of,\n addressesaddresses@addresses.addresses.addresses.addresses, \n longlonglonglonglong@long.long.long.long.long.long.long.long,\n listlistlistlistlist@list.list.list.list.list.list.list.list,\n ofofofofofofofofofof@of.of.of.of.of.of.of.of.of.of.of.of.of,\n addressesaddresses@addresses.addresses.addresses.addresses, \n longlonglonglonglong@long.long.long.long.long.long.long.long,\n listlistlistlistlist@list.list.list.list.list.list.list.list,\n ofofofofofofofofofof@of.of.of.of.of.of.of.of.of.of.of.of.of,\n addressesaddresses@addresses.addresses.addresses.addresses, \n longlonglonglonglong@long.long.long.long.long.long.long.long,\n listlistlistlistlist@list.list.list.list.list.list.list.list,\n ofofofofofofofofofof@of.of.of.of.of.of.of.of.of.of.of.of.of,\n addressesaddresses@addresses.addre'
+LOG: 10HmbB-0005vi-00 acl_verify_message: 'unmatched doublequote in local part: failing address in "Cc:" header begins: "abcd@x.y.z (missing quote),\n longlonglonglonglong@long.long.long.long.long.long.long.long,\n listlistlistlistlist@list.list.list.list.list.list.list.list,\n ofofofofofofofofofof@of.of.of.of.of.of.of.of.of.of.of.of.of,\n addressesaddresses@addresses.addresses.addresses.addresses, \n longlonglonglonglong@long.long.long.long.long.long.long.long,\n listlistlistlistlist@list.list.list.list.list.list.list.list,\n ofofofofofofofofofof@of.of.of.of.of.of.of.of.of.of.of.of.of,\n addressesaddresses@addresses.addresses.addresses.addresses, \n longlonglonglonglong@long.long.long.long.long.long.long.long,\n listlistlistlistlist@list.list.list.list.list.list.list.list,\n ofofofofofofofofofof@of.of.of.of.of.of.of.of.of.of.of.of.of,\n addressesaddresses@addresses.addresses.addresses.addresses, \n longlonglonglonglong@long.long.long.long.long.long.long.long,\n listlistlistlistlist@list.list.list.list.list.list.list.list,\n ofofofofofofofofofof@of.of.of.of.of.of.of.of.of.of.of.of.of,\n addressesaddresses@addresses.addre'
+>>> deny: condition test succeeded in ACL "check_message"
+>>> end of ACL "check_message": DENY
LOG: 10HmbB-0005vi-00 H=[V4NET.10.10.10] F=<userx@exim.test.ex> rejected after DATA: unmatched doublequote in local part: failing address in "Cc:" header begins: "abcd@x.y.z (missing quote),\n longlonglonglonglong@long.long.long.long.long.long.long.long,\n listlistlistlistlist@list.list.list.list.list.list.list.list,\n ofofofofofofofofofof@of.of.of.of.of.of.of.of.of.of.of.of.of,\n addressesaddresses@addresses.addresses.addresses.addresses, \n longlonglonglonglong@long.long.long.long.long.long.long.long,\n listlistlistlistlist@list.list.list.list.list.list.list.list,\n ofofofofofofofofofof@of.of.of.of.of.of.of.of.of.of.of.of.of,\n addressesaddresses@addresses.addresses.addresses.addresses, \n longlonglonglonglong@long.long.long.long.long.long.long.long,\n listlistlistlistlist@list.list.list.list.list.list.list.list,\n ofofofofofofofofofof@of.of.of.of.of.of.of.of.of.of.of.of.of,\n addressesaddresses@addresses.addresses.addresses.addresses, \n longlonglonglonglong@long.long.long.long.long.long.long.long,\n listlistlistlistlist@list.list.list.list.list.list.list.list,\n ofofofofofofofofofof@of.of.of.of.of.of.of.of.of.of.of.of.of,\n addressesaddresses@addresses.addre
>>> host in hosts_connection_nolog? no (option unset)
>>> host in host_lookup? no (option unset)
>>> end of inline ACL: ACCEPT
>>> host in ignore_fromline_hosts? no (option unset)
>>> using ACL "check_message"
->>> processing "require"
->>> check verify = header_syntax
->>> require: condition test failed in ACL "check_message"
->>> end of ACL "check_message": not OK
+>>> processing "deny"
+>>> check !verify = header_syntax
+>>> check logwrite = acl_verify_message: '$acl_verify_message'
+>>> = acl_verify_message: 'unqualified address not permitted: failing address in "Cc:" header is: <abcd>'
+LOG: 10HmbC-0005vi-00 acl_verify_message: 'unqualified address not permitted: failing address in "Cc:" header is: <abcd>'
+>>> deny: condition test succeeded in ACL "check_message"
+>>> end of ACL "check_message": DENY
LOG: 10HmbC-0005vi-00 H=[V4NET.10.10.10] F=<userx@exim.test.ex> rejected after DATA: unqualified address not permitted: failing address in "Cc:" header is: <abcd>
>>> host in hosts_connection_nolog? no (option unset)
>>> host in host_lookup? no (option unset)
>>> end of inline ACL: ACCEPT
>>> host in ignore_fromline_hosts? no (option unset)
>>> using ACL "check_message"
->>> processing "require"
->>> check verify = header_syntax
->>> require: condition test succeeded in ACL "check_message"
+>>> processing "deny"
+>>> check !verify = header_syntax
+>>> deny: condition test failed in ACL "check_message"
>>> processing "accept"
>>> accept: condition test succeeded in ACL "check_message"
>>> end of ACL "check_message": ACCEPT
>>> sender host name required, to match against *N-99.test.EX
>>> looking up host name for V4NET.0.0.99
>>> IP address lookup yielded "ten-99.test.ex"
-MUNGED: ::1 will be omitted in what follows
->>> get[host|ipnode]byname[2] looked up these IP addresses:
->>> name=ten-99.test.ex address=V4NET.0.0.99
>>> checking addresses for ten-99.test.ex
>>> V4NET.0.0.99 OK
>>> host in sender_unqualified_hosts? yes (matched "*N-99.test.EX")
>>> host in host_lookup? yes (matched "0.0.0.0/0")
>>> looking up host name for V4NET.0.0.1
>>> IP address lookup yielded "ten-1.test.ex"
-MUNGED: ::1 will be omitted in what follows
->>> get[host|ipnode]byname[2] looked up these IP addresses:
->>> name=ten-1.test.ex address=V4NET.0.0.1
>>> checking addresses for ten-1.test.ex
>>> V4NET.0.0.1 OK
>>> host in host_reject_connection? no (option unset)
DNS lookup of 90.99.99.V4NET.in-addr.arpa (PTR) succeeded
IP address lookup yielded "oneback.test.ex"
alias "host1.masq.test.ex"
-using host_fake_gethostbyname for oneback.test.ex (IPv4)
DNS lookup of oneback.test.ex (A) using fakens
DNS lookup of oneback.test.ex (A) succeeded
-MUNGED: ::1 will be omitted in what follows
-get[host|ipnode]byname[2] looked up these IP addresses:
- name=oneback.test.ex address=V4NET.99.99.90
+oneback.test.ex V4NET.99.99.90 mx=-1 sort=xx
checking addresses for oneback.test.ex
+Forward DNS security status: unverified
V4NET.99.99.90 OK
-using host_fake_gethostbyname for host1.masq.test.ex (IPv4)
DNS lookup of host1.masq.test.ex (A) using fakens
DNS lookup of host1.masq.test.ex (A) succeeded
-MUNGED: ::1 will be omitted in what follows
-get[host|ipnode]byname[2] looked up these IP addresses:
- name=host1.masq.test.ex address=V4NET.90.90.90
+host1.masq.test.ex V4NET.90.90.90 mx=-1 sort=xx
checking addresses for host1.masq.test.ex
+Forward DNS security status: unverified
V4NET.90.90.90
no IP address for host1.masq.test.ex matched V4NET.99.99.90
sender_fullhost = oneback.test.ex [V4NET.99.99.90]
>>> message: forced defer
>>> require: condition test deferred in ACL "check_message"
LOG: 10HmaZ-0005vi-00 H=[127.0.0.1] F=<userx@test.ex> temporarily rejected after DATA: all attempts to verify a sender in a header line deferred
+>>> host in hosts_connection_nolog? no (option unset)
+>>> host in host_lookup? no (option unset)
+>>> host in host_reject_connection? no (option unset)
+>>> host in sender_unqualified_hosts? no (option unset)
+>>> host in recipient_unqualified_hosts? no (option unset)
+>>> host in helo_verify_hosts? no (option unset)
+>>> host in helo_try_verify_hosts? no (option unset)
+>>> host in helo_accept_junk_hosts? no (option unset)
+>>> foo.bar in helo_lookup_domains? no (end of list)
+>>> host in dsn_advertise_hosts? no (option unset)
+>>> host in pipelining_advertise_hosts? yes (matched "*")
+>>> host in smtp_accept_max_nonmail_hosts? yes (matched "*")
+>>> foo.bar in helo_lookup_domains? no (end of list)
+>>> host in dsn_advertise_hosts? no (option unset)
+>>> host in pipelining_advertise_hosts? yes (matched "*")
+>>> foo.bar in helo_lookup_domains? no (end of list)
+>>> host in dsn_advertise_hosts? no (option unset)
+>>> host in pipelining_advertise_hosts? yes (matched "*")
+>>> foo.bar in helo_lookup_domains? no (end of list)
+>>> host in dsn_advertise_hosts? no (option unset)
+>>> host in pipelining_advertise_hosts? yes (matched "*")
+>>> foo.bar in helo_lookup_domains? no (end of list)
+>>> host in dsn_advertise_hosts? no (option unset)
+>>> host in pipelining_advertise_hosts? yes (matched "*")
my_smtp transport entered
userx@domain.com
checking status of 127.0.0.1
-127.0.0.1 [127.0.0.1]:1111 status = usable
+127.0.0.1 [127.0.0.1]:1111/ip4.ip4.ip4.ip4 status = usable
delivering 10HmaX-0005vi-00 to 127.0.0.1 [127.0.0.1] (userx@domain.com)
Connecting to 127.0.0.1 [127.0.0.1]:1224 from ip4.ip4.ip4.ip4 ... connected
SMTP<< 220 ESMTP
LOG: PANIC DIE
- Exim configuration error in line 16 of TESTSUITE/test-config:
+ Exim configuration error in line 17 of TESTSUITE/test-config:
missing quote at end of string value for hold_domains
calling lookuphost router
lookuphost router called for userx@test.again.dns
domain = test.again.dns
-Return from DNS lookup of test.again.dns (MX) faked for testing
+DNS lookup of test.again.dns (MX) using fakens
DNS lookup of test.again.dns (MX) gave TRY_AGAIN
test.again.dns in dns_again_means_nonexist? no (option unset)
returning DNS_AGAIN
set transport smtp
finding IP address for test.again.dns
doing DNS lookup
-Return from DNS lookup of test.again.dns (A) faked for testing
+DNS lookup of test.again.dns (A) using fakens
DNS lookup of test.again.dns (A) gave TRY_AGAIN
test.again.dns in dns_again_means_nonexist? no (option unset)
returning DNS_AGAIN
calling lookuphost router
lookuphost router called for userx@test.fail.dns
domain = test.fail.dns
-Return from DNS lookup of test.fail.dns (MX) faked for testing
+DNS lookup of test.fail.dns (MX) using fakens
DNS lookup of test.fail.dns (MX) gave NO_RECOVERY
returning DNS_FAIL
lookuphost router: defer for userx@test.fail.dns
set transport smtp
finding IP address for test.fail.dns
doing DNS lookup
-Return from DNS lookup of test.fail.dns (A) faked for testing
+DNS lookup of test.fail.dns (A) using fakens
DNS lookup of test.fail.dns (A) gave NO_RECOVERY
returning DNS_FAIL
useryz router: defer for usery@test.fail.dns
calling srv router
srv router called for srv@test.again.dns
domain = test.again.dns
-Return from DNS lookup of _smtp._tcp.test.again.dns (SRV) faked for testing
+DNS lookup of _smtp._tcp.test.again.dns (SRV) using fakens
DNS lookup of _smtp._tcp.test.again.dns (SRV) gave TRY_AGAIN
_smtp._tcp.test.again.dns in dns_again_means_nonexist? no (option unset)
returning DNS_AGAIN
calling srv router
srv router called for srv@test.fail.dns
domain = test.fail.dns
-Return from DNS lookup of _smtp._tcp.test.fail.dns (SRV) faked for testing
+DNS lookup of _smtp._tcp.test.fail.dns (SRV) using fakens
DNS lookup of _smtp._tcp.test.fail.dns (SRV) gave NO_RECOVERY
returning DNS_FAIL
test.fail.dns in "test.fail.dns"? yes (matched "test.fail.dns")
DNS_FAIL treated as DNS_NODATA (domain in srv_fail_domains)
-Return from DNS lookup of test.fail.dns (MX) faked for testing
+DNS lookup of test.fail.dns (MX) using fakens
DNS lookup of test.fail.dns (MX) gave NO_RECOVERY
returning DNS_FAIL
test.fail.dns in "test.fail.dns"? yes (matched "test.fail.dns")
DNS_FAIL treated as DNS_NODATA (domain in mx_fail_domains)
-Return from DNS lookup of test.fail.dns (A) faked for testing
+DNS lookup of test.fail.dns (A) using fakens
DNS lookup of test.fail.dns (A) gave NO_RECOVERY
returning DNS_FAIL
srv router: defer for srv@test.fail.dns
>>> host in hosts_connection_nolog? no (option unset)
-LOG: SMTP connection from [192.168.1.2]:1115
+LOG: SMTP connection from [192.168.1.2]:1117
>>> host in host_lookup? no (option unset)
>>> host in host_reject_connection? no (option unset)
>>> host in sender_unqualified_hosts? no (option unset)
>>> host in helo_verify_hosts? no (option unset)
>>> host in helo_try_verify_hosts? no (option unset)
>>> host in helo_accept_junk_hosts? no (option unset)
-LOG: SMTP connection from [192.168.1.2]:1115 closed by QUIT
+LOG: SMTP connection from [192.168.1.2]:1117 closed by QUIT
******** SERVER ********
LOG: PANIC DIE
- Exim configuration error in line 14 of TESTSUITE/test-config:
+ Exim configuration error in line 15 of TESTSUITE/test-config:
macro name too long (maximum is 63 characters)
DSN: envid: NULL ret: 0
DSN: Final recipient: userx@test.ex
DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
LOG: MAIN
Completed
end delivery of 10HmaX-0005vi-00
DSN: envid: NULL ret: 0
DSN: Final recipient: CALLER@test.ex
DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
LOG: MAIN
Completed
end delivery of 10HmaX-0005vi-00
LOG: PANIC DIE
- Exim configuration error in line 26 of TESTSUITE/test-config:
+ Exim configuration error in line 27 of TESTSUITE/test-config:
.include specifies a non-absolute path "non/absolute"
>>> myhost.test.ex in helo_lookup_domains? yes (matched "@")
>>> looking up host name for V4NET.0.0.1
>>> IP address lookup yielded "ten-1.test.ex"
-MUNGED: ::1 will be omitted in what follows
->>> get[host|ipnode]byname[2] looked up these IP addresses:
->>> name=ten-1.test.ex address=V4NET.0.0.1
>>> checking addresses for ten-1.test.ex
>>> V4NET.0.0.1 OK
>>> host in hosts_connection_nolog? no (option unset)
>>> [127.0.0.1] in helo_lookup_domains? yes (matched "@[]")
>>> looking up host name for V4NET.0.0.1
>>> IP address lookup yielded "ten-1.test.ex"
-MUNGED: ::1 will be omitted in what follows
->>> get[host|ipnode]byname[2] looked up these IP addresses:
->>> name=ten-1.test.ex address=V4NET.0.0.1
>>> checking addresses for ten-1.test.ex
>>> V4NET.0.0.1 OK
>>> host in dsn_advertise_hosts? no (option unset)
>>> sender host name required, to match against *.test.ex
>>> looking up host name for V4NET.0.0.1
>>> IP address lookup yielded "ten-1.test.ex"
-MUNGED: ::1 will be omitted in what follows
->>> get[host|ipnode]byname[2] looked up these IP addresses:
->>> name=ten-1.test.ex address=V4NET.0.0.1
>>> checking addresses for ten-1.test.ex
>>> V4NET.0.0.1 OK
>>> host in "*.test.ex"? yes (matched "*.test.ex")
-1999-03-02 09:44:33 Exim configuration error in line 24 of TESTSUITE/test-config:
+1999-03-02 09:44:33 Exim configuration error in line 25 of TESTSUITE/test-config:
bad parameters for retry rule
-1999-03-02 09:44:33 Exim configuration error in line 24 of TESTSUITE/test-config:
+1999-03-02 09:44:33 Exim configuration error in line 25 of TESTSUITE/test-config:
bad parameters for retry rule
-1999-03-02 09:44:33 Exim configuration error in line 24 of TESTSUITE/test-config:
+1999-03-02 09:44:33 Exim configuration error in line 25 of TESTSUITE/test-config:
bad parameters for retry rule
-1999-03-02 09:44:33 Exim configuration error in line 24 of TESTSUITE/test-config:
+1999-03-02 09:44:33 Exim configuration error in line 25 of TESTSUITE/test-config:
bad parameters for retry rule
DSN: envid: NULL ret: 0
DSN: Final recipient: kilos@recurse.test.ex.test.ex
DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
DSN: processing router : r3
DSN: processing successful delivery address: kilos@recurse.test.ex.test.ex
DSN: Sender_address: CALLER@test.ex
DSN: envid: NULL ret: 0
DSN: Final recipient: kilos@recurse.test.ex.test.ex
DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
LOG: MAIN
Completed
end delivery of 10HmaY-0005vi-00
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering ok@localhost
Attempting full verification using callout
-callout cache: no domain record found
-callout cache: no address record found
+callout cache: no domain record found for localhost
+callout cache: no address record found for ok@localhost
interface=NULL port=1224
Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
SMTP<< 220 Server ready
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering ok@localhost
Attempting full verification using callout
-callout cache: found domain record
-callout cache: found address record
+callout cache: found domain record for localhost
+callout cache: found address record for ok@localhost
callout cache: address record is positive
LOG: smtp_connection MAIN
SMTP connection from root closed by QUIT
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering ok@localhost
Attempting full verification using callout
-callout cache: found domain record
-callout cache: address record expired
+callout cache: found domain record for localhost
+callout cache: address record expired for ok@localhost
interface=NULL port=1224
Connecting to 127.0.0.1 [127.0.0.1]:1224 ... failed: Connection refused
LOG: MAIN REJECT
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering bad@localhost
Attempting full verification using callout
-callout cache: found domain record
-callout cache: no address record found
+callout cache: found domain record for localhost
+callout cache: no address record found for bad@localhost
interface=NULL port=1224
Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
SMTP<< 220 Server ready
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering bad@localhost
Attempting full verification using callout
-callout cache: found domain record
-callout cache: found address record
+callout cache: found domain record for localhost
+callout cache: found address record for bad@localhost
callout cache: address record is negative
LOG: MAIN REJECT
H=[V4NET.0.0.1] U=root sender verify fail for <bad@localhost>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering ok@localhost
Attempting full verification using callout
-callout cache: found domain record
-callout cache: address record expired
+callout cache: found domain record for localhost
+callout cache: address record expired for ok@localhost
interface=NULL port=1224
Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
SMTP<< 220 Server ready
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering ok@localhost
Attempting full verification using callout
-callout cache: found domain record
+callout cache: found domain record for localhost
callout cache: domain gave initial rejection, or does not accept HELO or MAIL FROM:<>
LOG: MAIN REJECT
H=[V4NET.0.0.1] U=root sender verify fail for <ok@localhost>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering ok@otherhost
Attempting full verification using callout
-callout cache: no domain record found
-callout cache: no address record found
+callout cache: no domain record found for otherhost
+callout cache: no address record found for ok@otherhost
interface=NULL port=1224
Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
SMTP<< 220 Server ready
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering ok@otherhost
Attempting full verification using callout
-callout cache: found domain record
+callout cache: found domain record for otherhost
callout cache: domain does not accept RCPT TO:<postmaster@domain>
LOG: MAIN REJECT
H=[V4NET.0.0.2] U=root sender verify fail for <ok@otherhost>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering ok@otherhost2
Attempting full verification using callout
-callout cache: no domain record found
-callout cache: no address record found
+callout cache: no domain record found for otherhost2
+callout cache: no address record found for ok@otherhost2
interface=NULL port=1224
Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
SMTP<< 220 Server ready
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering ok@otherhost2
Attempting full verification using callout
-callout cache: found domain record
+callout cache: found domain record for otherhost2
callout cache: domain accepts RCPT TO:<postmaster@domain>
-callout cache: found address record
+callout cache: found address record for ok@otherhost2
callout cache: address record is positive
LOG: smtp_connection MAIN
SMTP connection from root closed by QUIT
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering ok@otherhost3
Attempting full verification using callout
-callout cache: no domain record found
-callout cache: no address record found
+callout cache: no domain record found for otherhost3
+callout cache: no address record found for ok@otherhost3
interface=NULL port=1224
Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
SMTP<< 220 Server ready
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering otherok@otherhost3
Attempting full verification using callout
-callout cache: found domain record
+callout cache: found domain record for otherhost3
callout cache: domain accepts random addresses
LOG: smtp_connection MAIN
SMTP connection from root closed by QUIT
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering ok@otherhost4
Attempting full verification using callout
-callout cache: no domain record found
-callout cache: no address record found
+callout cache: no domain record found for otherhost4
+callout cache: no address record found for ok@otherhost4
interface=NULL port=1224
Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
SMTP<< 220 Server ready
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering ok@otherhost4
Attempting full verification using callout
-callout cache: found domain record
+callout cache: found domain record for otherhost4
callout cache: domain accepts random addresses
LOG: smtp_connection MAIN
SMTP connection from root closed by QUIT
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering ok@otherhost41
Attempting full verification using callout
-callout cache: no domain record found
-callout cache: no address record found
+callout cache: no domain record found for otherhost41
+callout cache: no address record found for ok@otherhost41
interface=NULL port=1224
Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
SMTP<< 220 Server ready
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering ok@otherhost41
Attempting full verification using callout
-callout cache: found domain record
+callout cache: found domain record for otherhost41
callout cache: domain rejects random addresses
callout cache: domain accepts RCPT TO:<postmaster@domain>
-callout cache: found address record
+callout cache: found address record for ok@otherhost41
callout cache: address record is positive
LOG: smtp_connection MAIN
SMTP connection from root closed by QUIT
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering ok@otherhost21
Attempting full verification using callout
-callout cache: no domain record found
-callout cache: no address record found
+callout cache: no domain record found for otherhost21
+callout cache: no address record found for ok@otherhost21
interface=NULL port=1224
Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
SMTP<< 220 Server ready
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering ok2@otherhost21
Attempting full verification using callout
-callout cache: found domain record
+callout cache: found domain record for otherhost21
callout cache: domain accepts RCPT TO:<postmaster@domain>
-callout cache: no address record found
+callout cache: no address record found for ok2@otherhost21
interface=NULL port=1224
Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
SMTP<< 220 Server ready
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering ok@otherhost31
Attempting full verification using callout
-callout cache: no domain record found
-callout cache: no address record found
+callout cache: no domain record found for otherhost31
+callout cache: no address record found for ok@otherhost31
interface=NULL port=1224
Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
SMTP<< 220 Server ready
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering okok@otherhost31
Attempting full verification using callout
-callout cache: found domain record
+callout cache: found domain record for otherhost31
callout cache: domain rejects random addresses
-callout cache: no address record found
+callout cache: no address record found for okok@otherhost31
interface=NULL port=1224
Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
SMTP<< 220 Server ready
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering okokok@otherhost31
Attempting full verification using callout
-callout cache: domain record expired
-callout cache: no address record found
+callout cache: domain record expired for otherhost31
+callout cache: no address record found for okokok@otherhost31
interface=NULL port=1224
Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
SMTP<< 220 Server ready
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering okok@otherhost51
Attempting full verification using callout
-callout cache: no domain record found
-callout cache: no address record found
+callout cache: no domain record found for otherhost51
+callout cache: no address record found for okok@otherhost51
interface=NULL port=1224
Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
SMTP<< 220 Server ready
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering okokok@otherhost52
Attempting full verification using callout
-callout cache: no domain record found
-callout cache: no address record found
+callout cache: no domain record found for otherhost52
+callout cache: no address record found for okokok@otherhost52
interface=NULL port=1224
Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
SMTP<< 220 Server ready
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering abcd@x.y.z
Attempting full verification using callout
-callout cache: no domain record found
-callout cache: no address record found
+callout cache: no domain record found for x.y.z
+callout cache: no address record found for abcd@x.y.z/<somesender@a.domain>
interface=NULL port=1224
Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
SMTP<< 220 Server ready
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering abcd@x.y.z
Attempting full verification using callout
-callout cache: found domain record
-callout cache: no address record found
+callout cache: found domain record for x.y.z
+callout cache: no address record found for abcd@x.y.z
interface=NULL port=1224
Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
SMTP<< 220 Server ready
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering ok@otherhost9
Attempting full verification using callout
-callout cache: no domain record found
-callout cache: no address record found
+callout cache: no domain record found for otherhost9
+callout cache: no address record found for ok@otherhost9
interface=NULL port=1224
Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
SMTP<< 220 Server ready
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering z@test.ex
Attempting full verification using callout
-callout cache: no domain record found
-callout cache: no address record found
+callout cache: no domain record found for test.ex
+callout cache: no address record found for z@test.ex/<postmaster@myhost.test.ex>
interface=NULL port=1224
Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
SMTP<< 220 Server ready
DNS lookup of 97.99.99.V4NET.in-addr.arpa (PTR) succeeded
IP address lookup yielded "x.gov.uk.test.ex"
alias "x.co.uk.test.ex"
-using host_fake_gethostbyname for x.gov.uk.test.ex (IPv4)
DNS lookup of x.gov.uk.test.ex (A) using fakens
DNS lookup of x.gov.uk.test.ex (A) succeeded
-MUNGED: ::1 will be omitted in what follows
-get[host|ipnode]byname[2] looked up these IP addresses:
- name=x.gov.uk.test.ex address=V4NET.99.99.97
+x.gov.uk.test.ex V4NET.99.99.97 mx=-1 sort=xx
checking addresses for x.gov.uk.test.ex
+Forward DNS security status: unverified
V4NET.99.99.97 OK
-using host_fake_gethostbyname for x.co.uk.test.ex (IPv4)
DNS lookup of x.co.uk.test.ex (A) using fakens
DNS lookup of x.co.uk.test.ex (A) succeeded
-MUNGED: ::1 will be omitted in what follows
-get[host|ipnode]byname[2] looked up these IP addresses:
- name=x.co.uk.test.ex address=V4NET.99.99.97
+x.co.uk.test.ex V4NET.99.99.97 mx=-1 sort=xx
checking addresses for x.co.uk.test.ex
+Forward DNS security status: unverified
V4NET.99.99.97 OK
sender_fullhost = x.gov.uk.test.ex [V4NET.99.99.97]
sender_rcvhost = x.gov.uk.test.ex ([V4NET.99.99.97] ident=CALLER)
DSN: envid: NULL ret: 0
DSN: Final recipient: 2@b
DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
LOG: MAIN
Completed
end delivery of 10HmaX-0005vi-00
DSN: envid: NULL ret: 0
DSN: Final recipient: 2@b
DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
LOG: MAIN
Completed
end delivery of 10HmaY-0005vi-00
mailbox TESTSUITE/test-mail/userx is locked
writing to file TESTSUITE/test-mail/userx
writing data block fd=dddd size=sss timeout=0
-process pppp running as transport filter: write=dddd read=dddd
writing data block fd=dddd size=sss timeout=0
-process pppp writing to transport filter
-copying from the filter
-waiting for filter process
-filter process returned 127
-waiting for writing process
-end of filtering transport writing: yield=0
-errno=-24 more_errno=dd
-appendfile yields 10 with errno=-24 more_errno=dd
-t1 transport returned PANIC for userx@test.ex
-LOG: MAIN PANIC
- == userx@test.ex R=r1 T=t1 defer (-24): transport filter process failed (127) while writing to TESTSUITE/test-mail/userx: unable to execute command
+writing data block fd=dddd size=sss timeout=0
+appendfile yields 0 with errno=dd more_errno=dd
+t1 transport returned OK for userx@test.ex
+LOG: MAIN
+ => userx <userx@test.ex> R=r1 T=t1
+LOG: MAIN
+ Completed
+>>>>>>>>>>>>>>>> Exim pid=pppp terminating with rc=0 >>>>>>>>>>>>>>>>
+>>>>>>>>>>>>>>>> Exim pid=pppp terminating with rc=0 >>>>>>>>>>>>>>>>
+Exim version x.yz ....
+configuration file is TESTSUITE/test-config
+admin user
+LOG: MAIN
+ <= CALLER@test.ex U=CALLER P=local S=sss
+Exim version x.yz ....
+configuration file is TESTSUITE/test-config
+trusted user
+admin user
+>>>>>>>>>>>>>>>> Local deliveries >>>>>>>>>>>>>>>>
+--------> userx@test.ex <--------
+direct command:
+ argv[0] = ${if={1}{1}{}{}}
+direct command after expansion:
+ argv[0] =
+appendfile transport entered
+appendfile: mode=600 notify_comsat=0 quota=0 warning=0
+ file=TESTSUITE/test-mail/userx format=unix
+ message_prefix=From ${if def:return_path{$return_path}{MAILER-DAEMON}} ${tod_bsdinbox}\n
+ message_suffix=\n
+ maildir_use_size_file=no
+ locking by lockfile fcntl
+lock name: TESTSUITE/test-mail/userx.lock
+hitch name: TESTSUITE/test-mail/userx.lock.test.ex.dddddddd.pppppppp
+lock file created
+mailbox TESTSUITE/test-mail/userx is locked
+writing to file TESTSUITE/test-mail/userx
+writing data block fd=dddd size=sss timeout=0
+writing data block fd=dddd size=sss timeout=0
+writing data block fd=dddd size=sss timeout=0
+appendfile yields 0 with errno=dd more_errno=dd
+t1 transport returned OK for userx@test.ex
+LOG: MAIN
+ => userx <userx@test.ex> R=r1 T=t1
+LOG: MAIN
+ Completed
>>>>>>>>>>>>>>>> Exim pid=pppp terminating with rc=0 >>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Exim pid=pppp terminating with rc=0 >>>>>>>>>>>>>>>>
>>> host in helo_accept_junk_hosts? no (option unset)
>>> using ACL "connect"
>>> processing "require"
->>> check verify = reverse_host_lookup/defer_ok
->>> require: condition test error in ACL "connect"
-LOG: H=[V4NET.255.255.255] temporarily rejected connection in "connect" ACL: unexpected '/' found in "reverse_host_lookup/defer_ok" (this verify item has no options)
->>> host in hosts_connection_nolog? no (option unset)
->>> host in host_lookup? yes (matched "*")
->>> looking up host name for V4NET.255.255.255
->>> IP address lookup yielded an empty name: treated as non-existent host name
-LOG: no host name found for IP address V4NET.255.255.255
->>> host in host_reject_connection? no (option unset)
->>> host in sender_unqualified_hosts? no (option unset)
->>> host in recipient_unqualified_hosts? no (option unset)
->>> host in helo_verify_hosts? no (option unset)
->>> host in helo_try_verify_hosts? no (option unset)
->>> host in helo_accept_junk_hosts? no (option unset)
->>> using ACL "connect"
->>> processing "require"
>>> check verify = certificate/defer_ok
>>> require: condition test error in ACL "connect"
LOG: H=[V4NET.255.255.255] temporarily rejected connection in "connect" ACL: unexpected '/' found in "certificate/defer_ok" (this verify item has no options)
returned from EXIM_DBOPEN
opened hints database TESTSUITE/spool/db/callout: flags=O_RDWR
dbfn_read: key=remote
-callout cache: found domain record
+callout cache: found domain record for remote
dbfn_read: key=qq@remote
-callout cache: no address record found
+callout cache: no address record found for qq@remote
interface=NULL port=1224
Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
SMTP<< 220 Server ready
returned from EXIM_DBOPEN
opened hints database TESTSUITE/spool/db/callout: flags=O_RDWR
dbfn_read: key=remote
-callout cache: found domain record
+callout cache: found domain record for remote
dbfn_read: key=qq@remote
-callout cache: found address record
+callout cache: found address record for qq@remote
callout cache: address record is negative
----------- end verify ------------
l_message: $acl_verify_message
DSN: envid: NULL ret: 0
DSN: Final recipient: userz@test.ex
DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
DSN: processing router : r2
DSN: processing successful delivery address: usery@test.ex
DSN: Sender_address: CALLER@test.ex
DSN: envid: NULL ret: 0
DSN: Final recipient: usery@test.ex
DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
DSN: processing router : r1
DSN: processing successful delivery address: CALLER@test.ex
DSN: Sender_address: CALLER@test.ex
DSN: envid: NULL ret: 0
DSN: Final recipient: CALLER@test.ex
DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
DSN: processing router : r4
DSN: processing successful delivery address: TESTSUITE/test-mail/junk
DSN: Sender_address: CALLER@test.ex
DSN: envid: NULL ret: 0
DSN: Final recipient: TESTSUITE/test-mail/junk
DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
DSN: processing router : r5
DSN: processing successful delivery address: TESTSUITE/test-mail/junk
DSN: Sender_address: CALLER@test.ex
DSN: envid: NULL ret: 0
DSN: Final recipient: TESTSUITE/test-mail/junk
DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
DSN: processing router : r4
DSN: processing successful delivery address: rd+CALLER@test.ex
DSN: Sender_address: CALLER@test.ex
DSN: envid: NULL ret: 0
DSN: Final recipient: rd+CALLER@test.ex
DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
DSN: processing router : r5
DSN: processing successful delivery address: rd+usery@test.ex
DSN: Sender_address: CALLER@test.ex
DSN: envid: NULL ret: 0
DSN: Final recipient: rd+usery@test.ex
DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
LOG: MAIN
Completed
end delivery of 10HmaX-0005vi-00
DSN: envid: NULL ret: 0
DSN: Final recipient: TESTSUITE/test-mail/junk
DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
DSN: processing router : r1
DSN: processing successful delivery address: userx@test.ex
DSN: Sender_address: CALLER@test.ex
DSN: envid: NULL ret: 0
DSN: Final recipient: userx@test.ex
DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
LOG: MAIN
Completed
end delivery of 10HmaX-0005vi-00
DSN: envid: NULL ret: 0
DSN: Final recipient: sender@test.ex
DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
LOG: MAIN
Completed
end delivery of 10HmaY-0005vi-00
DSN: envid: NULL ret: 0
DSN: Final recipient: >sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex,sender@test.ex, ...
DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
DSN: processing router : r2
DSN: processing successful delivery address: userx@test.ex
DSN: Sender_address: CALLER@test.ex
DSN: envid: NULL ret: 0
DSN: Final recipient: userx@test.ex
DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
LOG: MAIN
Completed
end delivery of 10HmaX-0005vi-00
DSN: envid: NULL ret: 0
DSN: Final recipient: userx@test.ex
DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
LOG: MAIN
Completed
end delivery of 10HmaX-0005vi-00
LOG: PANIC DIE
- Exim configuration error in line 19 of TESTSUITE/test-config:
+ Exim configuration error in line 20 of TESTSUITE/test-config:
absolute value of integer "4000000M" is too large (overflow)
LOG: PANIC DIE
- Exim configuration error in line 19 of TESTSUITE/test-config:
+ Exim configuration error in line 20 of TESTSUITE/test-config:
extra characters follow integer value for check_spool_space
LOG: PANIC DIE
- Exim configuration error in line 20 of TESTSUITE/test-config:
+ Exim configuration error in line 21 of TESTSUITE/test-config:
integer "4000000000.123" is too large (overflow)
LOG: PANIC DIE
- Exim configuration error in line 20 of TESTSUITE/test-config:
+ Exim configuration error in line 21 of TESTSUITE/test-config:
integer "4000000.123" is too large (overflow)
LOG: PANIC DIE
- Exim configuration error in line 22 of TESTSUITE/test-config:
+ Exim configuration error in line 23 of TESTSUITE/test-config:
absolute value of integer "999999999999999999" is too large (overflow)
LOG: PANIC DIE
- Exim configuration error in line 22 of TESTSUITE/test-config:
+ Exim configuration error in line 23 of TESTSUITE/test-config:
absolute value of integer "999999999K" is too large (overflow)
LOG: PANIC DIE
- Exim configuration error in line 22 of TESTSUITE/test-config:
+ Exim configuration error in line 23 of TESTSUITE/test-config:
absolute value of integer "999999M" is too large (overflow)
LOG: PANIC DIE
- Exim configuration error in line 22 of TESTSUITE/test-config:
+ Exim configuration error in line 23 of TESTSUITE/test-config:
extra characters follow integer value for finduser_retries
LOG: PANIC DIE
- Exim configuration error in line 22 of TESTSUITE/test-config:
+ Exim configuration error in line 23 of TESTSUITE/test-config:
integer expected for finduser_retries
LOG: PANIC DIE
- Exim configuration error in line 22 of TESTSUITE/test-config:
+ Exim configuration error in line 23 of TESTSUITE/test-config:
extra characters follow integer value for finduser_retries
>>> calling r1 router
>>> routed by r1 router
>>> local host found for non-MX address
->>> fully qualified name = 127.0.0.1
MUNGED: ::1 will be omitted in what follows
>>> get[host|ipnode]byname[2] looked up these IP addresses:
>>> name=127.0.0.1 address=127.0.0.1
transport: t1
using host_fake_gethostbyname for 127.0.0.1 (IPv4)
local host found for non-MX address
-fully qualified name = 127.0.0.1
MUNGED: ::1 will be omitted in what follows
get[host|ipnode]byname[2] looked up these IP addresses:
name=127.0.0.1 address=127.0.0.1
returned from EXIM_DBOPEN
opened hints database TESTSUITE/spool/db/callout: flags=O_RDWR
dbfn_read: key=y
-callout cache: no domain record found
+callout cache: no domain record found for y
dbfn_read: key=x@y
-callout cache: no address record found
+callout cache: no address record found for x@y
interface=NULL port=1224
Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
SMTP<< 220 server ready
transport: t1
using host_fake_gethostbyname for 127.0.0.1 (IPv4)
local host found for non-MX address
-fully qualified name = 127.0.0.1
MUNGED: ::1 will be omitted in what follows
get[host|ipnode]byname[2] looked up these IP addresses:
name=127.0.0.1 address=127.0.0.1
returned from EXIM_DBOPEN
opened hints database TESTSUITE/spool/db/callout: flags=O_RDWR
dbfn_read: key=y
-callout cache: found domain record
+callout cache: found domain record for y
dbfn_read: key=x@y
-callout cache: found address record
+callout cache: found address record for x@y
callout cache: address record is positive
----------- end verify ------------
sender x@y verified ok
>>> calling r1 router
>>> routed by r1 router
>>> local host found for non-MX address
->>> fully qualified name = 127.0.0.1
MUNGED: ::1 will be omitted in what follows
>>> get[host|ipnode]byname[2] looked up these IP addresses:
>>> name=127.0.0.1 address=127.0.0.1
>>> Attempting full verification using callout
->>> callout cache: found domain record
->>> callout cache: found address record
+>>> callout cache: found domain record for y
+>>> callout cache: found address record for x@y
>>> callout cache: address record is positive
>>> ----------- end verify ------------
>>> accept: condition test succeeded in ACL "mail"
>>> calling r1 router
>>> routed by r1 router
>>> local host found for non-MX address
->>> fully qualified name = 127.0.0.1
MUNGED: ::1 will be omitted in what follows
>>> get[host|ipnode]byname[2] looked up these IP addresses:
>>> name=127.0.0.1 address=127.0.0.1
>>> Attempting full verification using callout
->>> callout cache: no domain record found
->>> callout cache: no address record found
+>>> callout cache: no domain record found for b
+>>> callout cache: no address record found for a@b
>>> interface=NULL port=1224
>>> Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
>>> SMTP<< 220 server ready
>>> calling r1 router
>>> routed by r1 router
>>> local host found for non-MX address
->>> fully qualified name = 127.0.0.1
MUNGED: ::1 will be omitted in what follows
>>> get[host|ipnode]byname[2] looked up these IP addresses:
>>> name=127.0.0.1 address=127.0.0.1
>>> Attempting full verification using callout
->>> callout cache: no domain record found
->>> callout cache: no address record found
+>>> callout cache: no domain record found for q
+>>> callout cache: no address record found for p1@q
>>> interface=NULL port=1224
>>> Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
>>> SMTP<< 220 server ready
uid=EXIM_UID gid=EXIM_GID pid=pppp
LOG: MAIN
exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
-set_process_info: pppp daemon: no queue runs, listening for SMTP on port 1225
+set_process_info: pppp daemon(x.yz): no queue runs, listening for SMTP on port 1225
daemon running with uid=EXIM_UID gid=EXIM_GID euid=EXIM_UID egid=EXIM_GID
Listening...
Exim version x.yz ....
uid=EXIM_UID gid=EXIM_GID pid=pppp
LOG: MAIN
exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 port 1226
-set_process_info: pppp daemon: no queue runs, listening for SMTP on port 1225 port 1226
+set_process_info: pppp daemon(x.yz): no queue runs, listening for SMTP on port 1225 port 1226
daemon running with uid=EXIM_UID gid=EXIM_GID euid=EXIM_UID egid=EXIM_GID
Listening...
Exim version x.yz ....
uid=EXIM_UID gid=EXIM_GID pid=pppp
LOG: MAIN
exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on [127.0.0.1]:1228 port 1225 (IPv4) port 1226 (IPv4)
-set_process_info: pppp daemon: no queue runs, listening for SMTP on [127.0.0.1]:1228 port 1225 (IPv4) port 1226 (IPv4)
+set_process_info: pppp daemon(x.yz): no queue runs, listening for SMTP on [127.0.0.1]:1228 port 1225 (IPv4) port 1226 (IPv4)
daemon running with uid=EXIM_UID gid=EXIM_GID euid=EXIM_UID egid=EXIM_GID
Listening...
Exim version x.yz ....
uid=EXIM_UID gid=EXIM_GID pid=pppp
LOG: MAIN
exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 port 1226 [127.0.0.1]:1228
-set_process_info: pppp daemon: no queue runs, listening for SMTP on port 1225 port 1226 [127.0.0.1]:1228
+set_process_info: pppp daemon(x.yz): no queue runs, listening for SMTP on port 1225 port 1226 [127.0.0.1]:1228
daemon running with uid=EXIM_UID gid=EXIM_GID euid=EXIM_UID egid=EXIM_GID
Listening...
Exim version x.yz ....
uid=EXIM_UID gid=EXIM_GID pid=pppp
LOG: MAIN
exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on [127.0.0.1]:1228 port 1227 (IPv4)
-set_process_info: pppp daemon: no queue runs, listening for SMTP on [127.0.0.1]:1228 port 1227 (IPv4)
+set_process_info: pppp daemon(x.yz): no queue runs, listening for SMTP on [127.0.0.1]:1228 port 1227 (IPv4)
daemon running with uid=EXIM_UID gid=EXIM_GID euid=EXIM_UID egid=EXIM_GID
Listening...
Exim version x.yz ....
uid=EXIM_UID gid=EXIM_GID pid=pppp
LOG: MAIN
exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 port 1226
-set_process_info: pppp daemon: no queue runs, listening for SMTP on port 1225 port 1226
+set_process_info: pppp daemon(x.yz): no queue runs, listening for SMTP on port 1225 port 1226
daemon running with uid=EXIM_UID gid=EXIM_GID euid=EXIM_UID egid=EXIM_GID
Listening...
uid=EXIM_UID gid=EXIM_GID pid=pppp
LOG: MAIN
exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
-set_process_info: pppp daemon: no queue runs, listening for SMTP on port 1225
+set_process_info: pppp daemon(x.yz): no queue runs, listening for SMTP on port 1225
daemon running with uid=EXIM_UID gid=EXIM_GID euid=EXIM_UID egid=EXIM_GID
Listening...
Exim version x.yz ....
uid=EXIM_UID gid=EXIM_GID pid=pppp
LOG: MAIN
exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
-set_process_info: pppp daemon: no queue runs, listening for SMTP on port 1225
+set_process_info: pppp daemon(x.yz): no queue runs, listening for SMTP on port 1225
daemon running with uid=EXIM_UID gid=EXIM_GID euid=EXIM_UID egid=EXIM_GID
Listening...
-1999-03-02 09:44:33 Exim configuration error in line 42 of TESTSUITE/test-config:
+1999-03-02 09:44:33 Exim configuration error in line 43 of TESTSUITE/test-config:
failed to open included configuration file /non/existent
>>> calling r1 router
>>> routed by r1 router
>>> Attempting full verification using callout
->>> callout cache: no domain record found
->>> callout cache: no address record found
+>>> callout cache: no domain record found for ten-1.test.ex
+>>> callout cache: no address record found for x@ten-1.test.ex
>>> cannot callout via null transport
>>> ----------- end verify ------------
>>> accept: condition test deferred in ACL "rcpt"
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering Ok@localhost
Attempting full verification using callout
-callout cache: no domain record found
-callout cache: no address record found
+callout cache: no domain record found for localhost
+callout cache: no address record found for Ok@localhost
interface=NULL port=1224
Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
SMTP<< 220 Server ready
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering Ok@localhost
Attempting full verification using callout
-callout cache: found domain record
-callout cache: found address record
+callout cache: found domain record for localhost
+callout cache: found address record for Ok@localhost
callout cache: address record is positive
LOG: smtp_connection MAIN
SMTP connection from root closed by QUIT
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering NOTok@elsewhere
Attempting full verification using callout
-callout cache: no domain record found
-callout cache: no address record found
+callout cache: no domain record found for elsewhere
+callout cache: no address record found for NOTok@elsewhere
interface=NULL port=1224
Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
SMTP<< 220 Server ready
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering NOTok2@elsewhere
Attempting full verification using callout
-callout cache: found domain record
-callout cache: no address record found
+callout cache: found domain record for elsewhere
+callout cache: no address record found for NOTok2@elsewhere
interface=NULL port=1224
Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
SMTP<< 220 Server ready
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering r11@two.test.ex
Attempting full verification using callout
-callout cache: found domain record
-callout cache: no address record found
+callout cache: found domain record for two.test.ex
+callout cache: no address record found for r11@two.test.ex
interface=NULL port=1224
Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
SMTP<< 220 Server ready
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Considering r11@two.test.ex
Attempting full verification using callout
-callout cache: found domain record
-callout cache: no address record found
+callout cache: found domain record for two.test.ex
+callout cache: no address record found for r11@two.test.ex
interface=NULL port=1224
Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected
SMTP timeout
DSN: envid: NULL ret: 0
DSN: Final recipient: userx@test.ex
DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
LOG: MAIN
Completed
end delivery of 10HmaX-0005vi-00
-1999-03-02 09:44:33 ACL for QUIT returned ERROR: "deny" is not allowed in a QUIT or not-QUIT ACL
+1999-03-02 09:44:33 ACL for QUIT returned ERROR: QUIT or not-QUIT teplevel ACL may not fail ('deny' verb used incorrectly)
>>> host in host_lookup? yes (matched "*")
>>> looking up host name for V6NET:1234:0005:0006:0007:0008:0abc:000d
>>> IP address lookup yielded "test3.ipv6.test.ex"
-MUNGED: ::1 will be omitted in what follows
->>> get[host|ipnode]byname[2] looked up these IP addresses:
->>> name=test3.ipv6.test.ex address=V6NET:1234:5:6:7:8:abc:d
>>> checking addresses for test3.ipv6.test.ex
>>> V6NET:1234:5:6:7:8:abc:d OK
>>> host in host_reject_connection? no (option unset)
uid=EXIM_UID gid=EXIM_GID pid=pppp
LOG: MAIN
exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 (IPv6 and IPv4)
-set_process_info: pppp daemon: no queue runs, listening for SMTP on port 1225 (IPv6 and IPv4)
+set_process_info: pppp daemon(x.yz): no queue runs, listening for SMTP on port 1225 (IPv6 and IPv4)
daemon running with uid=EXIM_UID gid=EXIM_GID euid=EXIM_UID egid=EXIM_GID
Listening...
Exim version x.yz ....
uid=EXIM_UID gid=EXIM_GID pid=pppp
LOG: MAIN
exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 (IPv6 and IPv4) port 1226 (IPv6 and IPv4)
-set_process_info: pppp daemon: no queue runs, listening for SMTP on port 1225 (IPv6 and IPv4) port 1226 (IPv6 and IPv4)
+set_process_info: pppp daemon(x.yz): no queue runs, listening for SMTP on port 1225 (IPv6 and IPv4) port 1226 (IPv6 and IPv4)
daemon running with uid=EXIM_UID gid=EXIM_GID euid=EXIM_UID egid=EXIM_GID
Listening...
Exim version x.yz ....
uid=EXIM_UID gid=EXIM_GID pid=pppp
LOG: MAIN
exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 (IPv6 and IPv4) port 1226 (IPv6 and IPv4) [127.0.0.1]:1228
-set_process_info: pppp daemon: no queue runs, listening for SMTP on port 1225 (IPv6 and IPv4) port 1226 (IPv6 and IPv4) [127.0.0.1]:1228
+set_process_info: pppp daemon(x.yz): no queue runs, listening for SMTP on port 1225 (IPv6 and IPv4) port 1226 (IPv6 and IPv4) [127.0.0.1]:1228
daemon running with uid=EXIM_UID gid=EXIM_GID euid=EXIM_UID egid=EXIM_GID
Listening...
Exim version x.yz ....
uid=EXIM_UID gid=EXIM_GID pid=pppp
LOG: MAIN
exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 (IPv6 and IPv4) port 1226 (IPv6 and IPv4) [127.0.0.1]:1228
-set_process_info: pppp daemon: no queue runs, listening for SMTP on port 1225 (IPv6 and IPv4) port 1226 (IPv6 and IPv4) [127.0.0.1]:1228
+set_process_info: pppp daemon(x.yz): no queue runs, listening for SMTP on port 1225 (IPv6 and IPv4) port 1226 (IPv6 and IPv4) [127.0.0.1]:1228
daemon running with uid=EXIM_UID gid=EXIM_GID euid=EXIM_UID egid=EXIM_GID
Listening...
Exim version x.yz ....
uid=EXIM_UID gid=EXIM_GID pid=pppp
LOG: MAIN
exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on [ip6:ip6:ip6:ip6:ip6:ip6:ip6:ip6]:1225 [ip6:ip6:ip6:ip6:ip6:ip6:ip6:ip6]:1226
-set_process_info: pppp daemon: no queue runs, listening for SMTP on [ip6:ip6:ip6:ip6:ip6:ip6:ip6:ip6]:1225 [ip6:ip6:ip6:ip6:ip6:ip6:ip6:ip6]:1226
+set_process_info: pppp daemon(x.yz): no queue runs, listening for SMTP on [ip6:ip6:ip6:ip6:ip6:ip6:ip6:ip6]:1225 [ip6:ip6:ip6:ip6:ip6:ip6:ip6:ip6]:1226
daemon running with uid=EXIM_UID gid=EXIM_GID euid=EXIM_UID egid=EXIM_GID
Listening...
Exim version x.yz ....
uid=EXIM_UID gid=EXIM_GID pid=pppp
LOG: MAIN
exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1227 (IPv6 and IPv4) [127.0.0.1]:1228
-set_process_info: pppp daemon: no queue runs, listening for SMTP on port 1227 (IPv6 and IPv4) [127.0.0.1]:1228
+set_process_info: pppp daemon(x.yz): no queue runs, listening for SMTP on port 1227 (IPv6 and IPv4) [127.0.0.1]:1228
daemon running with uid=EXIM_UID gid=EXIM_GID euid=EXIM_UID egid=EXIM_GID
Listening...
Exim version x.yz ....
uid=EXIM_UID gid=EXIM_GID pid=pppp
LOG: MAIN
exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on [127.0.0.1]:1227 [127.0.0.1]:1225
-set_process_info: pppp daemon: no queue runs, listening for SMTP on [127.0.0.1]:1227 [127.0.0.1]:1225
+set_process_info: pppp daemon(x.yz): no queue runs, listening for SMTP on [127.0.0.1]:1227 [127.0.0.1]:1225
daemon running with uid=EXIM_UID gid=EXIM_GID euid=EXIM_UID egid=EXIM_GID
Listening...
Exim version x.yz ....
uid=EXIM_UID gid=EXIM_GID pid=pppp
LOG: MAIN
exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 (IPv6 and IPv4) port 1226 (IPv4)
-set_process_info: pppp daemon: no queue runs, listening for SMTP on port 1225 (IPv6 and IPv4) port 1226 (IPv4)
+set_process_info: pppp daemon(x.yz): no queue runs, listening for SMTP on port 1225 (IPv6 and IPv4) port 1226 (IPv4)
daemon running with uid=EXIM_UID gid=EXIM_GID euid=EXIM_UID egid=EXIM_GID
Listening...
SMTP>> STARTTLS
SMTP<< 220 TLS go ahead
LOG: MAIN
- SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
+ [127.0.0.1] SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
LOG: MAIN
- SSL verify error: certificate name mismatch: "/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock"
-
+ [127.0.0.1] SSL verify error: certificate name mismatch: "/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock"
SMTP>> EHLO helo.data.changed
SMTP<< 250-myhost.test.ex Hello helo.data.changed [127.0.0.1]
250-SIZE 52428800
SMTP>> STARTTLS
SMTP<< 220 TLS go ahead
LOG: MAIN
- SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
+ [127.0.0.1] SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
LOG: MAIN
- SSL verify error: certificate name mismatch: "/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock"
-
+ [127.0.0.1] SSL verify error: certificate name mismatch: "/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock"
SMTP>> EHLO helo.data.changed
SMTP<< 250-myhost.test.ex Hello helo.data.changed [127.0.0.1]
250-SIZE 52428800
SMTP>> STARTTLS
SMTP<< 220 TLS go ahead
LOG: MAIN
- SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
+ [ip4.ip4.ip4.ip4] SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock
LOG: MAIN
- SSL verify error: certificate name mismatch: "/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock"
-
+ [ip4.ip4.ip4.ip4] SSL verify error: certificate name mismatch: "/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock"
SMTP>> EHLO myhost.test.ex
SMTP<< 250-myhost.test.ex Hello the.local.host.name [ip4.ip4.ip4.ip4]
250-SIZE 52428800
configuration file is TESTSUITE/test-config
trusted user
admin user
+DSN: r0 propagating DSN
DSN: r1 propagating DSN
DSN: r2 propagating DSN
seeking password data for user "CALLER": using cached result
Considering test.ex@test.ex
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
routing test.ex@test.ex
+--------> r0 router <--------
+local_part=test.ex domain=test.ex
+checking senders
+address match test: subject=CALLER@myhost.test.ex pattern=a@shorthost.test.ex
+CALLER@myhost.test.ex in "a@shorthost.test.ex"? no (end of list)
+r0 router skipped: senders mismatch
--------> r1 router <--------
local_part=test.ex domain=test.ex
checking domains
Considering unknown@test.ex
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
routing unknown@test.ex
+--------> r0 router <--------
+local_part=unknown domain=test.ex
+checking senders
+address match test: subject=CALLER@myhost.test.ex pattern=a@shorthost.test.ex
+CALLER@myhost.test.ex in "a@shorthost.test.ex"? no (end of list)
+r0 router skipped: senders mismatch
--------> r1 router <--------
local_part=unknown domain=test.ex
checking domains
transport: local_delivery
search_tidyup called
>>>>>>>>>>>>>>>> Exim pid=pppp terminating with rc=0 >>>>>>>>>>>>>>>>
+Exim version x.yz ....
+configuration file is TESTSUITE/test-config
+trusted user
+admin user
+search_tidyup called
+search_tidyup called
+search_open: dnsdb "NULL"
+search_find: file="NULL"
+ key="a=shorthost.test.ex" partial=-1 affix=NULL starflags=0
+LRU list:
+internal_search_find: file="NULL"
+ type=dnsdb key="a=shorthost.test.ex"
+database lookup required for a=shorthost.test.ex
+dnsdb key: shorthost.test.ex
+lookup yielded: 127.0.0.1
+search_open: dnsdb "NULL"
+ cached open
+search_find: file="NULL"
+ key="a=shorthost.test.ex" partial=-1 affix=NULL starflags=0
+LRU list:
+internal_search_find: file="NULL"
+ type=dnsdb key="a=shorthost.test.ex"
+cached data used for lookup of a=shorthost.test.ex
+lookup yielded: 127.0.0.1
+search_open: dnsdb "NULL"
+ cached open
+search_find: file="NULL"
+ key="a=shorthost.test.ex" partial=-1 affix=NULL starflags=0
+LRU list:
+internal_search_find: file="NULL"
+ type=dnsdb key="a=shorthost.test.ex"
+cached data found but past valid time; database lookup required for a=shorthost.test.ex
+dnsdb key: shorthost.test.ex
+lookup yielded: 127.0.0.1
+LOG: MAIN
+ <= a@shorthost.test.ex U=CALLER P=local S=sss
+created log directory TESTSUITE/spool/log
+search_tidyup called
+>>>>>>>>>>>>>>>> Exim pid=pppp terminating with rc=0 >>>>>>>>>>>>>>>>
+
+******** SERVER ********
+Exim version x.yz ....
+configuration file is TESTSUITE/test-config
+trusted user
+admin user
+ppppp daemon_smtp_port overridden by -oX:
+ppppp <: 1225
+ppppp listening on all interfaces (IPv4) port 1225
+ppppp pid written to TESTSUITE/spool/exim-daemon.pid
+ppppp LOG: MAIN
+ppppp exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+ppppp daemon running with uid=EXIM_UID gid=EXIM_GID euid=EXIM_UID egid=EXIM_GID
+ppppp Listening...
+ppppp Connection request from 127.0.0.1 port sssss
+ppppp 1 SMTP accept process running
+ppppp Listening...
+ppppp Process ppppp is handling incoming connection from [127.0.0.1]
+ppppp Process ppppp is ready for new message
+ppppp DNS list check: rbl.test.ex/V4NET.11.12.14
+ppppp new DNS lookup for 14.12.11.V4NET.rbl.test.ex
+ppppp DNS lookup for 14.12.11.V4NET.rbl.test.ex succeeded (yielding 127.0.0.2)
+ppppp => that means V4NET.11.12.14 is listed at rbl.test.ex
+ppppp DNS list check: rbl.test.ex/V4NET.11.12.14
+ppppp using result of previous DNS lookup
+ppppp DNS lookup for 14.12.11.V4NET.rbl.test.ex succeeded (yielding 127.0.0.2)
+ppppp => that means V4NET.11.12.14 is listed at rbl.test.ex
+ppppp DNS list check: rbl.test.ex/V4NET.11.12.14
+ppppp cached data found but past valid time; new DNS lookup for 14.12.11.V4NET.rbl.test.ex
+ppppp DNS lookup for 14.12.11.V4NET.rbl.test.ex succeeded (yielding 127.0.0.2)
+ppppp => that means V4NET.11.12.14 is listed at rbl.test.ex
+ppppp LOG: MAIN
+ppppp <= a@shorthost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmaX-0005vi-00@myhost.test.ex
+ppppp Process ppppp is ready for new message
+ppppp LOG: smtp_connection MAIN
+ppppp SMTP connection from localhost (myhost.test.ex) [127.0.0.1] closed by QUIT
+ppppp child ppppp ended: status=0x0
+ppppp normal exit, 0
+ppppp 0 SMTP accept processes now running
+ppppp Listening...
type=dnsdb key=">:defer_never,mxh=cioce.test.again.dns"
database lookup required for >:defer_never,mxh=cioce.test.again.dns
dnsdb key: cioce.test.again.dns
-Return from DNS lookup of cioce.test.again.dns (MX) faked for testing
+DNS lookup of cioce.test.again.dns (MX) using fakens
DNS lookup of cioce.test.again.dns (MX) gave TRY_AGAIN
cioce.test.again.dns in dns_again_means_nonexist? yes (matched "*")
cioce.test.again.dns is in dns_again_means_nonexist: returning DNS_NOMATCH
DNS lookup of ip4-reverse.in-addr.arpa (PTR) using fakens
DNS lookup of ip4-reverse.in-addr.arpa (PTR) succeeded
IP address lookup yielded "the.local.host.name"
-using host_fake_gethostbyname for the.local.host.name (IPv4)
DNS lookup of the.local.host.name (A) using fakens
DNS lookup of the.local.host.name (A) succeeded
-MUNGED: ::1 will be omitted in what follows
-get[host|ipnode]byname[2] looked up these IP addresses:
- name=the.local.host.name address=ip4.ip4.ip4.ip4
+local host found for non-MX address
+the.local.host.name ip4.ip4.ip4.ip4 mx=-1 sort=xx
checking addresses for the.local.host.name
+Forward DNS security status: unverified
ip4.ip4.ip4.ip4 OK
sender_fullhost = the.local.host.name [ip4.ip4.ip4.ip4]
sender_rcvhost = the.local.host.name ([ip4.ip4.ip4.ip4])
+using host_fake_gethostbyname for cioce.test.again.dns (IPv4)
+DNS lookup of cioce.test.again.dns (A) using fakens
+DNS lookup of cioce.test.again.dns (A) gave TRY_AGAIN
cioce.test.again.dns in dns_again_means_nonexist? yes (matched "*")
-cioce.test.again.dns is in dns_again_means_nonexist: returning HOST_FIND_FAILED
+cioce.test.again.dns is in dns_again_means_nonexist: returning DNS_NOMATCH
+get[host|ipnode]byname[2] returned 1 (HOST_NOT_FOUND)
+no IP address found for host cioce.test.again.dns (during SMTP connection from the.local.host.name [ip4.ip4.ip4.ip4])
+LOG: host_lookup_failed MAIN
+ no IP address found for host cioce.test.again.dns (during SMTP connection from the.local.host.name [ip4.ip4.ip4.ip4])
failed to find IP address for cioce.test.again.dns: item ignored by +ignore_unknown
host in "+ignore_unknown : *.cioce.test.again.dns : cioce.test.again.dns : "? no (end of list)
accept: condition test failed in ACL "rcpt"
DSN: envid: NULL ret: 0
DSN: Final recipient: userx@myhost.test.ex
DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
LOG: MAIN
Completed
end delivery of 10HmaX-0005vi-00
-1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: aveserver: unable to scan file TESTSUITE/spool/scan/10HmaX-0005vi-00/10HmaX-0005vi-00.eml (Responded: 5xx defer).
-1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: aveserver: unavailable (Responded: nothing).
-1999-03-02 09:44:33 10HmaZ-0005vi-00 malware acl condition: aveserver: unavailable (Responded: nothing).
-1999-03-02 09:44:33 10HmbA-0005vi-00 malware acl condition: aveserver: unable to scan file TESTSUITE/spool/scan/10HmbA-0005vi-00/10HmbA-0005vi-00.eml (Responded: 5xx defer).
+1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: aveserver TESTSUITE/eximdir/aveserver_sock : unable to scan file TESTSUITE/spool/scan/10HmaX-0005vi-00/10HmaX-0005vi-00.eml (Responded: 5xx defer).
+1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: aveserver TESTSUITE/eximdir/aveserver_sock : unavailable (Responded: nothing).
+1999-03-02 09:44:33 10HmaZ-0005vi-00 malware acl condition: aveserver TESTSUITE/eximdir/aveserver_sock : unavailable (Responded: nothing).
+1999-03-02 09:44:33 10HmbA-0005vi-00 malware acl condition: aveserver TESTSUITE/eximdir/aveserver_sock : unable to scan file TESTSUITE/spool/scan/10HmbA-0005vi-00/10HmbA-0005vi-00.eml (Responded: 5xx defer).
-1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: fsecure: unable to read answer 0 (Connection timed out)
-1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: fsecure: unable to read answer 0 (Connection timed out)
+1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: fsecure TESTSUITE/eximdir/fsec_sock : unable to read answer 0 (Connection timed out)
+1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: fsecure TESTSUITE/eximdir/fsec_sock : unable to read answer 0 (Connection timed out)
-1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: sophie: scanner reported error
-1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: sophie: unable to read from UNIX socket (TESTSUITE/eximdir/sophie_sock)
-1999-03-02 09:44:33 10HmaZ-0005vi-00 malware acl condition: sophie: unable to read from UNIX socket (TESTSUITE/eximdir/sophie_sock)
+1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: sophie TESTSUITE/eximdir/sophie_sock : scanner reported error
+1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: sophie TESTSUITE/eximdir/sophie_sock : unable to read from UNIX socket (TESTSUITE/eximdir/sophie_sock)
+1999-03-02 09:44:33 10HmaZ-0005vi-00 malware acl condition: sophie TESTSUITE/eximdir/sophie_sock : unable to read from UNIX socket (TESTSUITE/eximdir/sophie_sock)
-1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: clamd: ClamAV returned: scanned_file_name: 666 ERROR
-1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: clamd: unable to read from socket (Connection timed out)
-1999-03-02 09:44:33 10HmaZ-0005vi-00 malware acl condition: clamd: unable to read from socket (Connection timed out)
+1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: clamd TESTSUITE/eximdir/clam_sock : ClamAV returned: scanned_file_name: 666 ERROR
+1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: clamd TESTSUITE/eximdir/clam_sock : unable to read from socket (Connection timed out)
+1999-03-02 09:44:33 10HmaZ-0005vi-00 malware acl condition: clamd TESTSUITE/eximdir/clam_sock : unable to read from socket (Connection timed out)
-1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: avast: invalid response from scanner: 'blah [E]'
-1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: avast: timeout from scanner
-1999-03-02 09:44:33 10HmaZ-0005vi-00 malware acl condition: avast: timeout from scanner
+1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: avast TESTSUITE/eximdir/avast_sock : invalid response from scanner: 'blah [E]'
+1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: avast TESTSUITE/eximdir/avast_sock : timeout from scanner
+1999-03-02 09:44:33 10HmaZ-0005vi-00 malware acl condition: avast TESTSUITE/eximdir/avast_sock : timeout from scanner
-1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: cmdline: unable to read from scanner (TESTSUITE/aux-fixed/4007.script -o pause3 TESTSUITE/spool/scan/10HmaX-0005vi-00 2>&1): Connection timed out
-1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: cmdline: unable to read from scanner (TESTSUITE/aux-fixed/4007.script -o pause3 TESTSUITE/spool/scan/10HmaY-0005vi-00 2>&1): Connection timed out
+1999-03-02 09:44:33 10HmaX-0005vi-00 malware acl condition: cmdline : unable to read from scanner (TESTSUITE/aux-fixed/4007.script -o pause3 TESTSUITE/spool/scan/10HmaX-0005vi-00 2>&1): Connection timed out
+1999-03-02 09:44:33 10HmaY-0005vi-00 malware acl condition: cmdline : unable to read from scanner (TESTSUITE/aux-fixed/4007.script -o pause3 TESTSUITE/spool/scan/10HmaY-0005vi-00 2>&1): Connection timed out
DSN: envid: NULL ret: 0
DSN: Final recipient: TESTSUITE/test-mail
DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
DSN: processing router : r1
DSN: processing successful delivery address: userx@test.ex
DSN: Sender_address: CALLER@test.ex
DSN: envid: NULL ret: 0
DSN: Final recipient: userx@test.ex
DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
LOG: MAIN
Completed
end delivery of 10HmaX-0005vi-00
looking for maildirsize in TESTSUITE/test-mail/nofile
TESTSUITE/test-mail/nofile/maildirsize does not exist: recalculating
MUNGED: the check_dir_size lines have been sorted to ensure consistency
-check_dir_size: dir=TESTSUITE/test-mail/nofile/cur sum=0 count=0
-check_dir_size: dir=TESTSUITE/test-mail/nofile/new sum=0 count=0
+check_dir_size: dir=TESTSUITE/test-mail/nofile/cur sum=0 count=dd
+check_dir_size: dir=TESTSUITE/test-mail/nofile/new sum=0 count=dd
skipping TESTSUITE/test-mail/nofile/tmp: dir_regex does not match
maildir_compute_size: path=TESTSUITE/test-mail/nofile
sum=0 filecount=0 timestamp=ddddddd
DSN: envid: NULL ret: 0
DSN: Final recipient: nofile@test.ex
DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
LOG: MAIN
Completed
end delivery of 10HmaX-0005vi-00
cached quota is out of date: recalculating
quota=500 cached_quota=50 filecount_quota=0 cached_quota_filecount=2
MUNGED: the check_dir_size lines have been sorted to ensure consistency
-check_dir_size: dir=TESTSUITE/test-mail/userx/cur sum=0 count=0
-check_dir_size: dir=TESTSUITE/test-mail/userx/new sum=0 count=0
+check_dir_size: dir=TESTSUITE/test-mail/userx/cur sum=0 count=dd
+check_dir_size: dir=TESTSUITE/test-mail/userx/new sum=0 count=dd
skipping TESTSUITE/test-mail/userx/maildirsize: dir_regex does not match
skipping TESTSUITE/test-mail/userx/tmp: dir_regex does not match
maildir_compute_size: path=TESTSUITE/test-mail/userx
DSN: envid: NULL ret: 0
DSN: Final recipient: userx@test.ex
DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
LOG: MAIN
Completed
end delivery of 10HmaY-0005vi-00
looking for maildirsize in TESTSUITE/test-mail/userx
TESTSUITE/test-mail/userx/maildirsize does not exist: recalculating
MUNGED: the check_dir_size lines have been sorted to ensure consistency
-check_dir_size: dir=TESTSUITE/test-mail/userx/cur sum=0 count=0
-check_dir_size: dir=TESTSUITE/test-mail/userx/new sum=0 count=0
+check_dir_size: dir=TESTSUITE/test-mail/userx/cur sum=0 count=dd
+check_dir_size: dir=TESTSUITE/test-mail/userx/new sum=0 count=dd
skipping TESTSUITE/test-mail/userx/tmp: dir_regex does not match
maildir_compute_size: path=TESTSUITE/test-mail/userx
sum=0 filecount=0 timestamp=ddddddd
DSN: envid: NULL ret: 0
DSN: Final recipient: userx@test.ex
DSN: Remote SMTP server supports DSN: 0
-DSN: *** NOT SENDING DSN SUCCESS Message ***
+DSN: not sending DSN success message
LOG: MAIN
Completed
end delivery of 10HmaX-0005vi-00
+++ /dev/null
-Exim version x.yz ....
-configuration file is TESTSUITE/test-config
-admin user
-LOG: smtp_connection MAIN
- SMTP connection from CALLER
-using ACL "ar"
-processing "accept"
-check control = cutthrough_delivery
-check logwrite = rcpt for $local_part@$domain
- = rcpt for userx@domain.com
-LOG: MAIN
- rcpt for userx@domain.com
-created log directory TESTSUITE/spool/log
-accept: condition test succeeded in ACL "ar"
-end of ACL "ar": ACCEPT
------------ start cutthrough setup ------------
-Connecting to 127.0.0.1 [127.0.0.1]:1224 from ip4.ip4.ip4.ip4 ... connected
- SMTP<< 220 ESMTP
- SMTP>> EHLO myhost.test.ex
- SMTP<< 250 OK
- SMTP>> MAIL FROM:<CALLER@myhost.test.ex>
- SMTP<< 250 Sender OK
- SMTP>> RCPT TO:<userx@domain.com>
- SMTP<< 250 Recipient OK
------------ end cutthrough setup ------------
-processing "accept"
-accept: condition test succeeded in inline ACL
-end of inline ACL: ACCEPT
- SMTP>> DATA
- SMTP<< 354 Send data
------------ start cutthrough headers send -----------
-added header line(s):
-X-hdr-rtr-new: +++
----
------------ done cutthrough headers send ------------
- SMTP>> .
- SMTP<< 250 OK
-LOG: MAIN
- >> userx@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
- SMTP>> QUIT
------------ cutthrough shutdown (delivered) ------------
-LOG: MAIN
- <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss
-LOG: MAIN
- Completed
-LOG: smtp_connection MAIN
- SMTP connection from CALLER closed by QUIT
->>>>>>>>>>>>>>>> Exim pid=pppp terminating with rc=0 >>>>>>>>>>>>>>>>
-Exim version x.yz ....
-configuration file is TESTSUITE/test-config
-admin user
-LOG: smtp_connection MAIN
- SMTP connection from CALLER
-using ACL "ar"
-processing "accept"
-check control = cutthrough_delivery
-check logwrite = rcpt for $local_part@$domain
- = rcpt for userz@domain.com
-LOG: MAIN
- rcpt for userz@domain.com
-accept: condition test succeeded in ACL "ar"
-end of ACL "ar": ACCEPT
------------ start cutthrough setup ------------
-Connecting to 127.0.0.1 [127.0.0.1]:1224 from ip4.ip4.ip4.ip4 ... connected
- SMTP<< 220 SMTP only spoken here
- SMTP>> EHLO myhost.test.ex
- SMTP<< 550 Not here, mate
- SMTP>> HELO myhost.test.ex
- SMTP<< 250 OK
- SMTP>> MAIL FROM:<CALLER@myhost.test.ex>
- SMTP<< 250 Sender OK
- SMTP>> RCPT TO:<userz@domain.com>
- SMTP<< 250 Recipient OK
------------ end cutthrough setup ------------
-processing "accept"
-accept: condition test succeeded in inline ACL
-end of inline ACL: ACCEPT
- SMTP>> DATA
- SMTP<< 354 Send data
------------ start cutthrough headers send -----------
-added header line(s):
-X-hdr-rtr-new: +++
----
------------ done cutthrough headers send ------------
- SMTP>> .
- SMTP<< 250 OK
-LOG: MAIN
- >> userz@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
- SMTP>> QUIT
------------ cutthrough shutdown (delivered) ------------
-LOG: MAIN
- <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss
-LOG: MAIN
- Completed
-LOG: smtp_connection MAIN
- SMTP connection from CALLER closed by QUIT
->>>>>>>>>>>>>>>> Exim pid=pppp terminating with rc=0 >>>>>>>>>>>>>>>>
-Exim version x.yz ....
-configuration file is TESTSUITE/test-config
-admin user
-LOG: smtp_connection MAIN
- SMTP connection from CALLER
-using ACL "ar"
-processing "accept"
-check control = cutthrough_delivery
-check logwrite = rcpt for $local_part@$domain
- = rcpt for usery@domain.com
-LOG: MAIN
- rcpt for usery@domain.com
-accept: condition test succeeded in ACL "ar"
-end of ACL "ar": ACCEPT
------------ start cutthrough setup ------------
-Connecting to 127.0.0.1 [127.0.0.1]:1224 from ip4.ip4.ip4.ip4 ... connected
- SMTP<< 220 ESMTP
- SMTP>> EHLO myhost.test.ex
- SMTP<< 250 OK
- SMTP>> MAIL FROM:<CALLER@myhost.test.ex>
- SMTP<< 250 Sender OK
- SMTP>> RCPT TO:<usery@domain.com>
- SMTP<< 250 Recipient OK
------------ end cutthrough setup ------------
-using ACL "ar"
-processing "accept"
-check control = cutthrough_delivery
-check logwrite = rcpt for $local_part@$domain
- = rcpt for userx@domain.com
-LOG: MAIN
- rcpt for userx@domain.com
-accept: condition test succeeded in ACL "ar"
-end of ACL "ar": ACCEPT
- SMTP>> QUIT
------------ cutthrough shutdown (more than one recipient) ------------
-LOG: MAIN
- <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss
-LOG: smtp_connection MAIN
- SMTP connection from CALLER closed by QUIT
->>>>>>>>>>>>>>>> Exim pid=pppp terminating with rc=0 >>>>>>>>>>>>>>>>
-Exim version x.yz ....
-configuration file is TESTSUITE/test-config
-trusted user
-admin user
->>>>>>>>>>>>>>>> Remote deliveries >>>>>>>>>>>>>>>>
---------> usery@domain.com <--------
-smtp transport entered
- usery@domain.com
- userx@domain.com
-checking status of 127.0.0.1
-127.0.0.1 [127.0.0.1]:1111 status = usable
-delivering 10HmaZ-0005vi-00 to 127.0.0.1 [127.0.0.1] (usery@domain.com, ...)
-Connecting to 127.0.0.1 [127.0.0.1]:1224 from ip4.ip4.ip4.ip4 ... connected
- SMTP<< 220 ESMTP
- SMTP>> EHLO myhost.test.ex
- SMTP<< 250 OK
-not using PIPELINING
-use_dsn=0
- SMTP>> MAIL FROM:<CALLER@myhost.test.ex>
- SMTP<< 250 Sender OK
- SMTP>> RCPT TO:<usery@domain.com>
- SMTP<< 250 Recipient OK
- SMTP>> RCPT TO:<userx@domain.com>
- SMTP<< 250 Recipient OK
- SMTP>> DATA
- SMTP<< 354 Send data
- SMTP>> writing message and terminating "."
-added header line(s):
-X-hdr-rtr-new: +++
----
-writing data block fd=dddd size=sss timeout=300
- SMTP<< 250 OK
-ok=1 send_quit=1 send_rset=0 continue_more=0 yield=0 first_address is NULL
-transport_check_waiting entered
- sequence=1 local_max=500 global_max=-1
-no messages waiting for 127.0.0.1
- SMTP>> QUIT
-Leaving smtp transport
-LOG: MAIN
- => usery@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
-LOG: MAIN
- -> userx@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
-LOG: MAIN
- Completed
->>>>>>>>>>>>>>>> Exim pid=pppp terminating with rc=0 >>>>>>>>>>>>>>>>
-Exim version x.yz ....
-configuration file is TESTSUITE/test-config
-admin user
-LOG: smtp_connection MAIN
- SMTP connection from CALLER
-using ACL "ar"
-processing "accept"
-check control = cutthrough_delivery
-check logwrite = rcpt for $local_part@$domain
- = rcpt for userx@domain.com
-LOG: MAIN
- rcpt for userx@domain.com
-accept: condition test succeeded in ACL "ar"
-end of ACL "ar": ACCEPT
------------ start cutthrough setup ------------
-Connecting to 127.0.0.1 [127.0.0.1]:1224 from ip4.ip4.ip4.ip4 ... connected
- SMTP<< 220 ESMTP
- SMTP>> EHLO myhost.test.ex
- SMTP<< 250 OK
- SMTP>> MAIL FROM:<CALLER@myhost.test.ex>
- SMTP<< 250 Sender OK
- SMTP>> RCPT TO:<userx@domain.com>
- SMTP<< 250 Recipient OK
------------ end cutthrough setup ------------
-processing "accept"
-accept: condition test succeeded in inline ACL
-end of inline ACL: ACCEPT
- SMTP>> DATA
- SMTP<< 354 Send data
------------ start cutthrough headers send -----------
-removed header line:
-X-hdr-rtr: qqq
----
-added header line(s):
-X-hdr-rtr-new: +++
----
-added header line:
-X-hdr-tpt-new: new
----
------------ done cutthrough headers send ------------
- SMTP>> .
- SMTP<< 250 OK
-LOG: MAIN
- >> userx@domain.com R=all T=smtp H=127.0.0.1 [127.0.0.1] C="250 OK"
- SMTP>> QUIT
------------ cutthrough shutdown (delivered) ------------
-LOG: MAIN
- <= CALLER@myhost.test.ex U=CALLER P=local-esmtp S=sss
-LOG: MAIN
- Completed
-LOG: smtp_connection MAIN
- SMTP connection from CALLER closed by QUIT
->>>>>>>>>>>>>>>> Exim pid=pppp terminating with rc=0 >>>>>>>>>>>>>>>>
> mask: 0.0.0.0/0
> Failed: missing mask value in "192.168.10.206"
> Failed: "a.b.c.d" is not an IP address
+> ipv6denorm: 0000:0000:0000:0000:0000:0000:0000:0001
+> ipv6denorm: fe00:0000:0000:0000:0000:0000:0000:0001
+> ipv6denorm: 0000:0000:0000:0000:0000:ffff:c0a8:0001
+> ipv6denorm: fe80:0000:0000:0000:0000:0000:c0a8:0001
+> ipv6norm: ::1
+> ipv6norm: 2a00::
+> ipv6norm: 2a00::1
+> ipv6norm: 2a00:eadf::1:0
+> ipv6norm: 2a00:eadf:0:1::
+> ipv6norm: 2a00::
+> ipv6norm: 2a00:2:3:4:5:6:7:8
> nhash: 19 0/61
> lc/uc: the quick BROWN FOX
> length: The quick abc
>
> true
>
+> # Environment access
+>
+> CALLER
+> correct
+>
>
> escape: B7·F2ò
>
> yes
> match_address: no
>
+> -be Sender host name and address etc, all unset
> -oMa sender_host_address =
> sender_host_port = 0
> -oMaa sender_host_authenticated =
> -oMs sender_host_name =
> -oMt sender_ident = CALLER
>
+> -be Sender host name and address etc, all set except host name.
> -oMa sender_host_address = V4NET.0.0.1
> sender_host_port = 1234
> -oMaa sender_host_authenticated = AAA
> -oMr received_protocol = special
> -oMt sender_ident = me
>
+> -be Sender host name explicitly set
> -oMa sender_host_address = V4NET.0.0.1
> sender_host_port = 1234
> -oMs sender_host_name = my.host.name
>
+> be Sender host name lookup fails (V4NET.11.12.13 is not reverse registered)
> -oMs sender_host_name =
> host_lookup_failed = 1
>
+> -be Sender host name and protocol set by Sendmail-compatible option
> -p received_protocol = special
> -p sender_host_name = host.name
>
+> -be Sender host name and address etc, all set except host name
> -oMa sender_host_address = V4NET.0.0.1
> sender_host_port = 1234
> -oMaa sender_host_authenticated = AAA
550 Administrative prohibition\r
221 myhost.test.ex closing connection\r
+**** SMTP testing session as if from host V4NET.99.99.96
+**** but without any ident (RFC 1413) callback.
+**** This is not for real!
+
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250 OK\r
+451 Temporary local problem - please try later\r
+221 myhost.test.ex closing connection\r
+
+**** SMTP testing session as if from host V4NET.99.99.96
+**** but without any ident (RFC 1413) callback.
+**** This is not for real!
+
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250 OK\r
+250 Accepted\r
+221 myhost.test.ex closing connection\r
+
**** SMTP testing session as if from host 29.29.29.29
**** but without any ident (RFC 1413) callback.
**** This is not for real!
250 OK\r
250 Accepted\r
354 Enter message, ending with "." on a line by itself\r
-250 OK id=10HmbC-0005vi-00\r
+250 OK id=10HmbD-0005vi-00\r
221 myhost.test.ex closing connection\r
220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
250 OK\r
250 OK\r
250 Accepted\r
354 Enter message, ending with "." on a line by itself\r
-250 OK id=10HmbD-0005vi-00\r
+550 Administrative prohibition\r
+221 myhost.test.ex closing connection\r
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbE-0005vi-00\r
221 myhost.test.ex closing connection\r
220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
250 OK\r
250 OK\r
250 Accepted\r
354 Enter message, ending with "." on a line by itself\r
-250 OK id=10HmbE-0005vi-00\r
+250 OK id=10HmbF-0005vi-00\r
221 myhost.test.ex closing connection\r
**** SMTP testing session as if from host 10.0.0.0
250 OK\r
250 Accepted\r
354 Enter message, ending with "." on a line by itself\r
-250 OK id=10HmbF-0005vi-00\r
+250 OK id=10HmbG-0005vi-00\r
221 myhost.test.ex closing connection\r
220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
250 OK\r
250 Accepted\r
354 Enter message, ending with "." on a line by itself\r
-250 OK id=10HmbG-0005vi-00\r
+250 OK id=10HmbH-0005vi-00\r
221 myhost.test.ex closing connection\r
220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
250 OK\r
xx@domain1
router = domainlist, transport = smtp
- host ten-1.test.ex [V4NET.0.0.1]
+ host ten-1.test.ex [V4NET.0.0.1]
xx@route1.ex
router = domainlist, transport = smtp
- host ten-2.test.ex [V4NET.0.0.2]
+ host ten-2.test.ex [V4NET.0.0.2]
xx@domain3
router = domainlist, transport = smtp
- host ten-3.test.ex [V4NET.0.0.3]
+ host ten-3.test.ex [V4NET.0.0.3]
xxx@ten-1.test.ex
router = lookuphost, transport = smtp
- host ten-1.test.ex [V4NET.0.0.1]
+ host ten-1.test.ex [V4NET.0.0.1]
xxx@ten-2.test.ex is undeliverable: Unrouteable address
host ten-1.test.ex [V4NET.0.0.1] MX=5
myhost.test.ex@mxt1.test.ex
router = self, transport = remote_smtp
- host myhost.test.ex [V4NET.10.10.10]
+ host myhost.test.ex [V4NET.10.10.10]
xx@mxt1.test.ex
router = self2, transport = remote_smtp
- host myhost.test.ex [V4NET.10.10.10]
+ host myhost.test.ex [V4NET.10.10.10]
xx@not.exist is undeliverable: Unrouteable address
router = select, transport = dummy
XYZ@ten-1.test.ex
router = manual, transport = dummy
- host ten-1.test.ex [V4NET.0.0.1]
+ host ten-1.test.ex [V4NET.0.0.1]
xyz@ten-1.test.ex is undeliverable: unrouteable mail domain "ten-1.test.ex"
first failed = time last try = time2 next try = time2 + 900
T:thisloop.test.ex:999 dd 65 Connection refused
first failed = time last try = time2 next try = time2 + 900
++++++++++++++++++++++++++++
+ R:mxt2.test.ex -32 0 all relevant MX records point to non-existent hosts
+first failed = time last try = time2 next try = time2 + 1800
+ R:nonexist -32 0 lookup of host "nonexist.test.ex" failed in all router
+first failed = time last try = time2 next try = time2 + 1800
+ T:thishost.test.ex:127.0.0.1:999 dd 65 Connection refused
+first failed = time last try = time2 next try = time2 + 900
+ T:thishost.test.ex:999 dd 65 Connection refused
+first failed = time last try = time2 next try = time2 + 900
+ T:thisloop.test.ex:127.0.0.1:999 dd 65 Connection refused
+first failed = time last try = time2 next try = time2 + 900
+ T:thisloop.test.ex:ip4.ip4.ip4.ip4:999 dd 65 Connection refused
+first failed = time last try = time2 next try = time2 + 900
+ T:thisloop.test.ex:999 dd 65 Connection refused
+first failed = time last try = time2 next try = time2 + 900
Retry rule: *.star.ex * F,3d,10m;
Retry rule: lsearch*@;TESTSUITE/aux-fixed/0099.rlist * F,1d,3m;
Retry rule: !*.not.ex * F,2d,15m;
Retry rule: * * G,1d,1m,1.5;
Retry rule: * * G,2d,2m,1.5;
Retry rule: * * F,1w5d,2h30m;
+Retry rule: * * F,1w3d,30m;
354 Enter message, ending with "." on a line by itself\r
451 Temporary local problem - please try later\r
221 the.local.host.name closing connection\r
+
+**** SMTP testing session as if from host 127.0.0.1
+**** but without any ident (RFC 1413) callback.
+**** This is not for real!
+
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello foo.bar [127.0.0.1]\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250 HELP\r
+250 OK\r
+250 Reset OK\r
+250-the.local.host.name Hello foo.bar [127.0.0.1]\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250 HELP\r
+250 OK\r
+250 Reset OK\r
+250-the.local.host.name Hello foo.bar [127.0.0.1]\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250 HELP\r
+250 OK\r
+250 Reset OK\r
+250-the.local.host.name Hello foo.bar [127.0.0.1]\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250 HELP\r
+250 OK\r
+250 Reset OK\r
+250-the.local.host.name Hello foo.bar [127.0.0.1]\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250 HELP\r
+250 OK\r
+221 the.local.host.name closing connection\r
condition =
debug_print =
no_disable_logging
+dnssec_request_domains =
+dnssec_require_domains =
domains =
driver = accept
no_dsn_lasthop
host ten-1.test.ex [V4NET.0.0.1] MX=5
myhost.test.ex@mxt1.test.ex
router = self, transport = remote_smtp
- host myhost.test.ex [V4NET.10.10.10]
+ host myhost.test.ex [V4NET.10.10.10]
xx@mxt1.test.ex
router = self2, transport = remote_smtp
- host myhost.test.ex [V4NET.10.10.10]
+ host myhost.test.ex [V4NET.10.10.10]
xx@not.exist is undeliverable: Unrouteable address
ff@mxt1.test.ex is undeliverable: lowest numbered MX record points to local host
fff@mxt1.test.ex is undeliverable: lookup of host "fff" failed in fail router
abcd@test.again.dns cannot be resolved at this time: host lookup did not complete
abcd@ten-1.test.ex
router = lookuphost, transport = smtp
- host ten-1.test.ex [V4NET.0.0.1]
+ host ten-1.test.ex [V4NET.0.0.1]
usery@test.again.dns cannot be resolved at this time: host lookup for test.again.dns did not complete (DNS timeout?)
userz@test.again.dns cannot be resolved at this time: host lookup for test.again.dns did not complete (DNS timeout?)
xyz@ten-1.test.ex
router = lookuphost, transport = smtp
- host ten-1.test.ex [V4NET.0.0.1]
+ host ten-1.test.ex [V4NET.0.0.1]
userx@test.fail.dns cannot be resolved at this time: host lookup did not complete
abcd@test.fail.dns cannot be resolved at this time: host lookup did not complete
abcd@ten-1.test.ex
router = lookuphost, transport = smtp
- host ten-1.test.ex [V4NET.0.0.1]
+ host ten-1.test.ex [V4NET.0.0.1]
usery@test.fail.dns cannot be resolved at this time: host lookup for test.fail.dns did not complete (DNS timeout?)
userz@test.fail.dns cannot be resolved at this time: host lookup for test.fail.dns did not complete (DNS timeout?)
xyz@ten-1.test.ex
router = lookuphost, transport = smtp
- host ten-1.test.ex [V4NET.0.0.1]
+ host ten-1.test.ex [V4NET.0.0.1]
userx@nonexist.test.ex is undeliverable: Unrouteable address
abcd@nonexist.test.ex is undeliverable: Unrouteable address
abcd@ten-1.test.ex
router = lookuphost, transport = smtp
- host ten-1.test.ex [V4NET.0.0.1]
+ host ten-1.test.ex [V4NET.0.0.1]
usery@nonexist.test.ex cannot be resolved at this time: lookup of host "nonexist.test.ex" failed in useryz router
userz@nonexist.test.ex cannot be resolved at this time: lookup of host "nonexist.test.ex" failed in useryz router
xyz@ten-1.test.ex
router = lookuphost, transport = smtp
- host ten-1.test.ex [V4NET.0.0.1]
+ host ten-1.test.ex [V4NET.0.0.1]
srv@test.again.dns cannot be resolved at this time: host lookup did not complete
srv@test.fail.dns cannot be resolved at this time: host lookup did not complete
userx@other2.test.ex
router = lookuphost, transport = smtp
- host other2.test.ex [V4NET.12.3.1]
+ host other2.test.ex [V4NET.12.3.1]
userx@ten-5-6.test.ex
router = domainlist, transport = smtp
- host ten-5-6.test.ex [V4NET.0.0.5]
+ host ten-5-6.test.ex [V4NET.0.0.5]
userx@other2.test.ex
router = lookuphost2, transport = smtp
- host other2.test.ex [V4NET.12.3.1]
+ host other2.test.ex [V4NET.12.3.1]
userx@ten-5-6.test.ex
router = domainlist, transport = smtp
- host ten-5-6.test.ex [V4NET.0.0.5]
+ host ten-5-6.test.ex [V4NET.0.0.5]
userx@mxt7.test.ex
router = lookuphost, transport = smtp
host ten-3.test.ex [V4NET.0.0.3] MX=6
host ten-3.test.ex [V4NET.0.0.3] MX=7
userx@eximtesthost.test.ex
router = lookuphost2, transport = smtp
- host eximtesthost.test.ex [ip4.ip4.ip4.ip4]
+ host eximtesthost.test.ex [ip4.ip4.ip4.ip4]
userx@localhost is undeliverable: Unrouteable address
userx@mxt10.test.ex is undeliverable: all relevant MX records point to non-existent hosts
userx@mxt11.test.ex is undeliverable: all relevant MX records point to non-existent hosts
x@x
router = others, transport = smtp2
- host V4NET.0.0.3 [V4NET.0.0.3]
- host V4NET.0.0.2 [V4NET.0.0.2]
- host V4NET.0.0.1 [V4NET.0.0.1]
+ host V4NET.0.0.3 [V4NET.0.0.3]
+ host V4NET.0.0.2 [V4NET.0.0.2]
+ host V4NET.0.0.1 [V4NET.0.0.1]
x@y
router = others, transport = smtp2
- host V4NET.0.0.1 [V4NET.0.0.1]
- host V4NET.0.0.2 [V4NET.0.0.2]
- host V4NET.0.0.3 [V4NET.0.0.3]
+ host V4NET.0.0.1 [V4NET.0.0.1]
+ host V4NET.0.0.2 [V4NET.0.0.2]
+ host V4NET.0.0.3 [V4NET.0.0.3]
x@z
router = others, transport = smtp2
- host V4NET.0.0.3 [V4NET.0.0.3]
- host V4NET.0.0.2 [V4NET.0.0.2]
- host V4NET.0.0.1 [V4NET.0.0.1]
+ host V4NET.0.0.3 [V4NET.0.0.3]
+ host V4NET.0.0.2 [V4NET.0.0.2]
+ host V4NET.0.0.1 [V4NET.0.0.1]
x@batch
router = batched, transport = smtp2
- host V4NET.0.0.3 [V4NET.0.0.3]
- host V4NET.0.0.2 [V4NET.0.0.2]
- host V4NET.0.0.1 [V4NET.0.0.1]
- host V4NET.0.0.4 [V4NET.0.0.4]
- host V4NET.0.0.5 [V4NET.0.0.5]
- host V4NET.0.0.6 [V4NET.0.0.6]
- host V4NET.0.0.7 [V4NET.0.0.7]
+ host V4NET.0.0.3 [V4NET.0.0.3]
+ host V4NET.0.0.2 [V4NET.0.0.2]
+ host V4NET.0.0.1 [V4NET.0.0.1]
+ host V4NET.0.0.4 [V4NET.0.0.4]
+ host V4NET.0.0.5 [V4NET.0.0.5]
+ host V4NET.0.0.6 [V4NET.0.0.6]
+ host V4NET.0.0.7 [V4NET.0.0.7]
y@batch
router = batched, transport = smtp2
- host V4NET.0.0.2 [V4NET.0.0.2]
- host V4NET.0.0.1 [V4NET.0.0.1]
- host V4NET.0.0.3 [V4NET.0.0.3]
- host V4NET.0.0.6 [V4NET.0.0.6]
- host V4NET.0.0.4 [V4NET.0.0.4]
- host V4NET.0.0.5 [V4NET.0.0.5]
- host V4NET.0.0.7 [V4NET.0.0.7]
+ host V4NET.0.0.2 [V4NET.0.0.2]
+ host V4NET.0.0.1 [V4NET.0.0.1]
+ host V4NET.0.0.3 [V4NET.0.0.3]
+ host V4NET.0.0.6 [V4NET.0.0.6]
+ host V4NET.0.0.4 [V4NET.0.0.4]
+ host V4NET.0.0.5 [V4NET.0.0.5]
+ host V4NET.0.0.7 [V4NET.0.0.7]
z@batch
router = batched, transport = smtp2
- host V4NET.0.0.1 [V4NET.0.0.1]
- host V4NET.0.0.3 [V4NET.0.0.3]
- host V4NET.0.0.2 [V4NET.0.0.2]
- host V4NET.0.0.5 [V4NET.0.0.5]
- host V4NET.0.0.4 [V4NET.0.0.4]
- host V4NET.0.0.6 [V4NET.0.0.6]
- host V4NET.0.0.7 [V4NET.0.0.7]
+ host V4NET.0.0.1 [V4NET.0.0.1]
+ host V4NET.0.0.3 [V4NET.0.0.3]
+ host V4NET.0.0.2 [V4NET.0.0.2]
+ host V4NET.0.0.5 [V4NET.0.0.5]
+ host V4NET.0.0.4 [V4NET.0.0.4]
+ host V4NET.0.0.6 [V4NET.0.0.6]
+ host V4NET.0.0.7 [V4NET.0.0.7]
x@batch2
router = batched, transport = smtp2
- host V4NET.0.0.1 [V4NET.0.0.1]
- host V4NET.0.0.2 [V4NET.0.0.2]
- host V4NET.0.0.3 [V4NET.0.0.3]
- host V4NET.0.0.4 [V4NET.0.0.4]
- host V4NET.0.0.5 [V4NET.0.0.5]
- host V4NET.0.0.6 [V4NET.0.0.6]
- host V4NET.0.0.7 [V4NET.0.0.7]
+ host V4NET.0.0.1 [V4NET.0.0.1]
+ host V4NET.0.0.2 [V4NET.0.0.2]
+ host V4NET.0.0.3 [V4NET.0.0.3]
+ host V4NET.0.0.4 [V4NET.0.0.4]
+ host V4NET.0.0.5 [V4NET.0.0.5]
+ host V4NET.0.0.6 [V4NET.0.0.6]
+ host V4NET.0.0.7 [V4NET.0.0.7]
y@batch2
router = batched, transport = smtp2
- host V4NET.0.0.1 [V4NET.0.0.1]
- host V4NET.0.0.2 [V4NET.0.0.2]
- host V4NET.0.0.3 [V4NET.0.0.3]
- host V4NET.0.0.4 [V4NET.0.0.4]
- host V4NET.0.0.5 [V4NET.0.0.5]
- host V4NET.0.0.6 [V4NET.0.0.6]
- host V4NET.0.0.7 [V4NET.0.0.7]
+ host V4NET.0.0.1 [V4NET.0.0.1]
+ host V4NET.0.0.2 [V4NET.0.0.2]
+ host V4NET.0.0.3 [V4NET.0.0.3]
+ host V4NET.0.0.4 [V4NET.0.0.4]
+ host V4NET.0.0.5 [V4NET.0.0.5]
+ host V4NET.0.0.6 [V4NET.0.0.6]
+ host V4NET.0.0.7 [V4NET.0.0.7]
x@batch3
router = batched2, transport = smtp2
- host V4NET.0.0.1 [V4NET.0.0.1]
- host V4NET.0.0.2 [V4NET.0.0.2]
- host V4NET.0.0.3 [V4NET.0.0.3]
- host V4NET.0.0.4 [V4NET.0.0.4]
- host V4NET.0.0.5 [V4NET.0.0.5]
- host V4NET.0.0.6 [V4NET.0.0.6]
- host V4NET.0.0.7 [V4NET.0.0.7]
+ host V4NET.0.0.1 [V4NET.0.0.1]
+ host V4NET.0.0.2 [V4NET.0.0.2]
+ host V4NET.0.0.3 [V4NET.0.0.3]
+ host V4NET.0.0.4 [V4NET.0.0.4]
+ host V4NET.0.0.5 [V4NET.0.0.5]
+ host V4NET.0.0.6 [V4NET.0.0.6]
+ host V4NET.0.0.7 [V4NET.0.0.7]
y@batch3
router = batched2, transport = smtp2
- host V4NET.0.0.1 [V4NET.0.0.1]
- host V4NET.0.0.2 [V4NET.0.0.2]
- host V4NET.0.0.3 [V4NET.0.0.3]
- host V4NET.0.0.4 [V4NET.0.0.4]
- host V4NET.0.0.5 [V4NET.0.0.5]
- host V4NET.0.0.6 [V4NET.0.0.6]
- host V4NET.0.0.7 [V4NET.0.0.7]
+ host V4NET.0.0.1 [V4NET.0.0.1]
+ host V4NET.0.0.2 [V4NET.0.0.2]
+ host V4NET.0.0.3 [V4NET.0.0.3]
+ host V4NET.0.0.4 [V4NET.0.0.4]
+ host V4NET.0.0.5 [V4NET.0.0.5]
+ host V4NET.0.0.6 [V4NET.0.0.6]
+ host V4NET.0.0.7 [V4NET.0.0.7]
x@batch4
router = batched2, transport = smtp2
- host V4NET.0.0.1 [V4NET.0.0.1]
- host V4NET.0.0.2 [V4NET.0.0.2]
- host V4NET.0.0.3 [V4NET.0.0.3]
- host V4NET.0.0.5 [V4NET.0.0.5]
- host V4NET.0.0.4 [V4NET.0.0.4]
- host V4NET.0.0.6 [V4NET.0.0.6]
- host V4NET.0.0.7 [V4NET.0.0.7]
+ host V4NET.0.0.1 [V4NET.0.0.1]
+ host V4NET.0.0.2 [V4NET.0.0.2]
+ host V4NET.0.0.3 [V4NET.0.0.3]
+ host V4NET.0.0.5 [V4NET.0.0.5]
+ host V4NET.0.0.4 [V4NET.0.0.4]
+ host V4NET.0.0.6 [V4NET.0.0.6]
+ host V4NET.0.0.7 [V4NET.0.0.7]
y@batch4
router = batched2, transport = smtp2
- host V4NET.0.0.2 [V4NET.0.0.2]
- host V4NET.0.0.1 [V4NET.0.0.1]
- host V4NET.0.0.3 [V4NET.0.0.3]
- host V4NET.0.0.5 [V4NET.0.0.5]
- host V4NET.0.0.6 [V4NET.0.0.6]
- host V4NET.0.0.4 [V4NET.0.0.4]
- host V4NET.0.0.7 [V4NET.0.0.7]
+ host V4NET.0.0.2 [V4NET.0.0.2]
+ host V4NET.0.0.1 [V4NET.0.0.1]
+ host V4NET.0.0.3 [V4NET.0.0.3]
+ host V4NET.0.0.5 [V4NET.0.0.5]
+ host V4NET.0.0.6 [V4NET.0.0.6]
+ host V4NET.0.0.4 [V4NET.0.0.4]
+ host V4NET.0.0.7 [V4NET.0.0.7]
userx@bdomain1
router = r3, transport = smtp2
- host ipv4.ipv4.ipv4.ipv4 [ipv4.ipv4.ipv4.ipv4]
+ host ipv4.ipv4.ipv4.ipv4 [ipv4.ipv4.ipv4.ipv4]
host 127.0.0.1 [127.0.0.1]
- host the.local.host.name [ip4.ip4.ip4.ip4]
+ host the.local.host.name [ip4.ip4.ip4.ip4]
userx@bdomain2
router = r3, transport = smtp2
- host the.local.host.name [ip4.ip4.ip4.ip4]
+ host the.local.host.name [ip4.ip4.ip4.ip4]
host 127.0.0.1 [127.0.0.1]
- host ipv4.ipv4.ipv4.ipv4 [ipv4.ipv4.ipv4.ipv4]
+ host ipv4.ipv4.ipv4.ipv4 [ipv4.ipv4.ipv4.ipv4]
userx@bdomain3
router = r3, transport = smtp2
- host ipv4.ipv4.ipv4.ipv4 [ipv4.ipv4.ipv4.ipv4]
+ host ipv4.ipv4.ipv4.ipv4 [ipv4.ipv4.ipv4.ipv4]
host 127.0.0.1 [127.0.0.1]
- host the.local.host.name [ip4.ip4.ip4.ip4]
+ host the.local.host.name [ip4.ip4.ip4.ip4]
******** SERVER ********
Listening on port 1224 ...
250 Recipient OK
DATA
354 Send message
-Line without end
+Line-without-end
.
250 OK
QUIT
End of script
Listening on port 1224 ...
Connection request from [127.0.0.1]
+220 Connected OK
+End of script
+Listening on port 1224 ...
+Connection request from [127.0.0.1]
550 Go away
QUIT
250 OK
220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
221 myhost.test.ex closing connection\r
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbB-0005vi-00\r
+221 myhost.test.ex closing connection\r
userx@localhost
router = rrr, transport = local
- host a.host.name
+ host a.host.name
userx@localhost verified
userx@localhost
router = rrr, transport = local
- host a.host.name
+ host a.host.name
userx@localhost
router = rrr, transport = local
- host a.host.name
+ host a.host.name
userx@smtp
router = sss, transport = smtp
- host 127.0.0.1 [127.0.0.1]
+ host 127.0.0.1 [127.0.0.1]
Listening on port 1413 ...
Connection request from [127.0.0.1]
<999 , 25
->999 , 25 : USERID : UNIX :ab\rcd
+>999 , 25 : USERID : UNIX :ab\x0dcd
End of script
Listening on port 1413 ...
Connection request from [127.0.0.1]
QUIT
250 OK
End of script
+Listening on port 1224 ...
+Connection request from [127.0.0.1]
+220 ESMTP
+EHLO myhost.test.ex
+250-OK
+250 HELP
+MAIL FROM:<CALLER@test.ex>
+250 Sender OK
+RCPT TO:<b@test.ex>
+250 Recipient OK
+DATA
+354 Send data
+Received: from CALLER by myhost.test.ex with local (Exim x.yz)
+ (envelope-from <CALLER@test.ex>)
+ id 10HmaX-0005vi-00; Tue, 2 Mar 1999 09:44:33 +0000
+Message-Id: <E10HmaX-0005vi-00@myhost.test.ex>
+From: CALLER_NAME <CALLER@test.ex>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+.
+250 OK
+QUIT
+250 OK
+End of script
x@y
router = r1, transport = t1
- host quoted.y
+ host quoted.y
x@d1
router = r1, transport = t1
- host 192.168.4.3 [192.168.4.3]
+ host 192.168.4.3 [192.168.4.3]
x@d2
router = r2, transport = t2
- host V4NET.9.8.7 [V4NET.9.8.7]
+ host V4NET.9.8.7 [V4NET.9.8.7]
x@d30
router = r3, transport = t4
- host 1.2.3.4 [1.2.3.4]
+ host 1.2.3.4 [1.2.3.4]
x@d31
router = r3, transport = t3
- host 1.2.3.4 [1.2.3.4]
+ host 1.2.3.4 [1.2.3.4]
xx@yy
router = r1, transport = t1
host 1.2.3.4 [1.2.3.4]
- host other2.test.ex [V4NET.12.3.2]
+ host other2.test.ex [V4NET.12.3.2]
xxx@ten-1.test.ex
<-- xxx@ten-1
router = r2, transport = t1
- host ten-1.test.ex [V4NET.0.0.1]
+ host ten-1.test.ex [V4NET.0.0.1]
xxx@testsub.sub.test.ex
<-- xxx@testsub.test.ex
<-- xxx@testsub
router = r2, transport = t1
- host testsub.sub.test.ex [V4NET.99.0.3]
+ host testsub.sub.test.ex [V4NET.99.0.3]
host ten-5-6.test.ex [V4NET.0.0.6] MX=4
x@manualroute
router = r1, transport = t1
- host ten-1.test.ex [V4NET.0.0.1]
- host ten-1.test.ex [V4NET.0.0.1]
- host ten-2.test.ex [V4NET.0.0.2]
+ host ten-1.test.ex [V4NET.0.0.1]
+ host ten-1.test.ex [V4NET.0.0.1]
+ host ten-2.test.ex [V4NET.0.0.2]
headers_rewrite =
home_directory =
no_initgroups
+max_parallel =
message_size_limit =
no_rcpt_include_affixes
retry_use_local_part
headers_rewrite =
home_directory =
no_initgroups
+max_parallel =
message_size_limit =
no_rcpt_include_affixes
retry_use_local_part
**** This is not for real!
451 Temporary local problem - please try later\r
-
-**** SMTP testing session as if from host V4NET.255.255.255
-**** but without any ident (RFC 1413) callback.
-**** This is not for real!
-
-451 Temporary local problem - please try later\r
syntax error: domain missing or malformed
bounce@π.test.ex
router = r1, transport = t1
- host mx.π.test.ex [V4NET.255.255.255] MX=0
+ host mx.xn--1xa.test.ex [V4NET.255.255.255] MX=0
x@manual.route
router = r1, transport = t1
- host ten-1.test.ex [V4NET.0.0.1]
+ host ten-1.test.ex [V4NET.0.0.1]
host ten-2.test.ex [V4NET.0.0.2] MX=5
host ten-3.test.ex [V4NET.0.0.3] MX=6
x@manual.route
router = r1, transport = t1
- host ten-1.test.ex [V4NET.0.0.1]
+ host ten-1.test.ex [V4NET.0.0.1]
host ten-2.test.ex [V4NET.0.0.2] MX=5
host ten-3.test.ex [V4NET.0.0.3] MX=6
- host ten-6.test.ex [V4NET.0.0.6]
+ host ten-6.test.ex [V4NET.0.0.6]
x@manual.route
router = r1, transport = t1
host ten-2.test.ex [V4NET.0.0.2] MX=5
host ten-3.test.ex [V4NET.0.0.3] MX=6
- host ten-6.test.ex [V4NET.0.0.6]
+ host ten-6.test.ex [V4NET.0.0.6]
x@random.manual.route
router = r2, transport = t1
host ten-2.test.ex [V4NET.0.0.2] MX=5
router = r2, transport = t1
host ten-2.test.ex [V4NET.0.0.2] MX=5
host ten-3.test.ex [V4NET.0.0.3] MX=6
- host ten-1.test.ex [V4NET.0.0.1]
+ host ten-1.test.ex [V4NET.0.0.1]
x@random.manual.route
router = r2, transport = t1
- host ten-6.test.ex [V4NET.0.0.6]
+ host ten-6.test.ex [V4NET.0.0.6]
host ten-2.test.ex [V4NET.0.0.2] MX=5
host ten-3.test.ex [V4NET.0.0.3] MX=6
- host ten-1.test.ex [V4NET.0.0.1]
+ host ten-1.test.ex [V4NET.0.0.1]
y@random.manual.route
router = r2, transport = t1
host ten-2.test.ex [V4NET.0.0.2] MX=5
host ten-3.test.ex [V4NET.0.0.3] MX=6
- host ten-6.test.ex [V4NET.0.0.6]
- host ten-1.test.ex [V4NET.0.0.1]
+ host ten-6.test.ex [V4NET.0.0.6]
+ host ten-1.test.ex [V4NET.0.0.1]
x@random.manual.route
router = r2, transport = t1
- host ten-6.test.ex [V4NET.0.0.6]
+ host ten-6.test.ex [V4NET.0.0.6]
host ten-2.test.ex [V4NET.0.0.2] MX=5
host ten-3.test.ex [V4NET.0.0.3] MX=6
x@manual.route
router = r1, transport = t1
- host ten-1.test.ex [V4NET.0.0.1]
+ host ten-1.test.ex [V4NET.0.0.1]
x@manual.route cannot be resolved at this time: lowest numbered MX record points to local host
x@manual.route
router = r1, transport = t1
x@random.manual.route cannot be resolved at this time: lookup of host "localhost.test.ex" failed in r2 router
x@random.manual.route
router = r2, transport = t1
- host ten-6.test.ex [V4NET.0.0.6]
+ host ten-6.test.ex [V4NET.0.0.6]
host ten-1.test.ex [V4NET.0.0.1] MX=6
x@manual.route
router = r1, transport = t1
a@b
router = r1, transport = t1
- host 1.2.3.4 [1.2.3.4]
+ host 1.2.3.4 [1.2.3.4]
a@b cannot be resolved at this time: remote host address is the local host
condition =
debug_print =
no_disable_logging
+dnssec_request_domains =
+dnssec_require_domains =
domains =
driver = accept
no_dsn_lasthop
x@ten-1.test.ex
<-- x@ten-1
router = all, transport = smtp
- host ten-1.test.ex [V4NET.0.0.1]
+ host ten-1.test.ex [V4NET.0.0.1]
x@y
router = r1, transport = t1
- host 127.0.0.1 [127.0.0.1]
+ host 127.0.0.1 [127.0.0.1]
250-PIPELINING\r
250 HELP\r
250 OK\r
+250 Accepted\r
+221 the.local.host.name closing connection\r
++++++++++++++++++++++++++++
+07-Mar-2000 12:21:52 r12@three.test.ex callout=accept
+07-Mar-2000 12:21:52 r1@test.ex callout=accept
+07-Mar-2000 12:21:52 r1@test.ex/<postmaster@the.local.host.name> callout=accept
+07-Mar-2000 12:21:52 r1@test.ex/<s1@test.ex> callout=accept
+07-Mar-2000 12:21:52 r1@test.ex/<s2@test.ex> callout=accept
+07-Mar-2000 12:21:52 r9@test.ex/<x9@test.ex> callout=reject
+07-Mar-2000 12:21:52 test.ex callout=accept postmaster=unknown random=unknown
+07-Mar-2000 12:21:52 three.test.ex callout=accept postmaster=unknown random=reject (07-Mar-2000 12:21:52)
+07-Mar-2000 12:21:52 two.test.ex callout=accept postmaster=unknown random=accept (07-Mar-2000 12:21:52)
+07-Mar-2000 12:21:52 x9@test.ex callout=reject
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-the.local.host.name Hello CALLER at xxxx\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250 HELP\r
+250 OK\r
451 Could not complete recipient verify callout\r
221 the.local.host.name closing connection\r
220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
250 OK
MAIL FROM:<>
250 OK
+RCPT TO:<the.local.host.name--testing@three.test.ex>
+550 Bad receipient, dropping conn
+>*eof
+Listening on port 1224 ...
+Connection request from [127.0.0.1]
+220 Server ready
+EHLO the.local.host.name
+250 OK
+MAIL FROM:<>
+250 OK
+RCPT TO:<r12@three.test.ex>
+250 OK
+QUIT
+250 OK
+End of script
+Listening on port 1224 ...
+Connection request from [127.0.0.1]
+220 Server ready
+EHLO the.local.host.name
+250 OK
+MAIL FROM:<>
+250 OK
RCPT TO:<r11@two.test.ex>
*sleep 2
End of script
??? 3
<<< 354 Enter message, ending with "." on a line by itself
>>> From : userx
->>>
->>> This is junk
+>>>
+>>> This is junk
>>> .
??? 5
<<< 550 Administrative prohibition
250 OK id=10HmaY-0005vi-00\r
221 Your message here\r
220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
-221 myhost.test.ex closing connection\r
+221 Your message here\r
220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
250 OK\r
221 myhost.test.ex closing connection\r
userx@alias-eximtesthost.test.ex
<-- userx@alias-eximtesthost
router = dns, transport = smtp
- host eximtesthost.test.ex [ip4.ip4.ip4.ip4]
+ host eximtesthost.test.ex [ip4.ip4.ip4.ip4]
userx@alias-eximtesthost.test.ex
router = dns, transport = smtp
- host eximtesthost.test.ex [ip4.ip4.ip4.ip4]
+ host eximtesthost.test.ex [ip4.ip4.ip4.ip4]
R:userx@test.ex:<CALLER@test.ex> -44 13121 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4]: SMTP error from remote mail server after RCPT TO:<userx@test.ex>: 451 Recipient deferred
first failed = time last try = time2 next try = time2 + 1
T:thishost.test.ex:127.0.0.1:1225 0 65 H=thishost.test.ex [127.0.0.1]: SMTP error from remote mail server after initial connection: 451 host deferred
-first failed = time last try = time2 next try = time2 + 1
+first failed = time last try = time2 next try = time2 + 2
+++++++++++++++++++++++++++
R:userx@test.ex:<CALLER@test.ex> -44 13121 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4]: SMTP error from remote mail server after RCPT TO:<userx@test.ex>: 451 Recipient deferred
first failed = time last try = time2 next try = time2 + 5 *
T:thishost.test.ex:127.0.0.1:1225 0 65 H=thishost.test.ex [127.0.0.1]: SMTP error from remote mail server after initial connection: 451 host deferred
-first failed = time last try = time2 next try = time2 + 1
+first failed = time last try = time2 next try = time2 + 2
+++++++++++++++++++++++++++
R:userx@test.ex:<CALLER@test.ex> -44 13121 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4]: SMTP error from remote mail server after RCPT TO:<userx@test.ex>: 451 Recipient deferred
first failed = time last try = time2 next try = time2 + 5 *
T:thishost.test.ex:127.0.0.1:1225 0 65 H=thishost.test.ex [127.0.0.1]: SMTP error from remote mail server after initial connection: 451 host deferred
+first failed = time last try = time2 next try = time2 + 2
++++++++++++++++++++++++++++
+ R:userx@test.ex:<CALLER@test.ex> -44 13121 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4]: SMTP error from remote mail server after RCPT TO:<userx@test.ex>: 451 Recipient deferred
+first failed = time last try = time2 next try = time2 + 5 *
+ R:usery@test.ex:<CALLER@test.ex> -44 13121 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4]: SMTP error from remote mail server after RCPT TO:<usery@test.ex>: 451 Recipient deferred
first failed = time last try = time2 next try = time2 + 1
+ T:thishost.test.ex:127.0.0.1:1225 0 65 H=thishost.test.ex [127.0.0.1]: SMTP error from remote mail server after initial connection: 451 host deferred
+first failed = time last try = time2 next try = time2 + 2
userx@test.ex cannot be resolved at this time: lookup failed for all hosts in r1 router: host_find_failed=ignore host_all_ignored=defer
userx@test.ex
router = r1, transport = t1
- host 127.0.0.1 [127.0.0.1]
+ host 127.0.0.1 [127.0.0.1]
userx@test.ex
router = r1, transport = t1
- host 127.0.0.1 [127.0.0.1]
- host 127.0.0.2 [127.0.0.2]
+ host 127.0.0.1 [127.0.0.1]
+ host 127.0.0.2 [127.0.0.2]
userx@test.ex cannot be resolved at this time: lookup failed for all hosts in r1 router: host_find_failed=ignore host_all_ignored=defer
userx@test.ex is undeliverable: Unrouteable address
userx@test.ex is undeliverable: lookup failed for all hosts in r1 router: host_find_failed=ignore host_all_ignored=fail
host 46.test.ex [V4NET.0.0.4] MX=46
manualroute@test.ex
router = r2, transport = smtp
- host 46.test.ex [V6NET:ffff:836f:a00:a:800:200a:c031]
+ host 46.test.ex [V6NET:ffff:836f:a00:a:800:200a:c031]
host 46.test.ex [V4NET.0.0.4]
dnslookup@v6.test.ex
router = r1, transport = smtp
- host v6.test.ex [V6NET:ffff:836f:a00:a:800:200a:c032]
+ host v6.test.ex [V6NET:ffff:836f:a00:a:800:200a:c032]
dnslookup@mx46.test.ex
router = r1, transport = smtp
host 46.test.ex [V4NET.0.0.4] MX=46
manualroute@test.ex
router = r2, transport = smtp
- host 46.test.ex [V4NET.0.0.4]
+ host 46.test.ex [V4NET.0.0.4]
dnslookup@v6.test.ex is undeliverable: Unrouteable address
Connecting to ip6:ip6:ip6:ip6:ip6:ip6:ip6:ip6 port 1225 ... connected
??? 220
x@46.test.ex
router = r1, transport = t1
- host 46.test.ex [V6NET:ffff:836f:a00:a:800:200a:c031]
+ host 46.test.ex [V6NET:ffff:836f:a00:a:800:200a:c031]
host 46.test.ex [V4NET.0.0.4]
x@mx46.test.ex
router = r1, transport = t1
SSL info: SSLv3 flush data
SSL info: SSLv3 read server session ticket A
SSL info: SSLv3 read server session ticket A
-pppp:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:s3_pkt.c:dddd:SSL alert number 40
+pppp:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:s3_pkt.c:dddd:SSL alert number 40
Failed to start TLS
End of script
Connecting to ip4.ip4.ip4.ip4 port 1225 ... connected
SSL info: SSLv3 flush data
SSL info: SSLv3 read server session ticket A
SSL info: SSLv3 read server session ticket A
-pppp:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:s3_pkt.c:dddd:SSL alert number 40
+pppp:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:s3_pkt.c:dddd:SSL alert number 40
Failed to start TLS
End of script
Connecting to 127.0.0.1 port 1225 ... connected
SSL info: SSLv3 flush data
SSL info: SSLv3 read server session ticket A
SSL info: SSLv3 read server session ticket A
-pppp:error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca:s3_pkt.c:dddd:SSL alert number 48
+pppp:error:14094418:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca:s3_pkt.c:dddd:SSL alert number 48
Failed to start TLS
End of script
Connecting to 127.0.0.1 port 1225 ... connected
SSL info: SSLv3 flush data
SSL info: SSLv3 read server session ticket A
SSL info: SSLv3 read server session ticket A
-pppp:error:14094414:SSL routines:SSL3_READ_BYTES:sslv3 alert certificate revoked:s3_pkt.c:dddd:SSL alert number 44
+pppp:error:14094414:SSL routines:ssl3_read_bytes:sslv3 alert certificate revoked:s3_pkt.c:dddd:SSL alert number 44
Failed to start TLS
End of script
Connecting to 127.0.0.1 port 1225 ... connected
SSL info: SSLv3 flush data
SSL info: SSLv3 read server session ticket A
SSL info: SSLv3 read server session ticket A
-pppp:error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca:s3_pkt.c:dddd:SSL alert number 48
+pppp:error:14094418:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca:s3_pkt.c:dddd:SSL alert number 48
Failed to start TLS
End of script
Connecting to ip4.ip4.ip4.ip4 port 1225 ... connected
SSL info: SSLv3 flush data
SSL info: SSLv3 read server session ticket A
SSL info: SSLv3 read server session ticket A
-pppp:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:s3_pkt.c:dddd:SSL alert number 40
+pppp:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:s3_pkt.c:dddd:SSL alert number 40
Failed to start TLS
End of script
Connecting to ip4.ip4.ip4.ip4 port 1225 ... connected
> csa=csa1.test.ex Y csa1.test.ex
> csa=csa2.test.ex N csa2.test.ex
>
+> soa=test.ex exim.test.ex
+> soa=a.test.ex exim.test.ex hostmaster.exim.test.ex 1430683638 1200 120 604800 3600
+>
> # DNS lookups with multiple items
>
> ten-1:ten2 V4NET.0.0.1
> defer_never:defer
> Failed: lookup of "defer_strict,a=test.again.dns:ten-1.test.ex" gave DEFER:
>
+> # Retry timeout and count. This only tests the syntax; we do not
+> # have any good way of testing the function.
+>
+> delay1500 ip4.ip4.ip4.ip4
+>
+> a=localhost.test.ex 127.0.0.1
+> a=localhost.test.ex 127.0.0.1
+>
> 42
> 30
> 3
-> 2/8
+> X/X
>
> Tue, 2 Mar 1999 09:44:33 +0000 // Changed locale // Tue, 2 Mar 1999 09:44:33 +0000
>
354 Enter message, ending with "." on a line by itself\r
250 OK id=10HmaY-0005vi-00\r
221 myhost.test.ex closing connection\r
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-myhost.test.ex Hello CALLER at test.ex\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmaZ-0005vi-00\r
+221 myhost.test.ex closing connection\r
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-myhost.test.ex Hello CALLER at test.ex\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbA-0005vi-00\r
+221 myhost.test.ex closing connection\r
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-myhost.test.ex Hello CALLER at test.ex\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbB-0005vi-00\r
+221 myhost.test.ex closing connection\r
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-myhost.test.ex Hello CALLER at test.ex\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbC-0005vi-00\r
+221 myhost.test.ex closing connection\r
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-myhost.test.ex Hello CALLER at test.ex\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbD-0005vi-00\r
+221 myhost.test.ex closing connection\r
******** SERVER ********
Listening on port 1224 ...
-Connection request from [127.0.0.1]
+Connection request from [IP_LOOPBACK_ADDR]
<GET TESTSUITE/spool/scan/10HmaZ-0005vi-00/10HmaZ-0005vi-00.eml HTTP/1.0
<
><summary code="11">
>*eof
End of script
Listening on port 1224 ...
-Connection request from [127.0.0.1]
+Connection request from [IP_LOOPBACK_ADDR]
<GET TESTSUITE/spool/scan/10HmaX-0005vi-00/10HmaX-0005vi-00.eml HTTP/1.0
<
>
>*eof
End of script
Listening on port 1224 ...
-Connection request from [127.0.0.1]
+Connection request from [IP_LOOPBACK_ADDR]
<GET TESTSUITE/spool/scan/10HmaY-0005vi-00/10HmaY-0005vi-00.eml HTTP/1.0
*sleep 3
End of script
Listening on port 1224 ...
-Connection request from [127.0.0.1]
+Connection request from [IP_LOOPBACK_ADDR]
<GET TESTSUITE/spool/scan/10HmbA-0005vi-00/10HmbA-0005vi-00.eml HTTP/1.0
*sleep 3
End of script
<SCAN TESTSUITE/spool/scan/10HmbB-0005vi-00/10HmbB-0005vi-00.eml
>LF>random ignored line
>LF>random ignored line 2
->LF>OK Scan ok.
+>LF>OK\x09Scan ok.
Expected EOF read from client
End of script
Listening on TESTSUITE/eximdir/fsec_sock ...
<CONFIGURE MIME 1
>ignored_response
<SCAN TESTSUITE/spool/scan/10HmaZ-0005vi-00/10HmaZ-0005vi-00.eml
->LF>xxxINFECTED blah VNAME blah
->LF>OK Scan ok.
+>LF>xxxINFECTED\x09blah\x09VNAME\x09blah
+>LF>OK\x09Scan ok.
Expected EOF read from client
End of script
Listening on TESTSUITE/eximdir/fsec_sock ...
<CONFIGURE MIME 1
>ignored_response
<SCAN TESTSUITE/spool/scan/10HmbA-0005vi-00/10HmbA-0005vi-00.eml
->LF>xxxINFECTED blah VNAME blah
->LF>OK Scan ok.
+>LF>xxxINFECTED\x09blah\x09VNAME\x09blah
+>LF>OK\x09Scan ok.
Expected EOF read from client
End of script
354 Enter message, ending with "." on a line by itself\r
250 OK id=10HmaZ-0005vi-00\r
221 myhost.test.ex closing connection\r
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-myhost.test.ex Hello CALLER at test.ex\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbC-0005vi-00\r
+221 myhost.test.ex closing connection\r
******** SERVER ********
Listening on TESTSUITE/eximdir/clam_sock ...
Connection request
*sleep 3
End of script
+Inital pause of 2 seconds
+Listening on TESTSUITE/eximdir/clam_sock ...
+Connection request
+<SCAN TESTSUITE/spool/scan/10HmbC-0005vi-00/10HmbC-0005vi-00.eml
+>LF>scanned_file_name: OK
+Unexpected EOF read from client
+End of script
>LF>200 FLAGS OK
<SCAN TESTSUITE/spool/scan/10HmbB-0005vi-00
>LF>210 SCAN DATA
->LF>blah [+]
+>LF>blah\x09[+]
>LF>200 SCAN OK
<QUIT
Unexpected EOF read from client
>LF>220 ready
<SCAN TESTSUITE/spool/scan/10HmaX-0005vi-00
>LF>210 SCAN DATA
->LF>blah [E]
+>LF>blah\x09[E]
>LF>200 SCAN OK
Unexpected EOF read from client
Listening on TESTSUITE/eximdir/avast_sock ...
>LF>220 ready
<SCAN TESTSUITE/spool/scan/10HmbA-0005vi-00
>LF>210 SCAN DATA
->LF>b\ l\ a\ h [L]9.9 9 VNAME
+>LF>b\\ l\\ a\\ h\x09[L]9.9\x099 VNAME
>LF>200 SCAN OK
Unexpected EOF read from client
Listening on TESTSUITE/eximdir/avast_sock ...
220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
250-myhost.test.ex Hello CALLER at test.ex\r
250-SIZE 52428800\r
+250-8BITMIME\r
250-PIPELINING\r
250 HELP\r
250 OK\r
250 Accepted\r
354 Enter message, ending with "." on a line by itself\r
-250 OK id=10HmaY-0005vi-00\r
-221 myhost.test.ex closing connection\r
-220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
-250-myhost.test.ex Hello CALLER at test.ex\r
-250-SIZE 52428800\r
-250-PIPELINING\r
-250 HELP\r
-250 OK\r
-250 Accepted\r
-354 Enter message, ending with "." on a line by itself\r
-250 OK id=10HmaZ-0005vi-00\r
-221 myhost.test.ex closing connection\r
-220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
-250-myhost.test.ex Hello CALLER at test.ex\r
-250-SIZE 52428800\r
-250-PIPELINING\r
-250 HELP\r
-250 OK\r
-250 Accepted\r
-354 Enter message, ending with "." on a line by itself\r
-250 OK id=10HmbA-0005vi-00\r
+250 OK id=10HmaX-0005vi-00\r
221 myhost.test.ex closing connection\r
220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
250-myhost.test.ex Hello CALLER at test.ex\r
250-SIZE 52428800\r
+250-8BITMIME\r
250-PIPELINING\r
250 HELP\r
250 OK\r
550-If it was a legitimate message, it may still be delivered to the target\r
550 recipient(s).\r
221 myhost.test.ex closing connection\r
-220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
-250-myhost.test.ex Hello CALLER at test.ex\r
-250-SIZE 52428800\r
-250-PIPELINING\r
-250 HELP\r
-250 OK\r
-250 Accepted\r
-354 Enter message, ending with "." on a line by itself\r
-250 OK id=10HmbC-0005vi-00\r
-221 myhost.test.ex closing connection\r
-220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
-250-myhost.test.ex Hello CALLER at test.ex\r
-250-SIZE 52428800\r
-250-PIPELINING\r
-250 HELP\r
-250 OK\r
-250 Accepted\r
-354 Enter message, ending with "." on a line by itself\r
-450-Your message has been rejected but is being kept for evaluation.\r
-450-If it was a legitimate message, it may still be delivered to the target\r
-450 recipient(s).\r
-221 myhost.test.ex closing connection\r
-220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
-250 OK\r
-250 Accepted\r
-354 Enter message, ending with "." on a line by itself\r
-550 Found Eicar-Test-Signature\r
-221 myhost.test.ex closing connection\r
userx@black-1.test.ex
router = lookuphost, transport = smtp
- host black-1.test.ex [1.2.3.4]
+ host black-1.test.ex [1.2.3.4] ad=no
userx@myhost.test.ex
router = lookuphost, transport = smtp
- host myhost.test.ex [V4NET.10.10.11]
+ host myhost.test.ex [V4NET.10.10.11] ad=no
userx@ten-1.test.ex
router = lookuphost, transport = smtp
- host other2.test.ex [V4NET.12.3.1]
- host other2.test.ex [V4NET.12.3.2]
+ host other2.test.ex [V4NET.12.3.1] ad=no
+ host other2.test.ex [V4NET.12.3.2] ad=no
userx@other1.test.ex
router = lookuphost, transport = smtp
- host other1.test.ex [V4NET.12.4.5]
+ host other1.test.ex [V4NET.12.4.5] ad=no
userx@other99.test.ex cannot be resolved at this time: host non-exist.test.ex not found when translating other99.test.ex [V4NET.99.0.1]
userx@other99.test.ex
router = lookuphost, transport = smtp
"DEFER cannot route this one (DEFER)"@some.host cannot be resolved at this time: cannot route this one (DEFER)
"ACCEPT transport = other_smtp hosts=ten-1.test.ex"@some.host
router = q, transport = other_smtp
- host ten-1.test.ex [V4NET.0.0.1]
+ host ten-1.test.ex [V4NET.0.0.1]
PASS@some.host
router = s, transport = smtp
- host 127.0.0.1 [127.0.0.1]
+ host 127.0.0.1 [127.0.0.1]
"FREEZE cannot route this one (FREEZE)"@some.host cannot be resolved at this time: cannot route this one (FREEZE)
postmaster@test.ex
<-- "REDIRECT postmaster@test.ex"@some.host
x@[V4NET.9.8.7]
router = r1, transport = t1
- host [V4NET.9.8.7] [V4NET.9.8.7]
+ host [V4NET.9.8.7] [V4NET.9.8.7]
x@[127.0.0.1]
router = r3, transport = t1
0m sss 10HmaX-0005vi-00 <y@[10.9.8.7]>
x@[abcd::dcba]
router = r0, transport = t1
- host [abcd::dcba] [abcd::dcba]
+ host [abcd::dcba] [abcd::dcba]
x@[IPv6:cba::abc]
router = r0, transport = t1
- host [ipv6:cba::abc] [cba::abc]
+ host [ipv6:cba::abc] [cba::abc]
x@[abcd::dcba]
router = r3, transport = t1
x@[IPv6:cba::abc]
354 Enter message, ending with "." on a line by itself\r
250 OK id=10HmbA-0005vi-00\r
221 myhost.test.ex closing connection\r
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-myhost.test.ex Hello CALLER at myhost.test.ex\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbB-0005vi-00\r
+221 myhost.test.ex closing connection\r
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-myhost.test.ex Hello CALLER at myhost.test.ex\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbC-0005vi-00\r
+221 myhost.test.ex closing connection\r
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-myhost.test.ex Hello CALLER at myhost.test.ex\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbD-0005vi-00\r
+221 myhost.test.ex closing connection\r
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-myhost.test.ex Hello CALLER at myhost.test.ex\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbE-0005vi-00\r
+221 myhost.test.ex closing connection\r
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-myhost.test.ex Hello CALLER at myhost.test.ex\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbF-0005vi-00\r
+221 myhost.test.ex closing connection\r
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250-myhost.test.ex Hello CALLER at myhost.test.ex\r
+250-SIZE 52428800\r
+250-8BITMIME\r
+250-PIPELINING\r
+250 HELP\r
+250 OK\r
+250 Accepted\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbG-0005vi-00\r
+221 myhost.test.ex closing connection\r
******** SERVER ********
Listening on port 1224 ...
250 Sender OK
RCPT TO:<usery@domain.com>
250 Recipient OK
-QUIT
-Expected EOF read from client
-Listening on port 1224 ...
-Connection request from [ip4.ip4.ip4.ip4]
-220 ESMTP
-EHLO myhost.test.ex
-250 OK
-MAIL FROM:<CALLER@myhost.test.ex>
-250 Sender OK
-RCPT TO:<usery@domain.com>
-250 Recipient OK
RCPT TO:<userx@domain.com>
250 Recipient OK
DATA
QUIT
250 OK
End of script
+Listening on port 1224 ...
+Connection request from [ip4.ip4.ip4.ip4]
+220 ESMTP
+EHLO myhost.test.ex
+250 OK
+MAIL FROM:<CALLER@myhost.test.ex>
+250 Sender OK
+RCPT TO:<no@domain.com>
+550 Not that one
+QUIT
+250 OK
+Expected EOF read from client
+Listening on port 1224 ...
+Connection request from [ip4.ip4.ip4.ip4]
+220 ESMTP
+EHLO myhost.test.ex
+250 OK
+MAIL FROM:<CALLER@myhost.test.ex>
+250 Sender OK
+RCPT TO:<no@domain.com>
+250 ok rcpt-1
+RCPT TO:<userx@domain.com>
+250 ok rcpt-2
+DATA
+354 Send data
+Received: from CALLER (helo=myhost.test.ex)
+ by myhost.test.ex with local-esmtp (Exim x.yz)
+ (envelope-from <CALLER@myhost.test.ex>)
+ id 10HmbB-0005vi-00; Tue, 2 Mar 1999 09:44:33 +0000
+Message-Id: <E10HmbB-0005vi-00@myhost.test.ex>
+From: CALLER_NAME <CALLER@myhost.test.ex>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+X-hdr-rtr-new: +++
+
+.
+250 OK
+QUIT
+250 OK
+End of script
+Listening on port 1224 ...
+Connection request from [ip4.ip4.ip4.ip4]
+220 ESMTP
+EHLO myhost.test.ex
+250 OK
+MAIL FROM:<CALLER@myhost.test.ex>
+250 Sender OK
+RCPT TO:<userx@domain.com>
+250 first recipient ok
+RCPT TO:<no@domain.com>
+550 Not that one
+QUIT
+250 OK
+Expected EOF read from client
+Listening on port 1224 ...
+Connection request from [ip4.ip4.ip4.ip4]
+220 ESMTP
+EHLO myhost.test.ex
+250 OK
+MAIL FROM:<CALLER@myhost.test.ex>
+250 Sender OK
+RCPT TO:<userx@domain.com>
+250 ok rcpt-1
+RCPT TO:<no@domain.com>
+250 ok rcpt-2
+DATA
+354 Send data
+Received: from CALLER (helo=myhost.test.ex)
+ by myhost.test.ex with local-esmtp (Exim x.yz)
+ (envelope-from <CALLER@myhost.test.ex>)
+ id 10HmbC-0005vi-00; Tue, 2 Mar 1999 09:44:33 +0000
+Message-Id: <E10HmbC-0005vi-00@myhost.test.ex>
+From: CALLER_NAME <CALLER@myhost.test.ex>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+X-hdr-rtr-new: +++
+
+.
+250 OK
+QUIT
+250 OK
+End of script
+Listening on port 1224 ...
+Connection request from [ip4.ip4.ip4.ip4]
+220 ESMTP
+EHLO myhost.test.ex
+250 OK
+MAIL FROM:<CALLER@myhost.test.ex>
+250 Sender OK
+RCPT TO:<userx@domain.com>
+250 first recipient ok
+QUIT
+250 OK
+Expected EOF read from client
+Listening on port 1224 ...
+Connection request from [ip4.ip4.ip4.ip4]
+220 ESMTP
+EHLO myhost.test.ex
+250 OK
+MAIL FROM:<CALLER@myhost.test.ex>
+250 Sender OK
+RCPT TO:<special_tpt@domain.com>
+250 second recipient ok
+QUIT
+250 OK
+Expected EOF read from client
+Listening on port 1224 ...
+Connection request from [ip4.ip4.ip4.ip4]
+220 ESMTP
+EHLO myhost.test.ex
+250 OK
+MAIL FROM:<CALLER@myhost.test.ex>
+250 Sender OK
+RCPT TO:<userx@domain.com>
+250 ok rcpt-1
+DATA
+354 Send data
+Received: from CALLER (helo=myhost.test.ex)
+ by myhost.test.ex with local-esmtp (Exim x.yz)
+ (envelope-from <CALLER@myhost.test.ex>)
+ id 10HmbD-0005vi-00; Tue, 2 Mar 1999 09:44:33 +0000
+Message-Id: <E10HmbD-0005vi-00@myhost.test.ex>
+From: CALLER_NAME <CALLER@myhost.test.ex>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+X-hdr-rtr-new: +++
+
+.
+250 OK
+QUIT
+250 OK
+Expected EOF read from client
+Listening on port 1224 ...
+Connection request from [ip4.ip4.ip4.ip4]
+220 ESMTP
+EHLO myhost.test.ex
+250 OK
+MAIL FROM:<CALLER@myhost.test.ex>
+250 Sender OK
+RCPT TO:<special_tpt@domain.com>
+250 ok rcpt-2
+DATA
+354 Send data
+Received: from CALLER (helo=myhost.test.ex)
+ by myhost.test.ex with local-esmtp (Exim x.yz)
+ (envelope-from <CALLER@myhost.test.ex>)
+ id 10HmbD-0005vi-00; Tue, 2 Mar 1999 09:44:33 +0000
+Message-Id: <E10HmbD-0005vi-00@myhost.test.ex>
+From: CALLER_NAME <CALLER@myhost.test.ex>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+X-hdr-rtr-new: +++
+
+.
+250 OK
+QUIT
+250 OK
+End of script
+Listening on port 1224 ...
+Connection request from [ip4.ip4.ip4.ip4]
+220 ESMTP
+EHLO myhost.test.ex
+250 OK
+MAIL FROM:<CALLER@myhost.test.ex>
+250 Sender OK
+RCPT TO:<userx@domain1.com>
+250 ok rcpt-1
+RCPT TO:<usery@domain2.com>
+250 ok rcpt-2
+DATA
+354 Send data
+Received: from CALLER (helo=myhost.test.ex)
+ by myhost.test.ex with local-esmtp (Exim x.yz)
+ (envelope-from <CALLER@myhost.test.ex>)
+ id 10HmbE-0005vi-00; Tue, 2 Mar 1999 09:44:33 +0000
+Message-Id: <E10HmbE-0005vi-00@myhost.test.ex>
+From: CALLER_NAME <CALLER@myhost.test.ex>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+X-hdr-rtr-new: +++
+
+.
+250 OK
+QUIT
+250 OK
+End of script
+Listening on port 1224 ...
+Connection request from [ip4.ip4.ip4.ip4]
+220 ESMTP
+EHLO myhost.test.ex
+250 OK
+MAIL FROM:<CALLER@myhost.test.ex>
+250 Sender OK
+RCPT TO:<userx@domain.com>
+250 first recipient ok
+QUIT
+250 OK
+Expected EOF read from client
+Listening on port 1224 ...
+Connection request from [ip4.ip4.ip4.ip4]
+220 ESMTP
+EHLO myhost.test.ex
+250 OK
+MAIL FROM:<CALLER@myhost.test.ex>
+250 Sender OK
+RCPT TO:<usery@special.com>
+250 second recipient ok
+QUIT
+250 OK
+Expected EOF read from client
+Listening on port 1224 ...
+Connection request from [ip4.ip4.ip4.ip4]
+220 ESMTP
+EHLO myhost.test.ex
+250 OK
+MAIL FROM:<CALLER@myhost.test.ex>
+250 Sender OK
+RCPT TO:<userx@domain.com>
+250 ok rcpt-1
+DATA
+354 Send data
+Received: from CALLER (helo=myhost.test.ex)
+ by myhost.test.ex with local-esmtp (Exim x.yz)
+ (envelope-from <CALLER@myhost.test.ex>)
+ id 10HmbF-0005vi-00; Tue, 2 Mar 1999 09:44:33 +0000
+Message-Id: <E10HmbF-0005vi-00@myhost.test.ex>
+From: CALLER_NAME <CALLER@myhost.test.ex>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+X-hdr-rtr-new: +++
+
+.
+250 OK
+QUIT
+250 OK
+Expected EOF read from client
+Listening on port 1224 ...
+Connection request from [ip4.ip4.ip4.ip4]
+220 ESMTP
+EHLO myhost.test.ex
+250 OK
+MAIL FROM:<CALLER@myhost.test.ex>
+250 Sender OK
+RCPT TO:<usery@special.com>
+250 ok rcpt-2
+DATA
+354 Send data
+Received: from CALLER (helo=myhost.test.ex)
+ by myhost.test.ex with local-esmtp (Exim x.yz)
+ (envelope-from <CALLER@myhost.test.ex>)
+ id 10HmbF-0005vi-00; Tue, 2 Mar 1999 09:44:33 +0000
+Message-Id: <E10HmbF-0005vi-00@myhost.test.ex>
+From: CALLER_NAME <CALLER@myhost.test.ex>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+X-hdr-rtr-new: +++
+
+.
+250 OK
+QUIT
+250 OK
+End of script
+Listening on port 1224 ...
+Connection request from [ip4.ip4.ip4.ip4]
+220 ESMTP
+EHLO myhost.test.ex
+250 OK
+MAIL FROM:<CALLER@myhost.test.ex>
+250 Sender OK
+RCPT TO:<userx@localhost4.test.ex>
+250 ok rcpt-1
+RCPT TO:<usery@thishost.test.ex>
+250 ok rcpt-2
+DATA
+354 Send data
+Received: from CALLER (helo=myhost.test.ex)
+ by myhost.test.ex with local-esmtp (Exim x.yz)
+ (envelope-from <CALLER@myhost.test.ex>)
+ id 10HmbG-0005vi-00; Tue, 2 Mar 1999 09:44:33 +0000
+Message-Id: <E10HmbG-0005vi-00@myhost.test.ex>
+From: CALLER_NAME <CALLER@myhost.test.ex>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+.
+250 OK
+QUIT
+250 OK
+End of script
??? 221
<<< 221 myhost.test.ex closing connection
End of script
+Connecting to 127.0.0.1 port 1225 ... connected
+??? 220
+<<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+>>> ehlo rhu.barb
+??? 250-
+<<< 250-myhost.test.ex Hello rhu.barb [127.0.0.1]
+??? 250-
+<<< 250-SIZE 52428800
+??? 250-
+<<< 250-8BITMIME
+??? 250-
+<<< 250-PIPELINING
+??? 250-PRDR
+<<< 250-PRDR
+??? 250
+<<< 250 HELP
+>>> mail from:<>
+??? 250
+<<< 250 OK
+>>> rcpt to:<userx@test.ex>
+??? 250
+<<< 250 Accepted
+>>> data
+??? 354
+<<< 354 Enter message, ending with "." on a line by itself
+>>> Sender: sender@some.where
+>>> .
+??? 250
+<<< 250 OK id=10HmbC-0005vi-00
+>>> quit
+??? 221
+<<< 221 myhost.test.ex closing connection
+End of script
SSL connection using AES256-SHA
Succeeded in starting TLS
End of script
+Connecting to ip4.ip4.ip4.ip4 port 1225 ... connected
+Certificate file = aux-fixed/cert2
+Key file = aux-fixed/cert2
+??? 220
+<<< 220 server1.example.com ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+>>> ehlo rhu.barb
+??? 250-
+<<< 250-server1.example.com Hello rhu.barb [ip4.ip4.ip4.ip4]
+??? 250-
+<<< 250-SIZE 52428800
+??? 250-
+<<< 250-8BITMIME
+??? 250-
+<<< 250-PIPELINING
+??? 250-
+<<< 250-STARTTLS
+??? 250
+<<< 250 HELP
+>>> starttls
+??? 220
+<<< 220 TLS go ahead
+Attempting to start TLS
+SSL info: before/connect initialization
+SSL info: before/connect initialization
+SSL info: SSLv3 read server hello A
+SSL info: SSLv3 read server certificate A
+SSL info: SSLv3 read server certificate request A
+SSL info: SSLv3 read server done A
+SSL info: SSLv3 write client certificate A
+SSL info: SSLv3 write client key exchange A
+SSL info: SSLv3 write certificate verify A
+SSL info: SSLv3 write change cipher spec A
+SSL info: SSLv3 write finished A
+SSL info: SSLv3 flush data
+SSL info: SSLv3 read server session ticket A
+SSL info: SSLv3 read finished A
+SSL info: SSL negotiation finished successfully
+SSL info: SSL negotiation finished successfully
+SSL connection using AES256-SHA
+Succeeded in starting TLS
+>>> ehlo rhu.barb.tls
+??? 250-
+<<< 250-server1.example.com Hello rhu.barb.tls [ip4.ip4.ip4.ip4]
+??? 250-
+<<< 250-SIZE 52428800
+??? 250-
+<<< 250-8BITMIME
+??? 250-
+<<< 250-PIPELINING
+??? 250
+<<< 250 HELP
+>>> quit
+End of script
Attempting to start TLS
Bad certificate
End of script
+Connecting to ip4.ip4.ip4.ip4 port 1225 ... connected
+Certificate file = aux-fixed/cert2
+Key file = aux-fixed/cert2
+??? 220
+<<< 220 server1.example.com ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+>>> ehlo rhu.barb
+??? 250-
+<<< 250-server1.example.com Hello rhu.barb [ip4.ip4.ip4.ip4]
+??? 250-
+<<< 250-SIZE 52428800
+??? 250-
+<<< 250-8BITMIME
+??? 250-
+<<< 250-PIPELINING
+??? 250-
+<<< 250-STARTTLS
+??? 250
+<<< 250 HELP
+>>> starttls
+??? 220
+<<< 220 TLS go ahead
+Attempting to start TLS
+Succeeded in starting TLS
+>>> ehlo rhu.barb.tls
+??? 250-
+<<< 250-server1.example.com Hello rhu.barb.tls [ip4.ip4.ip4.ip4]
+??? 250-
+<<< 250-SIZE 52428800
+??? 250-
+<<< 250-8BITMIME
+??? 250-
+<<< 250-PIPELINING
+??? 250
+<<< 250 HELP
+>>> quit
+End of script
EHLO the.local.host.name
250-OK
250 HELP
-MAIL FROM:<CALLER@the.local.host.name>
+MAIL FROM:<>
250 OK
RCPT TO:<userx@domain1>
250 OK
EHLO the.local.host.name
250-OK
250 HELP
-MAIL FROM:<CALLER@the.local.host.name>
+MAIL FROM:<>
250 OK
RCPT TO:<userx@domain2>
250 OK
EHLO the.local.host.name
250-OK
250 HELP
-MAIL FROM:<CALLER@the.local.host.name>
+MAIL FROM:<>
+250 OK
+RCPT TO:<userx@domain1>
+450 NOT RIGHT NOW
+QUIT
+220 OK
+End of script
+Listening on port 1224 ...
+Connection request from [127.0.0.1]
+220 ESMTP
+EHLO the.local.host.name
+250-OK
+250 HELP
+MAIL FROM:<>
250 OK
RCPT TO:<userx@domain1>
550 GO AWAY
--- /dev/null
+/home/jgh/git/exim/test/test-config