├── .gitignore
├── KNOWNBUGS
├── LICENSE
├── LICENSE.Sendmail
├── Makefile.am
├── README
├── RELEASE_NOTES
├── configure.ac
├── contrib
├── Makefile.am
├── docs
│ ├── Makefile.am
│ ├── draft-andersen-arc-05.txt
│ └── draft-andersen-arc.xml
├── init
│ ├── Makefile.am
│ ├── generic
│ │ ├── Makefile.am
│ │ ├── README
│ │ └── openarc
│ ├── redhat
│ │ ├── .gitignore
│ │ ├── Makefile.am
│ │ └── openarc.in
│ └── solaris
│ │ ├── Makefile.am
│ │ ├── openarc
│ │ └── openarc.xml
├── spec
│ ├── .gitignore
│ ├── Makefile.am
│ └── openarc.spec.in
└── systemd
│ ├── .gitignore
│ ├── Makefile.am
│ └── openarc.service.in
├── copyright-check
├── docs
└── Makefile.am
├── libopenarc
├── .gitignore
├── Makefile.am
├── arc-canon.c
├── arc-canon.h
├── arc-dns.c
├── arc-dns.h
├── arc-internal.h
├── arc-keys.c
├── arc-keys.h
├── arc-tables.c
├── arc-tables.h
├── arc-types.h
├── arc-util.c
├── arc-util.h
├── arc.c
├── arc.h
├── base64.c
├── base64.h
├── docs
│ ├── Makefile.am
│ └── index.html
├── openarc.pc.in
└── tests
│ └── Makefile.am
├── m4
├── .gitignore
└── ac_pthread.m4
└── openarc
├── .gitignore
├── Makefile.am
├── config.c
├── config.h
├── openarc-ar.c
├── openarc-ar.h
├── openarc-config.h
├── openarc-crypto.c
├── openarc-crypto.h
├── openarc-test.c
├── openarc-test.h
├── openarc.8.in
├── openarc.c
├── openarc.conf.5.in
├── openarc.conf.sample
├── openarc.conf.simple.in
├── openarc.h
├── tests
└── Makefile.am
├── util.c
└── util.h
/.gitignore:
--------------------------------------------------------------------------------
1 | # Object files
2 | *.o
3 | *.ko
4 | *.obj
5 | *.elf
6 |
7 | # Precompiled Headers
8 | *.gch
9 | *.pch
10 |
11 | # Libraries
12 | *.lib
13 | *.a
14 | *.la
15 | *.lo
16 |
17 | # Shared objects (inc. Windows DLLs)
18 | *.dll
19 | *.so
20 | *.so.*
21 | *.dylib
22 |
23 | # Executables
24 | *.exe
25 | *.out
26 | *.app
27 | *.i*86
28 | *.x86_64
29 | *.hex
30 |
31 | # Debug files
32 | *.dSYM/
33 |
34 | # tarballs
35 | *.tar.gz
36 |
37 | # other nonsense
38 | aclocal.m4
39 | autom4te.cache
40 | build-aux
41 | build-config.h
42 | build-config.h.in
43 | configure
44 | libtool
45 | Makefile
46 | Makefile.in
47 | CONFIG
48 | config.log
49 | config.status
50 | stamp-h1
51 | .deps/*
52 | *~
53 | *.cache
54 | *#*
55 |
56 | # compilation artifacts
57 | libopenarc/symbols.map
58 | openarc/.libs/
59 |
--------------------------------------------------------------------------------
/KNOWNBUGS:
--------------------------------------------------------------------------------
1 |
2 |
3 | K N O W N B U G S I N O P E N A R C
4 |
5 |
6 | The following are bugs or deficiencies in the OpenARC package that we
7 | are aware of but which have not been fixed in the current release. You
8 | probably want to get the most up to date version of this from
9 | http://www.trusteddomain.org. For descriptions of bugs that
10 | have been fixed, see the file RELEASE_NOTES.
11 |
12 | This list is not guaranteed to be complete. Check the Trusted Domain Project
13 | web site for additional pending bugs and feature requests.
14 |
15 | [TBD]
16 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2016, Murray S. Kucherawy
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | * Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 |
--------------------------------------------------------------------------------
/LICENSE.Sendmail:
--------------------------------------------------------------------------------
1 | SENDMAIL OPEN SOURCE LICENSE
2 |
3 | The following license terms and conditions apply to this open source
4 | software ("Software"), unless a different license is obtained directly
5 | from Sendmail, Inc. ("Sendmail") located at 6475 Christie Ave, Suite 350,
6 | Emeryville, CA 94608, USA.
7 |
8 | Use, modification and redistribution (including distribution of any
9 | modified or derived work) of the Software in source and binary forms is
10 | permitted only if each of the following conditions of 1-6 are met:
11 |
12 | 1. Redistributions of the Software qualify as "freeware" or "open
13 | source software" under one of the following terms:
14 |
15 | (a) Redistributions are made at no charge beyond the reasonable
16 | cost of materials and delivery; or
17 |
18 | (b) Redistributions are accompanied by a copy of the modified
19 | Source Code (on an acceptable machine-readable medium) or by an
20 | irrevocable offer to provide a copy of the modified Source Code
21 | (on an acceptable machine-readable medium) for up to three years
22 | at the cost of materials and delivery. Such redistributions must
23 | allow further use, modification, and redistribution of the Source
24 | Code under substantially the same terms as this license. For
25 | the purposes of redistribution "Source Code" means the complete
26 | human-readable, compilable, linkable, and operational source
27 | code of the redistributed module(s) including all modifications.
28 |
29 | 2. Redistributions of the Software Source Code must retain the
30 | copyright notices as they appear in each Source Code file, these
31 | license terms and conditions, and the disclaimer/limitation of
32 | liability set forth in paragraph 6 below. Redistributions of the
33 | Software Source Code must also comply with the copyright notices
34 | and/or license terms and conditions imposed by contributors on
35 | embedded code. The contributors' license terms and conditions
36 | and/or copyright notices are contained in the Source Code
37 | distribution.
38 |
39 | 3. Redistributions of the Software in binary form must reproduce the
40 | Copyright Notice described below, these license terms and conditions,
41 | and the disclaimer/limitation of liability set forth in paragraph
42 | 6 below, in the documentation and/or other materials provided with
43 | the binary distribution. For the purposes of binary distribution,
44 | "Copyright Notice" refers to the following language: "Copyright (c)
45 | 1998-2009 Sendmail, Inc. All rights reserved."
46 |
47 | 4. Neither the name, trademark or logo of Sendmail, Inc. (including
48 | without limitation its subsidiaries or affiliates) or its contributors
49 | may be used to endorse or promote products, or software or services
50 | derived from this Software without specific prior written permission.
51 | The name "sendmail" is a registered trademark and service mark of
52 | Sendmail, Inc.
53 |
54 | 5. We reserve the right to cancel this license if you do not comply with
55 | the terms. This license is governed by California law and both of us
56 | agree that for any dispute arising out of or relating to this Software,
57 | that jurisdiction and venue is proper in San Francisco or Alameda
58 | counties. These license terms and conditions reflect the complete
59 | agreement for the license of the Software (which means this supercedes
60 | prior or contemporaneous agreements or representations). If any term
61 | or condition under this license is found to be invalid, the remaining
62 | terms and conditions still apply.
63 |
64 | 6. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY
65 | SENDMAIL AND ITS CONTRIBUTORS "AS IS" WITHOUT WARRANTY OF ANY KIND
66 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
67 | IMPLIED WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT AND FITNESS FOR A
68 | PARTICULAR PURPOSE ARE EXPRESSLY DISCLAIMED. IN NO EVENT SHALL SENDMAIL
69 | OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
70 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
71 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
72 | OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
73 | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
74 | WITHOUT LIMITATION NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
75 | USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
76 |
77 | $Revision: 1.1 $ $Date: 2009/07/16 18:43:18 $
78 |
--------------------------------------------------------------------------------
/Makefile.am:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2010-2014, 2016, 2017, The Trusted Domain Project.
2 | # All rights reserved.
3 |
4 | AUTOMAKE_OPTIONS = foreign
5 | ACLOCAL_AMFLAGS = -I m4
6 |
7 | SUBDIRS = libopenarc contrib docs openarc
8 | dist_doc_DATA = LICENSE LICENSE.Sendmail RELEASE_NOTES
9 | dist_noinst_SCRIPTS = libtool
10 |
11 | DISTCLEANFILES = openarc-@VERSION@.tar.gz
12 |
13 | # TODO: get configure.ac to generate --enable-{feature} for all
14 | # non-experimental features and substitute it here e.g @SUPPORTED_FEATURES@.
15 | # Perhaps all features would enable a more comprehensive test coverage map
16 | # though.
17 | DISTCHECK_CONFIGURE_FLAGS=--with-openssl=/usr/local
18 |
19 | $(DIST_ARCHIVES): distcheck
20 |
21 | $(DIST_ARCHIVES).md5: $(DIST_ARCHIVES)
22 | md5 $? > $@ || md5sum $? > $@
23 |
24 | $(DIST_ARCHIVES).sha1: $(DIST_ARCHIVES)
25 | sha1 $? > $@ || sha1sum $? > $@
26 |
27 | $(DIST_ARCHIVES).asc: $(DIST_ARCHIVES)
28 | gpg -a -u security@trusteddomain.org --detach-sign $?
29 |
30 | push: $(DIST_ARCHIVES) $(DIST_ARCHIVES).sha1 $(DIST_ARCHIVES).md5 $(DIST_ARCHIVES).asc
31 | @echo "Are you sure you want to tag and release $(DIST_ARCHIVES)? (y/n)"
32 | @read confirm && [ $$confirm = 'y' ]
33 | git tag rel-openarc-`echo $(VERSION) | sed 's/\./-/g'`
34 | git push --tags
35 |
36 | dist-hook:
37 | [ -f $(distdir)/libopenarc/arc.h ] && rm -f $(distdir)/libopenarc/arc.h
38 | sed -e '/OPENARC_LIB_VERSION/s/0x[0-9]*/0x@HEX_VERSION@/' < $(srcdir)/libopenarc/arc.h > $(distdir)/libopenarc/arc.h
39 | echo "looking to see if @VERSION@ is in the RELEASE_NOTES"
40 | fgrep @VERSION@ $(srcdir)/RELEASE_NOTES
41 | sed -e 's|\(@VERSION@[ \t]*\)[0-9?]\{4\}\(/[0-9?]\{2\}\)\{2\}|\1'`date +%Y/%m/%d`'|' < $(srcdir)/RELEASE_NOTES > $(distdir)/RELEASE_NOTES
42 |
43 | rpm: dist-gzip
44 | rpmbuild -ta $(distdir).tar.gz
45 |
46 | .PHONY: push
47 |
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | OPENARC README
2 | ==============
3 |
4 | This directory has the latest open source ARC filter software from The
5 | Trusted Domain Project.
6 |
7 | There is a web site at http://www.trusteddomain.org that is home for the
8 | latest updates.
9 |
10 |
11 | +--------------+
12 | | INTRODUCTION |
13 | +--------------+
14 |
15 | The Trusted Domain Project (TDP) is a non-profit corporation dedicated to
16 | research and development of technologies that promote trust in the use of
17 | domain names in on the Internet. OpenARC is an initiative of TDP, and is
18 | primarily community effort to develop and maintain an open source library
19 | for producing ARC-aware applications, and a "milter"-based filter for
20 | providing ARC service.
21 |
22 | ARC is a technology proposal, put forward by a consortium of organizations,
23 | intended to allow a chain of message handlers (typically email operators)
24 | to confirm handling by trusted upstream handlers in an attempt to confirm
25 | the valid use of certain identifiers in the message.
26 |
27 | ARC is still experimental, and its specification may change. This package
28 | is intended for use by operators willing to take part in the experiment and
29 | provide their feedback to the development team.
30 |
31 | "milter" is a portmanteau of "mail filter" and refers to a protocol and API
32 | for communicating mail traffic information between MTAs and mail filtering
33 | plug-in applications. It was originally invented at Sendmail, Inc. but
34 | has also been adapted to other MTAs.
35 |
36 | A substantial amount of the code here is based on code developed as part of
37 | The OpenDKIM Project, also a TDP activity, which started as a code fork of
38 | version 2.8.3 of the open source "dkim-milter" package developed and
39 | maintained by Sendmail, Inc. The license used by The OpenDKIM Project is
40 | found in the LICENSE file. Portions of this project are also covered by the
41 | Sendmail Open Source License, available in this distribution in the file
42 | "LICENSE.Sendmail". See the copyright notice(s) in each source file to
43 | determine whether or not it is covered by both licenses.
44 |
45 | This package consists of a library that implements the ARC service and a
46 | milter-based filter application that can plug in to any milter-aware MTA to
47 | provide that service to sufficiently recent sendmail, Postfix or other MTAs
48 | that support the milter protocol.
49 |
50 |
51 | +--------------+
52 | | DEPENDENCIES |
53 | +--------------+
54 |
55 | To compile and operate, this package requires the following:
56 |
57 | o OpenSSL (http://www.openssl.org, or ask your software vendor for a package).
58 | Any version will get you started, however v0.9.8 or later is required if
59 | you want to be able to sign or verify messages using the SHA256 message
60 | digest algorithm which is generally required for current DKIM applications.
61 |
62 | o sendmail v8.13.0 (or later), or Postfix 2.3, (or later) and libmilter.
63 | (These are only required if you are building the filter.)
64 |
65 | o Access to a working nameserver (required only for signature verification).
66 |
67 | o On Linux systems, either libbsd (BSD compatibility library) or some other
68 | library that provides strlcat() and strlcpy().
69 |
70 | o If you are interested in tinkering with the build and packaging structure,
71 | you may need to upgrade to these versions of GNU's "autotools" components:
72 | autoconf (GNU Autoconf) 2.61
73 | automake (GNU automake) 1.7 (or 1.9 to avoid warnings)
74 | ltmain.sh (GNU libtool) 2.2.6 (or 1.5.26 after make maintainer-clean)
75 |
76 |
77 | +-----------------------+
78 | | RELATED DOCUMENTATION |
79 | +-----------------------+
80 |
81 | The man page for openarc (the actual filter program) is present in the
82 | openarc directory of this source distribution. There is additional
83 | information in the INSTALL and FEATURES files, and in the README file in the
84 | openarc directory. Changes are documented in the RELEASE_NOTES file.
85 |
86 | HTML-style documentation for libarc is available in libarc/docs in
87 | this source distribution.
88 |
89 | Mailing lists discussing and supporting the ARC software found in this
90 | package are maintained via a list server at trusteddomain.org. Visit
91 | http://www.trusteddomain.org to subscribe or browse archives. The available
92 | lists are:
93 |
94 | openarc-announce (moderated) Release announcements.
95 |
96 | openarc-users General OpenARC user questions and answers.
97 |
98 | openarc-dev Chatter among OpenARC developers.
99 |
100 | Bug tracking is done via the issue trackers on GitHub, at
101 | https://github.com/mskucherawy/OpenARC/issues. You can enter new bug
102 | reports there, but please check first for older bugs already open,
103 | or even already closed, before opening a new issue.
104 |
105 |
106 | +---------+
107 | | WARNING |
108 | +---------+
109 |
110 | Since OpenARC uses cryptography, the following information from OpenSSL
111 | applies to this package as well.
112 |
113 | PLEASE REMEMBER THAT EXPORT/IMPORT AND/OR USE OF STRONG CRYPTOGRAPHY
114 | SOFTWARE, PROVIDING CRYPTOGRAPHY HOOKS OR EVEN JUST COMMUNICATING
115 | TECHNICAL DETAILS ABOUT CRYPTOGRAPHY SOFTWARE IS ILLEGAL IN SOME
116 | PARTS OF THE WORLD. SO, WHEN YOU IMPORT THIS PACKAGE TO YOUR
117 | COUNTRY, RE-DISTRIBUTE IT FROM THERE OR EVEN JUST EMAIL TECHNICAL
118 | SUGGESTIONS OR EVEN SOURCE PATCHES TO THE AUTHOR OR OTHER PEOPLE
119 | YOU ARE STRONGLY ADVISED TO PAY CLOSE ATTENTION TO ANY EXPORT/IMPORT
120 | AND/OR USE LAWS WHICH APPLY TO YOU. THE AUTHORS ARE NOT LIABLE FOR
121 | ANY VIOLATIONS YOU MAKE HERE. SO BE CAREFUL, IT IS YOUR RESPONSIBILITY.
122 |
123 | If you use OpenSSL then make sure you read their README file which
124 | contains information about patents etc.
125 |
126 |
127 | +---------------------+
128 | | DIRECTORY STRUCTURE |
129 | +---------------------+
130 |
131 | contrib A collection of user contributed scripts that may be useful.
132 |
133 | docs A collection of RFCs and drafts related to opendkim.
134 |
135 | libopenarc A library that implements the proposed ARC service.
136 |
137 | libopenarc/docs HTML documentation describing the API provided by libopenarc.
138 |
139 | openarc A milter-based filter application which uses libopenarc
140 | to provide ARC service via an MTA using the milter protocol.
141 |
142 |
143 | +----------------+
144 | | RUNTIME ISSUES |
145 | +----------------+
146 |
147 | WARNING: symbol 'X' not available
148 |
149 | The filter attempted to get some information from the MTA that the MTA
150 | did not provide.
151 |
152 | At various points in the interaction between the MTA and the filter, certain
153 | macros containing information about the job in progress or the connection
154 | being handled are passed from the MTA to the filter.
155 |
156 | In the case of sendmail, the names of the macros the MTA should pass to the
157 | filter are defined by the "Milter.macros" settings in sendmail.cf, e.g.
158 | "Milter.macros.connect", "Milter.macros.envfrom", etc. This message
159 | indicates that the filter needed the contents of macro X, but that macro
160 | was not passed down from the MTA.
161 |
162 | Typically the values needed by this filter are passed from the MTA if the
163 | sendmail.cf was generated by the usual m4 method. If you do not have
164 | those options defined in your sendmail.cf, make sure your M4 configuration
165 | files are current and rebuild your sendmail.cf to get appropriate lines
166 | added to your sendmail.cf, and then restart sendmail.
167 |
168 | MTA timeouts
169 |
170 | By default, the MTA is configured to wait up to ten seconds for a response
171 | from a filter before giving up. When querying remote nameservers
172 | for key and policy data, the ARC filter may not get a response from the
173 | resolver within that time frame, and thus this MTA timeout will occur.
174 | This can cause messages to be rejected, temp-failed or delivered without
175 | verification, depending on the failure mode selected for the filter.
176 |
177 | When using the standard resolver library provided with your system, the
178 | DNS timeout cannot be adjusted. If you encounter this problem, you must
179 | increase the time the MTA waits for replies. See the documentation in
180 | the sendmail open source distribution (libmilter/README in particular)
181 | for instructions on changing these timeouts.
182 |
183 | d2i_PUBKEY_bio() failed
184 |
185 | After retrieving and decoding a public key to perform a message verification,
186 | the OpenSSL library attempted to make use of that key but failed. The
187 | known possible causes are:
188 |
189 | (a) Memory exhaustion
190 |
191 | (b) Key corruption
192 |
193 | If you're set to temp-fail messages in these cases, the remote end will
194 | probably retry the message. If the same message fails again later,
195 | the key is probably corrupted or otherwise invalid.
196 |
197 | Other OpenARC issues:
198 |
199 | Report any bugs to the email address openarc-users@trusteddomain.org or to
200 | the GitHub issue trackers accessible at:
201 |
202 | https://github.com/mskucherawy/OpenARC/issues
203 |
204 |
205 | +-----------------------------+
206 | | Sendmail REWRITING FEATURES |
207 | +-----------------------------+
208 |
209 | There are two features of the sendmail MTA which, if activated, can interfere
210 | with successful use of the DKIM service. The two features are MASQUERADE_AS
211 | and FEATURE(genericstable). See cf/README in the open source sendmail
212 | source code distribution for more information.
213 |
214 | Due to the way the milter protocol is incorporated into the MTA, openarc
215 | sees the headers before they are modified as required by those two features.
216 | This means any signature is generated based on the headers originally
217 | injected by the mail client and not on the headers which are actually sent
218 | out by the MTA. As a result, the verifying agent at the receiver's side
219 | will be unable to verify the signature as the signed data and the received
220 | data don't match.
221 |
222 | The suggested solutions to this problem are:
223 |
224 | (1) Send mail with the headers already written as needed, obviating the
225 | need for these features (or just turn them off).
226 |
227 | (2) Have two MTAs set up, either on separate boxes or on the same box.
228 | The first MTA should do all of the rewriting (i.e. use these two
229 | features) and the second one should use opendkim to add the signature
230 | and do no rewriting at all.
231 |
232 | (3) Have multiple DaemonPortOptions lines in your configuration file. The
233 | first daemon port (port 25) does the header rewriting and then routes
234 | the message to the second port; the latter does no rewriting but does the
235 | signing and then sends the message on its way.
236 |
237 | There is also a feature of Sendmail that will cause it to alter addresses
238 | after signing but before they are transmitted. The feature, which is on
239 | by default, passes addresses in header fields to the resolver functions
240 | to ensure they are canonical. This can result in the replacement of those
241 | strings in the sent message with their canonical forms only after the message
242 | is signed, which will invalidate the signatures. To suppress this feature,
243 | add the following line to your sendmail.mc and submit.mc configuration files,
244 | re-generate your configuration and restart the filter:
245 |
246 | FEATURE(`nocanonify')
247 |
248 | --
249 | Copyright (c) 2010-2012, 2014, 2016, 2017, The Trusted Domain Project.
250 | All rights reserved.
251 |
--------------------------------------------------------------------------------
/RELEASE_NOTES:
--------------------------------------------------------------------------------
1 | OPENARC RELEASE NOTES
2 |
3 | This listing shows the versions of the OpenARC package, the date of
4 | release, and a summary of the changes in that release.
5 |
6 | 0.1.0 2017/12/06
7 | Initial pre-release.
8 |
--------------------------------------------------------------------------------
/contrib/Makefile.am:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2010, 2011, 2016, The Trusted Domain Project.
2 | # All rights reserved.
3 |
4 | SUBDIRS = docs init spec systemd
5 |
--------------------------------------------------------------------------------
/contrib/docs/Makefile.am:
--------------------------------------------------------------------------------
1 | dist_doc_DATA=draft-andersen-arc-05.txt
2 |
--------------------------------------------------------------------------------
/contrib/init/Makefile.am:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2010, 2011, 2016, The Trusted Domain Project.
2 | # All rights reserved.
3 |
4 | AUTOMAKE_OPTIONS = foreign
5 |
6 | SUBDIRS = generic redhat solaris
7 |
--------------------------------------------------------------------------------
/contrib/init/generic/Makefile.am:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2010, 2011, 2016, The Trusted Domain Project.
2 | # All rights reserved.
3 |
4 | dist_doc_DATA = openarc
5 |
--------------------------------------------------------------------------------
/contrib/init/generic/README:
--------------------------------------------------------------------------------
1 | This directory contains a generic start/stop script that can be used on
2 | most UNIX systems to automate control of the openarc filter.
3 |
4 | To install, copy it to /etc/init.d/openarc, and ensure its mode is 0755.
5 | Then, follow the section below appropriate to your system. If you don't see
6 | your system listed, we would appreciate receiving from you instructions
7 | specific to your system once you get it working so that others who come
8 | after you can have helpful instructions.
9 |
10 | Please submit bug reports and feature requests to
11 | openarc-users@lists.trustedomain.org or via the trackers on SourceForge.
12 |
13 |
14 | RHEL-based and SLES-based Linux systems:
15 |
16 | Execute "chkconfig --add openarc" as root. This will read parameters found
17 | in the script and set up symbolic links under /etc/rc.d so that the filter
18 | is automatically started and stopped as needed.
19 |
20 | --
21 | Copyright (c) 2010, 2011, 2016, The Trusted Domain Project.
22 | All rights reserved.
23 |
--------------------------------------------------------------------------------
/contrib/init/generic/openarc:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Copyright (c) 2010, 2011, 2016, The Trusted Domain Project.
4 | # All rights reserved.
5 | #
6 | #
7 | ### BEGIN INIT INFO
8 | # Provides: openarc
9 | # Required-Start: $syslog $time $local_fs $remote_fs $named $network
10 | # Required-Stop: $syslog $time $local_fs $remote_fs $named
11 | # Default-Start: 2 3 4 5
12 | # Default-Stop: S 0 1 6
13 | # Short-Description: OpenARC Milter
14 | # Description: The OpenARC milter for signing and verifying email
15 | # messages using the DomainKeys Identified Mail protocol
16 | ### END INIT INFO
17 | #
18 | # chkconfig: 345 20 80
19 | # description: OpenARC milter for signing and verifying email
20 | # processname: openarc
21 | #
22 | # This script should run successfully on any LSB-compliant system. It will
23 | # attempt to fall back to RedHatisms if LSB isn't available, or to
24 | # commonly-available utilities if it's not even RedHat.
25 |
26 | NAME=openarc
27 | PATH=/bin:/usr/bin:/sbin:/usr/sbin
28 | DAEMON=/usr/sbin/$NAME
29 | PIDFILE=/var/run/$NAME/$NAME.pid
30 | CONFIG=/etc/$NAME.conf
31 | USER=openarc
32 |
33 | # Implement our own status function per LSB specs. This will be used on
34 | # non-RedHat systems.
35 | od_status() {
36 | pid=$(od_getpid)
37 | if [ $? -ne 0 ]; then
38 | if [ -f $PIDFILE ]; then
39 | echo "$NAME dead but pid file exists"
40 | return 1
41 | elif [ -d /var/lock/subsys -a -f /var/lock/subsys/$NAME ]; then
42 | echo "$NAME dead but subsys locked"
43 | return 2
44 | else
45 | echo "$NAME is stopped"
46 | return 3
47 | fi
48 | fi
49 | echo "$NAME (pid $pid) is running..."
50 | return 0
51 | }
52 |
53 | od_getpid() {
54 | if [ -n "$1" -a "$1" = "-P" ]; then
55 | shift
56 | PIDFILE=$1
57 | shift
58 | else
59 | PIDFILE=$(grep -i '^pidfile' $CONFIG | head -n 1 | awk '{print $2}')
60 | fi
61 | if [ ! -f "$PIDFILE" ]; then
62 | return 1
63 | fi
64 | PID=$(cat "$PIDFILE")
65 | if [ -n "$(which pgrep)" ]; then
66 | for p in $(pgrep -f $DAEMON); do
67 | if [ "$PID" = "$p" ]; then
68 | echo $p
69 | return 0
70 | fi
71 | done
72 | elif [ -x "/bin/pidof" ]; then
73 | for p in $(/bin/pidof -o %PPID $DAEMON); do
74 | if [ "$PID" = "$p" ]; then
75 | echo $p
76 | return 0
77 | fi
78 | done
79 | fi
80 | return 1
81 | }
82 |
83 | od_killproc() {
84 | [ -z "$1" ] && return 1
85 | if [ -n "$2" ]; then
86 | signal=$2
87 | else
88 | signal="TERM"
89 | fi
90 | if $(od_getpid); then
91 | pkill -"$signal" -f $1
92 | fi
93 | }
94 |
95 | # Check for helper functions
96 | if [ -f /lib/lsb/init-functions ]; then
97 | # Use LSB functions, if available
98 | . /lib/lsb/init-functions
99 | alias od_killproc=killproc
100 | alias od_daemon=start_daemon
101 | elif [ -f /etc/init.d/functions ]; then
102 | # Use RedHat init functions if LSB isn't available
103 | . /etc/init.d/functions
104 | alias od_daemon=daemon
105 | alias log_success_msg=success
106 | alias log_warning_msg=passed
107 | alias log_failure_msg=failure
108 | alias od_killproc=killproc
109 | alias od_status=status
110 | elif [ -f /etc/rc.d/init.d/functions ]; then
111 | # Legacy RedHat init location
112 | . /etc/rc.d/init.d/functions
113 | alias od_daemon=daemon
114 | alias log_success_msg=success
115 | alias log_warning_msg=passed
116 | alias log_failure_msg=failure
117 | alias od_killproc=killproc
118 | alias od_status=status
119 | else
120 | # If all else fails, use generic commands
121 | alias od_daemon=''
122 | alias log_success_msg=echo
123 | alias log_warning_msg=echo
124 | alias log_failure_msg=echo
125 | fi
126 |
127 | if [ ! -x "$DAEMON" ]; then
128 | exit 5
129 | fi
130 |
131 | if [ ! -f "$CONFIG" ]; then
132 | log_failure_msg "$CONFIG not found"
133 | exit 6
134 | fi
135 |
136 | [ -r /etc/default/$NAME ] && . /etc/default/$NAME
137 |
138 | ARGS="-u $USER $ARGS"
139 |
140 | if [ -n "$SOCKET" ]; then
141 | ARGS="$ARGS -p $SOCKET"
142 | fi
143 |
144 | od_start() {
145 | echo -n "Starting OpenARC Milter: "
146 | od_daemon $DAEMON -c $CONFIG $ARGS
147 | if [ $? -eq 0 ]; then
148 | log_success_msg $NAME
149 | if [ -d /var/lock/subsys ]; then
150 | touch /var/lock/subsys/$NAME
151 | fi
152 | else
153 | log_failure_msg $NAME
154 | fi
155 | echo
156 | }
157 |
158 | od_stop() {
159 | echo -n "Stopping OpenARC Milter: "
160 | CPIDFILE=""
161 | if [ -f $CONFIG ]; then
162 | CPIDFILE=$(grep -i '^pidfile' $CONFIG | head -n 1 | awk '{print $2}')
163 | fi
164 | if [ x"$CPIDFILE" != x"" ]; then
165 | PIDFILE=$CPIDFILE
166 | fi
167 |
168 | od_killproc -p $CPIDFILE $DAEMON
169 | if [ $? -eq 0 ]; then
170 | log_success_msg $NAME
171 | if [ -d /var/lock/subsys ]; then
172 | rm -f /var/lock/subsys/$NAME
173 | fi
174 | else
175 | log_failure_msg $NAME
176 | fi
177 | echo
178 | }
179 |
180 | od_reload() {
181 | echo -n "Reloading OpenARC Milter configuration: "
182 | od_killproc $DAEMON USR1
183 | if [ $? -eq 0 ]; then
184 | log_success_msg $NAME
185 | else
186 | log_failure_msg $NAME
187 | fi
188 | echo
189 | }
190 |
191 | case "$1" in
192 | start)
193 | od_start
194 | ;;
195 |
196 | stop)
197 | od_stop
198 | ;;
199 |
200 | restart|force-reload)
201 | od_stop
202 | od_start
203 | ;;
204 |
205 | reload)
206 | od_reload
207 | ;;
208 |
209 | status)
210 | od_status $NAME
211 | ;;
212 | esac
213 |
--------------------------------------------------------------------------------
/contrib/init/redhat/.gitignore:
--------------------------------------------------------------------------------
1 | openarc
2 |
--------------------------------------------------------------------------------
/contrib/init/redhat/Makefile.am:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2010, 2011, 2013, 2016, The Trusted Domain Project.
2 | # All rights reserved.
3 |
4 | dist_doc_DATA = openarc
5 |
--------------------------------------------------------------------------------
/contrib/init/redhat/openarc.in:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # openarc Start and stop OpenARC.
4 |
5 | # chkconfig: - 41 59
6 | # description: OpenARC implements the Authenticated Received Chain (ARC)
7 | # service and a milter-based filter application that can plug
8 | # in to any milter-aware MTA.
9 | # processname: openarc
10 | # pidfile: /var/run/openarc/openarc.pid
11 |
12 | ### BEGIN INIT INFO
13 | # Provides: openarc
14 | # Short-Description: Start and stop OpenARC
15 | # Description: OpenARC implements the Authenticated Received Chain
16 | # (ARC) service and a milter-based filter application
17 | # that can plug in to any milter-aware MTA.
18 | ### END INIT INFO
19 |
20 | # OpenARC startup script v2.0 for RHEL/CentOS/Fedora
21 | # by Steve Jenkins (SteveJenkins.com) - 03-24-2015
22 |
23 | . /etc/rc.d/init.d/functions
24 |
25 | prefix=@prefix@
26 | exec_prefix=@exec_prefix@
27 |
28 | RETVAL=0
29 | prog="openarc"
30 |
31 | DAEMON=@sbindir@/$prog
32 | CONF_FILE=@sysconfdir@/$prog.conf
33 | PID_FILE=@localstatedir@/run/$prog/$prog.pid
34 |
35 | if [ -f /etc/sysconfig/openarc ]; then
36 | . /etc/sysconfig/openarc
37 | fi
38 |
39 | start() {
40 | echo -n $"Starting OpenARC Milter: "
41 | if [ -f $PID_FILE ]; then
42 | PID=`cat $PID_FILE`
43 | echo OpenARC already running as pid $PID
44 | exit 2;
45 | else
46 | daemon $DAEMON -c $CONF_FILE -P $PID_FILE
47 | RETVAL=$?
48 | [ $RETVAL -eq 0 ] && touch /var/lock/subsys/openarc
49 | echo
50 | return $RETVAL
51 | fi
52 | }
53 |
54 | stop() {
55 | echo -n $"Stopping OpenARC Milter: "
56 | killproc -p $PID_FILE openarc
57 | RETVAL=$?
58 | echo
59 | [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/openarc
60 | return $RETVAL
61 | }
62 |
63 | restart() {
64 | stop
65 | start
66 | }
67 |
68 | reload() {
69 | echo -n $"Reloading OpenARC Milter configuration: "
70 | killproc -p $PID_FILE openarc -SIGUSR1
71 | RETVAL=$?
72 | echo
73 | return $RETVAL
74 | }
75 |
76 | case "$1" in
77 | start)
78 | start
79 | ;;
80 | stop)
81 | stop
82 | ;;
83 | reload)
84 | reload
85 | ;;
86 | restart)
87 | restart
88 | ;;
89 | status)
90 | status -p $PID_FILE openarc
91 | ;;
92 | condrestart)
93 | [ -f /var/lock/subsys/openarc ] && restart || :
94 | ;;
95 | *)
96 | echo $"Usage: $0 {start|stop|status|reload|restart|condrestart}"
97 | exit 1
98 | esac
99 |
100 | exit $?
101 |
--------------------------------------------------------------------------------
/contrib/init/solaris/Makefile.am:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2010, 2011, 2016, The Trusted Domain Project.
2 | # All rights reserved.
3 |
4 | dist_doc_DATA = openarc openarc.xml
5 |
--------------------------------------------------------------------------------
/contrib/init/solaris/openarc:
--------------------------------------------------------------------------------
1 | #!/sbin/sh
2 | #
3 | # Start method script for the ARC milter
4 | #
5 |
6 | PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin; export PATH
7 |
8 | . /lib/svc/share/smf_include.sh
9 |
10 | echo "starting openarc"
11 | openarc -x /etc/mail/openarc.conf
12 | echo "started openarc"
13 | exit $SMF_EXIT_OK
14 |
15 | #!/end
16 |
--------------------------------------------------------------------------------
/contrib/init/solaris/openarc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | ARC sender authentication
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/contrib/spec/.gitignore:
--------------------------------------------------------------------------------
1 | openarc.spec
2 |
--------------------------------------------------------------------------------
/contrib/spec/Makefile.am:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2010, 2011, 2016, The Trusted Domain Project.
2 | # All rights reserved.
3 |
4 | AUTOMAKE_OPTIONS = foreign
5 |
6 | dist_doc_DATA = openarc.spec.in
7 |
8 | EXTRA_DIST = openarc.spec
9 |
--------------------------------------------------------------------------------
/contrib/spec/openarc.spec.in:
--------------------------------------------------------------------------------
1 | %global systemd (0%{?fedora} >= 18) || (0%{?rhel} >= 7)
2 | %global tmpfiles (0%{?fedora} >= 15) || (0%{?rhel} >= 7)
3 |
4 | Summary: An open source library and milter for providing ARC service
5 | Name: openarc
6 | Version: @VERSION@
7 | Release: 1%{?dist}
8 | License: BSD and Sendmail
9 | URL: https://github.com/mskucherawy/OpenARC
10 |
11 | BuildRequires: libtool
12 | BuildRequires: pkgconfig(openssl)
13 | BuildRequires: pkgconfig(libbsd)
14 |
15 | # sendmail-devel renamed for F25+
16 | %if 0%{?fedora} > 25
17 | BuildRequires: sendmail-milter-devel
18 | %else
19 | BuildRequires: sendmail-devel
20 | %endif
21 |
22 | Requires: lib%{name}%{?_isa} = %{version}-%{release}
23 | Requires: libopenarc = %{version}-%{release}
24 | Requires(pre): shadow-utils
25 | %if %systemd
26 | # Required for systemd
27 | %{?systemd_requires}
28 | BuildRequires: systemd
29 | %else
30 | # Required for SysV
31 | Requires(post): chkconfig
32 | Requires(preun): chkconfig, initscripts
33 | Requires(postun): initscripts
34 | %endif
35 |
36 | Source0: openarc-%{version}.tar.gz
37 | Prefix: %{_prefix}
38 |
39 | %description
40 | The Trusted Domain Project is a community effort to develop and maintain a
41 | C library for producing ARC-aware applications and an open source milter for
42 | providing ARC service through milter-enabled MTAs.
43 |
44 | %package -n libopenarc
45 | Summary: An open source ARC library
46 |
47 | %description -n libopenarc
48 | This package contains the library files required for running services built
49 | using libopenarc.
50 |
51 | %package -n libopenarc-devel
52 | Summary: Development files for libopenarc
53 | Requires: lib%{name}%{?_isa} = %{version}-%{release}
54 |
55 | %description -n libopenarc-devel
56 | This package contains the static libraries, headers, and other support files
57 | required for developing applications against libopenarc.
58 |
59 | %prep
60 | %autosetup -p1
61 |
62 | %build
63 | %configure --disable-static
64 |
65 | make %{?_smp_mflags}
66 | %install
67 | make install DESTDIR=%{buildroot}
68 | mkdir -p %{buildroot}%{_sysconfdir}
69 | mkdir -p -m 0700 %{buildroot}%{_localstatedir}/run/%{name}
70 | rm -r %{buildroot}%{_prefix}/share/doc/openarc
71 | rm %{buildroot}/%{_libdir}/*.la
72 |
73 |
74 | cat > %{buildroot}%{_sysconfdir}/openarc.conf < %{buildroot}%{_unitdir}/%{name}.service << 'EOF'
96 | [Unit]
97 | Description=Authenticated Receive Chain (ARC) Milter
98 | Documentation=man:%{name}(8) man:%{name}.conf(5) http://www.trusteddomain.org/%{name}/
99 | After=network.target nss-lookup.target syslog.target
100 |
101 | [Service]
102 | Type=forking
103 | PIDFile=%{_localstatedir}/run/%{name}/%{name}.pid
104 | EnvironmentFile=-%{_sysconfdir}/sysconfig/%{name}
105 | ExecStart=/usr/sbin/%{name} $OPTIONS
106 | ExecReload=/bin/kill -USR1 $MAINPID
107 | User=%{name}
108 | Group=%{name}
109 |
110 | [Install]
111 | WantedBy=multi-user.target
112 | EOF
113 | %else
114 | mkdir -p %{buildroot}%{_initrddir}
115 | install -m 0755 contrib/init/redhat/%{name} %{buildroot}%{_initrddir}/%{name}
116 | %endif
117 |
118 | %if %{tmpfiles}
119 | install -p -d %{buildroot}%{_tmpfilesdir}
120 | cat > %{buildroot}%{_tmpfilesdir}/%{name}.conf </dev/null 2>&1; then
127 | %{_sbindir}/useradd -M -d %{_localstatedir}/lib -r -s /bin/false openarc
128 | if ! getent group openarc >/dev/null; then
129 | %{_sbindir}/groupadd openarc
130 | %{_sbindir}/usermod -g openarc openarc
131 | fi
132 | if getent group mail >/dev/null; then
133 | %{_sbindir}/usermod -G mail openarc
134 | fi
135 | fi
136 | exit 0
137 |
138 |
139 | %post
140 |
141 | %if %systemd
142 | %systemd_post %{name}.service
143 | %else
144 | /sbin/chkconfig --add %{name} || :
145 | %endif
146 |
147 |
148 | %preun
149 | %if %systemd
150 | %systemd_preun %{name}.service
151 | %else
152 | if [ $1 -eq 0 ]; then
153 | service %{name} stop >/dev/null || :
154 | /sbin/chkconfig --del %{name} || :
155 | fi
156 | exit 0
157 | %endif
158 |
159 | %post -n libopenarc -p /sbin/ldconfig
160 |
161 | %postun -n libopenarc -p /sbin/ldconfig
162 |
163 |
164 | %files
165 | %defattr(-,root,root)
166 | %doc LICENSE LICENSE.Sendmail README RELEASE_NOTES
167 | %config(noreplace) %{_sysconfdir}/openarc.conf
168 |
169 | %if %{tmpfiles}
170 | %{_tmpfilesdir}/%{name}.conf
171 | %else
172 | %dir %attr(-,%{name},%{name}) %{_localstatedir}/run/%{name}
173 | %endif
174 |
175 | %if %{systemd}
176 | %{_unitdir}/%{name}.service
177 | %else
178 | %{_initrddir}/%{name}
179 | %endif
180 | %{_mandir}/*/*
181 | %{_sbindir}/*
182 |
183 |
184 | %files -n libopenarc
185 | %doc LICENSE LICENSE.Sendmail
186 | %defattr(-,root,root)
187 | %{_libdir}/*.so.*
188 |
189 | %files -n libopenarc-devel
190 | %defattr(-,root,root)
191 | %doc LICENSE LICENSE.Sendmail
192 | %{_includedir}/*
193 | %{_libdir}/*.so
194 | %{_libdir}/pkgconfig/*.pc
195 |
196 | %changelog
197 | * Sun Jul 23 2017 Matt Domsch 0.1.0-1
198 | - update to Fedora Packaging Guidelines
199 |
--------------------------------------------------------------------------------
/contrib/systemd/.gitignore:
--------------------------------------------------------------------------------
1 | openarc.service
2 |
--------------------------------------------------------------------------------
/contrib/systemd/Makefile.am:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2016, The Trusted Domain Project. All rights reserved.
2 |
3 | dist_doc_DATA = openarc.service
4 |
--------------------------------------------------------------------------------
/contrib/systemd/openarc.service.in:
--------------------------------------------------------------------------------
1 | # After=network.target nss-lookup.target syslog.target
2 |
3 | [Unit]
4 | Description=Authenticated Resource Chain (ARC) Milter
5 | Documentation=man:openarc(8) man:openarc.conf(5) http://www.trusteddomain.org/openarc
6 | After=network.target nss-lookup.target syslog.target
7 |
8 | [Service]
9 | Type=forking
10 | PIDFile=@localstatedir@/run/openarc/openarc.pid
11 | EnvironmentFile=-@sysconfdir@/sysconfig/openarc
12 | ExecStart=@sbindir@/openarc $OPTIONS
13 | ExecReload=/bin/kill -USR1 $MAINPID
14 | User=openarc
15 | Group=openarc
16 |
17 | [Install]
18 | WantedBy=multi-user.target
19 |
--------------------------------------------------------------------------------
/copyright-check:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Copyright (c) 2011-2014, 2017, The Trusted Domain Project.
4 | # All rights reserved.
5 | #
6 |
7 | YEAR=`date +%Y`
8 | LASTYEAR=$(($YEAR - 1))
9 |
10 | for i in `git diff --name-only @{$LASTYEAR-12-31} | fgrep -v .jpg | fgrep -v contrib/ | fgrep -v m4/`
11 | do
12 | if test -f $i
13 | then
14 | if grep -q Copyright $i
15 | then
16 | if ! grep -q Copyright.\*$YEAR $i
17 | then
18 | echo $i
19 | fi
20 | fi
21 | fi
22 | done
23 |
--------------------------------------------------------------------------------
/docs/Makefile.am:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trusteddomainproject/OpenARC/355ee2a1ca85acccce494478991983b54f794f4e/docs/Makefile.am
--------------------------------------------------------------------------------
/libopenarc/.gitignore:
--------------------------------------------------------------------------------
1 | openarc.pc
2 | symbols.map
3 | .deps
4 | .libs
5 |
--------------------------------------------------------------------------------
/libopenarc/Makefile.am:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2016, 2017, The Trusted Domain Project. All rights reserved.
2 |
3 | #SUBDIRS=tests docs
4 | SUBDIRS=docs
5 |
6 | if DEBUG
7 | AM_CFLAGS = -g
8 | endif
9 | LDADD = ./libopenarc.la
10 |
11 | lib_LTLIBRARIES = libopenarc.la
12 | libopenarc_la_SOURCES = base64.c base64.h arc.c arc.h arc-canon.c arc-canon.h arc-dns.c arc-dns.h arc-internal.h arc-keys.c arc-keys.h arc-tables.c arc-tables.h arc-types.h arc-util.c arc-util.h
13 | libopenarc_la_CPPFLAGS = $(LIBCRYPTO_CPPFLAGS)
14 | libopenarc_la_CFLAGS = $(LIBCRYPTO_INCDIRS) $(LIBOPENARC_INC)
15 | libopenarc_la_LDFLAGS = -no-undefined $(LIBCRYPTO_LIBDIRS) -version-info $(LIBOPENARC_VERSION_INFO)
16 | libopenarc_la_LIBADD = $(LIBOPENARC_LIBS) $(LIBCRYPTO_LDADD)
17 | if !ALL_SYMBOLS
18 | libopenarc_la_DEPENDENCIES = symbols.map
19 | libopenarc_la_LDFLAGS += -export-symbols symbols.map
20 | endif
21 | if RPATH
22 | libopenarc_la_LDFLAGS += -rpath $(libdir)
23 | endif
24 | libopenarc_includedir = $(includedir)/openarc
25 | libopenarc_include_HEADERS = arc.h
26 |
27 | pkgconfigdir = $(libdir)/pkgconfig
28 | pkgconfig_DATA = openarc.pc
29 |
30 | DISTCLEANFILES=symbols.map *.gcno *.gcda
31 |
32 | symbols.map: $(libopenarc_include_HEADERS)
33 | grep '^extern' $? | \
34 | awk '{ for (c = 1; c <= NF; c++) if ($$c ~ /arc_/) { print $$c; break; } }' | \
35 | sed -e s/\[\*\;\]//g -e s/\[\\\[\\\]\]//g -e s/\(.*// | \
36 | sort -u -o $@
37 |
38 | MOSTLYCLEANFILES=symbols.map *.gcno *.gcda
39 |
--------------------------------------------------------------------------------
/libopenarc/arc-canon.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Copyright (c) 2007, 2008 Sendmail, Inc. and its suppliers.
3 | ** All rights reserved.
4 | **
5 | ** Copyright (c) 2009, 2011, 2012, 2017, The Trusted Domain Project.
6 | ** All rights reserved.
7 | */
8 |
9 | #ifndef _ARC_CANON_H_
10 | #define _ARC_CANON_H_
11 |
12 | #include "build-config.h"
13 |
14 | /* system includes */
15 | #include
16 | #ifdef HAVE_STDBOOL_H
17 | # include
18 | #endif /* HAVE_STDBOOL_H */
19 |
20 | /* libopenarc includes */
21 | #include "arc.h"
22 | #include "arc-types.h"
23 |
24 | #define ARC_HASHBUFSIZE 4096
25 |
26 | #define ARC_CANONTYPE_HEADER 0
27 | #define ARC_CANONTYPE_BODY 1
28 | #define ARC_CANONTYPE_SEAL 2
29 |
30 | /* prototypes */
31 | extern ARC_STAT arc_add_canon __P((ARC_MESSAGE *, int, arc_canon_t, int,
32 | u_char *, struct arc_hdrfield *,
33 | ssize_t length, ARC_CANON **));
34 | extern ARC_STAT arc_canon_add_to_seal __P((ARC_MESSAGE *));
35 | extern ARC_STAT arc_canon_bodychunk __P((ARC_MESSAGE *, u_char *, size_t));
36 | extern void arc_canon_cleanup __P((ARC_MESSAGE *));
37 | extern ARC_STAT arc_canon_closebody __P((ARC_MESSAGE *));
38 | extern ARC_STAT arc_canon_getfinal __P((ARC_CANON *, u_char **, size_t *));
39 | extern ARC_STAT arc_canon_gethashes __P((ARC_MESSAGE *, void **, size_t *,
40 | void **, size_t *));
41 | extern ARC_STAT arc_canon_getsealhash __P((ARC_MESSAGE *, int,
42 | void **, size_t *));
43 | extern ARC_STAT arc_canon_header_string __P((struct arc_dstring *,
44 | arc_canon_t,
45 | unsigned char *,
46 | size_t, _Bool));
47 | extern ARC_STAT arc_canon_init __P((ARC_MESSAGE *, _Bool, _Bool));
48 | extern u_long arc_canon_minbody __P((ARC_MESSAGE *));
49 | extern ARC_STAT arc_canon_runheaders __P((ARC_MESSAGE *));
50 | extern ARC_STAT arc_canon_runheaders_seal __P((ARC_MESSAGE *));
51 | extern int arc_canon_selecthdrs __P((ARC_MESSAGE *, u_char *,
52 | struct arc_hdrfield **, int));
53 | extern ARC_STAT arc_canon_signature __P((ARC_MESSAGE *, struct arc_hdrfield *, _Bool));
54 |
55 | extern ARC_STAT arc_parse_canon_t(unsigned char *, arc_canon_t *, arc_canon_t *);
56 |
57 | #endif /* ! _ARC_CANON_H_ */
58 |
--------------------------------------------------------------------------------
/libopenarc/arc-dns.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** Copyright (c) 2010-2012, 2017, The Trusted Domain Project.
3 | ** All rights reserved.
4 | */
5 |
6 | /* for Solaris */
7 | #ifndef _REENTRANT
8 | # define _REENTRANT
9 | #endif /* ! REENTRANT */
10 |
11 | /* system includes */
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 |
23 | /* libopenarc includes */
24 | #include "arc.h"
25 | #include "arc-dns.h"
26 |
27 | /* OpenARC includes */
28 | #include "build-config.h"
29 |
30 | /* macros, limits, etc. */
31 | #ifndef MAXPACKET
32 | # define MAXPACKET 8192
33 | #endif /* ! MAXPACKET */
34 |
35 | /*
36 | ** Standard UNIX resolver stub functions
37 | */
38 |
39 | struct arc_res_qh
40 | {
41 | int rq_error;
42 | int rq_dnssec;
43 | size_t rq_buflen;
44 | };
45 |
46 | /*
47 | ** ARC_RES_INIT -- initialize the resolver
48 | **
49 | ** Parameters:
50 | ** srv -- service handle (returned)
51 | **
52 | ** Return value
53 | ** 0 on success, !0 on failure
54 | */
55 |
56 | int
57 | arc_res_init(void **srv)
58 | {
59 | #ifdef HAVE_RES_NINIT
60 | struct __res_state *res;
61 |
62 | res = malloc(sizeof(struct __res_state));
63 | if (res == NULL)
64 | return -1;
65 |
66 | memset(res, '\0', sizeof(struct __res_state));
67 |
68 | if (res_ninit(res) != 0)
69 | {
70 | free(res);
71 | return -1;
72 | }
73 |
74 | *srv = res;
75 |
76 | return 0;
77 | #else /* HAVE_RES_NINIT */
78 | if (res_init() == 0)
79 | {
80 | *srv = (void *) 0x01;
81 | return 0;
82 | }
83 | else
84 | {
85 | return -1;
86 | }
87 | #endif /* HAVE_RES_NINIT */
88 | }
89 |
90 | /*
91 | ** ARC_RES_CLOSE -- shut down the resolver
92 | **
93 | ** Parameters:
94 | ** srv -- service handle
95 | **
96 | ** Return value:
97 | ** None.
98 | */
99 |
100 | void
101 | arc_res_close(void *srv)
102 | {
103 | #ifdef HAVE_RES_NINIT
104 | struct __res_state *res;
105 |
106 | res = srv;
107 |
108 | if (res != NULL)
109 | {
110 | res_nclose(res);
111 | free(res);
112 | }
113 | #endif /* HAVE_RES_NINIT */
114 | }
115 |
116 | /*
117 | ** ARC_RES_CANCEL -- cancel a pending resolver query
118 | **
119 | ** Parameters:
120 | ** srv -- query service handle (ignored)
121 | ** qh -- query handle (ignored)
122 | **
123 | ** Return value:
124 | ** 0 on success, !0 on error
125 | **
126 | ** Notes:
127 | ** The standard UNIX resolver is synchronous, so in theory this can
128 | ** never get called. We have not yet got any use cases for one thread
129 | ** canceling another thread's pending queries, so for now just return 0.
130 | */
131 |
132 | int
133 | arc_res_cancel(void *srv, void *qh)
134 | {
135 | if (qh != NULL)
136 | free(qh);
137 |
138 | return 0;
139 | }
140 |
141 | /*
142 | ** ARC_RES_QUERY -- initiate a DNS query
143 | **
144 | ** Parameters:
145 | ** srv -- service handle (ignored)
146 | ** type -- RR type to query
147 | ** query -- the question to ask
148 | ** buf -- where to write the answer
149 | ** buflen -- bytes at "buf"
150 | ** qh -- query handle, used with arc_res_waitreply
151 | **
152 | ** Return value:
153 | ** 0 on success, -1 on error
154 | **
155 | ** Notes:
156 | ** This is a stub for the stock UNIX resolver (res_) functions, which
157 | ** are synchronous so no handle needs to be created, so "qh" is set to
158 | ** "buf". "buf" is actually populated before this returns (unless
159 | ** there's an error).
160 | */
161 |
162 | int
163 | arc_res_query(void *srv, int type, unsigned char *query, unsigned char *buf,
164 | size_t buflen, void **qh)
165 | {
166 | int n;
167 | int ret;
168 | struct arc_res_qh *rq;
169 | unsigned char qbuf[HFIXEDSZ + MAXPACKET];
170 | #ifdef HAVE_RES_NINIT
171 | struct __res_state *statp;
172 | #endif /* HAVE_RES_NINIT */
173 |
174 | #ifdef HAVE_RES_NINIT
175 | statp = srv;
176 | n = res_nmkquery(statp, QUERY, (char *) query, C_IN, type, NULL, 0,
177 | NULL, qbuf, sizeof qbuf);
178 | #else /* HAVE_RES_NINIT */
179 | n = res_mkquery(QUERY, (char *) query, C_IN, type, NULL, 0, NULL, qbuf,
180 | sizeof qbuf);
181 | #endif /* HAVE_RES_NINIT */
182 | if (n == (size_t) -1)
183 | return ARC_DNS_ERROR;
184 |
185 | #ifdef HAVE_RES_NINIT
186 | ret = res_nsend(statp, qbuf, n, buf, buflen);
187 | #else /* HAVE_RES_NINIT */
188 | ret = res_send(qbuf, n, buf, buflen);
189 | #endif /* HAVE_RES_NINIT */
190 | if (ret == -1)
191 | return ARC_DNS_ERROR;
192 |
193 | rq = (struct arc_res_qh *) malloc(sizeof *rq);
194 | if (rq == NULL)
195 | return ARC_DNS_ERROR;
196 |
197 | rq->rq_dnssec = ARC_DNSSEC_UNKNOWN;
198 | if (ret == -1)
199 | {
200 | rq->rq_error = errno;
201 | rq->rq_buflen = 0;
202 | }
203 | else
204 | {
205 | rq->rq_error = 0;
206 | rq->rq_buflen = (size_t) ret;
207 | }
208 |
209 | *qh = (void *) rq;
210 |
211 | return ARC_DNS_SUCCESS;
212 | }
213 |
214 | /*
215 | ** ARC_RES_WAITREPLY -- wait for a reply to a pending query
216 | **
217 | ** Parameters:
218 | ** srv -- service handle
219 | ** qh -- query handle
220 | ** to -- timeout
221 | ** bytes -- number of bytes in the reply (returned)
222 | ** error -- error code (returned)
223 | **
224 | ** Return value:
225 | ** A ARC_DNS_* code.
226 | **
227 | ** Notes:
228 | ** Since the stock UNIX resolver is synchronous, the reply was completed
229 | ** before arc_res_query() returned, and thus this is almost a no-op.
230 | */
231 |
232 | int
233 | arc_res_waitreply(void *srv, void *qh, struct timeval *to, size_t *bytes,
234 | int *error, int *dnssec)
235 | {
236 | struct arc_res_qh *rq;
237 |
238 | assert(qh != NULL);
239 |
240 | rq = qh;
241 |
242 | if (bytes != NULL)
243 | *bytes = rq->rq_buflen;
244 | if (error != NULL)
245 | *error = rq->rq_error;
246 | if (dnssec != NULL)
247 | *dnssec = rq->rq_dnssec;
248 |
249 | return ARC_DNS_SUCCESS;
250 | }
251 |
252 | /*
253 | ** ARC_RES_SETNS -- set nameserver list
254 | **
255 | ** Parameters:
256 | ** srv -- service handle
257 | ** nslist -- nameserver list, as a string
258 | **
259 | ** Return value:
260 | ** ARC_DNS_SUCCESS -- success
261 | ** ARC_DNS_ERROR -- error
262 | */
263 |
264 | int
265 | arc_res_nslist(void *srv, const char *nslist)
266 | {
267 | #ifdef HAVE_RES_SETSERVERS
268 | int nscount = 0;
269 | char *tmp;
270 | char *ns;
271 | char *last = NULL;
272 | struct sockaddr_in in;
273 | # ifdef AF_INET6
274 | struct sockaddr_in6 in6;
275 | # endif /* AF_INET6 */
276 | struct state *res;
277 | res_sockaddr_union nses[MAXNS];
278 |
279 | assert(srv != NULL);
280 | assert(nslist != NULL);
281 |
282 | memset(nses, '\0', sizeof nses);
283 |
284 | tmp = strdup(nslist);
285 | if (tmp == NULL)
286 | return ARC_DNS_ERROR;
287 |
288 | for (ns = strtok_r(tmp, ",", &last);
289 | ns != NULL && nscount < MAXNS;
290 | ns = strtok_r(NULL, ",", &last)
291 | {
292 | memset(&in, '\0', sizeof in);
293 | # ifdef AF_INET6
294 | memset(&in6, '\0', sizeof in6);
295 | # endif /* AF_INET6 */
296 |
297 | if (inet_pton(AF_INET, ns, (struct in_addr *) &in.sin_addr,
298 | sizeof in.sin_addr) == 1)
299 | {
300 | in.sin_family= AF_INET;
301 | in.sin_port = htons(DNSPORT);
302 | memcpy(&nses[nscount].sin, &in,
303 | sizeof nses[nscount].sin);
304 | nscount++;
305 | }
306 | # ifdef AF_INET6
307 | else if (inet_pton(AF_INET6, ns,
308 | (struct in6_addr *) &in6.sin6_addr,
309 | sizeof in6.sin6_addr) == 1)
310 | {
311 | in6.sin6_family= AF_INET6;
312 | in6.sin6_port = htons(DNSPORT);
313 | memcpy(&nses[nscount].sin6, &in6,
314 | sizeof nses[nscount].sin6);
315 | nscount++;
316 | }
317 | # endif /* AF_INET6 */
318 | else
319 | {
320 | free(tmp);
321 | return ARC_DNS_ERROR;
322 | }
323 | }
324 |
325 | res = srv;
326 | res_setservers(res, nses, nscount);
327 |
328 | free(tmp);
329 | #endif /* HAVE_RES_SETSERVERS */
330 |
331 | return ARC_DNS_SUCCESS;
332 | }
333 |
--------------------------------------------------------------------------------
/libopenarc/arc-dns.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Copyright (c) 2010, 2012, 2017, The Trusted Domain Project.
3 | ** All rights reserved.
4 | */
5 |
6 | #ifndef _ARC_DNS_H_
7 | #define _ARC_DNS_H_
8 |
9 | /* libopenarc includes */
10 | #include "arc.h"
11 |
12 | /* prototypes */
13 | extern int arc_res_cancel __P((void *, void *));
14 | extern void arc_res_close __P((void *));
15 | extern int arc_res_init __P((void **));
16 | extern int arc_res_nslist __P((void *, const char *));
17 | extern int arc_res_query __P((void *, int, unsigned char *, unsigned char *,
18 | size_t, void **));
19 | extern int arc_res_waitreply __P((void *, void *, struct timeval *,
20 | size_t *, int *, int *));
21 |
22 | #endif /* ! _ARC_DNS_H_ */
23 |
--------------------------------------------------------------------------------
/libopenarc/arc-internal.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Copyright (c) 2016, The Trusted Domain Project.
3 | ** All rights reserved.
4 | */
5 |
6 | #ifndef _ARC_INTERNAL_H_
7 | #define _ARC_INTERNAL_H_
8 |
9 | /* libopenarc includes */
10 | #include "arc.h"
11 |
12 | /* the basics */
13 | #ifndef NULL
14 | # define NULL 0
15 | #endif /* ! NULL */
16 | #ifndef FALSE
17 | # define FALSE 0
18 | #endif /* ! FALSE */
19 | #ifndef TRUE
20 | # define TRUE 1
21 | #endif /* ! TRUE */
22 | #ifndef MAXPATHLEN
23 | # define MAXPATHLEN 256
24 | #endif /* ! MAXPATHLEN */
25 |
26 | #ifndef ULONG_MAX
27 | # define ULONG_MAX 0xffffffffL
28 | #endif /* ! ULONG_MAX */
29 | #ifndef ULLONG_MAX
30 | # define ULLONG_MAX 0xffffffffffffffffLL
31 | #endif /* ! ULLONG_MAX */
32 |
33 | #ifndef MIN
34 | # define MIN(x,y) ((x) < (y) ? (x) : (y))
35 | #endif /* ! MIN */
36 | #ifndef MAX
37 | # define MAX(x,y) ((x) > (y) ? (x) : (y))
38 | #endif /* ! MAX */
39 |
40 | #ifdef __STDC__
41 | # ifndef __P
42 | # define __P(x) x
43 | # endif /* ! __P */
44 | #else /* __STDC__ */
45 | # ifndef __P
46 | # define __P(x) ()
47 | # endif /* ! __P */
48 | #endif /* __STDC__ */
49 |
50 | /* limits, macros, etc. */
51 | #define BUFRSZ 1024 /* base temp buffer size */
52 | #define BASE64SIZE(x) (((x + 2) / 3) * 4)
53 | /* base64 encoding growth ratio */
54 | #define MAXADDRESS 256 /* biggest user@host we accept */
55 | #define MAXBUFRSZ 65536 /* max temp buffer size */
56 | #define MAXCNAMEDEPTH 3 /* max. CNAME recursion we allow */
57 | #define MAXHEADERS 32768 /* buffer for caching headers */
58 | #define MAXLABELS 16 /* max. labels we allow */
59 | #define MAXTAGNAME 8 /* biggest tag name */
60 |
61 | #define NPRINTABLE 95 /* number of printable characters */
62 |
63 | #define ARC_MAXHEADER 4096 /* buffer for caching one header */
64 | #define ARC_MAXHOSTNAMELEN 256 /* max. FQDN we support */
65 |
66 | /* defaults */
67 | #define DEFTMPDIR "/tmp" /* default temporary directory */
68 |
69 | /*
70 | ** ARC_KVSETTYPE -- types of key-value sets
71 | */
72 |
73 | typedef int arc_kvsettype_t;
74 |
75 | #define ARC_KVSETTYPE_ANY (-1)
76 | #define ARC_KVSETTYPE_SIGNATURE 0
77 | #define ARC_KVSETTYPE_KEY 1
78 | #define ARC_KVSETTYPE_SEAL 2
79 | #define ARC_KVSETTYPE_AR 3
80 | #define ARC_KVSETTYPE_MAX 3 /* sentinel value */
81 |
82 | /*
83 | ** ARC_HASHTYPE -- types of hashes
84 | */
85 |
86 | #define ARC_HASHTYPE_UNKNOWN (-1)
87 | #define ARC_HASHTYPE_SHA1 0
88 | #define ARC_HASHTYPE_SHA256 1
89 |
90 | /*
91 | ** ARC_KEYTYPE -- types of keys
92 | */
93 |
94 | #define ARC_KEYTYPE_UNKNOWN (-1)
95 | #define ARC_KEYTYPE_RSA 0
96 |
97 | /*
98 | ** ARC_QUERY -- types of queries
99 | */
100 |
101 | #define ARC_QUERY_UNKNOWN (-1)
102 | #define ARC_QUERY_DNS 0
103 |
104 | /*
105 | ** ARC_KVSET -- a set of parameters and values
106 | */
107 |
108 | struct arc_kvset;
109 | typedef struct arc_kvset ARC_KVSET;
110 |
111 | /*
112 | ** ARC_PLIST -- a parameter/value pair, as a linked list
113 | */
114 |
115 | struct arc_plist;
116 | typedef struct arc_plist ARC_PLIST;
117 |
118 | /*
119 | ** ARC_CANON -- canonicalization
120 | */
121 |
122 | struct arc_canon;
123 | typedef struct arc_canon ARC_CANON;
124 |
125 | #endif /* ! _ARC_INTERNAL_H_ */
126 |
--------------------------------------------------------------------------------
/libopenarc/arc-keys.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** Copyright (c) 2005-2009 Sendmail, Inc. and its suppliers.
3 | ** All rights reserved.
4 | **
5 | ** Copyright (c) 2009-2015, 2017, The Trusted Domain Project.
6 | ** All rights reserved.
7 | */
8 |
9 | /* system includes */
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 |
23 | #include "build-config.h"
24 |
25 | /* libopendkim includes */
26 | #include "arc-internal.h"
27 | #include "arc-types.h"
28 | #include "arc-keys.h"
29 | #include "arc-util.h"
30 |
31 | /* libbsd if found */
32 | #ifdef USE_BSD_H
33 | # include
34 | #endif /* USE_BSD_H */
35 |
36 | /* libstrl if needed */
37 | #ifdef USE_STRL_H
38 | # include
39 | #endif /* USE_STRL_H */
40 |
41 | /* prototypes */
42 | extern void arc_error __P((ARC_MESSAGE *, const char *, ...));
43 |
44 | /* local definitions needed for DNS queries */
45 | #define MAXPACKET 8192
46 | #if defined(__RES) && (__RES >= 19940415)
47 | # define RES_UNC_T char *
48 | #else /* __RES && __RES >= 19940415 */
49 | # define RES_UNC_T unsigned char *
50 | #endif /* __RES && __RES >= 19940415 */
51 | #ifndef T_RRSIG
52 | # define T_RRSIG 46
53 | #endif /* ! T_RRSIG */
54 |
55 | /*
56 | ** ARC_GET_KEY_DNS -- retrieve a key from DNS
57 | **
58 | ** Parameters:
59 | ** msg -- ARC_MESSAGE handle
60 | ** buf -- buffer into which to write the result
61 | ** buflen -- bytes available at "buf"
62 | **
63 | ** Return value:
64 | ** A ARC_STAT_* constant.
65 | */
66 |
67 | ARC_STAT
68 | arc_get_key_dns(ARC_MESSAGE *msg, u_char *buf, size_t buflen)
69 | {
70 | int status;
71 | int qdcount;
72 | int ancount;
73 | int error;
74 | int dnssec = ARC_DNSSEC_UNKNOWN;
75 | int c;
76 | int n = 0;
77 | int rdlength = 0;
78 | int type = -1;
79 | int class = -1;
80 | size_t anslen;
81 | void *q;
82 | ARC_LIB *lib;
83 | unsigned char *txtfound = NULL;
84 | unsigned char *p;
85 | unsigned char *cp;
86 | unsigned char *eom;
87 | unsigned char *eob;
88 | unsigned char qname[ARC_MAXHOSTNAMELEN + 1];
89 | unsigned char ansbuf[MAXPACKET];
90 | struct timeval timeout;
91 | HEADER hdr;
92 |
93 | assert(msg != NULL);
94 | assert(msg->arc_selector != NULL);
95 | assert(msg->arc_domain != NULL);
96 |
97 | lib = msg->arc_library;
98 |
99 | n = snprintf((char *) qname, sizeof qname - 1, "%s.%s.%s",
100 | msg->arc_selector, ARC_DNSKEYNAME, msg->arc_domain);
101 | if (n == -1 || n > sizeof qname - 1)
102 | {
103 | arc_error(msg, "key query name too large");
104 | return ARC_STAT_NORESOURCE;
105 | }
106 |
107 | anslen = sizeof ansbuf;
108 |
109 | timeout.tv_sec = msg->arc_timeout;
110 | timeout.tv_usec = 0;
111 |
112 | if (lib->arcl_dns_service == NULL &&
113 | lib->arcl_dns_init != NULL &&
114 | lib->arcl_dns_init(&lib->arcl_dns_service) != 0)
115 | {
116 | arc_error(msg, "cannot initialize resolver");
117 | return ARC_STAT_KEYFAIL;
118 | }
119 |
120 | status = lib->arcl_dns_start(lib->arcl_dns_service, T_TXT,
121 | qname, ansbuf, anslen, &q);
122 |
123 | if (status != 0)
124 | {
125 | arc_error(msg, "'%s' query failed", qname);
126 | return ARC_STAT_KEYFAIL;
127 | }
128 |
129 | if (lib->arcl_dns_callback == NULL)
130 | {
131 | timeout.tv_sec = msg->arc_timeout;
132 | timeout.tv_usec = 0;
133 |
134 | status = lib->arcl_dns_waitreply(lib->arcl_dns_service,
135 | q,
136 | msg->arc_timeout == 0 ? NULL
137 | : &timeout,
138 | &anslen, &error,
139 | &dnssec);
140 | }
141 | else
142 | {
143 | struct timeval master;
144 | struct timeval next;
145 | struct timeval *wt;
146 |
147 | (void) gettimeofday(&master, NULL);
148 | master.tv_sec += msg->arc_timeout;
149 |
150 | for (;;)
151 | {
152 | (void) gettimeofday(&next, NULL);
153 | next.tv_sec += lib->arcl_callback_int;
154 |
155 | arc_min_timeval(&master, &next,
156 | &timeout, &wt);
157 |
158 | status = lib->arcl_dns_waitreply(lib->arcl_dns_service,
159 | q,
160 | msg->arc_timeout == 0 ? NULL
161 | : &timeout,
162 | &anslen,
163 | &error,
164 | &dnssec);
165 |
166 | if (wt == &next)
167 | {
168 | if (status == ARC_DNS_NOREPLY ||
169 | status == ARC_DNS_EXPIRED)
170 | lib->arcl_dns_callback(msg->arc_user_context);
171 | else
172 | break;
173 | }
174 | else
175 | {
176 | break;
177 | }
178 | }
179 | }
180 |
181 | if (status == ARC_DNS_EXPIRED)
182 | {
183 | (void) lib->arcl_dns_cancel(lib->arcl_dns_service, q);
184 | arc_error(msg, "'%s' query timed out", qname);
185 | return ARC_STAT_KEYFAIL;
186 | }
187 | else if (status == ARC_DNS_ERROR)
188 | {
189 | (void) lib->arcl_dns_cancel(lib->arcl_dns_service, q);
190 | arc_error(msg, "'%s' query failed", qname);
191 | return ARC_STAT_KEYFAIL;
192 | }
193 |
194 | (void) lib->arcl_dns_cancel(lib->arcl_dns_service, q);
195 |
196 | msg->arc_dnssec_key = dnssec;
197 |
198 | /* set up pointers */
199 | memcpy(&hdr, ansbuf, sizeof hdr);
200 | cp = (u_char *) &ansbuf + HFIXEDSZ;
201 | eom = (u_char *) &ansbuf + anslen;
202 |
203 | /* skip over the name at the front of the answer */
204 | for (qdcount = ntohs((unsigned short) hdr.qdcount);
205 | qdcount > 0;
206 | qdcount--)
207 | {
208 | /* copy it first */
209 | (void) dn_expand((unsigned char *) &ansbuf, eom, cp,
210 | (char *) qname, sizeof qname);
211 |
212 | if ((n = dn_skipname(cp, eom)) < 0)
213 | {
214 | arc_error(msg, "'%s' reply corrupt", qname);
215 | return ARC_STAT_KEYFAIL;
216 | }
217 | cp += n;
218 |
219 | /* extract the type and class */
220 | if (cp + INT16SZ + INT16SZ > eom)
221 | {
222 | arc_error(msg, "'%s' reply corrupt", qname);
223 | return ARC_STAT_KEYFAIL;
224 | }
225 | GETSHORT(type, cp);
226 | GETSHORT(class, cp);
227 | }
228 |
229 | if (type != T_TXT || class != C_IN)
230 | {
231 | arc_error(msg, "'%s' unexpected reply class/type (%d/%d)",
232 | qname, class, type);
233 | return ARC_STAT_KEYFAIL;
234 | }
235 |
236 | /* if NXDOMAIN, return ARC_STAT_NOKEY */
237 | if (hdr.rcode == NXDOMAIN)
238 | {
239 | arc_error(msg, "'%s' record not found", qname);
240 | return ARC_STAT_NOKEY;
241 | }
242 |
243 | /* if truncated, we can't do it */
244 | if (arc_check_dns_reply(ansbuf, anslen, C_IN, T_TXT) == 1)
245 | {
246 | arc_error(msg, "'%s' reply truncated", qname);
247 | return ARC_STAT_KEYFAIL;
248 | }
249 |
250 | /* get the answer count */
251 | ancount = ntohs((unsigned short) hdr.ancount);
252 | if (ancount == 0)
253 | return ARC_STAT_NOKEY;
254 |
255 | /*
256 | ** Extract the data from the first TXT answer.
257 | */
258 |
259 | while (--ancount >= 0 && cp < eom)
260 | {
261 | /* grab the label, even though we know what we asked... */
262 | if ((n = dn_expand((unsigned char *) &ansbuf, eom, cp,
263 | (RES_UNC_T) qname, sizeof qname)) < 0)
264 | {
265 | arc_error(msg, "'%s' reply corrupt", qname);
266 | return ARC_STAT_KEYFAIL;
267 | }
268 | /* ...and move past it */
269 | cp += n;
270 |
271 | /* extract the type and class */
272 | if (cp + INT16SZ + INT16SZ + INT32SZ + INT16SZ > eom)
273 | {
274 | arc_error(msg, "'%s' reply corrupt", qname);
275 | return ARC_STAT_KEYFAIL;
276 | }
277 |
278 | GETSHORT(type, cp); /* TYPE */
279 | GETSHORT(class, cp); /* CLASS */
280 | /* skip the TTL */
281 | cp += INT32SZ; /* TTL */
282 | GETSHORT(n, cp); /* RDLENGTH */
283 |
284 | /* skip CNAME if found; assume it was resolved */
285 | if (type == T_CNAME)
286 | {
287 | cp += n;
288 | continue;
289 | }
290 | else if (type == T_RRSIG)
291 | {
292 | cp += n;
293 | continue;
294 | }
295 | else if (type != T_TXT)
296 | {
297 | arc_error(msg, "'%s' reply was unexpected type %d",
298 | qname, type);
299 | return ARC_STAT_KEYFAIL;
300 | }
301 |
302 | if (txtfound != NULL)
303 | {
304 | arc_error(msg, "multiple DNS replies for '%s'",
305 | qname);
306 | return ARC_STAT_MULTIDNSREPLY;
307 | }
308 |
309 | /* remember where this one started */
310 | txtfound = cp;
311 | rdlength = n;
312 |
313 | /* move forward for now */
314 | cp += n;
315 | }
316 |
317 | /* if ancount went below 0, there were no good records */
318 | if (txtfound == NULL)
319 | {
320 | arc_error(msg, "'%s' reply was unresolved CNAME", qname);
321 | return ARC_STAT_NOKEY;
322 | }
323 |
324 | /* come back to the one we found */
325 | cp = txtfound;
326 |
327 | /*
328 | ** XXX -- maybe deal with a partial reply rather than require
329 | ** it all
330 | */
331 |
332 | if (cp + rdlength > eom)
333 | {
334 | arc_error(msg, "'%s' reply corrupt", qname);
335 | return ARC_STAT_SYNTAX;
336 | }
337 |
338 | /* extract the payload */
339 | memset(buf, '\0', buflen);
340 | p = buf;
341 | eob = buf + buflen - 1;
342 | while (rdlength > 0 && p < eob)
343 | {
344 | c = *cp++;
345 | rdlength--;
346 | while (c > 0 && p < eob)
347 | {
348 | *p++ = *cp++;
349 | c--;
350 | rdlength--;
351 | }
352 | }
353 |
354 | return ARC_STAT_OK;
355 | }
356 |
357 | /*
358 | ** ARC_GET_KEY_FILE -- retrieve a key from a text file (for testing)
359 | **
360 | ** Parameters:
361 | ** msg -- ARC_MESSAGE handle
362 | ** buf -- buffer into which to write the result
363 | ** buflen -- bytes available at "buf"
364 | **
365 | ** Return value:
366 | ** A ARC_STAT_* constant.
367 | **
368 | ** Notes:
369 | ** The file opened is defined by the library option ARC_OPTS_QUERYINFO
370 | ** and must be set prior to use of this function. Failing to do
371 | ** so will cause this function to return ARC_STAT_KEYFAIL every time.
372 | ** The file should contain lines of the form:
373 | **
374 | ** ._domainkey. key-data
375 | **
376 | ** Case matching on the left is case-sensitive, but libopendkim already
377 | ** wraps the domain name to lowercase.
378 | */
379 |
380 | ARC_STAT
381 | arc_get_key_file(ARC_MESSAGE *msg, u_char *buf, size_t buflen)
382 | {
383 | int n;
384 | FILE *f;
385 | u_char *p;
386 | u_char *p2;
387 | u_char *path;
388 | char name[ARC_MAXHOSTNAMELEN + 1];
389 |
390 | assert(msg != NULL);
391 | assert(msg->arc_selector != NULL);
392 | assert(msg->arc_domain != NULL);
393 | assert(msg->arc_query == ARC_QUERY_FILE);
394 |
395 | path = msg->arc_library->arcl_queryinfo;
396 | if (path[0] == '\0')
397 | {
398 | arc_error(msg, "query file not defined");
399 | return ARC_STAT_KEYFAIL;
400 | }
401 |
402 | f = fopen((char *) path, "r");
403 | if (f == NULL)
404 | {
405 | arc_error(msg, "%s: fopen(): %s", path, strerror(errno));
406 | return ARC_STAT_KEYFAIL;
407 | }
408 |
409 | n = snprintf(name, sizeof name, "%s.%s.%s", msg->arc_selector,
410 | ARC_DNSKEYNAME, msg->arc_domain);
411 | if (n == -1 || n > sizeof name)
412 | {
413 | arc_error(msg, "key query name too large");
414 | fclose(f);
415 | return ARC_STAT_NORESOURCE;
416 | }
417 |
418 | memset(buf, '\0', buflen);
419 | while (fgets((char *) buf, buflen, f) != NULL)
420 | {
421 | if (buf[0] == '#')
422 | continue;
423 |
424 | p2 = NULL;
425 |
426 | for (p = buf; *p != '\0'; p++)
427 | {
428 | if (*p == '\n')
429 | {
430 | *p = '\0';
431 | break;
432 | }
433 | else if (isascii(*p) && isspace(*p))
434 | {
435 | *p = '\0';
436 | p2 = p + 1;
437 | }
438 | else if (p2 != NULL)
439 | {
440 | break;
441 | }
442 | }
443 |
444 | if (strcasecmp((char *) name, (char *) buf) == 0 && p2 != NULL)
445 | {
446 | memmove(buf, p2, strlen(p2) + 1);
447 | fclose(f);
448 | return ARC_STAT_OK;
449 | }
450 | }
451 |
452 | fclose(f);
453 |
454 | return ARC_STAT_NOKEY;
455 | }
456 |
--------------------------------------------------------------------------------
/libopenarc/arc-keys.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Copyright (c) 2005, 2007 Sendmail, Inc. and its suppliers.
3 | ** All rights reserved.
4 | **
5 | ** Copyright (c) 2009, 2012, The Trusted Domain Project. All rights reserved.
6 | */
7 |
8 | #ifndef _ARC_KEYS_H_
9 | #define _ARC_KEYS_H_
10 |
11 | /* libopenarc includes */
12 | #include "arc.h"
13 |
14 | /* prototypes */
15 | extern ARC_STAT arc_get_key_dns __P((ARC_MESSAGE *, u_char *, size_t));
16 | extern ARC_STAT arc_get_key_file __P((ARC_MESSAGE *, u_char *, size_t));
17 |
18 | #endif /* ! _ARC_KEYS_H_ */
19 |
--------------------------------------------------------------------------------
/libopenarc/arc-tables.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** Copyright (c) 2005-2009 Sendmail, Inc. and its suppliers.
3 | ** All rights reserved.
4 | **
5 | ** Copyright (c) 2009-2012, 2014-2016, The Trusted Domain Project.
6 | ** All rights reserved.
7 | */
8 |
9 | #include "build-config.h"
10 |
11 | /* system includes */
12 | #include
13 | #include
14 | #include
15 |
16 | /* libopenarc includes */
17 | #include "arc-tables.h"
18 | #include "arc-internal.h"
19 |
20 | /* lookup tables */
21 | static struct nametable prv_algorithms[] = /* signing algorithms */
22 | {
23 | { "rsa-sha1", ARC_SIGN_RSASHA1 },
24 | { "rsa-sha256", ARC_SIGN_RSASHA256 },
25 | { NULL, -1 },
26 | };
27 | struct nametable *algorithms = prv_algorithms;
28 |
29 | static struct nametable prv_archdrnames[] = /* header field names:types */
30 | {
31 | { ARC_AR_HDRNAME, ARC_KVSETTYPE_AR },
32 | { ARC_SEAL_HDRNAME, ARC_KVSETTYPE_SEAL },
33 | { ARC_MSGSIG_HDRNAME, ARC_KVSETTYPE_SIGNATURE },
34 | { NULL, -1 },
35 | };
36 | struct nametable *archdrnames = prv_archdrnames;
37 |
38 | static struct nametable prv_canonicalizations[] = /* canonicalizations */
39 | {
40 | { "simple", ARC_CANON_SIMPLE },
41 | { "relaxed", ARC_CANON_RELAXED },
42 | { NULL, -1 },
43 | };
44 | struct nametable *canonicalizations = prv_canonicalizations;
45 |
46 | static struct nametable prv_hashes[] = /* hashes */
47 | {
48 | { "sha1", ARC_HASHTYPE_SHA1 },
49 | { "sha256", ARC_HASHTYPE_SHA256 },
50 | { NULL, -1 },
51 | };
52 | struct nametable *hashes = prv_hashes;
53 |
54 | static struct nametable prv_keyflags[] = /* key flags */
55 | {
56 | { "y", ARC_KEYFLAG_TESTKEY },
57 | { "s", ARC_KEYFLAG_NOSUBDOMAIN },
58 | { NULL, -1 }
59 | };
60 | struct nametable *keyflags = prv_keyflags;
61 |
62 | static struct nametable prv_keytypes[] = /* key types */
63 | {
64 | { "rsa", ARC_KEYTYPE_RSA },
65 | { NULL, -1 },
66 | };
67 | struct nametable *keytypes = prv_keytypes;
68 |
69 | static struct nametable prv_querytypes[] = /* query types */
70 | {
71 | { "dns", ARC_QUERY_DNS },
72 | { NULL, -1 },
73 | };
74 | struct nametable *querytypes = prv_querytypes;
75 |
76 | static struct nametable prv_chainstatus[] = /* chain status */
77 | {
78 | { "none", ARC_CHAIN_NONE },
79 | { "fail", ARC_CHAIN_FAIL },
80 | { "pass", ARC_CHAIN_PASS },
81 | { "unknown", ARC_CHAIN_UNKNOWN },
82 | { NULL, -1 },
83 | };
84 | struct nametable *chainstatus = prv_chainstatus;
85 |
86 | static struct nametable prv_results[] = /* result codes */
87 | {
88 | { "Success", ARC_STAT_OK },
89 | { "Bad signature", ARC_STAT_BADSIG },
90 | { "No signature", ARC_STAT_NOSIG },
91 | { "No key", ARC_STAT_NOKEY },
92 | { "Unable to verify", ARC_STAT_CANTVRFY },
93 | { "Syntax error", ARC_STAT_SYNTAX },
94 | { "Resource unavailable", ARC_STAT_NORESOURCE },
95 | { "Internal error", ARC_STAT_INTERNAL },
96 | { "Revoked key", ARC_STAT_REVOKED },
97 | { "Invalid parameter", ARC_STAT_INVALID },
98 | { "Not implemented", ARC_STAT_NOTIMPLEMENT },
99 | { "Key retrieval failed", ARC_STAT_KEYFAIL },
100 | { NULL, -1 },
101 | };
102 | struct nametable *results = prv_results;
103 |
104 | static struct nametable prv_settypes[] = /* set types */
105 | {
106 | { "key", ARC_KVSETTYPE_KEY },
107 | { "ARC signature", ARC_KVSETTYPE_SIGNATURE },
108 | { "ARC seal", ARC_KVSETTYPE_SEAL },
109 | { "ARC results", ARC_KVSETTYPE_AR },
110 | { NULL, -1 },
111 | };
112 | struct nametable *settypes = prv_settypes;
113 |
114 | static struct nametable prv_sigerrors[] = /* signature parsing errors */
115 | {
116 | { "no signature error", ARC_SIGERROR_OK },
117 | { "unsupported signature version", ARC_SIGERROR_VERSION },
118 | { "invalid domain coverage", ARC_SIGERROR_DOMAIN },
119 | { "signature expired", ARC_SIGERROR_EXPIRED },
120 | { "signature timestamp in the future", ARC_SIGERROR_FUTURE },
121 | { "signature timestamp order error", ARC_SIGERROR_TIMESTAMPS },
122 | { "invalid header canonicalization", ARC_SIGERROR_INVALID_HC },
123 | { "invalid body canonicalization", ARC_SIGERROR_INVALID_BC },
124 | { "signature algorithm missing", ARC_SIGERROR_MISSING_A },
125 | { "signature algorithm invalid", ARC_SIGERROR_INVALID_A },
126 | { "header list missing", ARC_SIGERROR_MISSING_H },
127 | { "body length value invalid", ARC_SIGERROR_INVALID_L },
128 | { "query method invalid", ARC_SIGERROR_INVALID_Q },
129 | { "query option invalid", ARC_SIGERROR_INVALID_QO },
130 | { "domain tag missing", ARC_SIGERROR_MISSING_D },
131 | { "domain tag empty", ARC_SIGERROR_EMPTY_D },
132 | { "selector tag missing", ARC_SIGERROR_MISSING_S },
133 | { "selector tag empty", ARC_SIGERROR_EMPTY_S },
134 | { "signature data missing", ARC_SIGERROR_MISSING_B },
135 | { "signature data empty", ARC_SIGERROR_EMPTY_B },
136 | { "signature data corrupt", ARC_SIGERROR_CORRUPT_B },
137 | { "key not found in DNS", ARC_SIGERROR_NOKEY },
138 | { "key DNS reply corrupt", ARC_SIGERROR_DNSSYNTAX },
139 | { "key DNS query failed", ARC_SIGERROR_KEYFAIL },
140 | { "body hash missing", ARC_SIGERROR_MISSING_BH },
141 | { "body hash empty", ARC_SIGERROR_EMPTY_BH },
142 | { "body hash corrupt", ARC_SIGERROR_CORRUPT_BH },
143 | { "signature verification failed", ARC_SIGERROR_BADSIG },
144 | { "unauthorized subdomain", ARC_SIGERROR_SUBDOMAIN },
145 | { "multiple keys found", ARC_SIGERROR_MULTIREPLY },
146 | { "header list tag empty", ARC_SIGERROR_EMPTY_H },
147 | { "header list missing required entries", ARC_SIGERROR_INVALID_H },
148 | { "length tag value exceeds body size", ARC_SIGERROR_TOOLARGE_L },
149 | { "unprotected header field", ARC_SIGERROR_MBSFAILED },
150 | { "unknown key version", ARC_SIGERROR_KEYVERSION },
151 | { "unknown key hash", ARC_SIGERROR_KEYUNKNOWNHASH },
152 | { "signature-key hash mismatch", ARC_SIGERROR_KEYHASHMISMATCH },
153 | { "not an e-mail key", ARC_SIGERROR_NOTEMAILKEY },
154 | { "key type missing", ARC_SIGERROR_KEYTYPEMISSING },
155 | { "unknown key type", ARC_SIGERROR_KEYTYPEUNKNOWN },
156 | { "key revoked", ARC_SIGERROR_KEYREVOKED },
157 | { "unable to apply public key", ARC_SIGERROR_KEYDECODE },
158 | { "version missing", ARC_SIGERROR_MISSING_V },
159 | { "version empty", ARC_SIGERROR_EMPTY_V },
160 | { "signing key too small", ARC_SIGERROR_KEYTOOSMALL },
161 | { "duplicate instance", ARC_SIGERROR_DUPINSTANCE },
162 | { NULL, -1 },
163 | };
164 | struct nametable *sigerrors = prv_sigerrors;
165 |
166 | /* ===================================================================== */
167 |
168 | /*
169 | ** ARC_CODE_TO_NAME -- translate a mnemonic code to its name
170 | **
171 | ** Parameters:
172 | ** tbl -- name table
173 | ** code -- code to translate
174 | **
175 | ** Return value:
176 | ** Pointer to the name matching the provided code, or NULL if not found.
177 | */
178 |
179 | const char *
180 | arc_code_to_name(struct nametable *tbl, const int code)
181 | {
182 | int c;
183 |
184 | assert(tbl != NULL);
185 |
186 | for (c = 0; ; c++)
187 | {
188 | if (tbl[c].tbl_code == -1 && tbl[c].tbl_name == NULL)
189 | return NULL;
190 |
191 | if (tbl[c].tbl_code == code)
192 | return tbl[c].tbl_name;
193 | }
194 | }
195 |
196 | /*
197 | ** ARC_NAME_TO_CODE -- translate a name to a mnemonic code
198 | **
199 | ** Parameters:
200 | ** tbl -- name table
201 | ** name -- name to translate
202 | **
203 | ** Return value:
204 | ** A mnemonic code matching the provided name, or -1 if not found.
205 | */
206 |
207 | const int
208 | arc_name_to_code(struct nametable *tbl, const char *name)
209 | {
210 | int c;
211 |
212 | assert(tbl != NULL);
213 |
214 | for (c = 0; ; c++)
215 | {
216 | if (tbl[c].tbl_code == -1 && tbl[c].tbl_name == NULL)
217 | return -1;
218 |
219 | if (strcasecmp(tbl[c].tbl_name, name) == 0)
220 | return tbl[c].tbl_code;
221 | }
222 | }
223 |
--------------------------------------------------------------------------------
/libopenarc/arc-tables.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Copyright (c) 2005-2008 Sendmail, Inc. and its suppliers.
3 | ** All rights reserved.
4 | **
5 | ** Copyright (c) 2009, 2010, 2012, 2014-2016, The Trusted Domain Project.
6 | ** All rights reserved.
7 | */
8 |
9 | #ifndef _ARC_TABLES_H_
10 | #define _ARC_TABLES_H_
11 |
12 | #ifdef __STDC__
13 | # ifndef __P
14 | # define __P(x) x
15 | # endif /* ! __P */
16 | #else /* __STDC__ */
17 | # ifndef __P
18 | # define __P(x) ()
19 | # endif /* ! __P */
20 | #endif /* __STDC__ */
21 |
22 | /* structures */
23 | struct nametable
24 | {
25 | const char * tbl_name; /* name */
26 | const int tbl_code; /* code */
27 | };
28 |
29 | /* tables */
30 | extern struct nametable *algorithms;
31 | extern struct nametable *archdrnames;
32 | extern struct nametable *canonicalizations;
33 | extern struct nametable *chainstatus;
34 | extern struct nametable *hashes;
35 | extern struct nametable *keyflags;
36 | extern struct nametable *keytypes;
37 | extern struct nametable *settypes;
38 | extern struct nametable *sigerrors;
39 |
40 | /* prototypes */
41 | extern const char *arc_code_to_name __P((struct nametable *tbl,
42 | const int code));
43 | extern const int arc_name_to_code __P((struct nametable *tbl,
44 | const char *name));
45 |
46 | #endif /* _ARC_TABLES_H_ */
47 |
--------------------------------------------------------------------------------
/libopenarc/arc-types.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Copyright (c) 2016, 2017, The Trusted Domain Project. All rights reserved.
3 | */
4 |
5 | #ifndef _ARC_TYPES_H_
6 | #define _ARC_TYPES_H_
7 |
8 | #include "build-config.h"
9 |
10 | /* system includes */
11 | #include
12 | #ifdef HAVE_STDBOOL_H
13 | # include
14 | #endif /* HAVE_STDBOOL_H */
15 | #include
16 |
17 | /* OpenSSL includes */
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 |
24 | /* libopenarc includes */
25 | #include "arc.h"
26 | #include "arc-internal.h"
27 |
28 | /* struct arc_sha1 -- stuff needed to do a sha1 hash */
29 | struct arc_sha1
30 | {
31 | int sha1_tmpfd;
32 | BIO * sha1_tmpbio;
33 | SHA_CTX sha1_ctx;
34 | u_char sha1_out[SHA_DIGEST_LENGTH];
35 | };
36 |
37 | #ifdef HAVE_SHA256
38 | /* struct arc_sha256 -- stuff needed to do a sha256 hash */
39 | struct arc_sha256
40 | {
41 | int sha256_tmpfd;
42 | BIO * sha256_tmpbio;
43 | SHA256_CTX sha256_ctx;
44 | u_char sha256_out[SHA256_DIGEST_LENGTH];
45 | };
46 | #endif /* HAVE_SHA256 */
47 |
48 | /* struct arc_qmethod -- signature query method */
49 | struct arc_qmethod
50 | {
51 | char * qm_type;
52 | char * qm_options;
53 | struct arc_qmethod * qm_next;
54 | };
55 |
56 | /* struct arc_xtag -- signature extension tag */
57 | struct arc_xtag
58 | {
59 | char * xt_tag;
60 | char * xt_value;
61 | struct arc_xtag * xt_next;
62 | };
63 |
64 | /* struct arc_dstring -- a dynamically-sized string */
65 | struct arc_dstring
66 | {
67 | int ds_alloc;
68 | int ds_max;
69 | int ds_len;
70 | unsigned char * ds_buf;
71 | ARC_MESSAGE * ds_msg;
72 | };
73 |
74 | /* struct arc_hdrfield -- a header field */
75 | struct arc_hdrfield
76 | {
77 | uint32_t hdr_flags;
78 | size_t hdr_namelen;
79 | size_t hdr_textlen;
80 | u_char * hdr_colon;
81 | u_char * hdr_text;
82 | void * hdr_data;
83 | struct arc_hdrfield * hdr_next;
84 | };
85 |
86 | /* hdr_flags bits */
87 | #define ARC_HDR_SIGNED 0x01
88 |
89 | /* struct arc_set -- a complete single set of ARC header fields */
90 | struct arc_set
91 | {
92 | struct arc_hdrfield * arcset_aar;
93 | struct arc_hdrfield * arcset_ams;
94 | struct arc_hdrfield * arcset_as;
95 | };
96 |
97 | /* struct arc_plist -- a parameter/value pair */
98 | struct arc_plist
99 | {
100 | u_char * plist_param;
101 | u_char * plist_value;
102 | struct arc_plist * plist_next;
103 | };
104 |
105 | /* struct arc_kvset -- a set of parameter/value pairs */
106 | struct arc_kvset
107 | {
108 | _Bool set_bad;
109 | arc_kvsettype_t set_type;
110 | u_char * set_data;
111 | void * set_udata;
112 | struct arc_plist * set_plist[NPRINTABLE];
113 | struct arc_kvset * set_next;
114 | };
115 |
116 | /* struct arc_canon -- a canonicalization status handle */
117 | struct arc_canon
118 | {
119 | _Bool canon_done;
120 | _Bool canon_blankline;
121 | int canon_type;
122 | int canon_lastchar;
123 | int canon_bodystate;
124 | u_int canon_hashtype;
125 | u_int canon_blanks;
126 | size_t canon_hashbuflen;
127 | size_t canon_hashbufsize;
128 | ssize_t canon_remain;
129 | ssize_t canon_wrote;
130 | ssize_t canon_length;
131 | arc_canon_t canon_canon;
132 | u_char * canon_hashbuf;
133 | u_char * canon_hdrlist;
134 | void * canon_hash;
135 | struct arc_dstring * canon_buf;
136 | struct arc_hdrfield * canon_sigheader;
137 | struct arc_canon * canon_next;
138 | };
139 |
140 | /* struct arc_msghandle -- a complete ARC transaction context */
141 | struct arc_msghandle
142 | {
143 | _Bool arc_partial;
144 | int arc_dnssec_key;
145 | int arc_signalg;
146 | u_int arc_mode;
147 | u_int arc_nsets;
148 | u_int arc_margin;
149 | u_int arc_state;
150 | u_int arc_hdrcnt;
151 | u_int arc_timeout;
152 | u_int arc_keybits;
153 | u_int arc_keytype;
154 | u_int arc_hashtype;
155 | u_long arc_flags;
156 | arc_query_t arc_query;
157 | time_t arc_timestamp;
158 | time_t arc_sigttl;
159 | size_t arc_siglen;
160 | size_t arc_keylen;
161 | size_t arc_errorlen;
162 | size_t arc_b64keylen;
163 | ssize_t arc_bodylen;
164 | arc_canon_t arc_canonhdr;
165 | arc_canon_t arc_canonbody;
166 | ARC_CHAIN arc_cstate;
167 | ARC_SIGERROR arc_sigerror;
168 | u_char * arc_key;
169 | u_char * arc_error;
170 | u_char * arc_hdrlist;
171 | u_char * arc_domain;
172 | u_char * arc_selector;
173 | u_char * arc_authservid;
174 | u_char * arc_b64sig;
175 | u_char * arc_b64key;
176 | void * arc_signature;
177 | struct arc_qmethod * arc_querymethods;
178 | struct arc_xtag * arc_xtags;
179 | struct arc_dstring * arc_canonbuf;
180 | struct arc_dstring * arc_hdrbuf;
181 | struct arc_canon * arc_sealcanon;
182 | struct arc_canon ** arc_sealcanons;
183 | struct arc_canon * arc_valid_hdrcanon;
184 | struct arc_canon * arc_sign_hdrcanon;
185 | struct arc_canon * arc_valid_bodycanon;
186 | struct arc_canon * arc_sign_bodycanon;
187 | struct arc_canon * arc_canonhead;
188 | struct arc_canon * arc_canontail;
189 | struct arc_hdrfield * arc_hhead;
190 | struct arc_hdrfield * arc_htail;
191 | struct arc_hdrfield * arc_sealhead;
192 | struct arc_hdrfield * arc_sealtail;
193 | struct arc_kvset * arc_kvsethead;
194 | struct arc_kvset * arc_kvsettail;
195 | struct arc_set * arc_sets;
196 | ARC_LIB * arc_library;
197 | const void * arc_user_context;
198 | };
199 |
200 | /* struct arc_lib -- a ARC library context */
201 | struct arc_lib
202 | {
203 | _Bool arcl_signre;
204 | _Bool arcl_dnsinit_done;
205 | u_int arcl_flsize;
206 | uint32_t arcl_flags;
207 | time_t arcl_fixedtime;
208 | u_int arcl_callback_int;
209 | u_int arcl_minkeysize;
210 | u_int * arcl_flist;
211 | struct arc_dstring * arcl_sslerrbuf;
212 | u_char ** arcl_oversignhdrs;
213 | void (*arcl_dns_callback) (const void *context);
214 | void *arcl_dns_service;
215 | int (*arcl_dns_init) (void **srv);
216 | void (*arcl_dns_close) (void *srv);
217 | int (*arcl_dns_start) (void *srv, int type,
218 | unsigned char *query,
219 | unsigned char *buf,
220 | size_t buflen,
221 | void **qh);
222 | int (*arcl_dns_cancel) (void *srv, void *qh);
223 | int (*arcl_dns_waitreply) (void *srv,
224 | void *qh,
225 | struct timeval *to,
226 | size_t *bytes,
227 | int *error,
228 | int *dnssec);
229 | regex_t arcl_hdrre;
230 | u_char arcl_tmpdir[MAXPATHLEN + 1];
231 | u_char arcl_queryinfo[MAXPATHLEN + 1];
232 | };
233 |
234 | #endif /* _ARC_TYPES_H_ */
235 |
--------------------------------------------------------------------------------
/libopenarc/arc-util.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Copyright (c) 2016, 2017, The Trusted Domain Project. All rights reserved.
3 | */
4 |
5 | #ifndef _ARC_UTIL_H_
6 | #define _ARC_UTIL_H_
7 |
8 | #include "build-config.h"
9 |
10 | /* system includes */
11 | #include
12 | #include
13 | #ifdef HAVE_STDBOOL_H
14 | # include
15 | #endif /* HAVE_STDBOOL_H */
16 |
17 | /* libopenarc includes */
18 | #include "arc.h"
19 |
20 | extern void arc_dstring_blank __P((struct arc_dstring *));
21 | extern _Bool arc_dstring_cat __P((struct arc_dstring *, u_char *));
22 | extern _Bool arc_dstring_cat1 __P((struct arc_dstring *, int));
23 | extern _Bool arc_dstring_catn __P((struct arc_dstring *, u_char *, size_t));
24 | extern _Bool arc_dstring_copy __P((struct arc_dstring *, u_char *));
25 | extern void arc_dstring_free __P((struct arc_dstring *));
26 | extern u_char *arc_dstring_get __P((struct arc_dstring *));
27 | extern int arc_dstring_len __P((struct arc_dstring *));
28 | extern struct arc_dstring *arc_dstring_new __P((ARC_MESSAGE *, int, int));
29 | extern size_t arc_dstring_printf __P((struct arc_dstring *dstr, char *fmt,
30 | ...));
31 |
32 | extern int arc_check_dns_reply __P((unsigned char *ansbuf, size_t anslen,
33 | int xclass, int xtype));
34 |
35 | extern void arc_clobber_array __P((char **));
36 | extern void arc_collapse __P((u_char *));
37 | extern const char **arc_copy_array __P((char **));
38 | extern void arc_lowerhdr __P((u_char *));
39 | extern u_char *arc_strndup(u_char *, size_t);
40 |
41 | extern _Bool arc_hdrlist __P((u_char *, size_t, u_char **, _Bool));
42 |
43 | extern void arc_min_timeval __P((struct timeval *, struct timeval *,
44 | struct timeval *, struct timeval **));
45 |
46 | extern ARC_STAT arc_tmpfile __P((ARC_MESSAGE *, int *, _Bool));
47 |
48 | #endif /* _ARC_UTIL_H_ */
49 |
--------------------------------------------------------------------------------
/libopenarc/arc.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Copyright (c) 2016, 2017, The Trusted Domain Project. All rights reserved.
3 | */
4 |
5 | #ifndef _ARC_H_
6 | #define _ARC_H_
7 |
8 | #ifdef __cplusplus
9 | extern "C" {
10 | #endif /* __cplusplus */
11 |
12 | /* system includes */
13 | #include
14 | #include
15 | #include
16 | #ifdef HAVE_STDBOOL_H
17 | # include
18 | #endif /* HAVE_STDBOOL_H */
19 | #include
20 | #ifdef HAVE_LIMITS_H
21 | # include
22 | #endif /* HAVE_LIMITS_H */
23 |
24 | /*
25 | ** version -- 0xrrMMmmpp
26 | **
27 | ** rr == release number
28 | ** MM == major revision number
29 | ** mm == minor revision number
30 | ** pp == patch number
31 | */
32 |
33 | #define OPENARC_LIB_VERSION 0x00010000
34 |
35 | #ifdef __STDC__
36 | # ifndef __P
37 | # define __P(x) x
38 | # endif /* ! __P */
39 | #else /* __STDC__ */
40 | # ifndef __P
41 | # define __P(x) ()
42 | # endif /* ! __P */
43 | #endif /* __STDC__ */
44 |
45 | /* definitions */
46 | #define ARC_HDRMARGIN 75 /* "standard" header margin */
47 | #define ARC_MAXHEADER 4096 /* buffer for caching one header */
48 | #define ARC_MAXHOSTNAMELEN 256 /* max. FQDN we support */
49 |
50 | #define ARC_AR_HDRNAME "ARC-Authentication-Results"
51 | #define ARC_DEFAULT_MINKEYSIZE 1024
52 | #define ARC_MSGSIG_HDRNAME "ARC-Message-Signature"
53 | #define ARC_MSGSIG_HDRNAMELEN sizeof(ARC_MSGSIG_HDRNAME) - 1
54 | #define ARC_SEAL_HDRNAME "ARC-Seal"
55 | #define ARC_SEAL_HDRNAMELEN sizeof(ARC_SEAL_HDRNAME) - 1
56 |
57 | #define ARC_EXT_AR_HDRNAME "Authentication-Results"
58 |
59 | /* special DNS tokens */
60 | #define ARC_DNSKEYNAME "_domainkey"
61 |
62 | #define DKIM_VERSION_KEY "DKIM1"
63 |
64 | /*
65 | ** ARC_STAT -- status code type
66 | */
67 |
68 | typedef int ARC_STAT;
69 |
70 | #define ARC_STAT_OK 0 /* function completed successfully */
71 | #define ARC_STAT_BADSIG 1 /* signature available but failed */
72 | #define ARC_STAT_NOSIG 2 /* no signature available */
73 | #define ARC_STAT_NOKEY 3 /* public key not found */
74 | #define ARC_STAT_CANTVRFY 4 /* can't get domain key to verify */
75 | #define ARC_STAT_SYNTAX 5 /* message is not valid syntax */
76 | #define ARC_STAT_NORESOURCE 6 /* resource unavailable */
77 | #define ARC_STAT_INTERNAL 7 /* internal error */
78 | #define ARC_STAT_REVOKED 8 /* key found, but revoked */
79 | #define ARC_STAT_INVALID 9 /* invalid function parameter */
80 | #define ARC_STAT_NOTIMPLEMENT 10 /* function not implemented */
81 | #define ARC_STAT_KEYFAIL 11 /* key retrieval failed */
82 | #define ARC_STAT_MULTIDNSREPLY 12 /* multiple DNS replies */
83 | #define ARC_STAT_SIGGEN 13 /* seal generation failed */
84 |
85 | /*
86 | ** ARC_CHAIN -- chain state
87 | */
88 |
89 | typedef int ARC_CHAIN;
90 |
91 | #define ARC_CHAIN_UNKNOWN (-1) /* unknown */
92 | #define ARC_CHAIN_NONE 0 /* none */
93 | #define ARC_CHAIN_FAIL 1 /* fail */
94 | #define ARC_CHAIN_PASS 2 /* pass */
95 |
96 | /*
97 | ** ARC_CANON_T -- a canoncalization mode
98 | */
99 |
100 | typedef int arc_canon_t;
101 |
102 | #define ARC_CANON_UNKNOWN (-1)
103 | #define ARC_CANON_SIMPLE 0
104 | #define ARC_CANON_RELAXED 1
105 |
106 | /*
107 | ** ARC_SIGERROR -- signature errors
108 | */
109 |
110 | typedef int ARC_SIGERROR;
111 |
112 | #define ARC_SIGERROR_UNKNOWN (-1) /* unknown error */
113 | #define ARC_SIGERROR_OK 0 /* no error */
114 | #define ARC_SIGERROR_VERSION 1 /* unsupported version */
115 | #define ARC_SIGERROR_DOMAIN 2 /* invalid domain (d=/i=) */
116 | #define ARC_SIGERROR_EXPIRED 3 /* signature expired */
117 | #define ARC_SIGERROR_FUTURE 4 /* signature in the future */
118 | #define ARC_SIGERROR_TIMESTAMPS 5 /* x= < t= */
119 | #define ARC_SIGERROR_UNUSED 6 /* OBSOLETE */
120 | #define ARC_SIGERROR_INVALID_HC 7 /* c= invalid (header) */
121 | #define ARC_SIGERROR_INVALID_BC 8 /* c= invalid (body) */
122 | #define ARC_SIGERROR_MISSING_A 9 /* a= missing */
123 | #define ARC_SIGERROR_INVALID_A 10 /* a= invalid */
124 | #define ARC_SIGERROR_MISSING_H 11 /* h= missing */
125 | #define ARC_SIGERROR_INVALID_L 12 /* l= invalid */
126 | #define ARC_SIGERROR_INVALID_Q 13 /* q= invalid */
127 | #define ARC_SIGERROR_INVALID_QO 14 /* q= option invalid */
128 | #define ARC_SIGERROR_MISSING_D 15 /* d= missing */
129 | #define ARC_SIGERROR_EMPTY_D 16 /* d= empty */
130 | #define ARC_SIGERROR_MISSING_S 17 /* s= missing */
131 | #define ARC_SIGERROR_EMPTY_S 18 /* s= empty */
132 | #define ARC_SIGERROR_MISSING_B 19 /* b= missing */
133 | #define ARC_SIGERROR_EMPTY_B 20 /* b= empty */
134 | #define ARC_SIGERROR_CORRUPT_B 21 /* b= corrupt */
135 | #define ARC_SIGERROR_NOKEY 22 /* no key found in DNS */
136 | #define ARC_SIGERROR_DNSSYNTAX 23 /* DNS reply corrupt */
137 | #define ARC_SIGERROR_KEYFAIL 24 /* DNS query failed */
138 | #define ARC_SIGERROR_MISSING_BH 25 /* bh= missing */
139 | #define ARC_SIGERROR_EMPTY_BH 26 /* bh= empty */
140 | #define ARC_SIGERROR_CORRUPT_BH 27 /* bh= corrupt */
141 | #define ARC_SIGERROR_BADSIG 28 /* signature mismatch */
142 | #define ARC_SIGERROR_SUBDOMAIN 29 /* unauthorized subdomain */
143 | #define ARC_SIGERROR_MULTIREPLY 30 /* multiple records returned */
144 | #define ARC_SIGERROR_EMPTY_H 31 /* h= empty */
145 | #define ARC_SIGERROR_INVALID_H 32 /* h= missing req'd entries */
146 | #define ARC_SIGERROR_TOOLARGE_L 33 /* l= value exceeds body size */
147 | #define ARC_SIGERROR_MBSFAILED 34 /* "must be signed" failure */
148 | #define ARC_SIGERROR_KEYVERSION 35 /* unknown key version */
149 | #define ARC_SIGERROR_KEYUNKNOWNHASH 36 /* unknown key hash */
150 | #define ARC_SIGERROR_KEYHASHMISMATCH 37 /* sig-key hash mismatch */
151 | #define ARC_SIGERROR_NOTEMAILKEY 38 /* not an e-mail key */
152 | #define ARC_SIGERROR_UNUSED2 39 /* OBSOLETE */
153 | #define ARC_SIGERROR_KEYTYPEMISSING 40 /* key type missing */
154 | #define ARC_SIGERROR_KEYTYPEUNKNOWN 41 /* key type unknown */
155 | #define ARC_SIGERROR_KEYREVOKED 42 /* key revoked */
156 | #define ARC_SIGERROR_KEYDECODE 43 /* key couldn't be decoded */
157 | #define ARC_SIGERROR_MISSING_V 44 /* v= tag missing */
158 | #define ARC_SIGERROR_EMPTY_V 45 /* v= tag empty */
159 | #define ARC_SIGERROR_KEYTOOSMALL 46 /* too few key bits */
160 | #define ARC_SIGERROR_DUPINSTANCE 47 /* duplicate instance */
161 |
162 | /* generic DNS error codes */
163 | #define ARC_DNS_ERROR (-1) /* error in transit */
164 | #define ARC_DNS_SUCCESS 0 /* reply available */
165 | #define ARC_DNS_NOREPLY 1 /* reply not available (yet) */
166 | #define ARC_DNS_EXPIRED 2 /* no reply, query expired */
167 | #define ARC_DNS_INVALID 3 /* invalid request */
168 |
169 | /*
170 | ** ARC_SIGN -- signing method
171 | */
172 |
173 | typedef int arc_alg_t;
174 |
175 | #define ARC_SIGN_UNKNOWN (-2) /* unknown method */
176 | #define ARC_SIGN_DEFAULT (-1) /* use internal default */
177 | #define ARC_SIGN_RSASHA1 0 /* an RSA-signed SHA1 digest */
178 | #define ARC_SIGN_RSASHA256 1 /* an RSA-signed SHA256 digest */
179 |
180 | /*
181 | ** ARC_QUERY -- key query method
182 | */
183 |
184 | typedef int arc_query_t;
185 |
186 | #define ARC_QUERY_UNKNOWN (-1) /* unknown method */
187 | #define ARC_QUERY_DNS 0 /* DNS query method (per the draft) */
188 | #define ARC_QUERY_FILE 1 /* text file method (for testing) */
189 |
190 | #define ARC_QUERY_DEFAULT ARC_QUERY_DNS
191 |
192 | /*
193 | ** ARC_PARAM -- known signature parameters
194 | */
195 |
196 | typedef int arc_param_t;
197 |
198 | #define ARC_PARAM_UNKNOWN (-1) /* unknown */
199 | #define ARC_PARAM_SIGNATURE 0 /* b */
200 | #define ARC_PARAM_SIGNALG 1 /* a */
201 | #define ARC_PARAM_DOMAIN 2 /* d */
202 | #define ARC_PARAM_SELECTOR 5 /* s */
203 | #define ARC_PARAM_VERSION 7 /* v */
204 | #define ARC_PARAM_INSTANCE 8 /* i */
205 | #define ARC_PARAM_TIMESTAMP 9 /* t */
206 | #define ARC_PARAM_CHAINSTATUS 10 /* cv */
207 | #define ARC_PARAM_KEYPATH 11 /* k */
208 |
209 | /*
210 | ** ARC_OPTS -- library-specific options
211 | */
212 |
213 | typedef int arc_opt_t;
214 |
215 | /* what operations can be done */
216 | #define ARC_OP_GETOPT 0
217 | #define ARC_OP_SETOPT 1
218 |
219 | typedef int arc_opts_t;
220 |
221 | /* what options can be set */
222 | #define ARC_OPTS_FLAGS 0
223 | #define ARC_OPTS_TMPDIR 1
224 | #define ARC_OPTS_FIXEDTIME 2
225 | #define ARC_OPTS_SIGNHDRS 3
226 | #define ARC_OPTS_OVERSIGNHDRS 4
227 | #define ARC_OPTS_MINKEYSIZE 5
228 |
229 | /* flags */
230 | #define ARC_LIBFLAGS_NONE 0x00000000
231 | #define ARC_LIBFLAGS_FIXCRLF 0x00000001
232 | #define ARC_LIBFLAGS_KEEPFILES 0x00000002
233 |
234 | /* default */
235 | #define ARC_LIBFLAGS_DEFAULT ARC_LIBFLAGS_NONE
236 |
237 | /*
238 | ** ARC_DNSSEC -- results of DNSSEC queries
239 | */
240 |
241 | #define ARC_DNSSEC_UNKNOWN (-1)
242 | #define ARC_DNSSEC_BOGUS 0
243 | #define ARC_DNSSEC_INSECURE 1
244 | #define ARC_DNSSEC_SECURE 2
245 |
246 | /*
247 | ** ARC_KEYFLAG -- key flags
248 | */
249 |
250 | #define ARC_KEYFLAG_TESTKEY 0x01
251 | #define ARC_KEYFLAG_NOSUBDOMAIN 0x02
252 |
253 | /*
254 | ** ARC_MODE -- operating modes
255 | */
256 |
257 | typedef u_int arc_mode_t;
258 |
259 | #define ARC_MODE_SIGN 0x01
260 | #define ARC_MODE_VERIFY 0x02
261 |
262 | /*
263 | ** ARC_LIB -- library handle
264 | */
265 |
266 | struct arc_lib;
267 | typedef struct arc_lib ARC_LIB;
268 |
269 | /* LIBRARY FEATURES */
270 | #define ARC_FEATURE_SHA256 1
271 |
272 | #define ARC_FEATURE_MAX 1
273 |
274 | extern _Bool arc_libfeature __P((ARC_LIB *lib, u_int fc));
275 |
276 | /*
277 | ** ARC_MESSAGE -- ARC message context
278 | */
279 |
280 | struct arc_msghandle;
281 | typedef struct arc_msghandle ARC_MESSAGE;
282 |
283 | /*
284 | ** ARC_HDRFIELD -- a header field
285 | */
286 |
287 | struct arc_hdrfield;
288 | typedef struct arc_hdrfield ARC_HDRFIELD;
289 |
290 | /*
291 | ** PROTOTYPES
292 | */
293 |
294 | /*
295 | ** ARC_ERROR -- log an error message to an ARC message context
296 | **
297 | ** Parameters:
298 | ** msg -- ARC message context
299 | ** fmt -- format
300 | ** ... -- arguments
301 | **
302 | ** Return value:
303 | ** None.
304 | */
305 |
306 | extern void arc_error __P((ARC_MESSAGE *, const char *, ...));
307 |
308 | /*
309 | ** ARC_INIT -- create a library instance
310 | **
311 | ** Parameters:
312 | ** None.
313 | **
314 | ** Return value:
315 | ** A new library instance.
316 | */
317 |
318 | extern ARC_LIB *arc_init __P((void));
319 |
320 | /*
321 | ** ARC_CLOSE -- terminate a library instance
322 | **
323 | ** Parameters:
324 | ** lib -- library instance to terminate
325 | **
326 | ** Return value:
327 | ** None.
328 | */
329 |
330 | extern void arc_close __P((ARC_LIB *));
331 |
332 | /*
333 | ** ARC_GETERROR -- return any stored error string from within the DKIM
334 | ** context handle
335 | **
336 | ** Parameters:
337 | ** msg -- ARC_MESSAGE handle from which to retrieve an error string
338 | **
339 | ** Return value:
340 | ** A pointer to the stored string, or NULL if none was stored.
341 | */
342 |
343 | extern const char *arc_geterror __P((ARC_MESSAGE *));
344 |
345 | /*
346 | **
347 | ** ARC_OPTIONS -- get/set library options
348 | **
349 | ** Parameters:
350 | ** lib -- library instance of interest
351 | ** opt -- ARC_OP_GETOPT or ARC_OP_SETOPT
352 | ** arg -- ARC_OPTS_* constant
353 | ** val -- pointer to the new new value (or NULL)
354 | ** valsz -- size of the thing at val
355 | **
356 | ** Return value:
357 | ** An ARC_STAT_* constant.
358 | ** argument.
359 | */
360 |
361 | extern ARC_STAT arc_options __P((ARC_LIB *, int, int, void *, size_t));
362 |
363 | /*
364 | ** ARC_GETSSLBUF -- retrieve SSL error buffer
365 | **
366 | ** Parameters:
367 | ** lib -- library handle
368 | **
369 | ** Return value:
370 | ** Pointer to the SSL buffer in the library handle.
371 | */
372 |
373 | extern const char *arc_getsslbuf __P((ARC_LIB *));
374 |
375 | /*
376 | ** ARC_MESSAGE -- create a new message handle
377 | **
378 | ** Parameters:
379 | ** lib -- containing library instance
380 | ** canonhdr -- canonicalization to use for the header
381 | ** canonbody -- canonicalization to use for the body
382 | ** signalg -- signing algorithm
383 | ** mode -- mask of mode bits
384 | ** err -- error string (returned)
385 | **
386 | ** Return value:
387 | ** A new message instance, or NULL on failure (and "err" is updated).
388 | */
389 |
390 | extern ARC_MESSAGE *arc_message __P((ARC_LIB *, arc_canon_t, arc_canon_t,
391 | arc_alg_t, arc_mode_t, const u_char **));
392 |
393 | /*
394 | ** ARC_FREE -- deallocate a message object
395 | **
396 | ** Parameters:
397 | ** msg -- message object to be destroyed
398 | **
399 | ** Return value:
400 | ** None.
401 | */
402 |
403 | extern void arc_free __P((ARC_MESSAGE *));
404 |
405 | /*
406 | ** ARC_HEADER_FIELD -- consume a header field
407 | **
408 | ** Parameters:
409 | ** msg -- message handle
410 | ** hname -- name of the header field
411 | ** hlen -- bytes to use at hname
412 | **
413 | ** Return value:
414 | ** An ARC_STAT_* constant.
415 | */
416 |
417 | extern ARC_STAT arc_header_field __P((ARC_MESSAGE *, u_char *, size_t));
418 |
419 | /*
420 | ** ARC_EOH -- declare no more headers are coming
421 | **
422 | ** Parameters:
423 | ** msg -- message handle
424 | **
425 | ** Return value:
426 | ** An ARC_STAT_* constant.
427 | **
428 | ** Notes:
429 | ** This can probably be merged with arc_eom().
430 | */
431 |
432 | extern ARC_STAT arc_eoh __P((ARC_MESSAGE *));
433 |
434 | /*
435 | ** ARC_BODY -- process a body chunk
436 | **
437 | ** Parameters:
438 | ** msg -- an ARC message handle
439 | ** buf -- the body chunk to be processed, in canonical format
440 | ** len -- number of bytes to process starting at "buf"
441 | **
442 | ** Return value:
443 | ** A ARC_STAT_* constant.
444 | */
445 |
446 | extern ARC_STAT arc_body __P((ARC_MESSAGE *msg, u_char *buf, size_t len));
447 |
448 | /*
449 | ** ARC_EOM -- declare end of message
450 | **
451 | ** Parameters:
452 | ** msg -- message handle
453 | **
454 | ** Return value:
455 | ** An ARC_STAT_* constant.
456 | */
457 |
458 | extern ARC_STAT arc_eom __P((ARC_MESSAGE *));
459 |
460 | /*
461 | ** ARC_SET_CV -- force the chain state
462 | **
463 | ** Parameters:
464 | ** msg -- ARC_MESSAGE object
465 | ** cv -- chain state
466 | */
467 |
468 | extern void arc_set_cv(ARC_MESSAGE *, ARC_CHAIN);
469 |
470 | /*
471 | ** ARC_GETSEAL -- get the "seal" to apply to this message
472 | **
473 | ** Parameters:
474 | ** msg -- ARC_MESSAGE object
475 | ** seal -- seal to apply (returned)
476 | ** authservid -- authservid to use when generating A-R fields
477 | ** selector -- selector name
478 | ** domain -- domain name
479 | ** key -- secret key
480 | ** keylen -- key length
481 | ** ar -- Authentication-Results to be enshrined
482 | **
483 | ** Return value:
484 | ** An ARC_STAT_* constant.
485 | **
486 | ** Notes:
487 | ** The "seal" is a sequence of prepared header fields that should be
488 | ** prepended to the message in the presented order.
489 | */
490 |
491 | extern ARC_STAT arc_getseal __P((ARC_MESSAGE *, ARC_HDRFIELD **, char *,
492 | char *, char *, u_char *, size_t, u_char *));
493 |
494 | /*
495 | ** ARC_HDR_NAME -- extract name from an ARC_HDRFIELD
496 | **
497 | ** Parameters:
498 | ** hdr -- ARC_HDRFIELD object
499 | ** len -- length of the header field name (returned)
500 | **
501 | ** Return value:
502 | ** Header field name stored in the object.
503 | */
504 |
505 | extern u_char *arc_hdr_name __P((ARC_HDRFIELD *, size_t *));
506 |
507 | /*
508 | ** ARC_HDR_VALUE -- extract value from an ARC_HDRFIELD
509 | **
510 | ** Parameters:
511 | ** hdr -- ARC_HDRFIELD object
512 | **
513 | ** Return value:
514 | ** Header field value stored in the object.
515 | */
516 |
517 | extern u_char *arc_hdr_value __P((ARC_HDRFIELD *));
518 |
519 | /*
520 | ** ARC_HDR_NEXT -- return pointer to next ARC_HDRFIELD
521 | **
522 | ** Parameters:
523 | ** hdr -- ARC_HDRFIELD object
524 | **
525 | ** Return value:
526 | ** Pointer to the next ARC_HDRFIELD in the sequence.
527 | */
528 |
529 | extern ARC_HDRFIELD *arc_hdr_next __P((ARC_HDRFIELD *hdr));
530 |
531 | /*
532 | ** ARC_SSL_VERSION -- report the version of the crypto library against which
533 | ** the library was compiled, so the caller can ensure it matches
534 | **
535 | ** Parameters:
536 | ** None.
537 | **
538 | ** Return value:
539 | ** SSL library version, expressed as a uint64_t.
540 | */
541 |
542 | extern uint64_t arc_ssl_version __P((void));
543 |
544 | /*
545 | ** ARC_GET_DOMAIN -- retrieve stored domain for this message
546 | **
547 | ** Parameters:
548 | ** msg -- ARC_MESSAGE object
549 | **
550 | ** Return value:
551 | ** Pointer to string containing the domain stored for this message
552 | */
553 |
554 | extern char *arc_get_domain __P((ARC_MESSAGE *msg));
555 |
556 | /*
557 | ** ARC_CHAIN_STR -- retrieve chain status, as a string
558 | **
559 | ** Parameters:
560 | ** msg -- ARC_MESSAGE object
561 | **
562 | ** Return value:
563 | ** Pointer to string containing the current chain status.
564 | */
565 |
566 | extern const char *arc_chain_str __P((ARC_MESSAGE *msg));
567 |
568 | #ifdef __cplusplus
569 | }
570 | #endif /* __cplusplus */
571 |
572 | #endif /* _ARC_H_ */
573 |
--------------------------------------------------------------------------------
/libopenarc/base64.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** Copyright (c) 2016, The Trusted Domain Project. All rights reserved.
3 | */
4 |
5 | /* system includes */
6 | #include
7 | #include
8 |
9 | /* libopendkim includes */
10 | #include "base64.h"
11 |
12 | /* base64 alphabet */
13 | static unsigned char alphabet[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
14 |
15 | /* base64 decode stuff */
16 | static int decoder[256] =
17 | {
18 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
19 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
20 | 0, 62, 0, 0, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0,
21 | 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
22 | 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0,
23 | 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
24 | 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0, 0, 0,
25 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
26 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
27 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
28 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
29 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
30 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
31 | };
32 |
33 | #ifndef NULL
34 | # define NULL 0
35 | #endif /* ! NULL */
36 |
37 | /*
38 | ** ARC_BASE64_DECODE -- decode a base64 blob
39 | **
40 | ** Parameters:
41 | ** str -- string to decide
42 | ** buf -- where to write it
43 | ** buflen -- bytes available at "buf"
44 | **
45 | ** Return value:
46 | ** >= 0 -- success; length of what was decoded is returned
47 | ** -1 -- corrupt
48 | ** -2 -- not enough space at "buf"
49 | */
50 |
51 | int
52 | arc_base64_decode(u_char *str, u_char *buf, size_t buflen)
53 | {
54 | int n = 0;
55 | int bits = 0;
56 | int char_count = 0;
57 | u_char *c;
58 |
59 | assert(str != NULL);
60 | assert(buf != NULL);
61 |
62 | for (c = str; *c != '=' && *c != '\0'; c++)
63 | {
64 | /* end padding */
65 | if (*c == '=' || *c == '\0')
66 | break;
67 |
68 | /* skip stuff not part of the base64 alphabet (RFC2045) */
69 | if (!((*c >= 'A' && *c <= 'Z') ||
70 | (*c >= 'a' && *c <= 'z') ||
71 | (*c >= '0' && *c <= '9') ||
72 | (*c == '+') ||
73 | (*c == '/')))
74 | continue;
75 |
76 | /* everything else gets decoded */
77 | bits += decoder[(int) *c];
78 | char_count++;
79 | if (n + 3 > buflen)
80 | return -2;
81 | if (char_count == 4)
82 | {
83 | buf[n++] = (bits >> 16);
84 | buf[n++] = ((bits >> 8) & 0xff);
85 | buf[n++] = (bits & 0xff);
86 | bits = 0;
87 | char_count = 0;
88 | }
89 | else
90 | {
91 | bits <<= 6;
92 | }
93 | }
94 |
95 | /* XXX -- don't bother checking for proper termination (for now) */
96 |
97 | /* process trailing data, if any */
98 | switch (char_count)
99 | {
100 | case 0:
101 | break;
102 |
103 | case 1:
104 | /* base64 decoding incomplete; at least two bits missing */
105 | return -1;
106 |
107 | case 2:
108 | if (n + 1 > buflen)
109 | return -2;
110 | buf[n++] = (bits >> 10);
111 | break;
112 |
113 | case 3:
114 | if (n + 2 > buflen)
115 | return -2;
116 | buf[n++] = (bits >> 16);
117 | buf[n++] = ((bits >> 8) & 0xff);
118 | break;
119 | }
120 |
121 | return n;
122 | }
123 |
124 | /*
125 | ** ARC_BASE64_ENCODE -- encode base64 data
126 | **
127 | ** Parameters:
128 | ** data -- data to encode
129 | ** datalen -- bytes at "data" to encode
130 | ** buf -- where to write the encoding
131 | ** buflen -- bytes available at "buf"
132 | **
133 | ** Return value:
134 | ** >= 0 -- success; number of bytes written to "buf" returned
135 | ** -1 -- failure (not enough space at "buf")
136 | */
137 |
138 | int
139 | arc_base64_encode(u_char *data, size_t datalen, u_char *buf, size_t buflen)
140 | {
141 | int bits;
142 | int c;
143 | int char_count;
144 | size_t n;
145 |
146 | assert(data != NULL);
147 | assert(buf != NULL);
148 |
149 | bits = 0;
150 | char_count = 0;
151 | n = 0;
152 |
153 | for (c = 0; c < datalen; c++)
154 | {
155 | bits += data[c];
156 | char_count++;
157 | if (char_count == 3)
158 | {
159 | if (n + 4 > buflen)
160 | return -1;
161 |
162 | buf[n++] = alphabet[bits >> 18];
163 | buf[n++] = alphabet[(bits >> 12) & 0x3f];
164 | buf[n++] = alphabet[(bits >> 6) & 0x3f];
165 | buf[n++] = alphabet[bits & 0x3f];
166 | bits = 0;
167 | char_count = 0;
168 | }
169 | else
170 | {
171 | bits <<= 8;
172 | }
173 | }
174 |
175 | if (char_count != 0)
176 | {
177 | if (n + 4 > buflen)
178 | return -1;
179 |
180 | bits <<= 16 - (8 * char_count);
181 | buf[n++] = alphabet[bits >> 18];
182 | buf[n++] = alphabet[(bits >> 12) & 0x3f];
183 | if (char_count == 1)
184 | {
185 | buf[n++] = '=';
186 | buf[n++] = '=';
187 | }
188 | else
189 | {
190 | buf[n++] = alphabet[(bits >> 6) & 0x3f];
191 | buf[n++] = '=';
192 | }
193 | }
194 |
195 | return n;
196 | }
197 |
--------------------------------------------------------------------------------
/libopenarc/base64.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Copyright (c) 2016, The Trusted Domain Project. All rights reserved.
3 | */
4 |
5 | #ifndef _BASE64_H_
6 | #define _BASE64_H_
7 |
8 | /* system includes */
9 | #include
10 |
11 | /* prototypes */
12 | extern int arc_base64_decode(u_char *str, u_char *buf, size_t buflen);
13 | extern int arc_base64_encode(u_char *data, size_t datalen, u_char *buf,
14 | size_t buflen);
15 |
16 | #endif /* ! _BASE64_H_ */
17 |
--------------------------------------------------------------------------------
/libopenarc/docs/Makefile.am:
--------------------------------------------------------------------------------
1 | dist_doc_DATA = index.html
2 |
--------------------------------------------------------------------------------
/libopenarc/docs/index.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trusteddomainproject/OpenARC/355ee2a1ca85acccce494478991983b54f794f4e/libopenarc/docs/index.html
--------------------------------------------------------------------------------
/libopenarc/openarc.pc.in:
--------------------------------------------------------------------------------
1 | # Process this file with autoconf to produce a pkg-config metadata file.
2 |
3 | prefix=@prefix@
4 | exec_prefix=@exec_prefix@
5 | libdir=@libdir@
6 | includedir=@includedir@/openarc
7 |
8 | Name: OpenARC Library
9 | Description: Library for performing ARC signing and verification
10 | URL: http://trusteddomain.org/openarc
11 | Version: @VERSION@
12 | Libs: -L${libdir} @PTHREAD_CFLAGS@ -lopenarc
13 | Libs.private: @LIBOPENARC_LIBS_PKG@ @PTHREAD_LIBS@
14 | Cflags: -I${includedir} @PTHREAD_CFLAGS@
15 |
16 |
--------------------------------------------------------------------------------
/libopenarc/tests/Makefile.am:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trusteddomainproject/OpenARC/355ee2a1ca85acccce494478991983b54f794f4e/libopenarc/tests/Makefile.am
--------------------------------------------------------------------------------
/m4/.gitignore:
--------------------------------------------------------------------------------
1 | libtool.m4
2 | ltoptions.m4
3 | ltsugar.m4
4 | ltversion.m4
5 | lt~obsolete.m4
6 |
--------------------------------------------------------------------------------
/m4/ac_pthread.m4:
--------------------------------------------------------------------------------
1 | # ===========================================================================
2 | # http://www.gnu.org/software/autoconf-archive/ax_pthread.html
3 | # ===========================================================================
4 | #
5 | # SYNOPSIS
6 | #
7 | # AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
8 | #
9 | # DESCRIPTION
10 | #
11 | # This macro figures out how to build C programs using POSIX threads. It
12 | # sets the PTHREAD_LIBS output variable to the threads library and linker
13 | # flags, and the PTHREAD_CFLAGS output variable to any special C compiler
14 | # flags that are needed. (The user can also force certain compiler
15 | # flags/libs to be tested by setting these environment variables.)
16 | #
17 | # Also sets PTHREAD_CC to any special C compiler that is needed for
18 | # multi-threaded programs (defaults to the value of CC otherwise). (This
19 | # is necessary on AIX to use the special cc_r compiler alias.)
20 | #
21 | # NOTE: You are assumed to not only compile your program with these flags,
22 | # but also link it with them as well. e.g. you should link with
23 | # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
24 | #
25 | # If you are only building threads programs, you may wish to use these
26 | # variables in your default LIBS, CFLAGS, and CC:
27 | #
28 | # LIBS="$PTHREAD_LIBS $LIBS"
29 | # CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
30 | # CC="$PTHREAD_CC"
31 | #
32 | # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
33 | # has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
34 | # (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
35 | #
36 | # Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
37 | # PTHREAD_PRIO_INHERIT symbol is defined when compiling with
38 | # PTHREAD_CFLAGS.
39 | #
40 | # ACTION-IF-FOUND is a list of shell commands to run if a threads library
41 | # is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
42 | # is not found. If ACTION-IF-FOUND is not specified, the default action
43 | # will define HAVE_PTHREAD.
44 | #
45 | # Please let the authors know if this macro fails on any platform, or if
46 | # you have any other suggestions or comments. This macro was based on work
47 | # by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
48 | # from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
49 | # Alejandro Forero Cuervo to the autoconf macro repository. We are also
50 | # grateful for the helpful feedback of numerous users.
51 | #
52 | # Updated for Autoconf 2.68 by Daniel Richard G.
53 | #
54 | # LICENSE
55 | #
56 | # Copyright (c) 2008 Steven G. Johnson
57 | # Copyright (c) 2011 Daniel Richard G.
58 | #
59 | # This program is free software: you can redistribute it and/or modify it
60 | # under the terms of the GNU General Public License as published by the
61 | # Free Software Foundation, either version 3 of the License, or (at your
62 | # option) any later version.
63 | #
64 | # This program is distributed in the hope that it will be useful, but
65 | # WITHOUT ANY WARRANTY; without even the implied warranty of
66 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
67 | # Public License for more details.
68 | #
69 | # You should have received a copy of the GNU General Public License along
70 | # with this program. If not, see .
71 | #
72 | # As a special exception, the respective Autoconf Macro's copyright owner
73 | # gives unlimited permission to copy, distribute and modify the configure
74 | # scripts that are the output of Autoconf when processing the Macro. You
75 | # need not follow the terms of the GNU General Public License when using
76 | # or distributing such scripts, even though portions of the text of the
77 | # Macro appear in them. The GNU General Public License (GPL) does govern
78 | # all other use of the material that constitutes the Autoconf Macro.
79 | #
80 | # This special exception to the GPL applies to versions of the Autoconf
81 | # Macro released by the Autoconf Archive. When you make and distribute a
82 | # modified version of the Autoconf Macro, you may extend this special
83 | # exception to the GPL to apply to your modified version as well.
84 |
85 | #serial 21
86 |
87 | AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
88 | AC_DEFUN([AX_PTHREAD], [
89 | AC_REQUIRE([AC_CANONICAL_HOST])
90 | AC_LANG_PUSH([C])
91 | ax_pthread_ok=no
92 |
93 | # We used to check for pthread.h first, but this fails if pthread.h
94 | # requires special compiler flags (e.g. on True64 or Sequent).
95 | # It gets checked for in the link test anyway.
96 |
97 | # First of all, check if the user has set any of the PTHREAD_LIBS,
98 | # etcetera environment variables, and if threads linking works using
99 | # them:
100 | if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
101 | save_CFLAGS="$CFLAGS"
102 | CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
103 | save_LIBS="$LIBS"
104 | LIBS="$PTHREAD_LIBS $LIBS"
105 | AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
106 | AC_TRY_LINK_FUNC([pthread_join], [ax_pthread_ok=yes])
107 | AC_MSG_RESULT([$ax_pthread_ok])
108 | if test x"$ax_pthread_ok" = xno; then
109 | PTHREAD_LIBS=""
110 | PTHREAD_CFLAGS=""
111 | fi
112 | LIBS="$save_LIBS"
113 | CFLAGS="$save_CFLAGS"
114 | fi
115 |
116 | # We must check for the threads library under a number of different
117 | # names; the ordering is very important because some systems
118 | # (e.g. DEC) have both -lpthread and -lpthreads, where one of the
119 | # libraries is broken (non-POSIX).
120 |
121 | # Create a list of thread flags to try. Items starting with a "-" are
122 | # C compiler flags, and other items are library names, except for "none"
123 | # which indicates that we try without any flags at all, and "pthread-config"
124 | # which is a program returning the flags for the Pth emulation library.
125 |
126 | ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
127 |
128 | # The ordering *is* (sometimes) important. Some notes on the
129 | # individual items follow:
130 |
131 | # pthreads: AIX (must check this before -lpthread)
132 | # none: in case threads are in libc; should be tried before -Kthread and
133 | # other compiler flags to prevent continual compiler warnings
134 | # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
135 | # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
136 | # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
137 | # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
138 | # -pthreads: Solaris/gcc
139 | # -mthreads: Mingw32/gcc, Lynx/gcc
140 | # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
141 | # doesn't hurt to check since this sometimes defines pthreads too;
142 | # also defines -D_REENTRANT)
143 | # ... -mt is also the pthreads flag for HP/aCC
144 | # pthread: Linux, etcetera
145 | # --thread-safe: KAI C++
146 | # pthread-config: use pthread-config program (for GNU Pth library)
147 |
148 | case ${host_os} in
149 | solaris*)
150 |
151 | # On Solaris (at least, for some versions), libc contains stubbed
152 | # (non-functional) versions of the pthreads routines, so link-based
153 | # tests will erroneously succeed. (We need to link with -pthreads/-mt/
154 | # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
155 | # a function called by this macro, so we could check for that, but
156 | # who knows whether they'll stub that too in a future libc.) So,
157 | # we'll just look for -pthreads and -lpthread first:
158 |
159 | ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
160 | ;;
161 |
162 | darwin*)
163 | ax_pthread_flags="-pthread $ax_pthread_flags"
164 | ;;
165 | esac
166 |
167 | # Clang doesn't consider unrecognized options an error unless we specify
168 | # -Werror. We throw in some extra Clang-specific options to ensure that
169 | # this doesn't happen for GCC, which also accepts -Werror.
170 |
171 | AC_MSG_CHECKING([if compiler needs -Werror to reject unknown flags])
172 | save_CFLAGS="$CFLAGS"
173 | ax_pthread_extra_flags="-Werror"
174 | CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wunknown-warning-option -Wsizeof-array-argument"
175 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int foo(void);],[foo()])],
176 | [AC_MSG_RESULT([yes])],
177 | [ax_pthread_extra_flags=
178 | AC_MSG_RESULT([no])])
179 | CFLAGS="$save_CFLAGS"
180 |
181 | if test x"$ax_pthread_ok" = xno; then
182 | for flag in $ax_pthread_flags; do
183 |
184 | case $flag in
185 | none)
186 | AC_MSG_CHECKING([whether pthreads work without any flags])
187 | ;;
188 |
189 | -*)
190 | AC_MSG_CHECKING([whether pthreads work with $flag])
191 | PTHREAD_CFLAGS="$flag"
192 | ;;
193 |
194 | pthread-config)
195 | AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
196 | if test x"$ax_pthread_config" = xno; then continue; fi
197 | PTHREAD_CFLAGS="`pthread-config --cflags`"
198 | PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
199 | ;;
200 |
201 | *)
202 | AC_MSG_CHECKING([for the pthreads library -l$flag])
203 | PTHREAD_LIBS="-l$flag"
204 | ;;
205 | esac
206 |
207 | save_LIBS="$LIBS"
208 | save_CFLAGS="$CFLAGS"
209 | LIBS="$PTHREAD_LIBS $LIBS"
210 | CFLAGS="$CFLAGS $PTHREAD_CFLAGS $ax_pthread_extra_flags"
211 |
212 | # Check for various functions. We must include pthread.h,
213 | # since some functions may be macros. (On the Sequent, we
214 | # need a special flag -Kthread to make this header compile.)
215 | # We check for pthread_join because it is in -lpthread on IRIX
216 | # while pthread_create is in libc. We check for pthread_attr_init
217 | # due to DEC craziness with -lpthreads. We check for
218 | # pthread_cleanup_push because it is one of the few pthread
219 | # functions on Solaris that doesn't have a non-functional libc stub.
220 | # We try pthread_create on general principles.
221 | AC_LINK_IFELSE([AC_LANG_PROGRAM([#include
222 | static void routine(void *a) { a = 0; }
223 | static void *start_routine(void *a) { return a; }],
224 | [pthread_t th; pthread_attr_t attr;
225 | pthread_create(&th, 0, start_routine, 0);
226 | pthread_join(th, 0);
227 | pthread_attr_init(&attr);
228 | pthread_cleanup_push(routine, 0);
229 | pthread_cleanup_pop(0) /* ; */])],
230 | [ax_pthread_ok=yes],
231 | [])
232 |
233 | LIBS="$save_LIBS"
234 | CFLAGS="$save_CFLAGS"
235 |
236 | AC_MSG_RESULT([$ax_pthread_ok])
237 | if test "x$ax_pthread_ok" = xyes; then
238 | break;
239 | fi
240 |
241 | PTHREAD_LIBS=""
242 | PTHREAD_CFLAGS=""
243 | done
244 | fi
245 |
246 | # Various other checks:
247 | if test "x$ax_pthread_ok" = xyes; then
248 | save_LIBS="$LIBS"
249 | LIBS="$PTHREAD_LIBS $LIBS"
250 | save_CFLAGS="$CFLAGS"
251 | CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
252 |
253 | # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
254 | AC_MSG_CHECKING([for joinable pthread attribute])
255 | attr_name=unknown
256 | for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
257 | AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ],
258 | [int attr = $attr; return attr /* ; */])],
259 | [attr_name=$attr; break],
260 | [])
261 | done
262 | AC_MSG_RESULT([$attr_name])
263 | if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
264 | AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$attr_name],
265 | [Define to necessary symbol if this constant
266 | uses a non-standard name on your system.])
267 | fi
268 |
269 | AC_MSG_CHECKING([if more special flags are required for pthreads])
270 | flag=no
271 | case ${host_os} in
272 | aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";;
273 | osf* | hpux*) flag="-D_REENTRANT";;
274 | solaris*)
275 | if test "$GCC" = "yes"; then
276 | flag="-D_REENTRANT"
277 | else
278 | # TODO: What about Clang on Solaris?
279 | flag="-mt -D_REENTRANT"
280 | fi
281 | ;;
282 | esac
283 | AC_MSG_RESULT([$flag])
284 | if test "x$flag" != xno; then
285 | PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
286 | fi
287 |
288 | AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
289 | [ax_cv_PTHREAD_PRIO_INHERIT], [
290 | AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]],
291 | [[int i = PTHREAD_PRIO_INHERIT;]])],
292 | [ax_cv_PTHREAD_PRIO_INHERIT=yes],
293 | [ax_cv_PTHREAD_PRIO_INHERIT=no])
294 | ])
295 | AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"],
296 | [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])])
297 |
298 | LIBS="$save_LIBS"
299 | CFLAGS="$save_CFLAGS"
300 |
301 | # More AIX lossage: compile with *_r variant
302 | if test "x$GCC" != xyes; then
303 | case $host_os in
304 | aix*)
305 | AS_CASE(["x/$CC"],
306 | [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
307 | [#handle absolute path differently from PATH based program lookup
308 | AS_CASE(["x$CC"],
309 | [x/*],
310 | [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])],
311 | [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])])
312 | ;;
313 | esac
314 | fi
315 | fi
316 |
317 | test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
318 |
319 | AC_SUBST([PTHREAD_LIBS])
320 | AC_SUBST([PTHREAD_CFLAGS])
321 | AC_SUBST([PTHREAD_CC])
322 |
323 | # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
324 | if test x"$ax_pthread_ok" = xyes; then
325 | ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1])
326 | :
327 | else
328 | ax_pthread_ok=no
329 | $2
330 | fi
331 | AC_LANG_POP
332 | ])dnl AX_PTHREAD
333 |
--------------------------------------------------------------------------------
/openarc/.gitignore:
--------------------------------------------------------------------------------
1 | .deps/*
2 | openarc.8
3 | openarc.conf.5
4 | openarc
5 | openarc.conf.simple
6 |
--------------------------------------------------------------------------------
/openarc/Makefile.am:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2010-2014, 2016, 2017, The Trusted Domain Project.
2 | # All rights reserved.
3 |
4 | if DEBUG
5 | AM_CFLAGS = -g
6 | endif
7 |
8 | if BUILD_FILTER
9 | dist_doc_DATA = openarc.conf.sample openarc.conf.simple
10 |
11 | man_MANS = openarc.conf.5 openarc.8
12 |
13 | sbin_PROGRAMS = openarc
14 | openarc_SOURCES = config.c config.h openarc.c openarc.h openarc-ar.c openarc-ar.h openarc-config.h openarc-crypto.c openarc-crypto.h openarc-test.c openarc-test.h util.c util.h
15 | openarc_CC = $(PTHREAD_CC)
16 | openarc_CFLAGS = $(PTHREAD_CFLAGS) $(LIBCRYPTO_CFLAGS)
17 | openarc_CPPFLAGS = -I$(srcdir)/../libopenarc $(LIBCRYPTO_CPPFLAGS) $(LIBMILTER_INCDIRS)
18 | openarc_LDFLAGS = $(LIBCRYPTO_LIBDIRS) $(LIBMILTER_LIBDIRS) $(PTHREAD_CFLAGS)
19 | openarc_LDADD = ../libopenarc/libopenarc.la $(LIBMILTER_LIBS) $(LIBCRYPTO_LIBS) $(PTHREAD_LIBS) $(LIBRESOLV)
20 | endif
21 |
--------------------------------------------------------------------------------
/openarc/config.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** Copyright (c) 2006-2009 Sendmail, Inc. and its suppliers.
3 | ** All rights reserved.
4 | **
5 | ** Copyright (c) 2009-2015, 2017, The Trusted Domain Project.
6 | ** All rights reserved.
7 | */
8 |
9 | #include "build-config.h"
10 |
11 | /* for Solaris */
12 | #ifndef _REENTRANT
13 | # define _REENTRANT
14 | #endif /* _REENTRANT */
15 |
16 | /* system includes */
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 |
23 | /* libopenarc includes */
24 | #include
25 |
26 | /* libbsd if found */
27 | #ifdef USE_BSD_H
28 | # include
29 | #endif /* USE_BSD_H */
30 |
31 | /* libstrl if needed */
32 | #ifdef USE_STRL_H
33 | # include
34 | #endif /* USE_STRL_H */
35 |
36 | /* opendkim includes */
37 | #include "config.h"
38 |
39 | /* limits */
40 | #define BUFRSZ 1024 /* generic buffer size */
41 | #define MAXLEVEL 5 /* max. include recursion */
42 |
43 | #ifndef FALSE
44 | # define FALSE 0
45 | #endif /* ! FALSE */
46 | #ifndef TRUE
47 | # define TRUE 1
48 | #endif /* ! TRUE */
49 |
50 | /* prototypes */
51 | static void config_attach __P((struct config *, struct config **));
52 |
53 | /* errors */
54 | #define CONF_UNKNOWN (-1) /* unknown status */
55 | #define CONF_SUCCESS 0 /* no error */
56 | #define CONF_MISSING 1 /* required value missing */
57 | #define CONF_UNRECOG 2 /* unrecognized parameter */
58 | #define CONF_ILLEGAL 3 /* illegal value */
59 | #define CONF_NESTING 4 /* "include" nesting too deep */
60 | #define CONF_READING 5 /* error reading (see errno) */
61 | #define CONF_NMEMORY 6 /* malloc() failure */
62 |
63 | /* statics */
64 | static int conf_error; /* configuration error number */
65 |
66 | /*
67 | ** CONFIG_GETLINE -- read a line of arbitrary length from a stream
68 | **
69 | ** Parameters:
70 | ** in -- input stream
71 | **
72 | ** Return value:
73 | ** NULL on EOF, otherwise a newly-allocated string containing the next
74 | ** line from "in".
75 | */
76 |
77 | static char *
78 | config_getline(FILE *in)
79 | {
80 | int c;
81 | size_t asize = BUFRSZ;
82 | size_t len = 0;
83 | char *new = NULL;
84 |
85 | assert(in != NULL);
86 |
87 | new = malloc(asize);
88 | if (new == NULL)
89 | return NULL;
90 | new[0] = '\0';
91 |
92 | for (;;)
93 | {
94 | c = fgetc(in);
95 | if (c == '\n')
96 | {
97 | break;
98 | }
99 | else if (c == EOF)
100 | {
101 | if (len == 0)
102 | {
103 | free(new);
104 | new = NULL;
105 | }
106 | break;
107 | }
108 |
109 | if (len == asize - 1)
110 | {
111 | char *newnew;
112 |
113 | asize += BUFRSZ;
114 |
115 | newnew = realloc(new, asize);
116 | if (newnew == NULL)
117 | {
118 | free(new);
119 | return NULL;
120 | }
121 |
122 | new = newnew;
123 | }
124 |
125 | new[len++] = c;
126 | new[len] = '\0';
127 | }
128 |
129 | return new;
130 | }
131 |
132 | /*
133 | ** CONFIG_ATTACH -- attach one config to another
134 | **
135 | ** Parameters:
136 | ** c1 -- configuration to attach
137 | ** c2 -- configuration to which to attach
138 | **
139 | ** Return value:
140 | ** None.
141 | */
142 |
143 | static void
144 | config_attach(struct config *c1, struct config **c2)
145 | {
146 | struct config *prev;
147 | struct config *cur;
148 |
149 | assert(c1 != NULL);
150 |
151 | if (*c2 == NULL)
152 | {
153 | *c2 = c1;
154 | }
155 | else
156 | {
157 | prev = NULL;
158 |
159 | for (cur = c1; cur != NULL; cur = cur->cfg_next)
160 | prev = cur;
161 |
162 | prev->cfg_next = *c2;
163 | }
164 | }
165 |
166 | /*
167 | ** CONFIG_LOAD_LEVEL -- load configuration from a file (internal version)
168 | **
169 | ** Parameters:
170 | ** file -- path from which to load; NULL or "-" implies stdin
171 | ** cd -- array of (struct configdef) elements containing the
172 | ** configuration syntax to assert
173 | ** line -- line number where an error occurred (updated)
174 | ** outpath -- configuration file in which error occurred (updated)
175 | ** outpathlen -- bytes available at "outpath"
176 | ** level -- nesting level
177 | ** deprecated -- string containing list of deprecated items (updated)
178 | **
179 | ** Return value:
180 | ** Pointer to a (struct config) which is the head of a list of
181 | ** loaded configuration items, or NULL on error; if NULL, "line" is
182 | ** updated to indicate which line number contained the error and,
183 | ** if the configuration file being parsed was not the one referenced
184 | ** by "in", then "path" will be updated to point to the filename
185 | ** that was being processed.
186 | */
187 |
188 | static struct config *
189 | config_load_level(char *file, struct configdef *def,
190 | unsigned int *line, char *outpath, size_t outpathlen,
191 | int level, char **deprecated)
192 | {
193 | int n = -1;
194 | int err = 0;
195 | unsigned int myline = 0;
196 | int value = -1;
197 | FILE *in;
198 | char *p;
199 | char *s;
200 | char *str = NULL;
201 | char *buf;
202 | struct config *new = NULL;
203 | struct config *cur = NULL;
204 |
205 | assert(def != NULL);
206 |
207 | if (level > MAXLEVEL)
208 | {
209 | conf_error = CONF_NESTING;
210 | return NULL;
211 | }
212 |
213 | if (file == NULL || (file[0] == '-' && file[1] == '\0'))
214 | {
215 | in = stdin;
216 | file = "(stdin)";
217 | }
218 | else
219 | {
220 | in = fopen(file, "r");
221 | if (in == NULL)
222 | {
223 | conf_error = CONF_READING;
224 | if (line != NULL)
225 | *line = myline;
226 | if (outpath != NULL)
227 | strlcpy(outpath, file, outpathlen);
228 | return NULL;
229 | }
230 | }
231 |
232 | while ((buf = config_getline(in)) != NULL)
233 | {
234 | myline++;
235 | str = NULL;
236 |
237 | /* read a line; truncate at carriage return, newline, or "#" */
238 | for (p = buf; *p != '\0'; p++)
239 | {
240 | if (*p == '#' || *p == 0x0D)
241 | {
242 | *p = '\0';
243 | break;
244 | }
245 | }
246 |
247 | /* break down the line */
248 | p = strtok_r(buf, " \t", &s);
249 | if (p != NULL)
250 | {
251 | /* recognize the directive? */
252 | for (n = 0; ; n++)
253 | {
254 | /* nope */
255 | if (def[n].cd_name == NULL)
256 | {
257 | conf_error = CONF_UNRECOG;
258 | err = 1;
259 | break;
260 | }
261 |
262 | if (strcasecmp(def[n].cd_name, p) == 0)
263 | break;
264 | }
265 |
266 | if (!err)
267 | {
268 | char *q;
269 |
270 | /* skip leading whitespace on value */
271 | for (p = s; *p == ' ' || *p == '\t'; p++)
272 | continue;
273 |
274 | /* ...and trim trailing whitespace */
275 | q = p + strlen(p) - 1;
276 | while (p <= q && (*q == '\t' || *q == ' '))
277 | *q-- = '\0';
278 | }
279 |
280 | if (*p == '\0' && !err)
281 | {
282 | conf_error = CONF_MISSING;
283 | err = 1;
284 | }
285 |
286 | if (!err)
287 | {
288 | char *q;
289 |
290 | switch (def[n].cd_type)
291 | {
292 | case CONFIG_TYPE_DEPRECATED:
293 | if (deprecated == NULL)
294 | {
295 | break;
296 | }
297 | else if (*deprecated == NULL)
298 | {
299 | *deprecated = strdup(def[n].cd_name);
300 | }
301 | else
302 | {
303 | char *new;
304 | size_t oldlen;
305 | size_t newlen;
306 |
307 | oldlen = strlen(*deprecated);
308 | newlen = oldlen + 2 +
309 | strlen(def[n].cd_name);
310 | new = realloc(*deprecated,
311 | newlen);
312 | if (new != NULL)
313 | {
314 | new[oldlen] = ',';
315 | new[oldlen + 1] = '\0';
316 | strlcat(*deprecated,
317 | def[n].cd_name,
318 | newlen);
319 | *deprecated = new;
320 | }
321 | }
322 | break;
323 |
324 | case CONFIG_TYPE_STRING:
325 | case CONFIG_TYPE_INCLUDE:
326 | str = p;
327 | break;
328 |
329 | case CONFIG_TYPE_BOOLEAN:
330 | if (p[0] == 't' ||
331 | p[0] == 'T' ||
332 | p[0] == 'y' ||
333 | p[0] == 'Y' ||
334 | p[0] == '1')
335 | {
336 | value = 1;
337 | }
338 | else if (p[0] == 'f' ||
339 | p[0] == 'F' ||
340 | p[0] == 'n' ||
341 | p[0] == 'N' ||
342 | p[0] == '0')
343 | {
344 | value = 0;
345 | }
346 | else
347 | {
348 | conf_error = CONF_ILLEGAL;
349 | err = 1;
350 | }
351 |
352 | break;
353 |
354 | case CONFIG_TYPE_INTEGER:
355 | value = (int) strtol(p, &q, 0);
356 | if (*q != '\0')
357 | {
358 | conf_error = CONF_ILLEGAL;
359 | err = 1;
360 | }
361 |
362 | str = p;
363 |
364 | break;
365 |
366 | default:
367 | assert(0);
368 | /* NOTREACHED */
369 | return NULL;
370 | }
371 | }
372 | }
373 | else
374 | {
375 | free(buf);
376 | continue; /* blank line */
377 | }
378 |
379 | /* a parse error, or only one argument, is no good */
380 | if (err)
381 | {
382 | config_free(cur);
383 |
384 | if (line != NULL)
385 | *line = myline;
386 | if (outpath != NULL)
387 | strlcpy(outpath, file, outpathlen);
388 |
389 | if (in != stdin)
390 | fclose(in);
391 |
392 | free(buf);
393 | return NULL;
394 | }
395 |
396 | if (def[n].cd_type != CONFIG_TYPE_INCLUDE &&
397 | def[n].cd_type != CONFIG_TYPE_DEPRECATED)
398 | {
399 | new = (struct config *) malloc(sizeof(struct config));
400 | if (new == NULL)
401 | {
402 | config_free(cur);
403 |
404 | conf_error = CONF_NMEMORY;
405 |
406 | if (line != NULL)
407 | *line = myline;
408 | if (outpath != NULL)
409 | strlcpy(outpath, file, outpathlen);
410 |
411 | if (in != stdin)
412 | fclose(in);
413 |
414 | free(buf);
415 | return NULL;
416 | }
417 |
418 | new->cfg_next = cur;
419 | new->cfg_name = def[n].cd_name;
420 | new->cfg_type = def[n].cd_type;
421 | }
422 |
423 | switch (def[n].cd_type)
424 | {
425 | case CONFIG_TYPE_INCLUDE:
426 | {
427 | struct config *incl;
428 |
429 | incl = config_load_level(str, def, line, outpath,
430 | outpathlen, level + 1, deprecated);
431 | if (incl == NULL)
432 | {
433 | if (in != stdin)
434 | fclose(in);
435 |
436 | free(buf);
437 | return NULL;
438 | }
439 |
440 | config_attach(incl, &cur);
441 | new = incl;
442 |
443 | break;
444 | }
445 |
446 | case CONFIG_TYPE_STRING:
447 | new->cfg_string = strdup(str);
448 | break;
449 |
450 | case CONFIG_TYPE_BOOLEAN:
451 | new->cfg_bool = (_Bool) value;
452 | break;
453 |
454 | case CONFIG_TYPE_INTEGER:
455 | new->cfg_int = value;
456 | break;
457 |
458 | case CONFIG_TYPE_DEPRECATED:
459 | break;
460 |
461 | default:
462 | assert(0);
463 | }
464 |
465 | cur = new;
466 |
467 | free(buf);
468 | }
469 |
470 | conf_error = CONF_SUCCESS;
471 |
472 | if (in != stdin)
473 | fclose(in);
474 |
475 | if (myline == 0 || cur == NULL)
476 | {
477 | cur = (struct config *) malloc(sizeof *cur);
478 | if (cur != NULL)
479 | {
480 | cur->cfg_bool = FALSE;
481 | cur->cfg_type = CONFIG_TYPE_STRING;
482 | cur->cfg_int = 0;
483 | cur->cfg_name = "";
484 | cur->cfg_string = NULL;
485 | cur->cfg_next = NULL;
486 |
487 | return cur;
488 | }
489 | else
490 | {
491 | conf_error = CONF_NMEMORY;
492 |
493 | if (line != NULL)
494 | *line = myline;
495 | if (outpath != NULL)
496 | strlcpy(outpath, file, outpathlen);
497 |
498 | return NULL;
499 | }
500 | }
501 | else
502 | {
503 | return cur;
504 | }
505 | }
506 |
507 | /*
508 | ** CONFIG_ERROR -- return a string describing a configuration error
509 | **
510 | ** Parameters:
511 | ** None.
512 | **
513 | ** Return value:
514 | ** Pointer to a NULL-terminated string explaining the last error.
515 | */
516 |
517 | char *
518 | config_error(void)
519 | {
520 | switch (conf_error)
521 | {
522 | case CONF_SUCCESS:
523 | return "no error";
524 |
525 | case CONF_MISSING:
526 | return "required value missing";
527 |
528 | case CONF_UNRECOG:
529 | return "unrecognized parameter";
530 |
531 | case CONF_ILLEGAL:
532 | return "illegal value";
533 |
534 | case CONF_NESTING:
535 | return "nesting too deep";
536 |
537 | case CONF_READING:
538 | return "error reading configuration file";
539 |
540 | case CONF_NMEMORY:
541 | return "memory allocation failure";
542 |
543 | case CONF_UNKNOWN:
544 | default:
545 | return "unknown error";
546 | }
547 |
548 | /* NOTREACHED */
549 | }
550 |
551 | /*
552 | ** CONFIG_FREE -- release memory associated with a config list
553 | **
554 | ** Parameters:
555 | ** head -- head of the config list
556 | **
557 | ** Return value:
558 | ** None.
559 | */
560 |
561 | void
562 | config_free(struct config *head)
563 | {
564 | struct config *next;
565 | struct config *cur;
566 |
567 | cur = head;
568 | while (cur != NULL)
569 | {
570 | next = cur->cfg_next;
571 | if (cur->cfg_type == CONFIG_TYPE_STRING &&
572 | cur->cfg_string != NULL)
573 | free(cur->cfg_string);
574 | free(cur);
575 | cur = next;
576 | }
577 | }
578 |
579 | /*
580 | ** CONFIG_LOAD -- load configuration from a file
581 | **
582 | ** Parameters:
583 | ** file -- path from which to load; NULL or "-" implies stdin
584 | ** cd -- array of (struct configdef) elements containing the
585 | ** configuration syntax to assert
586 | ** line -- line number where an error occurred (updated)
587 | ** path -- configuration file in which error occurred (updated)
588 | ** pathlen -- number of bytes available at "path"
589 | **
590 | ** Return value:
591 | ** Pointer to a (struct config) which is the head of a list of
592 | ** loaded configuration items, or NULL on error; if NULL, "line" is
593 | ** updated to indicate which line number contained the error and,
594 | ** if the configuration file being parsed was not the one referenced
595 | ** by "in", then "path" will be updated to point to the filename
596 | ** that was being processed.
597 | */
598 |
599 | struct config *
600 | config_load(char *file, struct configdef *def, unsigned int *line,
601 | char *path, size_t pathlen, char **deprecated)
602 | {
603 | conf_error = CONF_UNKNOWN;
604 |
605 | return config_load_level(file, def, line, path, pathlen, 0, deprecated);
606 | }
607 |
608 | /*
609 | ** CONFIG_CHECK -- verify that stuff marked "required" is present
610 | **
611 | ** Parameters:
612 | ** head -- head of config list
613 | ** def -- definitions
614 | **
615 | ** Return value:
616 | ** Name of the first parameter in "def" that was marked "required"
617 | ** yet absent from the configuration parsed, or NULL if nothing
618 | ** required was missing.
619 | */
620 |
621 | char *
622 | config_check(struct config *head, struct configdef *def)
623 | {
624 | int n;
625 | struct config *cur;
626 |
627 | assert(head != NULL);
628 | assert(def != NULL);
629 |
630 | conf_error = CONF_UNKNOWN;
631 |
632 | for (n = 0; ; n++)
633 | {
634 | if (def[n].cd_name == NULL)
635 | {
636 | conf_error = CONF_SUCCESS;
637 | return NULL;
638 | }
639 | if (!def[n].cd_req)
640 | continue;
641 |
642 | for (cur = head; cur != NULL; cur = cur->cfg_next)
643 | {
644 | if (cur->cfg_name == def[n].cd_name)
645 | break;
646 | }
647 |
648 | if (cur == NULL)
649 | {
650 | conf_error = CONF_MISSING;
651 |
652 | return def[n].cd_name;
653 | }
654 | }
655 |
656 | /* NOTREACHED */
657 | }
658 |
659 | /*
660 | ** CONFIG_GET -- retrieve a parameter's value
661 | **
662 | ** Parameter:
663 | ** head -- head of config list
664 | ** name -- name of the parameter of interest
665 | ** value -- where to write the result (returned)
666 | ** size -- bytes available at "value"
667 | **
668 | ** Return value:
669 | ** 1 if the data was found, 0 otherwise, -1 if the request was illegal
670 | **
671 | ** Notes:
672 | ** "value" is a (void *). It can be used directly, such as:
673 | **
674 | ** int x;
675 | **
676 | ** (void) config_get(conflist, "MyInteger", (void *) &x);
677 | */
678 |
679 | int
680 | config_get(struct config *head, const char *name, void *value, size_t size)
681 | {
682 | struct config *cur;
683 |
684 | assert(head != NULL);
685 | assert(name != NULL);
686 | assert(value != NULL);
687 | assert(size > 0);
688 |
689 | conf_error = CONF_UNKNOWN;
690 |
691 | for (cur = head; cur != NULL; cur = cur->cfg_next)
692 | {
693 | if (strcasecmp(cur->cfg_name, name) == 0)
694 | {
695 | switch (cur->cfg_type)
696 | {
697 | case CONFIG_TYPE_BOOLEAN:
698 | if (size != sizeof(_Bool))
699 | {
700 | conf_error = CONF_ILLEGAL;
701 | return -1;
702 | }
703 | memcpy(value, &cur->cfg_bool, size);
704 | break;
705 |
706 | case CONFIG_TYPE_INTEGER:
707 | if (size != sizeof(int))
708 | {
709 | conf_error = CONF_ILLEGAL;
710 | return -1;
711 | }
712 | memcpy(value, &cur->cfg_int, size);
713 | break;
714 |
715 | case CONFIG_TYPE_INCLUDE:
716 | conf_error = CONF_ILLEGAL;
717 | return -1;
718 |
719 | default:
720 | if (size != sizeof(char *))
721 | {
722 | conf_error = CONF_ILLEGAL;
723 | return -1;
724 | }
725 | memcpy(value, &cur->cfg_string, size);
726 | break;
727 | }
728 |
729 | return 1;
730 | }
731 | }
732 |
733 | conf_error = CONF_SUCCESS;
734 |
735 | return 0;
736 | }
737 |
738 | /*
739 | ** CONFIG_VALIDNAME -- return True IFF the name provided was valid
740 | **
741 | ** Parameters:
742 | ** def -- configuration definition
743 | ** name -- name of value of interest
744 | **
745 | ** Return value:
746 | ** True IFF "name" was defined inside "cd"
747 | */
748 |
749 | _Bool
750 | config_validname(struct configdef *def, const char *name)
751 | {
752 | unsigned int n;
753 |
754 | assert(def != NULL);
755 | assert(name != NULL);
756 |
757 | for (n = 0; ; n++)
758 | {
759 | if (def[n].cd_name == NULL)
760 | return FALSE;
761 |
762 | if (strcasecmp(name, def[n].cd_name) == 0 &&
763 | def[n].cd_type != CONFIG_TYPE_DEPRECATED)
764 | return TRUE;
765 | }
766 |
767 | assert(0);
768 | /* NOTREACHED */
769 | }
770 |
771 | /*
772 | ** CONFIG_DUMP -- dump configuration contents
773 | **
774 | ** Parameters:
775 | ** cfg -- head of assembled configuration values
776 | ** out -- stream to which to write
777 | ** name -- name of value of interest
778 | **
779 | ** Return value:
780 | ** Number of items that matched.
781 | */
782 |
783 | unsigned int
784 | config_dump(struct config *cfg, FILE *out, const char *name)
785 | {
786 | unsigned int nprinted = 0;
787 | struct config *cur;
788 |
789 | assert(cfg != NULL);
790 | assert(out != NULL);
791 |
792 | for (cur = cfg; cur != NULL; cur = cur->cfg_next)
793 | {
794 | if (name != NULL)
795 | {
796 | if (strcasecmp(name, cur->cfg_name) != 0)
797 | continue;
798 | }
799 | else
800 | {
801 | fprintf(out, "%p: \"%s\" ", cur, cur->cfg_name);
802 | }
803 |
804 | switch (cur->cfg_type)
805 | {
806 | case CONFIG_TYPE_STRING:
807 | fprintf(out, "%s\n", cur->cfg_string);
808 | break;
809 |
810 | case CONFIG_TYPE_INTEGER:
811 | fprintf(out, "%d\n", cur->cfg_int);
812 | break;
813 |
814 | case CONFIG_TYPE_BOOLEAN:
815 | fprintf(out, "%s\n", cur->cfg_bool ? "True" : "False");
816 | break;
817 |
818 | default:
819 | assert(0);
820 | }
821 |
822 | nprinted++;
823 | }
824 |
825 | return nprinted;
826 | }
827 |
--------------------------------------------------------------------------------
/openarc/config.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Copyright (c) 2006-2008 Sendmail, Inc. and its suppliers.
3 | ** All rights reserved.
4 | **
5 | ** Copyright (c) 2009-2012, 2015, The Trusted Domain Project. All rights reserved.
6 | **
7 | */
8 |
9 | #ifndef _CONFIG_H_
10 | #define _CONFIG_H_
11 |
12 | #include "build-config.h"
13 |
14 | /* system includes */
15 | #include
16 | #ifdef HAVE_STDBOOL_H
17 | # include
18 | #endif /* HAVE_STDBOOL_H */
19 | #include
20 |
21 | /* types and things */
22 | #define CONFIG_TYPE_STRING 0
23 | #define CONFIG_TYPE_INTEGER 1
24 | #define CONFIG_TYPE_BOOLEAN 2
25 | #define CONFIG_TYPE_INCLUDE 3
26 | #define CONFIG_TYPE_DEPRECATED 4
27 |
28 | struct config
29 | {
30 | _Bool cfg_bool;
31 | u_int cfg_type;
32 | int cfg_int;
33 | char * cfg_name;
34 | char * cfg_string;
35 | struct config * cfg_next;
36 | };
37 |
38 | struct configdef
39 | {
40 | char * cd_name;
41 | u_int cd_type;
42 | _Bool cd_req;
43 | };
44 |
45 | /* prototypes */
46 | extern char *config_check __P((struct config *, struct configdef *));
47 | extern unsigned int config_dump __P((struct config *, FILE *, const char *));
48 | extern char *config_error __P((void));
49 | extern void config_free __P((struct config *));
50 | extern int config_get __P((struct config *, const char *, void *, size_t));
51 | extern struct config *config_load __P((char *, struct configdef *,
52 | unsigned int *, char *, size_t, char **));
53 | extern _Bool config_validname __P((struct configdef *, const char *));
54 |
55 | #endif /* _CONFIG_H_ */
56 |
--------------------------------------------------------------------------------
/openarc/openarc-ar.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** Copyright (c) 2007-2009 Sendmail, Inc. and its suppliers.
3 | ** All rights reserved.
4 | **
5 | ** Copyright (c) 2009, 2011-2014, 2016, 2017, The Trusted Domain Project.
6 | ** All rights reserved.
7 | */
8 |
9 | #include "build-config.h"
10 |
11 | /* system includes */
12 | #include
13 | #include
14 | #ifdef HAVE_STDBOOL_H
15 | # include
16 | #endif /* HAVE_STDBOOL_H */
17 | #include
18 | #include
19 | #include
20 | #ifdef ARTEST
21 | # include
22 | #endif /* ARTEST */
23 |
24 | /* libbsd if found */
25 | #ifdef USE_BSD_H
26 | # include
27 | #endif /* USE_BSD_H */
28 |
29 | /* libstrl if needed */
30 | #ifdef USE_STRL_H
31 | # include
32 | #endif /* USE_STRL_H */
33 |
34 | /* openarc includes */
35 | #include "openarc-ar.h"
36 |
37 | /* macros */
38 | #define ARES_ENDOF(x) ((x) + sizeof(x) - 1)
39 | #define ARES_STRORNULL(x) ((x) == NULL ? "(null)" : (x))
40 | #define ARES_TOKENS ";=."
41 | #define ARES_TOKENS2 "=."
42 |
43 | #define ARES_MAXTOKENS 512
44 |
45 | /* tables */
46 | struct lookup
47 | {
48 | char * str;
49 | int code;
50 | };
51 |
52 | struct lookup methods[] =
53 | {
54 | { "arc", ARES_METHOD_ARC },
55 | { "auth", ARES_METHOD_AUTH },
56 | { "dkim", ARES_METHOD_DKIM },
57 | { "dkim-adsp", ARES_METHOD_DKIMADSP },
58 | { "dkim-atps", ARES_METHOD_DKIMATPS },
59 | { "dmarc", ARES_METHOD_DMARC },
60 | { "domainkeys", ARES_METHOD_DOMAINKEYS },
61 | { "iprev", ARES_METHOD_IPREV },
62 | { "rrvs", ARES_METHOD_RRVS },
63 | { "sender-id", ARES_METHOD_SENDERID },
64 | { "smime", ARES_METHOD_SMIME },
65 | { "spf", ARES_METHOD_SPF },
66 | { NULL, ARES_METHOD_UNKNOWN }
67 | };
68 |
69 | struct lookup aresults[] =
70 | {
71 | { "none", ARES_RESULT_NONE },
72 | { "pass", ARES_RESULT_PASS },
73 | { "fail", ARES_RESULT_FAIL },
74 | { "policy", ARES_RESULT_POLICY },
75 | { "neutral", ARES_RESULT_NEUTRAL },
76 | { "temperror", ARES_RESULT_TEMPERROR },
77 | { "permerror", ARES_RESULT_PERMERROR },
78 | { "nxdomain", ARES_RESULT_NXDOMAIN },
79 | { "signed", ARES_RESULT_SIGNED },
80 | { "unknown", ARES_RESULT_UNKNOWN },
81 | { "discard", ARES_RESULT_DISCARD },
82 | { "softfail", ARES_RESULT_SOFTFAIL },
83 | { NULL, ARES_RESULT_UNKNOWN }
84 | };
85 |
86 | struct lookup ptypes[] =
87 | {
88 | { "smtp", ARES_PTYPE_SMTP },
89 | { "header", ARES_PTYPE_HEADER },
90 | { "body", ARES_PTYPE_BODY },
91 | { "policy", ARES_PTYPE_POLICY },
92 | { NULL, ARES_PTYPE_UNKNOWN }
93 | };
94 |
95 | /*
96 | ** ARES_TOKENIZE -- tokenize a string
97 | **
98 | ** Parameters:
99 | ** input -- input string
100 | ** outbuf -- output buffer
101 | ** outbuflen -- number of bytes available at "outbuf"
102 | ** tokens -- array of token pointers
103 | ** ntokens -- number of token pointers available at "tokens"
104 | **
105 | ** Return value:
106 | ** -1 -- not enough space at "outbuf" for tokenizing
107 | ** other -- number of tokens identified; may be greater than
108 | ** "ntokens" if there were more tokens found than there were
109 | ** pointers available.
110 | */
111 |
112 | static int
113 | ares_tokenize(u_char *input, u_char *outbuf, size_t outbuflen,
114 | u_char **tokens, int ntokens)
115 | {
116 | _Bool quoted = FALSE;
117 | _Bool escaped = FALSE;
118 | _Bool intok = FALSE;
119 | int n = 0;
120 | int parens = 0;
121 | u_char *p;
122 | u_char *q;
123 | u_char *end;
124 |
125 | assert(input != NULL);
126 | assert(outbuf != NULL);
127 | assert(outbuflen > 0);
128 | assert(tokens != NULL);
129 | assert(ntokens > 0);
130 |
131 | q = outbuf;
132 | end = outbuf + outbuflen - 1;
133 |
134 | for (p = input; *p != '\0' && q <= end; p++)
135 | {
136 | if (escaped) /* escape */
137 | {
138 | if (!intok)
139 | {
140 | if (n < ntokens)
141 | tokens[n] = q;
142 | intok = TRUE;
143 | }
144 |
145 | *q = *p;
146 | q++;
147 | escaped = FALSE;
148 | }
149 | else if (*p == '\\') /* escape */
150 | {
151 | escaped = TRUE;
152 | }
153 | else if (*p == '"' && parens == 0) /* quoting */
154 | {
155 | quoted = !quoted;
156 |
157 | if (!intok)
158 | {
159 | if (n < ntokens)
160 | tokens[n] = q;
161 | intok = TRUE;
162 | }
163 | }
164 | else if (*p == '(' && !quoted) /* "(" (comment) */
165 | {
166 | parens++;
167 |
168 | if (!intok)
169 | {
170 | if (n < ntokens)
171 | tokens[n] = q;
172 | intok = TRUE;
173 | }
174 |
175 | *q = *p;
176 | q++;
177 |
178 | }
179 | else if (*p == ')' && !quoted) /* ")" (comment) */
180 | {
181 | if (parens > 0)
182 | {
183 | parens--;
184 |
185 | if (parens == 0)
186 | {
187 | intok = FALSE;
188 | n++;
189 |
190 | *q = ')';
191 | q++;
192 | if (q <= end)
193 | {
194 | *q = '\0';
195 | q++;
196 | }
197 | }
198 | }
199 | }
200 | else if (quoted) /* quoted character */
201 | {
202 | *q = *p;
203 | q++;
204 | }
205 | else if (isascii(*p) && isspace(*p)) /* whitespace */
206 | {
207 | if (quoted || parens > 0)
208 | {
209 | if (intok)
210 | {
211 | *q = *p;
212 | q++;
213 | }
214 | }
215 | else if (intok)
216 | {
217 | intok = FALSE;
218 | *q = '\0';
219 | q++;
220 | n++;
221 | }
222 | }
223 | else if (strchr(ARES_TOKENS, *p) != NULL) /* delimiter */
224 | {
225 | if (parens > 0)
226 | {
227 | *q = *p;
228 | q++;
229 | continue;
230 | }
231 |
232 | if (intok)
233 | {
234 | intok = FALSE;
235 | *q = '\0';
236 | q++;
237 | n++;
238 | }
239 |
240 | if (q <= end)
241 | {
242 | *q = *p;
243 | if (n < ntokens)
244 | {
245 | tokens[n] = q;
246 | n++;
247 | }
248 | q++;
249 | }
250 |
251 | if (q <= end)
252 | {
253 | *q = '\0';
254 | q++;
255 | }
256 | }
257 | else /* other */
258 | {
259 | if (!intok)
260 | {
261 | if (n < ntokens)
262 | tokens[n] = q;
263 | intok = TRUE;
264 | }
265 |
266 | *q = *p;
267 | q++;
268 | }
269 | }
270 |
271 | if (q >= end)
272 | return -1;
273 |
274 | if (intok)
275 | {
276 | *q = '\0';
277 | n++;
278 | }
279 |
280 | return n;
281 | }
282 |
283 | /*
284 | ** ARES_CONVERT -- convert a string to its code
285 | **
286 | ** Parameters:
287 | ** table -- in which table to look up
288 | ** str -- string to find
289 | **
290 | ** Return value:
291 | ** A code translation of "str".
292 | */
293 |
294 | static int
295 | ares_convert(struct lookup *table, char *str)
296 | {
297 | int c;
298 |
299 | assert(table != NULL);
300 | assert(str != NULL);
301 |
302 | for (c = 0; ; c++)
303 | {
304 | if (table[c].str == NULL ||
305 | strcasecmp(table[c].str, str) == 0)
306 | return table[c].code;
307 | }
308 |
309 | /* NOTREACHED */
310 | }
311 |
312 | /*
313 | ** ARES_XCONVERT -- convert a code to its string
314 | **
315 | ** Parameters:
316 | ** table -- in which table to look up
317 | ** code -- code to find
318 | **
319 | ** Return value:
320 | ** A string translation of "code".
321 | */
322 |
323 | static char *
324 | ares_xconvert(struct lookup *table, int code)
325 | {
326 | int c;
327 |
328 | assert(table != NULL);
329 |
330 | for (c = 0; ; c++)
331 | {
332 | if (table[c].str == NULL || table[c].code == code)
333 | return table[c].str;
334 | }
335 |
336 | /* NOTREACHED */
337 | }
338 |
339 | /*
340 | ** ARES_DEDUP -- if we've gotten multiple results of the same method,
341 | ** discard the older one
342 | **
343 | ** Parameters:
344 | ** ar -- pointer to a (struct authres)
345 | ** n -- the last one that was loaded
346 | **
347 | ** Return value:
348 | ** TRUE iff a de-duplication happened, leaving the result referenced by
349 | ** "n" open.
350 | */
351 |
352 | static _Bool
353 | ares_dedup(struct authres *ar, int n)
354 | {
355 | int c;
356 |
357 | for (c = 0; c < n; c++)
358 | {
359 | if (ar->ares_result[c].result_method == ar->ares_result[n].result_method &&
360 | ar->ares_result[c].result_method != ARES_METHOD_DKIM)
361 | {
362 | memcpy(&ar->ares_result[c], &ar->ares_result[n],
363 | sizeof(ar->ares_result[c]));
364 | return TRUE;
365 | }
366 | }
367 |
368 | return FALSE;
369 | }
370 |
371 | /*
372 | ** ARES_PARSE -- parse an Authentication-Results: header, return a
373 | ** structure containing a parsed result
374 | **
375 | ** Parameters:
376 | ** hdr -- NULL-terminated contents of an Authentication-Results:
377 | ** header field
378 | ** ar -- a pointer to a (struct authres) loaded by values after parsing
379 | **
380 | ** Return value:
381 | ** 0 on success, -1 on failure.
382 | */
383 |
384 | int
385 | ares_parse(u_char *hdr, struct authres *ar)
386 | {
387 | int n;
388 | int ntoks;
389 | int c;
390 | int r = 0;
391 | int state;
392 | int prevstate;
393 | u_char tmp[ARC_MAXHEADER + 2];
394 | u_char *tokens[ARES_MAXTOKENS];
395 |
396 | assert(hdr != NULL);
397 | assert(ar != NULL);
398 |
399 | memset(ar, '\0', sizeof *ar);
400 | memset(tmp, '\0', sizeof tmp);
401 |
402 | ntoks = ares_tokenize(hdr, tmp, sizeof tmp, tokens, ARES_MAXTOKENS);
403 | if (ntoks == -1 || ntoks > ARES_MAXTOKENS)
404 | return -1;
405 |
406 | prevstate = -1;
407 | state = 0;
408 | n = 0;
409 |
410 | for (c = 0; c < ntoks; c++)
411 | {
412 | if (tokens[c][0] == '(') /* comment */
413 | {
414 | strlcpy((char *) ar->ares_result[n - 1].result_comment,
415 | (char *) tokens[c],
416 | sizeof ar->ares_result[n - 1].result_comment);
417 | continue;
418 | }
419 |
420 | switch (state)
421 | {
422 | case 0: /* authserv-id */
423 | if (!isascii(tokens[c][0]) ||
424 | !isalnum(tokens[c][0]))
425 | return -1;
426 |
427 | if (tokens[c][0] == ';')
428 | {
429 | prevstate = state;
430 | state = 3;
431 | }
432 | else
433 | {
434 | strlcat((char *) ar->ares_host,
435 | (char *) tokens[c],
436 | sizeof ar->ares_host);
437 |
438 | prevstate = state;
439 | state = 1;
440 | }
441 |
442 | break;
443 |
444 | case 1: /* [version] */
445 | if (tokens[c][0] == '.' &&
446 | tokens[c][1] == '\0' && prevstate == 0)
447 | {
448 | strlcat((char *) ar->ares_host,
449 | (char *) tokens[c],
450 | sizeof ar->ares_host);
451 |
452 | prevstate = state;
453 | state = 0;
454 |
455 | break;
456 | }
457 |
458 | if (tokens[c][0] == ';')
459 | {
460 | prevstate = state;
461 | state = 3;
462 | }
463 | else if (isascii(tokens[c][0]) &&
464 | isdigit(tokens[c][0]))
465 | {
466 | strlcpy((char *) ar->ares_version,
467 | (char *) tokens[c],
468 | sizeof ar->ares_version);
469 |
470 | prevstate = state;
471 | state = 2;
472 | }
473 | else
474 | {
475 | return -1;
476 | }
477 |
478 | break;
479 |
480 | case 2: /* ; */
481 | if (tokens[c][0] != ';' ||
482 | tokens[c][1] != '\0')
483 | return -1;
484 |
485 | prevstate = state;
486 | state = 3;
487 |
488 | break;
489 |
490 | case 3: /* method/none */
491 | if (n == 0 || !ares_dedup(ar, n))
492 | n++;
493 |
494 | if (n >= MAXARESULTS)
495 | return 0;
496 |
497 | r = 0;
498 |
499 | if (strcasecmp((char *) tokens[c], "none") == 0)
500 | {
501 | if (n > 0)
502 | n--;
503 |
504 | prevstate = state;
505 | state = 14;
506 |
507 | continue;
508 | }
509 |
510 | ar->ares_result[n - 1].result_method = ares_convert(methods,
511 | (char *) tokens[c]);
512 | prevstate = state;
513 | state = 4;
514 |
515 | break;
516 |
517 | case 4: /* = */
518 | if (tokens[c][0] != '=' ||
519 | tokens[c][1] != '\0')
520 | return -1;
521 |
522 | prevstate = state;
523 | state = 5;
524 |
525 | break;
526 |
527 | case 5: /* result */
528 | ar->ares_result[n - 1].result_result = ares_convert(aresults,
529 | (char *) tokens[c]);
530 | ar->ares_result[n - 1].result_comment[0] = '\0';
531 | prevstate = state;
532 | state = 6;
533 |
534 | break;
535 |
536 | case 7: /* = (reason) */
537 | if (tokens[c][0] != '=' ||
538 | tokens[c][1] != '\0')
539 | return -1;
540 |
541 | prevstate = state;
542 | state = 8;
543 |
544 | break;
545 |
546 | case 8:
547 | strlcpy((char *) ar->ares_result[n - 1].result_reason,
548 | (char *) tokens[c],
549 | sizeof ar->ares_result[n - 1].result_reason);
550 |
551 | prevstate = state;
552 | state = 9;
553 |
554 | break;
555 |
556 | case 6: /* reason/propspec */
557 | if (tokens[c][0] == ';' && /* neither */
558 | tokens[c][1] == '\0')
559 | {
560 | prevstate = state;
561 | state = 3;
562 |
563 | continue;
564 | }
565 |
566 | if (strcasecmp((char *) tokens[c], "reason") == 0)
567 | { /* reason */
568 | prevstate = state;
569 | state = 7;
570 |
571 | continue;
572 | }
573 | else
574 | {
575 | prevstate = state;
576 | state = 9;
577 | }
578 |
579 | /* FALLTHROUGH */
580 |
581 | case 9: /* ptype */
582 | if (prevstate == 13 &&
583 | strchr(ARES_TOKENS2, tokens[c][0]) != NULL &&
584 | tokens[c][1] == '\0')
585 | {
586 | r--;
587 |
588 | strlcat((char *) ar->ares_result[n - 1].result_value[r],
589 | (char *) tokens[c],
590 | sizeof ar->ares_result[n - 1].result_value[r]);
591 |
592 | prevstate = state;
593 | state = 13;
594 |
595 | continue;
596 | }
597 |
598 | if (tokens[c][0] == ';' &&
599 | tokens[c][1] == '\0')
600 | {
601 | prevstate = state;
602 | state = 3;
603 |
604 | continue;
605 | }
606 | else
607 | {
608 | ares_ptype_t x;
609 |
610 | x = ares_convert(ptypes, (char *) tokens[c]);
611 | if (x == ARES_PTYPE_UNKNOWN)
612 | return -1;
613 |
614 | if (r < MAXPROPS)
615 | ar->ares_result[n - 1].result_ptype[r] = x;
616 |
617 | prevstate = state;
618 | state = 10;
619 | }
620 |
621 | break;
622 |
623 | case 10: /* . */
624 | if (tokens[c][0] != '.' ||
625 | tokens[c][1] != '\0')
626 | return -1;
627 |
628 | prevstate = state;
629 | state = 11;
630 |
631 | break;
632 |
633 | case 11: /* property */
634 | if (r < MAXPROPS)
635 | {
636 | strlcpy((char *) ar->ares_result[n - 1].result_property[r],
637 | (char *) tokens[c],
638 | sizeof ar->ares_result[n - 1].result_property[r]);
639 | }
640 |
641 | prevstate = state;
642 | state = 12;
643 |
644 | break;
645 |
646 | case 12: /* = */
647 | if (tokens[c][0] != '=' ||
648 | tokens[c][1] != '\0')
649 | return -1;
650 |
651 | prevstate = state;
652 | state = 13;
653 |
654 | break;
655 |
656 | case 13: /* value */
657 | if (r < MAXPROPS)
658 | {
659 | strlcat((char *) ar->ares_result[n - 1].result_value[r],
660 | (char *) tokens[c],
661 | sizeof ar->ares_result[n - 1].result_value[r]);
662 | r++;
663 | ar->ares_result[n - 1].result_props = r;
664 | }
665 |
666 | prevstate = state;
667 | state = 9;
668 |
669 | break;
670 |
671 | case 14: /* only reached in case of a malformed A-R */
672 | return -1;
673 |
674 | break; /* not reached, just to make some lint-like sw happy */
675 | }
676 | }
677 |
678 | /* error out on non-terminal states */
679 | if (state == 4 || state == 7 || state == 10 ||
680 | state == 11 || state == 12)
681 | return -1;
682 |
683 | if (n > 1)
684 | {
685 | if (ares_dedup(ar, n - 1))
686 | n--;
687 | }
688 |
689 | ar->ares_count = n;
690 |
691 | return 0;
692 | }
693 |
694 | /*
695 | ** ARES_GETMETHOD -- translate a method code to its name
696 | **
697 | ** Parameters:
698 | ** method -- method to convert
699 | **
700 | ** Return value:
701 | ** String matching the provided method, or NULL.
702 | */
703 |
704 | const char *
705 | ares_getmethod(ares_method_t method)
706 | {
707 | return (const char *) ares_xconvert(methods, method);
708 | }
709 |
710 | /*
711 | ** ARES_GETRESULT -- translate a result code to its name
712 | **
713 | ** Parameters:
714 | ** result -- result to convert
715 | **
716 | ** Return value:
717 | ** String matching the provided result, or NULL.
718 | */
719 |
720 | const char *
721 | ares_getresult(ares_result_t result)
722 | {
723 | return (const char *) ares_xconvert(aresults, result);
724 | }
725 |
726 | /*
727 | ** ARES_GETPTYPE -- translate a ptype code to its name
728 | **
729 | ** Parameters:
730 | ** ptype -- ptype to convert
731 | **
732 | ** Return value:
733 | ** String matching the provided ptype, or NULL.
734 | */
735 |
736 | const char *
737 | ares_getptype(ares_ptype_t ptype)
738 | {
739 | return (const char *) ares_xconvert(ptypes, ptype);
740 | }
741 |
742 | #ifdef ARTEST
743 | /*
744 | ** MAIN -- program mainline
745 | **
746 | ** Parameters:
747 | ** argc, argv -- the usual
748 | **
749 | ** Return value:
750 | ** EX_USAGE or EX_OK
751 | */
752 |
753 | # define NTOKENS 256
754 |
755 | int
756 | main(int argc, char **argv)
757 | {
758 | int c;
759 | int d;
760 | int status;
761 | char *p;
762 | char *progname;
763 | struct authres ar;
764 | u_char buf[1024];
765 | u_char *toks[NTOKENS];
766 |
767 | progname = (p = strrchr(argv[0], '/')) == NULL ? argv[0] : p + 1;
768 |
769 | if (argc != 2)
770 | {
771 | printf("%s: usage: %s header-value\n", progname, progname);
772 | return EX_USAGE;
773 | }
774 |
775 | c = ares_tokenize(argv[1], buf, sizeof buf, toks, NTOKENS);
776 | for (d = 0; d < c; d++)
777 | printf("token %d = '%s'\n", d, toks[d]);
778 |
779 | printf("\n");
780 |
781 | status = ares_parse(argv[1], &ar);
782 | if (status == -1)
783 | {
784 | printf("%s: ares_parse() returned -1\n", progname);
785 | return EX_OK;
786 | }
787 |
788 | printf("%d result%s found\n", ar.ares_count,
789 | ar.ares_count == 1 ? "" : "s");
790 |
791 | printf("authserv-id '%s'\n", ar.ares_host);
792 | printf("version '%s'\n", ar.ares_version);
793 |
794 | for (c = 0; c < ar.ares_count; c++)
795 | {
796 | printf("result #%d, %d propert%s\n", c,
797 | ar.ares_result[c].result_props,
798 | ar.ares_result[c].result_props == 1 ? "y" : "ies");
799 |
800 | printf("\tmethod \"%s\"\n",
801 | ares_xconvert(methods,
802 | ar.ares_result[c].result_method));
803 | printf("\tresult \"%s\"\n",
804 | ares_xconvert(aresults,
805 | ar.ares_result[c].result_result));
806 | printf("\treason \"%s\"\n", ar.ares_result[c].result_reason);
807 |
808 | for (d = 0; d < ar.ares_result[c].result_props; d++)
809 | {
810 | printf("\tproperty #%d\n", d);
811 | printf("\t\tptype \"%s\"\n",
812 | ares_xconvert(ptypes,
813 | ar.ares_result[c].result_ptype[d]));
814 | printf("\t\tproperty \"%s\"\n",
815 | ar.ares_result[c].result_property[d]);
816 | printf("\t\tvalue \"%s\"\n",
817 | ar.ares_result[c].result_value[d]);
818 | }
819 | }
820 | }
821 | #endif /* ARTEST */
822 |
--------------------------------------------------------------------------------
/openarc/openarc-ar.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Copyright (c) 2007-2009 Sendmail, Inc. and its suppliers.
3 | ** All rights reserved.
4 | **
5 | ** Copyright (c) 2009, 2012-2014, 2016, 2017, The Trusted Domain Project.
6 | ** All rights reserved.
7 | */
8 |
9 | #ifndef _OPENARC_AR_H_
10 | #define _OPENARC_AR_H_
11 |
12 | /* system includes */
13 | /* system includes */
14 | #include
15 |
16 | /* openarc includes */
17 | #include "openarc.h"
18 |
19 | /* limits */
20 | #define MAXARESULTS 16
21 | #define MAXPROPS 16
22 | #define MAXAVALUE 256
23 |
24 | /* ARES_METHOD_T -- type for specifying an authentication method */
25 | typedef int ares_method_t;
26 |
27 | #define ARES_METHOD_UNKNOWN (-1)
28 | #define ARES_METHOD_AUTH 0
29 | #define ARES_METHOD_DKIM 1
30 | #define ARES_METHOD_DOMAINKEYS 2
31 | #define ARES_METHOD_SENDERID 3
32 | #define ARES_METHOD_SPF 4
33 | #define ARES_METHOD_DKIMADSP 5
34 | #define ARES_METHOD_IPREV 6
35 | #define ARES_METHOD_DKIMATPS 7
36 | #define ARES_METHOD_DMARC 8
37 | #define ARES_METHOD_SMIME 9
38 | #define ARES_METHOD_RRVS 10
39 | #define ARES_METHOD_ARC 11
40 |
41 | /* ARES_RESULT_T -- type for specifying an authentication result */
42 | typedef int ares_result_t;
43 |
44 | #define ARES_RESULT_UNDEFINED (-1)
45 | #define ARES_RESULT_PASS 0
46 | #define ARES_RESULT_UNASSIGNED 1 /* UNASSIGNED */
47 | #define ARES_RESULT_SOFTFAIL 2
48 | #define ARES_RESULT_NEUTRAL 3
49 | #define ARES_RESULT_TEMPERROR 4
50 | #define ARES_RESULT_PERMERROR 5
51 | #define ARES_RESULT_NONE 6
52 | #define ARES_RESULT_FAIL 7
53 | #define ARES_RESULT_POLICY 8
54 | #define ARES_RESULT_NXDOMAIN 9
55 | #define ARES_RESULT_SIGNED 10
56 | #define ARES_RESULT_UNKNOWN 11
57 | #define ARES_RESULT_DISCARD 12
58 |
59 | /* ARES_PTYPE_T -- type for specifying an authentication property */
60 | typedef int ares_ptype_t;
61 |
62 | #define ARES_PTYPE_UNKNOWN (-1)
63 | #define ARES_PTYPE_SMTP 0
64 | #define ARES_PTYPE_HEADER 1
65 | #define ARES_PTYPE_BODY 2
66 | #define ARES_PTYPE_POLICY 3
67 |
68 | /* RESULT structure -- a single result */
69 | struct result
70 | {
71 | int result_props;
72 | ares_method_t result_method;
73 | ares_result_t result_result;
74 | ares_ptype_t result_ptype[MAXPROPS];
75 | unsigned char result_reason[MAXAVALUE + 1];
76 | unsigned char result_comment[MAXAVALUE + 1];
77 | unsigned char result_property[MAXPROPS][MAXAVALUE + 1];
78 | unsigned char result_value[MAXPROPS][MAXAVALUE + 1];
79 | };
80 |
81 | /* AUTHRES structure -- the entire header parsed */
82 | struct authres
83 | {
84 | int ares_count;
85 | unsigned char ares_host[ARC_MAXHOSTNAMELEN + 1];
86 | unsigned char ares_version[MAXAVALUE + 1];
87 | struct result ares_result[MAXARESULTS];
88 | };
89 |
90 | /*
91 | ** ARES_PARSE -- parse an Authentication-Results: header, return a
92 | ** structure containing a parsed result
93 | **
94 | ** Parameters:
95 | ** hdr -- NULL-terminated contents of an Authentication-Results:
96 | ** header field
97 | ** ar -- a pointer to a (struct authres) loaded by values after parsing
98 | **
99 | ** Return value:
100 | ** 0 on success, -1 on failure.
101 | */
102 |
103 | extern int ares_parse __P((u_char *, struct authres *));
104 |
105 | extern const char *ares_getmethod __P((ares_method_t));
106 | extern const char *ares_getresult __P((ares_result_t));
107 | extern const char *ares_getptype __P((ares_ptype_t));
108 |
109 | #endif /* _OPENARC_AR_H_ */
110 |
--------------------------------------------------------------------------------
/openarc/openarc-config.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Copyright (c) 2016, 2017, The Trusted Domain Project. All rights reserved.
3 | */
4 |
5 | #ifndef _ARC_CONFIG_H_
6 | #define _ARC_CONFIG_H_
7 |
8 | #include "build-config.h"
9 |
10 | /* system includes */
11 | #include
12 |
13 | /* macros */
14 | #ifndef FALSE
15 | # define FALSE 0
16 | #endif /* ! FALSE */
17 | #ifndef TRUE
18 | # define TRUE 1
19 | #endif /* ! TRUE */
20 |
21 | /* config definition */
22 | struct configdef arcf_config[] =
23 | {
24 | { "AuthservID", CONFIG_TYPE_STRING, FALSE },
25 | { "AutoRestart", CONFIG_TYPE_BOOLEAN, FALSE },
26 | { "AutoRestartCount", CONFIG_TYPE_INTEGER, FALSE },
27 | { "AutoRestartRate", CONFIG_TYPE_STRING, FALSE },
28 | { "Background", CONFIG_TYPE_BOOLEAN, FALSE },
29 | { "BaseDirectory", CONFIG_TYPE_STRING, FALSE },
30 | { "Canonicalization", CONFIG_TYPE_STRING, FALSE },
31 | { "ChangeRootDirectory", CONFIG_TYPE_STRING, FALSE },
32 | { "Domain", CONFIG_TYPE_STRING, TRUE },
33 | { "EnableCoredumps", CONFIG_TYPE_BOOLEAN, FALSE },
34 | { "FixedTimestamp", CONFIG_TYPE_STRING, FALSE },
35 | { "Include", CONFIG_TYPE_INCLUDE, FALSE },
36 | { "InternalHosts", CONFIG_TYPE_STRING, FALSE },
37 | { "KeepTemporaryFiles", CONFIG_TYPE_BOOLEAN, FALSE },
38 | { "KeyFile", CONFIG_TYPE_STRING, TRUE },
39 | { "MaximumHeaders", CONFIG_TYPE_INTEGER, FALSE },
40 | { "MilterDebug", CONFIG_TYPE_INTEGER, FALSE },
41 | { "Mode", CONFIG_TYPE_STRING, FALSE },
42 | { "PeerList", CONFIG_TYPE_STRING, FALSE },
43 | { "PidFile", CONFIG_TYPE_STRING, FALSE },
44 | { "Selector", CONFIG_TYPE_STRING, TRUE },
45 | { "SignatureAlgorithm", CONFIG_TYPE_STRING, FALSE },
46 | { "SignHeaders", CONFIG_TYPE_STRING, FALSE },
47 | { "OverSignHeaders", CONFIG_TYPE_STRING, FALSE },
48 | { "Socket", CONFIG_TYPE_STRING, FALSE },
49 | { "SoftwareHeader", CONFIG_TYPE_BOOLEAN, FALSE },
50 | { "Syslog", CONFIG_TYPE_BOOLEAN, FALSE },
51 | { "SyslogFacility", CONFIG_TYPE_STRING, FALSE },
52 | { "TemporaryDirectory", CONFIG_TYPE_STRING, FALSE },
53 | { "UserID", CONFIG_TYPE_STRING, FALSE },
54 | { NULL, (u_int) -1, FALSE }
55 | };
56 |
57 | #endif /* _ARC_CONFIG_H_ */
58 |
--------------------------------------------------------------------------------
/openarc/openarc-crypto.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** Copyright (c) 2016, 2017, The Trusted Domain Project.
3 | ** All rights reserved.
4 | */
5 |
6 | #include
7 |
8 | #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
9 |
10 | #include "build-config.h"
11 |
12 | /* system includes */
13 | #include
14 | #ifdef HAVE_STDBOOL_H
15 | # include
16 | #endif /* HAVE_STDBOOL_H */
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 |
23 | /* openssl includes */
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 |
30 | /* openarc includes */
31 | #include "openarc-crypto.h"
32 | #include "openarc.h"
33 |
34 | /* globals */
35 | static _Bool crypto_init_done = FALSE;
36 | static pthread_mutex_t id_lock;
37 | static pthread_key_t id_key;
38 | static unsigned int nmutexes = 0;
39 | static unsigned long threadid = 0L;
40 | static pthread_mutex_t *mutexes = NULL;
41 |
42 | /*
43 | ** ARCF_CRYPTO_LOCK_CALLBACK -- locking callback for libcrypto
44 | **
45 | ** Parameters:
46 | ** mode -- lock mode (request from libcrypto)
47 | ** idx -- lock index for this request
48 | ** file -- file making the request
49 | ** line -- line making the request
50 | **
51 | ** Return value:
52 | ** None.
53 | */
54 |
55 | static void
56 | arcf_crypto_lock_callback(int mode, int idx,
57 | /* UNUSED */ const char *file,
58 | /* UNUSED */ int line)
59 | {
60 | int status;
61 |
62 | if ((mode & CRYPTO_LOCK) != 0)
63 | status = pthread_mutex_lock(&mutexes[idx]);
64 | else
65 | status = pthread_mutex_unlock(&mutexes[idx]);
66 |
67 | assert(status == 0);
68 | }
69 |
70 | /*
71 | ** ARCF_CRYPTO_GET_ID -- generate/retrieve thread ID
72 | **
73 | ** Parameters:
74 | **
75 | ** Return value:
76 | **
77 | */
78 |
79 | static unsigned long
80 | arcf_crypto_get_id(void)
81 | {
82 | unsigned long *id;
83 |
84 | id = pthread_getspecific(id_key);
85 | if (id == NULL)
86 | {
87 | id = (unsigned long *) malloc(sizeof *id);
88 | assert(pthread_mutex_lock(&id_lock) == 0);
89 | threadid++;
90 | *id = threadid;
91 | assert(pthread_mutex_unlock(&id_lock) == 0);
92 | assert(pthread_setspecific(id_key, id) == 0);
93 | }
94 |
95 | return *id;
96 | }
97 |
98 | /*
99 | ** ARCF_CRYPTO_FREE_ID -- destroy thread ID
100 | **
101 | ** Parameters:
102 | ** ptr -- pointer to be destroyed
103 | **
104 | ** Return value:
105 | ** None.
106 | */
107 |
108 | static void
109 | arcf_crypto_free_id(void *ptr)
110 | {
111 | /*
112 | ** Trick arcf_crypto_get_id(); the thread-specific pointer has
113 | ** already been cleared at this point, but arcf_crypto_get_id()
114 | ** may be called by ERR_remove_state() which will then allocate a
115 | ** new thread pointer if the thread-specific pointer is NULL. This
116 | ** means a memory leak of thread IDs and, on Solaris, an infinite loop
117 | ** because the destructor (indirectly) re-sets the thread-specific
118 | ** pointer to something not NULL. See pthread_key_create(3).
119 | */
120 |
121 | if (ptr != NULL)
122 | {
123 | assert(pthread_setspecific(id_key, ptr) == 0);
124 |
125 | ERR_remove_state(0);
126 |
127 | free(ptr);
128 |
129 | /* now we can actually clear it for real */
130 | assert(pthread_setspecific(id_key, NULL) == 0);
131 | }
132 | }
133 |
134 | /*
135 | ** ARCF_CRYPTO_DYN_CREATE -- dynamically create a mutex
136 | **
137 | ** Parameters:
138 | ** file -- file making the request
139 | ** line -- line making the request
140 | **
141 | ** Return value:
142 | ** Pointer to the new mutex.
143 | */
144 |
145 | static struct CRYPTO_dynlock_value *
146 | arcf_crypto_dyn_create(/* UNUSED */ const char *file,
147 | /* UNUSED */ int line)
148 | {
149 | int err;
150 | pthread_mutex_t *new;
151 |
152 | new = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));
153 | if (new == NULL)
154 | return NULL;
155 |
156 | err = pthread_mutex_init(new, NULL);
157 | if (err != 0)
158 | {
159 | free(new);
160 | return NULL;
161 | }
162 |
163 | return (void *) new;
164 | }
165 |
166 | /*
167 | ** ARCF_CRYPTO_DYN_DESTROY -- destroy a dynamic mutex
168 | **
169 | ** Parameters:
170 | ** mutex -- pointer to the mutex to destroy
171 | ** file -- file making the request
172 | ** line -- line making the request
173 | **
174 | ** Return value:
175 | ** None.
176 | */
177 |
178 | static void
179 | arcf_crypto_dyn_destroy(struct CRYPTO_dynlock_value *lock,
180 | /* UNUSED */ const char *file,
181 | /* UNUSED */ int line)
182 | {
183 | assert(lock != NULL);
184 |
185 | pthread_mutex_destroy((pthread_mutex_t *) lock);
186 |
187 | free(lock);
188 | }
189 |
190 | /*
191 | ** ARCF_CRYPTO_DYN_LOCK -- lock/unlock a dynamic mutex
192 | **
193 | ** Parameters:
194 | ** mode -- lock mode (request from libcrypto)
195 | ** mutex -- pointer to the mutex to lock/unlock
196 | ** file -- file making the request
197 | ** line -- line making the request
198 | **
199 | ** Return value:
200 | ** None.
201 | */
202 |
203 | static void
204 | arcf_crypto_dyn_lock(int mode, struct CRYPTO_dynlock_value *lock,
205 | /* UNUSED */ const char *file,
206 | /* UNUSED */ int line)
207 | {
208 | int status;
209 |
210 | assert(lock != NULL);
211 |
212 | if ((mode & CRYPTO_LOCK) != 0)
213 | status = pthread_mutex_lock((pthread_mutex_t *) lock);
214 | else
215 | status = pthread_mutex_unlock((pthread_mutex_t *) lock);
216 |
217 | assert(status == 0);
218 | }
219 |
220 | /*
221 | ** ARCF_CRYPTO_INIT -- set up openssl dependencies
222 | **
223 | ** Parameters:
224 | ** None.
225 | **
226 | ** Return value:
227 | ** 0 -- success
228 | ** !0 -- an error code (a la errno)
229 | */
230 |
231 | int
232 | arcf_crypto_init(void)
233 | {
234 | int c;
235 | int n;
236 | int status;
237 |
238 | n = CRYPTO_num_locks();
239 | mutexes = (pthread_mutex_t *) malloc(n * sizeof(pthread_mutex_t));
240 | if (mutexes == NULL)
241 | return errno;
242 |
243 | for (c = 0; c < n; c++)
244 | {
245 | status = pthread_mutex_init(&mutexes[c], NULL);
246 | if (status != 0)
247 | return status;
248 | }
249 |
250 | status = pthread_mutex_init(&id_lock, NULL);
251 | if (status != 0)
252 | return status;
253 |
254 | nmutexes = n;
255 |
256 | status = pthread_key_create(&id_key, &arcf_crypto_free_id);
257 | if (status != 0)
258 | return status;
259 |
260 | SSL_load_error_strings();
261 | SSL_library_init();
262 | ERR_load_crypto_strings();
263 |
264 | CRYPTO_set_id_callback(&arcf_crypto_get_id);
265 | CRYPTO_set_locking_callback(&arcf_crypto_lock_callback);
266 | CRYPTO_set_dynlock_create_callback(&arcf_crypto_dyn_create);
267 | CRYPTO_set_dynlock_lock_callback(&arcf_crypto_dyn_lock);
268 | CRYPTO_set_dynlock_destroy_callback(&arcf_crypto_dyn_destroy);
269 |
270 | #ifdef USE_OPENSSL_ENGINE
271 | if (!SSL_set_engine(NULL))
272 | return EINVAL;
273 | #endif /* USE_OPENSSL_ENGINE */
274 |
275 | crypto_init_done = TRUE;
276 |
277 | return 0;
278 | }
279 |
280 | /*
281 | ** ARCF_CRYPTO_FREE -- tear down openssl dependencies
282 | **
283 | ** Parameters:
284 | ** None.
285 | **
286 | ** Return value:
287 | ** None.
288 | */
289 |
290 | void
291 | arcf_crypto_free(void)
292 | {
293 | if (crypto_init_done)
294 | {
295 | CRYPTO_cleanup_all_ex_data();
296 | CONF_modules_free();
297 | EVP_cleanup();
298 | ERR_free_strings();
299 | ERR_remove_state(0);
300 |
301 | if (nmutexes > 0)
302 | {
303 | unsigned int c;
304 |
305 | for (c = 0; c < nmutexes; c++)
306 | pthread_mutex_destroy(&mutexes[c]);
307 |
308 | free(mutexes);
309 | mutexes = NULL;
310 | nmutexes = 0;
311 | }
312 |
313 | crypto_init_done = FALSE;
314 | }
315 | }
316 |
317 | #endif /* OpenSSL < 1.1.0 */
318 |
--------------------------------------------------------------------------------
/openarc/openarc-crypto.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Copyright (c) 2016, The Trusted Domain Project. All rights reserved.
3 | **
4 | */
5 |
6 | #ifndef _ARC_CRYPTO_H_
7 | #define _ARC_CRYPTO_H_
8 |
9 | #ifdef __STDC__
10 | # ifndef __P
11 | # define __P(x) x
12 | # endif /* ! __P */
13 | #else /* __STDC__ */
14 | # ifndef __P
15 | # define __P(x) ()
16 | # endif /* ! __P */
17 | #endif /* __STDC__ */
18 |
19 | /* PROTOTYPES */
20 | extern int arcf_crypto_init __P((void));
21 | extern void arcf_crypto_free __P((void));
22 |
23 | #endif /* _ARC_CRYPTO_H_ */
24 |
--------------------------------------------------------------------------------
/openarc/openarc-test.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** Copyright (c) 2007-2009 Sendmail, Inc. and its suppliers.
3 | ** All rights reserved.
4 | **
5 | ** Copyright (c) 2009-2013, The Trusted Domain Project. All rights reserved.
6 | */
7 |
8 | /* system includes */
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 | /* libopenarc includes */
21 | #include "build-config.h"
22 | #include
23 |
24 | /* libbsd if found */
25 | #ifdef USE_BSD_H
26 | # include
27 | #endif /* USE_BSD_H */
28 |
29 | /* libstrl if needed */
30 | #ifdef USE_STRL_H
31 | # include
32 | #endif /* USE_STRL_H */
33 |
34 | /* libmilter includes */
35 | #include
36 |
37 | /* openarc includes */
38 | #define ARCF_MILTER_PROTOTYPES
39 | #include "openarc-test.h"
40 | #include "openarc.h"
41 |
42 | /* local types and definitions*/
43 | #define CRLF "\r\n"
44 |
45 | struct test_context
46 | {
47 | void * tc_priv; /* private data pointer */
48 | };
49 |
50 | char *milter_status[] =
51 | {
52 | "SMFIS_CONTINUE",
53 | "SMFIS_REJECT",
54 | "SMFIS_DISCARD",
55 | "SMFIS_ACCEPT",
56 | "SMFIS_TEMPFAIL"
57 | };
58 |
59 | char *envfrom[] =
60 | {
61 | "",
62 | NULL
63 | };
64 |
65 | #define FCLOSE(x) if ((x) != stdin) \
66 | fclose((x));
67 | #define MLFI_OUTPUT(x,y) ((y) > 1 || ((y) == 1 && (x) != SMFIS_CONTINUE))
68 | #define STRORNULL(x) ((x) == NULL ? "(null)" : (x))
69 |
70 | /* globals */
71 | static int tverbose = 0;
72 |
73 | /*
74 | ** ARCF_TEST_SETPRIV -- store private pointer
75 | **
76 | ** Parameters:
77 | ** ctx -- context pointer
78 | ** ptr -- pointer to store
79 | **
80 | ** Return value:
81 | ** MI_SUCCESS
82 | */
83 |
84 | int
85 | arcf_test_setpriv(void *ctx, void *ptr)
86 | {
87 | struct test_context *tc;
88 |
89 | assert(ctx != NULL);
90 |
91 | tc = ctx;
92 | tc->tc_priv = ptr;
93 |
94 | return MI_SUCCESS;
95 | }
96 |
97 | /*
98 | ** ARCF_TEST_GETPRIV -- retrieve private pointer
99 | **
100 | ** Parameters:
101 | ** ctx -- context pointer
102 | **
103 | ** Return value:
104 | ** The private pointer.
105 | */
106 |
107 | void *
108 | arcf_test_getpriv(void *ctx)
109 | {
110 | struct test_context *tc;
111 |
112 | assert(ctx != NULL);
113 |
114 | tc = ctx;
115 |
116 | return tc->tc_priv;
117 | }
118 |
119 | /*
120 | ** ARCF_TEST_PROGRESS -- send progress message
121 | **
122 | ** Parameters:
123 | ** ctx -- context pointer
124 | **
125 | ** Return value:
126 | ** MI_SUCCESS
127 | */
128 |
129 | int
130 | arcf_test_progress(void *ctx)
131 | {
132 | assert(ctx != NULL);
133 |
134 | if (tverbose > 1)
135 | fprintf(stdout, "### PROGRESS\n");
136 |
137 | return MI_SUCCESS;
138 | }
139 |
140 | /*
141 | ** ARCF_TEST_SETREPLY -- set reply to use
142 | **
143 | ** Parameters:
144 | ** ctx -- context pointer
145 | ** rcode -- SMTP reply code
146 | ** xcode -- SMTP enhanced reply code
147 | ** replytxt -- SMTP reply text
148 | **
149 | ** Return value:
150 | ** MI_SUCCESS
151 | */
152 |
153 | int
154 | arcf_test_setreply(void *ctx, char *rcode, char *xcode, char *replytxt)
155 | {
156 | assert(ctx != NULL);
157 |
158 | if (tverbose > 1)
159 | {
160 | fprintf(stdout,
161 | "### SETREPLY: rcode='%s' xcode='%s' replytxt='%s'\n",
162 | STRORNULL(rcode), STRORNULL(xcode),
163 | STRORNULL(replytxt));
164 | }
165 |
166 | return MI_SUCCESS;
167 | }
168 |
169 | /*
170 | ** ARCF_TEST_INSHEADER -- insert a header
171 | **
172 | ** Parameters:
173 | ** ctx -- context pointer
174 | ** idx -- insertion index
175 | ** hname -- header name
176 | ** hvalue -- header value
177 | **
178 | ** Return value:
179 | ** MI_SUCCESS
180 | */
181 |
182 | int
183 | arcf_test_insheader(void *ctx, int idx, char *hname, char *hvalue)
184 | {
185 | assert(ctx != NULL);
186 |
187 | if (tverbose > 1)
188 | {
189 | fprintf(stdout,
190 | "### INSHEADER: idx=%d hname='%s' hvalue='%s'\n",
191 | idx, STRORNULL(hname), STRORNULL(hvalue));
192 | }
193 |
194 | return MI_SUCCESS;
195 | }
196 |
197 | /*
198 | ** ARCF_TEST_CHGHEADER -- change a header
199 | **
200 | ** Parameters:
201 | ** ctx -- context pointer
202 | ** hname -- header name
203 | ** idx -- header index
204 | ** hvalue -- header value
205 | **
206 | ** Return value:
207 | ** MI_SUCCESS
208 | */
209 |
210 | int
211 | arcf_test_chgheader(void *ctx, char *hname, int idx, char *hvalue)
212 | {
213 | assert(ctx != NULL);
214 |
215 | if (tverbose > 1)
216 | {
217 | fprintf(stdout,
218 | "### CHGHEADER: hname='%s' idx=%d hvalue='%s'\n",
219 | STRORNULL(hname), idx, STRORNULL(hvalue));
220 | }
221 |
222 | return MI_SUCCESS;
223 | }
224 |
225 | /*
226 | ** ARCF_TEST_QUARANTINE -- request message quarantine
227 | **
228 | ** Parameters:
229 | ** ctx -- context pointer
230 | ** reason -- reason string
231 | **
232 | ** Return value:
233 | ** MI_SUCCESS
234 | */
235 |
236 | int
237 | arcf_test_quarantine(void *ctx, char *reason)
238 | {
239 | assert(ctx != NULL);
240 |
241 | if (tverbose > 1)
242 | {
243 | fprintf(stdout,
244 | "### QUARANTINE: reason='%s'\n", STRORNULL(reason));
245 | }
246 |
247 | return MI_SUCCESS;
248 | }
249 |
250 | /*
251 | ** ARCF_TEST_ADDHEADER -- append a header
252 | **
253 | ** Parameters:
254 | ** ctx -- context pointer
255 | ** hname -- header name
256 | ** hvalue -- header value
257 | **
258 | ** Return value:
259 | ** MI_SUCCESS
260 | */
261 |
262 | int
263 | arcf_test_addheader(void *ctx, char *hname, char *hvalue)
264 | {
265 | assert(ctx != NULL);
266 |
267 | if (tverbose > 1)
268 | {
269 | fprintf(stdout,
270 | "### ADDHEADER: hname='%s' hvalue='%s'\n",
271 | STRORNULL(hname), STRORNULL(hvalue));
272 | }
273 |
274 | return MI_SUCCESS;
275 | }
276 |
277 | /*
278 | ** ARCF_TEST_DELRCPT -- request recipient delete
279 | **
280 | ** Parameters:
281 | ** ctx -- context pointer
282 | ** addr -- address
283 | **
284 | ** Return value:
285 | ** MI_SUCCESS
286 | */
287 |
288 | int
289 | arcf_test_delrcpt(void *ctx, char *addr)
290 | {
291 | assert(ctx != NULL);
292 | assert(addr != NULL);
293 |
294 | if (tverbose > 1)
295 | fprintf(stdout, "### DELRCPT: '%s'\n", addr);
296 |
297 | return MI_SUCCESS;
298 | }
299 |
300 | /*
301 | ** ARCF_TEST_ADDRCPT -- request recipient add
302 | **
303 | ** Parameters:
304 | ** ctx -- context pointer
305 | ** addr -- address
306 | **
307 | ** Return value:
308 | ** MI_SUCCESS
309 | */
310 |
311 | int
312 | arcf_test_addrcpt(void *ctx, char *addr)
313 | {
314 | assert(ctx != NULL);
315 | assert(addr != NULL);
316 |
317 | if (tverbose > 1)
318 | fprintf(stdout, "### ADDRCPT: '%s'\n", addr);
319 |
320 | return MI_SUCCESS;
321 | }
322 |
323 | /*
324 | ** ARCF_TEST_GETSYMVAL -- retrieve a symbol value
325 | **
326 | ** Parameters:
327 | ** ctx -- context pointer
328 | ** sym -- symbol name
329 | **
330 | ** Return value:
331 | ** Pointer to (static) string name.
332 | **
333 | ** Note:
334 | ** This isn't thread-safe, but test mode is single-threaded anyway.
335 | ** This is also a memory leak, but it's a short-lived test program
336 | ** anyway.
337 | */
338 |
339 | char *
340 | arcf_test_getsymval(void *ctx, char *sym)
341 | {
342 | static char symout[MAXBUFRSZ];
343 |
344 | assert(ctx != NULL);
345 | assert(sym != NULL);
346 |
347 | snprintf(symout, sizeof symout, "DEBUG-%s", sym);
348 |
349 | return strdup(symout);
350 | }
351 |
352 | /*
353 | ** ARCF_TESTFILE -- read a message and test it
354 | **
355 | ** Parameters:
356 | ** libopenarc -- DKIM_LIB handle
357 | ** file -- input file path
358 | ** fixedtime -- time to use on signatures (or -1)
359 | ** verbose -- verbose level
360 | **
361 | ** Return value:
362 | ** An EX_* constant (see sysexits.h)
363 | */
364 |
365 | static int
366 | arcf_testfile(ARC_LIB *libopenarc, struct test_context *tctx,
367 | FILE *f, char *file, int tverbose)
368 | {
369 | bool inheaders = TRUE;
370 | int len = 0;
371 | int buflen = 0;
372 | int lineno = 0;
373 | int hslineno = 0;
374 | int c;
375 | ARC_MESSAGE *msg;
376 | char *p;
377 | sfsistat ms;
378 | char buf[MAXBUFRSZ];
379 | char line[MAXBUFRSZ];
380 |
381 | assert(libopenarc != NULL);
382 | assert(tctx != NULL);
383 | assert(f != NULL);
384 |
385 | memset(buf, '\0', sizeof buf);
386 | memset(line, '\0', sizeof buf);
387 |
388 | ms = mlfi_envfrom((SMFICTX *) tctx, envfrom);
389 | if (MLFI_OUTPUT(ms, tverbose))
390 | {
391 | fprintf(stderr, "%s: %s: mlfi_envfrom() returned %s\n",
392 | progname, file, milter_status[ms]);
393 | }
394 | if (ms != SMFIS_CONTINUE)
395 | return EX_SOFTWARE;
396 |
397 | while (!feof(f))
398 | {
399 | if (fgets(line, sizeof line, f) == NULL)
400 | break;
401 |
402 | lineno++;
403 |
404 | c = '\0';
405 | for (p = line; *p != '\0'; p++)
406 | {
407 | if (*p == '\n')
408 | {
409 | *p = '\0';
410 | break;
411 | }
412 |
413 | c = *p;
414 | }
415 |
416 | if (c == '\r' && p != line) /* eat the CR */
417 | *(p - 1) = '\0';
418 |
419 | if (inheaders)
420 | {
421 | if (line[0] == '\0')
422 | {
423 | if (buf[0] != '\0')
424 | {
425 | char *colon;
426 |
427 | colon = strchr(buf, ':');
428 | if (colon == NULL)
429 | {
430 | fprintf(stderr,
431 | "%s: %s: line %d: header malformed\n",
432 | progname, file,
433 | lineno);
434 | return EX_DATAERR;
435 | }
436 |
437 | *colon = '\0';
438 | if (*(colon + 1) == ' ')
439 | colon++;
440 |
441 | ms = mlfi_header((SMFICTX *) tctx, buf,
442 | colon + 1);
443 | if (MLFI_OUTPUT(ms, tverbose))
444 | {
445 | fprintf(stderr,
446 | "%s: %s: line %d: mlfi_header() returned %s\n",
447 | progname, file,
448 | hslineno,
449 | milter_status[ms]);
450 | }
451 |
452 | if (ms != SMFIS_CONTINUE)
453 | return EX_SOFTWARE;
454 | }
455 |
456 | inheaders = FALSE;
457 | memset(buf, '\0', sizeof buf);
458 | memset(line, '\0', sizeof buf);
459 |
460 | ms = mlfi_eoh((SMFICTX *) tctx);
461 | if (MLFI_OUTPUT(ms, tverbose))
462 | {
463 | fprintf(stderr,
464 | "%s: %s: mlfi_eoh() returned %s\n",
465 | progname, file,
466 | milter_status[ms]);
467 | }
468 | if (ms != SMFIS_CONTINUE)
469 | return EX_SOFTWARE;
470 |
471 | continue;
472 | }
473 |
474 | if (line[0] == ' ' || line[0] == '\t')
475 | {
476 | (void) strlcat(buf, CRLF, sizeof buf);
477 |
478 | if (strlcat(buf, line,
479 | sizeof buf) >= sizeof buf)
480 | {
481 | fprintf(stderr,
482 | "%s: %s: line %d: header '%*s...' too large\n",
483 | progname, file, lineno,
484 | 20, buf);
485 | return EX_DATAERR;
486 | }
487 | }
488 | else
489 | {
490 | if (buf[0] != '\0')
491 | {
492 | char *colon;
493 |
494 | colon = strchr(buf, ':');
495 | if (colon == NULL)
496 | {
497 | fprintf(stderr,
498 | "%s: %s: line %d: header malformed\n",
499 | progname, file,
500 | lineno);
501 | return EX_DATAERR;
502 | }
503 |
504 | *colon = '\0';
505 | if (*(colon + 1) == ' ')
506 | colon++;
507 |
508 | ms = mlfi_header((SMFICTX *) tctx, buf,
509 | colon + 1);
510 | if (MLFI_OUTPUT(ms, tverbose))
511 | {
512 | fprintf(stderr,
513 | "%s: %s: line %d: mlfi_header() returned %s\n",
514 | progname, file,
515 | hslineno,
516 | milter_status[ms]);
517 | }
518 | if (ms != SMFIS_CONTINUE)
519 | return EX_SOFTWARE;
520 | hslineno = 0;
521 | }
522 |
523 | if (hslineno == 0)
524 | hslineno = lineno;
525 |
526 | strlcpy(buf, line, sizeof buf);
527 | }
528 | }
529 | else
530 | {
531 | len = strlen(line);
532 |
533 | if (len + buflen >= (int) sizeof buf - 3)
534 | {
535 | ms = mlfi_body((SMFICTX *) tctx,
536 | (u_char *) buf,
537 | strlen(buf));
538 | if (MLFI_OUTPUT(ms, tverbose))
539 | {
540 | fprintf(stderr,
541 | "%s: %s: mlfi_body() returned %s\n",
542 | progname, file,
543 | milter_status[ms]);
544 | }
545 | if (ms != SMFIS_CONTINUE)
546 | return EX_SOFTWARE;
547 |
548 | memset(buf, '\0', sizeof buf);
549 | buflen = 0;
550 | }
551 |
552 | memcpy(&buf[buflen], line, len);
553 | buflen += len;
554 | memcpy(&buf[buflen], CRLF, 2);
555 | buflen += 2;
556 | }
557 | }
558 |
559 | /* unprocessed partial header? */
560 | if (inheaders && buf[0] != '\0')
561 | {
562 | char *colon;
563 |
564 | colon = strchr(buf, ':');
565 | if (colon == NULL)
566 | {
567 | fprintf(stderr,
568 | "%s: %s: line %d: header malformed\n",
569 | progname, file, lineno);
570 | return EX_DATAERR;
571 | }
572 |
573 | *colon = '\0';
574 | if (*(colon + 1) == ' ')
575 | colon++;
576 |
577 | ms = mlfi_header((SMFICTX *) tctx, buf, colon + 1);
578 | if (MLFI_OUTPUT(ms, tverbose))
579 | {
580 | fprintf(stderr,
581 | "%s: %s: line %d: mlfi_header() returned %s\n",
582 | progname, file, lineno, milter_status[ms]);
583 | }
584 | if (ms != SMFIS_CONTINUE)
585 | return EX_SOFTWARE;
586 |
587 | ms = mlfi_eoh((SMFICTX *) tctx);
588 | if (MLFI_OUTPUT(ms, tverbose))
589 | {
590 | fprintf(stderr,
591 | "%s: %s: mlfi_eoh() returned %s\n",
592 | progname, file, milter_status[ms]);
593 | }
594 | if (ms != SMFIS_CONTINUE)
595 | return EX_SOFTWARE;
596 |
597 | inheaders = FALSE;
598 | memset(buf, '\0', sizeof buf);
599 | }
600 |
601 | /* no headers found */
602 | if (inheaders)
603 | {
604 | fprintf(stderr, "%s: %s: warning: no headers on input\n",
605 | progname, file);
606 |
607 | ms = mlfi_eoh((SMFICTX *) tctx);
608 | if (MLFI_OUTPUT(ms, tverbose))
609 | {
610 | fprintf(stderr, "%s: %s: mlfi_eoh() returned %s\n",
611 | progname, file, milter_status[ms]);
612 | }
613 | if (ms != SMFIS_CONTINUE)
614 | return EX_SOFTWARE;
615 | }
616 |
617 | /* some body left */
618 | if (!inheaders && buf[0] != '\0')
619 | {
620 | ms = mlfi_body((SMFICTX *) tctx, (u_char *) buf, strlen(buf));
621 | if (MLFI_OUTPUT(ms, tverbose))
622 | {
623 | fprintf(stderr, "%s: %s: mlfi_body() returned %s\n",
624 | progname, file, milter_status[ms]);
625 | }
626 | if (ms != SMFIS_CONTINUE)
627 | return EX_SOFTWARE;
628 | }
629 |
630 | ms = mlfi_eom((SMFICTX *) tctx);
631 | if (MLFI_OUTPUT(ms, tverbose))
632 | {
633 | fprintf(stderr, "%s: %s: mlfi_eom() returned %s\n",
634 | progname, file, milter_status[ms]);
635 | }
636 |
637 | return EX_OK;
638 | }
639 |
640 | /*
641 | ** ARCF_TESTFILES -- test one or more input messages
642 | **
643 | ** Parameters:
644 | ** libopenarc -- ARC_LIB handle
645 | ** flist -- input file list
646 | ** verbose -- verbose level
647 | **
648 | ** Return value:
649 | ** An EX_* constant (see sysexits.h)
650 | */
651 |
652 | int
653 | arcf_testfiles(ARC_LIB *libopenarc, char *flist, int verbose)
654 | {
655 | char *file;
656 | char *ctx;
657 | FILE *f;
658 | int status;
659 | sfsistat ms;
660 | struct test_context *tctx;
661 | struct sockaddr_in sin;
662 |
663 | assert(libopenarc != NULL);
664 | assert(flist != NULL);
665 |
666 | tverbose = verbose;
667 |
668 | /* set up a fake SMFICTX */
669 | tctx = (struct test_context *) malloc(sizeof(struct test_context));
670 | if (tctx == NULL)
671 | {
672 | fprintf(stderr, "%s: malloc(): %s\n", progname,
673 | strerror(errno));
674 | return EX_OSERR;
675 | }
676 | tctx->tc_priv = NULL;
677 |
678 | (void) memset(&sin, '\0', sizeof sin);
679 | sin.sin_family = AF_INET;
680 | sin.sin_port = htons(time(NULL) % 65536);
681 | sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
682 |
683 | ms = mlfi_connect((SMFICTX *) tctx, "localhost", (_SOCK_ADDR *) &sin);
684 | if (MLFI_OUTPUT(ms, tverbose))
685 | {
686 | fprintf(stderr, "%s: mlfi_connect() returned %s\n",
687 | progname, milter_status[ms]);
688 | }
689 | if (ms != SMFIS_CONTINUE)
690 | return EX_SOFTWARE;
691 |
692 | /* loop through inputs */
693 | for (file = strtok_r(flist, ",", &ctx);
694 | file != NULL;
695 | file = strtok_r(NULL, ",", &ctx))
696 | {
697 | /* open the input */
698 | if (strcmp(file, "-") == 0)
699 | {
700 | f = stdin;
701 | file = "(stdin)";
702 | }
703 | else
704 | {
705 | f = fopen(file, "r");
706 | if (f == NULL)
707 | {
708 | fprintf(stderr, "%s: %s: fopen(): %s\n",
709 | progname, file, strerror(errno));
710 | return EX_UNAVAILABLE;
711 | }
712 | }
713 |
714 | status = arcf_testfile(libopenarc, tctx, f, file, tverbose);
715 |
716 | FCLOSE(f);
717 |
718 | if (status != EX_OK)
719 | return status;
720 | }
721 |
722 | ms = mlfi_close((SMFICTX *) tctx);
723 | if (MLFI_OUTPUT(ms, tverbose))
724 | {
725 | fprintf(stderr, "%s: mlfi_close() returned %s\n",
726 | progname, milter_status[ms]);
727 | }
728 |
729 | return EX_OK;
730 | }
731 |
--------------------------------------------------------------------------------
/openarc/openarc-test.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Copyright (c) 2007 Sendmail, Inc. and its suppliers.
3 | ** All rights reserved.
4 | **
5 | ** Copyright (c) 2009-2012, The Trusted Domain Project. All rights reserved.
6 | **
7 | */
8 |
9 | #ifndef _TEST_H_
10 | #define _TEST_H_
11 |
12 | /* system includes */
13 | #include
14 | #include
15 |
16 | /* libmilter includes */
17 | #include
18 |
19 | /* libopenarc includes */
20 | #include "arc.h"
21 |
22 | /* PROTOTYPES */
23 | extern int arcf_testfiles __P((ARC_LIB *, char *, int));
24 |
25 | extern int arcf_test_addheader __P((void *, char *, char *));
26 | extern int arcf_test_addrcpt __P((void *, char *));
27 | extern int arcf_test_chgheader __P((void *, char *, int, char *));
28 | extern int arcf_test_delrcpt __P((void *, char *));
29 | extern void *arcf_test_getpriv __P((void *));
30 | extern char *arcf_test_getsymval __P((void *, char *));
31 | extern int arcf_test_insheader __P((void *, int, char *, char *));
32 | extern int arcf_test_progress __P((void *));
33 | extern int arcf_test_quarantine __P((void *, char *));
34 | extern int arcf_test_setpriv __P((void *, void *));
35 | extern int arcf_test_setreply __P((void *, char *, char *, char *));
36 |
37 | #endif /* _TEST_H_ */
38 |
--------------------------------------------------------------------------------
/openarc/openarc.8.in:
--------------------------------------------------------------------------------
1 | .TH openarc 8 "The Trusted Domain Project"
2 | .SH NAME
3 | .B openarc
4 | \- ARC signing and verifying filter for MTAs
5 | .SH SYNOPSIS
6 | .B openarc
7 | [\-c configfile]
8 | [\-f]
9 | [\-n]
10 | [\-p socketspec]
11 | [\-P pidfile]
12 | [\-u userid[:group]]
13 | [\-v]
14 | [\-V]
15 | .SH DESCRIPTION
16 | .B openarc
17 | implements the proposed
18 | .B ARC
19 | (Authenticated Received Chain) standard for confirming handling and
20 | authentication of a message as it is handled for delivery.
21 |
22 | .B openarc
23 | uses the
24 | .I milter
25 | interface, originally distributed as part of version 8.11 of
26 | .B sendmail(8),
27 | to provide ARC signing and/or verifying service for mail transiting
28 | a milter-aware MTA.
29 | .SH OPTIONS
30 | .TP
31 | .I \-c configfile
32 | Read the named configuration file. See the
33 | .I openarc.conf(5)
34 | man page for details. Values in the configuration file are overridden
35 | when their equivalents are provided on the command line until a configuration
36 | reload occurs. The default is to read a configuration file from
37 | .I @SYSCONFDIR@/openarc.conf
38 | if one exists, or otherwise to apply defaults to all values.
39 | .TP
40 | .I \-f
41 | Normally
42 | .I openarc
43 | forks and exits immediately, leaving the service running in the background.
44 | This flag suppresses that behaviour so that it runs in the foreground.
45 | .TP
46 | .I \-n
47 | Parse the configuration file and command line arguments, reporting any
48 | errors found, and then exit. The exit value will be 0 if the filter would
49 | start up without complaint, or non-zero otherwise.
50 | .TP
51 | .I \-p socketspec
52 | Specifies the socket that should be established by the filter to receive
53 | connections from
54 | .I sendmail(8)
55 | in order to provide service.
56 | .I socketspec
57 | is in one of two forms:
58 | .I local:path
59 | which creates a UNIX domain socket at the specified
60 | .I path,
61 | or
62 | .I inet:port[@host]
63 | or
64 | .I inet6:port[@host]
65 | which creates a TCP socket on the specified
66 | .I port
67 | using the requested protocol family. If the
68 | .I host
69 | is not given as either a hostname or an IP address, the socket will be
70 | listening on all interfaces. A literal IP address must be enclosed in
71 | square brackets. If neither socket type is specified,
72 | .I local
73 | is assumed, meaning the parameter is interpreted as a path at which
74 | the socket should be created. This parameter is mandatory either here or
75 | in the configuration file.
76 | .TP
77 | .I \-P pidfile
78 | Specifies a file into which the filter should write its process ID at startup.
79 | .TP
80 | .I \-u userid[:group]
81 | Attempts to be come the specified
82 | .I userid
83 | before starting operations. The process will be assigned all of the groups
84 | and primary group ID of the named
85 | .I userid
86 | unless an alternate
87 | .I group
88 | is specified. See the FILE PERMISSIONS section for more information.
89 | .TP
90 | .I \-V
91 | Print the version number and build-time options, and then exit without
92 | doing anything else.
93 | .SH EXIT STATUS
94 | Filter exit status codes are selected according to
95 | .I sysexits(3).
96 | .SH VERSION
97 | This man page covers version @VERSION@ of
98 | .I openarc.
99 | .SH COPYRIGHT
100 | Copyright (c) 2005-2008, Sendmail, Inc. and its suppliers. All rights
101 | reserved.
102 |
103 | Copyright (c) 2009-2013, 2015, 2016, The Trusted Domain Project.
104 | All rights reserved.
105 | .SH SEE ALSO
106 | .I openarc.conf(5), sendmail(8)
107 | .P
108 | Sendmail Operations Guide
109 | .P
110 | RFC5321 - Simple Mail Transfer Protocol
111 | .P
112 | RFC5322 - Internet Messages
113 | .P
114 | RFC7601 - Message Header Field for Indicating Message Authentication Status
115 | .P
116 |
--------------------------------------------------------------------------------
/openarc/openarc.conf.5.in:
--------------------------------------------------------------------------------
1 | .TH openarc.conf 5 "The Trusted Domain Project"
2 |
3 | .SH NAME
4 | .B openarc.conf
5 | \- Configuration file for openarc
6 |
7 | .SH LOCATION
8 | .I @SYSCONFDIR@/openarc.conf
9 |
10 | .SH DESCRIPTION
11 | .I openarc(8)
12 | implements the
13 | .B ARC
14 | (Authenticated Received Chain)
15 | specification for verifying authentication and handling of messages as
16 | they are routed to their destinations. This file is its configuration file.
17 |
18 | Blank lines are ignored. Lines containing a hash ("#") character are
19 | truncated at the hash character to allow for comments in the file.
20 |
21 | Other content should be the name of a parameter, followed by white space,
22 | followed by the value of that parameter, each on a separate line.
23 |
24 | For parameters that are Boolean in nature, only the first byte of
25 | the value is processed. For positive values, the following are accepted:
26 | "T", "t", "Y", "y", "1". For negative values, the following are accepted:
27 | "F", "f", "N", "n", "0".
28 |
29 | See the
30 | .I openarc(8)
31 | man page for details about how and when the configuration file contents
32 | are reloaded.
33 |
34 | Unless otherwise stated, Boolean values default to "false", integer values
35 | default to 0, and string and dataset values default to being undefined.
36 |
37 | .SH PARAMETERS
38 | .TP
39 | .I AutoRestart (Boolean)
40 | Automatically re-start on failures. Use with caution; if the filter
41 | fails instantly after it starts, this can cause a tight
42 | .I fork(2)
43 | loop.
44 |
45 | .TP
46 | .I AutoRestartCount (integer)
47 | Sets the maximum automatic restart count. After this number of
48 | automatic restarts, the filter will give up and terminate.
49 | A value of 0 implies no limit; this is the default.
50 |
51 | .TP
52 | .I AutoRestartRate (string)
53 | Sets the maximum automatic restart rate. If the filter begins restarting
54 | faster than the rate defined here, it will give up and terminate.
55 | This is a string of the form
56 | .I n/t[u]
57 | where
58 | .I n
59 | is an integer limiting the count of restarts in the given interval and
60 | .I t[u]
61 | defines the time interval through which the rate is calculated;
62 | .I t
63 | is an integer and
64 | .I u
65 | defines the units thus represented ("s" or "S" for seconds, the default;
66 | "m" or "M" for minutes; "h" or "H" for hours; "d" or "D" for days). For
67 | example, a value of "10/1h" limits the restarts to 10 in one hour. There
68 | is no default, meaning restart rate is not limited.
69 |
70 | .TP
71 | .I Background (Boolean)
72 | Causes
73 | .I openarc
74 | to fork and exits immediately, leaving the service running in the background.
75 | The default is "true".
76 |
77 | .TP
78 | .I Canonicalization (string)
79 | Selects the canonicalization method(s) to be used when signing messages.
80 | When verifying, the message's ARC-Message-Signature: header field specifies
81 | the canonicalization method. The recognized values are
82 | .I relaxed
83 | and
84 | .I simple
85 | as defined by the DKIM specification. The default is
86 | .I relaxed/simple.
87 | The value may include two different canonicalizations separated by a
88 | slash ("/") character, in which case the first will be applied to the
89 | header and the second to the body.
90 |
91 | .TP
92 | .I ChangeRootDirectory (string)
93 | Requests that the operating system change the effective root directory
94 | of the process to the one specified here prior to beginning execution.
95 | .BR chroot (2)
96 | requires superuser access. A warning will be generated if
97 | .I UserID
98 | is not also set.
99 |
100 | .TP
101 | .I EnableCoredumps (boolean)
102 | On systems that have such support, make an explicit request to the kernel
103 | to dump cores when the filter crashes for some reason. Some modern UNIX
104 | systems suppress core dumps during crashes for security reasons if the
105 | user ID has changed during the lifetime of the process. Currently only
106 | supported on Linux.
107 |
108 | .TP
109 | .I Include (string)
110 | Names a file to be opened and read as an additional configuration file.
111 | Nesting is allowed to a maximum of five levels.
112 |
113 | .TP
114 | .I InternalHosts (dataset)
115 | Identifies a set of hosts that identifies clients whose connections
116 | should be treated as "internal" by this filter. Messages received from
117 | such sources will not be verified and are instead trusted as-is; in
118 | particular, their Authentication-Results fields are trusted to be
119 | correct and authentic, meaning they will be assumed to contain the correct
120 | chain status when generating an outgoing seal. See the description of
121 | "PeerList" for a description of the supported format. If no set is
122 | provided, "127.0.0.1" is added to the list by default.
123 |
124 | .TP
125 | .I MilterDebug (integer)
126 | Sets the debug level to be requested from the milter library. The
127 | default is 0.
128 |
129 | .TP
130 | .I Mode (string)
131 | Selects the operating mode(s) for this filter. If the string contains
132 | the character "s", the filter will sign and seal messages passing through
133 | the filter. If the string contains the character "v", the filter
134 | will do signature and seal validation of arriving messages. The two
135 | can be combined. If neither is specified, the operating mode will
136 | be inferred on a per-connection basis based on the entries in the
137 | .I InternalHosts
138 | list; connections from internal hosts will be assigned to signing mode,
139 | and all others will be assigned to verify mode.
140 |
141 | .TP
142 | .I OversignHeaders (string)
143 | Specifies a comma-separated list of header field names that should be
144 | included in all signature header lists (the "h=" tag) once more than the
145 | number of times they were actually present in the signed message. The set
146 | is empty by default. The purpose of this, and especially of listing an
147 | absent header field, is to prevent the addition of important fields between
148 | the signer and the verifier. Since the verifier would include that header
149 | field when performing verification if it had been added by an intermediary,
150 | the signed message and the verified message were different and the
151 | verification would fail. Note that listing a field name here and not listing
152 | it in the
153 | .I SignHeaders
154 | list is likely to generate invalid signatures.
155 |
156 | .TP
157 | .I PeerList (dataset)
158 | Identifies a set of "peers" that identifies clients whose connections
159 | should be accepted without processing by this filter. The set
160 | should contain on each line a hostname, domain name (e.g. ".example.com"),
161 | IP address, an IPv6 address (including an IPv4 mapped address), or a
162 | CIDR-style IP specification (e.g. "192.168.1.0/24"). An entry beginning
163 | with a bang ("!") character means "not", allowing exclusions of specific
164 | hosts that are otherwise members of larger sets. Host and domain names are
165 | matched first, then the IP or IPv6 address depending on the connection
166 | type. More precise entries are preferred over less precise ones, i.e.
167 | "192.168.1.1" will match before "!192.168.1.0/24". The text form of IPv6
168 | addresses will be forced to lowercase when queried (RFC5952), so the contents
169 | of this data set should also use lowercase. The IP address portion of an
170 | entry may optionally contain square brackets; both forms (with and without)
171 | will be checked.
172 |
173 | .TP
174 | .I PidFile (string)
175 | Specifies the path to a file that should be created at process start
176 | containing the process ID.
177 |
178 | .TP
179 | .I SignatureAlgorithm (string)
180 | Selects the signing algorithm to use when generating signatures.
181 | Use 'openarc \-V' to see the list of supported algorithms.
182 | The default is
183 | .I rsa-sha256.
184 |
185 | .TP
186 | .I SignHeaders (string)
187 | Specifies the set of header fields that should be included when generating
188 | signatures. This is expected to be a comma-separated list of header
189 | field names, and matching is case-insensitive. If the list omits any header
190 | field that is mandated by the ARC specification, those fields are implicitly
191 | added. By default, those fields listed in the DKIM specification as
192 | "SHOULD" be signed (RFC6376, Section 5.4) will be signed by the filter.
193 |
194 | .TP
195 | .I Socket (string)
196 | Specifies the socket that should be established by the filter to receive
197 | connections from
198 | .I sendmail(8)
199 | in order to provide service.
200 | .I socketspec
201 | is in one of two forms:
202 | .I local:path,
203 | which creates a UNIX domain socket at the specified
204 | .I path,
205 | or
206 | .I inet:port[@host]
207 | or
208 | .I inet6:port[@host]
209 | which creates a TCP socket on the specified
210 | .I port
211 | and in the specified protocol family. If the
212 | .I host
213 | is not given as either a hostname or an IP address, the socket will be
214 | listening on all interfaces. A literal IP address must be enclosed in
215 | square brackets. This option is mandatory either in the configuration file or
216 | on the command line.
217 |
218 | .TP
219 | .I Syslog (Boolean)
220 | Log via calls to
221 | .I syslog(3)
222 | any interesting activity.
223 |
224 | .TP
225 | .I SyslogFacility (string)
226 | Log via calls to
227 | .I syslog(3)
228 | using the named facility. The facility names are the same as the ones
229 | allowed in
230 | .I syslog.conf(5).
231 | The default is "mail".
232 |
233 | .TP
234 | .I UserID (string)
235 | Attempts to become the specified userid before starting operations.
236 | The value is of the form
237 | .I userid[:group].
238 | The process will be assigned all of the groups and primary group ID of
239 | the named
240 | .I userid
241 | unless an alternate
242 | .I group
243 | is specified.
244 |
245 | .SH NOTES
246 | Features that involve specification of IPv4 addresses or CIDR blocks
247 | will use the
248 | .I inet_addr(3)
249 | function to parse that information. Users should be familiar with the
250 | way that function handles the non-trivial cases (for example, "192.0.2/24"
251 | and "192.0.2.0/24" are not the same thing).
252 | .SH FILES
253 | .TP
254 | .I @SYSCONFDIR@/openarc.conf
255 | Default location of this file.
256 | .SH VERSION
257 | This man page covers version @VERSION@ of
258 | .I openarc.
259 |
260 | .SH COPYRIGHT
261 | Copyright (c) 2007, 2008, Sendmail, Inc. and its suppliers. All rights
262 | reserved.
263 |
264 | Copyright (c) 2009-2017, The Trusted Domain Project. All rights reserved.
265 | .SH SEE ALSO
266 | .I openarc(8), sendmail(8)
267 | .P
268 | RFC5451 - Message Header Field for Indicating Message Authentication Status
269 | .P
270 | RFC5617 - DKIM Author Domain Signing Practises
271 | .P
272 | RFC5965 - An Extensible Format for Email Feedback Reports
273 | .P
274 | RFC6008 - Authentication-Results Registration for Differentiating among
275 | Cryptographic Results
276 | .P
277 | RFC6376 - DomainKeys Identified Mail
278 | .P
279 | RFC6651 - Extensions to DomainKeys Identified Mail (DKIM) for Failure Reporting
280 |
--------------------------------------------------------------------------------
/openarc/openarc.conf.sample:
--------------------------------------------------------------------------------
1 | ##
2 | ## openarc.conf -- configuration file for OpenARC filter
3 | ##
4 | ## Copyright (c) 2010-2015, 2017, The Trusted Domain Project.
5 | ## All rights reserved.
6 | ##
7 |
8 | ## CONFIGURATION OPTIONS
9 |
10 | ## AuthservID string
11 | ## default (local host name)
12 | ##
13 | ## Defines the "authserv-id" token to be used when generating
14 | ## Authentication-Results headers after message verification.
15 |
16 | # AuthservID example.com
17 |
18 | ## AutoRestart { yes | no }
19 | ## default "no"
20 | ##
21 | ## Indicate whether or not the filter should arrange to restart automatically
22 | ## if it crashes.
23 |
24 | # AutoRestart No
25 |
26 | ## AutoRestartCount n
27 | ## default 0
28 | ##
29 | ## Sets the maximum automatic restart count. After this number of
30 | ## automatic restarts, the filter will give up and terminate. A value of 0
31 | ## implies no limit.
32 |
33 | # AutoRestartCount 0
34 |
35 | ## AutoRestartRate n/t[u]
36 | ## default (none)
37 | ##
38 | ## Sets the maximum automatic restart rate. See the opendkim.conf(5)
39 | ## man page for the format of this parameter.
40 |
41 | # AutoRestartRate n/tu
42 |
43 | ## Background { yes | no }
44 | ## default "yes"
45 | ##
46 | ## Indicate whether or not the filter should run in the background.
47 |
48 | # Background Yes
49 |
50 | ## BaseDirectory path
51 | ## default (none)
52 | ##
53 | ## Causes the filter to change to the named directory before beginning
54 | ## operation. Thus, cores will be dumped here and configuration files
55 | ## are read relative to this location.
56 |
57 | # BaseDirectory /var/run/opendkim
58 |
59 | ## Canonicalization hdrcanon[/bodycanon]
60 | ## default "simple/simple"
61 | ##
62 | ## Select canonicalizations to use when signing. If the "bodycanon" is
63 | ## omitted, "simple" is used. Valid values for each are "simple" and
64 | ## "relaxed".
65 |
66 | # Canonicalization simple/simple
67 |
68 | ## ChangeRootDirectory directory
69 | ##
70 | ## Changes to the specified directory before beginning execution.
71 |
72 | # ChangeRootDirectory dirname
73 |
74 | ## Domain domain-name
75 | ## default (none)
76 | ##
77 | ## Specify the domain to use when generating ARC header fields. Must
78 | ## be specified for signing.
79 |
80 | Domain example.com
81 |
82 | ## EnableCoredumps { yes | no }
83 | ## default "no"
84 | ##
85 | ## On systems which have support for such, requests that the kernel dump
86 | ## core even though the process may change user ID during its execution.
87 |
88 | # EnableCoredumps no
89 |
90 | ## FixedTimestamp timestamp
91 | ## default (none)
92 | ##
93 | ## Forces a specific timestamp to be used when generating ARC header fields.
94 | ## By default, uses the current time.
95 |
96 | # FixedTimestamp 1234567890
97 |
98 | ## InternalHosts file
99 | ## default (none)
100 | ##
101 | ## Names a file that contains a list of IP addresses, CIDR blocks, hostnames
102 | ## or domain names whose mail should be considered to have come from an
103 | ## internal trusted source, and thus authentication details found in the
104 | ## message will be used as-is. See man page for file format.
105 |
106 | # InternalHosts filename
107 |
108 | ## KeepTemporaryFiles { yes | no }
109 | ## default "no"
110 | ##
111 | ## If set, causes temporary files generated during message signing or
112 | ## verifying to be left behind for debugging use. Not for normal operation;
113 | ## can fill your disks quite fast on busy systems.
114 |
115 | # KeepTemporaryFiles no
116 |
117 | ## KeyFile filename
118 | ## default (none)
119 | ##
120 | ## Specifies the path to the private key to use when signing. Ignored if
121 | ## SigningTable and KeyTable are used. No default; must be specified for
122 | ## signing if SigningTable/KeyTable are not in use.
123 |
124 | KeyFile /var/db/dkim/example.private
125 |
126 | ## MaximumHeaders n
127 | ##
128 | ## Disallow messages whose header blocks are bigger than "n" bytes.
129 | ## Intended to detect and block a denial-of-service attack. The default
130 | ## is 65536. A value of 0 disables this test.
131 |
132 | # MaximumHeaders n
133 |
134 | ## MilterDebug n
135 | ##
136 | ## Request a debug level of "n" from the milter library. The default is 0.
137 |
138 | # MilterDebug 0
139 |
140 | ## Mode modes
141 | ## default (none)
142 | ##
143 | ## Selects the operating mode(s) for this filter. If the string contains
144 | ## the character "s", the filter will sign and seal messages passing through
145 | ## the filter. If the string contains the character "v", the filter
146 | ## will do signature and seal validation of arriving messages. The two
147 | ## can be combined. If neither is specified, the operating mode will
148 | ## be inferred on a per-connection basis based on the entries in the
149 | ## InternalHosts list; connections from internal hosts will be assigned to
150 | ## signing mode, and all others will be assigned to verify mode.
151 |
152 | # Mode sv
153 |
154 | ## OversignHeaders (string)
155 | ## default (none)
156 | ##
157 | ## Specifies the set of header fields that should be "oversigned" when
158 | ## generating signatures. The string should be a comma-separated list of
159 | ## header field names. See the openarc.conf(5) man page for details.
160 |
161 | # OversignHeaders header1,header2,...
162 |
163 | ## PeerList file
164 | ## default (none)
165 | ##
166 | ## Names a file that contains a list of IP addresses, CIDR blocks, hostnames
167 | ## or domain names whose mail should be neither signed nor verified by this
168 | ## filter. See man page for file format.
169 |
170 | # PeerList filename
171 |
172 | ## PidFile filename
173 | ## default (none)
174 | ##
175 | ## Name of the file where the filter should write its pid before beginning
176 | ## normal operations.
177 |
178 | # PidFile filename
179 |
180 | ## Selector name
181 | ##
182 | ## The name of the selector to use when signing. No default; must be
183 | ## specified for signing.
184 |
185 | Selector my-selector-name
186 |
187 | ## SignatureAlgorithm signalg
188 | ## default "rsa-sha256"
189 | ##
190 | ## Signature algorithm to use when generating signatures. Must be either
191 | ## "rsa-sha1" or "rsa-sha256".
192 |
193 | # SignatureAlgorithm rsa-sha256
194 |
195 | ## SignHeaders (string)
196 | ## default (none)
197 | ##
198 | ## Specifies the set of header fields that should be included when generating
199 | ## signatures. The string should be a comma-separated list of header field
200 | ## names.
201 |
202 | # SignHeaders header1,header2,...
203 |
204 | ## Socket socketspec
205 | ##
206 | ## Names the socket where this filter should listen for milter connections
207 | ## from the MTA. Required. Should be in one of these forms:
208 | ##
209 | ## inet:port@address to listen on a specific interface
210 | ## inet:port to listen on all interfaces
211 | ## local:/path/to/socket to listen on a UNIX domain socket
212 |
213 | Socket inet:port@localhost
214 |
215 | ## SoftwareHeader { yes | no }
216 | ## default "no"
217 | ##
218 | ## Add an ARC-Filter header field to messages passing through this filter
219 | ## to identify messages it has processed.
220 |
221 | # SoftwareHeader no
222 |
223 | ## Syslog { yes | no }
224 | ## default "yes"
225 | ##
226 | ## Log informational and error activity to syslog?
227 |
228 | Syslog Yes
229 |
230 | ## SyslogFacility facility
231 | ## default "mail"
232 | ##
233 | ## Valid values are :
234 | ## auth cron daemon kern lpr mail news security syslog user uucp
235 | ## local0 local1 local2 local3 local4 local5 local6 local7
236 | ##
237 | ## syslog facility to be used
238 |
239 | # SyslogFacility mail
240 |
241 | ## TemporaryDirectory path
242 | ## default /tmp
243 | ##
244 | ## Specifies which directory will be used for creating temporary files
245 | ## during message processing.
246 |
247 | # TemporaryDirectory /tmp
248 |
249 | ## Userid userid
250 | ## default (none)
251 | ##
252 | ## Change to user "userid" before starting normal operation? May include
253 | ## a group ID as well, separated from the userid by a colon.
254 |
255 | # UserID userid
256 |
--------------------------------------------------------------------------------
/openarc/openarc.conf.simple.in:
--------------------------------------------------------------------------------
1 | # This is a simple config file for OpenARC
2 |
3 | Mode sv
4 |
5 | Syslog yes
6 |
7 | Socket inet:8891@localhost
8 |
9 | # PidFile /var/run/opendkim/opendkim.pid
10 |
--------------------------------------------------------------------------------
/openarc/openarc.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Copyright (c) 2005-2009 Sendmail, Inc. and its suppliers.
3 | ** All rights reserved.
4 | **
5 | ** Copyright (c) 2009-2014, 2016, The Trusted Domain Project.
6 | ** All rights reserved.
7 | */
8 |
9 | #ifndef _OPENARC_H_
10 | #define _OPENARC_H_
11 |
12 | #define ARCF_PRODUCT "OpenARC Filter"
13 | #define ARCF_PRODUCTNS "OpenARC-Filter"
14 |
15 | #include "build-config.h"
16 |
17 | /* system includes */
18 | #include
19 | #ifdef HAVE_STDBOOL_H
20 | # include
21 | #endif /* HAVE_STDBOOL_H */
22 |
23 | /* libmilter */
24 | #ifdef ARCF_MILTER_PROTOTYPES
25 | # include
26 | #endif /* ARCF_MILTER_PROTOTYPES */
27 |
28 | /* libopenarc */
29 | #include "arc.h"
30 |
31 | /* make sure we have TRUE and FALSE */
32 | #ifndef FALSE
33 | # define FALSE 0
34 | #endif /* !FALSE */
35 | #ifndef TRUE
36 | # define TRUE 1
37 | #endif /* !TRUE */
38 |
39 | /* defaults, limits, etc. */
40 | #define BUFRSZ 1024
41 | #define CONFIGOPTS "Ac:flnp:P:rt:u:vV"
42 | #define DEFCONFFILE CONFIG_BASE "/openarc.conf"
43 | #define DEFINTERNAL "csl:127.0.0.1,::1"
44 | #define DEFMAXHDRSZ 65536
45 | #define HOSTUNKNOWN "unknown-host"
46 | #define JOBIDUNKNOWN "(unknown-jobid)"
47 | #define LOCALHOST "127.0.0.1"
48 | #define MAXADDRESS 256
49 | #define MAXARGV 65536
50 | #define MAXBUFRSZ 65536
51 | #define MAXHDRCNT 64
52 | #define MAXHDRLEN 78
53 | #define MAXSIGNATURE 1024
54 | #define MTAMARGIN 78
55 | #define NULLDOMAIN "(invalid)"
56 | #define UNKNOWN "unknown"
57 |
58 | #define AUTHRESULTSHDR "Authentication-Results"
59 | #define SWHEADERNAME "ARC-Filter"
60 |
61 | /*
62 | ** HEADER -- a handle referring to a header
63 | */
64 |
65 | typedef struct Header * Header;
66 | struct Header
67 | {
68 | char * hdr_hdr;
69 | char * hdr_val;
70 | struct Header * hdr_next;
71 | struct Header * hdr_prev;
72 | };
73 |
74 | /* externs */
75 | extern _Bool dolog;
76 | extern char *progname;
77 |
78 | /* prototypes, exported for test.c */
79 | extern ARC_MESSAGE *arcf_getarc __P((void *));
80 |
81 | #ifdef ARCF_MILTER_PROTOTYPES
82 | extern sfsistat mlfi_connect __P((SMFICTX *, char *, _SOCK_ADDR *));
83 | extern sfsistat mlfi_envfrom __P((SMFICTX *, char **));
84 | extern sfsistat mlfi_envrcpt __P((SMFICTX *, char **));
85 | extern sfsistat mlfi_header __P((SMFICTX *, char *, char *));
86 | extern sfsistat mlfi_eoh __P((SMFICTX *));
87 | extern sfsistat mlfi_body __P((SMFICTX *, u_char *, size_t));
88 | extern sfsistat mlfi_eom __P((SMFICTX *));
89 | extern sfsistat mlfi_abort __P((SMFICTX *));
90 | extern sfsistat mlfi_close __P((SMFICTX *));
91 | #endif /* ARCF_MILTER_PROTOTYPES */
92 |
93 | #endif /* _OPENARC_H_ */
94 |
--------------------------------------------------------------------------------
/openarc/tests/Makefile.am:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trusteddomainproject/OpenARC/355ee2a1ca85acccce494478991983b54f794f4e/openarc/tests/Makefile.am
--------------------------------------------------------------------------------
/openarc/util.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** Copyright (c) 2016, 2017, The Trusted Domain Project.
3 | ** All rights reserved.
4 | */
5 |
6 | #ifndef _UTIL_H_
7 | #define _UTIL_H_
8 |
9 | /* system includes */
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 | /* openarc includes */
17 | #include "build-config.h"
18 |
19 | /* TYPES */
20 | struct arcf_dstring;
21 |
22 | /* PROTOTYPES */
23 | extern const char **arcf_mkarray __P((char *));
24 | extern size_t arcf_inet_ntoa __P((struct in_addr, char *, size_t));
25 | extern void arcf_lowercase __P((u_char *));
26 | extern void arcf_optlist __P((FILE *));
27 | extern void arcf_setmaxfd __P((void));
28 | extern int arcf_socket_cleanup __P((char *));
29 |
30 | extern struct arcf_dstring *arcf_dstring_new __P((int, int));
31 | extern void arcf_dstring_free __P((struct arcf_dstring *));
32 | extern _Bool arcf_dstring_copy __P((struct arcf_dstring *, u_char *));
33 | extern _Bool arcf_dstring_cat __P((struct arcf_dstring *, u_char *));
34 | extern _Bool arcf_dstring_cat1 __P((struct arcf_dstring *, int));
35 | extern _Bool arcf_dstring_catn __P((struct arcf_dstring *, u_char *, size_t));
36 | extern void arcf_dstring_chop __P((struct arcf_dstring *, int));
37 | extern u_char *arcf_dstring_get __P((struct arcf_dstring *));
38 | extern int arcf_dstring_len __P((struct arcf_dstring *));
39 | extern void arcf_dstring_blank __P((struct arcf_dstring *));
40 | extern size_t arcf_dstring_printf __P((struct arcf_dstring *, char *, ...));
41 |
42 | #endif /* _UTIL_H_ */
43 |
--------------------------------------------------------------------------------