mirror of
https://github.com/deneraraujo/OpenVPNAdapter.git
synced 2026-02-11 00:00:08 +08:00
Merge commit 'f65d76170b26155358c2fc27686f87e0475f6a94' as 'OpenVPN Adapter/Vendors/openvpn'
This commit is contained in:
1
OpenVPN Adapter/Vendors/openvpn/.gitignore
vendored
Normal file
1
OpenVPN Adapter/Vendors/openvpn/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
README.html
|
||||
65
OpenVPN Adapter/Vendors/openvpn/CLA.rst
Normal file
65
OpenVPN Adapter/Vendors/openvpn/CLA.rst
Normal file
@@ -0,0 +1,65 @@
|
||||
Contributor agreement for the OpenVPN project version 1.2 - March 2017
|
||||
########################################################################
|
||||
|
||||
This Contributor Agreement consists of two parts. Part I is the
|
||||
Developer Certificate of Origin available at
|
||||
http://developercertificate.org/.
|
||||
|
||||
In this contributor agreement, "This project" refers to the OpenVPN
|
||||
project and
|
||||
"open source license indicated in `the file <LICENSE.rst>`_" refers to
|
||||
the GPLv3 license with an additional permission that allows linking
|
||||
the OpenSSL software, https://www.openssl.org/, with the OpenVPN
|
||||
software.
|
||||
|
||||
Part I
|
||||
######
|
||||
|
||||
Developer Certificate of Origin Version 1.1
|
||||
|
||||
Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 1
|
||||
Letterman Drive Suite D4700 San Francisco, CA, 94129
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
Developer's Certificate of Origin 1.1
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I have
|
||||
the right to submit it under the open source license indicated in the
|
||||
file; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best of
|
||||
my knowledge, is covered under an appropriate open source license and
|
||||
I have the right under that license to submit that work with
|
||||
modifications, whether created in whole or in part by me, under the
|
||||
same open source license (unless I am permitted to submit under a
|
||||
different license), as indicated in the file; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other person
|
||||
who certified (a), (b) or (c) and I have not modified it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution are
|
||||
public and that a record of the contribution (including all personal
|
||||
information I submit with it, including my sign-off) is maintained
|
||||
indefinitely and may be redistributed consistent with this project or
|
||||
the open source license(s) involved.
|
||||
|
||||
Part II
|
||||
#######
|
||||
|
||||
Copyright (C) 2017 OpenVPN Technologies, Inc.
|
||||
|
||||
In addition:
|
||||
|
||||
(e) I understand that OpenVPN Technologies, Inc. may relicense this
|
||||
project, this contribution, and any modification to it under any
|
||||
license. I certify that I, or the person on whose behalf I am
|
||||
submitting the contribution, have the right to grant and hereby grant
|
||||
OpenVPN Technologies, Inc. a license to do so for this
|
||||
contribution. My grant is made on the condition that OpenVPN
|
||||
Technologies, Inc. will make any modification to this contribution
|
||||
available to the OpenVPN project under the open source license
|
||||
indicated in the file.
|
||||
7
OpenVPN Adapter/Vendors/openvpn/CONTRIBUTING.rst
Normal file
7
OpenVPN Adapter/Vendors/openvpn/CONTRIBUTING.rst
Normal file
@@ -0,0 +1,7 @@
|
||||
Contributing to OpenVPN 3
|
||||
=========================
|
||||
|
||||
Patches can be sent as GitHub pull requests.
|
||||
|
||||
Note that by contributing to the OpenVPN 3 project you accept the Contributor
|
||||
License Agreement described in `CLA.rst <CLA.rst>`_.
|
||||
674
OpenVPN Adapter/Vendors/openvpn/COPYRIGHT.GPLV3
Normal file
674
OpenVPN Adapter/Vendors/openvpn/COPYRIGHT.GPLV3
Normal file
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
15
OpenVPN Adapter/Vendors/openvpn/LICENSE.rst
Normal file
15
OpenVPN Adapter/Vendors/openvpn/LICENSE.rst
Normal file
@@ -0,0 +1,15 @@
|
||||
OpenVPN 3 is distributed under
|
||||
`GNU General Public License version 3 <COPYRIGHT.GPLV3>`_
|
||||
with a special permission to link against OpenSSL:
|
||||
|
||||
::
|
||||
|
||||
Additional permission under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or combining
|
||||
it with OpenSSL (or a modified version of that library), containing parts
|
||||
covered by the terms of the OpenSSL License or the Original SSLeay License,
|
||||
the licensors of this Program grant you additional permission to convey the
|
||||
resulting work. Corresponding Source for a non-source form of such a
|
||||
combination shall include the source code for the parts of OpenSSL used as
|
||||
well as that of the covered work.
|
||||
555
OpenVPN Adapter/Vendors/openvpn/README.rst
Normal file
555
OpenVPN Adapter/Vendors/openvpn/README.rst
Normal file
@@ -0,0 +1,555 @@
|
||||
OpenVPN 3
|
||||
=========
|
||||
|
||||
OpenVPN 3 is a C++ class library that implements the functionality
|
||||
of an OpenVPN client, and is protocol-compatible with the OpenVPN
|
||||
2.x branch.
|
||||
|
||||
OpenVPN 3 includes a minimal client wrapper (``cli``) that links in with
|
||||
the library and provides basic command line functionality.
|
||||
|
||||
OpenVPN 3 is currently used in production as the core of the
|
||||
OpenVPN Connect clients for iOS, Android, Linux, Windows, and Mac OS X.
|
||||
|
||||
NOTE: As of 2017, OpenVPN 3 is primarily of interest to developers,
|
||||
as it does not yet replicate the full functionality of OpenVPN 2.x.
|
||||
In particular, server functionality is not yet implemented.
|
||||
|
||||
.. contents:: Table of Contents
|
||||
|
||||
OpenVPN 3 Client API
|
||||
--------------------
|
||||
|
||||
OpenVPN 3 is organized as a C++ class library, and the API is defined in
|
||||
`<client/ovpncli.hpp>`_.
|
||||
|
||||
A simple command-line wrapper for the API is provided in
|
||||
`<test/ovpncli/cli.cpp>`_.
|
||||
|
||||
Building the OpenVPN 3 client on Linux
|
||||
--------------------------------------
|
||||
|
||||
These instructions were tested on Ubuntu 16.
|
||||
|
||||
Get prerequisites to allow for either mbedTLS or OpenSSL linkage::
|
||||
|
||||
$ sudo apt-get install g++ make libmbedtls-dev libssl-dev liblz4-dev
|
||||
|
||||
Get Asio C++ library::
|
||||
|
||||
$ cd ~
|
||||
$ git clone https://github.com/chriskohlhoff/asio.git
|
||||
|
||||
Set environmental variable used by OpenVPN 3 build scripts::
|
||||
|
||||
$ export O3=~/ovpn3
|
||||
|
||||
Clone the OpenVPN 3 source repo::
|
||||
|
||||
$ mkdir ~/ovpn3
|
||||
$ cd ~/ovpn3
|
||||
$ git clone https://github.com/OpenVPN/openvpn3.git core
|
||||
|
||||
Build the OpenVPN 3 client wrapper (cli) with mbedTLS crypto/ssl library
|
||||
and LZ4 compression::
|
||||
|
||||
$ cd $O3/core/test/ovpncli
|
||||
$ ECHO=1 PROF=linux ASIO_DIR=~/asio MTLS_SYS=1 LZ4_SYS=1 NOSSL=1 $O3/core/scripts/build cli
|
||||
|
||||
Or alternatively build with OpenSSL::
|
||||
|
||||
$ cd $O3/core/test/ovpncli
|
||||
$ ECHO=1 PROF=linux ASIO_DIR=~/asio OPENSSL_SYS=1 LZ4_SYS=1 $O3/core/scripts/build cli
|
||||
|
||||
Run OpenVPN 3 client::
|
||||
|
||||
$ sudo ./cli -a -c yes myprofile.ovpn route-nopull
|
||||
|
||||
Options used::
|
||||
|
||||
-a : use autologin sessions, if supported
|
||||
-c yes : negotiate LZ4 compression
|
||||
myprofile.ovpn : OpenVPN config file (must have .ovpn extension)
|
||||
route-nopull : if you are connected via ssh, prevent ssh session lockout
|
||||
|
||||
|
||||
Building the OpenVPN 3 client on Mac OS X
|
||||
-----------------------------------------
|
||||
|
||||
OpenVPN 3 should be built in a non-root Mac OS X account.
|
||||
Make sure that Xcode is installed with optional command-line tools.
|
||||
(These instructions have been tested with Xcode 5.1.1).
|
||||
|
||||
Create the directories ``~/src`` and ``~/src/mac``::
|
||||
|
||||
$ mkdir -p ~/src/mac
|
||||
|
||||
Clone the OpenVPN 3 repo::
|
||||
|
||||
$ cd ~/src
|
||||
$ mkdir ovpn3
|
||||
$ cd ovpn3
|
||||
$ git clone https://github.com/OpenVPN/openvpn3.git core
|
||||
|
||||
Export the shell variable ``O3`` to point to the OpenVPN 3 top level
|
||||
directory::
|
||||
|
||||
export O3=~/src/ovpn3
|
||||
|
||||
Download source tarballs (``.tar.gz`` or ``.tgz``) for these dependency
|
||||
libraries into ``~/Downloads``
|
||||
|
||||
See the file ``$O3/core/deps/lib-versions`` for the expected
|
||||
version numbers of each dependency. If you want to use a different
|
||||
version of the library than listed here, you can edit this file.
|
||||
|
||||
1. Asio — https://github.com/chriskohlhoff/asio
|
||||
2. mbed TLS (2.3.0 or higher) — https://tls.mbed.org/
|
||||
3. LZ4 — https://github.com/Cyan4973/lz4
|
||||
|
||||
For dependencies that are typically cloned from github vs.
|
||||
provided as a .tar.gz file, tools are provided to convert
|
||||
the github to a .tar.gz file. See "snapshot" scripts under
|
||||
``$O3/core/deps``
|
||||
|
||||
Note that while OpenSSL is listed in lib-versions, it is
|
||||
not required for Mac builds.
|
||||
|
||||
Build the dependencies::
|
||||
|
||||
$ OSX_ONLY=1 $O3/core/scripts/mac/build-all
|
||||
|
||||
Now build the OpenVPN 3 client executable::
|
||||
|
||||
$ cd $O3/core
|
||||
$ . vars/vars-osx64
|
||||
$ . vars/setpath
|
||||
$ cd test/ovpncli
|
||||
$ MTLS=1 LZ4=1 build cli
|
||||
|
||||
This will build the OpenVPN 3 client library with a small client
|
||||
wrapper (``cli``). It will also statically link in all external
|
||||
dependencies (Asio, mbedTLS, and LZ4), so ``cli`` may be distributed
|
||||
to other Macs and will run as a standalone executable.
|
||||
|
||||
These build scripts will create a **x86_x64** Mac OS X executable,
|
||||
with a minimum deployment target of 10.8.x. The Mac OS X tuntap driver is not
|
||||
required, as OpenVPN 3 can use the integrated utun interface if
|
||||
available.
|
||||
|
||||
To view the client wrapper options::
|
||||
|
||||
$ ./cli -h
|
||||
|
||||
To connect::
|
||||
|
||||
$ ./cli client.ovpn
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
The OpenVPN 3 core includes a stress/performance test of
|
||||
the OpenVPN protocol implementation. The test basically
|
||||
creates a virtualized lossy network between two OpenVPN
|
||||
protocol objects, triggers TLS negotiations between them,
|
||||
passes control/data channel messages, and measures the ability
|
||||
of the OpenVPN protocol objects to perform and remain in
|
||||
a valid state.
|
||||
|
||||
The OpenVPN protocol implementation that is being tested
|
||||
is here: `<openvpn/ssl/proto.hpp>`_
|
||||
|
||||
The test code itself is here: `<test/ssl/proto.cpp>`_
|
||||
|
||||
Build the test::
|
||||
|
||||
$ cd ovpn3/core/test/ssl
|
||||
$ ECHO=1 PROF=linux ASIO_DIR=~/asio MTLS_SYS=1 NOSSL=1 $O3/core/scripts/build proto
|
||||
|
||||
Run the test::
|
||||
|
||||
$ time ./proto
|
||||
*** app bytes=72777936 net_bytes=122972447 data_bytes=415892854 prog=0000216599/0000216598 D=12700/600/12700/600 N=109/109 SH=17400/15300 HE=0/0
|
||||
|
||||
real 0m15.813s
|
||||
user 0m15.800s
|
||||
sys 0m0.004s
|
||||
|
||||
|
||||
Developer Guide
|
||||
---------------
|
||||
|
||||
OpenVPN 3 is written in C++11 and developers who are moving
|
||||
from C to C++ should take some time to familiarize themselves with
|
||||
key C++ design patterns such as *RAII*:
|
||||
|
||||
https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization
|
||||
|
||||
OpenVPN 3 Client Core
|
||||
+++++++++++++++++++++
|
||||
|
||||
OpenVPN 3 is designed as a class library, with an API that
|
||||
is essentially defined inside of namespace ``ClientAPI``
|
||||
with headers and implementation in `<client>`_ and
|
||||
header-only library files under `<openvpn>`_.
|
||||
|
||||
The consise definition of the client API is essentially ``class OpenVPNClient``
|
||||
in `<client/ovpncli.hpp>`_ with several imporant extensions to
|
||||
the API found in:
|
||||
|
||||
* **class TunBuilderBase** in `<openvpn/tun/builder/base.hpp>`_ —
|
||||
Provides an abstraction layer defining the *tun* interface,
|
||||
and is especially useful for interfacing with an OS-layer VPN API.
|
||||
|
||||
* **class ExternalPKIBase** in `<openvpn/pki/epkibase.hpp>`_ —
|
||||
Provides a callback for external private key operations, and
|
||||
is useful for interfacing with an OS-layer Keychain such as
|
||||
the Keychain on iOS, Mac OS X, and Android, and the Crypto API
|
||||
on Windows.
|
||||
|
||||
* **class LogReceiver** in `<client/ovpncli.hpp>`_ —
|
||||
Provides an abstraction layer for the delivery of logging messages.
|
||||
|
||||
OpenVPN 3 includes a command-line reference client (``cli``) for
|
||||
testing the API. See `<test/ovpncli/cli.cpp>`_.
|
||||
|
||||
The basic approach to building an OpenVPN 3 client is
|
||||
to define a client class that derives from
|
||||
``ClientAPI::OpenVPNClient``, then provide implementations
|
||||
for callbacks including event and logging notifications:
|
||||
|
||||
.. code:: c++
|
||||
|
||||
class Client : public ClientAPI::OpenVPNClient
|
||||
{
|
||||
public:
|
||||
virtual void event(const Event&) override { // events delivered here
|
||||
...
|
||||
}
|
||||
virtual void log(const LogInfo&) override { // logging delivered here
|
||||
...
|
||||
}
|
||||
|
||||
...
|
||||
};
|
||||
|
||||
To start the client, first create a ``ClientAPI::Config`` object
|
||||
and initialize it with the OpenVPN config file and other options:
|
||||
|
||||
.. code:: c++
|
||||
|
||||
ClientAPI::Config config;
|
||||
config.content = <config_file_content_as_multiline_string>;
|
||||
...
|
||||
|
||||
Next, create a client object and evaluate the configuration:
|
||||
|
||||
.. code:: c++
|
||||
|
||||
Client client;
|
||||
ClientAPI::EvalConfig eval = client.eval_config(config);
|
||||
if (eval.error)
|
||||
throw ...;
|
||||
|
||||
Finally, in a new worker thread, start the connection:
|
||||
|
||||
.. code:: c++
|
||||
|
||||
ClientAPI::Status connect_status = client.connect();
|
||||
|
||||
Note that ``client.connect()`` will not return until
|
||||
the session has terminated.
|
||||
|
||||
Top Layer
|
||||
.........
|
||||
|
||||
The top layer of the OpenVPN 3 client is implemented
|
||||
in `<test/ovpncli/cli.cpp>`_ and `<openvpn/client/cliopt.hpp>`_.
|
||||
Most of what this code does is marshalling the configuration and
|
||||
dispatching the higher-level objects that implement the OpenVPN
|
||||
client session.
|
||||
|
||||
Connection
|
||||
..........
|
||||
|
||||
``class ClientConnect`` in `<openvpn/client/cliconnect.hpp>`_
|
||||
implements the top-level connection logic for an OpenVPN client
|
||||
connection. It is concerned with starting, stopping, pausing, and resuming
|
||||
OpenVPN client connections. It deals with retrying a connection and handles
|
||||
the connection timeout. It also deals with connection exceptions and understands
|
||||
the difference between an exception that should halt any further reconnection
|
||||
attempts (such as ``AUTH_FAILED``), and other exceptions such as network errors
|
||||
that would justify a retry.
|
||||
|
||||
Some of the methods in the class
|
||||
(such as ``stop``, ``pause``, and ``reconnect``) are often
|
||||
called by another thread that is controlling the connection, therefore
|
||||
thread-safe methods are provided where the thread-safe function posts a message
|
||||
to the actual connection thread.
|
||||
|
||||
In an OpenVPN client connection, the following object stack would be used:
|
||||
|
||||
1. **class ClientConnect** in `<openvpn/client/cliconnect.hpp>`_ —
|
||||
The top-layer object in an OpenVPN client connection.
|
||||
2. **class ClientProto::Session** in `<openvpn/client/cliproto.hpp>`_ —
|
||||
The OpenVPN client protocol object that subinstantiates the transport
|
||||
and tun layer objects.
|
||||
3. **class ProtoContext** in `<openvpn/ssl/proto.hpp>`_ —
|
||||
The core OpenVPN protocol implementation that is common to both
|
||||
client and server.
|
||||
4. **class ProtoStackBase<Packet>** in `<openvpn/ssl/protostack.hpp>`_ —
|
||||
The bottom-layer class that implements
|
||||
the basic functionality of tunneling a protocol over a reliable or
|
||||
unreliable transport layer, but isn't specific to OpenVPN per-se.
|
||||
|
||||
Transport Layer
|
||||
...............
|
||||
|
||||
OpenVPN 3 defines abstract base classes for Transport layer
|
||||
implementations in `<openvpn/transport/client/transbase.hpp>`_.
|
||||
|
||||
Currently, transport layer implementations are provided for:
|
||||
|
||||
* **UDP** — `<openvpn/transport/client/udpcli.hpp>`_
|
||||
* **TCP** — `<openvpn/transport/client/tcpcli.hpp>`_
|
||||
* **HTTP Proxy** — `<openvpn/transport/client/httpcli.hpp>`_
|
||||
|
||||
Tun Layer
|
||||
.........
|
||||
|
||||
OpenVPN 3 defines abstract base classes for Tun layer
|
||||
implementations in `<openvpn/tun/client/tunbase.hpp>`_.
|
||||
|
||||
There are two possible approaches to define a Tun
|
||||
layer implementation:
|
||||
|
||||
1. Use a VPN API-centric model (such as for Android
|
||||
or iOS). These models derive from **class TunBuilderBase**
|
||||
in `<openvpn/tun/builder/base.hpp>`_
|
||||
|
||||
2. Use an OS-specific model such as:
|
||||
|
||||
* **Linux** — `<openvpn/tun/linux/client/tuncli.hpp>`_
|
||||
* **Windows** — `<openvpn/tun/win/client/tuncli.hpp>`_
|
||||
* **Mac OS X** — `<openvpn/tun/mac/client/tuncli.hpp>`_
|
||||
|
||||
Protocol Layer
|
||||
..............
|
||||
|
||||
The OpenVPN protocol is implemented in **class ProtoContext**
|
||||
in `<openvpn/ssl/proto.hpp>`_.
|
||||
|
||||
Options Processing
|
||||
..................
|
||||
|
||||
The parsing and query of the OpenVPN config file
|
||||
is implemented by ``class OptionList`` in
|
||||
`<openvpn/common/options.hpp>`_.
|
||||
|
||||
Note that OpenVPN 3 always assumes an *inline* style of
|
||||
configuration, where all certs, keys, etc. are
|
||||
defined inline rather than through an external file
|
||||
reference.
|
||||
|
||||
For config files that do use external file references,
|
||||
``class ProfileMerge`` in `<openvpn/options/merge.hpp>`_
|
||||
is provided to merge those external
|
||||
file references into an inline form.
|
||||
|
||||
Calling the Client API from other languages
|
||||
...........................................
|
||||
|
||||
The OpenVPN 3 client API, as defined by ``class OpenVPNClient``
|
||||
in `<client/ovpncli.hpp>`_, can be wrapped by the
|
||||
Swig_ tool to create bindings for other languages.
|
||||
|
||||
.. _Swig: http://www.swig.org/
|
||||
|
||||
For example, OpenVPN Connect for Android creates a Java
|
||||
binding of the API using `<javacli/ovpncli.i>`_.
|
||||
|
||||
Security
|
||||
++++++++
|
||||
|
||||
When developing security software in C++, it's very important to
|
||||
take advantage of the language and OpenVPN library code
|
||||
to insulate code from the kinds of
|
||||
bugs that can introduce security vulnerabilities.
|
||||
|
||||
Here is a brief set of guidelines:
|
||||
|
||||
* When dealing with strings, use a ``std::string``
|
||||
rather than a ``char *``.
|
||||
|
||||
* When dealing with binary data or buffers, always try to use a ``Buffer``,
|
||||
``ConstBuffer``, ``BufferAllocated``, or ``BufferPtr`` object to
|
||||
provide managed access to the buffer, to protect against security
|
||||
bugs that arise when using raw buffer pointers.
|
||||
See `<openvpn/buffer/buffer.hpp>`_ for the OpenVPN ``Buffer`` classes.
|
||||
|
||||
* When it's necessary to have a pointer to an object, use
|
||||
``std::unique_ptr<>`` for non-shared objects and reference-counted
|
||||
smart pointers for shared objects. For shared-pointers,
|
||||
OpenVPN code should use the smart pointer classes defined
|
||||
in `<openvpn/common/rc.hpp>`_. Please see the comments in
|
||||
this file for documentation.
|
||||
|
||||
* Never use ``malloc`` or ``free``. When allocating objects,
|
||||
use the C++ ``new`` operator and then immediately construct
|
||||
a smart pointer to reference the object:
|
||||
|
||||
.. code:: c++
|
||||
|
||||
std::unique_ptr<MyObject> ptr = new MyObject();
|
||||
ptr->method();
|
||||
|
||||
* When interfacing with C functions that deal with
|
||||
raw pointers, memory allocation, etc., consider wrapping
|
||||
the functionality in C++. For an example, see ``enum_dir()``
|
||||
in `<openvpn/common/enumdir.hpp>`_,
|
||||
a function that returns a list of files in
|
||||
a directory (Unix only) via a high-level
|
||||
string vector, while internally calling
|
||||
the low level libc methods
|
||||
``opendir``, ``readdir``, and ``closedir``.
|
||||
Notice how ``unique_ptr_del`` is used to wrap the
|
||||
``DIR`` struct in a smart pointer with a custom
|
||||
deletion function.
|
||||
|
||||
* When grabbing random entropy that is to be used
|
||||
for cryptographic purposes (i.e. for keys, tokens, etc.),
|
||||
always ensure that the RNG is crypto-grade by calling
|
||||
``assert_crypto()`` on the RNG. This will throw
|
||||
an exception if the RNG is not crypto-grade:
|
||||
|
||||
.. code:: c++
|
||||
|
||||
void set_rng(RandomAPI::Ptr rng_arg) {
|
||||
rng_arg->assert_crypto();
|
||||
rng = std::move(rng_arg);
|
||||
}
|
||||
|
||||
* Any variable whose value is not expected to change should
|
||||
be declared ``const``.
|
||||
|
||||
* Don't use non-const global or static variables unless absolutely
|
||||
necessary.
|
||||
|
||||
* When formatting strings, don't use ``snprintf``. Instead, use
|
||||
``std::ostringstream`` or build the string using the '+' ``std::string``
|
||||
operator:
|
||||
|
||||
.. code:: c++
|
||||
|
||||
std::string format_reconnecting(const int n_seconds) {
|
||||
return "Reconnecting in " + openvpn::to_string(n_seconds) + " seconds.";
|
||||
}
|
||||
|
||||
or:
|
||||
|
||||
.. code:: c++
|
||||
|
||||
std::string format_reconnecting(const int n_seconds) {
|
||||
std::ostringstream os;
|
||||
os << "Reconnecting in " << n_seconds << " seconds.";
|
||||
return os.str();
|
||||
}
|
||||
|
||||
* OpenVPN 3 is a "header-only" library, therefore all free functions
|
||||
outside of classes should have the ``inline`` attribute.
|
||||
|
||||
Conventions
|
||||
+++++++++++
|
||||
|
||||
* Use the **Asio** library for I/O and timers.
|
||||
Don't deal with sockets directly.
|
||||
|
||||
* Never block. If you need to wait for something, use **Asio** timers
|
||||
or sockets.
|
||||
|
||||
* Use the ``OPENVPN_LOG()`` macro to log stuff. Don't use ``printf``.
|
||||
|
||||
* Don't call crypto/ssl libraries directly. Instead use the abstraction
|
||||
layers (`<openvpn/crypto>`_ and `<openvpn/ssl>`_) that allow OpenVPN
|
||||
to link with different crypto/ssl libraries (such as **OpenSSL**
|
||||
or **mbed TLS**).
|
||||
|
||||
* Use ``RandomAPI`` as a wrapper for random number
|
||||
generators (`<openvpn/random/randapi.hpp>`_).
|
||||
|
||||
* If you need to deal with configuration file options,
|
||||
see ``class OptionList`` in `<openvpn/common/options.hpp>`_.
|
||||
|
||||
* If you need to deal with time or time durations, use the
|
||||
classes under `<openvpn/time>`_.
|
||||
|
||||
* If you need to deal with IP addresses, see the comprehensive classes
|
||||
under `<openvpn/addr>`_.
|
||||
|
||||
* In general, if you need a general-purpose library class or function,
|
||||
look under `<openvpn/common>`_. Chances are good that it's already
|
||||
been implemented.
|
||||
|
||||
* The OpenVPN 3 approach to errors is to count them, rather than
|
||||
unconditionally log them. If you need to add a new error
|
||||
counter, see `<openvpn/error/error.hpp>`_.
|
||||
|
||||
* If you need to create a new event type which can be transmitted
|
||||
as a notification back to the client API user, see
|
||||
`<openvpn/client/clievent.hpp>`_.
|
||||
|
||||
* Raw pointers or references can be okay when used by an object to
|
||||
point back to its parent (or container), if you can guarantee that
|
||||
the object will not outlive its parent. Backreferences to a parent
|
||||
object is also a common use case for weak pointers.
|
||||
|
||||
* Use C++ exceptions for error handling and as an alternative
|
||||
to ``goto``. See OpenVPN's general exception classes
|
||||
and macros in `<openvpn/common/exception.hpp>`_.
|
||||
|
||||
* Use C++ destructors for automatic object cleanup, and so
|
||||
that thrown exceptions will not leak objects. Alternatively,
|
||||
use ``Cleanup`` in `<openvpn/common/cleanup.hpp>`_ when
|
||||
you need to specify a code block to execute prior to scope
|
||||
exit. For example, ensure that the file ``pid_fn`` is
|
||||
deleted before scope exit:
|
||||
|
||||
.. code:: c++
|
||||
|
||||
auto clean = Cleanup([pid_fn]() {
|
||||
if (pid_fn)
|
||||
::unlink(pid_fn);
|
||||
});
|
||||
|
||||
* When calling global methods (such as libc ``fork``),
|
||||
prepend "::" to the symbol name, e.g.:
|
||||
|
||||
.. code:: c++
|
||||
|
||||
struct dirent *e;
|
||||
while ((e = ::readdir(dir.get())) != nullptr) {
|
||||
...
|
||||
}
|
||||
|
||||
* Use ``nullptr`` instead of ``NULL``.
|
||||
|
||||
Threading
|
||||
+++++++++
|
||||
|
||||
The OpenVPN 3 client core is designed to run in a single thread, with
|
||||
the UI or controller driving the OpenVPN API running in a different
|
||||
thread.
|
||||
|
||||
It's almost never necessary to create additional threads within
|
||||
the OpenVPN 3 client core.
|
||||
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
See `<CONTRIBUTING.rst>`_.
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
See `<LICENSE.rst>`_.
|
||||
1222
OpenVPN Adapter/Vendors/openvpn/client/ovpncli.cpp
Normal file
1222
OpenVPN Adapter/Vendors/openvpn/client/ovpncli.cpp
Normal file
File diff suppressed because it is too large
Load Diff
573
OpenVPN Adapter/Vendors/openvpn/client/ovpncli.hpp
Normal file
573
OpenVPN Adapter/Vendors/openvpn/client/ovpncli.hpp
Normal file
@@ -0,0 +1,573 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// API for OpenVPN Client, may be used standalone or wrapped by swig.
|
||||
// Use ovpncli.i to wrap the API for swig.
|
||||
// The crux of the API is defined in OpenVPNClient (below)
|
||||
// and TunBuilderBase.
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
#include <openvpn/tun/builder/base.hpp>
|
||||
#include <openvpn/pki/epkibase.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
class OptionList;
|
||||
class ProfileMerge;
|
||||
class Stop;
|
||||
|
||||
namespace ClientAPI {
|
||||
// Represents an OpenVPN server and its friendly name
|
||||
// (client reads)
|
||||
struct ServerEntry
|
||||
{
|
||||
std::string server;
|
||||
std::string friendlyName;
|
||||
};
|
||||
|
||||
// return properties of config
|
||||
// (client reads)
|
||||
struct EvalConfig
|
||||
{
|
||||
// true if error
|
||||
bool error = false;
|
||||
|
||||
// if error, message given here
|
||||
std::string message;
|
||||
|
||||
// this username must be used with profile
|
||||
std::string userlockedUsername;
|
||||
|
||||
// profile name of config
|
||||
std::string profileName;
|
||||
|
||||
// "friendly" name of config
|
||||
std::string friendlyName;
|
||||
|
||||
// true: no creds required, false: username/password required
|
||||
bool autologin = false;
|
||||
|
||||
// if true, this is an External PKI profile (no cert or key directives)
|
||||
bool externalPki = false;
|
||||
|
||||
// static challenge, may be empty, ignored if autologin
|
||||
std::string staticChallenge;
|
||||
|
||||
// true if static challenge response should be echoed to UI, ignored if autologin
|
||||
bool staticChallengeEcho = false;
|
||||
|
||||
// true if this profile requires a private key password
|
||||
bool privateKeyPasswordRequired = false;
|
||||
|
||||
// true if user is allowed to save authentication password in UI
|
||||
bool allowPasswordSave = false;
|
||||
|
||||
// information about the first remote item in config
|
||||
std::string remoteHost; // will be overridden by Config::serverOverride if defined
|
||||
std::string remotePort;
|
||||
std::string remoteProto;
|
||||
|
||||
// optional list of user-selectable VPN servers
|
||||
std::vector<ServerEntry> serverList;
|
||||
};
|
||||
|
||||
// used to pass credentials to VPN core
|
||||
// (client writes)
|
||||
struct ProvideCreds
|
||||
{
|
||||
std::string username;
|
||||
std::string password;
|
||||
|
||||
// response to challenge
|
||||
std::string response;
|
||||
|
||||
// Dynamic challenge/response cookie
|
||||
std::string dynamicChallengeCookie;
|
||||
|
||||
// If true, on successful connect, we will replace the password
|
||||
// with the session ID we receive from the server (if provided).
|
||||
// If false, the password will be cached for future reconnects
|
||||
// and will not be replaced with a session ID, even if the
|
||||
// server provides one.
|
||||
bool replacePasswordWithSessionID = false;
|
||||
|
||||
// If true, and if replacePasswordWithSessionID is true, and if
|
||||
// we actually receive a session ID from the server, cache
|
||||
// the user-provided password for future use before replacing
|
||||
// the active password with the session ID.
|
||||
bool cachePassword = false;
|
||||
};
|
||||
|
||||
// used to get session token from VPN core
|
||||
// (client reads)
|
||||
struct SessionToken
|
||||
{
|
||||
std::string username;
|
||||
std::string session_id; // an OpenVPN Session ID, used as a proxy for password
|
||||
};
|
||||
|
||||
// used to query challenge/response from user
|
||||
// (client reads)
|
||||
struct DynamicChallenge
|
||||
{
|
||||
std::string challenge;
|
||||
bool echo = false;
|
||||
bool responseRequired = false;
|
||||
|
||||
std::string stateID;
|
||||
};
|
||||
|
||||
// a basic key/value pair, used in Config below when OpenVPN profile is
|
||||
// passed as a dictionary
|
||||
struct KeyValue
|
||||
{
|
||||
KeyValue() {}
|
||||
|
||||
KeyValue(std::string key_arg, std::string value_arg)
|
||||
: key(std::move(key_arg)),
|
||||
value(std::move(value_arg)) {}
|
||||
|
||||
std::string key;
|
||||
std::string value;
|
||||
};
|
||||
|
||||
// OpenVPN config-file/profile
|
||||
// (client writes)
|
||||
struct Config
|
||||
{
|
||||
// OpenVPN profile as a string
|
||||
std::string content;
|
||||
|
||||
// OpenVPN profile as series of key/value pairs (may be provided exclusively
|
||||
// or in addition to content string above).
|
||||
std::vector<KeyValue> contentList;
|
||||
|
||||
// Set to identity OpenVPN GUI version.
|
||||
// Format should be "<gui_identifier><space><version>"
|
||||
// Passed to server as IV_GUI_VER.
|
||||
std::string guiVersion;
|
||||
|
||||
// Use a different server than that specified in "remote"
|
||||
// option of profile
|
||||
std::string serverOverride;
|
||||
|
||||
// Force a given transport protocol
|
||||
// Should be tcp, udp, or adaptive.
|
||||
std::string protoOverride;
|
||||
|
||||
// IPv6 preference
|
||||
// no -- disable IPv6, so tunnel will be IPv4-only
|
||||
// yes -- request combined IPv4/IPv6 tunnel
|
||||
// default (or empty string) -- leave decision to server
|
||||
std::string ipv6;
|
||||
|
||||
// Connection timeout in seconds, or 0 to retry indefinitely
|
||||
int connTimeout = 0;
|
||||
|
||||
// Keep tun interface active during pauses or reconnections
|
||||
bool tunPersist = false;
|
||||
|
||||
// If true and a redirect-gateway profile doesn't also define
|
||||
// DNS servers, use the standard Google DNS servers.
|
||||
bool googleDnsFallback = false;
|
||||
|
||||
// Enable autologin sessions
|
||||
bool autologinSessions = true;
|
||||
|
||||
// An ID used for get-certificate and RSA signing callbacks
|
||||
// for External PKI profiles.
|
||||
std::string externalPkiAlias;
|
||||
|
||||
// If true, don't send client cert/key to peer.
|
||||
bool disableClientCert = false;
|
||||
|
||||
// SSL library debug level
|
||||
int sslDebugLevel = 0;
|
||||
|
||||
// Compression mode, one of:
|
||||
// yes -- allow compression on both uplink and downlink
|
||||
// asym -- allow compression on downlink only (i.e. server -> client)
|
||||
// no (default if empty) -- support compression stubs only
|
||||
std::string compressionMode;
|
||||
|
||||
// private key password (optional)
|
||||
std::string privateKeyPassword;
|
||||
|
||||
// Default key direction parameter for tls-auth (0, 1, or
|
||||
// -1 (bidirectional -- default)) if no key-direction parameter
|
||||
// defined in profile. Generally should be -1 (bidirectional)
|
||||
// for compatibility with 2.x branch
|
||||
int defaultKeyDirection = -1;
|
||||
|
||||
// If true, force ciphersuite to be one of:
|
||||
// 1. TLS_DHE_RSA_WITH_AES_256_CBC_SHA, or
|
||||
// 2. TLS_DHE_RSA_WITH_AES_128_CBC_SHA
|
||||
// and disable setting TLS minimum version.
|
||||
// This is intended for compatibility with legacy systems.
|
||||
bool forceAesCbcCiphersuites = false;
|
||||
|
||||
// Override the minimum TLS version:
|
||||
// disabled -- don't specify a minimum, and disable any minimum
|
||||
// specified in profile
|
||||
// default or "" -- use profile minimum
|
||||
// tls_1_0 -- use TLS 1.0 minimum (overrides profile)
|
||||
// tls_1_1 -- use TLS 1.1 minimum (overrides profile)
|
||||
// tls_1_2 -- use TLS 1.2 minimum (overrides profile)
|
||||
std::string tlsVersionMinOverride;
|
||||
|
||||
// Override or default the tls-cert-profile setting:
|
||||
// default or "" -- use profile default
|
||||
// legacy -- allow 1024-bit RSA certs signed with SHA1
|
||||
// preferred -- require at least 2048-bit RSA certs signed
|
||||
// with SHA256 or higher
|
||||
// suiteb -- require NSA Suite-B
|
||||
// legacy-default -- use legacy as the default if profile
|
||||
// doesn't specify tls-cert-profile
|
||||
// preferred-default -- use preferred as the default if profile
|
||||
// doesn't specify tls-cert-profile
|
||||
std::string tlsCertProfileOverride;
|
||||
|
||||
// Pass custom key/value pairs to OpenVPN server.
|
||||
std::vector<KeyValue> peerInfo;
|
||||
|
||||
// HTTP Proxy parameters (optional)
|
||||
std::string proxyHost; // hostname or IP address of proxy
|
||||
std::string proxyPort; // port number of proxy
|
||||
std::string proxyUsername; // proxy credentials (optional)
|
||||
std::string proxyPassword; // proxy credentials (optional)
|
||||
bool proxyAllowCleartextAuth = false; // enables HTTP Basic auth
|
||||
|
||||
// Custom proxy implementation
|
||||
bool altProxy = false;
|
||||
|
||||
// Custom Data Channel Offload implementation
|
||||
bool dco = false;
|
||||
|
||||
// pass through pushed "echo" directives via "ECHO" event
|
||||
bool echo = false;
|
||||
|
||||
// pass through control channel INFO notifications via "INFO" event
|
||||
bool info = false;
|
||||
|
||||
// Gremlin configuration (requires that the core is built with OPENVPN_GREMLIN)
|
||||
std::string gremlinConfig;
|
||||
};
|
||||
|
||||
// used to communicate VPN events such as connect, disconnect, etc.
|
||||
// (client reads)
|
||||
struct Event
|
||||
{
|
||||
bool error = false; // true if error (fatal or nonfatal)
|
||||
bool fatal = false; // true if fatal error (will disconnect)
|
||||
std::string name; // event name
|
||||
std::string info; // additional event info
|
||||
};
|
||||
|
||||
// used to communicate extra details about successful connection
|
||||
// (client reads)
|
||||
struct ConnectionInfo
|
||||
{
|
||||
bool defined = false;
|
||||
std::string user;
|
||||
std::string serverHost;
|
||||
std::string serverPort;
|
||||
std::string serverProto;
|
||||
std::string serverIp;
|
||||
std::string vpnIp4;
|
||||
std::string vpnIp6;
|
||||
std::string gw4;
|
||||
std::string gw6;
|
||||
std::string clientIp;
|
||||
std::string tunName;
|
||||
};
|
||||
|
||||
// returned by some methods as a status/error indication
|
||||
// (client reads)
|
||||
struct Status
|
||||
{
|
||||
bool error = false; // true if error
|
||||
std::string status; // an optional short error label that identifies the error
|
||||
std::string message; // if error, message given here
|
||||
};
|
||||
|
||||
// used to pass log lines
|
||||
// (client reads)
|
||||
struct LogInfo
|
||||
{
|
||||
LogInfo() {}
|
||||
LogInfo(std::string str);
|
||||
std::string text; // log output (usually but not always one line)
|
||||
};
|
||||
|
||||
// receives log messages
|
||||
struct LogReceiver
|
||||
{
|
||||
virtual void log(const LogInfo&) = 0;
|
||||
virtual ~LogReceiver() {}
|
||||
};
|
||||
|
||||
// used to pass stats for an interface
|
||||
struct InterfaceStats
|
||||
{
|
||||
long long bytesIn;
|
||||
long long packetsIn;
|
||||
long long errorsIn;
|
||||
long long bytesOut;
|
||||
long long packetsOut;
|
||||
long long errorsOut;
|
||||
};
|
||||
|
||||
// used to pass basic transport stats
|
||||
struct TransportStats
|
||||
{
|
||||
long long bytesIn;
|
||||
long long bytesOut;
|
||||
long long packetsIn;
|
||||
long long packetsOut;
|
||||
|
||||
// number of binary milliseconds (1/1024th of a second) since
|
||||
// last packet was received, or -1 if undefined
|
||||
int lastPacketReceived;
|
||||
};
|
||||
|
||||
// return value of merge_config methods
|
||||
struct MergeConfig
|
||||
{
|
||||
std::string status; // ProfileMerge::Status codes rendered as string
|
||||
std::string errorText; // error string (augments status)
|
||||
std::string basename; // profile basename
|
||||
std::string profileContent; // unified profile
|
||||
std::vector<std::string> refPathList; // list of all reference paths successfully read
|
||||
};
|
||||
|
||||
// base class for External PKI queries
|
||||
struct ExternalPKIRequestBase
|
||||
{
|
||||
bool error = false; // true if error occurred (client writes)
|
||||
std::string errorText; // text describing error (client writes)
|
||||
bool invalidAlias = false; // true if the error is caused by an invalid alias (client writes)
|
||||
std::string alias; // the alias string, used to query cert/key (client reads)
|
||||
};
|
||||
|
||||
// used to query for External PKI certificate
|
||||
struct ExternalPKICertRequest : public ExternalPKIRequestBase
|
||||
{
|
||||
// leaf cert
|
||||
std::string cert; // (client writes)
|
||||
|
||||
// chain of intermediates and root (optional)
|
||||
std::string supportingChain; // (client writes)
|
||||
};
|
||||
|
||||
// Used to request an RSA signature.
|
||||
// Data will be prefixed by an optional PKCS#1 digest prefix
|
||||
// per RFC 3447.
|
||||
struct ExternalPKISignRequest : public ExternalPKIRequestBase
|
||||
{
|
||||
std::string data; // data rendered as base64 (client reads)
|
||||
std::string sig; // RSA signature, rendered as base64 (client writes)
|
||||
};
|
||||
|
||||
// used to override "remote" directives
|
||||
struct RemoteOverride
|
||||
{
|
||||
// components of "remote" directive (client writes),
|
||||
std::string host; // either one of host
|
||||
std::string ip; // or ip must be defined (or both)
|
||||
std::string port;
|
||||
std::string proto;
|
||||
};
|
||||
|
||||
namespace Private {
|
||||
class ClientState;
|
||||
};
|
||||
|
||||
// Top-level OpenVPN client class.
|
||||
class OpenVPNClient : public TunBuilderBase, public LogReceiver, private ExternalPKIBase {
|
||||
public:
|
||||
OpenVPNClient();
|
||||
virtual ~OpenVPNClient();
|
||||
|
||||
// Call me first, before calling any other method (static or instance methods)
|
||||
// in this class.
|
||||
static void init_process();
|
||||
|
||||
// Release any resources allocated by init_process.
|
||||
static void uninit_process();
|
||||
|
||||
// Read an OpenVPN profile that might contain external
|
||||
// file references, returning a unified profile.
|
||||
static MergeConfig merge_config_static(const std::string& path, bool follow_references);
|
||||
|
||||
// Read an OpenVPN profile that might contain external
|
||||
// file references, returning a unified profile.
|
||||
static MergeConfig merge_config_string_static(const std::string& config_content);
|
||||
|
||||
// Parse profile and determine needed credentials statically.
|
||||
static EvalConfig eval_config_static(const Config& config);
|
||||
|
||||
// Maximum size of profile that should be allowed
|
||||
static long max_profile_size();
|
||||
|
||||
// Parse a dynamic challenge cookie, placing the result in dc.
|
||||
// Return true on success or false if parse error.
|
||||
static bool parse_dynamic_challenge(const std::string& cookie, DynamicChallenge& dc);
|
||||
|
||||
// Parse OpenVPN configuration file.
|
||||
EvalConfig eval_config(const Config&);
|
||||
|
||||
// Provide credentials and other options. Call before connect().
|
||||
Status provide_creds(const ProvideCreds&);
|
||||
|
||||
// Callback to "protect" a socket from being routed through the tunnel.
|
||||
// Will be called from the thread executing connect().
|
||||
virtual bool socket_protect(int socket) = 0;
|
||||
|
||||
// Primary VPN client connect method, doesn't return until disconnect.
|
||||
// Should be called by a worker thread. This method will make callbacks
|
||||
// to event() and log() functions. Make sure to call eval_config()
|
||||
// and possibly provide_creds() as well before this function.
|
||||
Status connect();
|
||||
|
||||
// Return information about the most recent connection. Should be called
|
||||
// after an event of type "CONNECTED".
|
||||
ConnectionInfo connection_info();
|
||||
|
||||
// Writes current session token to tok and returns true.
|
||||
// If session token is unavailable, false is returned and
|
||||
// tok is unmodified.
|
||||
bool session_token(SessionToken& tok);
|
||||
|
||||
// Stop the client. Only meaningful when connect() is running.
|
||||
// May be called asynchronously from a different thread
|
||||
// when connect() is running.
|
||||
void stop();
|
||||
|
||||
// Pause the client -- useful to avoid continuous reconnection attempts
|
||||
// when network is down. May be called from a different thread
|
||||
// when connect() is running.
|
||||
void pause(const std::string& reason);
|
||||
|
||||
// Resume the client after it has been paused. May be called from a
|
||||
// different thread when connect() is running.
|
||||
void resume();
|
||||
|
||||
// Do a disconnect/reconnect cycle n seconds from now. May be called
|
||||
// from a different thread when connect() is running.
|
||||
void reconnect(int seconds);
|
||||
|
||||
// When a connection is close to timeout, the core will call this
|
||||
// method. If it returns false, the core will disconnect with a
|
||||
// CONNECTION_TIMEOUT event. If true, the core will enter a PAUSE
|
||||
// state.
|
||||
virtual bool pause_on_connection_timeout() = 0;
|
||||
|
||||
// Get stats/error info. May be called from a different thread
|
||||
// when connect() is running.
|
||||
|
||||
// number of stats
|
||||
static int stats_n();
|
||||
|
||||
// return a stats name, index should be >= 0 and < stats_n()
|
||||
static std::string stats_name(int index);
|
||||
|
||||
// return a stats value, index should be >= 0 and < stats_n()
|
||||
long long stats_value(int index) const;
|
||||
|
||||
// return all stats in a bundle
|
||||
std::vector<long long> stats_bundle() const;
|
||||
|
||||
// return tun stats only
|
||||
InterfaceStats tun_stats() const;
|
||||
|
||||
// return transport stats only
|
||||
TransportStats transport_stats() const;
|
||||
|
||||
// post control channel message
|
||||
void post_cc_msg(const std::string& msg);
|
||||
|
||||
// Callback for delivering events during connect() call.
|
||||
// Will be called from the thread executing connect().
|
||||
virtual void event(const Event&) = 0;
|
||||
|
||||
// Callback for logging.
|
||||
// Will be called from the thread executing connect().
|
||||
virtual void log(const LogInfo&) = 0;
|
||||
|
||||
// External PKI callbacks
|
||||
// Will be called from the thread executing connect().
|
||||
virtual void external_pki_cert_request(ExternalPKICertRequest&) = 0;
|
||||
virtual void external_pki_sign_request(ExternalPKISignRequest&) = 0;
|
||||
|
||||
// Remote override callback (disabled by default).
|
||||
virtual bool remote_override_enabled();
|
||||
virtual void remote_override(RemoteOverride&);
|
||||
|
||||
// Do a crypto library self test
|
||||
static std::string crypto_self_test();
|
||||
|
||||
// Returns date/time of app expiration as a unix time value
|
||||
static int app_expire();
|
||||
|
||||
// Returns platform description string
|
||||
static std::string platform();
|
||||
|
||||
// Returns core copyright
|
||||
static std::string copyright();
|
||||
|
||||
// Hide protected methods/data from SWIG
|
||||
#ifdef SWIGJAVA
|
||||
private:
|
||||
#else
|
||||
protected:
|
||||
#endif
|
||||
|
||||
Status do_connect();
|
||||
|
||||
virtual void connect_attach();
|
||||
virtual void connect_pre_run();
|
||||
virtual void connect_run();
|
||||
virtual void connect_session_stop();
|
||||
|
||||
virtual Stop* get_async_stop();
|
||||
|
||||
Private::ClientState* state;
|
||||
|
||||
private:
|
||||
static void parse_config(const Config&, EvalConfig&, OptionList&);
|
||||
void parse_extras(const Config&, EvalConfig&);
|
||||
void external_pki_error(const ExternalPKIRequestBase&, const size_t err_type);
|
||||
void process_epki_cert_chain(const ExternalPKICertRequest& req);
|
||||
void check_app_expired();
|
||||
static MergeConfig build_merge_config(const ProfileMerge&);
|
||||
|
||||
// from ExternalPKIBase
|
||||
virtual bool sign(const std::string& data, std::string& sig);
|
||||
|
||||
// disable copy and assignment
|
||||
OpenVPNClient(const OpenVPNClient&) = delete;
|
||||
OpenVPNClient& operator=(const OpenVPNClient&) = delete;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
15
OpenVPN Adapter/Vendors/openvpn/deps/asio/build-asio
Executable file
15
OpenVPN Adapter/Vendors/openvpn/deps/asio/build-asio
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
if [ -z "$O3" ]; then
|
||||
echo O3 var must point to ovpn3 tree
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ -z "$DL" ] && DL=~/Downloads
|
||||
|
||||
. $O3/core/deps/lib-versions
|
||||
|
||||
rm -rf asio*
|
||||
tar xf $DL/$ASIO_VERSION.tar.gz
|
||||
cp -a $ASIO_VERSION asio
|
||||
@@ -0,0 +1,48 @@
|
||||
From 430862dee0dd960be1f702cc5ae0e7c0525d48a4 Mon Sep 17 00:00:00 2001
|
||||
From: James Yonan <james@openvpn.net>
|
||||
Date: Wed, 3 Aug 2016 11:42:38 -0600
|
||||
Subject: =?UTF-8?q?Added=20Apple=20NAT64=20support=20when=20both=20ASIO=5F?=
|
||||
=?UTF-8?q?HAS=5FGETADDRINFO=0Aand=20ASIO=5FAPPLE=5FNAT64=20are=20defined.?=
|
||||
|
||||
* When calling getaddrinfo(), Apple recommends to set
|
||||
AI_DEFAULT flags in hint.
|
||||
|
||||
* iOS bug workaround: sometimes iOS getaddrinfo() returns a
|
||||
non-zero scope ID for non-link-local addresses.
|
||||
Workaround by forcing scope ID to 0 for non-link-local
|
||||
addresses.
|
||||
---
|
||||
asio/include/asio/detail/impl/socket_ops.ipp | 17 +++++++++++++++++
|
||||
1 file changed, 17 insertions(+)
|
||||
|
||||
diff --git a/asio/include/asio/detail/impl/socket_ops.ipp b/asio/include/asio/detail/impl/socket_ops.ipp
|
||||
index d72afec..4f66c77 100644
|
||||
--- a/asio/include/asio/detail/impl/socket_ops.ipp
|
||||
+++ b/asio/include/asio/detail/impl/socket_ops.ipp
|
||||
@@ -3276,6 +3276,23 @@ asio::error_code getaddrinfo(const char* host,
|
||||
#elif !defined(ASIO_HAS_GETADDRINFO)
|
||||
int error = getaddrinfo_emulation(host, service, &hints, result);
|
||||
return ec = translate_addrinfo_error(error);
|
||||
+#elif defined(ASIO_HAS_GETADDRINFO) && defined(ASIO_APPLE_NAT64)
|
||||
+ // For NAT64 compatibility, Apple recommends to set AI_DEFAULT flags
|
||||
+ addrinfo_type new_hints = hints;
|
||||
+ new_hints.ai_flags |= AI_DEFAULT;
|
||||
+ int error = ::getaddrinfo(host, service, &new_hints, result);
|
||||
+
|
||||
+ // iOS bug workaround: sometimes iOS getaddrinfo() returns a non-zero scope ID
|
||||
+ // for non-link-local addresses. Workaround by forcing scope ID to 0 for
|
||||
+ // non-link-local addresses.
|
||||
+ if (!error && (*result)->ai_family == AF_INET6)
|
||||
+ {
|
||||
+ sockaddr_in6* a6 = (sockaddr_in6*)(*result)->ai_addr;
|
||||
+ if (a6->sin6_scope_id && !(IN6_IS_ADDR_LINKLOCAL(&a6->sin6_addr) || IN6_IS_ADDR_MC_NODELOCAL(&a6->sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&a6->sin6_addr)))
|
||||
+ a6->sin6_scope_id = 0;
|
||||
+ }
|
||||
+
|
||||
+ return ec = translate_addrinfo_error(error);
|
||||
#else
|
||||
int error = ::getaddrinfo(host, service, &hints, result);
|
||||
return ec = translate_addrinfo_error(error);
|
||||
--
|
||||
1.8.5.2 (Apple Git-48)
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
From d1758fee525c6adde63ff13df1ce00c63a9b7671 Mon Sep 17 00:00:00 2001
|
||||
From: James Yonan <james@openvpn.net>
|
||||
Date: Wed, 2 Sep 2015 12:18:48 -0700
|
||||
Subject: Added randomize() method to asio::ip::tcp::resolver::results_type.
|
||||
|
||||
---
|
||||
asio/include/asio/ip/basic_resolver_results.hpp | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/asio/include/asio/ip/basic_resolver_results.hpp b/asio/include/asio/ip/basic_resolver_results.hpp
|
||||
index dec2c7e..ae36906 100644
|
||||
--- a/asio/include/asio/ip/basic_resolver_results.hpp
|
||||
+++ b/asio/include/asio/ip/basic_resolver_results.hpp
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "asio/detail/config.hpp"
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
+#include <algorithm>
|
||||
#include "asio/detail/socket_ops.hpp"
|
||||
#include "asio/detail/socket_types.hpp"
|
||||
#include "asio/ip/basic_resolver_iterator.hpp"
|
||||
@@ -299,6 +300,12 @@ public:
|
||||
return !a.equal(b);
|
||||
}
|
||||
|
||||
+ template <typename Random>
|
||||
+ void randomize(Random& r)
|
||||
+ {
|
||||
+ std::shuffle(this->values_->begin(), this->values_->end(), r);
|
||||
+ }
|
||||
+
|
||||
private:
|
||||
typedef std::vector<basic_resolver_entry<InternetProtocol> > values_type;
|
||||
};
|
||||
--
|
||||
1.8.5.2 (Apple Git-48)
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
From 48f2e874280f0d93d1a3df2e48aacc9e13b8eef5 Mon Sep 17 00:00:00 2001
|
||||
From: James Yonan <james@openvpn.net>
|
||||
Date: Wed, 1 Mar 2017 13:45:38 -0700
|
||||
Subject: Android appears to not support pthread_condattr_setclock
|
||||
|
||||
---
|
||||
asio/include/asio/detail/impl/posix_event.ipp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/asio/include/asio/detail/impl/posix_event.ipp b/asio/include/asio/detail/impl/posix_event.ipp
|
||||
index a62c434..c4b7982 100644
|
||||
--- a/asio/include/asio/detail/impl/posix_event.ipp
|
||||
+++ b/asio/include/asio/detail/impl/posix_event.ipp
|
||||
@@ -31,7 +31,7 @@ namespace detail {
|
||||
posix_event::posix_event()
|
||||
: state_(0)
|
||||
{
|
||||
-#if (defined(__MACH__) && defined(__APPLE__))
|
||||
+#if (defined(__MACH__) && defined(__APPLE__)) || defined(__ANDROID__)
|
||||
int error = ::pthread_cond_init(&cond_, 0);
|
||||
#else // (defined(__MACH__) && defined(__APPLE__))
|
||||
::pthread_condattr_t attr;
|
||||
--
|
||||
2.7.4
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
From 630edbebfc2f77ad29480d884e20d0b767883ac2 Mon Sep 17 00:00:00 2001
|
||||
From: James Yonan <james@openvpn.net>
|
||||
Date: Mon, 27 Feb 2017 13:01:26 -0700
|
||||
Subject: =?UTF-8?q?Added=20user=20code=20hook=20async=5Fconnect=5Fpost=5Fo?=
|
||||
=?UTF-8?q?pen()=20to=20be=20called=0Aimmediately=20after=20socket=20open?=
|
||||
=?UTF-8?q?=20in=20async=5Fconnect.?=
|
||||
|
||||
---
|
||||
asio/include/asio/basic_socket.hpp | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/asio/include/asio/basic_socket.hpp b/asio/include/asio/basic_socket.hpp
|
||||
index cbd9b35..dbc9297 100644
|
||||
--- a/asio/include/asio/basic_socket.hpp
|
||||
+++ b/asio/include/asio/basic_socket.hpp
|
||||
@@ -866,6 +866,8 @@ public:
|
||||
asio::error_code ec;
|
||||
const protocol_type protocol = peer_endpoint.protocol();
|
||||
this->get_service().open(this->get_implementation(), protocol, ec);
|
||||
+ if (!ec)
|
||||
+ async_connect_post_open(protocol, ec);
|
||||
if (ec)
|
||||
{
|
||||
async_completion<ConnectHandler,
|
||||
@@ -1742,6 +1744,11 @@ protected:
|
||||
}
|
||||
|
||||
private:
|
||||
+ // optional user code hook immediately after socket open in async_connect
|
||||
+ virtual void async_connect_post_open(const protocol_type& protocol, asio::error_code& ec)
|
||||
+ {
|
||||
+ }
|
||||
+
|
||||
// Disallow copying and assignment.
|
||||
basic_socket(const basic_socket&) ASIO_DELETED;
|
||||
basic_socket& operator=(const basic_socket&) ASIO_DELETED;
|
||||
--
|
||||
1.8.5.2 (Apple Git-48)
|
||||
|
||||
4
OpenVPN Adapter/Vendors/openvpn/deps/asio/snapshot-asio
Executable file
4
OpenVPN Adapter/Vendors/openvpn/deps/asio/snapshot-asio
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
export NAME=asio
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
$DIR/../../scripts/snapshot
|
||||
@@ -0,0 +1,87 @@
|
||||
--- boost/atomic/detail/cas128strong.hpp
|
||||
+++ boost/atomic/detail/cas128strong.hpp
|
||||
@@ -196,15 +196,17 @@ class base_atomic<T, void, 16, Sign>
|
||||
|
||||
public:
|
||||
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
|
||||
- explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
|
||||
+ explicit base_atomic(value_type const& v) BOOST_NOEXCEPT
|
||||
{
|
||||
+ memset(&v_, 0, sizeof(v_));
|
||||
memcpy(&v_, &v, sizeof(value_type));
|
||||
}
|
||||
|
||||
void
|
||||
store(value_type const& value, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
- storage_type value_s = 0;
|
||||
+ storage_type value_s;
|
||||
+ memset(&value_s, 0, sizeof(value_s));
|
||||
memcpy(&value_s, &value, sizeof(value_type));
|
||||
platform_fence_before_store(order);
|
||||
platform_store128(value_s, &v_);
|
||||
@@ -247,7 +249,9 @@ class base_atomic<T, void, 16, Sign>
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
- storage_type expected_s = 0, desired_s = 0;
|
||||
+ storage_type expected_s, desired_s;
|
||||
+ memset(&expected_s, 0, sizeof(expected_s));
|
||||
+ memset(&desired_s, 0, sizeof(desired_s));
|
||||
memcpy(&expected_s, &expected, sizeof(value_type));
|
||||
memcpy(&desired_s, &desired, sizeof(value_type));
|
||||
|
||||
--- boost/atomic/detail/gcc-atomic.hpp
|
||||
+++ boost/atomic/detail/gcc-atomic.hpp
|
||||
@@ -958,14 +958,16 @@ class base_atomic<T, void, 16, Sign>
|
||||
|
||||
public:
|
||||
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
|
||||
- explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
|
||||
+ explicit base_atomic(value_type const& v) BOOST_NOEXCEPT
|
||||
{
|
||||
+ memset(&v_, 0, sizeof(v_));
|
||||
memcpy(&v_, &v, sizeof(value_type));
|
||||
}
|
||||
|
||||
void store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
- storage_type tmp = 0;
|
||||
+ storage_type tmp;
|
||||
+ memset(&tmp, 0, sizeof(tmp));
|
||||
memcpy(&tmp, &v, sizeof(value_type));
|
||||
__atomic_store_n(&v_, tmp, atomics::detail::convert_memory_order_to_gcc(order));
|
||||
}
|
||||
@@ -980,7 +982,8 @@ class base_atomic<T, void, 16, Sign>
|
||||
|
||||
value_type exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
- storage_type tmp = 0;
|
||||
+ storage_type tmp;
|
||||
+ memset(&tmp, 0, sizeof(tmp));
|
||||
memcpy(&tmp, &v, sizeof(value_type));
|
||||
tmp = __atomic_exchange_n(&v_, tmp, atomics::detail::convert_memory_order_to_gcc(order));
|
||||
value_type res;
|
||||
@@ -994,7 +997,9 @@ class base_atomic<T, void, 16, Sign>
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
- storage_type expected_s = 0, desired_s = 0;
|
||||
+ storage_type expected_s, desired_s;
|
||||
+ memset(&expected_s, 0, sizeof(expected_s));
|
||||
+ memset(&desired_s, 0, sizeof(desired_s));
|
||||
memcpy(&expected_s, &expected, sizeof(value_type));
|
||||
memcpy(&desired_s, &desired, sizeof(value_type));
|
||||
const bool success = __atomic_compare_exchange_n(&v_, &expected_s, desired_s, false,
|
||||
@@ -1010,7 +1015,9 @@ class base_atomic<T, void, 16, Sign>
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
- storage_type expected_s = 0, desired_s = 0;
|
||||
+ storage_type expected_s, desired_s;
|
||||
+ memset(&expected_s, 0, sizeof(expected_s));
|
||||
+ memset(&desired_s, 0, sizeof(desired_s));
|
||||
memcpy(&expected_s, &expected, sizeof(value_type));
|
||||
memcpy(&desired_s, &desired, sizeof(value_type));
|
||||
const bool success = __atomic_compare_exchange_n(&v_, &expected_s, desired_s, true,
|
||||
--
|
||||
75
OpenVPN Adapter/Vendors/openvpn/deps/boost/build-boost
Executable file
75
OpenVPN Adapter/Vendors/openvpn/deps/boost/build-boost
Executable file
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Parameters:
|
||||
# SDK_PATH_SCRIPT -- optional script to set SDK path
|
||||
|
||||
set -e
|
||||
if [ -z "$O3" ]; then
|
||||
echo O3 var must point to ovpn3 tree
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$TARGETS" ]; then
|
||||
echo TARGETS var must be defined
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# NOTE: in Boost 1.55 and earlier, set BCONF=tools/build/v2
|
||||
BCONF=tools/build/src
|
||||
|
||||
. $O3/core/deps/lib-versions
|
||||
[ -z "$DL" ] && DL=~/Downloads
|
||||
[ -z "$GPP_CMD" ] && export GPP_CMD=g++
|
||||
[ -z "$GCC_CMD" ] && export GCC_CMD=gcc
|
||||
if [ "$NO_WIPE" != "1" ]; then
|
||||
echo WIPE and reunzip source
|
||||
rm -rf boost $BOOST_VERSION
|
||||
mkdir boost
|
||||
tar xfz $DL/$BOOST_VERSION.tar.gz
|
||||
cd $BOOST_VERSION
|
||||
#patch -p1 <$DL/asio-engine.patch
|
||||
#patch -p0 <$O3/core/deps/boost/atomic-1.55.0.patch
|
||||
patch -p1 <$O3/core/deps/boost/intrusive_ptr.patch
|
||||
patch -p1 <$O3/core/deps/boost/page_size.patch
|
||||
|
||||
./bootstrap.sh
|
||||
|
||||
for T in $TARGETS ; do
|
||||
TS="${T//-/}"
|
||||
. $O3/core/vars/vars-$T
|
||||
cat >>$BCONF/user-config.jam <<EOF
|
||||
using $GCC_CMD : $TS : $GPP_CMD
|
||||
:
|
||||
<compileflags>"-Wno-unused-function $PLATFORM_FLAGS $CXX_COMPILER_FLAGS $OTHER_COMPILER_FLAGS $LIB_FPIC $LIB_OPT_LEVEL"
|
||||
;
|
||||
EOF
|
||||
done
|
||||
echo '********** BOOST CONFIG'
|
||||
tail -30 $BCONF/user-config.jam
|
||||
echo '********** END BOOST CONFIG'
|
||||
else
|
||||
echo RETAIN existing source
|
||||
cd $BOOST_VERSION
|
||||
for T in $TARGETS ; do
|
||||
TS="${T//-/}"
|
||||
. $O3/core/vars/vars-$T
|
||||
done
|
||||
fi
|
||||
[ "$SDK_PATH_SCRIPT" ] && . $SDK_PATH_SCRIPT
|
||||
for T in $TARGETS ; do
|
||||
. $O3/core/vars/vars-$T
|
||||
target="${T//-/}"
|
||||
stage=stage-$T
|
||||
if [ "${target:(-3)}" == "dbg" ]; then
|
||||
variant=debug
|
||||
else
|
||||
variant=release
|
||||
fi
|
||||
[ -z "$LINK_MODE" ] && LINK_MODE=static
|
||||
echo "************************ $target $variant $stage"
|
||||
cmd="./bjam -d2 toolset=${GCC_CMD}-${target} --stagedir=$stage --with-system --with-thread --with-atomic variant=$variant link=$LINK_MODE threading=multi runtime-link=$LINK_MODE"
|
||||
echo $cmd
|
||||
$cmd
|
||||
done
|
||||
mv stage-* ../boost/
|
||||
cp -a boost ../boost/
|
||||
exit 0
|
||||
@@ -0,0 +1,29 @@
|
||||
diff -ur boost_1_56_0.orig/boost/smart_ptr/intrusive_ptr.hpp boost_1_56_0/boost/smart_ptr/intrusive_ptr.hpp
|
||||
--- boost_1_56_0.orig/boost/smart_ptr/intrusive_ptr.hpp 2014-07-26 00:44:34.000000000 -0600
|
||||
+++ boost_1_56_0/boost/smart_ptr/intrusive_ptr.hpp 2014-08-15 19:51:11.000000000 -0600
|
||||
@@ -63,7 +63,7 @@
|
||||
{
|
||||
}
|
||||
|
||||
- intrusive_ptr( T * p, bool add_ref = true ): px( p )
|
||||
+ intrusive_ptr( T * p, bool add_ref = true ) BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(intrusive_ptr_add_ref(static_cast<T*>(nullptr)))) : px( p )
|
||||
{
|
||||
if( px != 0 && add_ref ) intrusive_ptr_add_ref( px );
|
||||
}
|
||||
@@ -80,14 +80,14 @@
|
||||
intrusive_ptr( intrusive_ptr<U> const & rhs )
|
||||
|
||||
#endif
|
||||
- : px( rhs.get() )
|
||||
+ BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(intrusive_ptr_add_ref(static_cast<T*>(nullptr)))) : px( rhs.get() )
|
||||
{
|
||||
if( px != 0 ) intrusive_ptr_add_ref( px );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
- intrusive_ptr(intrusive_ptr const & rhs): px( rhs.px )
|
||||
+ intrusive_ptr(intrusive_ptr const & rhs) BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(intrusive_ptr_add_ref(static_cast<T*>(nullptr)))) : px( rhs.px )
|
||||
{
|
||||
if( px != 0 ) intrusive_ptr_add_ref( px );
|
||||
}
|
||||
16
OpenVPN Adapter/Vendors/openvpn/deps/boost/page_size.patch
Normal file
16
OpenVPN Adapter/Vendors/openvpn/deps/boost/page_size.patch
Normal file
@@ -0,0 +1,16 @@
|
||||
diff -ur boost_1_57_0/boost/thread/pthread/thread_data.hpp boost_1_57_0.new/boost/thread/pthread/thread_data.hpp
|
||||
--- boost_1_57_0/boost/thread/pthread/thread_data.hpp 2014-10-24 10:43:26.000000000 -0600
|
||||
+++ boost_1_57_0.new/boost/thread/pthread/thread_data.hpp 2015-02-26 00:43:26.000000000 -0700
|
||||
@@ -24,8 +24,10 @@
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
-#if defined(__ANDROID__)
|
||||
-#include <asm/page.h> // http://code.google.com/p/android/issues/detail?id=39983
|
||||
+// JY modified
|
||||
+#if defined(__ANDROID__) && !defined(PAGE_SIZE)
|
||||
+#define PAGE_SIZE 4096
|
||||
+//#include <asm/page.h> // http://code.google.com/p/android/issues/detail?id=39983
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
4
OpenVPN Adapter/Vendors/openvpn/deps/lib-versions
Normal file
4
OpenVPN Adapter/Vendors/openvpn/deps/lib-versions
Normal file
@@ -0,0 +1,4 @@
|
||||
export ASIO_VERSION=asio-20170301
|
||||
export LZ4_VERSION=lz4-1.7.5
|
||||
export MBEDTLS_VERSION=mbedtls-2.4.0
|
||||
export OPENSSL_VERSION=openssl-1.0.2h
|
||||
45
OpenVPN Adapter/Vendors/openvpn/deps/lz4/build-lz4
Executable file
45
OpenVPN Adapter/Vendors/openvpn/deps/lz4/build-lz4
Executable file
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
if [ -z "$O3" ]; then
|
||||
echo O3 var must point to ovpn3 tree
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$TARGET" ]; then
|
||||
echo TARGET var must be defined
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ -z "$DL" ] && DL=~/Downloads
|
||||
|
||||
# source vars
|
||||
. $O3/core/vars/vars-${TARGET}
|
||||
. $O3/core/deps/lib-versions
|
||||
|
||||
|
||||
CC=cc
|
||||
LD=ld
|
||||
AR=ar
|
||||
RANLIB=ranlib
|
||||
[ "$GCC_CMD" ] && CC=$GCC_CMD
|
||||
[ "$LD_CMD" ] && LD=$LD_CMD
|
||||
[ "$AR_CMD" ] && AR=$AR_CMD
|
||||
[ "$RANLIB_CMD" ] && RANLIB=$RANLIB_CMD
|
||||
|
||||
if [ "$NO_WIPE" != "1" ]; then
|
||||
rm -rf $LZ4_VERSION
|
||||
tar xfz $DL/$LZ4_VERSION.tar.gz
|
||||
fi
|
||||
|
||||
DIST=$(pwd)/lz4/lz4-$PLATFORM
|
||||
rm -rf $DIST
|
||||
mkdir -p $DIST/include
|
||||
mkdir $DIST/lib
|
||||
cd $LZ4_VERSION/lib
|
||||
CMD="$CC $PLATFORM_FLAGS $OTHER_COMPILER_FLAGS $LIB_OPT_LEVEL $LIB_FPIC -c lz4.c"
|
||||
echo $CMD
|
||||
$CMD
|
||||
$AR rc $DIST/lib/liblz4.a lz4.o
|
||||
$RANLIB $DIST/lib/liblz4.a
|
||||
cp lz4.h $DIST/include/
|
||||
exit 0
|
||||
4
OpenVPN Adapter/Vendors/openvpn/deps/lz4/snapshot-lz4
Executable file
4
OpenVPN Adapter/Vendors/openvpn/deps/lz4/snapshot-lz4
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
export NAME=lz4
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
$DIR/../../scripts/snapshot
|
||||
62
OpenVPN Adapter/Vendors/openvpn/deps/lzo/build-lzo
Executable file
62
OpenVPN Adapter/Vendors/openvpn/deps/lzo/build-lzo
Executable file
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
if [ -z "$O3" ]; then
|
||||
echo O3 var must point to ovpn3 tree
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$TARGET" ]; then
|
||||
echo TARGET var must be defined
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ -z "$DL" ] && DL=~/Downloads
|
||||
|
||||
# source vars
|
||||
. $O3/core/vars/vars-${TARGET}
|
||||
. $O3/core/deps/lib-versions
|
||||
|
||||
[ "$GCC_CMD" ] && export CC=$GCC_CMD
|
||||
[ "$LD_CMD" ] && export LD=$LD_CMD
|
||||
[ "$AR_CMD" ] && export AR=$AR_CMD
|
||||
[ "$RANLIB_CMD" ] && export RANLIB=$RANLIB_CMD
|
||||
|
||||
case $PLATFORM in
|
||||
android*)
|
||||
echo PLATFORM android
|
||||
host=arm
|
||||
target=arm
|
||||
;;
|
||||
ios*)
|
||||
echo PLATFORM ios
|
||||
host="x86_64-apple-darwin"
|
||||
target=arm
|
||||
;;
|
||||
*)
|
||||
host=""
|
||||
target=""
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ "$target" ]; then
|
||||
targ_opt="--target=$target"
|
||||
fi
|
||||
|
||||
if [ "$host" ]; then
|
||||
host_opt="--host=$host"
|
||||
fi
|
||||
|
||||
if [ "$NO_WIPE" != "1" ]; then
|
||||
rm -rf $LZO_VERSION
|
||||
tar xfz $DL/$LZO_VERSION.tar.gz
|
||||
fi
|
||||
|
||||
DIST=$(pwd)/lzo/lzo-$PLATFORM
|
||||
rm -rf $DIST
|
||||
mkdir -p $DIST
|
||||
cd $LZO_VERSION
|
||||
echo 'OPTIONS' $CC $LD $AR $RANLIB $host_opt $targ_opt
|
||||
CFLAGS="$PLATFORM_FLAGS $OTHER_COMPILER_FLAGS $LIB_OPT_LEVEL $LIB_FPIC" ./configure --prefix=$DIST $host_opt $targ_opt
|
||||
make
|
||||
make install
|
||||
exit 0
|
||||
65
OpenVPN Adapter/Vendors/openvpn/deps/mbedtls/build-mbedtls
Executable file
65
OpenVPN Adapter/Vendors/openvpn/deps/mbedtls/build-mbedtls
Executable file
@@ -0,0 +1,65 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
if [ -z "$O3" ]; then
|
||||
echo O3 var must point to ovpn3 tree
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$TARGET" ]; then
|
||||
echo TARGET var must be defined
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# source vars
|
||||
. $O3/core/vars/vars-${TARGET}
|
||||
. $O3/core/deps/lib-versions
|
||||
|
||||
# put build targets here
|
||||
DIST=$(pwd)/mbedtls/mbedtls-$PLATFORM
|
||||
rm -rf $DIST
|
||||
mkdir -p $DIST
|
||||
|
||||
if [ "$NO_WIPE" = "1" ]; then
|
||||
echo RETAIN existing source
|
||||
cd $MBEDTLS_VERSION
|
||||
else
|
||||
echo WIPE and reunzip source
|
||||
rm -rf $MBEDTLS_VERSION
|
||||
[ -z "$DL" ] && DL=~/Downloads
|
||||
tar xfz $DL/$MBEDTLS_VERSION-apache.tgz
|
||||
cd $MBEDTLS_VERSION
|
||||
|
||||
# enable MD4 (needed for NTLM auth)
|
||||
perl -pi -e 's/^\/\/// if /#define MBEDTLS_MD4_C/' include/mbedtls/config.h
|
||||
fi
|
||||
|
||||
# compiler vars
|
||||
CC=cc
|
||||
LD=ld
|
||||
AR=ar
|
||||
RANLIB=ranlib
|
||||
[ "$GCC_CMD" ] && CC=$GCC_CMD
|
||||
[ "$LD_CMD" ] && LD=$LD_CMD
|
||||
[ "$AR_CMD" ] && AR=$AR_CMD
|
||||
[ "$RANLIB_CMD" ] && RANLIB=$RANLIB_CMD
|
||||
|
||||
# build it
|
||||
SRC=$(pwd)
|
||||
cd library
|
||||
rm -f *.o
|
||||
for c in *.c ; do
|
||||
CMD="$CC -I../include $PLATFORM_FLAGS $OTHER_COMPILER_FLAGS $LIB_OPT_LEVEL $LIB_FPIC -c $c"
|
||||
echo $CMD
|
||||
$CMD
|
||||
done
|
||||
|
||||
# create archive
|
||||
cd $DIST
|
||||
mkdir library
|
||||
$AR rc library/libmbedtls.a $SRC/library/*.o
|
||||
$RANLIB library/libmbedtls.a 2>&1 | grep -v "has no symbols" || true
|
||||
|
||||
# copy headers
|
||||
mkdir -p include/mbedtls
|
||||
cp $SRC/include/mbedtls/*.h include/mbedtls/
|
||||
exit 0
|
||||
@@ -0,0 +1,32 @@
|
||||
--- aes-armv4.pl.orig 2012-09-03 00:16:20.000000000 -0600
|
||||
+++ aes-armv4.pl 2012-09-03 00:17:22.000000000 -0600
|
||||
@@ -171,7 +170,8 @@
|
||||
stmdb sp!,{r1,r4-r12,lr}
|
||||
mov $rounds,r0 @ inp
|
||||
mov $key,r2
|
||||
- sub $tbl,r3,#AES_encrypt-AES_Te @ Te
|
||||
+ad1=AES_encrypt-AES_Te
|
||||
+ sub $tbl,r3,#ad1 @ Te
|
||||
#if __ARM_ARCH__<7
|
||||
ldrb $s0,[$rounds,#3] @ load input data in endian-neutral
|
||||
ldrb $t1,[$rounds,#2] @ manner...
|
||||
@@ -426,7 +426,8 @@
|
||||
bne .Labrt
|
||||
|
||||
.Lok: stmdb sp!,{r4-r12,lr}
|
||||
- sub $tbl,r3,#_armv4_AES_set_encrypt_key-AES_Te-1024 @ Te4
|
||||
+ad2=_armv4_AES_set_encrypt_key-AES_Te-1024
|
||||
+ sub $tbl,r3,#ad2 @ Te4
|
||||
|
||||
mov $rounds,r0 @ inp
|
||||
mov lr,r1 @ bits
|
||||
@@ -887,7 +888,8 @@
|
||||
stmdb sp!,{r1,r4-r12,lr}
|
||||
mov $rounds,r0 @ inp
|
||||
mov $key,r2
|
||||
- sub $tbl,r3,#AES_decrypt-AES_Td @ Td
|
||||
+ad3=AES_decrypt-AES_Td
|
||||
+ sub $tbl,r3,#ad3 @ Td
|
||||
#if __ARM_ARCH__<7
|
||||
ldrb $s0,[$rounds,#3] @ load input data in endian-neutral
|
||||
ldrb $t1,[$rounds,#2] @ manner...
|
||||
759
OpenVPN Adapter/Vendors/openvpn/deps/minicrypto/arm-as-to-ios
Executable file
759
OpenVPN Adapter/Vendors/openvpn/deps/minicrypto/arm-as-to-ios
Executable file
@@ -0,0 +1,759 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# arm-as-to-ios Modify ARM assembly code for the iOS assembler
|
||||
#
|
||||
# Copyright (c) 2012 Psellos http://psellos.com/
|
||||
# Licensed under the MIT License:
|
||||
# http://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
# Resources for running OCaml on iOS: http://psellos.com/ocaml/
|
||||
#
|
||||
import sys
|
||||
import re
|
||||
|
||||
VERSION = '1.4.0'
|
||||
|
||||
initial_glosyms = []
|
||||
initial_defsyms = []
|
||||
|
||||
# Character classes for expression lexing.
|
||||
#
|
||||
g_ccid0 = '[$.A-Z_a-z\x80-\xff]' # Beginning of id
|
||||
g_ccid = '[$.0-9A-Z_a-z\x80-\xff]' # Later in id
|
||||
def ccc(cc): # Complement the class
|
||||
if cc[1] == '^':
|
||||
return cc[0] + cc[2:]
|
||||
return cc[0] + '^' + cc[1:]
|
||||
def ccce(cc): # Complement the class, include EOL
|
||||
return '(?:' + ccc(cc) + '|$)'
|
||||
|
||||
# Prefixes for pooled symbol labels and jump table base labels. They're
|
||||
# in the space of Linux assembler local symbols. Later rules will
|
||||
# modify them to the Loc() form.
|
||||
#
|
||||
g_poolpfx = '.LP'
|
||||
g_basepfx = '.LB'
|
||||
|
||||
|
||||
def exists(p, l):
|
||||
for l1 in l:
|
||||
if p(l1):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def forall(p, l):
|
||||
for l1 in l:
|
||||
if not p(l1):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def add_prefix(instrs):
|
||||
# Add compatibility macros for all systems, plus hardware
|
||||
# definitions and compatibility macros for iOS.
|
||||
#
|
||||
# All systems:
|
||||
#
|
||||
# Glo() cpp macro for making global symbols (xxx vs _xxx)
|
||||
# Loc() cpp macro for making local symbols (.Lxxx vs Lxxx)
|
||||
# .funtype Expands to .thumb_func for iOS armv7 (null for armv6)
|
||||
# Expands to .type %function for others
|
||||
#
|
||||
# iOS:
|
||||
#
|
||||
# .machine armv6/armv7
|
||||
# .thumb (for armv7)
|
||||
# cbz Expands to cmp/beq for armv6 (Thumb-only instr)
|
||||
# .type Not supported by Apple assembler
|
||||
# .size Not supported by Apple assembler
|
||||
#
|
||||
defre = '#[ \t]*if.*def.*SYS' # Add new defs near first existing ones
|
||||
skipre = '$|\.syntax[ \t]' # Skip comment lines (and .syntax)
|
||||
|
||||
for i in range(len(instrs)):
|
||||
if re.match(defre, instrs[i][1]):
|
||||
break
|
||||
else:
|
||||
i = 0
|
||||
for i in range(i, len(instrs)):
|
||||
if not re.match(skipre, instrs[i][1]):
|
||||
break
|
||||
instrs[i:0] = [
|
||||
('', '', '\n'),
|
||||
('/* Apple compatibility macros */', '', '\n'),
|
||||
('', '#if defined(SYS_macosx)', '\n'),
|
||||
('', '#define Glo(s) _##s', '\n'),
|
||||
('', '#define Loc(s) L##s', '\n'),
|
||||
('', '#if defined(MODEL_armv6)', '\n'),
|
||||
(' ', '.machine armv6', '\n'),
|
||||
(' ', '.macro .funtype', '\n'),
|
||||
(' ', '.endm', '\n'),
|
||||
(' ', '.macro cbz', '\n'),
|
||||
(' ', 'cmp $0, #0', '\n'),
|
||||
(' ', 'beq $1', '\n'),
|
||||
(' ', '.endm', '\n'),
|
||||
('', '#else', '\n'),
|
||||
(' ', '.machine armv7', '\n'),
|
||||
('', '#if !defined(NO_THUMB)', '\n'),
|
||||
(' ', '.thumb', '\n'),
|
||||
('', '#endif', '\n'),
|
||||
(' ', '.macro .funtype', '\n'),
|
||||
('', '#if !defined(NO_THUMB)', '\n'),
|
||||
(' ', '.thumb_func $0', '\n'),
|
||||
('', '#endif', '\n'),
|
||||
(' ', '.endm', '\n'),
|
||||
('', '#endif', '\n'),
|
||||
(' ', '.macro .type', '\n'),
|
||||
(' ', '.endm', '\n'),
|
||||
(' ', '.macro .size', '\n'),
|
||||
(' ', '.endm', '\n'),
|
||||
(' ', '.macro .skip', '\n'),
|
||||
(' ', '.space $0', '\n'),
|
||||
(' ', '.endm', '\n'),
|
||||
(' ', '.macro .fpu', '\n'),
|
||||
(' ', '.endm', '\n'),
|
||||
(' ', '.macro .global', '\n'),
|
||||
(' ', '.globl $0', '\n'),
|
||||
(' ', '.endm', '\n'),
|
||||
('', '#else', '\n'),
|
||||
('', '#define Glo(s) s', '\n'),
|
||||
('', '#define Loc(s) .L##s', '\n'),
|
||||
(' ', '.macro .funtype symbol', '\n'),
|
||||
(' ', '.type \\symbol, %function', '\n'),
|
||||
(' ', '.endm', '\n'),
|
||||
('', '#endif', '\n'),
|
||||
('/* End Apple compatibility macros */', '', '\n'),
|
||||
('', '', '\n')
|
||||
]
|
||||
return instrs
|
||||
|
||||
|
||||
# Regular expression for modified ldr lines
|
||||
#
|
||||
g_ldre = '(ldr[ \t][^,]*,[ \t]*)=(([^ \t\n@,/]|/(?!\*))*)(.*)'
|
||||
|
||||
|
||||
def explicit_address_loads(instrs):
|
||||
# Linux assemblers allow the following:
|
||||
#
|
||||
# ldr rM, =symbol
|
||||
#
|
||||
# which loads rM with [mov] (immediately) if possible, or creates an
|
||||
# entry in memory for the symbol value and loads it PC-relatively
|
||||
# with [ldr].
|
||||
#
|
||||
# The Apple assembler doesn't seem to support this notation. If the
|
||||
# value is a suitable constant, it emits a valid [mov]. Otherwise
|
||||
# it seems to emit an invalid [ldr] that always generates an error.
|
||||
# (At least I have not been able to make it work). So, change uses
|
||||
# of =symbol to explicit PC-relative loads.
|
||||
#
|
||||
# This requires a pool containing the addresses to be loaded. For
|
||||
# now, we just keep track of it ourselves and emit it into the text
|
||||
# segment at the end of the file.
|
||||
#
|
||||
syms = {}
|
||||
result = []
|
||||
|
||||
def repl1((syms, result), (a, b, c)):
|
||||
global g_poolpfx
|
||||
global g_ldre
|
||||
(b1, b2, b3) = parse_iparts(b)
|
||||
mo = re.match(g_ldre, b3, re.DOTALL)
|
||||
if mo:
|
||||
if mo.group(2) not in syms:
|
||||
syms[mo.group(2)] = len(syms)
|
||||
psym = mo.group(2)
|
||||
if psym[0:2] == '.L':
|
||||
psym = psym[2:]
|
||||
newb3 = mo.group(1) + g_poolpfx + psym + mo.group(4)
|
||||
result.append((a, b1 + b2 + newb3, c))
|
||||
else:
|
||||
result.append((a, b, c))
|
||||
return (syms, result)
|
||||
|
||||
def pool1(result, s):
|
||||
global g_poolpfx
|
||||
psym = s
|
||||
if psym[0:2] == '.L':
|
||||
psym = psym[2:]
|
||||
result.append(('', g_poolpfx + psym + ':', '\n'))
|
||||
result.append((' ', '.long ' + s, '\n'))
|
||||
return result
|
||||
|
||||
reduce(repl1, instrs, (syms, result))
|
||||
if len(syms) > 0:
|
||||
result.append(('', '', '\n'))
|
||||
result.append(('/* Pool of addresses loaded into registers */',
|
||||
'', '\n'))
|
||||
result.append(('', '', '\n'))
|
||||
result.append((' ', '.text', '\n'))
|
||||
result.append((' ', '.align 2', '\n'))
|
||||
reduce(pool1, sorted(syms, key=syms.get), result)
|
||||
return result
|
||||
|
||||
|
||||
def global_symbols(instrs):
|
||||
# The form of a global symbol differs between Linux assemblers and
|
||||
# the Apple assember:
|
||||
#
|
||||
# Linux: xxx
|
||||
# Apple: _xxx
|
||||
#
|
||||
# Change occurrences of global symbols to use the Glo() cpp macro
|
||||
# defined in our prefix.
|
||||
#
|
||||
# We consider a symbol to be global if:
|
||||
#
|
||||
# a. It appears in a .globl declaration; or
|
||||
# b. It is referenced, has global form, and is not defined
|
||||
#
|
||||
glosyms = set(initial_glosyms)
|
||||
refsyms = set()
|
||||
defsyms = set(initial_defsyms)
|
||||
result = []
|
||||
|
||||
def findglo1 (glosyms, (a, b, c)):
|
||||
if re.match('#', b):
|
||||
# Preprocessor line; nothing to do
|
||||
return glosyms
|
||||
(b1, b2, b3) = parse_iparts(b)
|
||||
mo = re.match('(\.globa?l)' + ccce(g_ccid), b3)
|
||||
if mo:
|
||||
tokens = parse_expr(b3[len(mo.group(1)):])
|
||||
if forall(lambda t: token_type(t) in ['space', 'id', ','], tokens):
|
||||
for t in tokens:
|
||||
if token_type(t) == 'id':
|
||||
glosyms.add(t)
|
||||
return glosyms
|
||||
|
||||
def findref1 ((refsyms, skipct), (a, b, c)):
|
||||
|
||||
def looksglobal(s):
|
||||
if re.match('(r|a|v|p|c|cr|f|s|d|q|mvax|wcgr)[0-9]+$', s, re.I):
|
||||
return False # numbered registers
|
||||
if re.match('(wr|sb|sl|fp|ip|sp|lr|pc)$', s, re.I):
|
||||
return False # named registers
|
||||
if re.match('(fpsid|fpscr|fpexc|mvfr1|mvfr0)$', s, re.I):
|
||||
return False # more named registers
|
||||
if re.match('(mvf|mvd|mvfx|mvdx|dspsc)$', s, re.I):
|
||||
return False # even more named registers
|
||||
if re.match('(wcid|wcon|wcssf|wcasf|acc)$', s, re.I):
|
||||
return False # even more named registers
|
||||
if re.match('\.$|\.L|[0-9]|#', s):
|
||||
return False # dot, local symbol, or number
|
||||
if re.match('(asl|lsl|lsr|asr|ror|rrx)$', s, re.I):
|
||||
return False # shift names
|
||||
return True
|
||||
|
||||
if re.match('#', b):
|
||||
# Preprocessor line; nothing to do
|
||||
return (refsyms, skipct)
|
||||
|
||||
# Track nesting of .macro/.endm. For now, we don't look for
|
||||
# global syms in macro defs. (Avoiding scoping probs etc.)
|
||||
#
|
||||
if skipct > 0 and re.match('\.(endm|endmacro)' + ccce(g_ccid), b):
|
||||
return (refsyms, skipct - 1)
|
||||
if re.match('\.macro' + ccce(g_ccid), b):
|
||||
return (refsyms, skipct + 1)
|
||||
if skipct > 0:
|
||||
return (refsyms, skipct)
|
||||
if re.match('\.(type|size|syntax|arch|fpu)' + ccce(g_ccid), b):
|
||||
return (refsyms, skipct)
|
||||
|
||||
(b1, b2, b3) = parse_iparts(b)
|
||||
rtokens = parse_rexpr(b3)
|
||||
if len(rtokens) > 1 and rtokens[1] == '.req':
|
||||
# .req has atypical syntax; no symbol refs there anyway
|
||||
return (refsyms, skipct)
|
||||
for t in rtokens[1:]:
|
||||
if token_type(t) == 'id' and looksglobal(t):
|
||||
refsyms.add(t)
|
||||
return (refsyms, skipct)
|
||||
|
||||
def finddef1(defsyms, (a, b, c)):
|
||||
if re.match('#', b):
|
||||
# Preprocessor line
|
||||
return defsyms
|
||||
(b1, b2, b3) = parse_iparts(b)
|
||||
rtokens = parse_rexpr(b3)
|
||||
if b1 != '':
|
||||
defsyms.add(b1)
|
||||
if len(rtokens) > 1 and rtokens[1] == '.req':
|
||||
defsyms.add(rtokens[0])
|
||||
return defsyms
|
||||
|
||||
def repl1((glosyms, result), (a, b, c)):
|
||||
if re.match('#', b):
|
||||
# Preprocessor line
|
||||
result.append((a, b, c))
|
||||
return (glosyms, result)
|
||||
toglo = lambda s: 'Glo(' + s + ')'
|
||||
(b1, b2, b3) = parse_iparts(b)
|
||||
tokens = parse_expr(b3)
|
||||
|
||||
if b1 in glosyms:
|
||||
b1 = toglo(b1)
|
||||
for i in range(len(tokens)):
|
||||
if token_type(tokens[i]) == 'id' and tokens[i] in glosyms:
|
||||
tokens[i] = toglo(tokens[i])
|
||||
result.append((a, b1 + b2 + ''.join(tokens), c))
|
||||
return (glosyms, result)
|
||||
|
||||
reduce(findglo1, instrs, glosyms)
|
||||
reduce(findref1, instrs, (refsyms, 0))
|
||||
reduce(finddef1, instrs, defsyms)
|
||||
glosyms |= (refsyms - defsyms)
|
||||
reduce(repl1, instrs, (glosyms, result))
|
||||
return result
|
||||
|
||||
|
||||
def local_symbols(instrs):
|
||||
# The form of a local symbol differs between Linux assemblers and
|
||||
# the Apple assember:
|
||||
#
|
||||
# Linux: .Lxxx
|
||||
# Apple: Lxxx
|
||||
#
|
||||
# Change occurrences of local symbols to use the Loc() cpp macro
|
||||
# defined in our prefix.
|
||||
#
|
||||
lsyms = set()
|
||||
result = []
|
||||
|
||||
def find1 (lsyms, (a, b, c)):
|
||||
mo = re.match('(\.L[^ \t:]*)[ \t]*:', b)
|
||||
if mo:
|
||||
lsyms.add(mo.group(1))
|
||||
return lsyms
|
||||
|
||||
def repl1((lsyms, result), (a, b, c)):
|
||||
matches = list(re.finditer('\.L[^ \t@:,+*/\-()]+', b))
|
||||
if matches != []:
|
||||
matches.reverse()
|
||||
newb = b
|
||||
for mo in matches:
|
||||
if mo.group() in lsyms:
|
||||
newb = newb[0:mo.start()] + \
|
||||
'Loc(' + mo.group()[2:] + ')' + \
|
||||
newb[mo.end():]
|
||||
result.append((a, newb, c))
|
||||
else:
|
||||
result.append((a, b, c))
|
||||
return (lsyms, result)
|
||||
|
||||
reduce(find1, instrs, lsyms)
|
||||
reduce(repl1, instrs, (lsyms, result))
|
||||
return result
|
||||
|
||||
|
||||
def funtypes(instrs):
|
||||
# Linux assemblers accept declarations like this:
|
||||
#
|
||||
# .type symbol, %function
|
||||
#
|
||||
# For Thumb functions, the Apple assembler wants to see:
|
||||
#
|
||||
# .thumb_func symbol
|
||||
#
|
||||
# Handle this by converting declarations to this:
|
||||
#
|
||||
# .funtype symbol
|
||||
#
|
||||
# Our prefix defines an appropriate .funtype macro for each
|
||||
# environment.
|
||||
#
|
||||
result = []
|
||||
|
||||
def repl1(result, (a, b, c)):
|
||||
mo = re.match('.type[ \t]+([^ \t,]*),[ \t]*%function', b)
|
||||
if mo:
|
||||
result.append((a, '.funtype ' + mo.group(1), c))
|
||||
else:
|
||||
result.append((a, b, c))
|
||||
return result
|
||||
|
||||
reduce(repl1, instrs, result)
|
||||
return result
|
||||
|
||||
|
||||
def jump_tables(instrs):
|
||||
# Jump tables for Linux assemblers often look like this:
|
||||
#
|
||||
# tbh [pc, rM, lsl #1]
|
||||
# .short (.Labc-.)/2+0
|
||||
# .short (.Ldef-.)/2+1
|
||||
# .short (.Lghi-.)/2+2
|
||||
#
|
||||
# The Apple assembler disagrees about the meaning of this code,
|
||||
# producing jump tables that don't work. Convert to the following:
|
||||
#
|
||||
# tbh [pc, rM, lsl #1]
|
||||
# .LBxxx:
|
||||
# .short (.Labc-.LBxxx)/2
|
||||
# .short (.Ldef-.LBxxx)/2
|
||||
# .short (.Lghi-.LBxxx)/2
|
||||
#
|
||||
# In fact we just convert sequences of .short pseudo-ops of the
|
||||
# right form. There's no requirement that they follow a tbh
|
||||
# instruction.
|
||||
#
|
||||
baselabs = []
|
||||
result = []
|
||||
|
||||
def short_match(seq, op):
|
||||
# Determine whether the op is a .short of the form that needs to
|
||||
# be converted: .short (symbol-.)/2+k. If so, return a pair
|
||||
# containing the symbol and the value of k. If not, return
|
||||
# None. The short can only be converted if there were at least
|
||||
# k other .shorts in sequence before the current one. A summary
|
||||
# of the previous .shorts is in seq.
|
||||
#
|
||||
# (A real parser would do a better job, but this was quick to
|
||||
# get working.)
|
||||
#
|
||||
sp = '([ \t]|/\*.*?\*/)*' # space
|
||||
sp1 = '([ \t]|/\*.*?\*/)+' # at least 1 space
|
||||
spe = '([ \t]|/\*.*?\*/|@[^\n]*)*$' # end-of-instr space
|
||||
expr_re0 = (
|
||||
'\.short' + sp + '\(' + sp + # .short (
|
||||
'([^ \t+\-*/@()]+)' + sp + # symbol
|
||||
'-' + sp + '\.' + sp + '\)' + sp + # -.)
|
||||
'/' + sp + '2' + spe # /2 END
|
||||
)
|
||||
expr_re1 = (
|
||||
'\.short' + sp + '\(' + sp + # .short (
|
||||
'([^ \t+\-*/@()]+)' + sp + # symbol
|
||||
'-' + sp + '\.' + sp + '\)' + sp + # -.)
|
||||
'/' + sp + '2' + sp + # /2
|
||||
'\+' + sp + # +
|
||||
'((0[xX])?[0-9]+)' + spe # k END
|
||||
)
|
||||
expr_re2 = (
|
||||
'\.short' + sp1 + # .short
|
||||
'((0[xX])?[0-9]+)' + sp + # k
|
||||
'\+' + sp + '\(' + sp + # +(
|
||||
'([^ \t+\-*/@()]+)' + sp + # symbol
|
||||
'-' + sp + '\.' + sp + '\)' + sp + # -.)
|
||||
'/' + sp + '2' + spe # /2 END
|
||||
)
|
||||
mo = re.match(expr_re0, op)
|
||||
if mo:
|
||||
return(mo.group(3), 0)
|
||||
mo = re.match(expr_re1, op)
|
||||
if mo:
|
||||
k = int(mo.group(11), 0)
|
||||
if k > len(seq):
|
||||
return None
|
||||
return (mo.group(3), k)
|
||||
mo = re.match(expr_re2, op)
|
||||
if mo:
|
||||
k = int(mo.group(2), 0)
|
||||
if k > len(seq):
|
||||
return None
|
||||
return (mo.group(7), k)
|
||||
return None
|
||||
|
||||
def conv1 ((baselabs, shortseq, label, result), (a, b, c)):
|
||||
# Convert current instr (a,b,c) if it's a .short of the right
|
||||
# form that spans a previous sequence of .shorts.
|
||||
#
|
||||
(b1, b2, b3) = parse_iparts(b)
|
||||
|
||||
if b3 == '':
|
||||
# No operation: just note label if present.
|
||||
result.append((a, b, c))
|
||||
if re.match('\.L.', b1):
|
||||
return (baselabs, shortseq, b1, result)
|
||||
return (baselabs, shortseq, label, result)
|
||||
|
||||
if not re.match('.short[ \t]+[^ \t@]', b3):
|
||||
# Not a .short: clear shortseq and label
|
||||
result.append((a, b, c))
|
||||
return (baselabs, [], '', result)
|
||||
|
||||
# We have a .short: figure out the label if any
|
||||
if re.match('\.L', b1):
|
||||
sl = b1
|
||||
else:
|
||||
sl = label
|
||||
|
||||
mpair = short_match(shortseq, b3)
|
||||
if not mpair:
|
||||
# A .short, but not of right form
|
||||
shortseq.append((len(result), sl))
|
||||
result.append((a, b, c))
|
||||
return (baselabs, shortseq, '', result)
|
||||
|
||||
# OK, we have a .short to convert!
|
||||
(sym, k) = mpair
|
||||
shortseq.append((len(result), sl))
|
||||
|
||||
# Figure out base label (create one if necessary).
|
||||
bx = len(shortseq) - 1 - k
|
||||
bl = shortseq[bx][1]
|
||||
if bl == '':
|
||||
bl = g_basepfx + str(shortseq[bx][0])
|
||||
shortseq[bx] = (shortseq[bx][0], bl)
|
||||
baselabs.append(shortseq[bx])
|
||||
|
||||
op = '.short\t(' + sym + '-' + bl + ')/2'
|
||||
|
||||
result.append ((a, b1 + b2 + op, c))
|
||||
return (baselabs, shortseq, '', result)
|
||||
|
||||
# Convert, accumulate result and new labels.
|
||||
reduce(conv1, instrs, (baselabs, [], '', result))
|
||||
|
||||
# Add labels created here to the instruction stream.
|
||||
baselabs.reverse()
|
||||
for (ix, lab) in baselabs:
|
||||
result[ix:0] = [('', lab + ':', '\n')]
|
||||
|
||||
# That does it
|
||||
return result
|
||||
|
||||
|
||||
def dot_relative(instrs):
|
||||
# The Apple assembler (or possibly the linker) has trouble with code
|
||||
# that looks like this:
|
||||
#
|
||||
# .word .Label - . + 0x80000000
|
||||
# .word 0x1966
|
||||
# .Label:
|
||||
# .word 0x1967
|
||||
#
|
||||
# One way to describe the problem is that the assembler marks the
|
||||
# first .word for relocation when in fact it's an assembly-time
|
||||
# constant. Translate to the following form, which doesn't generate
|
||||
# a relocation marking:
|
||||
#
|
||||
# DR0 = .Label - . + 0x80000000
|
||||
# .word DR0
|
||||
# .word 0x1966
|
||||
# .Label:
|
||||
# .word 0x1967
|
||||
#
|
||||
prefix = 'DR'
|
||||
pseudos = '(\.byte|\.short|\.word|\.long|\.quad)'
|
||||
result = []
|
||||
|
||||
def tok_ok(t):
|
||||
return t in ['.', '+', '-', '(', ')'] or \
|
||||
token_type(t) in ['space', 'locid', 'number']
|
||||
|
||||
def dotrel_match(expr):
|
||||
# Determine whether the expression is one that needs to be
|
||||
# translated.
|
||||
tokens = parse_expr(expr)
|
||||
return forall(tok_ok, tokens) and \
|
||||
exists(lambda t: token_type(t) == 'locid', tokens) and \
|
||||
exists(lambda t: token_type(t) == 'number', tokens) and \
|
||||
exists(lambda t: t == '-', tokens) and \
|
||||
exists(lambda t: t == '.', tokens)
|
||||
|
||||
def conv1(result, (a, b, c)):
|
||||
if re.match('#', b):
|
||||
# Preprocessor line
|
||||
result.append((a, b, c))
|
||||
else:
|
||||
(b1, b2, b3) = parse_iparts(b)
|
||||
mo = re.match(pseudos + ccce(g_ccid), b3)
|
||||
if mo:
|
||||
p = mo.group(1)
|
||||
expr = b3[len(p):]
|
||||
if dotrel_match(expr):
|
||||
sym = prefix + str(len(result))
|
||||
instr = sym + ' =' + expr
|
||||
result.append(('', instr, '\n'))
|
||||
result.append((a, b1 + b2 + p + ' ' + sym, c))
|
||||
else:
|
||||
result.append((a, b, c))
|
||||
else:
|
||||
result.append((a, b, c))
|
||||
return result
|
||||
|
||||
reduce(conv1, instrs, result)
|
||||
return result
|
||||
|
||||
|
||||
def read_input():
|
||||
# Concatenate all the input files into a string.
|
||||
#
|
||||
def fnl(s):
|
||||
if s == '' or s[-1] == '\n':
|
||||
return s
|
||||
else:
|
||||
return s + '\n'
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
return fnl(sys.stdin.read())
|
||||
else:
|
||||
input = ""
|
||||
for f in sys.argv[1:]:
|
||||
# allow global symbols to be enabled or disabled, eg:
|
||||
# --global=foo,!bar
|
||||
# foo is forced to be global
|
||||
# bar is forced to be non-global
|
||||
if f.startswith('--global='):
|
||||
glist = f[9:].split(',')
|
||||
for g in glist:
|
||||
if g.startswith('!'):
|
||||
initial_defsyms.append(g[1:])
|
||||
else:
|
||||
initial_glosyms.append(g)
|
||||
elif f.startswith('--stdin'):
|
||||
input = input + fnl(sys.stdin.read())
|
||||
else:
|
||||
try:
|
||||
fd = open(f)
|
||||
input = input + fnl(fd.read())
|
||||
fd.close()
|
||||
except:
|
||||
sys.stderr.write('arm-as-to-ios: cannot open ' + f + '\n')
|
||||
return input
|
||||
|
||||
|
||||
def parse_instrs(s):
|
||||
# Parse the string into assembly instructions, also noting C
|
||||
# preprocessor lines. Each instruction is represented as a triple:
|
||||
# (space/comments, instruction, end). The end is either ';' or
|
||||
# '\n'.
|
||||
#
|
||||
def goodmo(mo):
|
||||
if mo == None:
|
||||
# Should never happen
|
||||
sys.stderr.write('arm-as-to-ios: internal parsing error\n')
|
||||
sys.exit(1)
|
||||
|
||||
cpp_re = '([ \t]*)(#([^\n]*\\\\\n)*[^\n]*[^\\\\\n])\n'
|
||||
comment_re = '[ \t]*#[^\n]*'
|
||||
instr_re = (
|
||||
'(([ \t]|/\*.*?\*/|@[^\n]*)*)' # Spaces & comments
|
||||
'(([ \t]|/\*.*?\*/|[^;\n])*)' # "Instruction"
|
||||
'([;\n])' # End
|
||||
)
|
||||
instrs = []
|
||||
while s != '':
|
||||
if re.match('[ \t]*#[ \t]*(if|ifdef|elif|else|endif|define)', s):
|
||||
mo = re.match(cpp_re, s)
|
||||
goodmo(mo)
|
||||
instrs.append((mo.group(1), mo.group(2), '\n'))
|
||||
elif re.match('[ \t]*#', s):
|
||||
mo = re.match(comment_re, s)
|
||||
goodmo(mo)
|
||||
instrs.append((mo.group(0), '', '\n'))
|
||||
else:
|
||||
mo = re.match(instr_re, s, re.DOTALL)
|
||||
goodmo(mo)
|
||||
instrs.append((mo.group(1), mo.group(3), mo.group(5)))
|
||||
s = s[len(mo.group(0)):]
|
||||
return instrs
|
||||
|
||||
|
||||
def parse_iparts(i):
|
||||
# Parse an instruction into smaller parts, returning a triple of
|
||||
# strings (label, colon, operation). The colon part also contains
|
||||
# any surrounding spaces and comments (making the label and the
|
||||
# operation cleaner to process).
|
||||
#
|
||||
# (Caller warrants that the given string doesn't start with space or
|
||||
# a comment. This is true for strings returned by the instruction
|
||||
# parser.)
|
||||
#
|
||||
lab_re = (
|
||||
'([^ \t:/@]+)' # Label
|
||||
'(([ \t]|/\*.*?\*/|@[^\n]*)*)' # Spaces & comments
|
||||
':' # Colon
|
||||
'(([ \t]|/\*.*?\*/|@[^\n]*)*)' # Spaces & comments
|
||||
'([^\n]*)' # Operation
|
||||
)
|
||||
|
||||
if len(i) > 0 and i[0] == '#':
|
||||
# C preprocessor line; treat as operation.
|
||||
return ('', '', i)
|
||||
mo = re.match(lab_re, i)
|
||||
if mo:
|
||||
return (mo.group(1), mo.group(2) + ':' + mo.group(4), mo.group(6))
|
||||
# No label, just an operation
|
||||
return ('', '', i)
|
||||
|
||||
|
||||
def parse_expr(s):
|
||||
# Parse a string into a sequence of tokens. A segment of white
|
||||
# space (including comments) is treated as a token, so that the
|
||||
# tokens can be reassembled into the string again.
|
||||
#
|
||||
result = []
|
||||
while s != '':
|
||||
mo = re.match('([ \t]|/\*.*?\*/|@.*)+', s)
|
||||
if not mo:
|
||||
# Glo(...) and Loc(...) are single tokens
|
||||
mo = re.match('(Glo|Loc)\([^()]*\)', s)
|
||||
if not mo:
|
||||
mo = re.match('"([^\\\\"]|\\\\.)*"', s)
|
||||
if not mo:
|
||||
mo = re.match(g_ccid0 + g_ccid + '*', s)
|
||||
if not mo:
|
||||
mo = re.match('[0-9]+[bf]', s)
|
||||
if not mo:
|
||||
mo = re.match('0[Xx][0-9a-fA-F]+|[0-9]+', s)
|
||||
if not mo:
|
||||
mo = re.match('.', s)
|
||||
result.append(mo.group(0))
|
||||
s = s[len(mo.group(0)):]
|
||||
return result
|
||||
|
||||
|
||||
def parse_rexpr(s):
|
||||
# Like parse_expr(), but return only "real" tokens, not the
|
||||
# intervening space.
|
||||
#
|
||||
return filter(lambda t: token_type(t) != 'space', parse_expr(s))
|
||||
|
||||
|
||||
def token_type(t):
|
||||
# Determine the type of a token. Caller warrants that it was
|
||||
# returned by parse_expr() or parse_rexpr().
|
||||
#
|
||||
if re.match('[ \t]|/\*|@', t):
|
||||
return 'space'
|
||||
if re.match('Glo\(', t):
|
||||
return 'gloid'
|
||||
if re.match('Loc\(', t):
|
||||
return 'locid'
|
||||
if re.match('"', t):
|
||||
return 'string'
|
||||
if re.match(g_ccid0, t):
|
||||
return 'id'
|
||||
if re.match('[0-9]+[bf]', t):
|
||||
return 'label'
|
||||
if re.match('[0-9]', t):
|
||||
return 'number'
|
||||
return t # Sui generis
|
||||
|
||||
|
||||
def debug_parse(a, b, c):
|
||||
# Show results of instuction stream parse.
|
||||
#
|
||||
(b1, b2, b3) = parse_iparts(b)
|
||||
newb = '{' + b1 + '}' + '{' + b2 + '}' + '{' + b3 + '}'
|
||||
sys.stdout.write('{' + a + '}' + newb + c)
|
||||
|
||||
|
||||
def main():
|
||||
instrs = parse_instrs(read_input())
|
||||
instrs = explicit_address_loads(instrs)
|
||||
instrs = funtypes(instrs)
|
||||
instrs = jump_tables(instrs)
|
||||
instrs = global_symbols(instrs)
|
||||
instrs = local_symbols(instrs)
|
||||
instrs = dot_relative(instrs)
|
||||
instrs = add_prefix(instrs)
|
||||
for (a, b, c) in instrs:
|
||||
sys.stdout.write(a + b + c)
|
||||
|
||||
|
||||
main()
|
||||
730
OpenVPN Adapter/Vendors/openvpn/deps/minicrypto/arm-as-to-ios.orig
Executable file
730
OpenVPN Adapter/Vendors/openvpn/deps/minicrypto/arm-as-to-ios.orig
Executable file
@@ -0,0 +1,730 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# arm-as-to-ios Modify ARM assembly code for the iOS assembler
|
||||
#
|
||||
# Copyright (c) 2012 Psellos http://psellos.com/
|
||||
# Licensed under the MIT License:
|
||||
# http://www.opensource.org/licenses/mit-license.php
|
||||
#
|
||||
# Resources for running OCaml on iOS: http://psellos.com/ocaml/
|
||||
#
|
||||
import sys
|
||||
import re
|
||||
|
||||
VERSION = '1.4.0'
|
||||
|
||||
# Character classes for expression lexing.
|
||||
#
|
||||
g_ccid0 = '[$.A-Z_a-z\x80-\xff]' # Beginning of id
|
||||
g_ccid = '[$.0-9A-Z_a-z\x80-\xff]' # Later in id
|
||||
def ccc(cc): # Complement the class
|
||||
if cc[1] == '^':
|
||||
return cc[0] + cc[2:]
|
||||
return cc[0] + '^' + cc[1:]
|
||||
def ccce(cc): # Complement the class, include EOL
|
||||
return '(?:' + ccc(cc) + '|$)'
|
||||
|
||||
# Prefixes for pooled symbol labels and jump table base labels. They're
|
||||
# in the space of Linux assembler local symbols. Later rules will
|
||||
# modify them to the Loc() form.
|
||||
#
|
||||
g_poolpfx = '.LP'
|
||||
g_basepfx = '.LB'
|
||||
|
||||
|
||||
def exists(p, l):
|
||||
for l1 in l:
|
||||
if p(l1):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def forall(p, l):
|
||||
for l1 in l:
|
||||
if not p(l1):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def add_prefix(instrs):
|
||||
# Add compatibility macros for all systems, plus hardware
|
||||
# definitions and compatibility macros for iOS.
|
||||
#
|
||||
# All systems:
|
||||
#
|
||||
# Glo() cpp macro for making global symbols (xxx vs _xxx)
|
||||
# Loc() cpp macro for making local symbols (.Lxxx vs Lxxx)
|
||||
# .funtype Expands to .thumb_func for iOS armv7 (null for armv6)
|
||||
# Expands to .type %function for others
|
||||
#
|
||||
# iOS:
|
||||
#
|
||||
# .machine armv6/armv7
|
||||
# .thumb (for armv7)
|
||||
# cbz Expands to cmp/beq for armv6 (Thumb-only instr)
|
||||
# .type Not supported by Apple assembler
|
||||
# .size Not supported by Apple assembler
|
||||
#
|
||||
defre = '#[ \t]*if.*def.*SYS' # Add new defs near first existing ones
|
||||
skipre = '$|\.syntax[ \t]' # Skip comment lines (and .syntax)
|
||||
|
||||
for i in range(len(instrs)):
|
||||
if re.match(defre, instrs[i][1]):
|
||||
break
|
||||
else:
|
||||
i = 0
|
||||
for i in range(i, len(instrs)):
|
||||
if not re.match(skipre, instrs[i][1]):
|
||||
break
|
||||
instrs[i:0] = [
|
||||
('', '', '\n'),
|
||||
('/* Apple compatibility macros */', '', '\n'),
|
||||
('', '#if defined(SYS_macosx)', '\n'),
|
||||
('', '#define Glo(s) _##s', '\n'),
|
||||
('', '#define Loc(s) L##s', '\n'),
|
||||
('', '#if defined(MODEL_armv6)', '\n'),
|
||||
(' ', '.machine armv6', '\n'),
|
||||
(' ', '.macro .funtype', '\n'),
|
||||
(' ', '.endm', '\n'),
|
||||
(' ', '.macro cbz', '\n'),
|
||||
(' ', 'cmp $0, #0', '\n'),
|
||||
(' ', 'beq $1', '\n'),
|
||||
(' ', '.endm', '\n'),
|
||||
('', '#else', '\n'),
|
||||
(' ', '.machine armv7', '\n'),
|
||||
(' ', '.thumb', '\n'),
|
||||
(' ', '.macro .funtype', '\n'),
|
||||
(' ', '.thumb_func $0', '\n'),
|
||||
(' ', '.endm', '\n'),
|
||||
('', '#endif', '\n'),
|
||||
(' ', '.macro .type', '\n'),
|
||||
(' ', '.endm', '\n'),
|
||||
(' ', '.macro .size', '\n'),
|
||||
(' ', '.endm', '\n'),
|
||||
('', '#else', '\n'),
|
||||
('', '#define Glo(s) s', '\n'),
|
||||
('', '#define Loc(s) .L##s', '\n'),
|
||||
(' ', '.macro .funtype symbol', '\n'),
|
||||
(' ', '.type \\symbol, %function', '\n'),
|
||||
(' ', '.endm', '\n'),
|
||||
('', '#endif', '\n'),
|
||||
('/* End Apple compatibility macros */', '', '\n'),
|
||||
('', '', '\n')
|
||||
]
|
||||
return instrs
|
||||
|
||||
|
||||
# Regular expression for modified ldr lines
|
||||
#
|
||||
g_ldre = '(ldr[ \t][^,]*,[ \t]*)=(([^ \t\n@,/]|/(?!\*))*)(.*)'
|
||||
|
||||
|
||||
def explicit_address_loads(instrs):
|
||||
# Linux assemblers allow the following:
|
||||
#
|
||||
# ldr rM, =symbol
|
||||
#
|
||||
# which loads rM with [mov] (immediately) if possible, or creates an
|
||||
# entry in memory for the symbol value and loads it PC-relatively
|
||||
# with [ldr].
|
||||
#
|
||||
# The Apple assembler doesn't seem to support this notation. If the
|
||||
# value is a suitable constant, it emits a valid [mov]. Otherwise
|
||||
# it seems to emit an invalid [ldr] that always generates an error.
|
||||
# (At least I have not been able to make it work). So, change uses
|
||||
# of =symbol to explicit PC-relative loads.
|
||||
#
|
||||
# This requires a pool containing the addresses to be loaded. For
|
||||
# now, we just keep track of it ourselves and emit it into the text
|
||||
# segment at the end of the file.
|
||||
#
|
||||
syms = {}
|
||||
result = []
|
||||
|
||||
def repl1((syms, result), (a, b, c)):
|
||||
global g_poolpfx
|
||||
global g_ldre
|
||||
(b1, b2, b3) = parse_iparts(b)
|
||||
mo = re.match(g_ldre, b3, re.DOTALL)
|
||||
if mo:
|
||||
if mo.group(2) not in syms:
|
||||
syms[mo.group(2)] = len(syms)
|
||||
psym = mo.group(2)
|
||||
if psym[0:2] == '.L':
|
||||
psym = psym[2:]
|
||||
newb3 = mo.group(1) + g_poolpfx + psym + mo.group(4)
|
||||
result.append((a, b1 + b2 + newb3, c))
|
||||
else:
|
||||
result.append((a, b, c))
|
||||
return (syms, result)
|
||||
|
||||
def pool1(result, s):
|
||||
global g_poolpfx
|
||||
psym = s
|
||||
if psym[0:2] == '.L':
|
||||
psym = psym[2:]
|
||||
result.append(('', g_poolpfx + psym + ':', '\n'))
|
||||
result.append((' ', '.long ' + s, '\n'))
|
||||
return result
|
||||
|
||||
reduce(repl1, instrs, (syms, result))
|
||||
if len(syms) > 0:
|
||||
result.append(('', '', '\n'))
|
||||
result.append(('/* Pool of addresses loaded into registers */',
|
||||
'', '\n'))
|
||||
result.append(('', '', '\n'))
|
||||
result.append((' ', '.text', '\n'))
|
||||
result.append((' ', '.align 2', '\n'))
|
||||
reduce(pool1, sorted(syms, key=syms.get), result)
|
||||
return result
|
||||
|
||||
|
||||
def global_symbols(instrs):
|
||||
# The form of a global symbol differs between Linux assemblers and
|
||||
# the Apple assember:
|
||||
#
|
||||
# Linux: xxx
|
||||
# Apple: _xxx
|
||||
#
|
||||
# Change occurrences of global symbols to use the Glo() cpp macro
|
||||
# defined in our prefix.
|
||||
#
|
||||
# We consider a symbol to be global if:
|
||||
#
|
||||
# a. It appears in a .globl declaration; or
|
||||
# b. It is referenced, has global form, and is not defined
|
||||
#
|
||||
glosyms = set()
|
||||
refsyms = set()
|
||||
defsyms = set()
|
||||
result = []
|
||||
|
||||
def findglo1 (glosyms, (a, b, c)):
|
||||
if re.match('#', b):
|
||||
# Preprocessor line; nothing to do
|
||||
return glosyms
|
||||
(b1, b2, b3) = parse_iparts(b)
|
||||
mo = re.match('(\.globl)' + ccce(g_ccid), b3)
|
||||
if mo:
|
||||
tokens = parse_expr(b3[len(mo.group(1)):])
|
||||
if forall(lambda t: token_type(t) in ['space', 'id', ','], tokens):
|
||||
for t in tokens:
|
||||
if token_type(t) == 'id':
|
||||
glosyms.add(t)
|
||||
return glosyms
|
||||
|
||||
def findref1 ((refsyms, skipct), (a, b, c)):
|
||||
|
||||
def looksglobal(s):
|
||||
if re.match('(r|a|v|p|c|cr|f|s|d|q|mvax|wcgr)[0-9]+$', s, re.I):
|
||||
return False # numbered registers
|
||||
if re.match('(wr|sb|sl|fp|ip|sp|lr|pc)$', s, re.I):
|
||||
return False # named registers
|
||||
if re.match('(fpsid|fpscr|fpexc|mvfr1|mvfr0)$', s, re.I):
|
||||
return False # more named registers
|
||||
if re.match('(mvf|mvd|mvfx|mvdx|dspsc)$', s, re.I):
|
||||
return False # even more named registers
|
||||
if re.match('(wcid|wcon|wcssf|wcasf|acc)$', s, re.I):
|
||||
return False # even more named registers
|
||||
if re.match('\.$|\.L|[0-9]|#', s):
|
||||
return False # dot, local symbol, or number
|
||||
if re.match('(asl|lsl|lsr|asr|ror|rrx)$', s, re.I):
|
||||
return False # shift names
|
||||
return True
|
||||
|
||||
if re.match('#', b):
|
||||
# Preprocessor line; nothing to do
|
||||
return (refsyms, skipct)
|
||||
|
||||
# Track nesting of .macro/.endm. For now, we don't look for
|
||||
# global syms in macro defs. (Avoiding scoping probs etc.)
|
||||
#
|
||||
if skipct > 0 and re.match('\.(endm|endmacro)' + ccce(g_ccid), b):
|
||||
return (refsyms, skipct - 1)
|
||||
if re.match('\.macro' + ccce(g_ccid), b):
|
||||
return (refsyms, skipct + 1)
|
||||
if skipct > 0:
|
||||
return (refsyms, skipct)
|
||||
if re.match('\.(type|size|syntax|arch|fpu)' + ccce(g_ccid), b):
|
||||
return (refsyms, skipct)
|
||||
|
||||
(b1, b2, b3) = parse_iparts(b)
|
||||
rtokens = parse_rexpr(b3)
|
||||
if len(rtokens) > 1 and rtokens[1] == '.req':
|
||||
# .req has atypical syntax; no symbol refs there anyway
|
||||
return (refsyms, skipct)
|
||||
for t in rtokens[1:]:
|
||||
if token_type(t) == 'id' and looksglobal(t):
|
||||
refsyms.add(t)
|
||||
return (refsyms, skipct)
|
||||
|
||||
def finddef1(defsyms, (a, b, c)):
|
||||
if re.match('#', b):
|
||||
# Preprocessor line
|
||||
return defsyms
|
||||
(b1, b2, b3) = parse_iparts(b)
|
||||
rtokens = parse_rexpr(b3)
|
||||
if b1 != '':
|
||||
defsyms.add(b1)
|
||||
if len(rtokens) > 1 and rtokens[1] == '.req':
|
||||
defsyms.add(rtokens[0])
|
||||
return defsyms
|
||||
|
||||
def repl1((glosyms, result), (a, b, c)):
|
||||
if re.match('#', b):
|
||||
# Preprocessor line
|
||||
result.append((a, b, c))
|
||||
return (glosyms, result)
|
||||
toglo = lambda s: 'Glo(' + s + ')'
|
||||
(b1, b2, b3) = parse_iparts(b)
|
||||
tokens = parse_expr(b3)
|
||||
|
||||
if b1 in glosyms:
|
||||
b1 = toglo(b1)
|
||||
for i in range(len(tokens)):
|
||||
if token_type(tokens[i]) == 'id' and tokens[i] in glosyms:
|
||||
tokens[i] = toglo(tokens[i])
|
||||
result.append((a, b1 + b2 + ''.join(tokens), c))
|
||||
return (glosyms, result)
|
||||
|
||||
reduce(findglo1, instrs, glosyms)
|
||||
reduce(findref1, instrs, (refsyms, 0))
|
||||
reduce(finddef1, instrs, defsyms)
|
||||
glosyms |= (refsyms - defsyms)
|
||||
reduce(repl1, instrs, (glosyms, result))
|
||||
return result
|
||||
|
||||
|
||||
def local_symbols(instrs):
|
||||
# The form of a local symbol differs between Linux assemblers and
|
||||
# the Apple assember:
|
||||
#
|
||||
# Linux: .Lxxx
|
||||
# Apple: Lxxx
|
||||
#
|
||||
# Change occurrences of local symbols to use the Loc() cpp macro
|
||||
# defined in our prefix.
|
||||
#
|
||||
lsyms = set()
|
||||
result = []
|
||||
|
||||
def find1 (lsyms, (a, b, c)):
|
||||
mo = re.match('(\.L[^ \t:]*)[ \t]*:', b)
|
||||
if mo:
|
||||
lsyms.add(mo.group(1))
|
||||
return lsyms
|
||||
|
||||
def repl1((lsyms, result), (a, b, c)):
|
||||
matches = list(re.finditer('\.L[^ \t@:,+*/\-()]+', b))
|
||||
if matches != []:
|
||||
matches.reverse()
|
||||
newb = b
|
||||
for mo in matches:
|
||||
if mo.group() in lsyms:
|
||||
newb = newb[0:mo.start()] + \
|
||||
'Loc(' + mo.group()[2:] + ')' + \
|
||||
newb[mo.end():]
|
||||
result.append((a, newb, c))
|
||||
else:
|
||||
result.append((a, b, c))
|
||||
return (lsyms, result)
|
||||
|
||||
reduce(find1, instrs, lsyms)
|
||||
reduce(repl1, instrs, (lsyms, result))
|
||||
return result
|
||||
|
||||
|
||||
def funtypes(instrs):
|
||||
# Linux assemblers accept declarations like this:
|
||||
#
|
||||
# .type symbol, %function
|
||||
#
|
||||
# For Thumb functions, the Apple assembler wants to see:
|
||||
#
|
||||
# .thumb_func symbol
|
||||
#
|
||||
# Handle this by converting declarations to this:
|
||||
#
|
||||
# .funtype symbol
|
||||
#
|
||||
# Our prefix defines an appropriate .funtype macro for each
|
||||
# environment.
|
||||
#
|
||||
result = []
|
||||
|
||||
def repl1(result, (a, b, c)):
|
||||
mo = re.match('.type[ \t]+([^ \t,]*),[ \t]*%function', b)
|
||||
if mo:
|
||||
result.append((a, '.funtype ' + mo.group(1), c))
|
||||
else:
|
||||
result.append((a, b, c))
|
||||
return result
|
||||
|
||||
reduce(repl1, instrs, result)
|
||||
return result
|
||||
|
||||
|
||||
def jump_tables(instrs):
|
||||
# Jump tables for Linux assemblers often look like this:
|
||||
#
|
||||
# tbh [pc, rM, lsl #1]
|
||||
# .short (.Labc-.)/2+0
|
||||
# .short (.Ldef-.)/2+1
|
||||
# .short (.Lghi-.)/2+2
|
||||
#
|
||||
# The Apple assembler disagrees about the meaning of this code,
|
||||
# producing jump tables that don't work. Convert to the following:
|
||||
#
|
||||
# tbh [pc, rM, lsl #1]
|
||||
# .LBxxx:
|
||||
# .short (.Labc-.LBxxx)/2
|
||||
# .short (.Ldef-.LBxxx)/2
|
||||
# .short (.Lghi-.LBxxx)/2
|
||||
#
|
||||
# In fact we just convert sequences of .short pseudo-ops of the
|
||||
# right form. There's no requirement that they follow a tbh
|
||||
# instruction.
|
||||
#
|
||||
baselabs = []
|
||||
result = []
|
||||
|
||||
def short_match(seq, op):
|
||||
# Determine whether the op is a .short of the form that needs to
|
||||
# be converted: .short (symbol-.)/2+k. If so, return a pair
|
||||
# containing the symbol and the value of k. If not, return
|
||||
# None. The short can only be converted if there were at least
|
||||
# k other .shorts in sequence before the current one. A summary
|
||||
# of the previous .shorts is in seq.
|
||||
#
|
||||
# (A real parser would do a better job, but this was quick to
|
||||
# get working.)
|
||||
#
|
||||
sp = '([ \t]|/\*.*?\*/)*' # space
|
||||
sp1 = '([ \t]|/\*.*?\*/)+' # at least 1 space
|
||||
spe = '([ \t]|/\*.*?\*/|@[^\n]*)*$' # end-of-instr space
|
||||
expr_re0 = (
|
||||
'\.short' + sp + '\(' + sp + # .short (
|
||||
'([^ \t+\-*/@()]+)' + sp + # symbol
|
||||
'-' + sp + '\.' + sp + '\)' + sp + # -.)
|
||||
'/' + sp + '2' + spe # /2 END
|
||||
)
|
||||
expr_re1 = (
|
||||
'\.short' + sp + '\(' + sp + # .short (
|
||||
'([^ \t+\-*/@()]+)' + sp + # symbol
|
||||
'-' + sp + '\.' + sp + '\)' + sp + # -.)
|
||||
'/' + sp + '2' + sp + # /2
|
||||
'\+' + sp + # +
|
||||
'((0[xX])?[0-9]+)' + spe # k END
|
||||
)
|
||||
expr_re2 = (
|
||||
'\.short' + sp1 + # .short
|
||||
'((0[xX])?[0-9]+)' + sp + # k
|
||||
'\+' + sp + '\(' + sp + # +(
|
||||
'([^ \t+\-*/@()]+)' + sp + # symbol
|
||||
'-' + sp + '\.' + sp + '\)' + sp + # -.)
|
||||
'/' + sp + '2' + spe # /2 END
|
||||
)
|
||||
mo = re.match(expr_re0, op)
|
||||
if mo:
|
||||
return(mo.group(3), 0)
|
||||
mo = re.match(expr_re1, op)
|
||||
if mo:
|
||||
k = int(mo.group(11), 0)
|
||||
if k > len(seq):
|
||||
return None
|
||||
return (mo.group(3), k)
|
||||
mo = re.match(expr_re2, op)
|
||||
if mo:
|
||||
k = int(mo.group(2), 0)
|
||||
if k > len(seq):
|
||||
return None
|
||||
return (mo.group(7), k)
|
||||
return None
|
||||
|
||||
def conv1 ((baselabs, shortseq, label, result), (a, b, c)):
|
||||
# Convert current instr (a,b,c) if it's a .short of the right
|
||||
# form that spans a previous sequence of .shorts.
|
||||
#
|
||||
(b1, b2, b3) = parse_iparts(b)
|
||||
|
||||
if b3 == '':
|
||||
# No operation: just note label if present.
|
||||
result.append((a, b, c))
|
||||
if re.match('\.L.', b1):
|
||||
return (baselabs, shortseq, b1, result)
|
||||
return (baselabs, shortseq, label, result)
|
||||
|
||||
if not re.match('.short[ \t]+[^ \t@]', b3):
|
||||
# Not a .short: clear shortseq and label
|
||||
result.append((a, b, c))
|
||||
return (baselabs, [], '', result)
|
||||
|
||||
# We have a .short: figure out the label if any
|
||||
if re.match('\.L', b1):
|
||||
sl = b1
|
||||
else:
|
||||
sl = label
|
||||
|
||||
mpair = short_match(shortseq, b3)
|
||||
if not mpair:
|
||||
# A .short, but not of right form
|
||||
shortseq.append((len(result), sl))
|
||||
result.append((a, b, c))
|
||||
return (baselabs, shortseq, '', result)
|
||||
|
||||
# OK, we have a .short to convert!
|
||||
(sym, k) = mpair
|
||||
shortseq.append((len(result), sl))
|
||||
|
||||
# Figure out base label (create one if necessary).
|
||||
bx = len(shortseq) - 1 - k
|
||||
bl = shortseq[bx][1]
|
||||
if bl == '':
|
||||
bl = g_basepfx + str(shortseq[bx][0])
|
||||
shortseq[bx] = (shortseq[bx][0], bl)
|
||||
baselabs.append(shortseq[bx])
|
||||
|
||||
op = '.short\t(' + sym + '-' + bl + ')/2'
|
||||
|
||||
result.append ((a, b1 + b2 + op, c))
|
||||
return (baselabs, shortseq, '', result)
|
||||
|
||||
# Convert, accumulate result and new labels.
|
||||
reduce(conv1, instrs, (baselabs, [], '', result))
|
||||
|
||||
# Add labels created here to the instruction stream.
|
||||
baselabs.reverse()
|
||||
for (ix, lab) in baselabs:
|
||||
result[ix:0] = [('', lab + ':', '\n')]
|
||||
|
||||
# That does it
|
||||
return result
|
||||
|
||||
|
||||
def dot_relative(instrs):
|
||||
# The Apple assembler (or possibly the linker) has trouble with code
|
||||
# that looks like this:
|
||||
#
|
||||
# .word .Label - . + 0x80000000
|
||||
# .word 0x1966
|
||||
# .Label:
|
||||
# .word 0x1967
|
||||
#
|
||||
# One way to describe the problem is that the assembler marks the
|
||||
# first .word for relocation when in fact it's an assembly-time
|
||||
# constant. Translate to the following form, which doesn't generate
|
||||
# a relocation marking:
|
||||
#
|
||||
# DR0 = .Label - . + 0x80000000
|
||||
# .word DR0
|
||||
# .word 0x1966
|
||||
# .Label:
|
||||
# .word 0x1967
|
||||
#
|
||||
prefix = 'DR'
|
||||
pseudos = '(\.byte|\.short|\.word|\.long|\.quad)'
|
||||
result = []
|
||||
|
||||
def tok_ok(t):
|
||||
return t in ['.', '+', '-', '(', ')'] or \
|
||||
token_type(t) in ['space', 'locid', 'number']
|
||||
|
||||
def dotrel_match(expr):
|
||||
# Determine whether the expression is one that needs to be
|
||||
# translated.
|
||||
tokens = parse_expr(expr)
|
||||
return forall(tok_ok, tokens) and \
|
||||
exists(lambda t: token_type(t) == 'locid', tokens) and \
|
||||
exists(lambda t: token_type(t) == 'number', tokens) and \
|
||||
exists(lambda t: t == '-', tokens) and \
|
||||
exists(lambda t: t == '.', tokens)
|
||||
|
||||
def conv1(result, (a, b, c)):
|
||||
if re.match('#', b):
|
||||
# Preprocessor line
|
||||
result.append((a, b, c))
|
||||
else:
|
||||
(b1, b2, b3) = parse_iparts(b)
|
||||
mo = re.match(pseudos + ccce(g_ccid), b3)
|
||||
if mo:
|
||||
p = mo.group(1)
|
||||
expr = b3[len(p):]
|
||||
if dotrel_match(expr):
|
||||
sym = prefix + str(len(result))
|
||||
instr = sym + ' =' + expr
|
||||
result.append(('', instr, '\n'))
|
||||
result.append((a, b1 + b2 + p + ' ' + sym, c))
|
||||
else:
|
||||
result.append((a, b, c))
|
||||
else:
|
||||
result.append((a, b, c))
|
||||
return result
|
||||
|
||||
reduce(conv1, instrs, result)
|
||||
return result
|
||||
|
||||
|
||||
def read_input():
|
||||
# Concatenate all the input files into a string.
|
||||
#
|
||||
def fnl(s):
|
||||
if s == '' or s[-1] == '\n':
|
||||
return s
|
||||
else:
|
||||
return s + '\n'
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
return fnl(sys.stdin.read())
|
||||
else:
|
||||
input = ""
|
||||
for f in sys.argv[1:]:
|
||||
try:
|
||||
fd = open(f)
|
||||
input = input + fnl(fd.read())
|
||||
fd.close()
|
||||
except:
|
||||
sys.stderr.write('arm-as-to-ios: cannot open ' + f + '\n')
|
||||
return input
|
||||
|
||||
|
||||
def parse_instrs(s):
|
||||
# Parse the string into assembly instructions, also noting C
|
||||
# preprocessor lines. Each instruction is represented as a triple:
|
||||
# (space/comments, instruction, end). The end is either ';' or
|
||||
# '\n'.
|
||||
#
|
||||
def goodmo(mo):
|
||||
if mo == None:
|
||||
# Should never happen
|
||||
sys.stderr.write('arm-as-to-ios: internal parsing error\n')
|
||||
sys.exit(1)
|
||||
|
||||
cpp_re = '([ \t]*)(#([^\n]*\\\\\n)*[^\n]*[^\\\\\n])\n'
|
||||
comment_re = '[ \t]*#[^\n]*'
|
||||
instr_re = (
|
||||
'(([ \t]|/\*.*?\*/|@[^\n]*)*)' # Spaces & comments
|
||||
'(([ \t]|/\*.*?\*/|[^;\n])*)' # "Instruction"
|
||||
'([;\n])' # End
|
||||
)
|
||||
instrs = []
|
||||
while s != '':
|
||||
if re.match('[ \t]*#[ \t]*(if|ifdef|elif|else|endif|define)', s):
|
||||
mo = re.match(cpp_re, s)
|
||||
goodmo(mo)
|
||||
instrs.append((mo.group(1), mo.group(2), '\n'))
|
||||
elif re.match('[ \t]*#', s):
|
||||
mo = re.match(comment_re, s)
|
||||
goodmo(mo)
|
||||
instrs.append((mo.group(0), '', '\n'))
|
||||
else:
|
||||
mo = re.match(instr_re, s, re.DOTALL)
|
||||
goodmo(mo)
|
||||
instrs.append((mo.group(1), mo.group(3), mo.group(5)))
|
||||
s = s[len(mo.group(0)):]
|
||||
return instrs
|
||||
|
||||
|
||||
def parse_iparts(i):
|
||||
# Parse an instruction into smaller parts, returning a triple of
|
||||
# strings (label, colon, operation). The colon part also contains
|
||||
# any surrounding spaces and comments (making the label and the
|
||||
# operation cleaner to process).
|
||||
#
|
||||
# (Caller warrants that the given string doesn't start with space or
|
||||
# a comment. This is true for strings returned by the instruction
|
||||
# parser.)
|
||||
#
|
||||
lab_re = (
|
||||
'([^ \t:/@]+)' # Label
|
||||
'(([ \t]|/\*.*?\*/|@[^\n]*)*)' # Spaces & comments
|
||||
':' # Colon
|
||||
'(([ \t]|/\*.*?\*/|@[^\n]*)*)' # Spaces & comments
|
||||
'([^\n]*)' # Operation
|
||||
)
|
||||
|
||||
if len(i) > 0 and i[0] == '#':
|
||||
# C preprocessor line; treat as operation.
|
||||
return ('', '', i)
|
||||
mo = re.match(lab_re, i)
|
||||
if mo:
|
||||
return (mo.group(1), mo.group(2) + ':' + mo.group(4), mo.group(6))
|
||||
# No label, just an operation
|
||||
return ('', '', i)
|
||||
|
||||
|
||||
def parse_expr(s):
|
||||
# Parse a string into a sequence of tokens. A segment of white
|
||||
# space (including comments) is treated as a token, so that the
|
||||
# tokens can be reassembled into the string again.
|
||||
#
|
||||
result = []
|
||||
while s != '':
|
||||
mo = re.match('([ \t]|/\*.*?\*/|@.*)+', s)
|
||||
if not mo:
|
||||
# Glo(...) and Loc(...) are single tokens
|
||||
mo = re.match('(Glo|Loc)\([^()]*\)', s)
|
||||
if not mo:
|
||||
mo = re.match('"([^\\\\"]|\\\\.)*"', s)
|
||||
if not mo:
|
||||
mo = re.match(g_ccid0 + g_ccid + '*', s)
|
||||
if not mo:
|
||||
mo = re.match('[0-9]+[bf]', s)
|
||||
if not mo:
|
||||
mo = re.match('0[Xx][0-9a-fA-F]+|[0-9]+', s)
|
||||
if not mo:
|
||||
mo = re.match('.', s)
|
||||
result.append(mo.group(0))
|
||||
s = s[len(mo.group(0)):]
|
||||
return result
|
||||
|
||||
|
||||
def parse_rexpr(s):
|
||||
# Like parse_expr(), but return only "real" tokens, not the
|
||||
# intervening space.
|
||||
#
|
||||
return filter(lambda t: token_type(t) != 'space', parse_expr(s))
|
||||
|
||||
|
||||
def token_type(t):
|
||||
# Determine the type of a token. Caller warrants that it was
|
||||
# returned by parse_expr() or parse_rexpr().
|
||||
#
|
||||
if re.match('[ \t]|/\*|@', t):
|
||||
return 'space'
|
||||
if re.match('Glo\(', t):
|
||||
return 'gloid'
|
||||
if re.match('Loc\(', t):
|
||||
return 'locid'
|
||||
if re.match('"', t):
|
||||
return 'string'
|
||||
if re.match(g_ccid0, t):
|
||||
return 'id'
|
||||
if re.match('[0-9]+[bf]', t):
|
||||
return 'label'
|
||||
if re.match('[0-9]', t):
|
||||
return 'number'
|
||||
return t # Sui generis
|
||||
|
||||
|
||||
def debug_parse(a, b, c):
|
||||
# Show results of instuction stream parse.
|
||||
#
|
||||
(b1, b2, b3) = parse_iparts(b)
|
||||
newb = '{' + b1 + '}' + '{' + b2 + '}' + '{' + b3 + '}'
|
||||
sys.stdout.write('{' + a + '}' + newb + c)
|
||||
|
||||
|
||||
def main():
|
||||
instrs = parse_instrs(read_input())
|
||||
instrs = explicit_address_loads(instrs)
|
||||
instrs = funtypes(instrs)
|
||||
instrs = jump_tables(instrs)
|
||||
instrs = global_symbols(instrs)
|
||||
instrs = local_symbols(instrs)
|
||||
instrs = dot_relative(instrs)
|
||||
instrs = add_prefix(instrs)
|
||||
for (a, b, c) in instrs:
|
||||
sys.stdout.write(a + b + c)
|
||||
|
||||
|
||||
main()
|
||||
137
OpenVPN Adapter/Vendors/openvpn/deps/minicrypto/build-minicrypto
Executable file
137
OpenVPN Adapter/Vendors/openvpn/deps/minicrypto/build-minicrypto
Executable file
@@ -0,0 +1,137 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
if [ -z "$O3" ]; then
|
||||
echo O3 var must point to ovpn3 tree
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$TARGET" ]; then
|
||||
echo TARGET var must be defined
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ -z "$DL" ] && DL=~/Downloads
|
||||
|
||||
. $O3/core/vars/vars-$TARGET
|
||||
. $O3/core/deps/lib-versions
|
||||
|
||||
# Build ASM files with clang 3.0
|
||||
if [ "$APPLE_FAMILY" = "1" ]; then
|
||||
GCC_AS_CMD=$HOME/clang3/clang
|
||||
if ! [ -f "$GCC_AS_CMD" ]; then
|
||||
echo "clang 3.0 binary must be present in $GCC_AS_CMD to assemble ARM crypto algorithms"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
DEST=minicrypto/minicrypto-$PLATFORM
|
||||
|
||||
GLOBAL_COMPILE_FLAGS="$PLATFORM_FLAGS $OTHER_COMPILER_FLAGS $LIB_OPT_LEVEL $LIB_FPIC -DSHA1_ASM -DBF_PTR -DOPENSSL_VERSION_PTEXT= -D__LP32__"
|
||||
|
||||
[ -z "$GCC_CMD" ] && GCC_CMD=gcc
|
||||
[ -z "$GCC_AS_CMD" ] && GCC_AS_CMD="$GCC_CMD"
|
||||
[ -z "$AR_CMD" ] && AR_CMD=ar
|
||||
# the directory where this script lives
|
||||
H=$O3/core/deps/minicrypto
|
||||
|
||||
if [ "$NO_WIPE" != "1" ]; then
|
||||
# unzip OpenSSL
|
||||
rm -rf $OPENSSL_VERSION
|
||||
tar xfz $DL/$OPENSSL_VERSION.tar.gz
|
||||
fi
|
||||
|
||||
OPENSSL_DIR=$(pwd)/$OPENSSL_VERSION
|
||||
|
||||
# make build directory
|
||||
mkdir -p minicrypto
|
||||
rm -rf minicrypto/minicrypto-$PLATFORM
|
||||
mkdir -p minicrypto/minicrypto-$PLATFORM/build.tmp
|
||||
cd minicrypto/minicrypto-$PLATFORM/build.tmp
|
||||
mkdir openssl
|
||||
|
||||
# copy files from OpenSSL tree
|
||||
|
||||
# ARM
|
||||
cp $OPENSSL_DIR/crypto/arm_arch.h .
|
||||
|
||||
# SHA general
|
||||
cp $OPENSSL_DIR/crypto/md32_common.h .
|
||||
cp $OPENSSL_DIR/crypto/sha/sha.h openssl
|
||||
|
||||
# AES
|
||||
cp $OPENSSL_DIR/crypto/aes/asm/aes-armv4.pl .
|
||||
|
||||
# SHA1
|
||||
cp $OPENSSL_DIR/crypto/sha/asm/sha1-armv4-large.pl .
|
||||
cp $OPENSSL_DIR/crypto/sha/sha_locl.h .
|
||||
cp $OPENSSL_DIR/crypto/sha/sha1dgst.c .
|
||||
|
||||
# SHA2
|
||||
cp $OPENSSL_DIR/crypto/sha/sha256.c .
|
||||
cp $OPENSSL_DIR/crypto/sha/asm/sha256-armv4.pl .
|
||||
|
||||
# SHA4
|
||||
cp $OPENSSL_DIR/crypto/sha/sha512.c .
|
||||
cp $OPENSSL_DIR/crypto/sha/asm/sha512-armv4.pl .
|
||||
|
||||
# note that OPENSSL_cleanse is not used by any
|
||||
# of the functions we are interested in
|
||||
cat >openssl/crypto.h <<EOF
|
||||
#define fips_md_init(alg) fips_md_init_ctx(alg, alg)
|
||||
#define fips_md_init_ctx(alg, cx) int alg##_Init(cx##_CTX *c)
|
||||
#define OPENSSL_cleanse(ptr, len) memset((ptr), 0, (len))
|
||||
EOF
|
||||
|
||||
# irrelevant headers
|
||||
touch openssl/e_os2.h
|
||||
touch openssl/opensslconf.h
|
||||
touch openssl/opensslv.h
|
||||
touch aes_locl.h
|
||||
touch cryptlib.h
|
||||
touch crypto.h
|
||||
|
||||
# patches
|
||||
patch <$H/aes-armv4.pl.patch
|
||||
patch <$H/sha512-armv4.pl.patch
|
||||
perl -pi -e 's/private_//g' aes-armv4.pl
|
||||
for f in aes-armv4.pl sha256-armv4.pl sha512-armv4.pl ; do # armv4cpuid.pre
|
||||
perl -pi -e 's/^(\.code.*)$/\/* \1 *\//' $f
|
||||
done
|
||||
|
||||
# build C files
|
||||
for f in *.c ; do
|
||||
COMPILE_FLAGS="-Wno-unused-value"
|
||||
CMD="$GCC_CMD $GLOBAL_COMPILE_FLAGS $COMPILE_FLAGS -I. -c $f"
|
||||
echo $CMD
|
||||
$CMD
|
||||
done
|
||||
|
||||
# build armv4cpuid.S
|
||||
#$O3/core/deps/minicrypto/arm-as-to-ios <armv4cpuid.pre >armv4cpuid.S
|
||||
#CMD="$GCC_AS_CMD $GLOBAL_COMPILE_FLAGS -DSYS_macosx -DNO_THUMB -c armv4cpuid.S"
|
||||
#echo $CMD
|
||||
#$CMD
|
||||
|
||||
# build the ASM files given as perl source
|
||||
for f in *.pl ; do
|
||||
bn=${f%%.pl}
|
||||
S=$bn.S
|
||||
COMPILE_FLAGS=""
|
||||
CVT_FLAGS=""
|
||||
if [ "$APPLE_FAMILY" = "1" ]; then
|
||||
COMPILE_FLAGS="$COMPILE_FLAGS -DNO_THUMB"
|
||||
[ "$bn" = "aes-armv4" ] && CVT_FLAGS="$CVT_FLAGS --global=!ad1,!ad2,!ad3"
|
||||
[ "$bn" = "sha512-armv4" ] && CVT_FLAGS="$CVT_FLAGS --global=!HI,!LO"
|
||||
perl $f | $O3/core/deps/minicrypto/arm-as-to-ios --stdin $CVT_FLAGS >$S
|
||||
else
|
||||
perl $f >$S
|
||||
fi
|
||||
CMD="$GCC_AS_CMD $GLOBAL_COMPILE_FLAGS $COMPILE_FLAGS -DSYS_macosx -c $S"
|
||||
echo $CMD
|
||||
$CMD
|
||||
done
|
||||
|
||||
CMD="$AR_CMD crs ../libminicrypto.a *.o"
|
||||
echo $CMD
|
||||
$CMD
|
||||
exit 0
|
||||
139
OpenVPN Adapter/Vendors/openvpn/deps/minicrypto/build-minicrypto-osx
Executable file
139
OpenVPN Adapter/Vendors/openvpn/deps/minicrypto/build-minicrypto-osx
Executable file
@@ -0,0 +1,139 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
if [ -z "$O3" ]; then
|
||||
echo O3 var must point to ovpn3 tree
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$TARGET" ]; then
|
||||
echo TARGET var must be defined
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$ARCH" ]; then
|
||||
echo "ARCH var must be defined (x86_64|i386)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ -z "$DL" ] && DL=~/Downloads
|
||||
|
||||
. $O3/core/vars-$TARGET
|
||||
. $O3/core/deps/lib-versions
|
||||
|
||||
DEST=minicrypto/minicrypto-$PLATFORM
|
||||
|
||||
GLOBAL_COMPILE_FLAGS="$MIN_DEPLOY_TARGET $OTHER_COMPILER_FLAGS $LIB_OPT_LEVEL $LIB_FPIC"
|
||||
|
||||
[ -z "$GCC_CMD" ] && GCC_CMD=gcc
|
||||
[ -z "$GCC_AS_CMD" ] && GCC_AS_CMD="$GCC_CMD"
|
||||
[ -z "$AR_CMD" ] && AR_CMD=ar
|
||||
|
||||
# the directory where this script lives
|
||||
H=$O3/core/deps/minicrypto
|
||||
|
||||
if [ "$NO_WIPE" != "1" ]; then
|
||||
# unzip OpenSSL
|
||||
rm -rf $OPENSSL_VERSION
|
||||
tar xfz $DL/$OPENSSL_VERSION.tar.gz
|
||||
fi
|
||||
|
||||
OPENSSL_DIR=$(pwd)/$OPENSSL_VERSION
|
||||
|
||||
# make build directory
|
||||
mkdir -p minicrypto
|
||||
rm -rf minicrypto/minicrypto-$PLATFORM/$ARCH
|
||||
mkdir -p minicrypto/minicrypto-$PLATFORM/$ARCH/build.tmp
|
||||
cd minicrypto/minicrypto-$PLATFORM/$ARCH/build.tmp
|
||||
mkdir openssl
|
||||
|
||||
# copy files from OpenSSL tree
|
||||
|
||||
# AES (not necessary now that PolarSSL has AES optimizations)
|
||||
#cp $OPENSSL_DIR/crypto/aes/asm/aesni-x86_64.pl .
|
||||
|
||||
if [ "$ARCH" = "x86_64" ]; then
|
||||
# General
|
||||
cp $O3/core/deps/polarssl/intel_cpu.c .
|
||||
cp $OPENSSL_DIR/crypto/perlasm/x86_64-xlate.pl .
|
||||
cp $OPENSSL_DIR/crypto/x86_64cpuid.pl .
|
||||
|
||||
# SHA general
|
||||
cp $OPENSSL_DIR/crypto/md32_common.h .
|
||||
cp $OPENSSL_DIR/crypto/sha/sha.h openssl
|
||||
|
||||
# SHA1
|
||||
cp $OPENSSL_DIR/crypto/sha/sha_locl.h .
|
||||
cp $OPENSSL_DIR/crypto/sha/sha1dgst.c .
|
||||
cp $OPENSSL_DIR/crypto/sha/asm/sha1-x86_64.pl .
|
||||
|
||||
# SHA256
|
||||
cp $OPENSSL_DIR/crypto/sha/sha256.c .
|
||||
|
||||
# SHA512
|
||||
cp $OPENSSL_DIR/crypto/sha/sha512.c .
|
||||
cp $OPENSSL_DIR/crypto/sha/asm/sha512-x86_64.pl .
|
||||
|
||||
# convert perl ASM to .s
|
||||
for f in x86_64cpuid sha1-x86_64 ; do
|
||||
perl $f.pl macosx >$f.s
|
||||
done
|
||||
perl sha512-x86_64.pl macosx sha512-x86_64.s
|
||||
perl sha512-x86_64.pl macosx sha256-x86_64.s
|
||||
elif [ "$ARCH" = "i386" ]; then
|
||||
# General
|
||||
cp $O3/core/deps/polarssl/intel_cpu.c .
|
||||
cp $OPENSSL_DIR/crypto/perlasm/x86asm.pl .
|
||||
cp $OPENSSL_DIR/crypto/perlasm/x86gas.pl .
|
||||
cp $OPENSSL_DIR/crypto/x86cpuid.pl .
|
||||
|
||||
# SHA general
|
||||
cp $OPENSSL_DIR/crypto/md32_common.h .
|
||||
cp $OPENSSL_DIR/crypto/sha/sha.h openssl
|
||||
|
||||
# SHA1
|
||||
cp $OPENSSL_DIR/crypto/sha/sha_locl.h .
|
||||
cp $OPENSSL_DIR/crypto/sha/sha1dgst.c .
|
||||
cp $OPENSSL_DIR/crypto/sha/asm/sha1-586.pl .
|
||||
|
||||
# SHA256
|
||||
cp $OPENSSL_DIR/crypto/sha/sha256.c .
|
||||
cp $OPENSSL_DIR/crypto/sha/asm/sha256-586.pl .
|
||||
|
||||
# SHA512
|
||||
cp $OPENSSL_DIR/crypto/sha/sha512.c .
|
||||
cp $OPENSSL_DIR/crypto/sha/asm/sha512-586.pl .
|
||||
|
||||
# convert perl ASM to .s
|
||||
for f in x86cpuid sha1-586 sha256-586 sha512-586 ; do
|
||||
perl $f.pl macosx >$f.s
|
||||
done
|
||||
fi
|
||||
|
||||
cat >openssl/crypto.h <<EOF
|
||||
#define fips_md_init(alg) fips_md_init_ctx(alg, alg)
|
||||
#define fips_md_init_ctx(alg, cx) int alg##_Init(cx##_CTX *c)
|
||||
void OPENSSL_cleanse(void *ptr, unsigned long len);
|
||||
#define OPENSSL_VERSION_PTEXT " minicrypto"
|
||||
EOF
|
||||
|
||||
# irrelevant headers
|
||||
touch openssl/e_os2.h
|
||||
touch openssl/opensslconf.h
|
||||
touch openssl/opensslv.h
|
||||
touch aes_locl.h
|
||||
touch cryptlib.h
|
||||
touch crypto.h
|
||||
|
||||
# build C/ASM files
|
||||
for f in *.c *.s ; do
|
||||
COMPILE_FLAGS="-arch $ARCH -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM"
|
||||
CMD="$GCC_CMD $GLOBAL_COMPILE_FLAGS $COMPILE_FLAGS -I. -c $f"
|
||||
echo $CMD
|
||||
$CMD
|
||||
done
|
||||
|
||||
CMD="$AR_CMD crs ../libminicrypto.a *.o"
|
||||
echo $CMD
|
||||
$CMD
|
||||
echo SYMBOLS
|
||||
nm ../libminicrypto.a
|
||||
exit 0
|
||||
@@ -0,0 +1,32 @@
|
||||
--- sha512-armv4.pl.orig 2012-09-03 13:21:35.000000000 -0600
|
||||
+++ sha512-armv4.pl 2012-09-03 13:50:08.000000000 -0600
|
||||
@@ -220,9 +220,6 @@
|
||||
WORD64(0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a)
|
||||
WORD64(0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817)
|
||||
.size K512,.-K512
|
||||
-.LOPENSSL_armcap:
|
||||
-.word OPENSSL_armcap_P-sha512_block_data_order
|
||||
-.skip 32-4
|
||||
|
||||
.global sha512_block_data_order
|
||||
.type sha512_block_data_order,%function
|
||||
@@ -230,10 +227,7 @@
|
||||
sub r3,pc,#8 @ sha512_block_data_order
|
||||
add $len,$inp,$len,lsl#7 @ len to point at the end of inp
|
||||
#if __ARM_ARCH__>=7
|
||||
- ldr r12,.LOPENSSL_armcap
|
||||
- ldr r12,[r3,r12] @ OPENSSL_armcap_P
|
||||
- tst r12,#1
|
||||
- bne .LNEON
|
||||
+ b .LNEON @ JY -- assume ARM v7 always supports NEON
|
||||
#endif
|
||||
stmdb sp!,{r4-r12,lr}
|
||||
sub $Ktbl,r3,#672 @ K512
|
||||
@@ -573,7 +567,6 @@
|
||||
.size sha512_block_data_order,.-sha512_block_data_order
|
||||
.asciz "SHA512 block transform for ARMv4/NEON, CRYPTOGAMS by <appro\@openssl.org>"
|
||||
.align 2
|
||||
-.comm OPENSSL_armcap_P,4,4
|
||||
___
|
||||
|
||||
$code =~ s/\`([^\`]*)\`/eval $1/gem;
|
||||
63
OpenVPN Adapter/Vendors/openvpn/deps/openssl/build-openssl
Executable file
63
OpenVPN Adapter/Vendors/openvpn/deps/openssl/build-openssl
Executable file
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
if [ -z "$O3" ]; then
|
||||
echo O3 var must point to ovpn3 tree
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$TARGET" ]; then
|
||||
echo TARGET var must be defined
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$OPENSSL_TARGET" ]; then
|
||||
echo "OPENSSL_TARGET var must be defined"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# GNU sed differs from BSD sed
|
||||
if sed --version 2>&1 | grep -q GNU ; then
|
||||
mysed='sed -i'
|
||||
else
|
||||
mysed='sed -i ""'
|
||||
fi
|
||||
|
||||
[ -z "$GCC_CMD" ] && GCC_CMD=gcc
|
||||
|
||||
[ -z "$LINK_MODE" ] && LINK_MODE=static
|
||||
[ "$LINK_MODE" = "static" ] && LINK_MODE=no-shared
|
||||
|
||||
[ -z "$DL" ] && DL=~/Downloads
|
||||
|
||||
. $O3/core/vars/vars-$TARGET
|
||||
. $O3/core/deps/lib-versions
|
||||
|
||||
AR=ar
|
||||
RANLIB=ranlib
|
||||
[ "$AR_CMD" ] && AR=$AR_CMD
|
||||
[ "$RANLIB_CMD" ] && RANLIB=$RANLIB_CMD
|
||||
|
||||
# special hack because OpenSSL build system doesn't use rc options for ar
|
||||
[ "$AR" = "gcc-ar" ] && AR="gcc-ar rc"
|
||||
[ "$AR" = "gcc-ar-5" ] && AR="gcc-ar-5 rc"
|
||||
|
||||
OPENSSL=$OPENSSL_VERSION
|
||||
DIST=$(pwd)/openssl/openssl-$PLATFORM
|
||||
[ "$ARCH" ] && DIST=$DIST/$ARCH
|
||||
rm -rf $OPENSSL $DIST
|
||||
mkdir -p $DIST
|
||||
tar xfz $DL/$OPENSSL.tar.gz
|
||||
pushd $OPENSSL
|
||||
CMD="./Configure $OPENSSL_TARGET $LINK_MODE threads no-idea no-mdc2 no-rc5 --prefix=$DIST"
|
||||
echo $CMD
|
||||
$CMD
|
||||
$mysed -e "s|-O3|$LIB_OPT_LEVEL $MIN_DEPLOY_TARGET $OTHER_COMPILER_FLAGS $LIB_FPIC|" Makefile
|
||||
#$mysed -e "s|ERR_load_COMP_strings()|//ERR_load_COMP_strings()|" crypto/err/err_all.c
|
||||
make depend
|
||||
make CC="$GCC_CMD" AR="$AR" RANLIB="$RANLIB" -j ${MAKE_JOBS:-1} build_libs
|
||||
touch apps/openssl
|
||||
touch openssl.pc
|
||||
touch libcrypto.pc
|
||||
touch libssl.pc
|
||||
make install_sw
|
||||
popd
|
||||
|
||||
exit 0
|
||||
1
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/.gitignore
vendored
Normal file
1
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
polartmp
|
||||
86
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/CMakeLists.txt
Normal file
86
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/CMakeLists.txt
Normal file
@@ -0,0 +1,86 @@
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
project(POLARSSL C)
|
||||
|
||||
enable_testing()
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
# JY Added
|
||||
set(CMAKE_OSX_ARCHITECTURES "")
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "")
|
||||
set(CMAKE_OSX_SYSROOT "")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} $ENV{LIB_FPIC} $ENV{LIB_OPT_LEVEL} $ENV{PLATFORM_FLAGS} $ENV{OTHER_COMPILER_FLAGS} -Wall -W -Wdeclaration-after-statement")
|
||||
if (NOT "$ENV{GCC_CMD}" STREQUAL "")
|
||||
set(CMAKE_C_COMPILER "$ENV{GCC_CMD}")
|
||||
endif()
|
||||
if (NOT "$ENV{GPP_CMD}" STREQUAL "")
|
||||
set(CMAKE_CXX_COMPILER "$ENV{GPP_CMD}")
|
||||
endif()
|
||||
if (NOT "$ENV{AR_CMD}" STREQUAL "")
|
||||
set(CMAKE_AR "$ENV{AR_CMD}")
|
||||
endif()
|
||||
if (NOT "$ENV{RANLIB_CMD}" STREQUAL "")
|
||||
set(CMAKE_RANLIB "$ENV{RANLIB_CMD}")
|
||||
endif()
|
||||
|
||||
# JY Commented out
|
||||
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -Wall -Wextra -W -Wdeclaration-after-statement")
|
||||
#set(CMAKE_C_FLAGS_DEBUG "-g3 -O0")
|
||||
#set(CMAKE_C_FLAGS_COVERAGE "-g3 -O0 -fprofile-arcs -ftest-coverage -lgcov")
|
||||
endif(CMAKE_COMPILER_IS_GNUCC)
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Coverage")
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "-fprofile-arcs -ftest-coverage")
|
||||
endif(CMAKE_COMPILER_IS_GNUCC)
|
||||
endif(CMAKE_BUILD_TYPE STREQUAL "Coverage")
|
||||
|
||||
option(USE_PKCS11_HELPER_LIBRARY "Build PolarSSL with the pkcs11-helper library." OFF)
|
||||
|
||||
option(ENABLE_ZLIB_SUPPORT "Build PolarSSL with zlib library." OFF)
|
||||
|
||||
# JY added
|
||||
if(MINICRYPTO)
|
||||
if(MINICRYPTO_DIR)
|
||||
add_library(minicrypto STATIC IMPORTED)
|
||||
set_property(TARGET minicrypto PROPERTY IMPORTED_LOCATION "${MINICRYPTO_DIR}/libminicrypto.a")
|
||||
endif()
|
||||
if(OSSLCRYPTO_DIR)
|
||||
add_library(crypto STATIC IMPORTED)
|
||||
set_property(TARGET crypto PROPERTY IMPORTED_LOCATION "${OSSLCRYPTO_DIR}/libcrypto.a")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# include full testing infrastructure (JY added)
|
||||
if(ENABLE_TESTING)
|
||||
enable_testing()
|
||||
endif()
|
||||
|
||||
if(LIB_INSTALL_DIR)
|
||||
else()
|
||||
set(LIB_INSTALL_DIR lib)
|
||||
endif()
|
||||
|
||||
include_directories(include/)
|
||||
|
||||
if(ENABLE_ZLIB_SUPPORT)
|
||||
find_package(ZLIB)
|
||||
|
||||
if(ZLIB_FOUND)
|
||||
include_directories(ZLIB_INCLUDE_DIR)
|
||||
endif(ZLIB_FOUND)
|
||||
endif(ENABLE_ZLIB_SUPPORT)
|
||||
|
||||
add_subdirectory(library)
|
||||
add_subdirectory(include)
|
||||
|
||||
# include full testing infrastructure (JY modified)
|
||||
if(ENABLE_TESTING)
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
add_subdirectory(tests)
|
||||
endif(CMAKE_COMPILER_IS_GNUCC)
|
||||
add_subdirectory(programs)
|
||||
endif()
|
||||
|
||||
ADD_CUSTOM_TARGET(apidoc
|
||||
COMMAND doxygen doxygen/polarssl.doxyfile
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
12
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/README.txt
Normal file
12
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/README.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
Building PolarSSL for android.
|
||||
|
||||
First, build static OpenSSL for PolarSSL/OpenSSL bridge
|
||||
(the build-openssl-small script may be used).
|
||||
|
||||
Next build libminicrypto.a from libcrypto.a :
|
||||
|
||||
$O3/polarssl/build-mini-openssl ref
|
||||
|
||||
Finally, build PolarSSL:
|
||||
|
||||
TARGET=android $O3/polarssl/build-polarssl
|
||||
17
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/android.cmake
Normal file
17
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/android.cmake
Normal file
@@ -0,0 +1,17 @@
|
||||
# this one is important
|
||||
SET(CMAKE_SYSTEM_NAME Linux)
|
||||
#this one not so much
|
||||
SET(CMAKE_SYSTEM_VERSION 1)
|
||||
|
||||
# specify the cross compiler (assumes that PATH already points to android toolchain)
|
||||
SET(CMAKE_C_COMPILER gcc)
|
||||
SET(CMAKE_CXX_COMPILER g++)
|
||||
|
||||
# where is the target environment
|
||||
#SET(CMAKE_FIND_ROOT_PATH /opt/eldk-2007-01-19/ppc_74xx /home/alex/eldk-ppc74xx-inst)
|
||||
|
||||
# search for programs in the build host directories
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
# for libraries and headers in the target directories
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
@@ -0,0 +1,4 @@
|
||||
# specify the cross compiler
|
||||
SET(CMAKE_C_COMPILER clang)
|
||||
SET(CMAKE_CXX_COMPILER clang++)
|
||||
SET(CMAKE_COMPILER_IS_GNUCC 1)
|
||||
@@ -0,0 +1,32 @@
|
||||
diff -uNr polarssl-1.2.7/include/polarssl/bn_mul.h polarssl-1.2.7.new/include/polarssl/bn_mul.h
|
||||
--- polarssl-1.2.7/include/polarssl/bn_mul.h 2013-04-13 03:56:17.000000000 -0600
|
||||
+++ polarssl-1.2.7.new/include/polarssl/bn_mul.h 2013-06-13 16:30:35.000000000 -0600
|
||||
@@ -548,7 +548,7 @@
|
||||
|
||||
#if defined(__arm__)
|
||||
|
||||
-#if defined(__thumb__)
|
||||
+#if defined(__thumb__) && !defined(__thumb2__)
|
||||
|
||||
#define MULADDC_INIT \
|
||||
asm( \
|
||||
diff -uNr polarssl-1.2.7/library/bignum.c polarssl-1.2.7.new/library/bignum.c
|
||||
--- polarssl-1.2.7/library/bignum.c 2013-04-13 03:56:17.000000000 -0600
|
||||
+++ polarssl-1.2.7.new/library/bignum.c 2013-06-13 16:30:35.000000000 -0600
|
||||
@@ -935,7 +935,15 @@
|
||||
/*
|
||||
* Helper for mpi multiplication
|
||||
*/
|
||||
-static void mpi_mul_hlp( size_t i, t_uint *s, t_uint *d, t_uint b )
|
||||
+static
|
||||
+#if defined(__APPLE__) && defined(__arm__)
|
||||
+/*
|
||||
+ * Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
|
||||
+ * appears to need this to prevent bad ARM code generation at -O3.
|
||||
+ */
|
||||
+__attribute__ ((noinline))
|
||||
+#endif
|
||||
+void mpi_mul_hlp( size_t i, t_uint *s, t_uint *d, t_uint b )
|
||||
{
|
||||
t_uint c = 0, t = 0;
|
||||
|
||||
24
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/build-detail-patch
Executable file
24
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/build-detail-patch
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
. $O3/core/deps/lib-versions
|
||||
POLARSSL_SRC=$HOME/src/mac/$POLARSSL_VERSION
|
||||
PD=$O3/core/deps/polarssl
|
||||
PB=$(basename $POLARSSL_SRC)
|
||||
|
||||
rm -rf polartmp
|
||||
mkdir polartmp
|
||||
cd polartmp
|
||||
cp -a $POLARSSL_SRC polarssl.new
|
||||
|
||||
# extract the PolarSSL source
|
||||
tar xfz $DL/$PB-gpl.tgz
|
||||
|
||||
cd $PB
|
||||
rm $(find . -type f | grep -E 'Makefile|\.orig$|\.rej$')
|
||||
rm -f CMakeLists.txt include/polarssl/config.h include/polarssl/openvpn-polarssl.h
|
||||
|
||||
cd ../polarssl.new
|
||||
rm -f CMakeLists.txt include/polarssl/config.h include/polarssl/openvpn-polarssl.h
|
||||
cd ..
|
||||
|
||||
diff -ur $PB polarssl.new | grep -v '^Only in'
|
||||
52
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/build-mini-openssl
Executable file
52
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/build-mini-openssl
Executable file
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env bash
|
||||
# Examples:
|
||||
# $O3/core/deps/polarssl/build-mini-openssl ref
|
||||
# $O3/core/deps/polarssl/build-mini-openssl ref-aesni
|
||||
|
||||
set -e
|
||||
if [ -z "$1" ]; then
|
||||
echo "usage: build-mini-openssl <ref|ref-aesni>"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$OPENSSL_DIR" ]; then
|
||||
echo OPENSSL_DIR must be defined
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$APPLE_FAMILY" = "1" ] && [ -z "$GCC_CMD" ]; then
|
||||
GCC_CMD=clang
|
||||
fi
|
||||
|
||||
if [ "$APPLE_FAMILY" = "1" ]; then
|
||||
NM_FLAGS=-P
|
||||
BSD_SYMBOLS="1"
|
||||
VISIBILITY="-fvisibility=hidden"
|
||||
else
|
||||
NM_FLAGS="-f posix"
|
||||
BSD_SYMBOLS="0"
|
||||
VISIBILITY=""
|
||||
fi
|
||||
|
||||
[ -z "$NM_CMD" ] && NM_CMD=nm
|
||||
[ -z "$AR_CMD" ] && AR_CMD=ar
|
||||
[ -z "$GCC_CMD" ] && GCC_CMD=gcc
|
||||
PD=$O3/core/deps/polarssl
|
||||
cd $OPENSSL_DIR
|
||||
cd lib
|
||||
rm -rf tmp
|
||||
mkdir tmp
|
||||
$NM_CMD $NM_FLAGS libcrypto.a >tmp/nm-file
|
||||
echo "NOTE: on BSD systems, don't worry about any 'no name list' errors above"
|
||||
cd tmp
|
||||
python $O3/common/scripts/sym.py $PD/$1 nm-file $AR_CMD ../libcrypto.a libminicrypto.a buildmini ../mini-undef.sh $BSD_SYMBOLS
|
||||
. buildmini
|
||||
|
||||
# need any special initialization?
|
||||
. ../mini-undef.sh
|
||||
if [ "$SYM_UNDEF_OPENSSL_ia32cap_P" ] && [ "$SYM_UNDEF_OPENSSL_cpuid_setup" ]; then
|
||||
echo BUILDING STUB intel_cpu.c
|
||||
$GCC_CMD $VISIBILITY $LIB_OPT_LEVEL $LIB_FPIC -c $PD/intel_cpu.c
|
||||
$AR_CMD rs libminicrypto.a intel_cpu.o
|
||||
fi
|
||||
|
||||
mv libminicrypto.a ..
|
||||
167
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/build-polarssl
Executable file
167
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/build-polarssl
Executable file
@@ -0,0 +1,167 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Parameters:
|
||||
# CMAKE_TARGET -- use $CMAKE_TARGET.cmake as toolchain file
|
||||
# AES_NI=1 -- enable AES_NI processor optimization
|
||||
# EXTERNAL_RNG=1 -- disable all internal RNG implementations (caller must provide)
|
||||
# ENABLE_TESTING=1 -- run PolarSSL test scripts after build
|
||||
# DEBUG_BUILD=1 or SELF_TEST=1 -- enable minimal testing on target
|
||||
# ENABLE_SERVER=1 -- enable SSL/TLS server code
|
||||
# ENABLE_FS_IO=1 -- enable PolarSSL file I/O
|
||||
# VERBOSE=1 -- see build commands
|
||||
# USE_MINICRYPTO=1 -- use minicrypto library
|
||||
# NO_WIPE=1 -- don't wipe source tree and reunzip tarball
|
||||
# STOCK_CONFIG=1 -- use stock PolarSSL config.h
|
||||
|
||||
set -e
|
||||
if [ -z "$O3" ]; then
|
||||
echo O3 var must point to ovpn3 tree
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$TARGET" ]; then
|
||||
echo TARGET var must be defined
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# source vars
|
||||
. $O3/core/vars/vars-${TARGET}
|
||||
. $O3/core/deps/lib-versions
|
||||
|
||||
# extract the PolarSSL source
|
||||
PD=$O3/core/deps/polarssl
|
||||
DIST=polarssl-$PLATFORM
|
||||
|
||||
rm -rf $DIST
|
||||
mkdir $DIST
|
||||
|
||||
if [ "$NO_WIPE" = "1" ]; then
|
||||
echo RETAIN existing source
|
||||
cd $POLARSSL_VERSION
|
||||
elif [ "$NO_WIPE" = "partial" ]; then
|
||||
echo RETAIN existing source but copy config.h and CMakeLists.txt
|
||||
cd $POLARSSL_VERSION
|
||||
|
||||
# define configs
|
||||
if [ "$STOCK_CONFIG" != "1" ]; then
|
||||
cp $PD/config.h include/polarssl/
|
||||
fi
|
||||
cp $PD/CMakeLists.txt .
|
||||
else
|
||||
echo WIPE and reunzip source
|
||||
rm -rf $POLARSSL_VERSION $POLARSSL_VERSION-prerelease
|
||||
[ -z "$DL" ] && DL=~/Downloads
|
||||
tar xfz $DL/$POLARSSL_VERSION-gpl.tgz
|
||||
|
||||
[ -d $POLARSSL_VERSION-prerelease ] && mv $POLARSSL_VERSION-prerelease $POLARSSL_VERSION
|
||||
cd $POLARSSL_VERSION
|
||||
|
||||
# delete makefiles (apparently not needed)
|
||||
rm $(find . -type f | grep Makefile)
|
||||
|
||||
patch -p1 <$PD/relaxed-x509-date.patch
|
||||
#patch -p1 <$PD/dhm.patch
|
||||
#patch -p1 <$PD/entropy-printf.patch
|
||||
|
||||
if [ "$USE_MINICRYPTO" = "1" ]; then
|
||||
# do the big polar-openssl patch
|
||||
echo MERGING polarssl-minicrypto.patch
|
||||
patch -p1 <$PD/polarssl-minicrypto.patch
|
||||
fi
|
||||
|
||||
# define configs
|
||||
cp include/polarssl/config.h include/polarssl/config.h.orig
|
||||
cp CMakeLists.txt CMakeLists.txt.orig
|
||||
cp $PD/config.h include/polarssl/
|
||||
cp $PD/CMakeLists.txt .
|
||||
fi
|
||||
|
||||
# dynamically generated header file with options,
|
||||
# included by config.h
|
||||
OPC=include/polarssl/openvpn-polarssl.h
|
||||
echo '/* Automatically generated by ovpn3/core/deps/polarssl/build-polarssl, do not edit */' >$OPC
|
||||
|
||||
# set options
|
||||
OPT=""
|
||||
|
||||
# relaxed cert checking
|
||||
echo "#define POLARSSL_RELAXED_X509_DATE" >>$OPC
|
||||
|
||||
# RNG
|
||||
if [ "$EXTERNAL_RNG" = "1" ]; then
|
||||
echo "#define EXTERNAL_RNG" >>$OPC
|
||||
fi
|
||||
|
||||
# enable full testing infrastructure
|
||||
if [ "$ENABLE_TESTING" = "1" ]; then
|
||||
OPT="$OPT -DENABLE_TESTING=1"
|
||||
echo "#define ENABLE_TESTING" >>$OPC
|
||||
fi
|
||||
|
||||
# enable minimal testing on target
|
||||
if [ "$DEBUG_BUILD" = "1" ] || [ "$SELF_TEST" = "1" ]; then
|
||||
echo "#define POLARSSL_SELF_TEST" >>$OPC
|
||||
fi
|
||||
|
||||
# configure target
|
||||
if [ "$CMAKE_TARGET" ]; then
|
||||
OPT="$OPT -DCMAKE_TOOLCHAIN_FILE=$PD/$CMAKE_TARGET.cmake"
|
||||
elif [ "$APPLE_FAMILY" = "1" ]; then
|
||||
OPT="$OPT -DCMAKE_TOOLCHAIN_FILE=$PD/apple.cmake"
|
||||
fi
|
||||
|
||||
# Minicrypto
|
||||
if [ "$USE_MINICRYPTO" = "1" ]; then
|
||||
OPT="$OPT -DMINICRYPTO=1"
|
||||
if [ "$MINICRYPTO_DIR" ]; then
|
||||
OPT="$OPT -DMINICRYPTO_DIR=$MINICRYPTO_DIR"
|
||||
fi
|
||||
if [ "$OSSLCRYPTO_DIR" ]; then
|
||||
OPT="$OPT -DOSSLCRYPTO_DIR=$OSSLCRYPTO_DIR"
|
||||
fi
|
||||
if [ "$MINICRYPTO_NO_AES" != "1" ]; then
|
||||
echo "#define POLARSSL_AES_ALT" >>$OPC
|
||||
fi
|
||||
echo "#define POLARSSL_SHA1_ALT" >>$OPC
|
||||
echo "#define POLARSSL_SHA256_ALT" >>$OPC
|
||||
echo "#define POLARSSL_SHA512_ALT" >>$OPC
|
||||
if [ "$AES_NI" = "1" ] && [ "$MINICRYPTO_NO_AES" != "1" ]; then
|
||||
echo "#define POLARSSL_USE_OPENSSL_AES_NI" >>$OPC
|
||||
fi
|
||||
fi
|
||||
|
||||
# Enable SSL/TLS server
|
||||
if [ "$ENABLE_SERVER" = "1" ]; then
|
||||
echo "#define POLARSSL_SSL_SRV_C" >>$OPC
|
||||
fi
|
||||
|
||||
# enable PolarSSL file I/O
|
||||
if [ "$ENABLE_FS_IO" = "1" ]; then
|
||||
echo "#define POLARSSL_FS_IO" >>$OPC
|
||||
fi
|
||||
|
||||
# Build shared library
|
||||
if [ "$SHARED" = "1" ]; then
|
||||
OPT="$OPT -DUSE_SHARED_POLARSSL_LIBRARY=1"
|
||||
fi
|
||||
|
||||
# echo options
|
||||
echo OPTIONS $OPT
|
||||
|
||||
# build it
|
||||
pwd
|
||||
cd ../$DIST
|
||||
cmake $OPT ../$POLARSSL_VERSION
|
||||
if [ "$VERBOSE" = "1" ]; then
|
||||
make VERBOSE=1
|
||||
else
|
||||
make
|
||||
fi
|
||||
|
||||
# test it
|
||||
if [ "$ENABLE_TESTING" = "1" ]; then
|
||||
make test
|
||||
fi
|
||||
|
||||
# copy headers
|
||||
cp -a ../$POLARSSL_VERSION/include/polarssl include/
|
||||
exit 0
|
||||
30
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/build-polarssl-patch
Executable file
30
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/build-polarssl-patch
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
. $O3/core/deps/lib-versions
|
||||
POLARSSL_SRC=$HOME/src/mac/$POLARSSL_VERSION
|
||||
PD=$O3/core/deps/polarssl
|
||||
PB=$(basename $POLARSSL_SRC)
|
||||
|
||||
rm -rf polartmp
|
||||
mkdir polartmp
|
||||
cd polartmp
|
||||
cp -a $POLARSSL_SRC polarssl.new
|
||||
|
||||
# extract the PolarSSL source
|
||||
tar xfz $DL/$PB-gpl.tgz
|
||||
|
||||
cd $PB
|
||||
rm $(find . -type f | grep -E 'Makefile|\.orig$|\.rej$')
|
||||
rm -f CMakeLists.txt include/polarssl/config.h include/polarssl/openvpn-polarssl.h
|
||||
|
||||
cd ../polarssl.new
|
||||
rm -f CMakeLists.txt include/polarssl/config.h include/polarssl/openvpn-polarssl.h
|
||||
cd ..
|
||||
|
||||
if [ "$CRYPTO_ALT_PATCH" = "1" ]; then
|
||||
diff -uNr $PB polarssl.new >$PD/polar-openssl.patch
|
||||
cp $PD/crypto-alt.txt $PD/polarssl-crypto-alt.patch
|
||||
diff -ur $PB polarssl.new | grep -v '^Only in' >>$PD/polarssl-crypto-alt.patch
|
||||
else
|
||||
diff -ur $PB polarssl.new | grep -v '^Only in'
|
||||
fi
|
||||
2227
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/config.h
Normal file
2227
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/config.h
Normal file
File diff suppressed because it is too large
Load Diff
2180
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/config.h.orig
Normal file
2180
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/config.h.orig
Normal file
File diff suppressed because it is too large
Load Diff
959
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/config12.h
Normal file
959
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/config12.h
Normal file
@@ -0,0 +1,959 @@
|
||||
/**
|
||||
* \file config.h
|
||||
*
|
||||
* \brief Configuration options (set of defines)
|
||||
*
|
||||
* Copyright (C) 2006-2012, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* This set of compile-time options may be used to enable
|
||||
* or disable features selectively, and reduce the global
|
||||
* memory footprint.
|
||||
*/
|
||||
#ifndef POLARSSL_CONFIG_H
|
||||
#define POLARSSL_CONFIG_H
|
||||
|
||||
#include <polarssl/openvpn-polarssl.h>
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
|
||||
#define _CRT_SECURE_NO_DEPRECATE 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \name SECTION: System support
|
||||
*
|
||||
* This section sets system specific settings.
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def POLARSSL_HAVE_INT8
|
||||
*
|
||||
* The system uses 8-bit wide native integers.
|
||||
*
|
||||
* Uncomment if native integers are 8-bit wide.
|
||||
#define POLARSSL_HAVE_INT8
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def POLARSSL_HAVE_INT16
|
||||
*
|
||||
* The system uses 16-bit wide native integers.
|
||||
*
|
||||
* Uncomment if native integers are 16-bit wide.
|
||||
#define POLARSSL_HAVE_INT16
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def POLARSSL_HAVE_LONGLONG
|
||||
*
|
||||
* The compiler supports the 'long long' type.
|
||||
* (Only used on 32-bit platforms)
|
||||
*/
|
||||
#define POLARSSL_HAVE_LONGLONG
|
||||
|
||||
/**
|
||||
* \def POLARSSL_HAVE_ASM
|
||||
*
|
||||
* The compiler has support for asm()
|
||||
*
|
||||
* Uncomment to enable the use of assembly code.
|
||||
*
|
||||
* Requires support for asm() in compiler.
|
||||
*
|
||||
* Used in:
|
||||
* library/timing.c
|
||||
* library/padlock.c
|
||||
* include/polarssl/bn_mul.h
|
||||
*
|
||||
*/
|
||||
#define POLARSSL_HAVE_ASM
|
||||
|
||||
/**
|
||||
* \def POLARSSL_HAVE_SSE2
|
||||
*
|
||||
* CPU supports SSE2 instruction set.
|
||||
*
|
||||
* Uncomment if the CPU supports SSE2 (IA-32 specific).
|
||||
*
|
||||
#define POLARSSL_HAVE_SSE2
|
||||
*/
|
||||
/* \} name */
|
||||
|
||||
/**
|
||||
* \name SECTION: PolarSSL feature support
|
||||
*
|
||||
* This section sets support for features that are or are not needed
|
||||
* within the modules that are enabled.
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def POLARSSL_AES_ROM_TABLES
|
||||
*
|
||||
* Store the AES tables in ROM.
|
||||
*
|
||||
* Uncomment this macro to store the AES tables in ROM.
|
||||
*
|
||||
#define POLARSSL_AES_ROM_TABLES
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def POLARSSL_CIPHER_MODE_CFB
|
||||
*
|
||||
* Enable Cipher Feedback mode (CFB) for symmetric ciphers.
|
||||
*/
|
||||
// JY removed
|
||||
//#define POLARSSL_CIPHER_MODE_CFB
|
||||
|
||||
/**
|
||||
* \def POLARSSL_CIPHER_MODE_CTR
|
||||
*
|
||||
* Enable Counter Block Cipher mode (CTR) for symmetric ciphers.
|
||||
*/
|
||||
// JY removed
|
||||
//#define POLARSSL_CIPHER_MODE_CTR
|
||||
|
||||
/**
|
||||
* \def POLARSSL_CIPHER_NULL_CIPHER
|
||||
*
|
||||
* Enable NULL cipher.
|
||||
* Warning: Only do so when you know what you are doing. This allows for
|
||||
* encryption or channels without any security!
|
||||
*
|
||||
* Requires POLARSSL_ENABLE_WEAK_CIPHERSUITES as well to enable
|
||||
* the following ciphersuites:
|
||||
* TLS_RSA_WITH_NULL_MD5
|
||||
* TLS_RSA_WITH_NULL_SHA
|
||||
* TLS_RSA_WITH_NULL_SHA256
|
||||
*
|
||||
* Uncomment this macro to enable the NULL cipher and ciphersuites
|
||||
#define POLARSSL_CIPHER_NULL_CIPHER
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def POLARSSL_ENABLE_WEAK_CIPHERSUITES
|
||||
*
|
||||
* Enable weak ciphersuites in SSL / TLS
|
||||
* Warning: Only do so when you know what you are doing. This allows for
|
||||
* channels with virtually no security at all!
|
||||
*
|
||||
* This enables the following ciphersuites:
|
||||
* TLS_RSA_WITH_DES_CBC_SHA
|
||||
* TLS_DHE_RSA_WITH_DES_CBC_SHA
|
||||
*
|
||||
* Uncomment this macro to enable weak ciphersuites
|
||||
#define POLARSSL_ENABLE_WEAK_CIPHERSUITES
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def POLARSSL_ERROR_STRERROR_DUMMY
|
||||
*
|
||||
* Enable a dummy error function to make use of error_strerror() in
|
||||
* third party libraries easier.
|
||||
*
|
||||
* Disable if you run into name conflicts and want to really remove the
|
||||
* error_strerror()
|
||||
*/
|
||||
#define POLARSSL_ERROR_STRERROR_DUMMY
|
||||
|
||||
/**
|
||||
* \def POLARSSL_GENPRIME
|
||||
*
|
||||
* Requires: POLARSSL_BIGNUM_C, POLARSSL_RSA_C
|
||||
*
|
||||
* Enable the RSA prime-number generation code.
|
||||
*/
|
||||
#define POLARSSL_GENPRIME
|
||||
|
||||
/**
|
||||
* \def POLARSSL_FS_IO
|
||||
*
|
||||
* Enable functions that use the filesystem.
|
||||
*/
|
||||
// JY removed
|
||||
//#define POLARSSL_FS_IO
|
||||
|
||||
/**
|
||||
* \def POLARSSL_NO_DEFAULT_ENTROPY_SOURCES
|
||||
*
|
||||
* Do not add default entropy sources. These are the platform specific,
|
||||
* hardclock and HAVEGE based poll functions.
|
||||
*
|
||||
* This is useful to have more control over the added entropy sources in an
|
||||
* application.
|
||||
*
|
||||
* Uncomment this macro to prevent loading of default entropy functions.
|
||||
#define POLARSSL_NO_DEFAULT_ENTROPY_SOURCES
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def POLARSSL_NO_PLATFORM_ENTROPY
|
||||
*
|
||||
* Do not use built-in platform entropy functions.
|
||||
* This is useful if your platform does not support
|
||||
* standards like the /dev/urandom or Windows CryptoAPI.
|
||||
*
|
||||
* Uncomment this macro to disable the built-in platform entropy functions.
|
||||
#define POLARSSL_NO_PLATFORM_ENTROPY
|
||||
*/
|
||||
|
||||
// JY added
|
||||
#ifdef EXTERNAL_RNG
|
||||
#define POLARSSL_NO_DEFAULT_ENTROPY_SOURCES
|
||||
#define POLARSSL_NO_PLATFORM_ENTROPY
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \def POLARSSL_PKCS1_V21
|
||||
*
|
||||
* Requires: POLARSSL_MD_C, POLARSSL_RSA_C
|
||||
*
|
||||
* Enable support for PKCS#1 v2.1 encoding.
|
||||
* This enables support for RSAES-OAEP and RSASSA-PSS operations.
|
||||
*/
|
||||
#define POLARSSL_PKCS1_V21
|
||||
|
||||
/**
|
||||
* \def POLARSSL_RSA_NO_CRT
|
||||
*
|
||||
* Do not use the Chinese Remainder Theorem for the RSA private operation.
|
||||
*
|
||||
* Uncomment this macro to disable the use of CRT in RSA.
|
||||
*
|
||||
#define POLARSSL_RSA_NO_CRT
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def POLARSSL_SELF_TEST
|
||||
*
|
||||
* Enable the checkup functions (*_self_test).
|
||||
*/
|
||||
// JY changed
|
||||
#if defined(ENABLE_TESTING) && !defined(POLARSSL_SELF_TEST)
|
||||
#define POLARSSL_SELF_TEST
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \def POLARSSL_SSL_ALL_ALERT_MESSAGES
|
||||
*
|
||||
* Enable sending of alert messages in case of encountered errors as per RFC.
|
||||
* If you choose not to send the alert messages, PolarSSL can still communicate
|
||||
* with other servers, only debugging of failures is harder.
|
||||
*
|
||||
* The advantage of not sending alert messages, is that no information is given
|
||||
* about reasons for failures thus preventing adversaries of gaining intel.
|
||||
*
|
||||
* Enable sending of all alert messages
|
||||
*/
|
||||
#define POLARSSL_SSL_ALERT_MESSAGES
|
||||
|
||||
/**
|
||||
* \def POLARSSL_SSL_DEBUG_ALL
|
||||
*
|
||||
* Enable the debug messages in SSL module for all issues.
|
||||
* Debug messages have been disabled in some places to prevent timing
|
||||
* attacks due to (unbalanced) debugging function calls.
|
||||
*
|
||||
* If you need all error reporting you should enable this during debugging,
|
||||
* but remove this for production servers that should log as well.
|
||||
*
|
||||
* Uncomment this macro to report all debug messages on errors introducing
|
||||
* a timing side-channel.
|
||||
*
|
||||
#define POLARSSL_SSL_DEBUG_ALL
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def POLARSSL_SSL_HW_RECORD_ACCEL
|
||||
*
|
||||
* Enable hooking functions in SSL module for hardware acceleration of
|
||||
* individual records.
|
||||
*
|
||||
* Uncomment this macro to enable hooking functions.
|
||||
#define POLARSSL_SSL_HW_RECORD_ACCEL
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO
|
||||
*
|
||||
* Enable support for receiving and parsing SSLv2 Client Hello messages for the
|
||||
* SSL Server module (POLARSSL_SSL_SRV_C)
|
||||
*
|
||||
* Comment this macro to disable support for SSLv2 Client Hello messages.
|
||||
*/
|
||||
// JY removed
|
||||
//#define POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO
|
||||
|
||||
/**
|
||||
* \def POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
|
||||
*
|
||||
* If set, the X509 parser will not break-off when parsing an X509 certificate
|
||||
* and encountering an unknown critical extension.
|
||||
*
|
||||
* Uncomment to prevent an error.
|
||||
*
|
||||
#define POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def POLARSSL_ZLIB_SUPPORT
|
||||
*
|
||||
* If set, the SSL/TLS module uses ZLIB to support compression and
|
||||
* decompression of packet data.
|
||||
*
|
||||
* Used in: library/ssl_tls.c
|
||||
* library/ssl_cli.c
|
||||
* library/ssl_srv.c
|
||||
*
|
||||
* This feature requires zlib library and headers to be present.
|
||||
*
|
||||
* Uncomment to enable use of ZLIB
|
||||
#define POLARSSL_ZLIB_SUPPORT
|
||||
*/
|
||||
/* \} name */
|
||||
|
||||
/**
|
||||
* \name SECTION: PolarSSL modules
|
||||
*
|
||||
* This section enables or disables entire modules in PolarSSL
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def POLARSSL_AES_C
|
||||
*
|
||||
* Enable the AES block cipher.
|
||||
*
|
||||
* Module: library/aes.c
|
||||
* Caller: library/ssl_tls.c
|
||||
* library/pem.c
|
||||
* library/ctr_drbg.c
|
||||
*
|
||||
* This module enables the following ciphersuites (if other requisites are
|
||||
* enabled as well):
|
||||
* TLS_RSA_WITH_AES_128_CBC_SHA
|
||||
* TLS_RSA_WITH_AES_256_CBC_SHA
|
||||
* TLS_DHE_RSA_WITH_AES_128_CBC_SHA
|
||||
* TLS_DHE_RSA_WITH_AES_256_CBC_SHA
|
||||
* TLS_RSA_WITH_AES_128_CBC_SHA256
|
||||
* TLS_RSA_WITH_AES_256_CBC_SHA256
|
||||
* TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
|
||||
* TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
|
||||
* TLS_RSA_WITH_AES_128_GCM_SHA256
|
||||
* TLS_RSA_WITH_AES_256_GCM_SHA384
|
||||
*
|
||||
* PEM uses AES for decrypting encrypted keys.
|
||||
*/
|
||||
#define POLARSSL_AES_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_ARC4_C
|
||||
*
|
||||
* Enable the ARCFOUR stream cipher.
|
||||
*
|
||||
* Module: library/arc4.c
|
||||
* Caller: library/ssl_tls.c
|
||||
*
|
||||
* This module enables the following ciphersuites:
|
||||
* TLS_RSA_WITH_RC4_128_MD5
|
||||
* TLS_RSA_WITH_RC4_128_SHA
|
||||
*/
|
||||
// JY removed
|
||||
//#define POLARSSL_ARC4_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_ASN1_PARSE_C
|
||||
*
|
||||
* Enable the generic ASN1 parser.
|
||||
*
|
||||
* Module: library/asn1.c
|
||||
* Caller: library/x509parse.c
|
||||
*/
|
||||
#define POLARSSL_ASN1_PARSE_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_ASN1_WRITE_C
|
||||
*
|
||||
* Enable the generic ASN1 writer.
|
||||
*
|
||||
* Module: library/asn1write.c
|
||||
*/
|
||||
// JY removed
|
||||
//#define POLARSSL_ASN1_WRITE_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_BASE64_C
|
||||
*
|
||||
* Enable the Base64 module.
|
||||
*
|
||||
* Module: library/base64.c
|
||||
* Caller: library/pem.c
|
||||
*
|
||||
* This module is required for PEM support (required by X.509).
|
||||
*/
|
||||
#define POLARSSL_BASE64_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_BIGNUM_C
|
||||
*
|
||||
* Enable the multi-precision integer library.
|
||||
*
|
||||
* Module: library/bignum.c
|
||||
* Caller: library/dhm.c
|
||||
* library/rsa.c
|
||||
* library/ssl_tls.c
|
||||
* library/x509parse.c
|
||||
*
|
||||
* This module is required for RSA and DHM support.
|
||||
*/
|
||||
#define POLARSSL_BIGNUM_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_BLOWFISH_C
|
||||
*
|
||||
* Enable the Blowfish block cipher.
|
||||
*
|
||||
* Module: library/blowfish.c
|
||||
*/
|
||||
#define POLARSSL_BLOWFISH_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_CAMELLIA_C
|
||||
*
|
||||
* Enable the Camellia block cipher.
|
||||
*
|
||||
* Module: library/camellia.c
|
||||
* Caller: library/ssl_tls.c
|
||||
*
|
||||
* This module enables the following ciphersuites (if other requisites are
|
||||
* enabled as well):
|
||||
* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
|
||||
* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
|
||||
* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
|
||||
* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
|
||||
* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
|
||||
* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
|
||||
* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
|
||||
* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
|
||||
*/
|
||||
// JY removed
|
||||
//#define POLARSSL_CAMELLIA_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_CERTS_C
|
||||
*
|
||||
* Enable the test certificates.
|
||||
*
|
||||
* Module: library/certs.c
|
||||
* Caller:
|
||||
*
|
||||
* This module is used for testing (ssl_client/server).
|
||||
*/
|
||||
// JY changed
|
||||
#ifdef ENABLE_TESTING
|
||||
#define POLARSSL_CERTS_C
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \def POLARSSL_CIPHER_C
|
||||
*
|
||||
* Enable the generic cipher layer.
|
||||
*
|
||||
* Module: library/cipher.c
|
||||
* Caller:
|
||||
*
|
||||
* Uncomment to enable generic cipher wrappers.
|
||||
*/
|
||||
#define POLARSSL_CIPHER_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_CTR_DRBG_C
|
||||
*
|
||||
* Enable the CTR_DRBG AES-256-based random generator
|
||||
*
|
||||
* Module: library/ctr_drbg.c
|
||||
* Caller:
|
||||
*
|
||||
* Requires: POLARSSL_AES_C
|
||||
*
|
||||
* This module provides the CTR_DRBG AES-256 random number generator.
|
||||
*/
|
||||
// JY added
|
||||
#ifndef EXTERNAL_RNG
|
||||
#define POLARSSL_CTR_DRBG_C
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \def POLARSSL_DEBUG_C
|
||||
*
|
||||
* Enable the debug functions.
|
||||
*
|
||||
* Module: library/debug.c
|
||||
* Caller: library/ssl_cli.c
|
||||
* library/ssl_srv.c
|
||||
* library/ssl_tls.c
|
||||
*
|
||||
* This module provides debugging functions.
|
||||
*/
|
||||
#define POLARSSL_DEBUG_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_DES_C
|
||||
*
|
||||
* Enable the DES block cipher.
|
||||
*
|
||||
* Module: library/des.c
|
||||
* Caller: library/pem.c
|
||||
* library/ssl_tls.c
|
||||
*
|
||||
* This module enables the following ciphersuites (if other requisites are
|
||||
* enabled as well):
|
||||
* TLS_RSA_WITH_3DES_EDE_CBC_SHA
|
||||
* TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
|
||||
*
|
||||
* PEM uses DES/3DES for decrypting encrypted keys.
|
||||
*/
|
||||
#define POLARSSL_DES_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_DHM_C
|
||||
*
|
||||
* Enable the Diffie-Hellman-Merkle key exchange.
|
||||
*
|
||||
* Module: library/dhm.c
|
||||
* Caller: library/ssl_cli.c
|
||||
* library/ssl_srv.c
|
||||
*
|
||||
* This module enables the following ciphersuites (if other requisites are
|
||||
* enabled as well):
|
||||
* TLS_DHE_RSA_WITH_DES_CBC_SHA
|
||||
* TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
|
||||
* TLS_DHE_RSA_WITH_AES_128_CBC_SHA
|
||||
* TLS_DHE_RSA_WITH_AES_256_CBC_SHA
|
||||
* TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
|
||||
* TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
|
||||
* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
|
||||
* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
|
||||
* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
|
||||
* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
|
||||
* TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
|
||||
* TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
|
||||
*/
|
||||
#define POLARSSL_DHM_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_ENTROPY_C
|
||||
*
|
||||
* Enable the platform-specific entropy code.
|
||||
*
|
||||
* Module: library/entropy.c
|
||||
* Caller:
|
||||
*
|
||||
* Requires: POLARSSL_SHA4_C
|
||||
*
|
||||
* This module provides a generic entropy pool
|
||||
*/
|
||||
#define POLARSSL_ENTROPY_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_ERROR_C
|
||||
*
|
||||
* Enable error code to error string conversion.
|
||||
*
|
||||
* Module: library/error.c
|
||||
* Caller:
|
||||
*
|
||||
* This module enables err_strerror().
|
||||
*/
|
||||
#define POLARSSL_ERROR_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_GCM_C
|
||||
*
|
||||
* Enable the Galois/Counter Mode (GCM) for AES
|
||||
*
|
||||
* Module: library/gcm.c
|
||||
*
|
||||
* Requires: POLARSSL_AES_C
|
||||
*
|
||||
* This module enables the following ciphersuites (if other requisites are
|
||||
* enabled as well):
|
||||
* TLS_RSA_WITH_AES_128_GCM_SHA256
|
||||
* TLS_RSA_WITH_AES_256_GCM_SHA384
|
||||
*/
|
||||
#define POLARSSL_GCM_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_HAVEGE_C
|
||||
*
|
||||
* Enable the HAVEGE random generator.
|
||||
*
|
||||
* Module: library/havege.c
|
||||
* Caller:
|
||||
*
|
||||
* Requires: POLARSSL_TIMING_C
|
||||
*
|
||||
* This module enables the HAVEGE random number generator.
|
||||
*/
|
||||
// JY removed
|
||||
//#define POLARSSL_HAVEGE_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_MD_C
|
||||
*
|
||||
* Enable the generic message digest layer.
|
||||
*
|
||||
* Module: library/md.c
|
||||
* Caller:
|
||||
*
|
||||
* Uncomment to enable generic message digest wrappers.
|
||||
*/
|
||||
#define POLARSSL_MD_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_MD2_C
|
||||
*
|
||||
* Enable the MD2 hash algorithm
|
||||
*
|
||||
* Module: library/md2.c
|
||||
* Caller: library/x509parse.c
|
||||
*
|
||||
* Uncomment to enable support for (rare) MD2-signed X.509 certs.
|
||||
*
|
||||
#define POLARSSL_MD2_C
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def POLARSSL_MD4_C
|
||||
*
|
||||
* Enable the MD4 hash algorithm
|
||||
*
|
||||
* Module: library/md4.c
|
||||
* Caller: library/x509parse.c
|
||||
*
|
||||
* Uncomment to enable support for (rare) MD4-signed X.509 certs.
|
||||
*
|
||||
*/
|
||||
// JY Added for NTLM proxy auth
|
||||
#define POLARSSL_MD4_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_MD5_C
|
||||
*
|
||||
* Enable the MD5 hash algorithm
|
||||
*
|
||||
* Module: library/md5.c
|
||||
* Caller: library/pem.c
|
||||
* library/ssl_tls.c
|
||||
* library/x509parse.c
|
||||
*
|
||||
* This module is required for SSL/TLS and X.509.
|
||||
* PEM uses MD5 for decrypting encrypted keys.
|
||||
*/
|
||||
#define POLARSSL_MD5_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_NET_C
|
||||
*
|
||||
* Enable the TCP/IP networking routines.
|
||||
*
|
||||
* Module: library/net.c
|
||||
* Caller:
|
||||
*
|
||||
* This module provides TCP/IP networking routines.
|
||||
*/
|
||||
// JY removed
|
||||
//#define POLARSSL_NET_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_PADLOCK_C
|
||||
*
|
||||
* Enable VIA Padlock support on x86.
|
||||
*
|
||||
* Module: library/padlock.c
|
||||
* Caller: library/aes.c
|
||||
*
|
||||
* This modules adds support for the VIA PadLock on x86.
|
||||
*/
|
||||
// JY removed
|
||||
//#define POLARSSL_PADLOCK_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_PBKDF2_C
|
||||
*
|
||||
* Enable PKCS#5 PBKDF2 key derivation function
|
||||
* DEPRECATED: Use POLARSSL_PKCS5_C instead
|
||||
*
|
||||
* Module: library/pbkdf2.c
|
||||
*
|
||||
* Requires: POLARSSL_PKCS5_C
|
||||
*
|
||||
* This module adds support for the PKCS#5 PBKDF2 key derivation function.
|
||||
#define POLARSSL_PBKDF2_C
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def POLARSSL_PEM_C
|
||||
*
|
||||
* Enable PEM decoding
|
||||
*
|
||||
* Module: library/pem.c
|
||||
* Caller: library/x509parse.c
|
||||
*
|
||||
* Requires: POLARSSL_BASE64_C
|
||||
*
|
||||
* This modules adds support for decoding PEM files.
|
||||
*/
|
||||
#define POLARSSL_PEM_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_PKCS5_C
|
||||
*
|
||||
* Enable PKCS#5 functions
|
||||
*
|
||||
* Module: library/pkcs5.c
|
||||
*
|
||||
* Requires: POLARSSL_MD_C
|
||||
*
|
||||
* This module adds support for the PKCS#5 functions.
|
||||
*/
|
||||
#define POLARSSL_PKCS5_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_PKCS11_C
|
||||
*
|
||||
* Enable wrapper for PKCS#11 smartcard support.
|
||||
*
|
||||
* Module: library/ssl_srv.c
|
||||
* Caller: library/ssl_cli.c
|
||||
* library/ssl_srv.c
|
||||
*
|
||||
* Requires: POLARSSL_SSL_TLS_C
|
||||
*
|
||||
* This module enables SSL/TLS PKCS #11 smartcard support.
|
||||
* Requires the presence of the PKCS#11 helper library (libpkcs11-helper)
|
||||
#define POLARSSL_PKCS11_C
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def POLARSSL_PKCS12_C
|
||||
*
|
||||
* Enable PKCS#12 PBE functions
|
||||
* Adds algorithms for parsing PKCS#8 encrypted private keys
|
||||
*
|
||||
* Module: library/pkcs12.c
|
||||
* Caller: library/x509parse.c
|
||||
*
|
||||
* Requires: POLARSSL_ASN1_PARSE_C
|
||||
* Can use: POLARSSL_SHA1_C, POLARSSL_DES_C, POLARSSL_ARC4_C
|
||||
*
|
||||
* This module enables PKCS#12 functions.
|
||||
*/
|
||||
#define POLARSSL_PKCS12_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_RSA_C
|
||||
*
|
||||
* Enable the RSA public-key cryptosystem.
|
||||
*
|
||||
* Module: library/rsa.c
|
||||
* Caller: library/ssl_cli.c
|
||||
* library/ssl_srv.c
|
||||
* library/ssl_tls.c
|
||||
* library/x509.c
|
||||
*
|
||||
* Requires: POLARSSL_BIGNUM_C
|
||||
*
|
||||
* This module is required for SSL/TLS and MD5-signed certificates.
|
||||
*/
|
||||
#define POLARSSL_RSA_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_SHA1_C
|
||||
*
|
||||
* Enable the SHA1 cryptographic hash algorithm.
|
||||
*
|
||||
* Module: library/sha1.c
|
||||
* Caller: library/ssl_cli.c
|
||||
* library/ssl_srv.c
|
||||
* library/ssl_tls.c
|
||||
* library/x509parse.c
|
||||
*
|
||||
* This module is required for SSL/TLS and SHA1-signed certificates.
|
||||
*/
|
||||
#define POLARSSL_SHA1_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_SHA2_C
|
||||
*
|
||||
* Enable the SHA-224 and SHA-256 cryptographic hash algorithms.
|
||||
*
|
||||
* Module: library/sha2.c
|
||||
* Caller: library/md_wrap.c
|
||||
* library/x509parse.c
|
||||
*
|
||||
* This module adds support for SHA-224 and SHA-256.
|
||||
* This module is required for the SSL/TLS 1.2 PRF function.
|
||||
*/
|
||||
#define POLARSSL_SHA2_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_SHA4_C
|
||||
*
|
||||
* Enable the SHA-384 and SHA-512 cryptographic hash algorithms.
|
||||
*
|
||||
* Module: library/sha4.c
|
||||
* Caller: library/md_wrap.c
|
||||
* library/x509parse.c
|
||||
*
|
||||
* This module adds support for SHA-384 and SHA-512.
|
||||
*/
|
||||
#define POLARSSL_SHA4_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_SSL_CACHE_C
|
||||
*
|
||||
* Enable simple SSL cache implementation.
|
||||
*
|
||||
* Module: library/ssl_cache.c
|
||||
* Caller:
|
||||
*
|
||||
* Requires: POLARSSL_SSL_CACHE_C
|
||||
*/
|
||||
// JY removed
|
||||
//#define POLARSSL_SSL_CACHE_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_SSL_CLI_C
|
||||
*
|
||||
* Enable the SSL/TLS client code.
|
||||
*
|
||||
* Module: library/ssl_cli.c
|
||||
* Caller:
|
||||
*
|
||||
* Requires: POLARSSL_SSL_TLS_C
|
||||
*
|
||||
* This module is required for SSL/TLS client support.
|
||||
*/
|
||||
#define POLARSSL_SSL_CLI_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_SSL_SRV_C
|
||||
*
|
||||
* Enable the SSL/TLS server code.
|
||||
*
|
||||
* Module: library/ssl_srv.c
|
||||
* Caller:
|
||||
*
|
||||
* Requires: POLARSSL_SSL_TLS_C
|
||||
*
|
||||
* This module is required for SSL/TLS server support.
|
||||
*/
|
||||
// JY removed
|
||||
//#define POLARSSL_SSL_SRV_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_SSL_TLS_C
|
||||
*
|
||||
* Enable the generic SSL/TLS code.
|
||||
*
|
||||
* Module: library/ssl_tls.c
|
||||
* Caller: library/ssl_cli.c
|
||||
* library/ssl_srv.c
|
||||
*
|
||||
* Requires: POLARSSL_MD5_C, POLARSSL_SHA1_C, POLARSSL_X509_PARSE_C
|
||||
*
|
||||
* This module is required for SSL/TLS.
|
||||
*/
|
||||
#define POLARSSL_SSL_TLS_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_TIMING_C
|
||||
*
|
||||
* Enable the portable timing interface.
|
||||
*
|
||||
* Module: library/timing.c
|
||||
* Caller: library/havege.c
|
||||
*
|
||||
* This module is used by the HAVEGE random number generator.
|
||||
*/
|
||||
// JY removed
|
||||
//#define POLARSSL_TIMING_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_VERSION_C
|
||||
*
|
||||
* Enable run-time version information.
|
||||
*
|
||||
* Module: library/version.c
|
||||
*
|
||||
* This module provides run-time version information.
|
||||
*/
|
||||
#define POLARSSL_VERSION_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_X509_PARSE_C
|
||||
*
|
||||
* Enable X.509 certificate parsing.
|
||||
*
|
||||
* Module: library/x509parse.c
|
||||
* Caller: library/ssl_cli.c
|
||||
* library/ssl_srv.c
|
||||
* library/ssl_tls.c
|
||||
*
|
||||
* Requires: POLARSSL_ASN1_PARSE_C, POLARSSL_BIGNUM_C, POLARSSL_RSA_C
|
||||
*
|
||||
* This module is required for X.509 certificate parsing.
|
||||
*/
|
||||
#define POLARSSL_X509_PARSE_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_X509_WRITE_C
|
||||
*
|
||||
* Enable X.509 buffer writing.
|
||||
*
|
||||
* Module: library/x509write.c
|
||||
*
|
||||
* Requires: POLARSSL_BIGNUM_C, POLARSSL_RSA_C
|
||||
*
|
||||
* This module is required for X.509 certificate request writing.
|
||||
*/
|
||||
// JY removed
|
||||
//#define POLARSSL_X509_WRITE_C
|
||||
|
||||
/**
|
||||
* \def POLARSSL_XTEA_C
|
||||
*
|
||||
* Enable the XTEA block cipher.
|
||||
*
|
||||
* Module: library/xtea.c
|
||||
* Caller:
|
||||
*/
|
||||
// JY removed
|
||||
//#define POLARSSL_XTEA_C
|
||||
/* \} name */
|
||||
|
||||
// JY added
|
||||
#define POLARSSL_BLOWFISH_NAME "BF"
|
||||
#define POLARSSL_BLOWFISH_DEFAULT_KEY_LEN 128
|
||||
|
||||
#endif /* config.h */
|
||||
16
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/crypto-alt.txt
Normal file
16
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/crypto-alt.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
This patch (against PolarSSL 1.2.7) allows alternative crypto
|
||||
implementations to be compiled, without actually defining
|
||||
such implementations.
|
||||
|
||||
* define POLARSSL_AES_ALT to include alternative AES implementation
|
||||
from polarssl/aes_alt.h
|
||||
|
||||
* define POLARSSL_SHA1_ALT to include alternative SHA1 implementation
|
||||
from polarssl/sha1_alt.h
|
||||
|
||||
* define POLARSSL_SHA2_ALT to include alternative SHA2 implementation
|
||||
from polarssl/sha2_alt.h
|
||||
|
||||
* define POLARSSL_SHA4_ALT to include alternative SHA4 implementation
|
||||
from polarssl/sha4_alt.h
|
||||
|
||||
12
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/dhm.patch
Normal file
12
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/dhm.patch
Normal file
@@ -0,0 +1,12 @@
|
||||
diff -ur polarssl-1.3.4/library/dhm.c polarssl.new/library/dhm.c
|
||||
--- polarssl-1.3.4/library/dhm.c 2014-01-27 05:36:23.000000000 -0700
|
||||
+++ polarssl.new/library/dhm.c 2014-03-02 14:47:02.000000000 -0700
|
||||
@@ -32,6 +32,8 @@
|
||||
|
||||
#if defined(POLARSSL_DHM_C)
|
||||
|
||||
+#include "polarssl/x509.h" // for POLARSSL_ERR_X509_FEATURE_UNAVAILABLE
|
||||
+
|
||||
#include "polarssl/dhm.h"
|
||||
|
||||
#if defined(POLARSSL_PEM_PARSE_C)
|
||||
@@ -0,0 +1,12 @@
|
||||
diff -ur polarssl-1.3.8.orig/library/entropy.c polarssl-1.3.8/library/entropy.c
|
||||
--- polarssl-1.3.8.orig/library/entropy.c 2014-07-09 03:34:48.000000000 -0600
|
||||
+++ polarssl-1.3.8/library/entropy.c 2014-07-09 16:27:06.000000000 -0600
|
||||
@@ -34,7 +34,7 @@
|
||||
#include "polarssl/entropy.h"
|
||||
#include "polarssl/entropy_poll.h"
|
||||
|
||||
-#if defined(POLARSSL_FS_IO)
|
||||
+#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
9
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/gitar
Executable file
9
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/gitar
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
. $O3/core/deps/lib-versions
|
||||
rm -rf gitar.tmp
|
||||
mkdir gitar.tmp
|
||||
cd gitar.tmp
|
||||
git clone https://github.com/polarssl/polarssl.git -b $POLARSSL_VERSION $POLARSSL_VERSION
|
||||
tar cfz $DL/$POLARSSL_VERSION-gpl.tgz $POLARSSL_VERSION
|
||||
cd ..
|
||||
rm -rf gitar.tmp
|
||||
22
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/intel_cpu.c
Normal file
22
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/intel_cpu.c
Normal file
@@ -0,0 +1,22 @@
|
||||
#if defined(_WIN32)
|
||||
typedef unsigned __int64 IA32CAP;
|
||||
#else
|
||||
typedef unsigned long long IA32CAP;
|
||||
#endif
|
||||
|
||||
IA32CAP OPENSSL_ia32_cpuid(void);
|
||||
|
||||
unsigned int OPENSSL_ia32cap_P[2]; // GLOBAL
|
||||
|
||||
void OPENSSL_cpuid_setup(void)
|
||||
{
|
||||
const IA32CAP vec = OPENSSL_ia32_cpuid();
|
||||
|
||||
/*
|
||||
* |(1<<10) sets a reserved bit to signal that variable
|
||||
* was initialized already... This is to avoid interference
|
||||
* with cpuid snippets in ELF .init segment.
|
||||
*/
|
||||
OPENSSL_ia32cap_P[0] = (unsigned int)vec|(1<<10);
|
||||
OPENSSL_ia32cap_P[1] = (unsigned int)(vec>>32);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
# this one is important
|
||||
SET(CMAKE_SYSTEM_NAME Linux)
|
||||
#this one not so much
|
||||
SET(CMAKE_SYSTEM_VERSION 1)
|
||||
|
||||
# specify the cross compiler
|
||||
SET(CMAKE_C_COMPILER arm-linux-gnueabi-gcc-4.6)
|
||||
SET(CMAKE_CXX_COMPILER arm-linux-gnueabi-g++-4.6)
|
||||
|
||||
# where is the target environment
|
||||
#SET(CMAKE_FIND_ROOT_PATH /opt/eldk-2007-01-19/ppc_74xx /home/alex/eldk-ppc74xx-inst)
|
||||
|
||||
# search for programs in the build host directories
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
# for libraries and headers in the target directories
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
@@ -0,0 +1,782 @@
|
||||
diff -uNr polarssl-1.2.7/include/polarssl/aes.h polarssl.new/include/polarssl/aes.h
|
||||
--- polarssl-1.2.7/include/polarssl/aes.h 2013-04-13 03:56:17.000000000 -0600
|
||||
+++ polarssl.new/include/polarssl/aes.h 2013-06-07 17:43:56.000000000 -0600
|
||||
@@ -29,6 +29,8 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
+#include "config.h"
|
||||
+
|
||||
#ifdef _MSC_VER
|
||||
#include <basetsd.h>
|
||||
typedef UINT32 uint32_t;
|
||||
@@ -42,6 +44,12 @@
|
||||
#define POLARSSL_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */
|
||||
#define POLARSSL_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */
|
||||
|
||||
+#ifdef POLARSSL_AES_ALT
|
||||
+
|
||||
+#include "polarssl/aes_alt.h"
|
||||
+
|
||||
+#else
|
||||
+
|
||||
/**
|
||||
* \brief AES context structure
|
||||
*/
|
||||
@@ -169,6 +177,17 @@
|
||||
unsigned char stream_block[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+#endif /* POLARSSL_AES_ALT */
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
diff -uNr polarssl-1.2.7/include/polarssl/aes_alt.h polarssl.new/include/polarssl/aes_alt.h
|
||||
--- polarssl-1.2.7/include/polarssl/aes_alt.h 1969-12-31 17:00:00.000000000 -0700
|
||||
+++ polarssl.new/include/polarssl/aes_alt.h 2013-06-07 18:18:37.000000000 -0600
|
||||
@@ -0,0 +1,183 @@
|
||||
+/*
|
||||
+ * Use OpenSSL implementation of AES methods to get asm and hardware acceleration.
|
||||
+ * Don't include this file directly, it is included by aes.h when
|
||||
+ * POLARSSL_AES_ALT is defined.
|
||||
+ */
|
||||
+
|
||||
+#ifdef _MSC_VER
|
||||
+#include <basetsd.h>
|
||||
+typedef UINT32 uint32_t;
|
||||
+#else
|
||||
+#include <inttypes.h>
|
||||
+#endif
|
||||
+
|
||||
+#define OPENSSL_AES_BLOCK_SIZE 16
|
||||
+#define OPENSSL_AES_MAXNR 14
|
||||
+
|
||||
+/**
|
||||
+ * \brief AES context structure
|
||||
+ */
|
||||
+typedef struct
|
||||
+{
|
||||
+ uint32_t rd_key[4 * (OPENSSL_AES_MAXNR + 1)];
|
||||
+ int rounds;
|
||||
+}
|
||||
+aes_context;
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
+#if defined(POLARSSL_USE_OPENSSL_AES_NI)
|
||||
+
|
||||
+int aesni_set_encrypt_key(const unsigned char *userKey, const int bits,
|
||||
+ aes_context *key);
|
||||
+int aesni_set_decrypt_key(const unsigned char *userKey, const int bits,
|
||||
+ aes_context *key);
|
||||
+void aesni_ecb_encrypt(const unsigned char *in, unsigned char *out,
|
||||
+ size_t length, const aes_context *key, const int enc);
|
||||
+void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||
+ size_t length, const aes_context *key,
|
||||
+ unsigned char *ivec, const int enc);
|
||||
+
|
||||
+#define OPENSSL_AES_SET_ENCRYPT_KEY(k,b,c) aesni_set_encrypt_key(k,b,c)
|
||||
+#define OPENSSL_AES_SET_DECRYPT_KEY(k,b,c) aesni_set_decrypt_key(k,b,c)
|
||||
+#define OPENSSL_AES_ECB_ENCRYPT(i,o,k) aesni_ecb_encrypt(i,o,16,k,AES_ENCRYPT)
|
||||
+#define OPENSSL_AES_ECB_DECRYPT(i,o,k) aesni_ecb_encrypt(i,o,16,k,AES_DECRYPT)
|
||||
+#define OPENSSL_AES_CBC_ENCRYPT(i,o,l,k,iv,e) aesni_cbc_encrypt(i,o,l,k,iv,e)
|
||||
+
|
||||
+#else
|
||||
+
|
||||
+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
|
||||
+ aes_context *key);
|
||||
+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
|
||||
+ aes_context *key);
|
||||
+
|
||||
+void AES_encrypt(const unsigned char *in, unsigned char *out, const aes_context *key);
|
||||
+void AES_decrypt(const unsigned char *in, unsigned char *out, const aes_context *key);
|
||||
+
|
||||
+
|
||||
+#define OPENSSL_AES_SET_ENCRYPT_KEY(k,b,c) AES_set_encrypt_key(k,b,c)
|
||||
+#define OPENSSL_AES_SET_DECRYPT_KEY(k,b,c) AES_set_decrypt_key(k,b,c)
|
||||
+#define OPENSSL_AES_ECB_ENCRYPT(i,o,k) AES_encrypt(i,o,k)
|
||||
+#define OPENSSL_AES_ECB_DECRYPT(i,o,k) AES_decrypt(i,o,k)
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
+/**
|
||||
+ * \brief AES key schedule (encryption)
|
||||
+ *
|
||||
+ * \param ctx AES context to be initialized
|
||||
+ * \param key encryption key
|
||||
+ * \param keysize must be 128, 192 or 256
|
||||
+ *
|
||||
+ * \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
|
||||
+ */
|
||||
+static inline int aes_setkey_enc( aes_context *ctx, const unsigned char *key, const unsigned int keysize )
|
||||
+{
|
||||
+ const int status = OPENSSL_AES_SET_ENCRYPT_KEY(key, keysize, ctx);
|
||||
+ return status ? POLARSSL_ERR_AES_INVALID_KEY_LENGTH : 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * \brief AES key schedule (decryption)
|
||||
+ *
|
||||
+ * \param ctx AES context to be initialized
|
||||
+ * \param key decryption key
|
||||
+ * \param keysize must be 128, 192 or 256
|
||||
+ *
|
||||
+ * \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
|
||||
+ */
|
||||
+static inline int aes_setkey_dec( aes_context *ctx, const unsigned char *key, const unsigned int keysize )
|
||||
+{
|
||||
+ const int status = OPENSSL_AES_SET_DECRYPT_KEY(key, keysize, ctx);
|
||||
+ return status ? POLARSSL_ERR_AES_INVALID_KEY_LENGTH : 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * \brief AES-ECB block encryption/decryption
|
||||
+ *
|
||||
+ * \param ctx AES context
|
||||
+ * \param mode AES_ENCRYPT or AES_DECRYPT
|
||||
+ * \param input 16-byte input block
|
||||
+ * \param output 16-byte output block
|
||||
+ *
|
||||
+ * \return 0 if successful
|
||||
+ */
|
||||
+static inline int aes_crypt_ecb( aes_context *ctx,
|
||||
+ const int mode,
|
||||
+ const unsigned char input[16],
|
||||
+ unsigned char output[16] )
|
||||
+{
|
||||
+ if (mode == AES_DECRYPT)
|
||||
+ OPENSSL_AES_ECB_DECRYPT(input, output, ctx);
|
||||
+ else
|
||||
+ OPENSSL_AES_ECB_ENCRYPT(input, output, ctx);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * \brief AES-CBC buffer encryption/decryption
|
||||
+ * Length should be a multiple of the block
|
||||
+ * size (16 bytes)
|
||||
+ *
|
||||
+ * \param ctx AES context
|
||||
+ * \param mode AES_ENCRYPT or AES_DECRYPT
|
||||
+ * \param length length of the input data
|
||||
+ * \param iv initialization vector (updated after use)
|
||||
+ * \param input buffer holding the input data
|
||||
+ * \param output buffer holding the output data
|
||||
+ *
|
||||
+ * \return 0 if successful, or POLARSSL_ERR_AES_INVALID_INPUT_LENGTH
|
||||
+ */
|
||||
+static inline int aes_crypt_cbc( aes_context *ctx,
|
||||
+ const int mode,
|
||||
+ size_t length,
|
||||
+ unsigned char iv[16],
|
||||
+ const unsigned char *input,
|
||||
+ unsigned char *output )
|
||||
+{
|
||||
+#ifdef OPENSSL_AES_CBC_ENCRYPT
|
||||
+ if (length & (OPENSSL_AES_BLOCK_SIZE-1))
|
||||
+ return POLARSSL_ERR_AES_INVALID_INPUT_LENGTH;
|
||||
+ OPENSSL_AES_CBC_ENCRYPT(input, output, length, ctx, iv, mode);
|
||||
+ return 0;
|
||||
+#else
|
||||
+ int i;
|
||||
+ unsigned char temp[16];
|
||||
+ if (length & (OPENSSL_AES_BLOCK_SIZE-1))
|
||||
+ return POLARSSL_ERR_AES_INVALID_INPUT_LENGTH;
|
||||
+ if( mode == AES_DECRYPT )
|
||||
+ {
|
||||
+ while( length > 0 )
|
||||
+ {
|
||||
+ memcpy( temp, input, 16 );
|
||||
+ OPENSSL_AES_ECB_DECRYPT(input, output, ctx);
|
||||
+ for( i = 0; i < 16; i++ )
|
||||
+ output[i] = (unsigned char)( output[i] ^ iv[i] );
|
||||
+ memcpy( iv, temp, 16 );
|
||||
+ input += 16;
|
||||
+ output += 16;
|
||||
+ length -= 16;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ while( length > 0 )
|
||||
+ {
|
||||
+ for( i = 0; i < 16; i++ )
|
||||
+ output[i] = (unsigned char)( input[i] ^ iv[i] );
|
||||
+ OPENSSL_AES_ECB_ENCRYPT(output, output, ctx);
|
||||
+ memcpy( iv, output, 16 );
|
||||
+ input += 16;
|
||||
+ output += 16;
|
||||
+ length -= 16;
|
||||
+ }
|
||||
+ }
|
||||
+ return( 0 );
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
diff -uNr polarssl-1.2.7/include/polarssl/sha1.h polarssl.new/include/polarssl/sha1.h
|
||||
--- polarssl-1.2.7/include/polarssl/sha1.h 2013-04-13 03:56:17.000000000 -0600
|
||||
+++ polarssl.new/include/polarssl/sha1.h 2013-06-07 17:43:56.000000000 -0600
|
||||
@@ -29,6 +29,8 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
+#include "config.h"
|
||||
+
|
||||
#ifdef _MSC_VER
|
||||
#include <basetsd.h>
|
||||
typedef UINT32 uint32_t;
|
||||
@@ -38,6 +40,12 @@
|
||||
|
||||
#define POLARSSL_ERR_SHA1_FILE_IO_ERROR -0x0076 /**< Read/write error in file. */
|
||||
|
||||
+#ifdef POLARSSL_SHA1_ALT
|
||||
+
|
||||
+#include "polarssl/sha1_alt.h"
|
||||
+
|
||||
+#else
|
||||
+
|
||||
/**
|
||||
* \brief SHA-1 context structure
|
||||
*/
|
||||
@@ -80,6 +88,19 @@
|
||||
*/
|
||||
void sha1_finish( sha1_context *ctx, unsigned char output[20] );
|
||||
|
||||
+/* Internal use */
|
||||
+void sha1_process( sha1_context *ctx, const unsigned char data[64] );
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+#endif /* POLARSSL_SHA1_ALT */
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
/**
|
||||
* \brief Output = SHA-1( input buffer )
|
||||
*
|
||||
@@ -152,9 +173,6 @@
|
||||
*/
|
||||
int sha1_self_test( int verbose );
|
||||
|
||||
-/* Internal use */
|
||||
-void sha1_process( sha1_context *ctx, const unsigned char data[64] );
|
||||
-
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
diff -uNr polarssl-1.2.7/include/polarssl/sha1_alt.h polarssl.new/include/polarssl/sha1_alt.h
|
||||
--- polarssl-1.2.7/include/polarssl/sha1_alt.h 1969-12-31 17:00:00.000000000 -0700
|
||||
+++ polarssl.new/include/polarssl/sha1_alt.h 2013-06-07 17:43:56.000000000 -0600
|
||||
@@ -0,0 +1,56 @@
|
||||
+/*
|
||||
+ * Use OpenSSL implementation of SHA1 methods to get asm and hardware acceleration.
|
||||
+ * Don't include this file directly, it is included by sha1.h when
|
||||
+ * POLARSSL_SHA1_ALT is defined.
|
||||
+ */
|
||||
+
|
||||
+#include "polarssl/sha_openssl.h"
|
||||
+
|
||||
+struct openssl_sha_context {
|
||||
+ SHA_LONG h0,h1,h2,h3,h4;
|
||||
+ SHA_LONG Nl,Nh;
|
||||
+ SHA_LONG data[SHA_LBLOCK];
|
||||
+ unsigned int num;
|
||||
+};
|
||||
+
|
||||
+typedef struct
|
||||
+{
|
||||
+ struct openssl_sha_context octx;
|
||||
+
|
||||
+ unsigned char ipad[64]; /*!< HMAC: inner padding */
|
||||
+ unsigned char opad[64]; /*!< HMAC: outer padding */
|
||||
+}
|
||||
+sha1_context;
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
+int SHA1_Init(struct openssl_sha_context *c);
|
||||
+int SHA1_Update(struct openssl_sha_context *c, const void *data, size_t len);
|
||||
+int SHA1_Final(unsigned char *md, struct openssl_sha_context *c);
|
||||
+void sha1_block_data_order(struct openssl_sha_context *c, const void *p, size_t num);
|
||||
+
|
||||
+static inline void sha1_starts( sha1_context *ctx )
|
||||
+{
|
||||
+ SHA1_Init(&ctx->octx);
|
||||
+}
|
||||
+
|
||||
+static inline void sha1_update( sha1_context *ctx, const unsigned char *input, size_t ilen )
|
||||
+{
|
||||
+ SHA1_Update(&ctx->octx, input, ilen);
|
||||
+}
|
||||
+
|
||||
+static inline void sha1_finish( sha1_context *ctx, unsigned char output[20] )
|
||||
+{
|
||||
+ SHA1_Final(output, &ctx->octx);
|
||||
+}
|
||||
+
|
||||
+static inline void sha1_process( sha1_context *ctx, const unsigned char data[64] )
|
||||
+{
|
||||
+ sha1_block_data_order(&ctx->octx, data, 1);
|
||||
+}
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
diff -uNr polarssl-1.2.7/include/polarssl/sha2.h polarssl.new/include/polarssl/sha2.h
|
||||
--- polarssl-1.2.7/include/polarssl/sha2.h 2013-04-13 03:56:17.000000000 -0600
|
||||
+++ polarssl.new/include/polarssl/sha2.h 2013-06-07 17:43:56.000000000 -0600
|
||||
@@ -29,6 +29,8 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
+#include "config.h"
|
||||
+
|
||||
#ifdef _MSC_VER
|
||||
#include <basetsd.h>
|
||||
typedef UINT32 uint32_t;
|
||||
@@ -38,6 +40,12 @@
|
||||
|
||||
#define POLARSSL_ERR_SHA2_FILE_IO_ERROR -0x0078 /**< Read/write error in file. */
|
||||
|
||||
+#ifdef POLARSSL_SHA2_ALT
|
||||
+
|
||||
+#include "polarssl/sha2_alt.h"
|
||||
+
|
||||
+#else
|
||||
+
|
||||
/**
|
||||
* \brief SHA-256 context structure
|
||||
*/
|
||||
@@ -82,6 +90,19 @@
|
||||
*/
|
||||
void sha2_finish( sha2_context *ctx, unsigned char output[32] );
|
||||
|
||||
+/* Internal use */
|
||||
+void sha2_process( sha2_context *ctx, const unsigned char data[64] );
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+#endif /* POLARSSL_SHA2_ALT */
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
/**
|
||||
* \brief Output = SHA-256( input buffer )
|
||||
*
|
||||
@@ -160,9 +181,6 @@
|
||||
*/
|
||||
int sha2_self_test( int verbose );
|
||||
|
||||
-/* Internal use */
|
||||
-void sha2_process( sha2_context *ctx, const unsigned char data[64] );
|
||||
-
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
diff -uNr polarssl-1.2.7/include/polarssl/sha2_alt.h polarssl.new/include/polarssl/sha2_alt.h
|
||||
--- polarssl-1.2.7/include/polarssl/sha2_alt.h 1969-12-31 17:00:00.000000000 -0700
|
||||
+++ polarssl.new/include/polarssl/sha2_alt.h 2013-06-07 17:43:56.000000000 -0600
|
||||
@@ -0,0 +1,71 @@
|
||||
+/*
|
||||
+ * Use OpenSSL implementation of SHA2 methods to get asm and hardware acceleration.
|
||||
+ * Don't include this file directly, it is included by sha2.h when
|
||||
+ * POLARSSL_SHA2_ALT is defined.
|
||||
+ */
|
||||
+
|
||||
+#include "polarssl/sha_openssl.h"
|
||||
+
|
||||
+struct openssl_sha2_context {
|
||||
+ SHA_LONG h[8];
|
||||
+ SHA_LONG Nl,Nh;
|
||||
+ SHA_LONG data[SHA_LBLOCK];
|
||||
+ unsigned int num,md_len;
|
||||
+};
|
||||
+
|
||||
+typedef struct
|
||||
+{
|
||||
+ struct openssl_sha2_context octx;
|
||||
+
|
||||
+ unsigned char ipad[64]; /*!< HMAC: inner padding */
|
||||
+ unsigned char opad[64]; /*!< HMAC: outer padding */
|
||||
+ int is224; /*!< 0 => SHA-256, else SHA-224 */
|
||||
+}
|
||||
+sha2_context;
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
+int SHA224_Init(struct openssl_sha2_context *c);
|
||||
+int SHA224_Update(struct openssl_sha2_context *c, const void *data, size_t len);
|
||||
+int SHA224_Final(unsigned char *md, struct openssl_sha2_context *c);
|
||||
+
|
||||
+int SHA256_Init(struct openssl_sha2_context *c);
|
||||
+int SHA256_Update(struct openssl_sha2_context *c, const void *data, size_t len);
|
||||
+int SHA256_Final(unsigned char *md, struct openssl_sha2_context *c);
|
||||
+
|
||||
+void sha256_block_data_order(struct openssl_sha2_context *c, const void *p, size_t num);
|
||||
+
|
||||
+static inline void sha2_starts( sha2_context *ctx, int is224 )
|
||||
+{
|
||||
+ if ((ctx->is224 = is224))
|
||||
+ SHA224_Init(&ctx->octx);
|
||||
+ else
|
||||
+ SHA256_Init(&ctx->octx);
|
||||
+}
|
||||
+
|
||||
+static inline void sha2_update( sha2_context *ctx, const unsigned char *input, size_t ilen )
|
||||
+{
|
||||
+ if (ctx->is224)
|
||||
+ SHA224_Update(&ctx->octx, input, ilen);
|
||||
+ else
|
||||
+ SHA256_Update(&ctx->octx, input, ilen);
|
||||
+}
|
||||
+
|
||||
+static inline void sha2_finish( sha2_context *ctx, unsigned char output[32] )
|
||||
+{
|
||||
+ if (ctx->is224)
|
||||
+ SHA224_Final(output, &ctx->octx);
|
||||
+ else
|
||||
+ SHA256_Final(output, &ctx->octx);
|
||||
+}
|
||||
+
|
||||
+static inline void sha2_process( sha2_context *ctx, const unsigned char data[64] )
|
||||
+{
|
||||
+ sha256_block_data_order(&ctx->octx, data, 1);
|
||||
+}
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
diff -uNr polarssl-1.2.7/include/polarssl/sha4.h polarssl.new/include/polarssl/sha4.h
|
||||
--- polarssl-1.2.7/include/polarssl/sha4.h 2013-04-13 03:56:17.000000000 -0600
|
||||
+++ polarssl.new/include/polarssl/sha4.h 2013-06-07 17:43:56.000000000 -0600
|
||||
@@ -29,6 +29,8 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
+#include "config.h"
|
||||
+
|
||||
#if defined(_MSC_VER) || defined(__WATCOMC__)
|
||||
#define UL64(x) x##ui64
|
||||
typedef unsigned __int64 uint64_t;
|
||||
@@ -39,6 +41,12 @@
|
||||
|
||||
#define POLARSSL_ERR_SHA4_FILE_IO_ERROR -0x007A /**< Read/write error in file. */
|
||||
|
||||
+#ifdef POLARSSL_SHA4_ALT
|
||||
+
|
||||
+#include "polarssl/sha4_alt.h"
|
||||
+
|
||||
+#else
|
||||
+
|
||||
/**
|
||||
* \brief SHA-512 context structure
|
||||
*/
|
||||
@@ -83,6 +91,16 @@
|
||||
*/
|
||||
void sha4_finish( sha4_context *ctx, unsigned char output[64] );
|
||||
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+#endif /* POLARSSL_SHA4_ALT */
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
/**
|
||||
* \brief Output = SHA-512( input buffer )
|
||||
*
|
||||
diff -uNr polarssl-1.2.7/include/polarssl/sha4_alt.h polarssl.new/include/polarssl/sha4_alt.h
|
||||
--- polarssl-1.2.7/include/polarssl/sha4_alt.h 1969-12-31 17:00:00.000000000 -0700
|
||||
+++ polarssl.new/include/polarssl/sha4_alt.h 2013-06-07 17:43:56.000000000 -0600
|
||||
@@ -0,0 +1,67 @@
|
||||
+/*
|
||||
+ * Use OpenSSL implementation of SHA4 methods to get asm and hardware acceleration.
|
||||
+ * Don't include this file directly, it is included by sha4.h when
|
||||
+ * POLARSSL_SHA4_ALT is defined.
|
||||
+ */
|
||||
+
|
||||
+#include "polarssl/sha_openssl.h"
|
||||
+
|
||||
+struct openssl_sha4_context {
|
||||
+ SHA_LONG64 h[8];
|
||||
+ SHA_LONG64 Nl,Nh;
|
||||
+ union {
|
||||
+ SHA_LONG64 d[SHA_LBLOCK];
|
||||
+ unsigned char p[SHA512_CBLOCK];
|
||||
+ } u;
|
||||
+ unsigned int num,md_len;
|
||||
+};
|
||||
+
|
||||
+typedef struct
|
||||
+{
|
||||
+ struct openssl_sha4_context octx;
|
||||
+
|
||||
+ unsigned char ipad[128]; /*!< HMAC: inner padding */
|
||||
+ unsigned char opad[128]; /*!< HMAC: outer padding */
|
||||
+ int is384; /*!< 0 => SHA-512, else SHA-384 */
|
||||
+}
|
||||
+sha4_context;
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
+int SHA384_Init(struct openssl_sha4_context *c);
|
||||
+int SHA384_Update(struct openssl_sha4_context *c, const void *data, size_t len);
|
||||
+int SHA384_Final(unsigned char *md, struct openssl_sha4_context *c);
|
||||
+
|
||||
+int SHA512_Init(struct openssl_sha4_context *c);
|
||||
+int SHA512_Update(struct openssl_sha4_context *c, const void *data, size_t len);
|
||||
+int SHA512_Final(unsigned char *md, struct openssl_sha4_context *c);
|
||||
+
|
||||
+static inline void sha4_starts( sha4_context *ctx, int is384 )
|
||||
+{
|
||||
+ if ((ctx->is384 = is384))
|
||||
+ SHA384_Init(&ctx->octx);
|
||||
+ else
|
||||
+ SHA512_Init(&ctx->octx);
|
||||
+}
|
||||
+
|
||||
+static inline void sha4_update( sha4_context *ctx, const unsigned char *input, size_t ilen )
|
||||
+{
|
||||
+ if (ctx->is384)
|
||||
+ SHA384_Update(&ctx->octx, input, ilen);
|
||||
+ else
|
||||
+ SHA512_Update(&ctx->octx, input, ilen);
|
||||
+}
|
||||
+
|
||||
+static inline void sha4_finish( sha4_context *ctx, unsigned char output[64] )
|
||||
+{
|
||||
+ if (ctx->is384)
|
||||
+ SHA384_Final(output, &ctx->octx);
|
||||
+ else
|
||||
+ SHA512_Final(output, &ctx->octx);
|
||||
+}
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
diff -uNr polarssl-1.2.7/include/polarssl/sha_openssl.h polarssl.new/include/polarssl/sha_openssl.h
|
||||
--- polarssl-1.2.7/include/polarssl/sha_openssl.h 1969-12-31 17:00:00.000000000 -0700
|
||||
+++ polarssl.new/include/polarssl/sha_openssl.h 2013-06-07 17:43:56.000000000 -0600
|
||||
@@ -0,0 +1,42 @@
|
||||
+/*
|
||||
+ * Common header file for all OpenSSL-imported SHA methods
|
||||
+ */
|
||||
+
|
||||
+#ifndef POLARSSL_SHA_OPENSSL_H
|
||||
+#define POLARSSL_SHA_OPENSSL_H
|
||||
+
|
||||
+/*
|
||||
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
+ * ! SHA_LONG has to be at least 32 bits wide. If it's wider, then !
|
||||
+ * ! SHA_LONG_LOG2 has to be defined along. !
|
||||
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
+ */
|
||||
+
|
||||
+#if defined(__LP32__)
|
||||
+#define SHA_LONG unsigned long
|
||||
+#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
|
||||
+#define SHA_LONG unsigned long
|
||||
+#define SHA_LONG_LOG2 3
|
||||
+#else
|
||||
+#define SHA_LONG unsigned int
|
||||
+#endif
|
||||
+
|
||||
+#define SHA_LBLOCK 16
|
||||
+
|
||||
+/*
|
||||
+ * Unlike 32-bit digest algorithms, SHA-512 *relies* on SHA_LONG64
|
||||
+ * being exactly 64-bit wide. See Implementation Notes in sha512.c
|
||||
+ * for further details.
|
||||
+ */
|
||||
+#define SHA512_CBLOCK (SHA_LBLOCK*8) /* SHA-512 treats input data as a
|
||||
+ * contiguous array of 64 bit
|
||||
+ * wide big-endian values. */
|
||||
+#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
|
||||
+#define SHA_LONG64 unsigned __int64
|
||||
+#elif defined(__arch64__)
|
||||
+#define SHA_LONG64 unsigned long
|
||||
+#else
|
||||
+#define SHA_LONG64 unsigned long long
|
||||
+#endif
|
||||
+
|
||||
+#endif
|
||||
diff -uNr polarssl-1.2.7/library/aes.c polarssl.new/library/aes.c
|
||||
--- polarssl-1.2.7/library/aes.c 2013-04-13 03:56:17.000000000 -0600
|
||||
+++ polarssl.new/library/aes.c 2013-06-07 17:43:56.000000000 -0600
|
||||
@@ -38,6 +38,8 @@
|
||||
#include "polarssl/padlock.h"
|
||||
#endif
|
||||
|
||||
+#ifndef POLARSSL_AES_ALT
|
||||
+
|
||||
/*
|
||||
* 32-bit integer manipulation macros (little endian)
|
||||
*/
|
||||
@@ -914,6 +916,7 @@
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* POLARSSL_CIPHER_MODE_CTR */
|
||||
+#endif /* !POLARSSL_AES_ALT */
|
||||
|
||||
#if defined(POLARSSL_SELF_TEST)
|
||||
|
||||
diff -uNr polarssl-1.2.7/library/sha1.c polarssl.new/library/sha1.c
|
||||
--- polarssl-1.2.7/library/sha1.c 2013-04-13 03:56:17.000000000 -0600
|
||||
+++ polarssl.new/library/sha1.c 2013-06-07 17:43:56.000000000 -0600
|
||||
@@ -38,6 +38,8 @@
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
+#ifndef POLARSSL_SHA1_ALT
|
||||
+
|
||||
/*
|
||||
* 32-bit integer manipulation macros (big endian)
|
||||
*/
|
||||
@@ -313,6 +315,8 @@
|
||||
PUT_UINT32_BE( ctx->state[4], output, 16 );
|
||||
}
|
||||
|
||||
+#endif /* !POLARSSL_SHA1_ALT */
|
||||
+
|
||||
/*
|
||||
* output = SHA-1( input buffer )
|
||||
*/
|
||||
diff -uNr polarssl-1.2.7/library/sha2.c polarssl.new/library/sha2.c
|
||||
--- polarssl-1.2.7/library/sha2.c 2013-04-13 03:56:17.000000000 -0600
|
||||
+++ polarssl.new/library/sha2.c 2013-06-07 17:43:56.000000000 -0600
|
||||
@@ -38,6 +38,8 @@
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
+#ifndef POLARSSL_SHA2_ALT
|
||||
+
|
||||
/*
|
||||
* 32-bit integer manipulation macros (big endian)
|
||||
*/
|
||||
@@ -314,6 +316,8 @@
|
||||
PUT_UINT32_BE( ctx->state[7], output, 28 );
|
||||
}
|
||||
|
||||
+#endif /* !POLARSSL_SHA2_ALT */
|
||||
+
|
||||
/*
|
||||
* output = SHA-256( input buffer )
|
||||
*/
|
||||
diff -uNr polarssl-1.2.7/library/sha4.c polarssl.new/library/sha4.c
|
||||
--- polarssl-1.2.7/library/sha4.c 2013-04-13 03:56:17.000000000 -0600
|
||||
+++ polarssl.new/library/sha4.c 2013-06-07 17:43:56.000000000 -0600
|
||||
@@ -38,6 +38,8 @@
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
+#ifndef POLARSSL_SHA4_ALT
|
||||
+
|
||||
/*
|
||||
* 64-bit integer manipulation macros (big endian)
|
||||
*/
|
||||
@@ -312,6 +314,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
+#endif /* !POLARSSL_SHA4_ALT */
|
||||
+
|
||||
/*
|
||||
* output = SHA-512( input buffer )
|
||||
*/
|
||||
diff -uNr polarssl-1.2.7/library/ssl_tls.c polarssl.new/library/ssl_tls.c
|
||||
--- polarssl-1.2.7/library/ssl_tls.c 2013-04-13 03:56:17.000000000 -0600
|
||||
+++ polarssl.new/library/ssl_tls.c 2013-06-07 17:43:56.000000000 -0600
|
||||
@@ -2550,8 +2550,10 @@
|
||||
SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *)
|
||||
md5.state, sizeof( md5.state ) );
|
||||
|
||||
+#ifndef POLARSSL_SHA1_ALT
|
||||
SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *)
|
||||
sha1.state, sizeof( sha1.state ) );
|
||||
+#endif
|
||||
|
||||
sender = ( from == SSL_IS_CLIENT ) ? (char *) "CLNT"
|
||||
: (char *) "SRVR";
|
||||
@@ -2621,8 +2623,10 @@
|
||||
SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *)
|
||||
md5.state, sizeof( md5.state ) );
|
||||
|
||||
+#ifndef POLARSSL_SHA1_ALT
|
||||
SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *)
|
||||
sha1.state, sizeof( sha1.state ) );
|
||||
+#endif
|
||||
|
||||
sender = ( from == SSL_IS_CLIENT )
|
||||
? (char *) "client finished"
|
||||
@@ -2666,8 +2670,10 @@
|
||||
* Hash( handshake ) )[0.11]
|
||||
*/
|
||||
|
||||
+#ifndef POLARSSL_SHA2_ALT
|
||||
SSL_DEBUG_BUF( 4, "finished sha2 state", (unsigned char *)
|
||||
sha2.state, sizeof( sha2.state ) );
|
||||
+#endif
|
||||
|
||||
sender = ( from == SSL_IS_CLIENT )
|
||||
? (char *) "client finished"
|
||||
@@ -2710,8 +2716,10 @@
|
||||
* Hash( handshake ) )[0.11]
|
||||
*/
|
||||
|
||||
+#ifndef POLARSSL_SHA4_ALT
|
||||
SSL_DEBUG_BUF( 4, "finished sha4 state", (unsigned char *)
|
||||
sha4.state, sizeof( sha4.state ) );
|
||||
+#endif
|
||||
|
||||
sender = ( from == SSL_IS_CLIENT )
|
||||
? (char *) "client finished"
|
||||
diff -uNr polarssl-1.2.7/tests/suites/test_suite_aes.function polarssl.new/tests/suites/test_suite_aes.function
|
||||
--- polarssl-1.2.7/tests/suites/test_suite_aes.function 2013-04-13 03:56:17.000000000 -0600
|
||||
+++ polarssl.new/tests/suites/test_suite_aes.function 2013-06-07 17:43:56.000000000 -0600
|
||||
@@ -1,4 +1,5 @@
|
||||
BEGIN_HEADER
|
||||
+#include <polarssl/config.h>
|
||||
#include <polarssl/aes.h>
|
||||
END_HEADER
|
||||
|
||||
diff -uNr polarssl-1.2.7/tests/suites/test_suite_ctr_drbg.function polarssl.new/tests/suites/test_suite_ctr_drbg.function
|
||||
--- polarssl-1.2.7/tests/suites/test_suite_ctr_drbg.function 2013-04-13 03:56:17.000000000 -0600
|
||||
+++ polarssl.new/tests/suites/test_suite_ctr_drbg.function 2013-06-07 17:43:56.000000000 -0600
|
||||
@@ -1,4 +1,5 @@
|
||||
BEGIN_HEADER
|
||||
+#include <polarssl/config.h>
|
||||
#include <polarssl/ctr_drbg.h>
|
||||
|
||||
int test_offset;
|
||||
@@ -0,0 +1,446 @@
|
||||
diff -uNr polarssl-1.2.7/include/polarssl/aes_alt.h polarssl.new/include/polarssl/aes_alt.h
|
||||
--- polarssl-1.2.7/include/polarssl/aes_alt.h 1969-12-31 17:00:00.000000000 -0700
|
||||
+++ polarssl.new/include/polarssl/aes_alt.h 2013-06-07 18:18:37.000000000 -0600
|
||||
@@ -0,0 +1,183 @@
|
||||
+/*
|
||||
+ * Use OpenSSL implementation of AES methods to get asm and hardware acceleration.
|
||||
+ * Don't include this file directly, it is included by aes.h when
|
||||
+ * POLARSSL_AES_ALT is defined.
|
||||
+ */
|
||||
+
|
||||
+#ifdef _MSC_VER
|
||||
+#include <basetsd.h>
|
||||
+typedef UINT32 uint32_t;
|
||||
+#else
|
||||
+#include <inttypes.h>
|
||||
+#endif
|
||||
+
|
||||
+#define OPENSSL_AES_BLOCK_SIZE 16
|
||||
+#define OPENSSL_AES_MAXNR 14
|
||||
+
|
||||
+/**
|
||||
+ * \brief AES context structure
|
||||
+ */
|
||||
+typedef struct
|
||||
+{
|
||||
+ uint32_t rd_key[4 * (OPENSSL_AES_MAXNR + 1)];
|
||||
+ int rounds;
|
||||
+}
|
||||
+aes_context;
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
+#if defined(POLARSSL_USE_OPENSSL_AES_NI)
|
||||
+
|
||||
+int aesni_set_encrypt_key(const unsigned char *userKey, const int bits,
|
||||
+ aes_context *key);
|
||||
+int aesni_set_decrypt_key(const unsigned char *userKey, const int bits,
|
||||
+ aes_context *key);
|
||||
+void aesni_ecb_encrypt(const unsigned char *in, unsigned char *out,
|
||||
+ size_t length, const aes_context *key, const int enc);
|
||||
+void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||
+ size_t length, const aes_context *key,
|
||||
+ unsigned char *ivec, const int enc);
|
||||
+
|
||||
+#define OPENSSL_AES_SET_ENCRYPT_KEY(k,b,c) aesni_set_encrypt_key(k,b,c)
|
||||
+#define OPENSSL_AES_SET_DECRYPT_KEY(k,b,c) aesni_set_decrypt_key(k,b,c)
|
||||
+#define OPENSSL_AES_ECB_ENCRYPT(i,o,k) aesni_ecb_encrypt(i,o,16,k,AES_ENCRYPT)
|
||||
+#define OPENSSL_AES_ECB_DECRYPT(i,o,k) aesni_ecb_encrypt(i,o,16,k,AES_DECRYPT)
|
||||
+#define OPENSSL_AES_CBC_ENCRYPT(i,o,l,k,iv,e) aesni_cbc_encrypt(i,o,l,k,iv,e)
|
||||
+
|
||||
+#else
|
||||
+
|
||||
+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
|
||||
+ aes_context *key);
|
||||
+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
|
||||
+ aes_context *key);
|
||||
+
|
||||
+void AES_encrypt(const unsigned char *in, unsigned char *out, const aes_context *key);
|
||||
+void AES_decrypt(const unsigned char *in, unsigned char *out, const aes_context *key);
|
||||
+
|
||||
+
|
||||
+#define OPENSSL_AES_SET_ENCRYPT_KEY(k,b,c) AES_set_encrypt_key(k,b,c)
|
||||
+#define OPENSSL_AES_SET_DECRYPT_KEY(k,b,c) AES_set_decrypt_key(k,b,c)
|
||||
+#define OPENSSL_AES_ECB_ENCRYPT(i,o,k) AES_encrypt(i,o,k)
|
||||
+#define OPENSSL_AES_ECB_DECRYPT(i,o,k) AES_decrypt(i,o,k)
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
+/**
|
||||
+ * \brief AES key schedule (encryption)
|
||||
+ *
|
||||
+ * \param ctx AES context to be initialized
|
||||
+ * \param key encryption key
|
||||
+ * \param keysize must be 128, 192 or 256
|
||||
+ *
|
||||
+ * \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
|
||||
+ */
|
||||
+static inline int aes_setkey_enc( aes_context *ctx, const unsigned char *key, const unsigned int keysize )
|
||||
+{
|
||||
+ const int status = OPENSSL_AES_SET_ENCRYPT_KEY(key, keysize, ctx);
|
||||
+ return status ? POLARSSL_ERR_AES_INVALID_KEY_LENGTH : 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * \brief AES key schedule (decryption)
|
||||
+ *
|
||||
+ * \param ctx AES context to be initialized
|
||||
+ * \param key decryption key
|
||||
+ * \param keysize must be 128, 192 or 256
|
||||
+ *
|
||||
+ * \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
|
||||
+ */
|
||||
+static inline int aes_setkey_dec( aes_context *ctx, const unsigned char *key, const unsigned int keysize )
|
||||
+{
|
||||
+ const int status = OPENSSL_AES_SET_DECRYPT_KEY(key, keysize, ctx);
|
||||
+ return status ? POLARSSL_ERR_AES_INVALID_KEY_LENGTH : 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * \brief AES-ECB block encryption/decryption
|
||||
+ *
|
||||
+ * \param ctx AES context
|
||||
+ * \param mode AES_ENCRYPT or AES_DECRYPT
|
||||
+ * \param input 16-byte input block
|
||||
+ * \param output 16-byte output block
|
||||
+ *
|
||||
+ * \return 0 if successful
|
||||
+ */
|
||||
+static inline int aes_crypt_ecb( aes_context *ctx,
|
||||
+ const int mode,
|
||||
+ const unsigned char input[16],
|
||||
+ unsigned char output[16] )
|
||||
+{
|
||||
+ if (mode == AES_DECRYPT)
|
||||
+ OPENSSL_AES_ECB_DECRYPT(input, output, ctx);
|
||||
+ else
|
||||
+ OPENSSL_AES_ECB_ENCRYPT(input, output, ctx);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * \brief AES-CBC buffer encryption/decryption
|
||||
+ * Length should be a multiple of the block
|
||||
+ * size (16 bytes)
|
||||
+ *
|
||||
+ * \param ctx AES context
|
||||
+ * \param mode AES_ENCRYPT or AES_DECRYPT
|
||||
+ * \param length length of the input data
|
||||
+ * \param iv initialization vector (updated after use)
|
||||
+ * \param input buffer holding the input data
|
||||
+ * \param output buffer holding the output data
|
||||
+ *
|
||||
+ * \return 0 if successful, or POLARSSL_ERR_AES_INVALID_INPUT_LENGTH
|
||||
+ */
|
||||
+static inline int aes_crypt_cbc( aes_context *ctx,
|
||||
+ const int mode,
|
||||
+ size_t length,
|
||||
+ unsigned char iv[16],
|
||||
+ const unsigned char *input,
|
||||
+ unsigned char *output )
|
||||
+{
|
||||
+#ifdef OPENSSL_AES_CBC_ENCRYPT
|
||||
+ if (length & (OPENSSL_AES_BLOCK_SIZE-1))
|
||||
+ return POLARSSL_ERR_AES_INVALID_INPUT_LENGTH;
|
||||
+ OPENSSL_AES_CBC_ENCRYPT(input, output, length, ctx, iv, mode);
|
||||
+ return 0;
|
||||
+#else
|
||||
+ int i;
|
||||
+ unsigned char temp[16];
|
||||
+ if (length & (OPENSSL_AES_BLOCK_SIZE-1))
|
||||
+ return POLARSSL_ERR_AES_INVALID_INPUT_LENGTH;
|
||||
+ if( mode == AES_DECRYPT )
|
||||
+ {
|
||||
+ while( length > 0 )
|
||||
+ {
|
||||
+ memcpy( temp, input, 16 );
|
||||
+ OPENSSL_AES_ECB_DECRYPT(input, output, ctx);
|
||||
+ for( i = 0; i < 16; i++ )
|
||||
+ output[i] = (unsigned char)( output[i] ^ iv[i] );
|
||||
+ memcpy( iv, temp, 16 );
|
||||
+ input += 16;
|
||||
+ output += 16;
|
||||
+ length -= 16;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ while( length > 0 )
|
||||
+ {
|
||||
+ for( i = 0; i < 16; i++ )
|
||||
+ output[i] = (unsigned char)( input[i] ^ iv[i] );
|
||||
+ OPENSSL_AES_ECB_ENCRYPT(output, output, ctx);
|
||||
+ memcpy( iv, output, 16 );
|
||||
+ input += 16;
|
||||
+ output += 16;
|
||||
+ length -= 16;
|
||||
+ }
|
||||
+ }
|
||||
+ return( 0 );
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
diff -uNr polarssl-1.2.7/include/polarssl/sha1_alt.h polarssl.new/include/polarssl/sha1_alt.h
|
||||
--- polarssl-1.2.7/include/polarssl/sha1_alt.h 1969-12-31 17:00:00.000000000 -0700
|
||||
+++ polarssl.new/include/polarssl/sha1_alt.h 2013-06-07 17:43:56.000000000 -0600
|
||||
@@ -0,0 +1,56 @@
|
||||
+/*
|
||||
+ * Use OpenSSL implementation of SHA1 methods to get asm and hardware acceleration.
|
||||
+ * Don't include this file directly, it is included by sha1.h when
|
||||
+ * POLARSSL_SHA1_ALT is defined.
|
||||
+ */
|
||||
+
|
||||
+#include "polarssl/sha_openssl.h"
|
||||
+
|
||||
+struct openssl_sha_context {
|
||||
+ SHA_LONG h0,h1,h2,h3,h4;
|
||||
+ SHA_LONG Nl,Nh;
|
||||
+ SHA_LONG data[SHA_LBLOCK];
|
||||
+ unsigned int num;
|
||||
+};
|
||||
+
|
||||
+typedef struct
|
||||
+{
|
||||
+ struct openssl_sha_context octx;
|
||||
+
|
||||
+ unsigned char ipad[64]; /*!< HMAC: inner padding */
|
||||
+ unsigned char opad[64]; /*!< HMAC: outer padding */
|
||||
+}
|
||||
+sha1_context;
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
+int SHA1_Init(struct openssl_sha_context *c);
|
||||
+int SHA1_Update(struct openssl_sha_context *c, const void *data, size_t len);
|
||||
+int SHA1_Final(unsigned char *md, struct openssl_sha_context *c);
|
||||
+void sha1_block_data_order(struct openssl_sha_context *c, const void *p, size_t num);
|
||||
+
|
||||
+static inline void sha1_starts( sha1_context *ctx )
|
||||
+{
|
||||
+ SHA1_Init(&ctx->octx);
|
||||
+}
|
||||
+
|
||||
+static inline void sha1_update( sha1_context *ctx, const unsigned char *input, size_t ilen )
|
||||
+{
|
||||
+ SHA1_Update(&ctx->octx, input, ilen);
|
||||
+}
|
||||
+
|
||||
+static inline void sha1_finish( sha1_context *ctx, unsigned char output[20] )
|
||||
+{
|
||||
+ SHA1_Final(output, &ctx->octx);
|
||||
+}
|
||||
+
|
||||
+static inline void sha1_process( sha1_context *ctx, const unsigned char data[64] )
|
||||
+{
|
||||
+ sha1_block_data_order(&ctx->octx, data, 1);
|
||||
+}
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
diff -uNr polarssl-1.2.7/include/polarssl/sha256_alt.h polarssl.new/include/polarssl/sha256_alt.h
|
||||
--- polarssl-1.2.7/include/polarssl/sha256_alt.h 1969-12-31 17:00:00.000000000 -0700
|
||||
+++ polarssl.new/include/polarssl/sha256_alt.h 2013-06-07 17:43:56.000000000 -0600
|
||||
@@ -0,0 +1,71 @@
|
||||
+/*
|
||||
+ * Use OpenSSL implementation of SHA256 methods to get asm and hardware acceleration.
|
||||
+ * Don't include this file directly, it is included by sha256.h when
|
||||
+ * POLARSSL_SHA256_ALT is defined.
|
||||
+ */
|
||||
+
|
||||
+#include "polarssl/sha_openssl.h"
|
||||
+
|
||||
+struct openssl_sha256_context {
|
||||
+ SHA_LONG h[8];
|
||||
+ SHA_LONG Nl,Nh;
|
||||
+ SHA_LONG data[SHA_LBLOCK];
|
||||
+ unsigned int num,md_len;
|
||||
+};
|
||||
+
|
||||
+typedef struct
|
||||
+{
|
||||
+ struct openssl_sha256_context octx;
|
||||
+
|
||||
+ unsigned char ipad[64]; /*!< HMAC: inner padding */
|
||||
+ unsigned char opad[64]; /*!< HMAC: outer padding */
|
||||
+ int is224; /*!< 0 => SHA-256, else SHA-224 */
|
||||
+}
|
||||
+sha256_context;
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
+int SHA224_Init(struct openssl_sha256_context *c);
|
||||
+int SHA224_Update(struct openssl_sha256_context *c, const void *data, size_t len);
|
||||
+int SHA224_Final(unsigned char *md, struct openssl_sha256_context *c);
|
||||
+
|
||||
+int SHA256_Init(struct openssl_sha256_context *c);
|
||||
+int SHA256_Update(struct openssl_sha256_context *c, const void *data, size_t len);
|
||||
+int SHA256_Final(unsigned char *md, struct openssl_sha256_context *c);
|
||||
+
|
||||
+void sha256_block_data_order(struct openssl_sha256_context *c, const void *p, size_t num);
|
||||
+
|
||||
+static inline void sha256_starts( sha256_context *ctx, int is224 )
|
||||
+{
|
||||
+ if ((ctx->is224 = is224))
|
||||
+ SHA224_Init(&ctx->octx);
|
||||
+ else
|
||||
+ SHA256_Init(&ctx->octx);
|
||||
+}
|
||||
+
|
||||
+static inline void sha256_update( sha256_context *ctx, const unsigned char *input, size_t ilen )
|
||||
+{
|
||||
+ if (ctx->is224)
|
||||
+ SHA224_Update(&ctx->octx, input, ilen);
|
||||
+ else
|
||||
+ SHA256_Update(&ctx->octx, input, ilen);
|
||||
+}
|
||||
+
|
||||
+static inline void sha256_finish( sha256_context *ctx, unsigned char output[32] )
|
||||
+{
|
||||
+ if (ctx->is224)
|
||||
+ SHA224_Final(output, &ctx->octx);
|
||||
+ else
|
||||
+ SHA256_Final(output, &ctx->octx);
|
||||
+}
|
||||
+
|
||||
+static inline void sha256_process( sha256_context *ctx, const unsigned char data[64] )
|
||||
+{
|
||||
+ sha256_block_data_order(&ctx->octx, data, 1);
|
||||
+}
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
diff -uNr polarssl-1.2.7/include/polarssl/sha512_alt.h polarssl.new/include/polarssl/sha512_alt.h
|
||||
--- polarssl-1.2.7/include/polarssl/sha512_alt.h 1969-12-31 17:00:00.000000000 -0700
|
||||
+++ polarssl.new/include/polarssl/sha512_alt.h 2013-06-07 17:43:56.000000000 -0600
|
||||
@@ -0,0 +1,74 @@
|
||||
+/*
|
||||
+ * Use OpenSSL implementation of SHA512 methods to get asm and hardware acceleration.
|
||||
+ * Don't include this file directly, it is included by sha512.h when
|
||||
+ * POLARSSL_SHA512_ALT is defined.
|
||||
+ */
|
||||
+
|
||||
+#include "polarssl/sha_openssl.h"
|
||||
+
|
||||
+struct openssl_sha512_context {
|
||||
+ SHA_LONG64 h[8];
|
||||
+ SHA_LONG64 Nl,Nh;
|
||||
+ union {
|
||||
+ SHA_LONG64 d[SHA_LBLOCK];
|
||||
+ unsigned char p[SHA512_CBLOCK];
|
||||
+ } u;
|
||||
+ unsigned int num,md_len;
|
||||
+};
|
||||
+
|
||||
+typedef struct
|
||||
+{
|
||||
+ struct openssl_sha512_context octx;
|
||||
+
|
||||
+ unsigned char ipad[128]; /*!< HMAC: inner padding */
|
||||
+ unsigned char opad[128]; /*!< HMAC: outer padding */
|
||||
+ int is384; /*!< 0 => SHA-512, else SHA-384 */
|
||||
+}
|
||||
+sha512_context;
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
+int SHA384_Init(struct openssl_sha512_context *c);
|
||||
+int SHA384_Update(struct openssl_sha512_context *c, const void *data, size_t len);
|
||||
+int SHA384_Final(unsigned char *md, struct openssl_sha512_context *c);
|
||||
+
|
||||
+int SHA512_Init(struct openssl_sha512_context *c);
|
||||
+int SHA512_Update(struct openssl_sha512_context *c, const void *data, size_t len);
|
||||
+int SHA512_Final(unsigned char *md, struct openssl_sha512_context *c);
|
||||
+
|
||||
+void sha512_block_data_order(struct openssl_sha512_context *c, const void *p, size_t num);
|
||||
+
|
||||
+static inline void sha512_starts( sha512_context *ctx, int is384 )
|
||||
+{
|
||||
+ if ((ctx->is384 = is384))
|
||||
+ SHA384_Init(&ctx->octx);
|
||||
+ else
|
||||
+ SHA512_Init(&ctx->octx);
|
||||
+}
|
||||
+
|
||||
+static inline void sha512_update( sha512_context *ctx, const unsigned char *input, size_t ilen )
|
||||
+{
|
||||
+ if (ctx->is384)
|
||||
+ SHA384_Update(&ctx->octx, input, ilen);
|
||||
+ else
|
||||
+ SHA512_Update(&ctx->octx, input, ilen);
|
||||
+}
|
||||
+
|
||||
+static inline void sha512_finish( sha512_context *ctx, unsigned char output[64] )
|
||||
+{
|
||||
+ if (ctx->is384)
|
||||
+ SHA384_Final(output, &ctx->octx);
|
||||
+ else
|
||||
+ SHA512_Final(output, &ctx->octx);
|
||||
+}
|
||||
+
|
||||
+static inline void sha512_process( sha512_context *ctx, const unsigned char data[128] )
|
||||
+{
|
||||
+ sha512_block_data_order(&ctx->octx, data, 1);
|
||||
+}
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
diff -uNr polarssl-1.2.7/include/polarssl/sha_openssl.h polarssl.new/include/polarssl/sha_openssl.h
|
||||
--- polarssl-1.2.7/include/polarssl/sha_openssl.h 1969-12-31 17:00:00.000000000 -0700
|
||||
+++ polarssl.new/include/polarssl/sha_openssl.h 2013-06-07 17:43:56.000000000 -0600
|
||||
@@ -0,0 +1,42 @@
|
||||
+/*
|
||||
+ * Common header file for all OpenSSL-imported SHA methods
|
||||
+ */
|
||||
+
|
||||
+#ifndef POLARSSL_SHA_OPENSSL_H
|
||||
+#define POLARSSL_SHA_OPENSSL_H
|
||||
+
|
||||
+/*
|
||||
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
+ * ! SHA_LONG has to be at least 32 bits wide. If it's wider, then !
|
||||
+ * ! SHA_LONG_LOG2 has to be defined along. !
|
||||
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
+ */
|
||||
+
|
||||
+#if defined(__LP32__)
|
||||
+#define SHA_LONG unsigned long
|
||||
+#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
|
||||
+#define SHA_LONG unsigned long
|
||||
+#define SHA_LONG_LOG2 3
|
||||
+#else
|
||||
+#define SHA_LONG unsigned int
|
||||
+#endif
|
||||
+
|
||||
+#define SHA_LBLOCK 16
|
||||
+
|
||||
+/*
|
||||
+ * Unlike 32-bit digest algorithms, SHA-512 *relies* on SHA_LONG64
|
||||
+ * being exactly 64-bit wide. See Implementation Notes in sha512.c
|
||||
+ * for further details.
|
||||
+ */
|
||||
+#define SHA512_CBLOCK (SHA_LBLOCK*8) /* SHA-512 treats input data as a
|
||||
+ * contiguous array of 64 bit
|
||||
+ * wide big-endian values. */
|
||||
+#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
|
||||
+#define SHA_LONG64 unsigned __int64
|
||||
+#elif defined(__arch64__)
|
||||
+#define SHA_LONG64 unsigned long
|
||||
+#else
|
||||
+#define SHA_LONG64 unsigned long long
|
||||
+#endif
|
||||
+
|
||||
+#endif
|
||||
24
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/ref
Normal file
24
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/ref
Normal file
@@ -0,0 +1,24 @@
|
||||
AES_set_encrypt_key
|
||||
AES_set_decrypt_key
|
||||
AES_ecb_encrypt
|
||||
AES_cbc_encrypt
|
||||
BF_set_key
|
||||
BF_ecb_encrypt
|
||||
BF_cbc_encrypt
|
||||
SHA1_Init
|
||||
SHA1_Update
|
||||
SHA1_Final
|
||||
SHA224_Init
|
||||
SHA224_Update
|
||||
SHA224_Final
|
||||
SHA256_Init
|
||||
SHA256_Update
|
||||
SHA256_Final
|
||||
SHA384_Init
|
||||
SHA384_Update
|
||||
SHA384_Final
|
||||
SHA512_Init
|
||||
SHA512_Update
|
||||
SHA512_Final
|
||||
OPENSSL_ia32_cpuid
|
||||
-OPENSSL_cpuid_setup
|
||||
24
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/ref-aesni
Normal file
24
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/ref-aesni
Normal file
@@ -0,0 +1,24 @@
|
||||
aesni_set_encrypt_key
|
||||
aesni_set_decrypt_key
|
||||
aesni_ecb_encrypt
|
||||
aesni_cbc_encrypt
|
||||
BF_set_key
|
||||
BF_ecb_encrypt
|
||||
BF_cbc_encrypt
|
||||
SHA1_Init
|
||||
SHA1_Update
|
||||
SHA1_Final
|
||||
SHA224_Init
|
||||
SHA224_Update
|
||||
SHA224_Final
|
||||
SHA256_Init
|
||||
SHA256_Update
|
||||
SHA256_Final
|
||||
SHA384_Init
|
||||
SHA384_Update
|
||||
SHA384_Final
|
||||
SHA512_Init
|
||||
SHA512_Update
|
||||
SHA512_Final
|
||||
OPENSSL_ia32_cpuid
|
||||
-OPENSSL_cpuid_setup
|
||||
@@ -0,0 +1,118 @@
|
||||
diff -ur mbedtls-1.3.17/library/x509.c polarssl.new/library/x509.c
|
||||
--- mbedtls-1.3.17/library/x509.c 2016-06-27 13:00:26.000000000 -0600
|
||||
+++ polarssl.new/library/x509.c 2016-08-04 17:21:52.000000000 -0600
|
||||
@@ -490,6 +490,73 @@
|
||||
}
|
||||
|
||||
/*
|
||||
+ * Parse an ASN1_UTC_TIME (yearlen=2) or ASN1_GENERALIZED_TIME (yearlen=4) field.
|
||||
+ */
|
||||
+static int x509_parse_time(unsigned char **p, size_t len, unsigned int yearlen, x509_time *time)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ /* minimum length is 10 or 12 depending on yearlen */
|
||||
+ if (len < yearlen + 8)
|
||||
+ return POLARSSL_ERR_X509_INVALID_DATE;
|
||||
+ len -= yearlen + 8;
|
||||
+
|
||||
+ /* parse year, month, day, hour, minute */
|
||||
+ CHECK( x509_parse_int( p, yearlen, &time->year ) );
|
||||
+ if (yearlen == 2)
|
||||
+ {
|
||||
+ if (time->year < 50)
|
||||
+ time->year += 100;
|
||||
+ time->year += 1900;
|
||||
+ }
|
||||
+ CHECK( x509_parse_int( p, 2, &time->mon ) );
|
||||
+ CHECK( x509_parse_int( p, 2, &time->day ) );
|
||||
+ CHECK( x509_parse_int( p, 2, &time->hour ) );
|
||||
+ CHECK( x509_parse_int( p, 2, &time->min ) );
|
||||
+
|
||||
+ /* parse seconds if present */
|
||||
+ if (len >= 2 && **p >= '0' && **p <= '9')
|
||||
+ {
|
||||
+ CHECK( x509_parse_int( p, 2, &time->sec ) );
|
||||
+ len -= 2;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+#if defined(POLARSSL_RELAXED_X509_DATE)
|
||||
+ /* if relaxed mode, allow seconds to be absent */
|
||||
+ time->sec = 0;
|
||||
+#else
|
||||
+ return POLARSSL_ERR_X509_INVALID_DATE;
|
||||
+#endif
|
||||
+ }
|
||||
+
|
||||
+ /* parse trailing 'Z' if present */
|
||||
+ if (len == 1 && **p == 'Z')
|
||||
+ {
|
||||
+ (*p)++;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+#if defined(POLARSSL_RELAXED_X509_DATE)
|
||||
+ /* if relaxed mode, allow timezone to be present */
|
||||
+ else if (len == 5 && **p == '+')
|
||||
+ {
|
||||
+ int tz; /* throwaway timezone */
|
||||
+ (*p)++;
|
||||
+ CHECK( x509_parse_int( p, 4, &tz ) );
|
||||
+ return 0;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ /* okay if no trailing 'Z' or timezone specified */
|
||||
+ else if (len == 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ else
|
||||
+ return POLARSSL_ERR_X509_INVALID_DATE;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* Time ::= CHOICE {
|
||||
* utcTime UTCTime,
|
||||
* generalTime GeneralizedTime }
|
||||
@@ -515,20 +582,7 @@
|
||||
if( ret != 0 )
|
||||
return( POLARSSL_ERR_X509_INVALID_DATE + ret );
|
||||
|
||||
- CHECK( x509_parse_int( p, 2, &time->year ) );
|
||||
- CHECK( x509_parse_int( p, 2, &time->mon ) );
|
||||
- CHECK( x509_parse_int( p, 2, &time->day ) );
|
||||
- CHECK( x509_parse_int( p, 2, &time->hour ) );
|
||||
- CHECK( x509_parse_int( p, 2, &time->min ) );
|
||||
- if( len > 10 )
|
||||
- CHECK( x509_parse_int( p, 2, &time->sec ) );
|
||||
- if( len > 12 && *(*p)++ != 'Z' )
|
||||
- return( POLARSSL_ERR_X509_INVALID_DATE );
|
||||
-
|
||||
- time->year += 100 * ( time->year < 50 );
|
||||
- time->year += 1900;
|
||||
-
|
||||
- return( 0 );
|
||||
+ return x509_parse_time(p, len, 2, time);
|
||||
}
|
||||
else if( tag == ASN1_GENERALIZED_TIME )
|
||||
{
|
||||
@@ -538,17 +592,7 @@
|
||||
if( ret != 0 )
|
||||
return( POLARSSL_ERR_X509_INVALID_DATE + ret );
|
||||
|
||||
- CHECK( x509_parse_int( p, 4, &time->year ) );
|
||||
- CHECK( x509_parse_int( p, 2, &time->mon ) );
|
||||
- CHECK( x509_parse_int( p, 2, &time->day ) );
|
||||
- CHECK( x509_parse_int( p, 2, &time->hour ) );
|
||||
- CHECK( x509_parse_int( p, 2, &time->min ) );
|
||||
- if( len > 12 )
|
||||
- CHECK( x509_parse_int( p, 2, &time->sec ) );
|
||||
- if( len > 14 && *(*p)++ != 'Z' )
|
||||
- return( POLARSSL_ERR_X509_INVALID_DATE );
|
||||
-
|
||||
- return( 0 );
|
||||
+ return x509_parse_time(p, len, 4, time);
|
||||
}
|
||||
else
|
||||
return( POLARSSL_ERR_X509_INVALID_DATE +
|
||||
13
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/testpatch
Executable file
13
OpenVPN Adapter/Vendors/openvpn/deps/polarssl/testpatch
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
ver=1.2.7
|
||||
src=~/src/mac/polarssl-$ver
|
||||
rm -rf polarssl-$ver polarssl-$ver.new
|
||||
tar xfz $DL/polarssl-$ver-gpl.tgz
|
||||
cp -a polarssl-$ver polarssl-$ver.new
|
||||
cd polarssl-$ver.new
|
||||
cp $src/include/polarssl/bn_mul.h include/polarssl/
|
||||
cp $src/library/bignum.c library/
|
||||
#cp $src/library/mpi_mul_hlp.c library/
|
||||
#cp $src/library/CMakeLists.txt library/
|
||||
cd ..
|
||||
diff -uNr polarssl-$ver polarssl-$ver.new
|
||||
@@ -0,0 +1,37 @@
|
||||
Make the ciphersuites array argument to ssl_set_ciphersuites const.
|
||||
This should be done to assure callers that PolarSSL doesn't intend
|
||||
to modify this array (which it apparently doesn't).
|
||||
|
||||
diff -ur polarssl-1.1.1/include/polarssl/ssl.h polarssl-1.1.1.new/include/polarssl/ssl.h
|
||||
--- polarssl-1.1.1/include/polarssl/ssl.h 2012-01-23 02:57:38.000000000 -0700
|
||||
+++ polarssl-1.1.1.new/include/polarssl/ssl.h 2012-03-14 02:46:30.315215130 -0600
|
||||
@@ -306,7 +306,7 @@
|
||||
sha1_context fin_sha1; /*!< Finished SHA-1 checksum */
|
||||
|
||||
int do_crypt; /*!< en(de)cryption flag */
|
||||
- int *ciphersuites; /*!< allowed ciphersuites */
|
||||
+ const int *ciphersuites; /*!< allowed ciphersuites */
|
||||
size_t pmslen; /*!< premaster length */
|
||||
unsigned int keylen; /*!< symmetric key length */
|
||||
size_t minlen; /*!< min. ciphertext length */
|
||||
@@ -495,7 +495,7 @@
|
||||
* \param ssl SSL context
|
||||
* \param ciphersuites 0-terminated list of allowed ciphersuites
|
||||
*/
|
||||
-void ssl_set_ciphersuites( ssl_context *ssl, int *ciphersuites );
|
||||
+void ssl_set_ciphersuites( ssl_context *ssl, const int *ciphersuites );
|
||||
|
||||
/**
|
||||
* \brief Set the data required to verify peer certificate
|
||||
diff -ur polarssl-1.1.1/library/ssl_tls.c polarssl-1.1.1.new/library/ssl_tls.c
|
||||
--- polarssl-1.1.1/library/ssl_tls.c 2012-01-23 02:57:38.000000000 -0700
|
||||
+++ polarssl-1.1.1.new/library/ssl_tls.c 2012-03-14 02:47:10.830001668 -0600
|
||||
@@ -1838,7 +1838,7 @@
|
||||
ssl->session = session;
|
||||
}
|
||||
|
||||
-void ssl_set_ciphersuites( ssl_context *ssl, int *ciphersuites )
|
||||
+void ssl_set_ciphersuites( ssl_context *ssl, const int *ciphersuites )
|
||||
{
|
||||
ssl->ciphersuites = ciphersuites;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
This fixes an issue where the cipher.h header doesn't compile when included
|
||||
by C++ code, as C++ is more strict than C about implicit enum casts.
|
||||
|
||||
diff -ur polarssl-1.1.1/include/polarssl/cipher.h /home/james/polarssl-1.1.1/include/polarssl/cipher.h
|
||||
--- polarssl-1.1.1/include/polarssl/cipher.h 2011-11-15 08:38:45.000000000 -0700
|
||||
+++ /home/james/polarssl-1.1.1/include/polarssl/cipher.h 2012-03-12 17:31:12.279631469 -0600
|
||||
@@ -313,7 +313,7 @@
|
||||
static inline cipher_type_t cipher_get_type( const cipher_context_t *ctx )
|
||||
{
|
||||
if( NULL == ctx || NULL == ctx->cipher_info )
|
||||
- return 0;
|
||||
+ return POLARSSL_CIPHER_NONE;
|
||||
|
||||
return ctx->cipher_info->type;
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
This patch allows the caller to create a proxy object that can be used
|
||||
in place of a private key. The proxy object must define sign and
|
||||
decrypt methods. This functionality is similar to that provided by
|
||||
POLARSSL_PKCS11_C except that it can accomodate any arbitrary
|
||||
implementation of external private keys, not only that provided by
|
||||
the PKCS#11 helper library.
|
||||
|
||||
This is necessary to allow PolarSSL to interact with certificate/key
|
||||
stores on many different platforms that don't natively support
|
||||
PKCS#11 such as Mac (uses Keychain API), Windows (uses CryptoAPI),
|
||||
and Android (android.security.KeyChain).
|
||||
|
||||
In the basic usage model, the library is built with POLARSSL_PKCS11_C
|
||||
and POLARSSL_GENERIC_EXTERNAL_PRIVATE_KEY. Doing this causes the
|
||||
pkcs11_context object to become an interface to any arbitrary
|
||||
external private key implementation that defines sign and decrypt
|
||||
methods. Note that in this configuration, the PKCS#11 helper library
|
||||
(libpkcs11-helper) is not used.
|
||||
|
||||
When POLARSSL_PKCS11_C is defined in the absence of
|
||||
POLARSSL_GENERIC_EXTERNAL_PRIVATE_KEY, the pkcs11_context object
|
||||
reverts to its previous implementation, where it becomes a
|
||||
connector to a certificate/private-key context in the PKCS#11 helper
|
||||
library.
|
||||
|
||||
diff -ur polarssl-1.1.1.orig/include/polarssl/config.h polarssl-1.1.1/include/polarssl/config.h
|
||||
--- polarssl-1.1.1.orig/include/polarssl/config.h 2011-12-22 03:06:27.000000000 -0700
|
||||
+++ polarssl-1.1.1/include/polarssl/config.h 2012-03-14 02:31:04.000000000 -0600
|
||||
@@ -531,10 +531,26 @@
|
||||
*
|
||||
* This module is required for SSL/TLS PKCS #11 smartcard support.
|
||||
* Requires the presence of the PKCS#11 helper library (libpkcs11-helper)
|
||||
+ * unless POLARSSL_GENERIC_EXTERNAL_PRIVATE_KEY is also defined.
|
||||
+ *
|
||||
#define POLARSSL_PKCS11_C
|
||||
*/
|
||||
|
||||
/**
|
||||
+ * \def POLARSSL_GENERIC_EXTERNAL_PRIVATE_KEY
|
||||
+ *
|
||||
+ * Enable support for generic external private key implementations.
|
||||
+ *
|
||||
+ * Module: library/ssl_srv.c
|
||||
+ * Caller: library/ssl_cli.c
|
||||
+ * library/ssl_srv.c
|
||||
+ *
|
||||
+ * Requires: POLARSSL_PKCS11_C
|
||||
+ *
|
||||
+#define POLARSSL_GENERIC_EXTERNAL_PRIVATE_KEY
|
||||
+ */
|
||||
+
|
||||
+/**
|
||||
* \def POLARSSL_RSA_C
|
||||
*
|
||||
* Enable the RSA public-key cryptosystem.
|
||||
diff -ur polarssl-1.1.1.orig/include/polarssl/pkcs11.h polarssl-1.1.1/include/polarssl/pkcs11.h
|
||||
--- polarssl-1.1.1.orig/include/polarssl/pkcs11.h 2011-11-18 07:26:47.000000000 -0700
|
||||
+++ polarssl-1.1.1/include/polarssl/pkcs11.h 2012-03-14 02:28:34.000000000 -0600
|
||||
@@ -35,6 +35,95 @@
|
||||
|
||||
#include "x509.h"
|
||||
|
||||
+#if defined(POLARSSL_GENERIC_EXTERNAL_PRIVATE_KEY)
|
||||
+
|
||||
+/* inline preamble */
|
||||
+#if defined(_MSC_VER) && !defined(inline)
|
||||
+#define inline _inline
|
||||
+#else
|
||||
+#if defined(__ARMCC_VERSION) && !defined(inline)
|
||||
+#define inline __inline
|
||||
+#endif /* __ARMCC_VERSION */
|
||||
+#endif /*_MSC_VER */
|
||||
+
|
||||
+/**
|
||||
+ * This object is a reference to an external private key,
|
||||
+ * and can be used in place of a concrete private key.
|
||||
+ */
|
||||
+typedef struct _pkcs11_context {
|
||||
+ void *parameter; /** user-defined parameter */
|
||||
+ int len; /** private key length in bytes */
|
||||
+
|
||||
+ /** user-defined decrypt method, see pkcs11_decrypt doc below */
|
||||
+ int (*f_decrypt)( struct _pkcs11_context *ctx,
|
||||
+ int mode, size_t *olen,
|
||||
+ const unsigned char *input,
|
||||
+ unsigned char *output,
|
||||
+ unsigned int output_max_len );
|
||||
+
|
||||
+ /** user-defined sign method, see pkcs11_sign doc below */
|
||||
+ int (*f_sign)( struct _pkcs11_context *ctx,
|
||||
+ int mode,
|
||||
+ int hash_id,
|
||||
+ unsigned int hashlen,
|
||||
+ const unsigned char *hash,
|
||||
+ unsigned char *sig );
|
||||
+
|
||||
+} pkcs11_context;
|
||||
+
|
||||
+/**
|
||||
+ * \brief Do an RSA private key decrypt, then remove the message padding
|
||||
+ *
|
||||
+ * \param ctx PKCS #11 context
|
||||
+ * \param mode must be RSA_PRIVATE, for compatibility with rsa.c's signature
|
||||
+ * \param input buffer holding the encrypted data
|
||||
+ * \param output buffer that will hold the plaintext
|
||||
+ * \param olen will contain the plaintext length
|
||||
+ * \param output_max_len maximum length of the output buffer
|
||||
+ *
|
||||
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
|
||||
+ *
|
||||
+ * \note The output buffer must be as large as the size
|
||||
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
|
||||
+ * an error is thrown.
|
||||
+ */
|
||||
+static inline int pkcs11_decrypt( pkcs11_context *ctx,
|
||||
+ int mode, size_t *olen,
|
||||
+ const unsigned char *input,
|
||||
+ unsigned char *output,
|
||||
+ unsigned int output_max_len )
|
||||
+{
|
||||
+ return (*ctx->f_decrypt)(ctx, mode, olen, input, output, output_max_len);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * \brief Do a private RSA to sign a message digest
|
||||
+ *
|
||||
+ * \param ctx PKCS #11 context
|
||||
+ * \param mode must be RSA_PRIVATE, for compatibility with rsa.c's signature
|
||||
+ * \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
|
||||
+ * \param hashlen message digest length (for SIG_RSA_RAW only)
|
||||
+ * \param hash buffer holding the message digest
|
||||
+ * \param sig buffer that will hold the ciphertext
|
||||
+ *
|
||||
+ * \return 0 if the signing operation was successful,
|
||||
+ * or an POLARSSL_ERR_RSA_XXX error code
|
||||
+ *
|
||||
+ * \note The "sig" buffer must be as large as the size
|
||||
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used).
|
||||
+ */
|
||||
+static inline int pkcs11_sign( pkcs11_context *ctx,
|
||||
+ int mode,
|
||||
+ int hash_id,
|
||||
+ unsigned int hashlen,
|
||||
+ const unsigned char *hash,
|
||||
+ unsigned char *sig )
|
||||
+{
|
||||
+ return (*ctx->f_sign)(ctx, mode, hash_id, hashlen, hash, sig);
|
||||
+}
|
||||
+
|
||||
+#else
|
||||
+
|
||||
#include <pkcs11-helper-1.0/pkcs11h-certificate.h>
|
||||
|
||||
/**
|
||||
@@ -121,6 +210,8 @@
|
||||
const unsigned char *hash,
|
||||
unsigned char *sig );
|
||||
|
||||
+#endif /* POLARSSL_GENERIC_EXTERNAL_PRIVATE_KEY */
|
||||
+
|
||||
#endif /* POLARSSL_PKCS11_C */
|
||||
|
||||
#endif /* POLARSSL_PKCS11_H */
|
||||
diff -ur polarssl-1.1.1.orig/library/pkcs11.c polarssl-1.1.1/library/pkcs11.c
|
||||
--- polarssl-1.1.1.orig/library/pkcs11.c 2011-04-24 02:57:21.000000000 -0600
|
||||
+++ polarssl-1.1.1/library/pkcs11.c 2012-03-14 02:28:22.000000000 -0600
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
#include "polarssl/pkcs11.h"
|
||||
|
||||
-#if defined(POLARSSL_PKCS11_C)
|
||||
+#if defined(POLARSSL_PKCS11_C) && !defined(POLARSSL_GENERIC_EXTERNAL_PRIVATE_KEY)
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -235,4 +235,4 @@
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
-#endif /* defined(POLARSSL_PKCS11_C) */
|
||||
+#endif /* defined(POLARSSL_PKCS11_C) && !defined(POLARSSL_GENERIC_EXTERNAL_PRIVATE_KEY) */
|
||||
@@ -0,0 +1,12 @@
|
||||
diff -ur polarssl-1.1.3/library/ssl_tls.c polarssl-1.1.3.jy/library/ssl_tls.c
|
||||
--- polarssl-1.1.3/library/ssl_tls.c 2012-04-20 07:33:14.000000000 -0600
|
||||
+++ polarssl-1.1.3.jy/library/ssl_tls.c 2012-05-29 09:12:11.687371794 -0600
|
||||
@@ -785,7 +785,7 @@
|
||||
/*
|
||||
* Always compute the MAC (RFC4346, CBCTIME).
|
||||
*/
|
||||
- if( ssl->in_msglen <= ssl->maclen + padlen )
|
||||
+ if( ssl->in_msglen < ssl->maclen + padlen )
|
||||
{
|
||||
SSL_DEBUG_MSG( 1, ( "msglen (%d) < maclen (%d) + padlen (%d)",
|
||||
ssl->in_msglen, ssl->maclen, padlen ) );
|
||||
@@ -0,0 +1,44 @@
|
||||
Patch to 1.1.4 to allow X509 v3 trust extensions.
|
||||
--------------------------------------------------
|
||||
Index: x509parse.c
|
||||
===================================================================
|
||||
--- x509parse.c (revision 1322)
|
||||
+++ x509parse.c (working copy)
|
||||
@@ -1134,7 +1134,7 @@
|
||||
{
|
||||
int ret;
|
||||
size_t len;
|
||||
- unsigned char *p, *end;
|
||||
+ unsigned char *p, *end, *crt_end;
|
||||
|
||||
/*
|
||||
* Check for valid input
|
||||
@@ -1168,13 +1168,14 @@
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
|
||||
}
|
||||
|
||||
- if( len != (size_t) ( end - p ) )
|
||||
+ if( len > (size_t) ( end - p ) )
|
||||
{
|
||||
x509_free( crt );
|
||||
return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
|
||||
POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
|
||||
}
|
||||
-
|
||||
+ crt_end = p + len;
|
||||
+
|
||||
/*
|
||||
* TBSCertificate ::= SEQUENCE {
|
||||
*/
|
||||
@@ -1344,7 +1345,7 @@
|
||||
POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
|
||||
}
|
||||
|
||||
- end = crt->raw.p + crt->raw.len;
|
||||
+ end = crt_end;
|
||||
|
||||
/*
|
||||
* signatureAlgorithm AlgorithmIdentifier,
|
||||
|
||||
----------------------------------------------------
|
||||
End of patch file
|
||||
66
OpenVPN Adapter/Vendors/openvpn/deps/snappy/build-snappy
Executable file
66
OpenVPN Adapter/Vendors/openvpn/deps/snappy/build-snappy
Executable file
@@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
if [ -z "$O3" ]; then
|
||||
echo O3 var must point to ovpn3 tree
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$TARGET" ]; then
|
||||
echo TARGET var must be defined
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ -z "$DL" ] && DL=~/Downloads
|
||||
|
||||
# source vars
|
||||
. $O3/core/vars/vars-${TARGET}
|
||||
. $O3/core/deps/lib-versions
|
||||
|
||||
[ "$GCC_CMD" ] && export CC=$GCC_CMD
|
||||
[ "$GPP_CMD" ] && export CXX=$GPP_CMD
|
||||
[ "$LD_CMD" ] && export LD=$LD_CMD
|
||||
[ "$AR_CMD" ] && export AR=$AR_CMD
|
||||
[ "$RANLIB_CMD" ] && export RANLIB=$RANLIB_CMD
|
||||
|
||||
case $PLATFORM in
|
||||
android*)
|
||||
echo PLATFORM android
|
||||
host=arm
|
||||
target=arm
|
||||
;;
|
||||
ios*)
|
||||
echo PLATFORM ios
|
||||
host="x86_64-apple-darwin"
|
||||
target=arm
|
||||
;;
|
||||
*)
|
||||
host=""
|
||||
target=""
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ "$target" ]; then
|
||||
targ_opt="--target=$target"
|
||||
fi
|
||||
|
||||
if [ "$host" ]; then
|
||||
host_opt="--host=$host"
|
||||
fi
|
||||
|
||||
if [ "$NO_WIPE" != "1" ]; then
|
||||
rm -rf $SNAPPY_VERSION
|
||||
tar xfz $DL/$SNAPPY_VERSION.tar.gz
|
||||
fi
|
||||
|
||||
DIST=$(pwd)/snappy/snappy-$PLATFORM
|
||||
rm -rf $DIST
|
||||
mkdir -p $DIST
|
||||
cd $SNAPPY_VERSION
|
||||
echo 'OPTIONS' CC=$CC LD=$LD AR=$AR RANLIB=$RANLIB host_opt=$host_opt targ_opt=$targ_opt
|
||||
export CFLAGS="$PLATFORM_FLAGS $OTHER_COMPILER_FLAGS $LIB_OPT_LEVEL $LIB_FPIC"
|
||||
echo 'CFLAGS' $CFLAGS
|
||||
export CXXFLAGS="$CFLAGS $CXX_COMPILER_FLAGS"
|
||||
./configure --prefix=$DIST $host_opt $targ_opt --enable-static --disable-shared
|
||||
make
|
||||
make install
|
||||
exit 0
|
||||
@@ -0,0 +1,198 @@
|
||||
OpenVPN Protocol extensions
|
||||
2015-01-06
|
||||
|
||||
1. DATA_V2 opcode with 24-bit peer ID
|
||||
|
||||
* The DATA_V2 opcode is 9.
|
||||
* The DATA_V2 opcode/key_id byte is followed by 3 additional
|
||||
(network endian) bytes indicating the peer ID.
|
||||
* If a 4-byte DATA_V2 header is passed through ntohl,
|
||||
the resulting high 8 bits will be the DATA_V2 opcode/key_id,
|
||||
and the lower 24 bits will be the peer ID.
|
||||
* A disabled peer ID is denoted by 0xFFFFFF.
|
||||
* Server tells the client to use DATA_V2/peer_id by pushing
|
||||
the directive "peer-id ID" where ID is a decimal integer
|
||||
in the range [-1, 16777215]. Setting the peer ID to -1
|
||||
transmits DATA_V2 packets with the peer ID field set to
|
||||
0xFFFFFF. Setting the peer_id to -1 is the same as
|
||||
setting it to 16777215 (i.e. 0xFFFFFF).
|
||||
* Client never transmits DATA_V2 packets unless the server
|
||||
has pushed a "peer-id" directive.
|
||||
* Server never pushes a "peer-id" directive unless the
|
||||
client has indicated its support for DATA_V2 by
|
||||
including "IV_PROTO=2" in the peer info data.
|
||||
* When DATA_V2 is used for "float" functionality, the server
|
||||
must perform the following checks before allowing
|
||||
a client to float, i.e. to assume a new source address.
|
||||
(a) verify integrity (HMAC or GCM auth tag, replay
|
||||
protection, etc.) of the DATA_V2 packet, and
|
||||
(b) ensure that the float doesn't clobber a pre-existing
|
||||
client (i.e. if the address floated to is already
|
||||
owned by another client) unless it can be verified
|
||||
that the pre-existing client is a previous instance
|
||||
of the floating client.
|
||||
|
||||
2. AEAD mode
|
||||
|
||||
To support AEAD crypto modes such as AES-GCM, some protocol
|
||||
changes are in order. AES-GCM, for example, requires a 12
|
||||
byte unique nonce for every packet. I would propose that 4
|
||||
bytes be taken from the Packet ID which increments for every
|
||||
packet and therefore provides uniqueness. The remaining 8
|
||||
bytes would be derived from the random key material that would
|
||||
normally be used to key the HMAC key. This is possible since
|
||||
AEAD modes use a combined key for encryption and integrity
|
||||
checking, therefore the random key material for HMAC is
|
||||
unused and can be repurposed as an AEAD nonce source. The 8
|
||||
byte nonce component derived from the HMAC keying material
|
||||
would remain constant for a given Key State. Only the 4 byte
|
||||
Packet ID would increment for each packet. Because AEAD
|
||||
encryption can be compromised if the nonce ever repeats for
|
||||
a given key, the implementation MUST disable encryption
|
||||
for a key if the 32-bit packet ID wraps. In practical usage,
|
||||
renegotiation usually preempts wrapping, so the
|
||||
disable-encryption-on-wrap feature is a failsafe.
|
||||
|
||||
AEAD Nonce:
|
||||
|
||||
[ Packet ID ] [ HMAC keying material ]
|
||||
[ 4 bytes ] [ 8 bytes ]
|
||||
[ AEAD nonce total: 12 bytes ]
|
||||
|
||||
TLS wire protocol:
|
||||
|
||||
[ DATA_V2 opcode ] [ Packet ID ] [ AEAD Auth tag ] [ ciphertext ]
|
||||
[ 4 bytes ] [ 4 bytes ] [ 16 bytes ]
|
||||
[ AEAD additional data (AD) ]
|
||||
|
||||
Static Key wire protocol:
|
||||
|
||||
[ DATA_V2 opcode ] [ Packet ID ] [ Nonce tail (random) ] [ AEAD Auth tag ] [ ciphertext ]
|
||||
[ AEAD nonce ]
|
||||
[ 4 bytes ] [ 8 bytes ] [ 4 bytes ] [ 16 bytes ]
|
||||
[ AEAD additional data (AD) ]
|
||||
|
||||
Note that the AEAD additional data (AD) includes all data
|
||||
preceding the AEAD Auth tag including the DATA_V2/peer_id
|
||||
opcode and packet ID.
|
||||
|
||||
Also, note that because the HMAC keying material used to derive
|
||||
the last 8 bytes of the AEAD nonce is negotiated once per key
|
||||
as part of the control channel handshake, we can omit it from the
|
||||
data channel packets, thereby saving 8 bytes per packet. So
|
||||
only the 4-byte Packet ID component of the nonce must be
|
||||
transmitted with every packet.
|
||||
|
||||
When negotiating AEAD mode, the client indicates its support
|
||||
of AES-128-GCM, AES-192-GCM, and AES-192-GCM by including:
|
||||
|
||||
IV_NCP=2
|
||||
|
||||
in the peer info string (NCP stands for Negotiable Crypto
|
||||
Parameters).
|
||||
|
||||
When the IV_NCP value is 2 or higher, it indicates that
|
||||
the server may push an AEAD "cipher" directive, e.g.:
|
||||
|
||||
push "cipher AES-128-GCM"
|
||||
|
||||
In the future, the IV_NCP value (2 in the current
|
||||
implementation) may be increased to indicate the
|
||||
availability of additional negotiable ciphers.
|
||||
|
||||
3. Compression V2
|
||||
|
||||
I have observed that compression in many cases, even when
|
||||
enabled, often does not produce packet size reduction
|
||||
because much of the packet data typically generated by web
|
||||
sessions is already compressed. Further, the single byte that
|
||||
precedes the packet and indicates whether or not compression
|
||||
occurred has the unfortunate side effect of misaligning the IP
|
||||
packet in cases where compression did not occur. To remedy this,
|
||||
I propose a Compression V2 header that is optimized for the
|
||||
case where compression does not occur.
|
||||
|
||||
a. No compression occurred and first byte of IP/Ethernet packet
|
||||
is NOT 0x50 (0 bytes of overhead and maintains alignment):
|
||||
|
||||
[ uncompressed IP/Ethernet packet ]
|
||||
|
||||
b. No compression occurred and first byte of IP/Ethernet packet
|
||||
is 0x50 (2 bytes of overhead but unlikely since no known
|
||||
IP packet can begin with 0x50):
|
||||
|
||||
[ 0x50 ] [ 0x00 ] [ uncompressed IP/Ethernet packet ]
|
||||
|
||||
c. Compression occurred (2 bytes of overhead):
|
||||
|
||||
[ 0x50 ] [ compression Alg ID byte ] [ compressed IP/Ethernet packet ]
|
||||
|
||||
Compression Alg ID is one-byte algorithm identifier
|
||||
for LZ4 (0x1), LZO (0x2), or Snappy (0x3).
|
||||
|
||||
This approach has several beneficial effects:
|
||||
|
||||
1. In the common case where compression does not occur, no
|
||||
compression op is required, therefore there is zero overhead.
|
||||
|
||||
2. When compression does not occur, the IP/Ethernet packet
|
||||
alignment is retained.
|
||||
|
||||
3. This technique does not require any byte swapping with
|
||||
the tail of the packet which can potentially incur an
|
||||
expensive cache miss.
|
||||
|
||||
When negotiating Compression V2 mode, the client indicates its
|
||||
support by including the following in the peer info string:
|
||||
|
||||
IV_LZ4v2=1 -> LZ4 compression available in V2 format
|
||||
IV_COMP_STUBv2=1 -> stub compression available in V2 format
|
||||
(i.e. disable compression but still
|
||||
retain compression framing)
|
||||
|
||||
In response, the server can push to the client:
|
||||
|
||||
push "compress lz4-v2" -> enable LZ4 compression in V2 format
|
||||
|
||||
or
|
||||
|
||||
push "compress stub-v2" -> disable compression but retain
|
||||
compression framing in V2 format
|
||||
|
||||
4. TCP nonlinear mode
|
||||
|
||||
The OpenVPN 2.x packet ID and replay protection code, when running
|
||||
in TCP mode, requires that the packet ID follows a linearly
|
||||
incrementing sequence, i.e. 1, 2, 2, 3, ... This was a reasonable
|
||||
requirement, since the reliable nature of TCP guaranteed that a
|
||||
linear sequence of packet IDs transmitted by the sender would be
|
||||
received in the same order by the receiver.
|
||||
|
||||
However, recent work has shown that multithreaded OpenVPN servers
|
||||
may not be able to guarantee TCP packet ID linearity (on the
|
||||
transmit side) without incurring a performance penalty. This
|
||||
is because the packet ID for transmitted packets must be allocated
|
||||
before the packet is encrypted, while a multithreaded OpenVPN server
|
||||
might be concurrently encrypting and transmitting multiple packets
|
||||
using different threads, where the order that the threads complete
|
||||
encryption and transmit the packet is non-deterministic. This
|
||||
non-deterministic ordering of packets over the TCP session means
|
||||
that the client might see out-of-order packets and a non-linear
|
||||
packet ID progression, just as clients now see with UDP.
|
||||
|
||||
My proposed solution to the issue is to relax the Packet ID
|
||||
validation on the receiver side to allow non-linear packet ID
|
||||
sequences, even in TCP mode. This essentially means that the
|
||||
packet ID validation logic is now the same for both UDP and TCP.
|
||||
|
||||
The client indicates its ability to process non-linear packet
|
||||
ID sequences in TCP mode by including the following in the
|
||||
peer info string:
|
||||
|
||||
IV_TCPNL=1 -> TCP non-linear receiver supported
|
||||
|
||||
When the server receives a IV_TCPNL setting of 1 from the
|
||||
client, it may transmit out-of-order packets in TCP mode.
|
||||
Otherwise, servers must use other means (such as using thread
|
||||
synchronization primitives) to ensure strictly linear packet
|
||||
ID ordering in TCP mode.
|
||||
7
OpenVPN Adapter/Vendors/openvpn/javacli/.gitignore
vendored
Normal file
7
OpenVPN Adapter/Vendors/openvpn/javacli/.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
build
|
||||
ovpncli_wrap.cxx
|
||||
ovpncli_wrap.h
|
||||
ovpncli.java
|
||||
ovpncliJNI.java
|
||||
ClientAPI_*.java
|
||||
SWIGTYPE_*.java
|
||||
144
OpenVPN Adapter/Vendors/openvpn/javacli/Client.java
Normal file
144
OpenVPN Adapter/Vendors/openvpn/javacli/Client.java
Normal file
@@ -0,0 +1,144 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// TESTING_ONLY
|
||||
|
||||
public class Client implements OpenVPNClientThread.EventReceiver {
|
||||
private OpenVPNClientThread client_thread;
|
||||
|
||||
public static class ConfigError extends Exception {
|
||||
public ConfigError(String msg) { super(msg); }
|
||||
}
|
||||
|
||||
public static class CredsUnspecifiedError extends Exception {
|
||||
public CredsUnspecifiedError(String msg) { super(msg); }
|
||||
}
|
||||
|
||||
// Load OpenVPN core (implements ClientAPI_OpenVPNClient) from shared library
|
||||
static {
|
||||
System.loadLibrary("ovpncli");
|
||||
ClientAPI_OpenVPNClient.init_process();
|
||||
String test = ClientAPI_OpenVPNClient.crypto_self_test();
|
||||
System.out.format("CRYPTO SELF TEST: %s", test);
|
||||
}
|
||||
|
||||
public Client(String config_text, String username, String password) throws ConfigError, CredsUnspecifiedError {
|
||||
// init client implementation object
|
||||
client_thread = new OpenVPNClientThread();
|
||||
|
||||
// load/eval config
|
||||
ClientAPI_Config config = new ClientAPI_Config();
|
||||
config.setContent(config_text);
|
||||
config.setCompressionMode("yes");
|
||||
ClientAPI_EvalConfig ec = client_thread.eval_config(config);
|
||||
if (ec.getError())
|
||||
throw new ConfigError("OpenVPN config file parse error: " + ec.getMessage());
|
||||
|
||||
// handle creds
|
||||
ClientAPI_ProvideCreds creds = new ClientAPI_ProvideCreds();
|
||||
if (!ec.getAutologin())
|
||||
{
|
||||
if (username.length() > 0)
|
||||
{
|
||||
creds.setUsername(username);
|
||||
creds.setPassword(password);
|
||||
creds.setReplacePasswordWithSessionID(true);
|
||||
}
|
||||
else
|
||||
throw new CredsUnspecifiedError("OpenVPN config file requires username/password but none provided");
|
||||
}
|
||||
client_thread.provide_creds(creds);
|
||||
}
|
||||
|
||||
public void connect() {
|
||||
// connect
|
||||
client_thread.connect(this);
|
||||
|
||||
// wait for worker thread to exit
|
||||
client_thread.wait_thread_long();
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
client_thread.stop();
|
||||
}
|
||||
|
||||
public void show_stats() {
|
||||
int n = client_thread.stats_n();
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
String name = client_thread.stats_name(i);
|
||||
long value = client_thread.stats_value(i);
|
||||
if (value > 0)
|
||||
System.out.format("STAT %s=%s%n", name, value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void event(ClientAPI_Event event) {
|
||||
boolean error = event.getError();
|
||||
String name = event.getName();
|
||||
String info = event.getInfo();
|
||||
System.out.format("EVENT: err=%b name=%s info='%s'%n", error, name, info);
|
||||
}
|
||||
|
||||
// Callback to get a certificate
|
||||
@Override
|
||||
public void external_pki_cert_request(ClientAPI_ExternalPKICertRequest req) {
|
||||
req.setError(true);
|
||||
req.setErrorText("cert request failed: external PKI not implemented");
|
||||
}
|
||||
|
||||
// Callback to sign data
|
||||
@Override
|
||||
public void external_pki_sign_request(ClientAPI_ExternalPKISignRequest req) {
|
||||
req.setError(true);
|
||||
req.setErrorText("sign request failed: external PKI not implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(ClientAPI_LogInfo loginfo) {
|
||||
String text = loginfo.getText();
|
||||
System.out.format("LOG: %s", text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void done(ClientAPI_Status status) {
|
||||
System.out.format("DONE ClientAPI_Status: err=%b msg='%s'%n", status.getError(), status.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean socket_protect(int socket)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pause_on_connection_timeout()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OpenVPNClientThread.TunBuilder tun_builder_new()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
97
OpenVPN Adapter/Vendors/openvpn/javacli/Main.java
Normal file
97
OpenVPN Adapter/Vendors/openvpn/javacli/Main.java
Normal file
@@ -0,0 +1,97 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// TESTING_ONLY
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
public class Main {
|
||||
// utility method to read a file and return as a String
|
||||
public static String readFile(String filename) throws IOException {
|
||||
return readStream(new FileInputStream(filename));
|
||||
}
|
||||
|
||||
private static String readStream(InputStream stream) throws IOException {
|
||||
// No real need to close the BufferedReader/InputStreamReader
|
||||
// as they're only wrapping the stream
|
||||
try {
|
||||
Reader reader = new BufferedReader(new InputStreamReader(stream));
|
||||
StringBuilder builder = new StringBuilder();
|
||||
char[] buffer = new char[4096];
|
||||
int read;
|
||||
while ((read = reader.read(buffer, 0, buffer.length)) > 0) {
|
||||
builder.append(buffer, 0, read);
|
||||
}
|
||||
return builder.toString();
|
||||
} finally {
|
||||
// Potential issue here: if this throws an IOException,
|
||||
// it will mask any others. Normally I'd use a utility
|
||||
// method which would log exceptions and swallow them
|
||||
stream.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException, Client.ConfigError, Client.CredsUnspecifiedError {
|
||||
if (args.length >= 1)
|
||||
{
|
||||
// load config file
|
||||
String config = readFile(args[0]);
|
||||
|
||||
// get creds
|
||||
String username = "";
|
||||
String password = "";
|
||||
if (args.length >= 3)
|
||||
{
|
||||
username = args[1];
|
||||
password = args[2];
|
||||
}
|
||||
|
||||
// instantiate client object
|
||||
final Client client = new Client(config, username, password);
|
||||
|
||||
// catch signals
|
||||
final Thread mainThread = Thread.currentThread();
|
||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
public void run() {
|
||||
client.stop();
|
||||
try {
|
||||
mainThread.join();
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// execute client session
|
||||
client.connect();
|
||||
|
||||
// show stats before exit
|
||||
client.show_stats();
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("OpenVPN Java client");
|
||||
System.err.println("Usage: java Client <client.ovpn> [username] [password]");
|
||||
System.exit(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
359
OpenVPN Adapter/Vendors/openvpn/javacli/OpenVPNClientThread.java
Normal file
359
OpenVPN Adapter/Vendors/openvpn/javacli/OpenVPNClientThread.java
Normal file
@@ -0,0 +1,359 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// package OPENVPN_PACKAGE
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
public class OpenVPNClientThread extends ClientAPI_OpenVPNClient implements Runnable {
|
||||
private EventReceiver parent;
|
||||
private TunBuilder tun_builder;
|
||||
private Thread thread;
|
||||
private ClientAPI_Status m_connect_status;
|
||||
private boolean connect_called = false;
|
||||
|
||||
private int bytes_in_index = -1;
|
||||
private int bytes_out_index = -1;
|
||||
|
||||
// thrown if instantiator attempts to call connect more than once
|
||||
public static class ConnectCalledTwice extends RuntimeException {
|
||||
}
|
||||
|
||||
public interface EventReceiver {
|
||||
// Called with events from core
|
||||
void event(ClientAPI_Event event);
|
||||
|
||||
// Called with log text from core
|
||||
void log(ClientAPI_LogInfo loginfo);
|
||||
|
||||
// Called when connect() thread exits
|
||||
void done(ClientAPI_Status status);
|
||||
|
||||
// Called to "protect" a socket from being routed through the tunnel
|
||||
boolean socket_protect(int socket);
|
||||
|
||||
// When a connection is close to timeout, the core will call this
|
||||
// method. If it returns false, the core will disconnect with a
|
||||
// CONNECTION_TIMEOUT event. If true, the core will enter a PAUSE
|
||||
// state.
|
||||
boolean pause_on_connection_timeout();
|
||||
|
||||
// Callback to construct a new tun builder
|
||||
TunBuilder tun_builder_new();
|
||||
|
||||
// Callback to get a certificate
|
||||
void external_pki_cert_request(ClientAPI_ExternalPKICertRequest req);
|
||||
|
||||
// Callback to sign data
|
||||
void external_pki_sign_request(ClientAPI_ExternalPKISignRequest req);
|
||||
}
|
||||
|
||||
public interface TunBuilder {
|
||||
// Tun builder methods.
|
||||
// Methods documented in openvpn/tun/builder/base.hpp
|
||||
|
||||
boolean tun_builder_set_remote_address(String address, boolean ipv6);
|
||||
boolean tun_builder_add_address(String address, int prefix_length, String gateway, boolean ipv6, boolean net30);
|
||||
boolean tun_builder_reroute_gw(boolean ipv4, boolean ipv6, long flags);
|
||||
boolean tun_builder_add_route(String address, int prefix_length, boolean ipv6);
|
||||
boolean tun_builder_exclude_route(String address, int prefix_length, boolean ipv6);
|
||||
boolean tun_builder_add_dns_server(String address, boolean ipv6);
|
||||
boolean tun_builder_add_search_domain(String domain);
|
||||
boolean tun_builder_set_mtu(int mtu);
|
||||
boolean tun_builder_set_session_name(String name);
|
||||
int tun_builder_establish();
|
||||
void tun_builder_teardown(boolean disconnect);
|
||||
}
|
||||
|
||||
public OpenVPNClientThread() {
|
||||
final int n = stats_n();
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
String name = stats_name(i);
|
||||
if (name.equals("BYTES_IN"))
|
||||
bytes_in_index = i;
|
||||
if (name.equals("BYTES_OUT"))
|
||||
bytes_out_index = i;
|
||||
}
|
||||
}
|
||||
|
||||
// start connect session in worker thread
|
||||
public void connect(EventReceiver parent_arg) {
|
||||
if (connect_called)
|
||||
throw new ConnectCalledTwice();
|
||||
connect_called = true;
|
||||
|
||||
// direct client callbacks to parent
|
||||
parent = parent_arg;
|
||||
|
||||
// clear status
|
||||
m_connect_status = null;
|
||||
|
||||
// execute client in a worker thread
|
||||
thread = new Thread(this, "OpenVPNClientThread");
|
||||
thread.start();
|
||||
}
|
||||
|
||||
// Wait for worker thread to complete; to stop thread,
|
||||
// first call super stop() method then wait_thread().
|
||||
// This method will give the thread one second to
|
||||
// exit and will abandon it after this time.
|
||||
public void wait_thread_short() {
|
||||
final int wait_millisecs = 5000; // max time that we will wait for thread to exit
|
||||
Thread th = thread;
|
||||
if (th != null) {
|
||||
try {
|
||||
th.join(wait_millisecs);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
}
|
||||
|
||||
// thread failed to stop?
|
||||
if (th.isAlive()) {
|
||||
// abandon thread and deliver our own status object to instantiator.
|
||||
ClientAPI_Status status = new ClientAPI_Status();
|
||||
status.setError(true);
|
||||
status.setMessage("CORE_THREAD_ABANDONED");
|
||||
call_done(status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for worker thread to complete; to stop thread,
|
||||
// first call super stop() method then wait_thread().
|
||||
// This method will wait forever for the thread to exit.
|
||||
public void wait_thread_long() {
|
||||
if (thread != null) {
|
||||
boolean interrupted;
|
||||
do {
|
||||
interrupted = false;
|
||||
try {
|
||||
thread.join();
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
interrupted = true;
|
||||
super.stop(); // send thread a stop message
|
||||
}
|
||||
} while (interrupted);
|
||||
}
|
||||
}
|
||||
|
||||
public long bytes_in()
|
||||
{
|
||||
return super.stats_value(bytes_in_index);
|
||||
}
|
||||
|
||||
public long bytes_out()
|
||||
{
|
||||
return super.stats_value(bytes_out_index);
|
||||
}
|
||||
|
||||
private void call_done(ClientAPI_Status status)
|
||||
{
|
||||
EventReceiver p = finalize_thread(status);
|
||||
if (p != null)
|
||||
p.done(m_connect_status);
|
||||
}
|
||||
|
||||
private synchronized EventReceiver finalize_thread(ClientAPI_Status connect_status)
|
||||
{
|
||||
EventReceiver p = parent;
|
||||
if (p != null) {
|
||||
// save thread connection status
|
||||
m_connect_status = connect_status;
|
||||
|
||||
// disassociate client callbacks from parent
|
||||
parent = null;
|
||||
tun_builder = null;
|
||||
thread = null;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
// Runnable overrides
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// Call out to core to start connection.
|
||||
// Doesn't return until connection has terminated.
|
||||
ClientAPI_Status status = super.connect();
|
||||
call_done(status);
|
||||
}
|
||||
|
||||
// ClientAPI_OpenVPNClient (C++ class) overrides
|
||||
|
||||
@Override
|
||||
public boolean socket_protect(int socket) {
|
||||
EventReceiver p = parent;
|
||||
if (p != null)
|
||||
return p.socket_protect(socket);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pause_on_connection_timeout() {
|
||||
EventReceiver p = parent;
|
||||
if (p != null)
|
||||
return p.pause_on_connection_timeout();
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void event(ClientAPI_Event event) {
|
||||
EventReceiver p = parent;
|
||||
if (p != null)
|
||||
p.event(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(ClientAPI_LogInfo loginfo) {
|
||||
EventReceiver p = parent;
|
||||
if (p != null)
|
||||
p.log(loginfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void external_pki_cert_request(ClientAPI_ExternalPKICertRequest req) {
|
||||
EventReceiver p = parent;
|
||||
if (p != null)
|
||||
p.external_pki_cert_request(req);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void external_pki_sign_request(ClientAPI_ExternalPKISignRequest req) {
|
||||
EventReceiver p = parent;
|
||||
if (p != null)
|
||||
p.external_pki_sign_request(req);
|
||||
}
|
||||
|
||||
// TunBuilderBase (C++ class) overrides
|
||||
|
||||
@Override
|
||||
public boolean tun_builder_new() {
|
||||
EventReceiver p = parent;
|
||||
if (p != null) {
|
||||
tun_builder = p.tun_builder_new();
|
||||
return tun_builder != null;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tun_builder_set_remote_address(String address, boolean ipv6) {
|
||||
TunBuilder tb = tun_builder;
|
||||
if (tb != null)
|
||||
return tb.tun_builder_set_remote_address(address, ipv6);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tun_builder_add_address(String address, int prefix_length, String gateway, boolean ipv6, boolean net30) {
|
||||
TunBuilder tb = tun_builder;
|
||||
if (tb != null)
|
||||
return tb.tun_builder_add_address(address, prefix_length, gateway, ipv6, net30);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tun_builder_reroute_gw(boolean ipv4, boolean ipv6, long flags) {
|
||||
TunBuilder tb = tun_builder;
|
||||
if (tb != null)
|
||||
return tb.tun_builder_reroute_gw(ipv4, ipv6, flags);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tun_builder_add_route(String address, int prefix_length, int metric, boolean ipv6) {
|
||||
TunBuilder tb = tun_builder;
|
||||
if (tb != null)
|
||||
return tb.tun_builder_add_route(address, prefix_length, ipv6);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tun_builder_exclude_route(String address, int prefix_length, int metric, boolean ipv6) {
|
||||
TunBuilder tb = tun_builder;
|
||||
if (tb != null)
|
||||
return tb.tun_builder_exclude_route(address, prefix_length, ipv6);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tun_builder_add_dns_server(String address, boolean ipv6) {
|
||||
TunBuilder tb = tun_builder;
|
||||
if (tb != null)
|
||||
return tb.tun_builder_add_dns_server(address, ipv6);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tun_builder_add_search_domain(String domain)
|
||||
{
|
||||
TunBuilder tb = tun_builder;
|
||||
if (tb != null)
|
||||
return tb.tun_builder_add_search_domain(domain);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tun_builder_set_mtu(int mtu) {
|
||||
TunBuilder tb = tun_builder;
|
||||
if (tb != null)
|
||||
return tb.tun_builder_set_mtu(mtu);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tun_builder_set_session_name(String name)
|
||||
{
|
||||
TunBuilder tb = tun_builder;
|
||||
if (tb != null)
|
||||
return tb.tun_builder_set_session_name(name);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int tun_builder_establish() {
|
||||
TunBuilder tb = tun_builder;
|
||||
if (tb != null)
|
||||
return tb.tun_builder_establish();
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tun_builder_teardown(boolean disconnect) {
|
||||
TunBuilder tb = tun_builder;
|
||||
if (tb != null)
|
||||
tb.tun_builder_teardown(disconnect);
|
||||
}
|
||||
}
|
||||
62
OpenVPN Adapter/Vendors/openvpn/javacli/android/cpu.cpp
Normal file
62
OpenVPN Adapter/Vendors/openvpn/javacli/android/cpu.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <jni.h>
|
||||
|
||||
#ifdef SWIGEXPORT
|
||||
#define EXPORT SWIGEXPORT
|
||||
#else
|
||||
#define EXPORT
|
||||
#endif
|
||||
|
||||
#ifndef OPENVPN_PACKAGE_ID
|
||||
#error OPENVPN_PACKAGE_ID must be defined
|
||||
#endif
|
||||
|
||||
#define MAKE_SYM2(pkg_id, suffix) Java_ ## pkg_id ## _CPUUsage_ ## suffix
|
||||
#define MAKE_SYM(pkg_id, suffix) MAKE_SYM2(pkg_id, suffix)
|
||||
|
||||
#define CPU_USAGE MAKE_SYM(OPENVPN_PACKAGE_ID, cpu_1usage)
|
||||
|
||||
extern "C" {
|
||||
jdouble CPU_USAGE(JNIEnv* env, jclass);
|
||||
};
|
||||
|
||||
EXPORT jdouble CPU_USAGE(JNIEnv* env, jclass)
|
||||
{
|
||||
char fnbuf[64];
|
||||
const pid_t pid = getpid();
|
||||
double ret = 0.0;
|
||||
|
||||
snprintf(fnbuf, sizeof(fnbuf), "/proc/%u/stat", (unsigned int)pid);
|
||||
FILE *fp = fopen(fnbuf, "r");
|
||||
if (fp)
|
||||
{
|
||||
double user = 0.0;
|
||||
double system = 0.0;
|
||||
if (fscanf(fp, "%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %lf %lf", &user, &system) == 2)
|
||||
ret = (user + system) / sysconf(_SC_CLK_TCK);
|
||||
fclose(fp);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Native companion code for JellyBeanHack.java
|
||||
|
||||
#include <stdio.h>
|
||||
#include <dlfcn.h>
|
||||
#include <jni.h>
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
#ifdef SWIGEXPORT
|
||||
#define EXPORT SWIGEXPORT
|
||||
#else
|
||||
#define EXPORT
|
||||
#endif
|
||||
|
||||
#ifndef OPENVPN_PACKAGE_ID
|
||||
#error OPENVPN_PACKAGE_ID must be defined
|
||||
#endif
|
||||
|
||||
#define MAKE_SYM2(pkg_id, suffix) Java_ ## pkg_id ## _JellyBeanHack_ ## suffix
|
||||
#define MAKE_SYM(pkg_id, suffix) MAKE_SYM2(pkg_id, suffix)
|
||||
|
||||
#define RSA_SIGN_INIT MAKE_SYM(OPENVPN_PACKAGE_ID, rsa_1sign_1init)
|
||||
#define RSA_SIGN MAKE_SYM(OPENVPN_PACKAGE_ID, rsa_1sign)
|
||||
#define PKEY_RETAIN MAKE_SYM(OPENVPN_PACKAGE_ID, pkey_1retain)
|
||||
|
||||
extern "C" {
|
||||
jint RSA_SIGN_INIT(JNIEnv* env, jclass);
|
||||
jbyteArray RSA_SIGN(JNIEnv* env, jclass, jbyteArray from, jint pkeyRef);
|
||||
void PKEY_RETAIN(JNIEnv* env, jclass, jint pkeyRef);
|
||||
};
|
||||
|
||||
typedef void *RSA;
|
||||
|
||||
enum {
|
||||
NID_md5_sha1=114,
|
||||
CRYPTO_LOCK_EVP_PKEY=10,
|
||||
};
|
||||
|
||||
struct EVP_PKEY
|
||||
{
|
||||
int type;
|
||||
int save_type;
|
||||
int references;
|
||||
void *ameth;
|
||||
void *engine;
|
||||
union {
|
||||
RSA *rsa;
|
||||
} pkey;
|
||||
};
|
||||
|
||||
typedef int (*RSA_size_func_t)(const RSA *);
|
||||
|
||||
typedef int (*RSA_sign_func_t)(int type, const unsigned char *m, unsigned int m_length,
|
||||
unsigned char *sigret, unsigned int *siglen, RSA *rsa);
|
||||
|
||||
typedef void (*ERR_print_errors_fp_func_t)(FILE *fp);
|
||||
|
||||
typedef int (*CRYPTO_add_lock_func_t)(int *pointer, int amount, int type, const char *file, int line);
|
||||
|
||||
static bool initialized;
|
||||
static RSA_size_func_t RSA_size;
|
||||
static RSA_sign_func_t RSA_sign;
|
||||
static ERR_print_errors_fp_func_t ERR_print_errors_fp;
|
||||
static CRYPTO_add_lock_func_t CRYPTO_add_lock;
|
||||
|
||||
inline bool callbacks_defined()
|
||||
{
|
||||
return RSA_size != NULL
|
||||
&& RSA_sign != NULL
|
||||
&& ERR_print_errors_fp != NULL
|
||||
&& CRYPTO_add_lock != NULL;
|
||||
}
|
||||
|
||||
EXPORT jint RSA_SIGN_INIT(JNIEnv* env, jclass)
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
void *handle = dlopen("libcrypto.so", RTLD_NOW);
|
||||
if (handle)
|
||||
{
|
||||
RSA_size = (RSA_size_func_t) dlsym(handle, "RSA_size");
|
||||
RSA_sign = (RSA_sign_func_t) dlsym(handle, "RSA_sign");
|
||||
ERR_print_errors_fp = (ERR_print_errors_fp_func_t) dlsym(handle, "ERR_print_errors_fp");
|
||||
CRYPTO_add_lock = (CRYPTO_add_lock_func_t) dlsym(handle, "CRYPTO_add_lock");
|
||||
}
|
||||
initialized = true;
|
||||
}
|
||||
return callbacks_defined();
|
||||
}
|
||||
|
||||
static int jni_throw(JNIEnv* env, const char* className, const char* msg)
|
||||
{
|
||||
jclass exceptionClass = env->FindClass(className);
|
||||
|
||||
if (exceptionClass == NULL) {
|
||||
// ClassNotFoundException now pending
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (env->ThrowNew( exceptionClass, msg) != JNI_OK) {
|
||||
// an exception, most likely OOM, will now be pending
|
||||
return -1;
|
||||
}
|
||||
|
||||
env->DeleteLocalRef(exceptionClass);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT jbyteArray RSA_SIGN(JNIEnv* env, jclass, jbyteArray from, jint pkeyRef)
|
||||
{
|
||||
if (!callbacks_defined())
|
||||
{
|
||||
jni_throw(env, "java/lang/NullPointerException", "rsa_sign: OpenSSL callbacks undefined");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
|
||||
if (pkey == NULL || from == NULL)
|
||||
{
|
||||
jni_throw(env, "java/lang/NullPointerException", "rsa_sign: from/pkey is NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jbyte* data = env->GetByteArrayElements(from, NULL);
|
||||
if (data == NULL)
|
||||
{
|
||||
jni_throw(env, "java/lang/NullPointerException", "rsa_sign: data is NULL");
|
||||
return NULL;
|
||||
}
|
||||
int datalen = env->GetArrayLength(from);
|
||||
|
||||
unsigned int siglen;
|
||||
unsigned char* sigret = new unsigned char[(*RSA_size)(pkey->pkey.rsa)];
|
||||
|
||||
if ((*RSA_sign)(NID_md5_sha1, (unsigned char*) data, datalen,
|
||||
sigret, &siglen, pkey->pkey.rsa) <= 0)
|
||||
{
|
||||
jni_throw(env, "java/security/InvalidKeyException", "OpenSSL RSA_sign failed");
|
||||
(*ERR_print_errors_fp)(stderr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jbyteArray jb = env->NewByteArray(siglen);
|
||||
env->SetByteArrayRegion(jb, 0, siglen, (jbyte *)sigret);
|
||||
delete [] sigret;
|
||||
return jb;
|
||||
}
|
||||
|
||||
EXPORT void PKEY_RETAIN(JNIEnv* env, jclass, jint pkeyRef)
|
||||
{
|
||||
EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
|
||||
if (pkey && CRYPTO_add_lock)
|
||||
{
|
||||
const int newref = (*CRYPTO_add_lock)(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY, __FILE__, __LINE__);
|
||||
__android_log_print(ANDROID_LOG_DEBUG, "openvpn", "pkey_retain ref=%d", newref);
|
||||
}
|
||||
}
|
||||
116
OpenVPN Adapter/Vendors/openvpn/javacli/build-android
Executable file
116
OpenVPN Adapter/Vendors/openvpn/javacli/build-android
Executable file
@@ -0,0 +1,116 @@
|
||||
#!/usr/bin/env bash
|
||||
# generate expire time in python: time.mktime((2012, 5, 1, 0, 0, 0, 0, 0, -1))
|
||||
# -DAPP_EXPIRE_TIME=1364796000 \
|
||||
set -e
|
||||
|
||||
if [ -z "$O3" ]; then
|
||||
echo O3 var must point to ovpn3 tree
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd $O3/core
|
||||
. vars/android-sdk-path
|
||||
cd javacli
|
||||
git clean -q -fXd .
|
||||
|
||||
if [ "$PKG" ]; then
|
||||
pkg=$PKG
|
||||
pkg_id_def="-DOPENVPN_PACKAGE_ID=${PKG//./_}"
|
||||
else
|
||||
pkg=net.openvpn.openvpn
|
||||
pkg_id_def="-DOPENVPN_PACKAGE_ID=net_openvpn_openvpn"
|
||||
fi
|
||||
echo PACKAGE $PKG
|
||||
|
||||
if [ "$PT_PROXY" = "1" ] && [ -d "$O3/common" ]; then
|
||||
common="-I$O3/common -DPRIVATE_TUNNEL_PROXY"
|
||||
else
|
||||
common=""
|
||||
fi
|
||||
|
||||
echo SWIG
|
||||
swig -c++ -java -package $pkg -I$O3/core/client -I$O3/core ovpncli.i
|
||||
|
||||
# fixme: removed "android" from TARGET list due to compile failures in Asio
|
||||
for TARGET in android-a8a android-a7a ; do
|
||||
|
||||
if [ "$DEBUG_BUILD" = "1" ]; then
|
||||
. ../vars/vars-${TARGET}-dbg
|
||||
vis1=""
|
||||
vis2=""
|
||||
opt2="$pkg_id_def $LIB_OPT_LEVEL"
|
||||
else
|
||||
. ../vars/vars-${TARGET}
|
||||
vis1="-fvisibility=hidden"
|
||||
vis2='-DSWIGEXPORT=__attribute__((visibility("default")))'
|
||||
opt2="$pkg_id_def -Os"
|
||||
fi
|
||||
|
||||
if [ "$OPENSSL" = "1" ]; then
|
||||
ssl_def="-DUSE_OPENSSL"
|
||||
ssl_inc="-I$DEP_DIR/openssl/openssl-$PLATFORM/include"
|
||||
ssl_lib="-lssl -lcrypto"
|
||||
ssl_libdir="-L$DEP_DIR/openssl/openssl-$PLATFORM/lib"
|
||||
else
|
||||
ssl_def="-DUSE_MBEDTLS"
|
||||
ssl_inc="-I$DEP_DIR/mbedtls/mbedtls-$PLATFORM/include"
|
||||
ssl_lib="-lmbedtls"
|
||||
ssl_libdir="-L$DEP_DIR/mbedtls/mbedtls-$PLATFORM/library"
|
||||
fi
|
||||
|
||||
echo CORE $ABI
|
||||
g++ \
|
||||
$CXX_COMPILER_FLAGS \
|
||||
$PLATFORM_FLAGS \
|
||||
$LIB_OPT_LEVEL $LIB_FPIC \
|
||||
-Wall -Wno-sign-compare -Wno-unused-parameter \
|
||||
-Wno-unused-local-typedefs \
|
||||
$vis1 \
|
||||
$ssl_def \
|
||||
-DUSE_ASIO \
|
||||
-DASIO_STANDALONE \
|
||||
-DASIO_NO_DEPRECATED \
|
||||
-DHAVE_LZ4 \
|
||||
-I$O3/core/client \
|
||||
-I$O3/core \
|
||||
$common \
|
||||
-I$DEP_DIR/asio/asio/include \
|
||||
$ssl_inc \
|
||||
-I$DEP_DIR/lz4/lz4-$PLATFORM/include \
|
||||
-c $O3/core/client/ovpncli.cpp
|
||||
|
||||
echo WRAP $ABI
|
||||
g++ \
|
||||
$CXX_COMPILER_FLAGS \
|
||||
$PLATFORM_FLAGS \
|
||||
$opt2 $LIB_FPIC \
|
||||
-fno-strict-aliasing \
|
||||
-Wall \
|
||||
$vis1 $vis2 \
|
||||
-I$O3/core/client \
|
||||
-I$O3/core \
|
||||
$common \
|
||||
$ssl_libdir \
|
||||
-L$DEP_DIR/lz4/lz4-$PLATFORM/lib \
|
||||
ovpncli_wrap.cxx \
|
||||
android/jellybean_hack.cpp \
|
||||
android/cpu.cpp \
|
||||
ovpncli.o \
|
||||
-o libovpncli.so \
|
||||
-shared -Wl,-soname,libovpncli.so \
|
||||
$ssl_lib \
|
||||
-llz4 \
|
||||
-llog
|
||||
|
||||
if [ "$DEBUG_BUILD" != "1" ]; then
|
||||
echo STRIP $ABI
|
||||
strip libovpncli.so
|
||||
fi
|
||||
|
||||
mkdir -p build/libs/$ABI
|
||||
mv libovpncli.so build/libs/$ABI/
|
||||
rm ovpncli.o
|
||||
done
|
||||
|
||||
mv ovpncli.java ovpncliJNI.java SWIGTYPE_*.java ClientAPI_*.java build/
|
||||
git clean -q -fX .
|
||||
95
OpenVPN Adapter/Vendors/openvpn/javacli/build-linux
Executable file
95
OpenVPN Adapter/Vendors/openvpn/javacli/build-linux
Executable file
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Build OpenVPN 3 core on Linux as a callable module from Java:
|
||||
#
|
||||
# ./build-linux
|
||||
# java -Djava.library.path=. Main profile.ovpn
|
||||
|
||||
set -e
|
||||
|
||||
if [ -z "$O3" ]; then
|
||||
echo O3 var must point to ovpn3 tree
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TARGET=linux
|
||||
JINC="-I/usr/local/java/jdk1.7.0_55/include -I/usr/local/java/jdk1.7.0_55/include/linux"
|
||||
|
||||
cd $O3/core/javacli
|
||||
git clean -q -fXd .
|
||||
git clean -q -fd .
|
||||
|
||||
if [ "$DEBUG_BUILD" = "1" ]; then
|
||||
. $O3/core/vars/vars-${TARGET}-dbg
|
||||
vis1=""
|
||||
vis2=""
|
||||
opt2="$pkg_id_def $LIB_OPT_LEVEL"
|
||||
else
|
||||
. $O3/core/vars/vars-${TARGET}
|
||||
vis1="-fvisibility=hidden"
|
||||
vis2='-DSWIGEXPORT=__attribute__((visibility("default")))'
|
||||
opt2="$pkg_id_def -Os"
|
||||
fi
|
||||
|
||||
if [ "$OPENSSL" = "1" ]; then
|
||||
ssl_def="-DUSE_OPENSSL"
|
||||
ssl_inc="-I$DEP_DIR/openssl/openssl-$PLATFORM/include"
|
||||
ssl_lib="-lssl -lcrypto"
|
||||
ssl_libdir="-L$DEP_DIR/openssl/openssl-$PLATFORM/lib"
|
||||
else
|
||||
ssl_def="-DUSE_MBEDTLS"
|
||||
ssl_inc="-I$DEP_DIR/mbedtls/mbedtls-$PLATFORM/include"
|
||||
ssl_lib="-lmbedtls"
|
||||
ssl_libdir="-L$DEP_DIR/mbedtls/mbedtls-$PLATFORM/library"
|
||||
fi
|
||||
|
||||
echo SWIG
|
||||
swig -c++ -java -I$O3/core/client -I$O3/core ovpncli.i
|
||||
|
||||
echo JAVA
|
||||
javac *.java
|
||||
|
||||
echo CORE
|
||||
g++ \
|
||||
$CXX_COMPILER_FLAGS \
|
||||
$PLATFORM_FLAGS \
|
||||
$LIB_OPT_LEVEL $LIB_FPIC \
|
||||
-Wall -Wno-sign-compare -Wno-unused-parameter \
|
||||
-Wno-unused-local-typedefs \
|
||||
$vis1 \
|
||||
$ssl_def \
|
||||
-DUSE_ASIO \
|
||||
-DASIO_STANDALONE \
|
||||
-DASIO_NO_DEPRECATED \
|
||||
-DHAVE_LZ4 \
|
||||
-I$O3/core/client \
|
||||
-I$O3/core \
|
||||
-I$DEP_DIR/asio/asio/include \
|
||||
$ssl_inc \
|
||||
-I$DEP_DIR/lz4/lz4-$PLATFORM/include \
|
||||
-c $O3/core/client/ovpncli.cpp
|
||||
|
||||
echo WRAP
|
||||
g++ \
|
||||
$CXX_COMPILER_FLAGS \
|
||||
$PLATFORM_FLAGS \
|
||||
$opt2 $LIB_FPIC \
|
||||
-fno-strict-aliasing \
|
||||
-Wall \
|
||||
$vis1 $vis2 \
|
||||
-I$O3/core/client \
|
||||
-I$O3/core \
|
||||
$JINC \
|
||||
$ssl_libdir \
|
||||
-L$DEP_DIR/lz4/lz4-$PLATFORM/lib \
|
||||
ovpncli_wrap.cxx \
|
||||
ovpncli.o \
|
||||
-o libovpncli.so \
|
||||
-shared -Wl,-soname,libovpncli.so \
|
||||
$ssl_lib \
|
||||
-llz4
|
||||
|
||||
if [ "$DEBUG_BUILD" != "1" ]; then
|
||||
echo STRIP $ABI
|
||||
strip libovpncli.so
|
||||
fi
|
||||
50
OpenVPN Adapter/Vendors/openvpn/javacli/ovpncli.i
Normal file
50
OpenVPN Adapter/Vendors/openvpn/javacli/ovpncli.i
Normal file
@@ -0,0 +1,50 @@
|
||||
// SWIG interface file for OpenVPN client
|
||||
|
||||
// enable director feature for OpenVPNClientBase virtual method callbacks
|
||||
%module(directors="1") ovpncli
|
||||
%feature("director") OpenVPNClient;
|
||||
|
||||
%include "std_string.i" // for std::string typemaps
|
||||
%include "std_vector.i"
|
||||
|
||||
// top-level C++ implementation file
|
||||
%{
|
||||
#include "ovpncli.hpp"
|
||||
%}
|
||||
|
||||
// ignore ClientAPI::OpenVPNClient bases other than TunBuilderBase
|
||||
%ignore openvpn::ClientAPI::LogReceiver;
|
||||
|
||||
// modify exported C++ class names to incorporate their enclosing namespace
|
||||
%rename(ClientAPI_OpenVPNClient) OpenVPNClient;
|
||||
%rename(ClientAPI_TunBuilderBase) TunBuilderBase;
|
||||
%rename(ClientAPI_ExternalPKIBase) ExternalPKIBase;
|
||||
%rename(ClientAPI_ServerEntry) ServerEntry;
|
||||
%rename(ClientAPI_EvalConfig) EvalConfig;
|
||||
%rename(ClientAPI_ProvideCreds) ProvideCreds;
|
||||
%rename(ClientAPI_SessionToken) SessionToken;
|
||||
%rename(ClientAPI_DynamicChallenge) DynamicChallenge;
|
||||
%rename(ClientAPI_KeyValue) KeyValue;
|
||||
%rename(ClientAPI_Config) Config;
|
||||
%rename(ClientAPI_Event) Event;
|
||||
%rename(ClientAPI_ConnectionInfo) ConnectionInfo;
|
||||
%rename(ClientAPI_Status) Status;
|
||||
%rename(ClientAPI_LogInfo) LogInfo;
|
||||
%rename(ClientAPI_InterfaceStats) InterfaceStats;
|
||||
%rename(ClientAPI_TransportStats) TransportStats;
|
||||
%rename(ClientAPI_MergeConfig) MergeConfig;
|
||||
%rename(ClientAPI_ExternalPKIRequestBase) ExternalPKIRequestBase;
|
||||
%rename(ClientAPI_ExternalPKICertRequest) ExternalPKICertRequest;
|
||||
%rename(ClientAPI_ExternalPKISignRequest) ExternalPKISignRequest;
|
||||
%rename(ClientAPI_RemoteOverride) RemoteOverride;
|
||||
|
||||
// declare vectors
|
||||
namespace std {
|
||||
%template(ClientAPI_ServerEntryVector) vector<openvpn::ClientAPI::ServerEntry>;
|
||||
%template(ClientAPI_LLVector) vector<long long>;
|
||||
};
|
||||
|
||||
// interface to be bridged between C++ and target language
|
||||
%include "openvpn/pki/epkibase.hpp"
|
||||
%include "openvpn/tun/builder/base.hpp"
|
||||
%include "ovpncli.hpp"
|
||||
65
OpenVPN Adapter/Vendors/openvpn/openvpn/addr/addrlist.hpp
Normal file
65
OpenVPN Adapter/Vendors/openvpn/openvpn/addr/addrlist.hpp
Normal file
@@ -0,0 +1,65 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef OPENVPN_ADDR_ADDRLIST_H
|
||||
#define OPENVPN_ADDR_ADDRLIST_H
|
||||
|
||||
#include <openvpn/common/rc.hpp>
|
||||
#include <openvpn/addr/ip.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
namespace IP {
|
||||
|
||||
// A list of unique IP addresses
|
||||
class AddrList : public std::vector<IP::Addr>, public RC<thread_unsafe_refcount>
|
||||
{
|
||||
public:
|
||||
typedef RCPtr<AddrList> Ptr;
|
||||
|
||||
void add(const IP::Addr& a)
|
||||
{
|
||||
if (!exists(a))
|
||||
push_back(a);
|
||||
}
|
||||
|
||||
bool exists(const IP::Addr& a) const
|
||||
{
|
||||
for (const_iterator i = begin(); i != end(); ++i)
|
||||
{
|
||||
if (a == *i)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void dump() const
|
||||
{
|
||||
OPENVPN_LOG("******* AddrList::dump");
|
||||
for (const_iterator i = begin(); i != end(); ++i)
|
||||
OPENVPN_LOG(i->to_string());
|
||||
}
|
||||
#endif
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
218
OpenVPN Adapter/Vendors/openvpn/openvpn/addr/addrpair.hpp
Normal file
218
OpenVPN Adapter/Vendors/openvpn/openvpn/addr/addrpair.hpp
Normal file
@@ -0,0 +1,218 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef OPENVPN_ADDR_ADDRPAIR_H
|
||||
#define OPENVPN_ADDR_ADDRPAIR_H
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/common/number.hpp>
|
||||
#include <openvpn/common/split.hpp>
|
||||
#include <openvpn/addr/ip.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
namespace IP {
|
||||
|
||||
// AddrMaskPair is basically an object that combines an IP address (v4 or v6)
|
||||
// with a netmask or prefix length.
|
||||
struct AddrMaskPair
|
||||
{
|
||||
public:
|
||||
OPENVPN_EXCEPTION(addr_pair_mask_parse_error);
|
||||
|
||||
class StringPair {
|
||||
public:
|
||||
OPENVPN_SIMPLE_EXCEPTION(addr_pair_string_error);
|
||||
|
||||
StringPair()
|
||||
: size_(0)
|
||||
{
|
||||
}
|
||||
|
||||
explicit StringPair(const std::string& s1)
|
||||
: size_(1)
|
||||
{
|
||||
data[0] = s1;
|
||||
}
|
||||
|
||||
explicit StringPair(const std::string& s1, const std::string& s2)
|
||||
: size_(2)
|
||||
{
|
||||
data[0] = s1;
|
||||
data[1] = s2;
|
||||
}
|
||||
|
||||
void push_back(const std::string& s)
|
||||
{
|
||||
if (size_ < 2)
|
||||
data[size_++] = s;
|
||||
else
|
||||
throw addr_pair_string_error();
|
||||
}
|
||||
|
||||
const std::string& operator[](const size_t i) const
|
||||
{
|
||||
if (i >= 2)
|
||||
throw addr_pair_string_error();
|
||||
return data[i];
|
||||
}
|
||||
|
||||
std::string& operator[](const size_t i)
|
||||
{
|
||||
if (i >= 2)
|
||||
throw addr_pair_string_error();
|
||||
return data[i];
|
||||
}
|
||||
|
||||
size_t size() const { return size_; }
|
||||
|
||||
std::string render() const
|
||||
{
|
||||
switch (size_)
|
||||
{
|
||||
case 1:
|
||||
return data[0];
|
||||
case 2:
|
||||
return data[0] + "/" + data[1];
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::string data[2];
|
||||
unsigned int size_;
|
||||
};
|
||||
|
||||
static AddrMaskPair from_string(const std::string& s1, const std::string& s2, const char *title = nullptr)
|
||||
{
|
||||
try {
|
||||
if (s2.empty())
|
||||
{
|
||||
const StringPair pair = Split::by_char<StringPair, NullLex, Split::NullLimit>(s1, '/');
|
||||
return from_string_impl(pair, title);
|
||||
}
|
||||
else
|
||||
{
|
||||
const StringPair pair(s1, s2);
|
||||
return from_string_impl(pair, title);
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
const StringPair pair(s1, s2);
|
||||
error(e, pair.render(), title);
|
||||
}
|
||||
return AddrMaskPair(); // NOTREACHED
|
||||
}
|
||||
|
||||
static AddrMaskPair from_string(const std::string& s, const char *title = nullptr)
|
||||
{
|
||||
try {
|
||||
const StringPair pair = Split::by_char<StringPair, NullLex, Split::NullLimit>(s, '/');
|
||||
return from_string_impl(pair, title);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
error(e, s, title);
|
||||
}
|
||||
return AddrMaskPair(); // NOTREACHED
|
||||
}
|
||||
|
||||
static AddrMaskPair from_string(const StringPair& pair, const char *title = nullptr)
|
||||
{
|
||||
try {
|
||||
return from_string_impl(pair, title);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
error(e, pair.render(), title);
|
||||
}
|
||||
return AddrMaskPair(); // NOTREACHED
|
||||
}
|
||||
|
||||
std::string to_string(const bool netmask_form=false) const
|
||||
{
|
||||
std::ostringstream os;
|
||||
if (netmask_form)
|
||||
os << addr.to_string() << '/' << netmask.to_string();
|
||||
else
|
||||
os << addr.to_string() << '/' << netmask.prefix_len();
|
||||
return os.str();
|
||||
}
|
||||
|
||||
bool is_canonical() const
|
||||
{
|
||||
return (addr & netmask) == addr;
|
||||
}
|
||||
|
||||
Addr::Version version() const
|
||||
{
|
||||
const Addr::Version v1 = addr.version();
|
||||
const Addr::Version v2 = netmask.version();
|
||||
if (v1 == v2)
|
||||
return v1;
|
||||
else
|
||||
return Addr::UNSPEC;
|
||||
}
|
||||
|
||||
Addr addr;
|
||||
Addr netmask;
|
||||
|
||||
private:
|
||||
static void error(const std::exception& e, const std::string& s, const char *title)
|
||||
{
|
||||
if (!title)
|
||||
title = "";
|
||||
OPENVPN_THROW(addr_pair_mask_parse_error, "AddrMaskPair parse error '" << title << "': " << s << " : " << e.what());
|
||||
}
|
||||
|
||||
static AddrMaskPair from_string_impl(const StringPair& pair, const char *title = nullptr)
|
||||
{
|
||||
AddrMaskPair ret;
|
||||
if (pair.size() == 1 || pair.size() == 2)
|
||||
{
|
||||
ret.addr = Addr::from_string(pair[0], title);
|
||||
if (pair.size() == 2 && !pair[1].empty())
|
||||
{
|
||||
if (is_number(pair[1].c_str()))
|
||||
ret.netmask = Addr::netmask_from_prefix_len(ret.addr.version(),
|
||||
parse_number_throw<unsigned int>(pair[1], "prefix length"));
|
||||
else
|
||||
ret.netmask = Addr::from_string(pair[1]);
|
||||
ret.netmask.prefix_len(); // verify that netmask is ok
|
||||
}
|
||||
else
|
||||
ret.netmask = Addr::from_zero_complement(ret.addr.version());
|
||||
ret.addr.verify_version_consistency(ret.netmask);
|
||||
}
|
||||
else
|
||||
throw addr_pair_mask_parse_error("only one or two address terms allowed");
|
||||
return ret;
|
||||
}
|
||||
|
||||
};
|
||||
OPENVPN_OSTREAM(AddrMaskPair, to_string)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
956
OpenVPN Adapter/Vendors/openvpn/openvpn/addr/ip.hpp
Normal file
956
OpenVPN Adapter/Vendors/openvpn/openvpn/addr/ip.hpp
Normal file
@@ -0,0 +1,956 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef OPENVPN_ADDR_IP_H
|
||||
#define OPENVPN_ADDR_IP_H
|
||||
|
||||
#include <string>
|
||||
#include <cstring> // for std::memset
|
||||
|
||||
#include <openvpn/io/io.hpp>
|
||||
|
||||
#include <openvpn/common/size.hpp>
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/common/ostream.hpp>
|
||||
#include <openvpn/common/hash.hpp>
|
||||
#include <openvpn/addr/ipv4.hpp>
|
||||
#include <openvpn/addr/ipv6.hpp>
|
||||
#include <openvpn/addr/iperr.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
// This is our fundamental IP address class that handles IPv4 or IPv6
|
||||
// IP addresses. It is implemented as a discriminated union of IPv4::Addr
|
||||
// and IPv6::Addr.
|
||||
namespace IP {
|
||||
|
||||
OPENVPN_EXCEPTION(ip_exception);
|
||||
|
||||
class Addr
|
||||
{
|
||||
public:
|
||||
enum Version { UNSPEC, V4, V6 };
|
||||
|
||||
enum { V4_MASK=(1<<0), V6_MASK=(1<<1) };
|
||||
typedef unsigned int VersionMask;
|
||||
|
||||
enum VersionSize {
|
||||
V4_SIZE = IPv4::Addr::SIZE,
|
||||
V6_SIZE = IPv6::Addr::SIZE,
|
||||
};
|
||||
|
||||
Addr(const Addr& other, const char *title = nullptr, Version required_version = UNSPEC)
|
||||
: ver(other.ver)
|
||||
{
|
||||
other.validate_version(title, required_version);
|
||||
switch (ver)
|
||||
{
|
||||
case V4:
|
||||
u.v4 = other.u.v4;
|
||||
break;
|
||||
case V6:
|
||||
u.v6 = other.u.v6;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Addr(const std::string& ipstr, const char *title = nullptr, Version required_version = UNSPEC)
|
||||
: Addr(from_string(ipstr, title, required_version))
|
||||
{
|
||||
}
|
||||
|
||||
Addr(const std::string& ipstr, const std::string& title, Version required_version = UNSPEC)
|
||||
: Addr(from_string(ipstr, title.c_str(), required_version))
|
||||
{
|
||||
}
|
||||
|
||||
void validate_version(const char *title, Version required_version) const
|
||||
{
|
||||
if (required_version != UNSPEC && required_version != ver)
|
||||
throw ip_exception(internal::format_error(to_string(), title, version_string_static(required_version), "wrong IP version"));
|
||||
}
|
||||
|
||||
void validate_version(const std::string& title, Version required_version) const
|
||||
{
|
||||
validate_version(title.c_str(), required_version);
|
||||
}
|
||||
|
||||
static std::string validate(const std::string& ipstr, const char *title = nullptr, Version required_version = UNSPEC)
|
||||
{
|
||||
Addr a = from_string(ipstr, title, required_version);
|
||||
return a.to_string();
|
||||
}
|
||||
|
||||
static std::string validate(const std::string& ipstr, const std::string& title, Version required_version = UNSPEC)
|
||||
{
|
||||
return validate(ipstr, title.c_str(), required_version);
|
||||
}
|
||||
|
||||
static bool is_valid(const std::string& ipstr)
|
||||
{
|
||||
// fast path -- rule out validity if invalid chars
|
||||
for (size_t i = 0; i < ipstr.length(); ++i)
|
||||
{
|
||||
const char c = ipstr[i];
|
||||
if (!((c >= '0' && c <= '9')
|
||||
|| (c >= 'a' && c <= 'f')
|
||||
|| (c >= 'A' && c <= 'F')
|
||||
|| (c == '.' || c == ':' || c == '%')))
|
||||
return false;
|
||||
}
|
||||
|
||||
// slow path
|
||||
{
|
||||
openvpn_io::error_code ec;
|
||||
openvpn_io::ip::make_address(ipstr, ec);
|
||||
return !ec;
|
||||
}
|
||||
}
|
||||
|
||||
static Addr from_string(const std::string& ipstr, const char *title = nullptr, Version required_version = UNSPEC)
|
||||
{
|
||||
openvpn_io::error_code ec;
|
||||
openvpn_io::ip::address a = openvpn_io::ip::make_address(ipstr, ec);
|
||||
if (ec)
|
||||
throw ip_exception(internal::format_error(ipstr, title, "", ec));
|
||||
const Addr ret = from_asio(a);
|
||||
if (required_version != UNSPEC && required_version != ret.ver)
|
||||
throw ip_exception(internal::format_error(ipstr, title, version_string_static(required_version), "wrong IP version"));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Addr from_hex(Version v, const std::string& s)
|
||||
{
|
||||
if (v == V4)
|
||||
return from_ipv4(IPv4::Addr::from_hex(s));
|
||||
else if (v == V6)
|
||||
return from_ipv6(IPv6::Addr::from_hex(s));
|
||||
else
|
||||
throw ip_exception("address unspecified");
|
||||
}
|
||||
|
||||
static Addr from_ipv4(const IPv4::Addr& addr)
|
||||
{
|
||||
Addr a;
|
||||
a.ver = V4;
|
||||
a.u.v4 = addr;
|
||||
return a;
|
||||
}
|
||||
|
||||
static Addr from_ipv6(const IPv6::Addr& addr)
|
||||
{
|
||||
Addr a;
|
||||
a.ver = V6;
|
||||
a.u.v6 = addr;
|
||||
return a;
|
||||
}
|
||||
|
||||
const IPv4::Addr& to_ipv4() const
|
||||
{
|
||||
if (ver == V4)
|
||||
return u.v4;
|
||||
else
|
||||
throw ip_exception("address is not IPv4");
|
||||
}
|
||||
|
||||
const IPv6::Addr& to_ipv6() const
|
||||
{
|
||||
if (ver == V6)
|
||||
return u.v6;
|
||||
else
|
||||
throw ip_exception("address is not IPv6");
|
||||
}
|
||||
|
||||
const IPv4::Addr& to_ipv4_nocheck() const
|
||||
{
|
||||
return u.v4;
|
||||
}
|
||||
|
||||
const IPv6::Addr& to_ipv6_nocheck() const
|
||||
{
|
||||
return u.v6;
|
||||
}
|
||||
|
||||
static Addr from_sockaddr(const struct sockaddr *sa)
|
||||
{
|
||||
if (sa->sa_family == AF_INET)
|
||||
return from_ipv4(IPv4::Addr::from_sockaddr((struct sockaddr_in *)sa));
|
||||
else if (sa->sa_family == AF_INET6)
|
||||
return from_ipv6(IPv6::Addr::from_sockaddr((struct sockaddr_in6 *)sa));
|
||||
else
|
||||
return Addr();
|
||||
}
|
||||
|
||||
static bool sockaddr_defined(const struct sockaddr *sa)
|
||||
{
|
||||
return sa && (sa->sa_family == AF_INET || sa->sa_family == AF_INET6);
|
||||
}
|
||||
|
||||
static Addr from_ulong(Version v, unsigned long ul)
|
||||
{
|
||||
if (v == V4)
|
||||
return from_ipv4(IPv4::Addr::from_ulong(ul));
|
||||
else if (v == V6)
|
||||
return from_ipv6(IPv6::Addr::from_ulong(ul));
|
||||
else
|
||||
throw ip_exception("address unspecified");
|
||||
}
|
||||
|
||||
// return *this as a ulong, will raise exception on overflow
|
||||
unsigned long to_ulong() const
|
||||
{
|
||||
if (ver == V4)
|
||||
return u.v4.to_ulong();
|
||||
else if (ver == V6)
|
||||
return u.v6.to_ulong();
|
||||
else
|
||||
throw ip_exception("address unspecified");
|
||||
}
|
||||
|
||||
static Addr from_long(Version v, long ul)
|
||||
{
|
||||
if (v == V4)
|
||||
return from_ipv4(IPv4::Addr::from_long(ul));
|
||||
else if (v == V6)
|
||||
return from_ipv6(IPv6::Addr::from_long(ul));
|
||||
else
|
||||
throw ip_exception("address unspecified");
|
||||
}
|
||||
|
||||
// return *this as a long, will raise exception on overflow
|
||||
long to_long() const
|
||||
{
|
||||
if (ver == V4)
|
||||
return u.v4.to_long();
|
||||
else if (ver == V6)
|
||||
return u.v6.to_long();
|
||||
else
|
||||
throw ip_exception("address unspecified");
|
||||
}
|
||||
|
||||
// return Addr from 16 byte binary string
|
||||
static Addr from_byte_string(const unsigned char *bytestr)
|
||||
{
|
||||
Addr a;
|
||||
if (IPv6::Addr::byte_string_is_v4(bytestr))
|
||||
{
|
||||
a.ver = V4;
|
||||
a.u.v4 = IPv4::Addr::from_uint32_net(IPv6::Addr::v4_from_byte_string(bytestr));
|
||||
}
|
||||
else
|
||||
{
|
||||
a.ver = V4;
|
||||
a.u.v6 = IPv6::Addr::from_byte_string(bytestr);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
// convert Addr to 16 byte binary string
|
||||
void to_byte_string(unsigned char *bytestr) const
|
||||
{
|
||||
if (ver == V4)
|
||||
IPv6::Addr::v4_to_byte_string(bytestr, u.v4.to_uint32_net());
|
||||
else if (ver == V6)
|
||||
u.v6.to_byte_string(bytestr);
|
||||
else
|
||||
std::memset(bytestr, 0, 16);
|
||||
}
|
||||
|
||||
// convert Addr to variable length byte string
|
||||
void to_byte_string_variable(unsigned char *bytestr) const
|
||||
{
|
||||
if (ver == V4)
|
||||
u.v4.to_byte_string(bytestr);
|
||||
else if (ver == V6)
|
||||
u.v6.to_byte_string(bytestr);
|
||||
else
|
||||
throw ip_exception("address unspecified");
|
||||
}
|
||||
|
||||
std::uint32_t to_uint32_net() const // return value in net byte order
|
||||
{
|
||||
if (ver == V4)
|
||||
return u.v4.to_uint32_net();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
// construct an address where all bits are zero
|
||||
static Addr from_zero(Version v)
|
||||
{
|
||||
if (v == V4)
|
||||
return from_ipv4(IPv4::Addr::from_zero());
|
||||
else if (v == V6)
|
||||
return from_ipv6(IPv6::Addr::from_zero());
|
||||
else
|
||||
throw ip_exception("address unspecified");
|
||||
}
|
||||
|
||||
// construct an address where all bits are zero
|
||||
static Addr from_one(Version v)
|
||||
{
|
||||
if (v == V4)
|
||||
return from_ipv4(IPv4::Addr::from_one());
|
||||
else if (v == V6)
|
||||
return from_ipv6(IPv6::Addr::from_one());
|
||||
else
|
||||
throw ip_exception("address unspecified");
|
||||
}
|
||||
|
||||
// construct an address where all bits are one
|
||||
static Addr from_zero_complement(Version v)
|
||||
{
|
||||
if (v == V4)
|
||||
return from_ipv4(IPv4::Addr::from_zero_complement());
|
||||
else if (v == V6)
|
||||
return from_ipv6(IPv6::Addr::from_zero_complement());
|
||||
else
|
||||
throw ip_exception("address unspecified");
|
||||
}
|
||||
|
||||
// build a netmask using given prefix_len
|
||||
static Addr netmask_from_prefix_len(Version v, const unsigned int prefix_len)
|
||||
{
|
||||
if (v == V4)
|
||||
return from_ipv4(IPv4::Addr::netmask_from_prefix_len(prefix_len));
|
||||
else if (v == V6)
|
||||
return from_ipv6(IPv6::Addr::netmask_from_prefix_len(prefix_len));
|
||||
else
|
||||
throw ip_exception("address unspecified");
|
||||
}
|
||||
|
||||
// build a netmask using *this as extent
|
||||
Addr netmask_from_extent() const
|
||||
{
|
||||
if (ver == V4)
|
||||
return from_ipv4(u.v4.netmask_from_extent());
|
||||
else if (ver == V6)
|
||||
return from_ipv6(u.v6.netmask_from_extent());
|
||||
else
|
||||
throw ip_exception("address unspecified");
|
||||
}
|
||||
|
||||
std::string to_string() const
|
||||
{
|
||||
if (ver != UNSPEC)
|
||||
{
|
||||
const openvpn_io::ip::address a = to_asio();
|
||||
std::string ret = a.to_string();
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
return "UNSPEC";
|
||||
}
|
||||
|
||||
std::string to_string_bracket_ipv6() const
|
||||
{
|
||||
std::string ret;
|
||||
if (ver == V6)
|
||||
ret += '[';
|
||||
ret += to_string();
|
||||
if (ver == V6)
|
||||
ret += ']';
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string to_hex() const
|
||||
{
|
||||
if (ver == V4)
|
||||
return u.v4.to_hex();
|
||||
else if (ver == V6)
|
||||
return u.v6.to_hex();
|
||||
else
|
||||
throw ip_exception("address unspecified");
|
||||
}
|
||||
|
||||
std::string arpa() const
|
||||
{
|
||||
if (ver == V4)
|
||||
return u.v4.arpa();
|
||||
else if (ver == V6)
|
||||
return u.v6.arpa();
|
||||
else
|
||||
throw ip_exception("address unspecified");
|
||||
}
|
||||
|
||||
static Addr from_asio(const openvpn_io::ip::address& addr)
|
||||
{
|
||||
if (addr.is_v4())
|
||||
{
|
||||
Addr a;
|
||||
a.ver = V4;
|
||||
a.u.v4 = IPv4::Addr::from_asio(addr.to_v4());
|
||||
return a;
|
||||
}
|
||||
else if (addr.is_v6())
|
||||
{
|
||||
Addr a;
|
||||
a.ver = V6;
|
||||
a.u.v6 = IPv6::Addr::from_asio(addr.to_v6());
|
||||
return a;
|
||||
}
|
||||
else
|
||||
throw ip_exception("address unspecified");
|
||||
}
|
||||
|
||||
openvpn_io::ip::address to_asio() const
|
||||
{
|
||||
switch (ver)
|
||||
{
|
||||
case V4:
|
||||
return openvpn_io::ip::address_v4(u.v4.to_asio());
|
||||
case V6:
|
||||
return openvpn_io::ip::address_v6(u.v6.to_asio());
|
||||
default:
|
||||
throw ip_exception("address unspecified");
|
||||
}
|
||||
}
|
||||
|
||||
Addr operator+(const long delta) const {
|
||||
switch (ver)
|
||||
{
|
||||
case V4:
|
||||
{
|
||||
Addr ret;
|
||||
ret.ver = V4;
|
||||
ret.u.v4 = u.v4 + delta;
|
||||
return ret;
|
||||
}
|
||||
case V6:
|
||||
{
|
||||
Addr ret;
|
||||
ret.ver = V6;
|
||||
ret.u.v6 = u.v6 + delta;
|
||||
return ret;
|
||||
}
|
||||
default:
|
||||
throw ip_exception("address unspecified");
|
||||
}
|
||||
}
|
||||
|
||||
Addr operator-(const long delta) const {
|
||||
return operator+(-delta);
|
||||
}
|
||||
|
||||
#define OPENVPN_IP_OPERATOR_BINOP(OP) \
|
||||
Addr operator OP (const Addr& other) const { \
|
||||
if (ver != other.ver) \
|
||||
throw ip_exception("version inconsistency"); \
|
||||
switch (ver) \
|
||||
{ \
|
||||
case V4: \
|
||||
{ \
|
||||
Addr ret; \
|
||||
ret.ver = V4; \
|
||||
ret.u.v4 = u.v4 OP other.u.v4; \
|
||||
return ret; \
|
||||
} \
|
||||
case V6: \
|
||||
{ \
|
||||
Addr ret; \
|
||||
ret.ver = V6; \
|
||||
ret.u.v6 = u.v6 OP other.u.v6; \
|
||||
return ret; \
|
||||
} \
|
||||
default: \
|
||||
throw ip_exception("address unspecified"); \
|
||||
} \
|
||||
}
|
||||
|
||||
OPENVPN_IP_OPERATOR_BINOP(+)
|
||||
OPENVPN_IP_OPERATOR_BINOP(-)
|
||||
OPENVPN_IP_OPERATOR_BINOP(*)
|
||||
OPENVPN_IP_OPERATOR_BINOP(/)
|
||||
OPENVPN_IP_OPERATOR_BINOP(%)
|
||||
OPENVPN_IP_OPERATOR_BINOP(&)
|
||||
OPENVPN_IP_OPERATOR_BINOP(|)
|
||||
|
||||
#undef OPENVPN_IP_OPERATOR_BINOP
|
||||
|
||||
Addr operator<<(const unsigned int shift) const {
|
||||
switch (ver)
|
||||
{
|
||||
case V4:
|
||||
{
|
||||
Addr ret;
|
||||
ret.ver = V4;
|
||||
ret.u.v4 = u.v4 << shift;
|
||||
return ret;
|
||||
}
|
||||
case V6:
|
||||
{
|
||||
Addr ret;
|
||||
ret.ver = V6;
|
||||
ret.u.v6 = u.v6 << shift;
|
||||
return ret;
|
||||
}
|
||||
default:
|
||||
throw ip_exception("address unspecified");
|
||||
}
|
||||
}
|
||||
|
||||
Addr operator>>(const unsigned int shift) const {
|
||||
switch (ver)
|
||||
{
|
||||
case V4:
|
||||
{
|
||||
Addr ret;
|
||||
ret.ver = V4;
|
||||
ret.u.v4 = u.v4 >> shift;
|
||||
return ret;
|
||||
}
|
||||
case V6:
|
||||
{
|
||||
Addr ret;
|
||||
ret.ver = V6;
|
||||
ret.u.v6 = u.v6 >> shift;
|
||||
return ret;
|
||||
}
|
||||
default:
|
||||
throw ip_exception("address unspecified");
|
||||
}
|
||||
}
|
||||
|
||||
Addr operator~() const {
|
||||
switch (ver)
|
||||
{
|
||||
case V4:
|
||||
{
|
||||
Addr ret;
|
||||
ret.ver = V4;
|
||||
ret.u.v4 = ~u.v4;
|
||||
return ret;
|
||||
}
|
||||
case V6:
|
||||
{
|
||||
Addr ret;
|
||||
ret.ver = V6;
|
||||
ret.u.v6 = ~u.v6;
|
||||
return ret;
|
||||
}
|
||||
default:
|
||||
throw ip_exception("address unspecified");
|
||||
}
|
||||
}
|
||||
|
||||
Addr network_addr(const unsigned int prefix_len) const {
|
||||
switch (ver)
|
||||
{
|
||||
case V4:
|
||||
{
|
||||
Addr ret;
|
||||
ret.ver = V4;
|
||||
ret.u.v4 = u.v4.network_addr(prefix_len);
|
||||
return ret;
|
||||
}
|
||||
case V6:
|
||||
{
|
||||
Addr ret;
|
||||
ret.ver = V6;
|
||||
ret.u.v6 = u.v6.network_addr(prefix_len);
|
||||
return ret;
|
||||
}
|
||||
default:
|
||||
throw ip_exception("address unspecified");
|
||||
}
|
||||
}
|
||||
|
||||
bool operator==(const Addr& other) const
|
||||
{
|
||||
switch (ver)
|
||||
{
|
||||
case UNSPEC:
|
||||
return other.ver == UNSPEC;
|
||||
case V4:
|
||||
if (ver == other.ver)
|
||||
return u.v4 == other.u.v4;
|
||||
break;
|
||||
case V6:
|
||||
if (ver == other.ver)
|
||||
return u.v6 == other.u.v6;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator!=(const Addr& other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
#define OPENVPN_IP_OPERATOR_REL(OP) \
|
||||
bool operator OP(const Addr& other) const \
|
||||
{ \
|
||||
if (ver == other.ver) \
|
||||
{ \
|
||||
switch (ver) \
|
||||
{ \
|
||||
case V4: \
|
||||
return u.v4 OP other.u.v4; \
|
||||
case V6: \
|
||||
return u.v6 OP other.u.v6; \
|
||||
default: \
|
||||
return false; \
|
||||
} \
|
||||
} \
|
||||
else if (ver OP other.ver) \
|
||||
return true; \
|
||||
else \
|
||||
return false; \
|
||||
}
|
||||
|
||||
OPENVPN_IP_OPERATOR_REL(<)
|
||||
OPENVPN_IP_OPERATOR_REL(>)
|
||||
OPENVPN_IP_OPERATOR_REL(<=)
|
||||
OPENVPN_IP_OPERATOR_REL(>=)
|
||||
|
||||
#undef OPENVPN_IP_OPERATOR_REL
|
||||
|
||||
bool unspecified() const
|
||||
{
|
||||
return all_zeros();
|
||||
}
|
||||
|
||||
bool specified() const
|
||||
{
|
||||
return !unspecified();
|
||||
}
|
||||
|
||||
bool all_zeros() const
|
||||
{
|
||||
switch (ver)
|
||||
{
|
||||
case V4:
|
||||
return u.v4.all_zeros();
|
||||
case V6:
|
||||
return u.v6.all_zeros();
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool all_ones() const
|
||||
{
|
||||
switch (ver)
|
||||
{
|
||||
case V4:
|
||||
return u.v4.all_ones();
|
||||
case V6:
|
||||
return u.v6.all_ones();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_loopback() const
|
||||
{
|
||||
switch (ver)
|
||||
{
|
||||
case V4:
|
||||
return u.v4.is_loopback();
|
||||
case V6:
|
||||
return u.v6.is_loopback();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool defined() const
|
||||
{
|
||||
return ver != UNSPEC;
|
||||
}
|
||||
|
||||
const char *version_string() const
|
||||
{
|
||||
return version_string_static(ver);
|
||||
}
|
||||
|
||||
static const char *version_string_static(Version ver)
|
||||
{
|
||||
switch (ver)
|
||||
{
|
||||
case V4:
|
||||
return "v4";
|
||||
case V6:
|
||||
return "v6";
|
||||
default:
|
||||
return "v?";
|
||||
}
|
||||
}
|
||||
|
||||
Version version() const { return ver; }
|
||||
|
||||
static VersionMask version_mask(const Version ver)
|
||||
{
|
||||
switch (ver)
|
||||
{
|
||||
case V4:
|
||||
return V4_MASK;
|
||||
case V6:
|
||||
return V6_MASK;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
VersionMask version_mask() const
|
||||
{
|
||||
return version_mask(ver);
|
||||
}
|
||||
|
||||
int version_index() const
|
||||
{
|
||||
switch (ver)
|
||||
{
|
||||
case V4:
|
||||
return 0;
|
||||
case V6:
|
||||
return 1;
|
||||
default:
|
||||
throw ip_exception("version index undefined");
|
||||
}
|
||||
}
|
||||
|
||||
int family() const
|
||||
{
|
||||
switch (ver)
|
||||
{
|
||||
case V4:
|
||||
return AF_INET;
|
||||
case V6:
|
||||
return AF_INET6;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_compatible(const Addr& other) const
|
||||
{
|
||||
return ver == other.ver;
|
||||
}
|
||||
|
||||
bool is_ipv6() const
|
||||
{
|
||||
return ver == V6;
|
||||
}
|
||||
|
||||
void verify_version_consistency(const Addr& other) const
|
||||
{
|
||||
if (!is_compatible(other))
|
||||
throw ip_exception("version inconsistency");
|
||||
}
|
||||
|
||||
// throw exception if address is not a valid netmask
|
||||
void validate_netmask()
|
||||
{
|
||||
prefix_len();
|
||||
}
|
||||
|
||||
// number of network bits in netmask,
|
||||
// throws exception if addr is not a netmask
|
||||
unsigned int prefix_len() const
|
||||
{
|
||||
switch (ver)
|
||||
{
|
||||
case V4:
|
||||
return u.v4.prefix_len();
|
||||
case V6:
|
||||
return u.v6.prefix_len();
|
||||
default:
|
||||
throw ip_exception("address unspecified");
|
||||
}
|
||||
}
|
||||
|
||||
// IPv6 scope ID or -1 if not IPv6
|
||||
int scope_id() const
|
||||
{
|
||||
return ver == V6 ? u.v6.scope_id() : -1;
|
||||
}
|
||||
|
||||
// number of host bits in netmask
|
||||
unsigned int host_len() const
|
||||
{
|
||||
switch (ver)
|
||||
{
|
||||
case V4:
|
||||
return u.v4.host_len();
|
||||
case V6:
|
||||
return u.v6.host_len();
|
||||
default:
|
||||
throw ip_exception("address unspecified");
|
||||
}
|
||||
}
|
||||
|
||||
// return the number of host addresses contained within netmask
|
||||
Addr extent_from_netmask() const
|
||||
{
|
||||
switch (ver)
|
||||
{
|
||||
case V4:
|
||||
return from_ipv4(u.v4.extent_from_netmask());
|
||||
case V6:
|
||||
return from_ipv6(u.v6.extent_from_netmask());
|
||||
default:
|
||||
throw ip_exception("address unspecified");
|
||||
}
|
||||
}
|
||||
|
||||
// address size in bits
|
||||
unsigned int size() const
|
||||
{
|
||||
return version_size(ver);
|
||||
}
|
||||
|
||||
// address size in bytes
|
||||
unsigned int size_bytes() const
|
||||
{
|
||||
return size() / 8;
|
||||
}
|
||||
|
||||
// address size in bits of particular IP version
|
||||
static unsigned int version_size(Version v)
|
||||
{
|
||||
if (v == V4)
|
||||
return IPv4::Addr::SIZE;
|
||||
else if (v == V6)
|
||||
return IPv6::Addr::SIZE;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::size_t hashval() const
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
switch (ver)
|
||||
{
|
||||
case Addr::V4:
|
||||
Hash::combine(seed, 4, u.v4);
|
||||
break;
|
||||
case Addr::V6:
|
||||
Hash::combine(seed, 6, u.v6);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return seed;
|
||||
}
|
||||
|
||||
#ifdef OPENVPN_IP_IMMUTABLE
|
||||
private:
|
||||
#endif
|
||||
|
||||
Addr()
|
||||
: ver(UNSPEC)
|
||||
{
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
ver = UNSPEC;
|
||||
}
|
||||
|
||||
Addr& operator=(const Addr& other)
|
||||
{
|
||||
switch (ver = other.ver)
|
||||
{
|
||||
case V4:
|
||||
u.v4 = other.u.v4;
|
||||
break;
|
||||
case V6:
|
||||
u.v6 = other.u.v6;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Addr& operator++()
|
||||
{
|
||||
switch (ver)
|
||||
{
|
||||
case V4:
|
||||
++u.v4;
|
||||
break;
|
||||
case V6:
|
||||
++u.v6;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Addr& operator+=(const long delta)
|
||||
{
|
||||
switch (ver)
|
||||
{
|
||||
case V4:
|
||||
u.v4 += delta;
|
||||
break;
|
||||
case V6:
|
||||
u.v6 += delta;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Addr& operator-=(const long delta)
|
||||
{
|
||||
switch (ver)
|
||||
{
|
||||
case V4:
|
||||
u.v4 -= delta;
|
||||
break;
|
||||
case V6:
|
||||
u.v6 -= delta;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void reset_ipv4_from_uint32(const IPv4::Addr::base_type addr)
|
||||
{
|
||||
ver = V4;
|
||||
u.v4 = IPv4::Addr::from_uint32(addr);
|
||||
}
|
||||
|
||||
private:
|
||||
union {
|
||||
IPv4::Addr v4;
|
||||
IPv6::Addr v6;
|
||||
} u;
|
||||
|
||||
Version ver;
|
||||
};
|
||||
|
||||
OPENVPN_OSTREAM(Addr, to_string)
|
||||
}
|
||||
}
|
||||
|
||||
OPENVPN_HASH_METHOD(openvpn::IP::Addr, hashval);
|
||||
|
||||
#endif
|
||||
75
OpenVPN Adapter/Vendors/openvpn/openvpn/addr/iperr.hpp
Normal file
75
OpenVPN Adapter/Vendors/openvpn/openvpn/addr/iperr.hpp
Normal file
@@ -0,0 +1,75 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef OPENVPN_ADDR_IPERR_H
|
||||
#define OPENVPN_ADDR_IPERR_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <openvpn/io/io.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
namespace IP {
|
||||
namespace internal {
|
||||
// Called internally by IP, IPv4, and IPv6 classes
|
||||
|
||||
inline std::string format_error(const std::string& ipstr, const char *title, const char *ipver, const openvpn_io::error_code& ec)
|
||||
{
|
||||
std::string err = "error parsing";
|
||||
if (title)
|
||||
{
|
||||
err += ' ';
|
||||
err += title;
|
||||
}
|
||||
err += " IP";
|
||||
err += ipver;
|
||||
err += " address '";
|
||||
err += ipstr;
|
||||
err += "' : ";
|
||||
err += ec.message();
|
||||
return err;
|
||||
}
|
||||
|
||||
inline std::string format_error(const std::string& ipstr, const char *title, const char *ipver, const char *message)
|
||||
{
|
||||
std::string err = "error parsing";
|
||||
if (title)
|
||||
{
|
||||
err += ' ';
|
||||
err += title;
|
||||
}
|
||||
err += " IP";
|
||||
err += ipver;
|
||||
err += " address '";
|
||||
err += ipstr;
|
||||
err += '\'';
|
||||
if (message)
|
||||
{
|
||||
err += " : ";
|
||||
err += message;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
571
OpenVPN Adapter/Vendors/openvpn/openvpn/addr/ipv4.hpp
Normal file
571
OpenVPN Adapter/Vendors/openvpn/openvpn/addr/ipv4.hpp
Normal file
@@ -0,0 +1,571 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef OPENVPN_ADDR_IPV4_H
|
||||
#define OPENVPN_ADDR_IPV4_H
|
||||
|
||||
#include <cstring> // for std::memcpy, std::memset
|
||||
#include <sstream>
|
||||
#include <cstdint> // for std::uint32_t
|
||||
|
||||
#include <openvpn/io/io.hpp>
|
||||
|
||||
#include <openvpn/common/size.hpp>
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/common/endian.hpp>
|
||||
#include <openvpn/common/ostream.hpp>
|
||||
#include <openvpn/common/socktypes.hpp>
|
||||
#include <openvpn/common/ffs.hpp>
|
||||
#include <openvpn/common/hexstr.hpp>
|
||||
#include <openvpn/common/hash.hpp>
|
||||
#include <openvpn/addr/iperr.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
namespace IP {
|
||||
class Addr;
|
||||
}
|
||||
|
||||
// Fundamental classes for representing an IPv4 IP address.
|
||||
|
||||
namespace IPv4 {
|
||||
|
||||
OPENVPN_EXCEPTION(ipv4_exception);
|
||||
|
||||
class Addr // NOTE: must be union-legal, so default constructor does not initialize
|
||||
{
|
||||
friend class IP::Addr;
|
||||
|
||||
public:
|
||||
enum { SIZE=32 };
|
||||
|
||||
typedef std::uint32_t base_type;
|
||||
typedef std::int32_t signed_base_type;
|
||||
|
||||
static Addr from_addr(const Addr& addr)
|
||||
{
|
||||
return addr;
|
||||
}
|
||||
|
||||
static Addr from_in_addr(const struct in_addr *in4)
|
||||
{
|
||||
Addr ret;
|
||||
ret.u.addr = ntohl(in4->s_addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct in_addr to_in_addr() const
|
||||
{
|
||||
struct in_addr ret;
|
||||
ret.s_addr = htonl(u.addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Addr from_sockaddr(const struct sockaddr_in *sa)
|
||||
{
|
||||
Addr ret;
|
||||
ret.u.addr = ntohl(sa->sin_addr.s_addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct sockaddr_in to_sockaddr() const
|
||||
{
|
||||
struct sockaddr_in ret;
|
||||
std::memset(&ret, 0, sizeof(ret));
|
||||
ret.sin_family = AF_INET;
|
||||
ret.sin_port = 0;
|
||||
ret.sin_addr.s_addr = htonl(u.addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Addr from_uint32(const base_type addr) // host byte order
|
||||
{
|
||||
Addr ret;
|
||||
ret.u.addr = addr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::uint32_t to_uint32() const // host byte order
|
||||
{
|
||||
return u.addr;
|
||||
}
|
||||
|
||||
static Addr from_uint32_net(const base_type addr) // addr in net byte order
|
||||
{
|
||||
Addr ret;
|
||||
ret.u.addr = ntohl(addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void to_byte_string(unsigned char *bytestr) const
|
||||
{
|
||||
*(base_type*)bytestr = ntohl(u.addr);
|
||||
}
|
||||
|
||||
std::uint32_t to_uint32_net() const // return value in net byte order
|
||||
{
|
||||
return htonl(u.addr);
|
||||
}
|
||||
|
||||
static Addr from_ulong(unsigned long ul)
|
||||
{
|
||||
Addr ret;
|
||||
ret.u.addr = (base_type)ul;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// return *this as a unsigned long
|
||||
unsigned long to_ulong() const
|
||||
{
|
||||
return (unsigned long)u.addr;
|
||||
}
|
||||
|
||||
static Addr from_long(long ul)
|
||||
{
|
||||
Addr ret;
|
||||
ret.u.addr = (base_type)(signed_base_type)ul;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// return *this as a long
|
||||
long to_long() const
|
||||
{
|
||||
return (long)(signed_base_type)u.addr;
|
||||
}
|
||||
|
||||
static Addr from_bytes(const unsigned char *bytes) // host byte order
|
||||
{
|
||||
Addr ret;
|
||||
std::memcpy(ret.u.bytes, bytes, 4);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Addr from_bytes_net(const unsigned char *bytes) // network byte order
|
||||
{
|
||||
Addr ret;
|
||||
std::memcpy(ret.u.bytes, bytes, 4);
|
||||
ret.u.addr = ntohl(ret.u.addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Addr from_zero()
|
||||
{
|
||||
Addr ret;
|
||||
ret.zero();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Addr from_one()
|
||||
{
|
||||
Addr ret;
|
||||
ret.one();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Addr from_zero_complement()
|
||||
{
|
||||
Addr ret;
|
||||
ret.zero_complement();
|
||||
return ret;
|
||||
}
|
||||
|
||||
// build a netmask using given prefix_len
|
||||
static Addr netmask_from_prefix_len(const unsigned int prefix_len)
|
||||
{
|
||||
Addr ret;
|
||||
ret.u.addr = prefix_len_to_netmask(prefix_len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// build a netmask using given extent
|
||||
Addr netmask_from_extent() const
|
||||
{
|
||||
const int lb = find_last_set(u.addr - 1);
|
||||
return netmask_from_prefix_len(SIZE - lb);
|
||||
}
|
||||
|
||||
static Addr from_string(const std::string& ipstr, const char *title = nullptr)
|
||||
{
|
||||
openvpn_io::error_code ec;
|
||||
openvpn_io::ip::address_v4 a = openvpn_io::ip::make_address_v4(ipstr, ec);
|
||||
if (ec)
|
||||
throw ipv4_exception(IP::internal::format_error(ipstr, title, "v4", ec));
|
||||
return from_asio(a);
|
||||
}
|
||||
|
||||
std::string to_string() const
|
||||
{
|
||||
const openvpn_io::ip::address_v4 a = to_asio();
|
||||
std::string ret = a.to_string();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Addr from_hex(const std::string& s)
|
||||
{
|
||||
Addr ret;
|
||||
ret.u.addr = 0;
|
||||
size_t len = s.length();
|
||||
size_t base = 0;
|
||||
if (len > 0 && s[len-1] == 'L')
|
||||
len -= 1;
|
||||
if (len >= 2 && s[0] == '0' && s[1] == 'x')
|
||||
{
|
||||
base = 2;
|
||||
len -= 2;
|
||||
}
|
||||
if (len < 1 || len > 8)
|
||||
throw ipv4_exception("parse hex error");
|
||||
size_t di = (len-1)>>1;
|
||||
for (int i = (len & 1) ? -1 : 0; i < int(len); i += 2)
|
||||
{
|
||||
const size_t idx = base + i;
|
||||
const int bh = (i >= 0) ? parse_hex_char(s[idx]) : 0;
|
||||
const int bl = parse_hex_char(s[idx+1]);
|
||||
if (bh == -1 || bl == -1)
|
||||
throw ipv4_exception("parse hex error");
|
||||
ret.u.bytes[Endian::e4(di--)] = (bh<<4) + bl;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string to_hex() const
|
||||
{
|
||||
std::string ret;
|
||||
ret.reserve(8);
|
||||
bool firstnonzero = false;
|
||||
for (size_t i = 0; i < 4; ++i)
|
||||
{
|
||||
const unsigned char b = u.bytes[Endian::e4rev(i)];
|
||||
if (b || firstnonzero || i == 3)
|
||||
{
|
||||
const char bh = b >> 4;
|
||||
if (bh || firstnonzero)
|
||||
ret += render_hex_char(bh);
|
||||
ret += render_hex_char(b & 0x0F);
|
||||
firstnonzero = true;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string arpa() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << int(u.bytes[Endian::e4(0)]) << '.'
|
||||
<< int(u.bytes[Endian::e4(1)]) << '.'
|
||||
<< int(u.bytes[Endian::e4(2)]) << '.'
|
||||
<< int(u.bytes[Endian::e4(3)]) << ".in-addr.arpa";
|
||||
return os.str();
|
||||
}
|
||||
|
||||
static Addr from_asio(const openvpn_io::ip::address_v4& asio_addr)
|
||||
{
|
||||
Addr ret;
|
||||
ret.u.addr = (std::uint32_t)asio_addr.to_uint();
|
||||
return ret;
|
||||
}
|
||||
|
||||
openvpn_io::ip::address_v4 to_asio() const
|
||||
{
|
||||
return openvpn_io::ip::address_v4(u.addr);
|
||||
}
|
||||
|
||||
Addr operator&(const Addr& other) const {
|
||||
Addr ret;
|
||||
ret.u.addr = u.addr & other.u.addr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Addr operator|(const Addr& other) const {
|
||||
Addr ret;
|
||||
ret.u.addr = u.addr | other.u.addr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Addr operator+(const long delta) const {
|
||||
Addr ret;
|
||||
ret.u.addr = u.addr + (std::uint32_t)delta;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Addr operator+(const Addr& other) const {
|
||||
Addr ret;
|
||||
ret.u.addr = u.addr + other.u.addr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Addr operator-(const long delta) const {
|
||||
return operator+(-delta);
|
||||
}
|
||||
|
||||
Addr operator-(const Addr& other) const {
|
||||
Addr ret;
|
||||
ret.u.addr = u.addr - other.u.addr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Addr operator*(const Addr& other) const {
|
||||
Addr ret;
|
||||
ret.u.addr = u.addr * other.u.addr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Addr operator/(const Addr& other) const {
|
||||
Addr ret;
|
||||
ret.u.addr = u.addr / other.u.addr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Addr operator%(const Addr& other) const {
|
||||
Addr ret;
|
||||
ret.u.addr = u.addr % other.u.addr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Addr operator<<(const unsigned int shift) const {
|
||||
Addr ret;
|
||||
ret.u.addr = u.addr << shift;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Addr operator>>(const unsigned int shift) const {
|
||||
Addr ret;
|
||||
ret.u.addr = u.addr >> shift;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Addr operator~() const {
|
||||
Addr ret;
|
||||
ret.u.addr = ~u.addr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// return the network that contains the current address
|
||||
Addr network_addr(const unsigned int prefix_len) const
|
||||
{
|
||||
Addr ret;
|
||||
ret.u.addr = u.addr & prefix_len_to_netmask(prefix_len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool operator==(const Addr& other) const
|
||||
{
|
||||
return u.addr == other.u.addr;
|
||||
}
|
||||
|
||||
bool operator!=(const Addr& other) const
|
||||
{
|
||||
return u.addr != other.u.addr;
|
||||
}
|
||||
|
||||
bool operator<(const Addr& other) const
|
||||
{
|
||||
return u.addr < other.u.addr;
|
||||
}
|
||||
|
||||
bool operator>(const Addr& other) const
|
||||
{
|
||||
return u.addr > other.u.addr;
|
||||
}
|
||||
|
||||
bool operator<=(const Addr& other) const
|
||||
{
|
||||
return u.addr <= other.u.addr;
|
||||
}
|
||||
|
||||
bool operator>=(const Addr& other) const
|
||||
{
|
||||
return u.addr >= other.u.addr;
|
||||
}
|
||||
|
||||
bool unspecified() const
|
||||
{
|
||||
return all_zeros();
|
||||
}
|
||||
|
||||
bool specified() const
|
||||
{
|
||||
return !unspecified();
|
||||
}
|
||||
|
||||
bool all_zeros() const
|
||||
{
|
||||
return u.addr == 0;
|
||||
}
|
||||
|
||||
bool all_ones() const
|
||||
{
|
||||
return ~u.addr == 0;
|
||||
}
|
||||
|
||||
bool is_loopback() const
|
||||
{
|
||||
return (u.addr & 0x7F000000) == 0x7F000000;
|
||||
}
|
||||
|
||||
// number of network bits in netmask,
|
||||
// throws exception if addr is not a netmask
|
||||
unsigned int prefix_len() const
|
||||
{
|
||||
const int ret = prefix_len_32(u.addr);
|
||||
if (ret >= 0)
|
||||
return ret;
|
||||
else
|
||||
throw ipv4_exception("malformed netmask");
|
||||
}
|
||||
|
||||
int prefix_len_nothrow() const
|
||||
{
|
||||
return prefix_len_32(u.addr);
|
||||
}
|
||||
|
||||
// number of host bits in netmask
|
||||
unsigned int host_len() const
|
||||
{
|
||||
return SIZE - prefix_len();
|
||||
}
|
||||
|
||||
// return the number of host addresses contained within netmask
|
||||
Addr extent_from_netmask() const
|
||||
{
|
||||
Addr ret;
|
||||
ret.u.addr = extent_from_netmask_uint32();
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::uint32_t extent_from_netmask_uint32() const
|
||||
{
|
||||
const unsigned int hl = host_len();
|
||||
if (hl < SIZE)
|
||||
return 1 << hl;
|
||||
else if (hl == SIZE)
|
||||
return 0;
|
||||
else
|
||||
throw ipv4_exception("extent overflow");
|
||||
}
|
||||
|
||||
// convert netmask in addr to prefix_len, will return -1 on error
|
||||
static int prefix_len_32(const std::uint32_t addr)
|
||||
{
|
||||
if (addr == ~std::uint32_t(0))
|
||||
return 32;
|
||||
else if (addr == 0)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
unsigned int high = 32;
|
||||
unsigned int low = 1;
|
||||
for (unsigned int i = 0; i < 5; ++i)
|
||||
{
|
||||
const unsigned int mid = (high + low) / 2;
|
||||
const IPv4::Addr::base_type test = prefix_len_to_netmask_unchecked(mid);
|
||||
if (addr == test)
|
||||
return mid;
|
||||
else if (addr > test)
|
||||
low = mid;
|
||||
else
|
||||
high = mid;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// address size in bits
|
||||
static unsigned int size()
|
||||
{
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
std::size_t hashval() const
|
||||
{
|
||||
return Hash::value(u.addr);
|
||||
}
|
||||
|
||||
#ifdef OPENVPN_IP_IMMUTABLE
|
||||
private:
|
||||
#endif
|
||||
|
||||
void negate()
|
||||
{
|
||||
u.addr = ~u.addr;
|
||||
}
|
||||
|
||||
void zero()
|
||||
{
|
||||
u.addr = 0;
|
||||
}
|
||||
|
||||
void zero_complement()
|
||||
{
|
||||
u.addr = ~0;
|
||||
}
|
||||
|
||||
void one()
|
||||
{
|
||||
u.addr = 1;
|
||||
}
|
||||
|
||||
Addr& operator++()
|
||||
{
|
||||
++u.addr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Addr& operator+=(const long delta)
|
||||
{
|
||||
u.addr += (std::uint32_t)delta;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Addr& operator-=(const long delta)
|
||||
{
|
||||
return operator+=(-delta);
|
||||
}
|
||||
|
||||
private:
|
||||
static base_type prefix_len_to_netmask_unchecked(const unsigned int prefix_len)
|
||||
{
|
||||
if (prefix_len)
|
||||
return ~((1 << (SIZE - prefix_len)) - 1);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static base_type prefix_len_to_netmask(const unsigned int prefix_len)
|
||||
{
|
||||
if (prefix_len <= SIZE)
|
||||
return prefix_len_to_netmask_unchecked(prefix_len);
|
||||
else
|
||||
throw ipv4_exception("bad prefix len");
|
||||
}
|
||||
|
||||
union {
|
||||
base_type addr; // host byte order
|
||||
unsigned char bytes[4];
|
||||
} u;
|
||||
};
|
||||
|
||||
OPENVPN_OSTREAM(Addr, to_string)
|
||||
}
|
||||
}
|
||||
|
||||
OPENVPN_HASH_METHOD(openvpn::IPv4::Addr, hashval);
|
||||
|
||||
#endif // OPENVPN_ADDR_IPV4_H
|
||||
830
OpenVPN Adapter/Vendors/openvpn/openvpn/addr/ipv6.hpp
Normal file
830
OpenVPN Adapter/Vendors/openvpn/openvpn/addr/ipv6.hpp
Normal file
@@ -0,0 +1,830 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef OPENVPN_ADDR_IPV6_H
|
||||
#define OPENVPN_ADDR_IPV6_H
|
||||
|
||||
#include <cstring> // for std::memcpy, std::memset
|
||||
#include <algorithm> // for std::min
|
||||
#include <cstdint> // for std::uint32_t
|
||||
|
||||
#include <openvpn/io/io.hpp>
|
||||
|
||||
#include <openvpn/common/size.hpp>
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/common/ostream.hpp>
|
||||
#include <openvpn/common/socktypes.hpp>
|
||||
#include <openvpn/common/ffs.hpp>
|
||||
#include <openvpn/common/hexstr.hpp>
|
||||
#include <openvpn/common/hash.hpp>
|
||||
#include <openvpn/addr/ipv4.hpp>
|
||||
#include <openvpn/addr/iperr.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
namespace IP {
|
||||
class Addr;
|
||||
}
|
||||
|
||||
// Fundamental classes for representing an IPv6 IP address.
|
||||
|
||||
namespace IPv6 {
|
||||
|
||||
OPENVPN_EXCEPTION(ipv6_exception);
|
||||
|
||||
class Addr // NOTE: must be union-legal, so default constructor does not initialize
|
||||
{
|
||||
friend class IP::Addr;
|
||||
|
||||
public:
|
||||
enum { SIZE=128 };
|
||||
|
||||
static Addr from_addr(const Addr& addr)
|
||||
{
|
||||
return addr;
|
||||
}
|
||||
|
||||
static Addr from_in6_addr(const struct in6_addr *in6)
|
||||
{
|
||||
Addr ret;
|
||||
network_to_host_order(&ret.u, (const union ipv6addr *)in6->s6_addr);
|
||||
ret.scope_id_ = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct in6_addr to_in6_addr() const
|
||||
{
|
||||
struct in6_addr ret;
|
||||
host_to_network_order((union ipv6addr *)&ret, &u);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Addr from_sockaddr(const struct sockaddr_in6 *sa)
|
||||
{
|
||||
Addr ret;
|
||||
network_to_host_order(&ret.u, (const union ipv6addr *)sa->sin6_addr.s6_addr);
|
||||
ret.scope_id_ = sa->sin6_scope_id;
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct sockaddr_in6 to_sockaddr() const
|
||||
{
|
||||
struct sockaddr_in6 ret;
|
||||
std::memset(&ret, 0, sizeof(ret));
|
||||
ret.sin6_family = AF_INET6;
|
||||
ret.sin6_port = 0;
|
||||
host_to_network_order((union ipv6addr *)&ret.sin6_addr.s6_addr, &u);
|
||||
ret.sin6_scope_id = scope_id_;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Addr from_string(const std::string& ipstr, const char *title = nullptr)
|
||||
{
|
||||
openvpn_io::error_code ec;
|
||||
openvpn_io::ip::address_v6 a = openvpn_io::ip::make_address_v6(ipstr, ec);
|
||||
if (ec)
|
||||
throw ipv6_exception(IP::internal::format_error(ipstr, title, "v6", ec));
|
||||
return from_asio(a);
|
||||
}
|
||||
|
||||
std::string to_string() const
|
||||
{
|
||||
const openvpn_io::ip::address_v6 a = to_asio();
|
||||
std::string ret = a.to_string();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Addr from_hex(const std::string& s)
|
||||
{
|
||||
Addr ret;
|
||||
ret.scope_id_ = 0;
|
||||
ret.zero();
|
||||
size_t len = s.length();
|
||||
size_t base = 0;
|
||||
if (len > 0 && s[len-1] == 'L')
|
||||
len -= 1;
|
||||
if (len >= 2 && s[0] == '0' && s[1] == 'x')
|
||||
{
|
||||
base = 2;
|
||||
len -= 2;
|
||||
}
|
||||
if (len < 1 || len > 32)
|
||||
throw ipv6_exception("parse hex error");
|
||||
size_t di = (len-1)>>1;
|
||||
for (int i = (len & 1) ? -1 : 0; i < int(len); i += 2)
|
||||
{
|
||||
const size_t idx = base + i;
|
||||
const int bh = (i >= 0) ? parse_hex_char(s[idx]) : 0;
|
||||
const int bl = parse_hex_char(s[idx+1]);
|
||||
if (bh == -1 || bl == -1)
|
||||
throw ipv6_exception("parse hex error");
|
||||
ret.u.bytes[Endian::e16(di--)] = (bh<<4) + bl;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string to_hex() const
|
||||
{
|
||||
std::string ret;
|
||||
ret.reserve(32);
|
||||
bool firstnonzero = false;
|
||||
for (size_t i = 0; i < 16; ++i)
|
||||
{
|
||||
const unsigned char b = u.bytes[Endian::e16rev(i)];
|
||||
if (b || firstnonzero || i == 15)
|
||||
{
|
||||
const char bh = b >> 4;
|
||||
if (bh || firstnonzero)
|
||||
ret += render_hex_char(bh);
|
||||
ret += render_hex_char(b & 0x0F);
|
||||
firstnonzero = true;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Addr from_ulong(unsigned long ul)
|
||||
{
|
||||
Addr ret;
|
||||
ret.scope_id_ = 0;
|
||||
ret.u.u64[Endian::e2(0)] = std::uint64_t(ul);
|
||||
ret.u.u64[Endian::e2(1)] = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// return *this as a unsigned long
|
||||
unsigned long to_ulong() const
|
||||
{
|
||||
const unsigned long ret = (unsigned long)u.u64[Endian::e2(0)];
|
||||
const std::uint64_t cmp = std::uint64_t(ret);
|
||||
if (u.u64[Endian::e2(1)] || cmp != u.u64[Endian::e2(0)])
|
||||
throw ipv6_exception("overflow in conversion from IPv6.Addr to unsigned long");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Addr from_long(long ul)
|
||||
{
|
||||
bool neg = false;
|
||||
Addr ret;
|
||||
ret.scope_id_ = 0;
|
||||
if (ul < 0)
|
||||
{
|
||||
ul = -(ul + 1);
|
||||
neg = true;
|
||||
}
|
||||
ret.u.u64[Endian::e2(0)] = std::uint64_t(ul);
|
||||
ret.u.u64[Endian::e2(1)] = 0;
|
||||
if (neg)
|
||||
ret.negate();
|
||||
return ret;
|
||||
}
|
||||
|
||||
// return *this as a long
|
||||
long to_long() const
|
||||
{
|
||||
bool neg = false;
|
||||
Addr a = *this;
|
||||
if (a.u.u64[Endian::e2(1)])
|
||||
{
|
||||
a.negate();
|
||||
neg = true;
|
||||
}
|
||||
const long ret = (long)a.u.u64[Endian::e2(0)];
|
||||
const std::uint64_t cmp = std::uint64_t(ret);
|
||||
if (a.u.u64[Endian::e2(1)] || cmp != a.u.u64[Endian::e2(0)])
|
||||
throw ipv6_exception("overflow in conversion from IPv6.Addr to long");
|
||||
return neg ? -(ret + 1) : ret;
|
||||
}
|
||||
|
||||
std::string arpa() const
|
||||
{
|
||||
throw ipv6_exception("arpa() not implemented");
|
||||
}
|
||||
|
||||
static Addr from_asio(const openvpn_io::ip::address_v6& asio_addr)
|
||||
{
|
||||
Addr ret;
|
||||
union ipv6addr addr;
|
||||
addr.asio_bytes = asio_addr.to_bytes();
|
||||
network_to_host_order(&ret.u, &addr);
|
||||
ret.scope_id_ = (unsigned int)asio_addr.scope_id();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Addr from_byte_string(const unsigned char *bytestr)
|
||||
{
|
||||
Addr ret;
|
||||
network_to_host_order(&ret.u, (const union ipv6addr *)bytestr);
|
||||
ret.scope_id_ = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void to_byte_string(unsigned char *bytestr) const
|
||||
{
|
||||
host_to_network_order((union ipv6addr *)bytestr, &u);
|
||||
}
|
||||
|
||||
static void v4_to_byte_string(unsigned char *bytestr,
|
||||
const std::uint32_t v4addr)
|
||||
{
|
||||
union ipv6addr *a = (union ipv6addr *)bytestr;
|
||||
a->u32[0] = a->u32[1] = a->u32[2] = 0;
|
||||
a->u32[3] = v4addr;
|
||||
}
|
||||
|
||||
static bool byte_string_is_v4(const unsigned char *bytestr)
|
||||
{
|
||||
const union ipv6addr *a = (const union ipv6addr *)bytestr;
|
||||
return a->u32[0] == 0 && a->u32[1] == 0 && a->u32[2] == 0;
|
||||
}
|
||||
|
||||
static std::uint32_t v4_from_byte_string(const unsigned char *bytestr)
|
||||
{
|
||||
const union ipv6addr *a = (const union ipv6addr *)bytestr;
|
||||
return a->u32[3];
|
||||
}
|
||||
|
||||
openvpn_io::ip::address_v6 to_asio() const
|
||||
{
|
||||
union ipv6addr addr;
|
||||
host_to_network_order(&addr, &u);
|
||||
return openvpn_io::ip::address_v6(addr.asio_bytes, scope_id_);
|
||||
}
|
||||
|
||||
static Addr from_zero()
|
||||
{
|
||||
Addr ret;
|
||||
ret.scope_id_ = 0;
|
||||
ret.zero();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Addr from_one()
|
||||
{
|
||||
Addr ret;
|
||||
ret.scope_id_ = 0;
|
||||
ret.one();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Addr from_zero_complement()
|
||||
{
|
||||
Addr ret;
|
||||
ret.scope_id_ = 0;
|
||||
ret.zero_complement();
|
||||
return ret;
|
||||
}
|
||||
|
||||
// build a netmask using given prefix_len
|
||||
static Addr netmask_from_prefix_len(const unsigned int prefix_len)
|
||||
{
|
||||
Addr ret;
|
||||
ret.scope_id_ = 0;
|
||||
ret.prefix_len_to_netmask(prefix_len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// build a netmask using given extent
|
||||
Addr netmask_from_extent() const
|
||||
{
|
||||
const Addr lb = *this - 1;
|
||||
for (size_t i = 4; i --> 0 ;)
|
||||
{
|
||||
const std::uint32_t v = lb.u.u32[Endian::e4(i)];
|
||||
if (v)
|
||||
return netmask_from_prefix_len(SIZE - (((unsigned int)i<<5) + find_last_set(v)));
|
||||
}
|
||||
return from_zero_complement();
|
||||
}
|
||||
|
||||
Addr operator&(const Addr& other) const {
|
||||
Addr ret;
|
||||
ret.scope_id_ = scope_id_;
|
||||
ret.u.u64[0] = u.u64[0] & other.u.u64[0];
|
||||
ret.u.u64[1] = u.u64[1] & other.u.u64[1];
|
||||
return ret;
|
||||
}
|
||||
|
||||
Addr operator|(const Addr& other) const {
|
||||
Addr ret;
|
||||
ret.scope_id_ = scope_id_;
|
||||
ret.u.u64[0] = u.u64[0] | other.u.u64[0];
|
||||
ret.u.u64[1] = u.u64[1] | other.u.u64[1];
|
||||
return ret;
|
||||
}
|
||||
|
||||
Addr operator+(const long delta) const {
|
||||
Addr ret = *this;
|
||||
ret.u.u64[Endian::e2(0)] += delta;
|
||||
ret.u.u64[Endian::e2(1)] += (delta >= 0)
|
||||
? (ret.u.u64[Endian::e2(0)] < u.u64[Endian::e2(0)])
|
||||
: -(ret.u.u64[Endian::e2(0)] > u.u64[Endian::e2(0)]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Addr operator+(const Addr& other) const {
|
||||
Addr ret = *this;
|
||||
add(ret.u, other.u);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Addr operator-(const long delta) const {
|
||||
return operator+(-delta);
|
||||
}
|
||||
|
||||
Addr operator-(const Addr& other) const {
|
||||
Addr ret = *this;
|
||||
sub(ret.u, other.u);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Addr operator*(const Addr& d) const {
|
||||
Addr m = d;
|
||||
Addr ret = from_zero();
|
||||
for (unsigned int i = 0; i < SIZE; ++i)
|
||||
{
|
||||
if (bit(i))
|
||||
ret += m;
|
||||
m <<= 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
Addr operator/(const Addr& d) const {
|
||||
Addr q, r;
|
||||
div(*this, d, q, r);
|
||||
return q;
|
||||
}
|
||||
|
||||
Addr operator%(const Addr& d) const {
|
||||
Addr q, r;
|
||||
div(*this, d, q, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
Addr operator<<(const unsigned int shift) const {
|
||||
Addr ret = *this;
|
||||
shiftl128(ret.u.u64[Endian::e2(0)],
|
||||
ret.u.u64[Endian::e2(1)],
|
||||
shift);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Addr operator>>(const unsigned int shift) const {
|
||||
Addr ret = *this;
|
||||
shiftr128(ret.u.u64[Endian::e2(0)],
|
||||
ret.u.u64[Endian::e2(1)],
|
||||
shift);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Addr operator~() const {
|
||||
Addr ret;
|
||||
ret.scope_id_ = scope_id_;
|
||||
ret.u.u64[0] = ~u.u64[0];
|
||||
ret.u.u64[1] = ~u.u64[1];
|
||||
return ret;
|
||||
}
|
||||
|
||||
// return the network that contains the current address
|
||||
Addr network_addr(const unsigned int prefix_len) const
|
||||
{
|
||||
return *this & netmask_from_prefix_len(prefix_len);
|
||||
}
|
||||
|
||||
bool operator==(const Addr& other) const
|
||||
{
|
||||
return u.u64[0] == other.u.u64[0] && u.u64[1] == other.u.u64[1] && scope_id_ == other.scope_id_;
|
||||
}
|
||||
|
||||
bool operator!=(const Addr& other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
#define OPENVPN_IPV6_OPERATOR_REL(OP) \
|
||||
bool operator OP(const Addr& other) const \
|
||||
{ \
|
||||
if (u.u64[Endian::e2(1)] == other.u.u64[Endian::e2(1)]) \
|
||||
{ \
|
||||
if (u.u64[Endian::e2(0)] != other.u.u64[Endian::e2(0)]) \
|
||||
return u.u64[Endian::e2(0)] OP other.u.u64[Endian::e2(0)]; \
|
||||
else \
|
||||
return scope_id_ OP other.scope_id_; \
|
||||
} \
|
||||
else \
|
||||
return u.u64[Endian::e2(1)] OP other.u.u64[Endian::e2(1)]; \
|
||||
}
|
||||
|
||||
OPENVPN_IPV6_OPERATOR_REL(<)
|
||||
OPENVPN_IPV6_OPERATOR_REL(>)
|
||||
OPENVPN_IPV6_OPERATOR_REL(<=)
|
||||
OPENVPN_IPV6_OPERATOR_REL(>=)
|
||||
|
||||
#undef OPENVPN_IPV6_OPERATOR_REL
|
||||
|
||||
bool unspecified() const
|
||||
{
|
||||
return all_zeros();
|
||||
}
|
||||
|
||||
bool specified() const
|
||||
{
|
||||
return !unspecified();
|
||||
}
|
||||
|
||||
bool all_zeros() const
|
||||
{
|
||||
return u.u64[0] == 0 && u.u64[1] == 0;
|
||||
}
|
||||
|
||||
bool all_ones() const
|
||||
{
|
||||
return u.u64[0] == ~std::uint64_t(0) && u.u64[1] == ~std::uint64_t(0);
|
||||
}
|
||||
|
||||
bool is_loopback() const // ::1
|
||||
{
|
||||
return u.u64[Endian::e2(1)] == 0 && u.u64[Endian::e2(0)] == 1;
|
||||
}
|
||||
|
||||
bool bit(unsigned int pos) const
|
||||
{
|
||||
if (pos < 64)
|
||||
return (u.u64[Endian::e2(0)] & (std::uint64_t(1)<<pos)) != 0;
|
||||
else
|
||||
return (u.u64[Endian::e2(1)] & (std::uint64_t(1)<<(pos-64))) != 0;
|
||||
}
|
||||
|
||||
// number of network bits in netmask,
|
||||
// throws exception if addr is not a netmask
|
||||
unsigned int prefix_len() const
|
||||
{
|
||||
int idx = -1;
|
||||
|
||||
if (u.u32[Endian::e4(3)] != ~std::uint32_t(0))
|
||||
{
|
||||
if (!u.u32[Endian::e4(0)] && !u.u32[Endian::e4(1)] && !u.u32[Endian::e4(2)])
|
||||
idx = 0;
|
||||
}
|
||||
else if (u.u32[Endian::e4(2)] != ~std::uint32_t(0))
|
||||
{
|
||||
if (!u.u32[Endian::e4(0)] && !u.u32[Endian::e4(1)])
|
||||
idx = 1;
|
||||
}
|
||||
else if (u.u32[Endian::e4(1)] != ~std::uint32_t(0))
|
||||
{
|
||||
if (!u.u32[Endian::e4(0)])
|
||||
idx = 2;
|
||||
}
|
||||
else
|
||||
idx = 3;
|
||||
|
||||
if (idx >= 0)
|
||||
{
|
||||
const int ret = IPv4::Addr::prefix_len_32(u.u32[Endian::e4rev(idx)]);
|
||||
if (ret >= 0)
|
||||
return ret + (idx<<5);
|
||||
}
|
||||
throw ipv6_exception("malformed netmask");
|
||||
}
|
||||
|
||||
// number of host bits in netmask
|
||||
unsigned int host_len() const
|
||||
{
|
||||
return SIZE - prefix_len();
|
||||
}
|
||||
|
||||
// return the number of host addresses contained within netmask
|
||||
Addr extent_from_netmask() const
|
||||
{
|
||||
const unsigned int hl = host_len();
|
||||
if (hl < SIZE)
|
||||
{
|
||||
Addr a;
|
||||
a.scope_id_ = 0;
|
||||
a.one();
|
||||
return a << hl;
|
||||
}
|
||||
else if (hl == SIZE)
|
||||
return from_zero();
|
||||
else
|
||||
throw ipv6_exception("extent overflow");
|
||||
}
|
||||
|
||||
// address size in bits
|
||||
static unsigned int size()
|
||||
{
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
std::size_t hashval() const
|
||||
{
|
||||
return Hash::value(u.u32[0], u.u32[1], u.u32[2], u.u32[3]);
|
||||
}
|
||||
|
||||
#ifdef OPENVPN_IP_IMMUTABLE
|
||||
private:
|
||||
#endif
|
||||
|
||||
void negate()
|
||||
{
|
||||
u.u64[0] = ~u.u64[0];
|
||||
u.u64[1] = ~u.u64[1];
|
||||
}
|
||||
|
||||
void zero()
|
||||
{
|
||||
u.u64[0] = 0;
|
||||
u.u64[1] = 0;
|
||||
}
|
||||
|
||||
void zero_complement()
|
||||
{
|
||||
u.u64[0] = ~std::uint64_t(0);
|
||||
u.u64[1] = ~std::uint64_t(0);
|
||||
}
|
||||
|
||||
void one()
|
||||
{
|
||||
u.u64[0] = 1;
|
||||
u.u64[1] = 0;
|
||||
}
|
||||
|
||||
Addr& operator++()
|
||||
{
|
||||
if (++u.u64[Endian::e2(0)] == 0)
|
||||
++u.u64[Endian::e2(1)];
|
||||
return *this;
|
||||
}
|
||||
|
||||
Addr& operator+=(const long delta)
|
||||
{
|
||||
*this = *this + delta;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Addr& operator-=(const long delta)
|
||||
{
|
||||
return operator+=(-delta);
|
||||
}
|
||||
|
||||
Addr& operator+=(const Addr& other) {
|
||||
add(u, other.u);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Addr& operator-=(const Addr& other) {
|
||||
sub(u, other.u);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Addr& operator<<=(const unsigned int shift) {
|
||||
shiftl128(u.u64[Endian::e2(0)],
|
||||
u.u64[Endian::e2(1)],
|
||||
shift);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Addr& operator>>=(const unsigned int shift) {
|
||||
shiftr128(u.u64[Endian::e2(0)],
|
||||
u.u64[Endian::e2(1)],
|
||||
shift);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void set_clear_bit(unsigned int pos, bool value)
|
||||
{
|
||||
if (pos < 64)
|
||||
{
|
||||
if (value)
|
||||
u.u64[Endian::e2(0)] |= (std::uint64_t(1)<<pos);
|
||||
else
|
||||
u.u64[Endian::e2(0)] &= ~(std::uint64_t(1)<<pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value)
|
||||
u.u64[Endian::e2(1)] |= (std::uint64_t(1)<<(pos-64));
|
||||
else
|
||||
u.u64[Endian::e2(1)] &= ~(std::uint64_t(1)<<(pos-64));
|
||||
}
|
||||
}
|
||||
|
||||
void set_bit(unsigned int pos, bool value)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
if (pos < 64)
|
||||
u.u64[Endian::e2(0)] |= (std::uint64_t(1)<<pos);
|
||||
else
|
||||
u.u64[Endian::e2(1)] |= (std::uint64_t(1)<<(pos-64));
|
||||
}
|
||||
}
|
||||
|
||||
static void div(const Addr& n, const Addr& d, Addr& q, Addr& r)
|
||||
{
|
||||
if (d.all_zeros())
|
||||
throw ipv6_exception("division by 0");
|
||||
q = from_zero(); // quotient
|
||||
r = n; // remainder (init to numerator)
|
||||
Addr ml = from_zero(); // mask low
|
||||
Addr mh = d; // mask high (init to denominator)
|
||||
for (unsigned int i = 0; i < SIZE; ++i)
|
||||
{
|
||||
ml >>= 1;
|
||||
ml.set_bit(SIZE-1, mh.bit(0));
|
||||
mh >>= 1;
|
||||
if (mh.all_zeros() && r >= ml)
|
||||
{
|
||||
r -= ml;
|
||||
q.set_bit((SIZE-1)-i, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int scope_id() const
|
||||
{
|
||||
return scope_id_;
|
||||
}
|
||||
|
||||
private:
|
||||
union ipv6addr {
|
||||
std::uint64_t u64[2];
|
||||
std::uint32_t u32[4]; // generally stored in host byte order
|
||||
unsigned char bytes[16];
|
||||
openvpn_io::ip::address_v6::bytes_type asio_bytes;
|
||||
};
|
||||
|
||||
void prefix_len_to_netmask_unchecked(const unsigned int prefix_len)
|
||||
{
|
||||
if (prefix_len > 0)
|
||||
{
|
||||
const unsigned int pl = prefix_len - 1;
|
||||
const std::uint32_t mask = ~((1 << (31 - (pl & 31))) - 1);
|
||||
switch (pl >> 5)
|
||||
{
|
||||
case 0:
|
||||
u.u32[Endian::e4(0)] = 0;
|
||||
u.u32[Endian::e4(1)] = 0;
|
||||
u.u32[Endian::e4(2)] = 0;
|
||||
u.u32[Endian::e4(3)] = mask;
|
||||
break;
|
||||
case 1:
|
||||
u.u32[Endian::e4(0)] = 0;
|
||||
u.u32[Endian::e4(1)] = 0;
|
||||
u.u32[Endian::e4(2)] = mask;
|
||||
u.u32[Endian::e4(3)] = ~0;
|
||||
break;
|
||||
case 2:
|
||||
u.u32[Endian::e4(0)] = 0;
|
||||
u.u32[Endian::e4(1)] = mask;
|
||||
u.u32[Endian::e4(2)] = ~0;
|
||||
u.u32[Endian::e4(3)] = ~0;
|
||||
break;
|
||||
case 3:
|
||||
u.u32[Endian::e4(0)] = mask;
|
||||
u.u32[Endian::e4(1)] = ~0;
|
||||
u.u32[Endian::e4(2)] = ~0;
|
||||
u.u32[Endian::e4(3)] = ~0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
zero();
|
||||
}
|
||||
|
||||
void prefix_len_to_netmask(const unsigned int prefix_len)
|
||||
{
|
||||
if (prefix_len <= SIZE)
|
||||
return prefix_len_to_netmask_unchecked(prefix_len);
|
||||
else
|
||||
throw ipv6_exception("bad prefix len");
|
||||
}
|
||||
|
||||
static void host_to_network_order(union ipv6addr *dest, const union ipv6addr *src)
|
||||
{
|
||||
dest->u32[0] = htonl(src->u32[Endian::e4rev(0)]);
|
||||
dest->u32[1] = htonl(src->u32[Endian::e4rev(1)]);
|
||||
dest->u32[2] = htonl(src->u32[Endian::e4rev(2)]);
|
||||
dest->u32[3] = htonl(src->u32[Endian::e4rev(3)]);
|
||||
}
|
||||
|
||||
static void network_to_host_order(union ipv6addr *dest, const union ipv6addr *src)
|
||||
{
|
||||
dest->u32[0] = ntohl(src->u32[Endian::e4rev(0)]);
|
||||
dest->u32[1] = ntohl(src->u32[Endian::e4rev(1)]);
|
||||
dest->u32[2] = ntohl(src->u32[Endian::e4rev(2)]);
|
||||
dest->u32[3] = ntohl(src->u32[Endian::e4rev(3)]);
|
||||
}
|
||||
|
||||
static void shiftl128(std::uint64_t& low,
|
||||
std::uint64_t& high,
|
||||
unsigned int shift)
|
||||
{
|
||||
if (shift == 1)
|
||||
{
|
||||
high <<= 1;
|
||||
if (low & (std::uint64_t(1) << 63))
|
||||
high |= 1;
|
||||
low <<= 1;
|
||||
}
|
||||
else if (shift == 0)
|
||||
;
|
||||
else if (shift <= 128)
|
||||
{
|
||||
if (shift >= 64)
|
||||
{
|
||||
high = low;
|
||||
low = 0;
|
||||
shift -= 64;
|
||||
}
|
||||
if (shift < 64)
|
||||
{
|
||||
high = (high << shift) | (low >> (64-shift));
|
||||
low <<= shift;
|
||||
}
|
||||
else // shift == 64
|
||||
high = 0;
|
||||
}
|
||||
else
|
||||
throw ipv6_exception("l-shift too large");
|
||||
}
|
||||
|
||||
static void shiftr128(std::uint64_t& low,
|
||||
std::uint64_t& high,
|
||||
unsigned int shift)
|
||||
{
|
||||
if (shift == 1)
|
||||
{
|
||||
low >>= 1;
|
||||
if (high & 1)
|
||||
low |= (std::uint64_t(1) << 63);
|
||||
high >>= 1;
|
||||
}
|
||||
else if (shift == 0)
|
||||
;
|
||||
else if (shift <= 128)
|
||||
{
|
||||
if (shift >= 64)
|
||||
{
|
||||
low = high;
|
||||
high = 0;
|
||||
shift -= 64;
|
||||
}
|
||||
if (shift < 64)
|
||||
{
|
||||
low = (low >> shift) | (high << (64-shift));
|
||||
high >>= shift;
|
||||
}
|
||||
else // shift == 64
|
||||
low = 0;
|
||||
}
|
||||
else
|
||||
throw ipv6_exception("r-shift too large");
|
||||
}
|
||||
|
||||
static void add(ipv6addr& dest, const ipv6addr& src) {
|
||||
const std::uint64_t dorigl = dest.u64[Endian::e2(0)];
|
||||
dest.u64[Endian::e2(0)] += src.u64[Endian::e2(0)];
|
||||
dest.u64[Endian::e2(1)] += src.u64[Endian::e2(1)];
|
||||
// check for overflow of low 64 bits, add carry to high
|
||||
if (dest.u64[Endian::e2(0)] < dorigl)
|
||||
++dest.u64[Endian::e2(1)];
|
||||
}
|
||||
|
||||
static void sub(ipv6addr& dest, const ipv6addr& src) {
|
||||
const std::uint64_t dorigl = dest.u64[Endian::e2(0)];
|
||||
dest.u64[Endian::e2(0)] -= src.u64[Endian::e2(0)];
|
||||
dest.u64[Endian::e2(1)] -= src.u64[Endian::e2(1)]
|
||||
+ (dorigl < dest.u64[Endian::e2(0)]);
|
||||
}
|
||||
|
||||
union ipv6addr u;
|
||||
unsigned int scope_id_;
|
||||
};
|
||||
|
||||
OPENVPN_OSTREAM(Addr, to_string)
|
||||
}
|
||||
}
|
||||
|
||||
OPENVPN_HASH_METHOD(openvpn::IPv6::Addr, hashval);
|
||||
|
||||
#endif // OPENVPN_ADDR_IPV6_H
|
||||
67
OpenVPN Adapter/Vendors/openvpn/openvpn/addr/macaddr.hpp
Normal file
67
OpenVPN Adapter/Vendors/openvpn/openvpn/addr/macaddr.hpp
Normal file
@@ -0,0 +1,67 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef OPENVPN_ADDR_MACADDR_H
|
||||
#define OPENVPN_ADDR_MACADDR_H
|
||||
|
||||
#include <ostream>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/common/ostream.hpp>
|
||||
#include <openvpn/common/hexstr.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
|
||||
// Fundamental class for representing an ethernet MAC address.
|
||||
|
||||
class MACAddr {
|
||||
public:
|
||||
MACAddr()
|
||||
{
|
||||
std::memset(addr_, 0, sizeof(addr_));
|
||||
}
|
||||
|
||||
MACAddr(const unsigned char *addr)
|
||||
{
|
||||
reset(addr);
|
||||
}
|
||||
|
||||
void reset(const unsigned char *addr)
|
||||
{
|
||||
std::memcpy(addr_, addr, sizeof(addr_));
|
||||
}
|
||||
|
||||
std::string to_string() const
|
||||
{
|
||||
return render_hex_sep(addr_, sizeof(addr_), ':');
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned char addr_[6];
|
||||
};
|
||||
|
||||
OPENVPN_OSTREAM(MACAddr, to_string)
|
||||
|
||||
} // namespace openvpn
|
||||
|
||||
#endif // OPENVPN_ADDR_MACADDR_H
|
||||
138
OpenVPN Adapter/Vendors/openvpn/openvpn/addr/pool.hpp
Normal file
138
OpenVPN Adapter/Vendors/openvpn/openvpn/addr/pool.hpp
Normal file
@@ -0,0 +1,138 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef OPENVPN_ADDR_POOL_H
|
||||
#define OPENVPN_ADDR_POOL_H
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <deque>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <openvpn/common/size.hpp>
|
||||
#include <openvpn/common/exception.hpp>
|
||||
|
||||
#include <openvpn/addr/ip.hpp>
|
||||
#include <openvpn/addr/range.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
namespace IP {
|
||||
|
||||
// Maintain a pool of IP addresses.
|
||||
// A should be IP::Addr, IPv4::Addr, or IPv6::Addr.
|
||||
template <typename ADDR>
|
||||
class PoolType
|
||||
{
|
||||
public:
|
||||
PoolType() {}
|
||||
|
||||
// Add range of addresses to pool (pool will own the addresses).
|
||||
void add_range(const RangeType<ADDR>& range)
|
||||
{
|
||||
typename RangeType<ADDR>::Iterator iter = range.iterator();
|
||||
while (iter.more())
|
||||
{
|
||||
const ADDR& a = iter.addr();
|
||||
add_addr(a);
|
||||
iter.next();
|
||||
}
|
||||
}
|
||||
|
||||
// Add single address to pool (pool will own the address).
|
||||
void add_addr(const ADDR& addr)
|
||||
{
|
||||
typename std::unordered_map<ADDR, bool>::const_iterator e = map.find(addr);
|
||||
if (e == map.end())
|
||||
{
|
||||
freelist.push_back(addr);
|
||||
map[addr] = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Return number of pool addresses currently in use.
|
||||
size_t n_in_use() const
|
||||
{
|
||||
return map.size() - freelist.size();
|
||||
}
|
||||
|
||||
// Acquire an address from pool. Returns true if successful,
|
||||
// with address placed in dest, or false if pool depleted.
|
||||
bool acquire_addr(ADDR& dest)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (freelist.empty())
|
||||
return false;
|
||||
const ADDR& a = freelist.front();
|
||||
typename std::unordered_map<ADDR, bool>::iterator e = map.find(a);
|
||||
if (e == map.end()) // any address in freelist must exist in map
|
||||
throw Exception("PoolType: address in freelist doesn't exist in map");
|
||||
if (!e->second)
|
||||
{
|
||||
e->second = true;
|
||||
dest = a;
|
||||
freelist.pop_front();
|
||||
return true;
|
||||
}
|
||||
freelist.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
// Acquire a specific address from pool, returning true if
|
||||
// successful, or false if the address is not available.
|
||||
bool acquire_specific_addr(const ADDR& addr)
|
||||
{
|
||||
typename std::unordered_map<ADDR, bool>::iterator e = map.find(addr);
|
||||
if (e != map.end() && !e->second)
|
||||
{
|
||||
e->second = true;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return a previously acquired address to the pool. Does nothing if
|
||||
// (a) the address is owned by the pool and marked as free, or
|
||||
// (b) the address is not owned by the pool.
|
||||
void release_addr(const ADDR& addr)
|
||||
{
|
||||
typename std::unordered_map<ADDR, bool>::iterator e = map.find(addr);
|
||||
if (e != map.end() && e->second)
|
||||
{
|
||||
freelist.push_back(addr);
|
||||
e->second = false;
|
||||
}
|
||||
}
|
||||
|
||||
// DEBUGGING -- get the map load factor
|
||||
float load_factor() const { return map.load_factor(); }
|
||||
|
||||
private:
|
||||
std::deque<ADDR> freelist;
|
||||
std::unordered_map<ADDR, bool> map;
|
||||
};
|
||||
|
||||
typedef PoolType<IP::Addr> Pool;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
137
OpenVPN Adapter/Vendors/openvpn/openvpn/addr/range.hpp
Normal file
137
OpenVPN Adapter/Vendors/openvpn/openvpn/addr/range.hpp
Normal file
@@ -0,0 +1,137 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef OPENVPN_ADDR_RANGE_H
|
||||
#define OPENVPN_ADDR_RANGE_H
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
#include <openvpn/common/size.hpp>
|
||||
#include <openvpn/common/exception.hpp>
|
||||
|
||||
#include <openvpn/addr/ip.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
namespace IP {
|
||||
|
||||
// Denote a range of IP addresses with a start and extent,
|
||||
// where A represents an address class.
|
||||
// A should be a network address class such as IP::Addr, IPv4::Addr, or IPv6::Addr.
|
||||
|
||||
template <typename ADDR>
|
||||
class RangeType
|
||||
{
|
||||
public:
|
||||
class Iterator
|
||||
{
|
||||
friend class RangeType;
|
||||
public:
|
||||
bool more() const { return remaining_ > 0; }
|
||||
|
||||
const ADDR& addr() const { return addr_; }
|
||||
|
||||
void next()
|
||||
{
|
||||
if (more())
|
||||
{
|
||||
++addr_;
|
||||
--remaining_;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Iterator(const RangeType& range)
|
||||
: addr_(range.start_), remaining_(range.extent_) {}
|
||||
|
||||
ADDR addr_;
|
||||
size_t remaining_;
|
||||
};
|
||||
|
||||
RangeType() : extent_(0) {}
|
||||
|
||||
RangeType(const ADDR& start, const size_t extent)
|
||||
: start_(start), extent_(extent) {}
|
||||
|
||||
Iterator iterator() const { return Iterator(*this); }
|
||||
|
||||
const bool defined() const { return extent_ > 0; }
|
||||
const ADDR& start() const { return start_; }
|
||||
size_t extent() const { return extent_; }
|
||||
|
||||
RangeType pull_front(size_t extent)
|
||||
{
|
||||
if (extent > extent_)
|
||||
extent = extent_;
|
||||
RangeType ret(start_, extent);
|
||||
start_ += extent;
|
||||
extent_ -= extent;
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string to_string() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << start_.to_string() << '[' << extent_ << ']';
|
||||
return os.str();
|
||||
}
|
||||
|
||||
private:
|
||||
ADDR start_;
|
||||
size_t extent_;
|
||||
};
|
||||
|
||||
template <typename ADDR>
|
||||
class RangePartitionType
|
||||
{
|
||||
public:
|
||||
RangePartitionType(const RangeType<ADDR>& src_range, const size_t n_partitions)
|
||||
: range(src_range),
|
||||
remaining(n_partitions)
|
||||
{
|
||||
}
|
||||
|
||||
bool next(RangeType<ADDR>& r)
|
||||
{
|
||||
if (remaining)
|
||||
{
|
||||
if (remaining > 1)
|
||||
r = range.pull_front(range.extent() / remaining);
|
||||
else
|
||||
r = range;
|
||||
--remaining;
|
||||
return r.defined();
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
RangeType<ADDR> range;
|
||||
size_t remaining;
|
||||
};
|
||||
|
||||
typedef RangeType<IP::Addr> Range;
|
||||
typedef RangePartitionType<IP::Addr> RangePartition;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
38
OpenVPN Adapter/Vendors/openvpn/openvpn/addr/regex.hpp
Normal file
38
OpenVPN Adapter/Vendors/openvpn/openvpn/addr/regex.hpp
Normal file
@@ -0,0 +1,38 @@
|
||||
// Regular expressions for IPv4/v6
|
||||
// Source: http://stackoverflow.com/questions/53497/regular-expression-that-matches-valid-ipv6-addresses
|
||||
|
||||
#ifndef OPENVPN_ADDR_REGEX_H
|
||||
#define OPENVPN_ADDR_REGEX_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace openvpn {
|
||||
namespace IP {
|
||||
inline std::string v4_regex()
|
||||
{
|
||||
const std::string ipv4seg = "(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])";
|
||||
return "(?:" + ipv4seg + "\\.){3,3}" + ipv4seg;
|
||||
}
|
||||
|
||||
inline std::string v6_regex()
|
||||
{
|
||||
const std::string ipv6seg = "[0-9a-fA-F]{1,4}";
|
||||
return "(?:"
|
||||
"(?:" + ipv6seg + ":){7,7}" + ipv6seg + "|" // 1:2:3:4:5:6:7:8
|
||||
"(?:" + ipv6seg + ":){1,7}:|" // 1:: 1:2:3:4:5:6:7::
|
||||
"(?:" + ipv6seg + ":){1,6}:" + ipv6seg + "|" // 1::8 1:2:3:4:5:6::8 1:2:3:4:5:6::8
|
||||
"(?:" + ipv6seg + ":){1,5}(?::" + ipv6seg + "){1,2}|" // 1::7:8 1:2:3:4:5::7:8 1:2:3:4:5::8
|
||||
"(?:" + ipv6seg + ":){1,4}(?::" + ipv6seg + "){1,3}|" // 1::6:7:8 1:2:3:4::6:7:8 1:2:3:4::8
|
||||
"(?:" + ipv6seg + ":){1,3}(?::" + ipv6seg + "){1,4}|" // 1::5:6:7:8 1:2:3::5:6:7:8 1:2:3::8
|
||||
"(?:" + ipv6seg + ":){1,2}(?::" + ipv6seg + "){1,5}|" + // 1::4:5:6:7:8 1:2::4:5:6:7:8 1:2::8
|
||||
ipv6seg + ":(?:(?::" + ipv6seg + "){1,6})|" // 1::3:4:5:6:7:8 1::3:4:5:6:7:8 1::8
|
||||
":(?:(?::" + ipv6seg + "){1,7}|:)|" // ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 ::
|
||||
"fe80:(?::" + ipv6seg + "){0,4}%[0-9a-zA-Z]{1,}|" // fe80::7:8%eth0 fe80::7:8%1 (link-local IPv6 addresses with zone index)
|
||||
"::(?:ffff(?::0{1,4}){0,1}:){0,1}" + v4_regex() + "|" // ::255.255.255.255 ::ffff:255.255.255.255 ::ffff:0:255.255.255.255 (IPv4-mapped IPv6 addresses and IPv4-translated addresses)
|
||||
"(?:" + ipv6seg + ":){1,4}:" + v4_regex() + // 2001:db8:3:4::192.0.2.33 64:ff9b::192.0.2.33 (IPv4-Embedded IPv6 Address)
|
||||
")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
260
OpenVPN Adapter/Vendors/openvpn/openvpn/addr/route.hpp
Normal file
260
OpenVPN Adapter/Vendors/openvpn/openvpn/addr/route.hpp
Normal file
@@ -0,0 +1,260 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef OPENVPN_ADDR_ROUTE_H
|
||||
#define OPENVPN_ADDR_ROUTE_H
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <cstdint> // for std::uint32_t
|
||||
|
||||
#include <openvpn/common/size.hpp>
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/common/number.hpp>
|
||||
#include <openvpn/common/to_string.hpp>
|
||||
#include <openvpn/common/split.hpp>
|
||||
#include <openvpn/common/hash.hpp>
|
||||
#include <openvpn/addr/ip.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
namespace IP {
|
||||
// Basic route object
|
||||
template <typename ADDR>
|
||||
struct RouteType
|
||||
{
|
||||
typedef ADDR Addr;
|
||||
|
||||
ADDR addr;
|
||||
unsigned int prefix_len;
|
||||
|
||||
OPENVPN_EXCEPTION(route_error);
|
||||
|
||||
RouteType()
|
||||
: prefix_len(0)
|
||||
{
|
||||
}
|
||||
|
||||
RouteType(const std::string& rtstr, const char *title = nullptr)
|
||||
: RouteType(RouteType::from_string(rtstr, title))
|
||||
{
|
||||
}
|
||||
|
||||
RouteType(const std::string& rtstr, const std::string& title)
|
||||
: RouteType(RouteType::from_string(rtstr, title.c_str()))
|
||||
{
|
||||
}
|
||||
|
||||
RouteType(const ADDR& addr_arg,
|
||||
const unsigned int prefix_len_arg)
|
||||
: addr(addr_arg),
|
||||
prefix_len(prefix_len_arg)
|
||||
{
|
||||
}
|
||||
|
||||
static RouteType from_string(const std::string& rtstr, const char *title = nullptr)
|
||||
{
|
||||
RouteType r;
|
||||
std::vector<std::string> pair;
|
||||
pair.reserve(2);
|
||||
Split::by_char_void<std::vector<std::string>, NullLex, Split::NullLimit>(pair, rtstr, '/', 0, 1);
|
||||
r.addr = ADDR::from_string(pair[0], title);
|
||||
if (pair.size() >= 2)
|
||||
{
|
||||
r.prefix_len = parse_number_throw<unsigned int>(pair[1], "prefix length");
|
||||
if (r.prefix_len > r.addr.size())
|
||||
OPENVPN_THROW(route_error, (title ? title : "route") << " : bad prefix length : " << rtstr);
|
||||
}
|
||||
else
|
||||
r.prefix_len = r.addr.size();
|
||||
return r;
|
||||
}
|
||||
|
||||
IP::Addr::Version version() const
|
||||
{
|
||||
return addr.version();
|
||||
}
|
||||
|
||||
IP::Addr::VersionMask version_mask() const
|
||||
{
|
||||
return addr.version_mask();
|
||||
}
|
||||
|
||||
ADDR netmask() const
|
||||
{
|
||||
return ADDR::netmask_from_prefix_len(version(), prefix_len);
|
||||
}
|
||||
|
||||
size_t extent() const
|
||||
{
|
||||
return netmask().extent_from_netmask().to_ulong();
|
||||
}
|
||||
|
||||
bool is_canonical() const
|
||||
{
|
||||
return (addr & netmask()) == addr;
|
||||
}
|
||||
|
||||
void force_canonical()
|
||||
{
|
||||
addr = addr & netmask();
|
||||
}
|
||||
|
||||
bool is_host() const
|
||||
{
|
||||
return addr.defined() && prefix_len == addr.size();
|
||||
}
|
||||
|
||||
bool contains(const ADDR& a) const // assumes canonical address/routes
|
||||
{
|
||||
if (addr.defined() && addr.version() == a.version())
|
||||
return (a & netmask()) == addr;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool contains(const RouteType& r) const // assumes canonical routes
|
||||
{
|
||||
return contains(r.addr) && r.prefix_len >= prefix_len;
|
||||
}
|
||||
|
||||
bool split(RouteType& r1, RouteType& r2) const // assumes we are canonical
|
||||
{
|
||||
if (!is_host())
|
||||
{
|
||||
const unsigned int newpl = prefix_len + 1;
|
||||
r1.addr = addr;
|
||||
r1.prefix_len = newpl;
|
||||
|
||||
r2.addr = addr + ADDR::netmask_from_prefix_len(addr.version(), newpl).extent_from_netmask();
|
||||
r2.prefix_len = newpl;
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string to_string() const
|
||||
{
|
||||
return addr.to_string() + '/' + openvpn::to_string(prefix_len);
|
||||
}
|
||||
|
||||
std::string to_string_by_netmask() const
|
||||
{
|
||||
return addr.to_string() + ' ' + netmask().to_string();
|
||||
}
|
||||
|
||||
bool operator==(const RouteType& other) const
|
||||
{
|
||||
return prefix_len == other.prefix_len && addr == other.addr;
|
||||
}
|
||||
|
||||
std::size_t hash_value() const
|
||||
{
|
||||
return Hash::value(addr, prefix_len);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ADDR>
|
||||
struct RouteTypeList : public std::vector<RouteType<ADDR>>
|
||||
{
|
||||
typedef std::vector< RouteType<ADDR> > Base;
|
||||
|
||||
OPENVPN_EXCEPTION(route_list_error);
|
||||
|
||||
std::string to_string() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
for (auto &r : *this)
|
||||
os << r.to_string() << std::endl;
|
||||
return os.str();
|
||||
}
|
||||
|
||||
IP::Addr::VersionMask version_mask() const
|
||||
{
|
||||
IP::Addr::VersionMask mask = 0;
|
||||
for (auto &r : *this)
|
||||
mask |= r.version_mask();
|
||||
return mask;
|
||||
}
|
||||
|
||||
void verify_canonical() const
|
||||
{
|
||||
for (auto &r : *this)
|
||||
if (!r.is_canonical())
|
||||
throw route_list_error("route not canonical: " + r.to_string());
|
||||
}
|
||||
|
||||
template <typename R>
|
||||
bool contains(const R& c) const
|
||||
{
|
||||
for (auto &r : *this)
|
||||
if (r.contains(c))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
typedef RouteType<IP::Addr> Route;
|
||||
typedef RouteType<IPv4::Addr> Route4;
|
||||
typedef RouteType<IPv6::Addr> Route6;
|
||||
|
||||
typedef RouteTypeList<IP::Addr> RouteList;
|
||||
typedef RouteTypeList<IPv4::Addr> Route4List;
|
||||
typedef RouteTypeList<IPv6::Addr> Route6List;
|
||||
|
||||
OPENVPN_OSTREAM(Route, to_string);
|
||||
OPENVPN_OSTREAM(Route4, to_string);
|
||||
OPENVPN_OSTREAM(Route6, to_string);
|
||||
|
||||
OPENVPN_OSTREAM(RouteList, to_string);
|
||||
OPENVPN_OSTREAM(Route4List, to_string);
|
||||
OPENVPN_OSTREAM(Route6List, to_string);
|
||||
|
||||
inline Route route_from_string_prefix(const std::string& addrstr,
|
||||
const unsigned int prefix_len,
|
||||
const std::string& title,
|
||||
const IP::Addr::Version required_version = IP::Addr::UNSPEC)
|
||||
{
|
||||
Route r;
|
||||
r.addr = IP::Addr(addrstr, title, required_version);
|
||||
r.prefix_len = prefix_len;
|
||||
if (r.prefix_len > r.addr.size())
|
||||
OPENVPN_THROW(Route::route_error, title << " : bad prefix length : " << addrstr);
|
||||
return r;
|
||||
}
|
||||
|
||||
inline Route route_from_string(const std::string& rtstr,
|
||||
const std::string& title,
|
||||
const IP::Addr::Version required_version = IP::Addr::UNSPEC)
|
||||
{
|
||||
Route r(rtstr, title);
|
||||
r.addr.validate_version(title, required_version);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OPENVPN_HASH_METHOD(openvpn::IP::Route, hash_value);
|
||||
OPENVPN_HASH_METHOD(openvpn::IP::Route4, hash_value);
|
||||
OPENVPN_HASH_METHOD(openvpn::IP::Route6, hash_value);
|
||||
|
||||
#endif
|
||||
105
OpenVPN Adapter/Vendors/openvpn/openvpn/addr/routeinv.hpp
Normal file
105
OpenVPN Adapter/Vendors/openvpn/openvpn/addr/routeinv.hpp
Normal file
@@ -0,0 +1,105 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Invert a route list. Used to support excluded routes on platforms that
|
||||
// don't support them natively.
|
||||
|
||||
#ifndef OPENVPN_ADDR_ROUTEINV_H
|
||||
#define OPENVPN_ADDR_ROUTEINV_H
|
||||
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/addr/route.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
namespace IP {
|
||||
class RouteInverter : public RouteList
|
||||
{
|
||||
public:
|
||||
OPENVPN_EXCEPTION(route_inverter);
|
||||
|
||||
RouteInverter() {}
|
||||
|
||||
// NOTE: when passing RouteInverter to this constructor, make sure
|
||||
// to static_cast it to RouteList& so as to avoid matching the
|
||||
// default copy constructor.
|
||||
explicit RouteInverter(const RouteList& in)
|
||||
: RouteInverter(in, in.version_mask())
|
||||
{
|
||||
}
|
||||
|
||||
RouteInverter(const RouteList& in, const Addr::VersionMask vermask)
|
||||
{
|
||||
in.verify_canonical();
|
||||
if (vermask & Addr::V4_MASK)
|
||||
descend(in, Addr::V4, Route(Addr::from_zero(Addr::V4), 0));
|
||||
if (vermask & Addr::V6_MASK)
|
||||
descend(in, Addr::V6, Route(Addr::from_zero(Addr::V6), 0));
|
||||
}
|
||||
|
||||
private:
|
||||
enum Type {
|
||||
EQUAL,
|
||||
SUBROUTE,
|
||||
LEAF,
|
||||
};
|
||||
|
||||
void descend(const RouteList& in, const Addr::Version ver, const Route& route)
|
||||
{
|
||||
switch (find(in, route))
|
||||
{
|
||||
case SUBROUTE:
|
||||
{
|
||||
Route r1, r2;
|
||||
if (route.split(r1, r2))
|
||||
{
|
||||
descend(in, ver, r1);
|
||||
descend(in, ver, r2);
|
||||
}
|
||||
else
|
||||
push_back(route);
|
||||
break;
|
||||
}
|
||||
case LEAF:
|
||||
push_back(route);
|
||||
break;
|
||||
case EQUAL:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static Type find(const RouteList& in, const Route& route)
|
||||
{
|
||||
Type type = LEAF;
|
||||
for (RouteList::const_iterator i = in.begin(); i != in.end(); ++i)
|
||||
{
|
||||
const Route& r = *i;
|
||||
if (route == r)
|
||||
return EQUAL;
|
||||
else if (route.contains(r))
|
||||
type = SUBROUTE;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
325
OpenVPN Adapter/Vendors/openvpn/openvpn/apple/maclife.hpp
Normal file
325
OpenVPN Adapter/Vendors/openvpn/openvpn/apple/maclife.hpp
Normal file
@@ -0,0 +1,325 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef OPENVPN_APPLE_MACLIFE_H
|
||||
#define OPENVPN_APPLE_MACLIFE_H
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include <openvpn/log/logthread.hpp>
|
||||
#include <openvpn/applecrypto/cf/cftimer.hpp>
|
||||
#include <openvpn/applecrypto/cf/cfhelper.hpp>
|
||||
#include <openvpn/applecrypto/util/reachable.hpp>
|
||||
#include <openvpn/client/clilife.hpp>
|
||||
#include <openvpn/apple/runloop.hpp>
|
||||
#include <openvpn/apple/macsleep.hpp>
|
||||
#include <openvpn/apple/scdynstore.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
class MacLifeCycle : public ClientLifeCycle, MacSleep, ReachabilityTracker
|
||||
{
|
||||
public:
|
||||
OPENVPN_EXCEPTION(mac_lifecycle_error);
|
||||
|
||||
MacLifeCycle()
|
||||
: ReachabilityTracker(true, false),
|
||||
nc(nullptr),
|
||||
thread(nullptr),
|
||||
paused(false)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~MacLifeCycle()
|
||||
{
|
||||
stop_thread();
|
||||
}
|
||||
|
||||
virtual bool network_available()
|
||||
{
|
||||
return net_up();
|
||||
}
|
||||
|
||||
virtual void start(NotifyCallback* nc_arg)
|
||||
{
|
||||
if (!thread && nc_arg)
|
||||
{
|
||||
nc = nc_arg;
|
||||
thread = new std::thread(&MacLifeCycle::thread_func, this);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void stop()
|
||||
{
|
||||
stop_thread();
|
||||
}
|
||||
|
||||
private:
|
||||
struct State
|
||||
{
|
||||
State()
|
||||
: net_up(false),
|
||||
sleep(false)
|
||||
{
|
||||
}
|
||||
|
||||
State(bool net_up_arg, const std::string& iface_arg, bool sleep_arg)
|
||||
: net_up(net_up_arg),
|
||||
iface(iface_arg),
|
||||
sleep(sleep_arg)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator==(const State& other) const
|
||||
{
|
||||
return net_up == other.net_up && iface == other.iface && sleep == other.sleep;
|
||||
}
|
||||
|
||||
bool operator!=(const State& other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
std::string to_string() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "[net_up=" << net_up << " iface=" << iface << " sleep=" << sleep << ']';
|
||||
return os.str();
|
||||
}
|
||||
|
||||
bool net_up;
|
||||
std::string iface;
|
||||
bool sleep;
|
||||
};
|
||||
|
||||
void stop_thread()
|
||||
{
|
||||
if (thread)
|
||||
{
|
||||
if (runloop.defined())
|
||||
CFRunLoopStop(runloop());
|
||||
thread->join();
|
||||
delete thread;
|
||||
thread = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void thread_func()
|
||||
{
|
||||
runloop.reset(CFRunLoopGetCurrent(), CF::BORROW);
|
||||
Log::Context logctx(logwrap);
|
||||
try {
|
||||
// set up dynamic store query object
|
||||
dstore.reset(SCDynamicStoreCreate(kCFAllocatorDefault,
|
||||
CFSTR("OpenVPN_MacLifeCycle"),
|
||||
nullptr,
|
||||
nullptr));
|
||||
|
||||
// init state
|
||||
state = State(net_up(), primary_interface(), false);
|
||||
prev_state = state;
|
||||
paused = false;
|
||||
|
||||
// enable sleep/wakeup notifications
|
||||
mac_sleep_start();
|
||||
|
||||
// enable network reachability notifications
|
||||
reachability_tracker_schedule();
|
||||
|
||||
// enable interface change notifications
|
||||
iface_watch();
|
||||
|
||||
// process event loop until CFRunLoopStop is called from parent thread
|
||||
CFRunLoopRun();
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
OPENVPN_LOG("MacLifeCycle Exception: " << e.what());
|
||||
}
|
||||
|
||||
// cleanup
|
||||
cancel_action_timer();
|
||||
mac_sleep_stop();
|
||||
reachability_tracker_cancel();
|
||||
dstore.reset();
|
||||
}
|
||||
|
||||
std::string primary_interface()
|
||||
{
|
||||
CF::Dict dict(CF::DynamicStoreCopyDict(dstore, "State:/Network/Global/IPv4"));
|
||||
return CF::dict_get_str(dict, "PrimaryInterface");
|
||||
}
|
||||
|
||||
bool net_up()
|
||||
{
|
||||
ReachabilityViaInternet r;
|
||||
return ReachabilityViaInternet::status_from_flags(r.flags()) != ReachabilityInterface::NotReachable;
|
||||
}
|
||||
|
||||
void iface_watch()
|
||||
{
|
||||
SCDynamicStoreContext context = {0, this, nullptr, nullptr, nullptr};
|
||||
CF::DynamicStore ds(SCDynamicStoreCreate(kCFAllocatorDefault,
|
||||
CFSTR("OpenVPN_MacLifeCycle_iface_watch"),
|
||||
iface_watch_callback_static,
|
||||
&context));
|
||||
if (!ds.defined())
|
||||
throw mac_lifecycle_error("SCDynamicStoreCreate");
|
||||
CF::MutableArray watched_keys(CF::mutable_array());
|
||||
CF::array_append_str(watched_keys, "State:/Network/Global/IPv4");
|
||||
//CF::array_append_str(watched_keys, "State:/Network/Global/IPv6");
|
||||
if (!watched_keys.defined())
|
||||
throw mac_lifecycle_error("watched_keys is undefined");
|
||||
if (!SCDynamicStoreSetNotificationKeys(ds(),
|
||||
watched_keys(),
|
||||
nullptr))
|
||||
throw mac_lifecycle_error("SCDynamicStoreSetNotificationKeys failed");
|
||||
CF::RunLoopSource rls(SCDynamicStoreCreateRunLoopSource(kCFAllocatorDefault, ds(), 0));
|
||||
if (!rls.defined())
|
||||
throw mac_lifecycle_error("SCDynamicStoreCreateRunLoopSource failed");
|
||||
CFRunLoopAddSource(CFRunLoopGetCurrent(), rls(), kCFRunLoopDefaultMode);
|
||||
}
|
||||
|
||||
static void iface_watch_callback_static(SCDynamicStoreRef store, CFArrayRef changedKeys, void *arg)
|
||||
{
|
||||
MacLifeCycle *self = (MacLifeCycle *)arg;
|
||||
self->iface_watch_callback(store, changedKeys);
|
||||
}
|
||||
|
||||
void iface_watch_callback(SCDynamicStoreRef store, CFArrayRef changedKeys)
|
||||
{
|
||||
state.iface = primary_interface();
|
||||
OPENVPN_LOG("MacLifeCycle NET_IFACE " << state.iface);
|
||||
schedule_action_timer(1);
|
||||
}
|
||||
|
||||
virtual void notify_sleep()
|
||||
{
|
||||
OPENVPN_LOG("MacLifeCycle SLEEP");
|
||||
state.sleep = true;
|
||||
schedule_action_timer(0);
|
||||
}
|
||||
|
||||
virtual void notify_wakeup()
|
||||
{
|
||||
OPENVPN_LOG("MacLifeCycle WAKEUP");
|
||||
state.sleep = false;
|
||||
schedule_action_timer(1);
|
||||
}
|
||||
|
||||
virtual void reachability_tracker_event(const ReachabilityBase& rb, SCNetworkReachabilityFlags flags)
|
||||
{
|
||||
if (rb.vtype() == ReachabilityBase::Internet)
|
||||
{
|
||||
const ReachabilityBase::Status status = rb.vstatus(flags);
|
||||
state.net_up = (status != ReachabilityInterface::NotReachable);
|
||||
OPENVPN_LOG("MacLifeCycle NET_STATE " << state.net_up << " status=" << ReachabilityBase::render_status(status) << " flags=" << ReachabilityBase::render_flags(flags));
|
||||
schedule_action_timer(1);
|
||||
}
|
||||
}
|
||||
|
||||
void schedule_action_timer(const int seconds)
|
||||
{
|
||||
cancel_action_timer();
|
||||
if (seconds)
|
||||
{
|
||||
CFRunLoopTimerContext context = { 0, this, nullptr, nullptr, nullptr };
|
||||
action_timer.reset(CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + seconds, 0, 0, 0, action_timer_callback_static, &context));
|
||||
if (action_timer.defined())
|
||||
CFRunLoopAddTimer(CFRunLoopGetCurrent(), action_timer(), kCFRunLoopCommonModes);
|
||||
else
|
||||
OPENVPN_LOG("MacLifeCycle::schedule_action_timer: failed to create timer");
|
||||
}
|
||||
else
|
||||
action_timer_callback(nullptr);
|
||||
}
|
||||
|
||||
void cancel_action_timer()
|
||||
{
|
||||
if (action_timer.defined())
|
||||
{
|
||||
CFRunLoopTimerInvalidate(action_timer());
|
||||
action_timer.reset(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
static void action_timer_callback_static(CFRunLoopTimerRef timer, void *info)
|
||||
{
|
||||
MacLifeCycle* self = (MacLifeCycle*)info;
|
||||
self->action_timer_callback(timer);
|
||||
}
|
||||
|
||||
void action_timer_callback(CFRunLoopTimerRef timer)
|
||||
{
|
||||
try {
|
||||
if (state != prev_state)
|
||||
{
|
||||
OPENVPN_LOG("MacLifeCycle ACTION pause=" << paused << " state=" << state.to_string() << " prev=" << prev_state.to_string());
|
||||
if (paused)
|
||||
{
|
||||
if (!state.sleep && state.net_up)
|
||||
{
|
||||
nc->cln_resume();
|
||||
paused = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (state.sleep)
|
||||
{
|
||||
nc->cln_pause("sleep");
|
||||
paused = true;
|
||||
}
|
||||
else if (!state.net_up)
|
||||
{
|
||||
nc->cln_pause("network-unavailable");
|
||||
paused = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (state.iface != prev_state.iface)
|
||||
nc->cln_reconnect(0);
|
||||
}
|
||||
}
|
||||
prev_state = state;
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
OPENVPN_LOG("MacLifeCycle::action_timer_callback: " << e.what());
|
||||
}
|
||||
}
|
||||
|
||||
NotifyCallback* nc;
|
||||
std::thread* thread;
|
||||
CF::RunLoop runloop; // run loop in thread
|
||||
CF::DynamicStore dstore;
|
||||
State state;
|
||||
State prev_state;
|
||||
bool paused;
|
||||
CF::Timer action_timer;
|
||||
Log::Context::Wrapper logwrap; // used to carry forward the log context from parent thread
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
129
OpenVPN Adapter/Vendors/openvpn/openvpn/apple/macsleep.hpp
Normal file
129
OpenVPN Adapter/Vendors/openvpn/openvpn/apple/macsleep.hpp
Normal file
@@ -0,0 +1,129 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef OPENVPN_APPLE_MACSLEEP_H
|
||||
#define OPENVPN_APPLE_MACSLEEP_H
|
||||
|
||||
#include <mach/mach_port.h>
|
||||
#include <mach/mach_interface.h>
|
||||
#include <mach/mach_init.h>
|
||||
|
||||
#include <IOKit/pwr_mgt/IOPMLib.h>
|
||||
#include <IOKit/IOMessage.h>
|
||||
|
||||
#include <openvpn/common/size.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
class MacSleep
|
||||
{
|
||||
MacSleep(const MacSleep&) = delete;
|
||||
MacSleep& operator=(const MacSleep&) = delete;
|
||||
|
||||
public:
|
||||
MacSleep()
|
||||
: root_port(0),
|
||||
notifyPortRef(nullptr),
|
||||
notifierObject(0)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~MacSleep()
|
||||
{
|
||||
mac_sleep_stop();
|
||||
}
|
||||
|
||||
bool mac_sleep_start()
|
||||
{
|
||||
if (!root_port)
|
||||
{
|
||||
root_port = IORegisterForSystemPower(this, ¬ifyPortRef, callback_static, ¬ifierObject);
|
||||
if (!root_port)
|
||||
return false;
|
||||
CFRunLoopAddSource(CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(notifyPortRef), kCFRunLoopCommonModes);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void mac_sleep_stop()
|
||||
{
|
||||
if (root_port)
|
||||
{
|
||||
// remove the sleep notification port from the application runloop
|
||||
CFRunLoopRemoveSource(CFRunLoopGetCurrent(),
|
||||
IONotificationPortGetRunLoopSource(notifyPortRef),
|
||||
kCFRunLoopCommonModes);
|
||||
|
||||
// deregister for system sleep notifications
|
||||
IODeregisterForSystemPower(¬ifierObject);
|
||||
|
||||
// IORegisterForSystemPower implicitly opens the Root Power Domain IOService
|
||||
// so we close it here
|
||||
IOServiceClose(root_port);
|
||||
|
||||
// destroy the notification port allocated by IORegisterForSystemPower
|
||||
IONotificationPortDestroy(notifyPortRef);
|
||||
|
||||
// reset object members
|
||||
root_port = 0;
|
||||
notifyPortRef = nullptr;
|
||||
notifierObject = 0;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void notify_sleep() = 0;
|
||||
virtual void notify_wakeup() = 0;
|
||||
|
||||
private:
|
||||
static void callback_static(void* arg, io_service_t service, natural_t messageType, void *messageArgument)
|
||||
{
|
||||
MacSleep* self = (MacSleep*)arg;
|
||||
self->callback(service, messageType, messageArgument);
|
||||
}
|
||||
|
||||
void callback(io_service_t service, natural_t messageType, void *messageArgument)
|
||||
{
|
||||
switch (messageType)
|
||||
{
|
||||
case kIOMessageCanSystemSleep:
|
||||
IOAllowPowerChange(root_port, (long)messageArgument);
|
||||
break;
|
||||
case kIOMessageSystemWillSleep:
|
||||
notify_sleep();
|
||||
IOAllowPowerChange(root_port, (long)messageArgument);
|
||||
break;
|
||||
case kIOMessageSystemHasPoweredOn:
|
||||
notify_wakeup();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// a reference to the Root Power Domain IOService
|
||||
io_connect_t root_port;
|
||||
|
||||
// notification port allocated by IORegisterForSystemPower
|
||||
IONotificationPortRef notifyPortRef;
|
||||
|
||||
// notifier object, used to deregister later
|
||||
io_object_t notifierObject;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
75
OpenVPN Adapter/Vendors/openvpn/openvpn/apple/macver.hpp
Normal file
75
OpenVPN Adapter/Vendors/openvpn/openvpn/apple/macver.hpp
Normal file
@@ -0,0 +1,75 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef OPENVPN_APPLE_MACVER_H
|
||||
#define OPENVPN_APPLE_MACVER_H
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#include <openvpn/common/split.hpp>
|
||||
#include <openvpn/common/number.hpp>
|
||||
#include <openvpn/apple/ver.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
namespace Mac {
|
||||
class Version : public AppleVersion
|
||||
{
|
||||
public:
|
||||
// Mac OS X versions
|
||||
// 15.x.x OS X 10.11.x El Capitan
|
||||
// 14.x.x OS X 10.10.x Yosemite
|
||||
// 13.x.x OS X 10.9.x Mavericks
|
||||
// 12.x.x OS X 10.8.x Mountain Lion
|
||||
// 11.x.x OS X 10.7.x Lion
|
||||
// 10.x.x OS X 10.6.x Snow Leopard
|
||||
// 9.x.x OS X 10.5.x Leopard
|
||||
// 8.x.x OS X 10.4.x Tiger
|
||||
// 7.x.x OS X 10.3.x Panther
|
||||
// 6.x.x OS X 10.2.x Jaguar
|
||||
// 5.x OS X 10.1.x Puma
|
||||
|
||||
enum {
|
||||
OSX_10_11=15,
|
||||
OSX_10_10=14,
|
||||
OSX_10_9=13,
|
||||
OSX_10_8=12,
|
||||
OSX_10_7=11,
|
||||
OSX_10_6=10,
|
||||
};
|
||||
|
||||
Version()
|
||||
{
|
||||
char str[256];
|
||||
size_t size = sizeof(str);
|
||||
int ret = sysctlbyname("kern.osrelease", str, &size, nullptr, 0);
|
||||
if (!ret)
|
||||
init(std::string(str, size));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
34
OpenVPN Adapter/Vendors/openvpn/openvpn/apple/runloop.hpp
Normal file
34
OpenVPN Adapter/Vendors/openvpn/openvpn/apple/runloop.hpp
Normal file
@@ -0,0 +1,34 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef OPENVPN_APPLE_RUNLOOP_H
|
||||
#define OPENVPN_APPLE_RUNLOOP_H
|
||||
|
||||
#include <openvpn/applecrypto/cf/cf.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
namespace CF {
|
||||
OPENVPN_CF_WRAP(RunLoop, runloop_cast, CFRunLoopRef, CFRunLoopGetTypeID);
|
||||
OPENVPN_CF_WRAP(RunLoopSource, runloop_source_cast, CFRunLoopSourceRef, CFRunLoopSourceGetTypeID);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
52
OpenVPN Adapter/Vendors/openvpn/openvpn/apple/scdynstore.hpp
Normal file
52
OpenVPN Adapter/Vendors/openvpn/openvpn/apple/scdynstore.hpp
Normal file
@@ -0,0 +1,52 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef OPENVPN_APPLE_SCDYNSTORE_H
|
||||
#define OPENVPN_APPLE_SCDYNSTORE_H
|
||||
|
||||
#include <SystemConfiguration/SCDynamicStore.h>
|
||||
|
||||
#include <openvpn/applecrypto/cf/cf.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
namespace CF {
|
||||
OPENVPN_CF_WRAP(DynamicStore, dynamic_store_cast, SCDynamicStoreRef, SCDynamicStoreGetTypeID)
|
||||
|
||||
template <typename RET, typename KEY>
|
||||
inline RET DynamicStoreCopy(const DynamicStore& ds, const KEY& key)
|
||||
{
|
||||
String keystr = string(key);
|
||||
return RET(RET::cast(SCDynamicStoreCopyValue(ds(), keystr())));
|
||||
}
|
||||
|
||||
template <typename KEY>
|
||||
inline Dict DynamicStoreCopyDict(const DynamicStore& ds, const KEY& key)
|
||||
{
|
||||
Dict dict = DynamicStoreCopy<Dict>(ds, key);
|
||||
if (dict.defined())
|
||||
return dict;
|
||||
else
|
||||
return CF::empty_dict();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
81
OpenVPN Adapter/Vendors/openvpn/openvpn/apple/ver.hpp
Normal file
81
OpenVPN Adapter/Vendors/openvpn/openvpn/apple/ver.hpp
Normal file
@@ -0,0 +1,81 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef OPENVPN_APPLE_VER_H
|
||||
#define OPENVPN_APPLE_VER_H
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#include <openvpn/common/split.hpp>
|
||||
#include <openvpn/common/number.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
class AppleVersion
|
||||
{
|
||||
public:
|
||||
int major() const { return ver[0]; }
|
||||
int minor() const { return ver[1]; }
|
||||
int build() const { return ver[2]; }
|
||||
|
||||
std::string to_string() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << major() << '.' << minor() << '.' << build();
|
||||
return os.str();
|
||||
}
|
||||
|
||||
protected:
|
||||
AppleVersion()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
// verstr should be in the form major.minor.build
|
||||
void init(const std::string& verstr)
|
||||
{
|
||||
typedef std::vector<std::string> StringList;
|
||||
reset();
|
||||
StringList sl;
|
||||
sl.reserve(3);
|
||||
Split::by_char_void<StringList, NullLex, Split::NullLimit>(sl, verstr, '.');
|
||||
for (size_t i = 0; i < 3; ++i)
|
||||
{
|
||||
if (i < sl.size())
|
||||
parse_number(sl[i], ver[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void reset()
|
||||
{
|
||||
ver[0] = ver[1] = ver[2] = -1;
|
||||
}
|
||||
|
||||
int ver[3];
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
464
OpenVPN Adapter/Vendors/openvpn/openvpn/applecrypto/cf/cf.hpp
Normal file
464
OpenVPN Adapter/Vendors/openvpn/openvpn/applecrypto/cf/cf.hpp
Normal file
@@ -0,0 +1,464 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef OPENVPN_APPLECRYPTO_CF_CF_H
|
||||
#define OPENVPN_APPLECRYPTO_CF_CF_H
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
#include <openvpn/common/size.hpp>
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/buffer/buffer.hpp>
|
||||
|
||||
// Wrapper classes for Apple Core Foundation objects.
|
||||
|
||||
#define OPENVPN_CF_WRAP(cls, castmeth, cftype, idmeth) \
|
||||
template <> \
|
||||
struct Type<cftype> \
|
||||
{ \
|
||||
static CFTypeRef cast(CFTypeRef obj) \
|
||||
{ \
|
||||
if (obj && CFGetTypeID(obj) == idmeth()) \
|
||||
return obj; \
|
||||
else \
|
||||
return nullptr; \
|
||||
} \
|
||||
}; \
|
||||
typedef Wrap<cftype> cls; \
|
||||
inline cls castmeth(CFTypeRef obj) \
|
||||
{ \
|
||||
CFTypeRef o = Type<cftype>::cast(obj); \
|
||||
if (o) \
|
||||
return cls(cftype(o), BORROW); \
|
||||
else \
|
||||
return cls(); \
|
||||
}
|
||||
|
||||
namespace openvpn {
|
||||
namespace CF
|
||||
{
|
||||
enum Own {
|
||||
OWN,
|
||||
BORROW
|
||||
};
|
||||
|
||||
template <typename T> struct Type {};
|
||||
|
||||
template <typename T>
|
||||
class Wrap
|
||||
{
|
||||
public:
|
||||
Wrap() : obj_(nullptr) {}
|
||||
|
||||
// Set own=BORROW if we don't currently own the object
|
||||
explicit Wrap(T obj, const Own own=OWN)
|
||||
{
|
||||
if (own == BORROW && obj)
|
||||
CFRetain(obj);
|
||||
obj_ = obj;
|
||||
}
|
||||
|
||||
Wrap(const Wrap& other)
|
||||
{
|
||||
obj_ = other.obj_;
|
||||
if (obj_)
|
||||
CFRetain(obj_);
|
||||
}
|
||||
|
||||
Wrap& operator=(const Wrap& other)
|
||||
{
|
||||
if (other.obj_)
|
||||
CFRetain(other.obj_);
|
||||
if (obj_)
|
||||
CFRelease(obj_);
|
||||
obj_ = other.obj_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Wrap(Wrap&& other) noexcept
|
||||
{
|
||||
obj_ = other.obj_;
|
||||
other.obj_ = nullptr;
|
||||
}
|
||||
|
||||
Wrap& operator=(Wrap&& other) noexcept
|
||||
{
|
||||
if (obj_)
|
||||
CFRelease(obj_);
|
||||
obj_ = other.obj_;
|
||||
other.obj_ = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(Wrap& other)
|
||||
{
|
||||
std::swap(obj_, other.obj_);
|
||||
}
|
||||
|
||||
void reset(T obj=nullptr, const Own own=OWN)
|
||||
{
|
||||
if (own == BORROW && obj)
|
||||
CFRetain(obj);
|
||||
if (obj_)
|
||||
CFRelease(obj_);
|
||||
obj_ = obj;
|
||||
}
|
||||
|
||||
bool defined() const { return obj_ != nullptr; }
|
||||
|
||||
T operator()() const { return obj_; }
|
||||
|
||||
CFTypeRef generic() const { return (CFTypeRef)obj_; }
|
||||
|
||||
static T cast(CFTypeRef obj) { return T(Type<T>::cast(obj)); }
|
||||
|
||||
static Wrap from_generic(CFTypeRef obj, const Own own=OWN)
|
||||
{
|
||||
return Wrap(cast(obj), own);
|
||||
}
|
||||
|
||||
T release()
|
||||
{
|
||||
T ret = obj_;
|
||||
obj_ = nullptr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
CFTypeRef generic_release()
|
||||
{
|
||||
T ret = obj_;
|
||||
obj_ = nullptr;
|
||||
return (CFTypeRef)ret;
|
||||
}
|
||||
|
||||
// Intended for use with Core Foundation methods that require
|
||||
// a T* for saving a (non-borrowed) return value
|
||||
T* mod_ref()
|
||||
{
|
||||
if (obj_)
|
||||
{
|
||||
CFRelease(obj_);
|
||||
obj_ = nullptr;
|
||||
}
|
||||
return &obj_;
|
||||
}
|
||||
|
||||
void show() const
|
||||
{
|
||||
if (obj_)
|
||||
CFShow(obj_);
|
||||
else
|
||||
std::cerr << "CF_UNDEFINED" << std::endl;
|
||||
}
|
||||
|
||||
virtual ~Wrap()
|
||||
{
|
||||
if (obj_)
|
||||
CFRelease(obj_);
|
||||
}
|
||||
|
||||
private:
|
||||
Wrap& operator=(T obj); // prevent use because no way to pass ownership parameter
|
||||
|
||||
T obj_;
|
||||
};
|
||||
|
||||
// essentially a vector of void *, used as source for array and dictionary constructors
|
||||
typedef BufferAllocatedType<CFTypeRef> SrcList;
|
||||
|
||||
// common CF types
|
||||
|
||||
OPENVPN_CF_WRAP(String, string_cast, CFStringRef, CFStringGetTypeID)
|
||||
OPENVPN_CF_WRAP(Number, number_cast, CFNumberRef, CFNumberGetTypeID)
|
||||
OPENVPN_CF_WRAP(Bool, bool_cast, CFBooleanRef, CFBooleanGetTypeID)
|
||||
OPENVPN_CF_WRAP(Data, data_cast, CFDataRef, CFDataGetTypeID)
|
||||
OPENVPN_CF_WRAP(Array, array_cast, CFArrayRef, CFArrayGetTypeID)
|
||||
OPENVPN_CF_WRAP(MutableArray, mutable_array_cast, CFMutableArrayRef, CFArrayGetTypeID)
|
||||
OPENVPN_CF_WRAP(Dict, dict_cast, CFDictionaryRef, CFDictionaryGetTypeID)
|
||||
OPENVPN_CF_WRAP(MutableDict, mutable_dict_cast, CFMutableDictionaryRef, CFDictionaryGetTypeID)
|
||||
OPENVPN_CF_WRAP(Error, error_cast, CFErrorRef, CFErrorGetTypeID);
|
||||
|
||||
// generic CFTypeRef wrapper
|
||||
|
||||
typedef Wrap<CFTypeRef> Generic;
|
||||
|
||||
inline Generic generic_cast(CFTypeRef obj)
|
||||
{
|
||||
return Generic(obj, BORROW);
|
||||
}
|
||||
|
||||
// constructors
|
||||
|
||||
inline String string(const char *str)
|
||||
{
|
||||
return String(CFStringCreateWithCString(kCFAllocatorDefault, str, kCFStringEncodingUTF8));
|
||||
}
|
||||
|
||||
inline String string(CFStringRef str)
|
||||
{
|
||||
return String(str, BORROW);
|
||||
}
|
||||
|
||||
inline String string(const String& str)
|
||||
{
|
||||
return String(str);
|
||||
}
|
||||
|
||||
inline String string(const std::string& str)
|
||||
{
|
||||
return String(CFStringCreateWithCString(kCFAllocatorDefault, str.c_str(), kCFStringEncodingUTF8));
|
||||
}
|
||||
|
||||
inline String string(const std::string* str)
|
||||
{
|
||||
return String(CFStringCreateWithCString(kCFAllocatorDefault, str->c_str(), kCFStringEncodingUTF8));
|
||||
}
|
||||
|
||||
inline Number number_from_int(const int n)
|
||||
{
|
||||
return Number(CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &n));
|
||||
}
|
||||
|
||||
inline Number number_from_int32(const SInt32 n)
|
||||
{
|
||||
return Number(CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &n));
|
||||
}
|
||||
|
||||
inline Number number_from_long_long(const long long n)
|
||||
{
|
||||
return Number(CFNumberCreate(kCFAllocatorDefault, kCFNumberLongLongType, &n));
|
||||
}
|
||||
|
||||
inline Number number_from_index(const CFIndex n)
|
||||
{
|
||||
return Number(CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &n));
|
||||
}
|
||||
|
||||
inline Data data(const void *bytes, CFIndex length)
|
||||
{
|
||||
return Data(CFDataCreate(kCFAllocatorDefault, (const UInt8 *)bytes, length));
|
||||
}
|
||||
|
||||
inline Array array(const void **values, CFIndex numValues)
|
||||
{
|
||||
return Array(CFArrayCreate(kCFAllocatorDefault, values, numValues, &kCFTypeArrayCallBacks));
|
||||
}
|
||||
|
||||
inline Array array(const SrcList& values)
|
||||
{
|
||||
return array((const void **)values.c_data(), values.size());
|
||||
}
|
||||
|
||||
inline Dict dict(const void **keys, const void **values, CFIndex numValues)
|
||||
{
|
||||
return Dict(CFDictionaryCreate(kCFAllocatorDefault,
|
||||
keys,
|
||||
values,
|
||||
numValues,
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks));
|
||||
}
|
||||
|
||||
inline Dict dict(const SrcList& keys, const SrcList& values)
|
||||
{
|
||||
return dict((const void **)keys.c_data(), (const void **)values.c_data(), std::min(keys.size(), values.size()));
|
||||
}
|
||||
|
||||
inline Dict const_dict(MutableDict& mdict)
|
||||
{
|
||||
return Dict(mdict(), CF::BORROW);
|
||||
}
|
||||
|
||||
inline Array const_array(MutableArray& marray)
|
||||
{
|
||||
return Array(marray(), CF::BORROW);
|
||||
}
|
||||
|
||||
inline Dict empty_dict()
|
||||
{
|
||||
return Dict(CFDictionaryCreate(kCFAllocatorDefault,
|
||||
nullptr,
|
||||
nullptr,
|
||||
0,
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks));
|
||||
}
|
||||
|
||||
inline MutableArray mutable_array(const CFIndex capacity=0)
|
||||
{
|
||||
return MutableArray(CFArrayCreateMutable(kCFAllocatorDefault, capacity, &kCFTypeArrayCallBacks));
|
||||
}
|
||||
|
||||
inline MutableDict mutable_dict(const CFIndex capacity=0)
|
||||
{
|
||||
return MutableDict(CFDictionaryCreateMutable(kCFAllocatorDefault, capacity, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
|
||||
}
|
||||
|
||||
template <typename DICT>
|
||||
inline MutableDict mutable_dict_copy(const DICT& dict, const CFIndex capacity=0)
|
||||
{
|
||||
if (dict.defined())
|
||||
return MutableDict(CFDictionaryCreateMutableCopy(kCFAllocatorDefault, capacity, dict()));
|
||||
else
|
||||
return mutable_dict(capacity);
|
||||
}
|
||||
|
||||
inline Error error(CFStringRef domain, CFIndex code, CFDictionaryRef userInfo)
|
||||
{
|
||||
return Error(CFErrorCreate(kCFAllocatorDefault, domain, code, userInfo));
|
||||
}
|
||||
|
||||
// accessors
|
||||
|
||||
template <typename ARRAY>
|
||||
inline CFIndex array_len(const ARRAY& array)
|
||||
{
|
||||
if (array.defined())
|
||||
return CFArrayGetCount(array());
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename DICT>
|
||||
inline CFIndex dict_len(const DICT& dict)
|
||||
{
|
||||
if (dict.defined())
|
||||
return CFDictionaryGetCount(dict());
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename ARRAY>
|
||||
inline CFTypeRef array_index(const ARRAY& array, const CFIndex idx)
|
||||
{
|
||||
if (array.defined() && CFArrayGetCount(array()) > idx)
|
||||
return CFArrayGetValueAtIndex(array(), idx);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename DICT, typename KEY>
|
||||
inline CFTypeRef dict_index(const DICT& dict, const KEY& key)
|
||||
{
|
||||
if (dict.defined())
|
||||
{
|
||||
String keystr = string(key);
|
||||
if (keystr.defined())
|
||||
return CFDictionaryGetValue(dict(), keystr());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// string methods
|
||||
|
||||
OPENVPN_SIMPLE_EXCEPTION(cppstring_error);
|
||||
|
||||
inline std::string cppstring(CFStringRef str)
|
||||
{
|
||||
const CFStringEncoding encoding = kCFStringEncodingUTF8;
|
||||
if (str)
|
||||
{
|
||||
const CFIndex len = CFStringGetLength(str);
|
||||
if (len > 0)
|
||||
{
|
||||
const CFIndex maxsize = CFStringGetMaximumSizeForEncoding(len, encoding);
|
||||
char *buf = new char[maxsize];
|
||||
const Boolean status = CFStringGetCString(str, buf, maxsize, encoding);
|
||||
if (status)
|
||||
{
|
||||
std::string ret(buf);
|
||||
delete [] buf;
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete [] buf;
|
||||
throw cppstring_error();
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
inline std::string cppstring(const String& str)
|
||||
{
|
||||
return cppstring(str());
|
||||
}
|
||||
|
||||
inline std::string description(CFTypeRef obj)
|
||||
{
|
||||
if (obj)
|
||||
{
|
||||
String s(CFCopyDescription(obj));
|
||||
return cppstring(s);
|
||||
}
|
||||
else
|
||||
return "UNDEF";
|
||||
}
|
||||
|
||||
// format an array of strings (non-string elements in array are ignored)
|
||||
template <typename ARRAY>
|
||||
inline std::string array_to_string(const ARRAY& array, const char delim=',')
|
||||
{
|
||||
std::ostringstream os;
|
||||
const CFIndex len = array_len(array);
|
||||
if (len)
|
||||
{
|
||||
bool sep = false;
|
||||
for (CFIndex i = 0; i < len; ++i)
|
||||
{
|
||||
const String v(string_cast(array_index(array, i)));
|
||||
if (v.defined())
|
||||
{
|
||||
if (sep)
|
||||
os << delim;
|
||||
os << cppstring(v);
|
||||
sep = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
||||
inline bool string_equal(const String& s1, const String& s2, const CFStringCompareFlags compareOptions = 0)
|
||||
{
|
||||
return s1.defined() && s2.defined() && CFStringCompare(s1(), s2(), compareOptions) == kCFCompareEqualTo;
|
||||
}
|
||||
|
||||
// property lists
|
||||
inline Data plist(CFTypeRef obj)
|
||||
{
|
||||
return Data(CFPropertyListCreateData(kCFAllocatorDefault,
|
||||
obj,
|
||||
kCFPropertyListBinaryFormat_v1_0,
|
||||
0,
|
||||
nullptr));
|
||||
}
|
||||
|
||||
} // namespace CF
|
||||
} // namespace openvpn
|
||||
|
||||
#endif // OPENVPN_APPLECRYPTO_CF_CF_H
|
||||
@@ -0,0 +1,247 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef OPENVPN_APPLECRYPTO_CF_CFHELPER_H
|
||||
#define OPENVPN_APPLECRYPTO_CF_CFHELPER_H
|
||||
|
||||
#include <openvpn/applecrypto/cf/cf.hpp>
|
||||
|
||||
// These methods build on the Wrapper classes for Apple Core Foundation objects
|
||||
// defined in cf.hpp. They add additional convenience methods, such as dictionary
|
||||
// lookup.
|
||||
|
||||
namespace openvpn {
|
||||
namespace CF {
|
||||
|
||||
inline CFTypeRef mutable_dict_new()
|
||||
{
|
||||
return CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
|
||||
}
|
||||
|
||||
inline CFTypeRef mutable_array_new()
|
||||
{
|
||||
return CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
|
||||
}
|
||||
|
||||
// Lookup or create (if absent) an item in a mutable dictionary.
|
||||
// Return the item, which will be owned by base.
|
||||
template <typename KEY>
|
||||
inline CFTypeRef dict_get_create(CFMutableDictionaryRef base,
|
||||
const KEY& key,
|
||||
CFTypeRef (*create_method)())
|
||||
{
|
||||
if (base)
|
||||
{
|
||||
String keystr = string(key);
|
||||
CFTypeRef ret = CFDictionaryGetValue(base, keystr()); // try lookup first
|
||||
if (!ret)
|
||||
{
|
||||
// doesn't exist, must create
|
||||
ret = (*create_method)();
|
||||
CFDictionaryAddValue(base, keystr(), ret);
|
||||
CFRelease(ret); // because ret is now owned by base
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// lookup a dict in another dict (base) and return or create if absent
|
||||
template <typename KEY>
|
||||
inline MutableDict dict_get_create_dict(MutableDict& base, const KEY& key)
|
||||
{
|
||||
String keystr = string(key);
|
||||
return mutable_dict_cast(dict_get_create(base(), keystr(), mutable_dict_new));
|
||||
}
|
||||
|
||||
// lookup an array in a dict (base) and return or create if absent
|
||||
template <typename KEY>
|
||||
inline MutableArray dict_get_create_array(MutableDict& base, const KEY& key)
|
||||
{
|
||||
String keystr = string(key);
|
||||
return mutable_array_cast(dict_get_create(base(), keystr(), mutable_array_new));
|
||||
}
|
||||
|
||||
// lookup an object in a dictionary (DICT should be a Dict or a MutableDict)
|
||||
template <typename DICT, typename KEY>
|
||||
inline CFTypeRef dict_get_obj(const DICT& dict, const KEY& key)
|
||||
{
|
||||
return dict_index(dict, key);
|
||||
}
|
||||
|
||||
// lookup a string in a dictionary (DICT should be a Dict or a MutableDict)
|
||||
template <typename DICT, typename KEY>
|
||||
inline std::string dict_get_str(const DICT& dict, const KEY& key)
|
||||
{
|
||||
return cppstring(string_cast(dict_index(dict, key)));
|
||||
}
|
||||
|
||||
// lookup a string in a dictionary (DICT should be a Dict or a MutableDict)
|
||||
template <typename DICT, typename KEY>
|
||||
inline std::string dict_get_str(const DICT& dict, const KEY& key, const std::string& default_value)
|
||||
{
|
||||
String str(string_cast(dict_index(dict, key)));
|
||||
if (str.defined())
|
||||
return cppstring(str());
|
||||
else
|
||||
return default_value;
|
||||
}
|
||||
|
||||
// lookup an integer in a dictionary (DICT should be a Dict or a MutableDict)
|
||||
template <typename DICT, typename KEY>
|
||||
inline int dict_get_int(const DICT& dict, const KEY& key, const int default_value)
|
||||
{
|
||||
int ret;
|
||||
Number num = number_cast(dict_index(dict, key));
|
||||
if (num.defined() && CFNumberGetValue(num(), kCFNumberIntType, &ret))
|
||||
return ret;
|
||||
else
|
||||
return default_value;
|
||||
}
|
||||
|
||||
// lookup a boolean in a dictionary (DICT should be a Dict or a MutableDict)
|
||||
template <typename DICT, typename KEY>
|
||||
inline bool dict_get_bool(const DICT& dict, const KEY& key, const bool default_value)
|
||||
{
|
||||
Bool b = bool_cast(dict_index(dict, key));
|
||||
if (b.defined())
|
||||
{
|
||||
if (b() == kCFBooleanTrue)
|
||||
return true;
|
||||
else if (b() == kCFBooleanFalse)
|
||||
return false;
|
||||
}
|
||||
return default_value;
|
||||
}
|
||||
|
||||
// like CFDictionarySetValue, but no-op if any args are NULL
|
||||
inline void dictionarySetValue(CFMutableDictionaryRef theDict, const void *key, const void *value)
|
||||
{
|
||||
if (theDict && key && value)
|
||||
CFDictionarySetValue(theDict, key, value);
|
||||
}
|
||||
|
||||
// like CFArrayAppendValue, but no-op if any args are NULL
|
||||
inline void arrayAppendValue(CFMutableArrayRef theArray, const void *value)
|
||||
{
|
||||
if (theArray && value)
|
||||
CFArrayAppendValue(theArray, value);
|
||||
}
|
||||
|
||||
// set a CFTypeRef in a mutable dictionary
|
||||
template <typename KEY>
|
||||
inline void dict_set_obj(MutableDict& dict, const KEY& key, CFTypeRef value)
|
||||
{
|
||||
String keystr = string(key);
|
||||
dictionarySetValue(dict(), keystr(), value);
|
||||
}
|
||||
|
||||
// set a string in a mutable dictionary
|
||||
|
||||
template <typename KEY, typename VALUE>
|
||||
inline void dict_set_str(MutableDict& dict, const KEY& key, const VALUE& value)
|
||||
{
|
||||
String keystr = string(key);
|
||||
String valstr = string(value);
|
||||
dictionarySetValue(dict(), keystr(), valstr());
|
||||
}
|
||||
|
||||
// set a number in a mutable dictionary
|
||||
|
||||
template <typename KEY>
|
||||
inline void dict_set_int(MutableDict& dict, const KEY& key, int value)
|
||||
{
|
||||
String keystr = string(key);
|
||||
Number num = number_from_int(value);
|
||||
dictionarySetValue(dict(), keystr(), num());
|
||||
}
|
||||
|
||||
template <typename KEY>
|
||||
inline void dict_set_int32(MutableDict& dict, const KEY& key, SInt32 value)
|
||||
{
|
||||
String keystr = string(key);
|
||||
Number num = number_from_int32(value);
|
||||
dictionarySetValue(dict(), keystr(), num());
|
||||
}
|
||||
|
||||
template <typename KEY>
|
||||
inline void dict_set_long_long(MutableDict& dict, const KEY& key, long long value)
|
||||
{
|
||||
String keystr = string(key);
|
||||
Number num = number_from_long_long(value);
|
||||
dictionarySetValue(dict(), keystr(), num());
|
||||
}
|
||||
|
||||
template <typename KEY>
|
||||
inline void dict_set_index(MutableDict& dict, const KEY& key, CFIndex value)
|
||||
{
|
||||
String keystr = string(key);
|
||||
Number num = number_from_index(value);
|
||||
dictionarySetValue((CFMutableDictionaryRef)dict(), keystr(), num());
|
||||
}
|
||||
|
||||
// set a boolean in a mutable dictionary
|
||||
|
||||
template <typename KEY>
|
||||
inline void dict_set_bool(MutableDict& dict, const KEY& key, bool value)
|
||||
{
|
||||
String keystr = string(key);
|
||||
CFBooleanRef boolref = value ? kCFBooleanTrue : kCFBooleanFalse;
|
||||
dictionarySetValue(dict(), keystr(), boolref);
|
||||
}
|
||||
|
||||
// append string to a mutable array
|
||||
|
||||
template <typename VALUE>
|
||||
inline void array_append_str(MutableArray& array, const VALUE& value)
|
||||
{
|
||||
String valstr = string(value);
|
||||
arrayAppendValue(array(), valstr());
|
||||
}
|
||||
|
||||
// append a number to a mutable array
|
||||
|
||||
inline void array_append_int(MutableArray& array, int value)
|
||||
{
|
||||
Number num = number_from_int(value);
|
||||
arrayAppendValue(array(), num());
|
||||
}
|
||||
|
||||
inline void array_append_int32(MutableArray& array, SInt32 value)
|
||||
{
|
||||
Number num = number_from_int32(value);
|
||||
arrayAppendValue(array(), num());
|
||||
}
|
||||
|
||||
inline void array_append_long_long(MutableArray& array, long long value)
|
||||
{
|
||||
Number num = number_from_long_long(value);
|
||||
arrayAppendValue(array(), num());
|
||||
}
|
||||
|
||||
inline void array_append_index(MutableArray& array, CFIndex value)
|
||||
{
|
||||
Number num = number_from_index(value);
|
||||
arrayAppendValue(array(), num());
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,58 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef OPENVPN_APPLECRYPTO_CF_CFSEC_H
|
||||
#define OPENVPN_APPLECRYPTO_CF_CFSEC_H
|
||||
|
||||
#include <openvpn/common/platform.hpp>
|
||||
|
||||
#include <Security/SecCertificate.h>
|
||||
#include <Security/SecIdentity.h>
|
||||
#include <Security/SecPolicy.h>
|
||||
#include <Security/SecTrust.h>
|
||||
|
||||
#ifndef OPENVPN_PLATFORM_IPHONE
|
||||
#include <Security/SecKeychain.h>
|
||||
#include <Security/SecAccess.h>
|
||||
#endif
|
||||
|
||||
#include <openvpn/common/size.hpp>
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/applecrypto/cf/cf.hpp>
|
||||
|
||||
// Define C++ wrappings for Apple security-related objects.
|
||||
|
||||
namespace openvpn {
|
||||
namespace CF {
|
||||
OPENVPN_CF_WRAP(Cert, cert_cast, SecCertificateRef, SecCertificateGetTypeID)
|
||||
OPENVPN_CF_WRAP(Key, key_cast, SecKeyRef, SecKeyGetTypeID)
|
||||
OPENVPN_CF_WRAP(Identity, identity_cast, SecIdentityRef, SecIdentityGetTypeID)
|
||||
OPENVPN_CF_WRAP(Policy, policy_cast, SecPolicyRef, SecPolicyGetTypeID)
|
||||
OPENVPN_CF_WRAP(Trust, trust_cast, SecTrustRef, SecTrustGetTypeID)
|
||||
#ifndef OPENVPN_PLATFORM_IPHONE
|
||||
OPENVPN_CF_WRAP(Keychain, keychain_cast, SecKeychainRef, SecKeychainGetTypeID)
|
||||
OPENVPN_CF_WRAP(Access, access_cast, SecAccessRef, SecAccessGetTypeID)
|
||||
#endif
|
||||
} // namespace CF
|
||||
|
||||
} // namespace openvpn
|
||||
|
||||
#endif // OPENVPN_APPLECRYPTO_CF_CFSEC_H
|
||||
@@ -0,0 +1,33 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef OPENVPN_APPLECRYPTO_CF_CFTIMER_H
|
||||
#define OPENVPN_APPLECRYPTO_CF_CFTIMER_H
|
||||
|
||||
#include <openvpn/applecrypto/cf/cf.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
namespace CF {
|
||||
OPENVPN_CF_WRAP(Timer, timer_cast, CFRunLoopTimerRef, CFRunLoopTimerGetTypeID)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,67 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef OPENVPN_APPLECRYPTO_CF_ERROR_H
|
||||
#define OPENVPN_APPLECRYPTO_CF_ERROR_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <CoreFoundation/CFBase.h>
|
||||
|
||||
#include <openvpn/common/exception.hpp>
|
||||
|
||||
// An exception object that encapsulates Apple Core Foundation errors.
|
||||
|
||||
namespace openvpn {
|
||||
|
||||
// string exception class
|
||||
class CFException : public std::exception
|
||||
{
|
||||
public:
|
||||
CFException(const std::string& text)
|
||||
{
|
||||
errtxt = text;
|
||||
}
|
||||
|
||||
CFException(const std::string& text, const OSStatus status)
|
||||
{
|
||||
set_errtxt(text, status);
|
||||
}
|
||||
|
||||
virtual const char* what() const throw() { return errtxt.c_str(); }
|
||||
std::string what_str() const { return errtxt; }
|
||||
|
||||
virtual ~CFException() throw() {}
|
||||
|
||||
private:
|
||||
void set_errtxt(const std::string& text, const OSStatus status)
|
||||
{
|
||||
std::ostringstream s;
|
||||
s << text << ": OSX Error code=" << status;
|
||||
errtxt = s.str();
|
||||
}
|
||||
|
||||
std::string errtxt;
|
||||
};
|
||||
|
||||
} // namespace openvpn
|
||||
|
||||
#endif // OPENVPN_APPLECRYPTO_CF_ERROR_H
|
||||
@@ -0,0 +1,46 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef OPENVPN_APPLECRYPTO_CRYPTO_API_H
|
||||
#define OPENVPN_APPLECRYPTO_CRYPTO_API_H
|
||||
|
||||
#include <openvpn/applecrypto/crypto/cipher.hpp>
|
||||
#include <openvpn/applecrypto/crypto/ciphergcm.hpp>
|
||||
#include <openvpn/applecrypto/crypto/digest.hpp>
|
||||
#include <openvpn/applecrypto/crypto/hmac.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
|
||||
// type container for Apple Crypto-level API
|
||||
struct AppleCryptoAPI {
|
||||
// cipher
|
||||
typedef AppleCrypto::CipherContext CipherContext;
|
||||
typedef AppleCrypto::CipherContextGCM CipherContextGCM;
|
||||
|
||||
// digest
|
||||
typedef AppleCrypto::DigestContext DigestContext;
|
||||
|
||||
// HMAC
|
||||
typedef AppleCrypto::HMACContext HMACContext;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,200 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Wrap the Apple cipher API defined in <CommonCrypto/CommonCryptor.h> so
|
||||
// that it can be used as part of the crypto layer of the OpenVPN core.
|
||||
|
||||
#ifndef OPENVPN_APPLECRYPTO_CRYPTO_CIPHER_H
|
||||
#define OPENVPN_APPLECRYPTO_CRYPTO_CIPHER_H
|
||||
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
#include <CommonCrypto/CommonCryptor.h>
|
||||
|
||||
#include <openvpn/common/size.hpp>
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/common/platform.hpp>
|
||||
#include <openvpn/common/string.hpp>
|
||||
#include <openvpn/crypto/static_key.hpp>
|
||||
#include <openvpn/crypto/cryptoalgs.hpp>
|
||||
#include <openvpn/applecrypto/cf/error.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
namespace AppleCrypto {
|
||||
class CipherContext
|
||||
{
|
||||
CipherContext(const CipherContext&) = delete;
|
||||
CipherContext& operator=(const CipherContext&) = delete;
|
||||
|
||||
public:
|
||||
OPENVPN_SIMPLE_EXCEPTION(apple_cipher_mode_error);
|
||||
OPENVPN_SIMPLE_EXCEPTION(apple_cipher_uninitialized);
|
||||
OPENVPN_EXCEPTION(apple_cipher_error);
|
||||
|
||||
// mode parameter for constructor
|
||||
enum {
|
||||
MODE_UNDEF = -1,
|
||||
ENCRYPT = kCCEncrypt,
|
||||
DECRYPT = kCCDecrypt
|
||||
};
|
||||
|
||||
enum {
|
||||
MAX_IV_LENGTH = 16,
|
||||
CIPH_CBC_MODE = 0
|
||||
};
|
||||
|
||||
CipherContext()
|
||||
: cinfo(nullptr), cref(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
~CipherContext() { erase() ; }
|
||||
|
||||
void init(const CryptoAlgs::Type alg, const unsigned char *key, const int mode)
|
||||
{
|
||||
erase();
|
||||
|
||||
// check that mode is valid
|
||||
if (!(mode == ENCRYPT || mode == DECRYPT))
|
||||
throw apple_cipher_mode_error();
|
||||
|
||||
// initialize cipher context with cipher type
|
||||
const CCCryptorStatus status = CCCryptorCreate(mode,
|
||||
cipher_type(alg),
|
||||
kCCOptionPKCS7Padding,
|
||||
key,
|
||||
CryptoAlgs::key_length(alg),
|
||||
nullptr,
|
||||
&cref);
|
||||
if (status != kCCSuccess)
|
||||
throw CFException("CipherContext: CCCryptorCreate", status);
|
||||
|
||||
cinfo = CryptoAlgs::get_ptr(alg);
|
||||
}
|
||||
|
||||
void reset(const unsigned char *iv)
|
||||
{
|
||||
check_initialized();
|
||||
const CCCryptorStatus status = CCCryptorReset(cref, iv);
|
||||
if (status != kCCSuccess)
|
||||
throw CFException("CipherContext: CCCryptorReset", status);
|
||||
}
|
||||
|
||||
bool update(unsigned char *out, const size_t max_out_size,
|
||||
const unsigned char *in, const size_t in_size,
|
||||
size_t& out_acc)
|
||||
{
|
||||
check_initialized();
|
||||
size_t dataOutMoved;
|
||||
const CCCryptorStatus status = CCCryptorUpdate(cref, in, in_size, out, max_out_size, &dataOutMoved);
|
||||
if (status == kCCSuccess)
|
||||
{
|
||||
out_acc += dataOutMoved;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool final(unsigned char *out, const size_t max_out_size, size_t& out_acc)
|
||||
{
|
||||
check_initialized();
|
||||
size_t dataOutMoved;
|
||||
const CCCryptorStatus status = CCCryptorFinal(cref, out, max_out_size, &dataOutMoved);
|
||||
if (status == kCCSuccess)
|
||||
{
|
||||
out_acc += dataOutMoved;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_initialized() const { return cinfo != nullptr; }
|
||||
|
||||
size_t iv_length() const
|
||||
{
|
||||
check_initialized();
|
||||
return cinfo->iv_length();
|
||||
}
|
||||
|
||||
size_t block_size() const
|
||||
{
|
||||
check_initialized();
|
||||
return cinfo->block_size();
|
||||
}
|
||||
|
||||
// return cipher mode (such as CIPH_CBC_MODE, etc.)
|
||||
int cipher_mode() const
|
||||
{
|
||||
check_initialized();
|
||||
return CIPH_CBC_MODE;
|
||||
}
|
||||
|
||||
private:
|
||||
static CCAlgorithm cipher_type(const CryptoAlgs::Type alg)
|
||||
{
|
||||
switch (alg)
|
||||
{
|
||||
case CryptoAlgs::AES_128_CBC:
|
||||
case CryptoAlgs::AES_192_CBC:
|
||||
case CryptoAlgs::AES_256_CBC:
|
||||
return kCCAlgorithmAES128;
|
||||
case CryptoAlgs::DES_CBC:
|
||||
return kCCAlgorithmDES;
|
||||
case CryptoAlgs::DES_EDE3_CBC:
|
||||
return kCCAlgorithm3DES;
|
||||
#ifdef OPENVPN_PLATFORM_IPHONE
|
||||
case CryptoAlgs::BF_CBC:
|
||||
return kCCAlgorithmBlowfish;
|
||||
#endif
|
||||
default:
|
||||
OPENVPN_THROW(apple_cipher_error, CryptoAlgs::name(alg) << ": not usable");
|
||||
}
|
||||
}
|
||||
|
||||
void erase()
|
||||
{
|
||||
if (cinfo)
|
||||
{
|
||||
if (cref)
|
||||
CCCryptorRelease(cref);
|
||||
cref = nullptr;
|
||||
cinfo = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void check_initialized() const
|
||||
{
|
||||
#ifdef OPENVPN_ENABLE_ASSERT
|
||||
if (!cinfo)
|
||||
throw apple_cipher_uninitialized();
|
||||
#endif
|
||||
}
|
||||
|
||||
const CryptoAlgs::Alg* cinfo;
|
||||
CCCryptorRef cref;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,255 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Wrap the Apple digest API defined in <CommonCrypto/CommonDigest.h>
|
||||
// so that it can be used as part of the crypto layer of the OpenVPN core.
|
||||
|
||||
#ifndef OPENVPN_APPLECRYPTO_CRYPTO_DIGEST_H
|
||||
#define OPENVPN_APPLECRYPTO_CRYPTO_DIGEST_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <CommonCrypto/CommonDigest.h>
|
||||
#include <CommonCrypto/CommonHMAC.h>
|
||||
|
||||
#include <openvpn/common/size.hpp>
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/common/string.hpp>
|
||||
#include <openvpn/crypto/cryptoalgs.hpp>
|
||||
#include <openvpn/applecrypto/cf/error.hpp>
|
||||
|
||||
#define OPENVPN_DIGEST_CONTEXT(TYPE) CC_##TYPE##_CTX TYPE##_ctx
|
||||
|
||||
#define OPENVPN_DIGEST_ALG_CLASS(TYPE) \
|
||||
class DigestAlgorithm##TYPE : public DigestAlgorithm \
|
||||
{ \
|
||||
public: \
|
||||
DigestAlgorithm##TYPE() {} \
|
||||
virtual int init(DigestCTX& ctx) const \
|
||||
{ \
|
||||
return CC_##TYPE##_Init(&ctx.u.TYPE##_ctx); \
|
||||
} \
|
||||
virtual int update(DigestCTX& ctx, const unsigned char *data, size_t size) const \
|
||||
{ \
|
||||
return CC_##TYPE##_Update(&ctx.u.TYPE##_ctx, data, size); \
|
||||
} \
|
||||
virtual int final(DigestCTX& ctx, unsigned char *md) const \
|
||||
{ \
|
||||
return CC_##TYPE##_Final(md, &ctx.u.TYPE##_ctx); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define OPENVPN_DIGEST_ALG_DECLARE(TYPE) const DigestAlgorithm##TYPE alg_##TYPE;
|
||||
|
||||
#define OPENVPN_DIGEST_INFO_DECLARE(TYPE) const DigestInfo info_##TYPE(CryptoAlgs::TYPE, &alg_##TYPE, kCCHmacAlg##TYPE)
|
||||
|
||||
#define OPENVPN_DIGEST_INFO_DECLARE_NO_HMAC(TYPE) const DigestInfo info_##TYPE(CryptoAlgs::TYPE, &alg_##TYPE, DigestInfo::NO_HMAC_ALG)
|
||||
|
||||
namespace openvpn {
|
||||
namespace AppleCrypto {
|
||||
typedef CC_SHA256_CTX CC_SHA224_CTX;
|
||||
typedef CC_SHA512_CTX CC_SHA384_CTX;
|
||||
|
||||
struct DigestCTX {
|
||||
union {
|
||||
OPENVPN_DIGEST_CONTEXT(MD4);
|
||||
OPENVPN_DIGEST_CONTEXT(MD5);
|
||||
OPENVPN_DIGEST_CONTEXT(SHA1);
|
||||
OPENVPN_DIGEST_CONTEXT(SHA224);
|
||||
OPENVPN_DIGEST_CONTEXT(SHA256);
|
||||
OPENVPN_DIGEST_CONTEXT(SHA384);
|
||||
OPENVPN_DIGEST_CONTEXT(SHA512);
|
||||
} u;
|
||||
};
|
||||
|
||||
struct DigestAlgorithm {
|
||||
virtual int init(DigestCTX& ctx) const = 0;
|
||||
virtual int update(DigestCTX& ctx, const unsigned char *data, size_t size) const = 0;
|
||||
virtual int final(DigestCTX& ctx, unsigned char *md) const = 0;
|
||||
};
|
||||
|
||||
// individual digest algorithm classes (each inherits from DigestAlgorithm)
|
||||
OPENVPN_DIGEST_ALG_CLASS(MD4);
|
||||
OPENVPN_DIGEST_ALG_CLASS(MD5);
|
||||
OPENVPN_DIGEST_ALG_CLASS(SHA1);
|
||||
OPENVPN_DIGEST_ALG_CLASS(SHA224);
|
||||
OPENVPN_DIGEST_ALG_CLASS(SHA256);
|
||||
OPENVPN_DIGEST_ALG_CLASS(SHA384);
|
||||
OPENVPN_DIGEST_ALG_CLASS(SHA512);
|
||||
|
||||
class DigestInfo
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
NO_HMAC_ALG = -1
|
||||
};
|
||||
|
||||
DigestInfo(CryptoAlgs::Type type,
|
||||
const DigestAlgorithm* digest_alg,
|
||||
const CCHmacAlgorithm hmac_alg)
|
||||
: type_(type),
|
||||
digest_alg_(digest_alg),
|
||||
hmac_alg_(hmac_alg) {}
|
||||
|
||||
CryptoAlgs::Type type() const { return type_; }
|
||||
const char *name() const { return CryptoAlgs::name(type_); }
|
||||
size_t size() const { return CryptoAlgs::size(type_); }
|
||||
const DigestAlgorithm* digest_alg() const { return digest_alg_; }
|
||||
CCHmacAlgorithm hmac_alg() const { return hmac_alg_; }
|
||||
|
||||
private:
|
||||
CryptoAlgs::Type type_;
|
||||
const DigestAlgorithm* digest_alg_;
|
||||
CCHmacAlgorithm hmac_alg_;
|
||||
};
|
||||
|
||||
// instantiate individual digest algorithm class instances (each inherits from DigestAlgorithm),
|
||||
// naming convention is alg_TYPE
|
||||
OPENVPN_DIGEST_ALG_DECLARE(MD4);
|
||||
OPENVPN_DIGEST_ALG_DECLARE(MD5);
|
||||
OPENVPN_DIGEST_ALG_DECLARE(SHA1);
|
||||
OPENVPN_DIGEST_ALG_DECLARE(SHA224);
|
||||
OPENVPN_DIGEST_ALG_DECLARE(SHA256);
|
||||
OPENVPN_DIGEST_ALG_DECLARE(SHA384);
|
||||
OPENVPN_DIGEST_ALG_DECLARE(SHA512);
|
||||
|
||||
// instantiate individual digest info class instances (each is a DigestInfo),
|
||||
// naming convention is info_TYPE
|
||||
OPENVPN_DIGEST_INFO_DECLARE_NO_HMAC(MD4);
|
||||
OPENVPN_DIGEST_INFO_DECLARE(MD5);
|
||||
OPENVPN_DIGEST_INFO_DECLARE(SHA1);
|
||||
OPENVPN_DIGEST_INFO_DECLARE(SHA224);
|
||||
OPENVPN_DIGEST_INFO_DECLARE(SHA256);
|
||||
OPENVPN_DIGEST_INFO_DECLARE(SHA384);
|
||||
OPENVPN_DIGEST_INFO_DECLARE(SHA512);
|
||||
|
||||
class HMACContext;
|
||||
|
||||
class DigestContext
|
||||
{
|
||||
DigestContext(const DigestContext&) = delete;
|
||||
DigestContext& operator=(const DigestContext&) = delete;
|
||||
|
||||
public:
|
||||
friend class HMACContext;
|
||||
|
||||
OPENVPN_SIMPLE_EXCEPTION(apple_digest_uninitialized);
|
||||
OPENVPN_SIMPLE_EXCEPTION(apple_digest_final_overflow);
|
||||
OPENVPN_EXCEPTION(apple_digest_error);
|
||||
|
||||
enum {
|
||||
MAX_DIGEST_SIZE = CC_SHA512_DIGEST_LENGTH // largest known is SHA512
|
||||
};
|
||||
|
||||
DigestContext()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
DigestContext(const CryptoAlgs::Type alg)
|
||||
{
|
||||
init(alg);
|
||||
}
|
||||
|
||||
void init(const CryptoAlgs::Type alg)
|
||||
{
|
||||
clear();
|
||||
info = digest_type(alg);
|
||||
meth = info->digest_alg();
|
||||
if (meth->init(ctx) != 1)
|
||||
throw apple_digest_error("init");
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
void update(const unsigned char *in, const size_t size)
|
||||
{
|
||||
check_initialized();
|
||||
if (meth->update(ctx, in, size) != 1)
|
||||
throw apple_digest_error("update");
|
||||
}
|
||||
|
||||
size_t final(unsigned char *out)
|
||||
{
|
||||
check_initialized();
|
||||
if (meth->final(ctx, out) != 1)
|
||||
throw apple_digest_error("final");
|
||||
return info->size();
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
check_initialized();
|
||||
return info->size();
|
||||
}
|
||||
|
||||
bool is_initialized() const { return initialized; }
|
||||
|
||||
private:
|
||||
static const DigestInfo *digest_type(const CryptoAlgs::Type alg)
|
||||
{
|
||||
switch (alg)
|
||||
{
|
||||
case CryptoAlgs::MD4:
|
||||
return &info_MD4;
|
||||
case CryptoAlgs::MD5:
|
||||
return &info_MD5;
|
||||
case CryptoAlgs::SHA1:
|
||||
return &info_SHA1;
|
||||
case CryptoAlgs::SHA224:
|
||||
return &info_SHA224;
|
||||
case CryptoAlgs::SHA256:
|
||||
return &info_SHA256;
|
||||
case CryptoAlgs::SHA384:
|
||||
return &info_SHA384;
|
||||
case CryptoAlgs::SHA512:
|
||||
return &info_SHA512;
|
||||
default:
|
||||
OPENVPN_THROW(apple_digest_error, CryptoAlgs::name(alg) << ": not usable");
|
||||
}
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
void check_initialized() const
|
||||
{
|
||||
#ifdef OPENVPN_ENABLE_ASSERT
|
||||
if (!initialized)
|
||||
throw apple_digest_uninitialized();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool initialized;
|
||||
const DigestInfo *info;
|
||||
const DigestAlgorithm *meth;
|
||||
DigestCTX ctx;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#undef OPENVPN_DIGEST_CONTEXT
|
||||
#undef OPENVPN_DIGEST_ALG_CLASS
|
||||
#undef OPENVPN_DIGEST_ALG_DECLARE
|
||||
#undef OPENVPN_DIGEST_INFO_DECLARE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,145 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef OPENVPN_APPLECRYPTO_CRYPTO_HMAC_H
|
||||
#define OPENVPN_APPLECRYPTO_CRYPTO_HMAC_H
|
||||
|
||||
// Wrap the Apple HMAC API defined in <CommonCrypto/CommonHMAC.h> so that
|
||||
// it can be used as part of the crypto layer of the OpenVPN core.
|
||||
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
#include <CommonCrypto/CommonHMAC.h>
|
||||
|
||||
#include <openvpn/common/size.hpp>
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/applecrypto/crypto/digest.hpp>
|
||||
|
||||
namespace openvpn {
|
||||
namespace AppleCrypto {
|
||||
class HMACContext
|
||||
{
|
||||
HMACContext(const HMACContext&) = delete;
|
||||
HMACContext& operator=(const HMACContext&) = delete;
|
||||
|
||||
public:
|
||||
OPENVPN_EXCEPTION(digest_cannot_be_used_with_hmac);
|
||||
OPENVPN_SIMPLE_EXCEPTION(hmac_uninitialized);
|
||||
OPENVPN_SIMPLE_EXCEPTION(hmac_keysize_error);
|
||||
|
||||
enum {
|
||||
MAX_HMAC_SIZE = DigestContext::MAX_DIGEST_SIZE,
|
||||
MAX_HMAC_KEY_SIZE = 128,
|
||||
};
|
||||
|
||||
HMACContext()
|
||||
{
|
||||
state = PRE;
|
||||
}
|
||||
|
||||
HMACContext(const CryptoAlgs::Type digest, const unsigned char *key, const size_t key_size)
|
||||
{
|
||||
init(digest, key, key_size);
|
||||
}
|
||||
|
||||
~HMACContext()
|
||||
{
|
||||
}
|
||||
|
||||
void init(const CryptoAlgs::Type digest, const unsigned char *key, const size_t key_size)
|
||||
{
|
||||
state = PRE;
|
||||
info = DigestContext::digest_type(digest);
|
||||
digest_size_ = CryptoAlgs::size(digest);
|
||||
hmac_alg = info->hmac_alg();
|
||||
if (hmac_alg == DigestInfo::NO_HMAC_ALG)
|
||||
throw digest_cannot_be_used_with_hmac(info->name());
|
||||
if (key_size > MAX_HMAC_KEY_SIZE)
|
||||
throw hmac_keysize_error();
|
||||
std::memcpy(key_, key, key_size_ = key_size);
|
||||
state = PARTIAL;
|
||||
}
|
||||
|
||||
void reset() // Apple HMAC API is missing reset method, so we have to reinit
|
||||
{
|
||||
cond_reset(true);
|
||||
}
|
||||
|
||||
void update(const unsigned char *in, const size_t size)
|
||||
{
|
||||
cond_reset(false);
|
||||
CCHmacUpdate(&ctx, in, size);
|
||||
}
|
||||
|
||||
size_t final(unsigned char *out)
|
||||
{
|
||||
cond_reset(false);
|
||||
CCHmacFinal(&ctx, out);
|
||||
return digest_size_;
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
if (!is_initialized())
|
||||
throw hmac_uninitialized();
|
||||
return digest_size_;
|
||||
}
|
||||
|
||||
bool is_initialized() const
|
||||
{
|
||||
return state >= PARTIAL;
|
||||
}
|
||||
|
||||
private:
|
||||
void cond_reset(const bool force_init)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case PRE:
|
||||
throw hmac_uninitialized();
|
||||
case READY:
|
||||
if (!force_init)
|
||||
return;
|
||||
case PARTIAL:
|
||||
CCHmacInit(&ctx, hmac_alg, key_, key_size_);
|
||||
state = READY;
|
||||
}
|
||||
}
|
||||
|
||||
enum State {
|
||||
PRE=0,
|
||||
PARTIAL,
|
||||
READY
|
||||
};
|
||||
int state;
|
||||
|
||||
const DigestInfo *info;
|
||||
CCHmacAlgorithm hmac_alg;
|
||||
size_t key_size_;
|
||||
size_t digest_size_;
|
||||
unsigned char key_[MAX_HMAC_KEY_SIZE];
|
||||
CCHmacContext ctx;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,493 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Wrap the Apple SSL API as defined in <Security/SecureTransport.h>
|
||||
// so that it can be used as the SSL layer by the OpenVPN core.
|
||||
// NOTE: not used in production code.
|
||||
|
||||
// Note that the Apple SSL API is missing some functionality (as of
|
||||
// Mac OS X 10.8) that makes it difficult to use as a drop in replacement
|
||||
// for OpenSSL or MbedTLS. The biggest issue is that the API doesn't
|
||||
// allow an SSL context to be built out of PEM-based certificates and
|
||||
// keys. It requires an "Identity" in the Keychain that was imported
|
||||
// by the user as a PKCS#12 file.
|
||||
|
||||
#ifndef OPENVPN_APPLECRYPTO_SSL_SSLCTX_H
|
||||
#define OPENVPN_APPLECRYPTO_SSL_SSLCTX_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <Security/SecImportExport.h>
|
||||
#include <Security/SecItem.h>
|
||||
#include <Security/SecureTransport.h>
|
||||
#include <Security/SecKey.h>
|
||||
|
||||
#include <openvpn/common/size.hpp>
|
||||
#include <openvpn/common/exception.hpp>
|
||||
#include <openvpn/common/mode.hpp>
|
||||
#include <openvpn/buffer/buffer.hpp>
|
||||
#include <openvpn/frame/frame.hpp>
|
||||
#include <openvpn/frame/memq_stream.hpp>
|
||||
#include <openvpn/pki/epkibase.hpp>
|
||||
#include <openvpn/applecrypto/cf/cfsec.hpp>
|
||||
#include <openvpn/applecrypto/cf/error.hpp>
|
||||
#include <openvpn/ssl/tlsver.hpp>
|
||||
#include <openvpn/ssl/sslconsts.hpp>
|
||||
#include <openvpn/ssl/sslapi.hpp>
|
||||
|
||||
// An SSL Context is essentially a configuration that can be used
|
||||
// to generate an arbitrary number of actual SSL connections objects.
|
||||
|
||||
// AppleSSLContext is an SSL Context implementation that uses the
|
||||
// Mac/iOS SSL library as a backend.
|
||||
|
||||
namespace openvpn {
|
||||
|
||||
// Represents an SSL configuration that can be used
|
||||
// to instantiate actual SSL sessions.
|
||||
class AppleSSLContext : public SSLFactoryAPI
|
||||
{
|
||||
public:
|
||||
typedef RCPtr<AppleSSLContext> Ptr;
|
||||
|
||||
enum {
|
||||
MAX_CIPHERTEXT_IN = 64
|
||||
};
|
||||
|
||||
// The data needed to construct an AppleSSLContext.
|
||||
class Config : public SSLConfigAPI
|
||||
{
|
||||
friend class AppleSSLContext;
|
||||
|
||||
public:
|
||||
typedef RCPtr<Config> Ptr;
|
||||
|
||||
Config() {}
|
||||
|
||||
void load_identity(const std::string& subject_match)
|
||||
{
|
||||
identity = load_identity_(subject_match);
|
||||
if (!identity())
|
||||
OPENVPN_THROW(ssl_context_error, "AppleSSLContext: identity '" << subject_match << "' undefined");
|
||||
}
|
||||
|
||||
virtual SSLFactoryAPI::Ptr new_factory()
|
||||
{
|
||||
return SSLFactoryAPI::Ptr(new AppleSSLContext(this));
|
||||
}
|
||||
|
||||
virtual void set_mode(const Mode& mode_arg)
|
||||
{
|
||||
mode = mode_arg;
|
||||
}
|
||||
|
||||
virtual const Mode& get_mode() const
|
||||
{
|
||||
return mode;
|
||||
}
|
||||
|
||||
virtual void set_frame(const Frame::Ptr& frame_arg)
|
||||
{
|
||||
frame = frame_arg;
|
||||
}
|
||||
|
||||
virtual void load(const OptionList& opt, const unsigned int lflags)
|
||||
{
|
||||
// client/server
|
||||
if (lflags & LF_PARSE_MODE)
|
||||
mode = opt.exists("client") ? Mode(Mode::CLIENT) : Mode(Mode::SERVER);
|
||||
|
||||
// identity
|
||||
{
|
||||
const std::string& subject_match = opt.get("identity", 1, 256);
|
||||
load_identity(subject_match);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void set_external_pki_callback(ExternalPKIBase* external_pki_arg)
|
||||
{
|
||||
not_implemented("set_external_pki_callback");
|
||||
}
|
||||
|
||||
virtual void set_private_key_password(const std::string& pwd)
|
||||
{
|
||||
return not_implemented("set_private_key_password");
|
||||
}
|
||||
|
||||
virtual void load_ca(const std::string& ca_txt, bool strict)
|
||||
{
|
||||
return not_implemented("load_ca");
|
||||
}
|
||||
|
||||
virtual void load_crl(const std::string& crl_txt)
|
||||
{
|
||||
return not_implemented("load_crl");
|
||||
}
|
||||
|
||||
virtual void load_cert(const std::string& cert_txt)
|
||||
{
|
||||
return not_implemented("load_cert");
|
||||
}
|
||||
|
||||
virtual void load_cert(const std::string& cert_txt, const std::string& extra_certs_txt)
|
||||
{
|
||||
return not_implemented("load_cert");
|
||||
}
|
||||
|
||||
virtual void load_private_key(const std::string& key_txt)
|
||||
{
|
||||
return not_implemented("load_private_key");
|
||||
}
|
||||
|
||||
virtual void load_dh(const std::string& dh_txt)
|
||||
{
|
||||
return not_implemented("load_dh");
|
||||
}
|
||||
|
||||
virtual void set_debug_level(const int debug_level)
|
||||
{
|
||||
return not_implemented("set_debug_level");
|
||||
}
|
||||
|
||||
virtual void set_flags(const unsigned int flags_arg)
|
||||
{
|
||||
return not_implemented("set_flags");
|
||||
}
|
||||
|
||||
virtual void set_ns_cert_type(const NSCert::Type ns_cert_type_arg)
|
||||
{
|
||||
return not_implemented("set_ns_cert_type");
|
||||
}
|
||||
|
||||
virtual void set_remote_cert_tls(const KUParse::TLSWebType wt)
|
||||
{
|
||||
return not_implemented("set_remote_cert_tls");
|
||||
}
|
||||
|
||||
virtual void set_tls_remote(const std::string& tls_remote_arg)
|
||||
{
|
||||
return not_implemented("set_tls_remote");
|
||||
}
|
||||
|
||||
virtual void set_tls_version_min(const TLSVersion::Type tvm)
|
||||
{
|
||||
return not_implemented("set_tls_version_min");
|
||||
}
|
||||
|
||||
virtual void set_local_cert_enabled(const bool v)
|
||||
{
|
||||
return not_implemented("set_local_cert_enabled");
|
||||
}
|
||||
|
||||
virtual void set_enable_renegotiation(const bool v)
|
||||
{
|
||||
return not_implemented("set_enable_renegotiation");
|
||||
}
|
||||
|
||||
virtual void set_force_aes_cbc_ciphersuites(const bool v)
|
||||
{
|
||||
return not_implemented("set_force_aes_cbc_ciphersuites");
|
||||
}
|
||||
|
||||
virtual void set_rng(const RandomAPI::Ptr& rng_arg)
|
||||
{
|
||||
return not_implemented("set_rng");
|
||||
}
|
||||
|
||||
private:
|
||||
void not_implemented(const char *funcname)
|
||||
{
|
||||
OPENVPN_LOG("AppleSSL: " << funcname << " not implemented");
|
||||
}
|
||||
|
||||
Mode mode;
|
||||
CF::Array identity; // as returned by load_identity
|
||||
Frame::Ptr frame;
|
||||
};
|
||||
|
||||
// Represents an actual SSL session.
|
||||
// Normally instantiated by AppleSSLContext::ssl().
|
||||
class SSL : public SSLAPI
|
||||
{
|
||||
friend class AppleSSLContext;
|
||||
|
||||
public:
|
||||
typedef RCPtr<SSL> Ptr;
|
||||
|
||||
virtual void start_handshake()
|
||||
{
|
||||
SSLHandshake(ssl);
|
||||
}
|
||||
|
||||
virtual ssize_t write_cleartext_unbuffered(const void *data, const size_t size)
|
||||
{
|
||||
size_t actual = 0;
|
||||
const OSStatus status = SSLWrite(ssl, data, size, &actual);
|
||||
if (status < 0)
|
||||
{
|
||||
if (status == errSSLWouldBlock)
|
||||
return SSLConst::SHOULD_RETRY;
|
||||
else
|
||||
throw CFException("AppleSSLContext::SSL::write_cleartext failed", status);
|
||||
}
|
||||
else
|
||||
return actual;
|
||||
}
|
||||
|
||||
virtual ssize_t read_cleartext(void *data, const size_t capacity)
|
||||
{
|
||||
if (!overflow)
|
||||
{
|
||||
size_t actual = 0;
|
||||
const OSStatus status = SSLRead(ssl, data, capacity, &actual);
|
||||
if (status < 0)
|
||||
{
|
||||
if (status == errSSLWouldBlock)
|
||||
return SSLConst::SHOULD_RETRY;
|
||||
else
|
||||
throw CFException("AppleSSLContext::SSL::read_cleartext failed", status);
|
||||
}
|
||||
else
|
||||
return actual;
|
||||
}
|
||||
else
|
||||
throw ssl_ciphertext_in_overflow();
|
||||
}
|
||||
|
||||
virtual bool read_cleartext_ready() const
|
||||
{
|
||||
// fixme: need to detect data buffered at SSL layer
|
||||
return !ct_in.empty();
|
||||
}
|
||||
|
||||
virtual void write_ciphertext(const BufferPtr& buf)
|
||||
{
|
||||
if (ct_in.size() < MAX_CIPHERTEXT_IN)
|
||||
ct_in.write_buf(buf);
|
||||
else
|
||||
overflow = true;
|
||||
}
|
||||
|
||||
virtual bool read_ciphertext_ready() const
|
||||
{
|
||||
return !ct_out.empty();
|
||||
}
|
||||
|
||||
virtual BufferPtr read_ciphertext()
|
||||
{
|
||||
return ct_out.read_buf();
|
||||
}
|
||||
|
||||
virtual std::string ssl_handshake_details() const // fixme -- code me
|
||||
{
|
||||
return "[AppleSSL not implemented]";
|
||||
}
|
||||
|
||||
virtual const AuthCert::Ptr& auth_cert() const
|
||||
{
|
||||
OPENVPN_THROW(ssl_context_error, "AppleSSL::SSL: auth_cert() not implemented");
|
||||
}
|
||||
|
||||
~SSL()
|
||||
{
|
||||
ssl_erase();
|
||||
}
|
||||
|
||||
private:
|
||||
SSL(const AppleSSLContext& ctx)
|
||||
{
|
||||
ssl_clear();
|
||||
try {
|
||||
OSStatus s;
|
||||
|
||||
#ifdef OPENVPN_PLATFORM_IPHONE
|
||||
// init SSL object, select client or server mode
|
||||
if (ctx.mode().is_server())
|
||||
ssl = SSLCreateContext(kCFAllocatorDefault, kSSLServerSide, kSSLStreamType);
|
||||
else if (ctx.mode().is_client())
|
||||
ssl = SSLCreateContext(kCFAllocatorDefault, kSSLClientSide, kSSLStreamType);
|
||||
else
|
||||
OPENVPN_THROW(ssl_context_error, "AppleSSLContext::SSL: unknown client/server mode");
|
||||
if (ssl == nullptr)
|
||||
throw CFException("SSLCreateContext failed");
|
||||
|
||||
// use TLS v1
|
||||
s = SSLSetProtocolVersionMin(ssl, kTLSProtocol1);
|
||||
if (s)
|
||||
throw CFException("SSLSetProtocolVersionMin failed", s);
|
||||
#else
|
||||
// init SSL object, select client or server mode
|
||||
if (ctx.mode().is_server())
|
||||
s = SSLNewContext(true, &ssl);
|
||||
else if (ctx.mode().is_client())
|
||||
s = SSLNewContext(false, &ssl);
|
||||
else
|
||||
OPENVPN_THROW(ssl_context_error, "AppleSSLContext::SSL: unknown client/server mode");
|
||||
if (s)
|
||||
throw CFException("SSLNewContext failed", s);
|
||||
|
||||
// use TLS v1
|
||||
s = SSLSetProtocolVersionEnabled(ssl, kSSLProtocol2, false);
|
||||
if (s)
|
||||
throw CFException("SSLSetProtocolVersionEnabled !S2 failed", s);
|
||||
s = SSLSetProtocolVersionEnabled(ssl, kSSLProtocol3, false);
|
||||
if (s)
|
||||
throw CFException("SSLSetProtocolVersionEnabled !S3 failed", s);
|
||||
s = SSLSetProtocolVersionEnabled(ssl, kTLSProtocol1, true);
|
||||
if (s)
|
||||
throw CFException("SSLSetProtocolVersionEnabled T1 failed", s);
|
||||
#endif
|
||||
// configure cert, private key, and supporting CAs via identity wrapper
|
||||
s = SSLSetCertificate(ssl, ctx.identity()());
|
||||
if (s)
|
||||
throw CFException("SSLSetCertificate failed", s);
|
||||
|
||||
// configure ciphertext buffers
|
||||
ct_in.set_frame(ctx.frame());
|
||||
ct_out.set_frame(ctx.frame());
|
||||
|
||||
// configure the "connection" object to be self
|
||||
s = SSLSetConnection(ssl, this);
|
||||
if (s)
|
||||
throw CFException("SSLSetConnection", s);
|
||||
|
||||
// configure ciphertext read/write callbacks
|
||||
s = SSLSetIOFuncs(ssl, ct_read_func, ct_write_func);
|
||||
if (s)
|
||||
throw CFException("SSLSetIOFuncs failed", s);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
ssl_erase();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
static OSStatus ct_read_func(SSLConnectionRef cref, void *data, size_t *length)
|
||||
{
|
||||
try {
|
||||
SSL *self = (SSL *)cref;
|
||||
const size_t actual = self->ct_in.read((unsigned char *)data, *length);
|
||||
const OSStatus ret = (*length == actual) ? 0 : errSSLWouldBlock;
|
||||
*length = actual;
|
||||
return ret;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return errSSLInternal;
|
||||
}
|
||||
}
|
||||
|
||||
static OSStatus ct_write_func(SSLConnectionRef cref, const void *data, size_t *length)
|
||||
{
|
||||
try {
|
||||
SSL *self = (SSL *)cref;
|
||||
self->ct_out.write((const unsigned char *)data, *length);
|
||||
return 0;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return errSSLInternal;
|
||||
}
|
||||
}
|
||||
|
||||
void ssl_clear()
|
||||
{
|
||||
ssl = nullptr;
|
||||
overflow = false;
|
||||
}
|
||||
|
||||
void ssl_erase()
|
||||
{
|
||||
if (ssl)
|
||||
{
|
||||
#ifdef OPENVPN_PLATFORM_IPHONE
|
||||
CFRelease(ssl);
|
||||
#else
|
||||
SSLDisposeContext(ssl);
|
||||
#endif
|
||||
}
|
||||
ssl_clear();
|
||||
}
|
||||
|
||||
SSLContextRef ssl; // underlying SSL connection object
|
||||
MemQStream ct_in; // write ciphertext to here
|
||||
MemQStream ct_out; // read ciphertext from here
|
||||
bool overflow;
|
||||
};
|
||||
|
||||
/////// start of main class implementation
|
||||
|
||||
// create a new SSL instance
|
||||
virtual SSLAPI::Ptr ssl()
|
||||
{
|
||||
return SSL::Ptr(new SSL(*this));
|
||||
}
|
||||
|
||||
// like ssl() above but verify hostname against cert CommonName and/or SubjectAltName
|
||||
virtual SSLAPI::Ptr ssl(const std::string& hostname)
|
||||
{
|
||||
OPENVPN_THROW(ssl_context_error, "AppleSSLContext: ssl session with CommonName and/or SubjectAltName verification not implemented");
|
||||
}
|
||||
|
||||
virtual const Mode& mode() const
|
||||
{
|
||||
return config_->mode;
|
||||
}
|
||||
|
||||
private:
|
||||
AppleSSLContext(Config* config)
|
||||
: config_(config)
|
||||
{
|
||||
if (!config_->identity())
|
||||
OPENVPN_THROW(ssl_context_error, "AppleSSLContext: identity undefined");
|
||||
}
|
||||
|
||||
const Frame::Ptr& frame() const { return config_->frame; }
|
||||
const CF::Array& identity() const { return config_->identity; }
|
||||
|
||||
// load an identity from keychain, return as an array that can
|
||||
// be passed to SSLSetCertificate
|
||||
static CF::Array load_identity_(const std::string& subj_match)
|
||||
{
|
||||
const CF::String label = CF::string(subj_match);
|
||||
const void *keys[] = { kSecClass, kSecMatchSubjectContains, kSecMatchTrustedOnly, kSecReturnRef };
|
||||
const void *values[] = { kSecClassIdentity, label(), kCFBooleanTrue, kCFBooleanTrue };
|
||||
const CF::Dict query = CF::dict(keys, values, sizeof(keys)/sizeof(keys[0]));
|
||||
CF::Generic result;
|
||||
const OSStatus s = SecItemCopyMatching(query(), result.mod_ref());
|
||||
if (!s && result.defined())
|
||||
{
|
||||
const void *asrc[] = { result() };
|
||||
return CF::array(asrc, 1);
|
||||
}
|
||||
else
|
||||
return CF::Array(); // not found
|
||||
}
|
||||
|
||||
Config::Ptr config_;
|
||||
};
|
||||
|
||||
typedef AppleSSLContext::Ptr AppleSSLContextPtr;
|
||||
|
||||
} // namespace openvpn
|
||||
|
||||
#endif // OPENVPN_APPLECRYPTO_SSL_SSLCTX_H
|
||||
@@ -0,0 +1,74 @@
|
||||
// OpenVPN -- An application to securely tunnel IP networks
|
||||
// over a single port, with support for SSL/TLS-based
|
||||
// session authentication and key exchange,
|
||||
// packet encryption, packet authentication, and
|
||||
// packet compression.
|
||||
//
|
||||
// Copyright (C) 2012-2017 OpenVPN Technologies, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License Version 3
|
||||
// as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program in the COPYING file.
|
||||
// If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <openvpn/applecrypto/util/reach.hpp>
|
||||
#include <openvpn/netconf/enumiface.hpp>
|
||||
|
||||
#ifndef OPENVPN_APPLECRYPTO_UTIL_IOSACTIVEIFACE_H
|
||||
#define OPENVPN_APPLECRYPTO_UTIL_IOSACTIVEIFACE_H
|
||||
|
||||
namespace openvpn {
|
||||
|
||||
class iOSActiveInterface : public ReachabilityInterface
|
||||
{
|
||||
public:
|
||||
virtual Status reachable() const
|
||||
{
|
||||
if (ei.iface_up("en0"))
|
||||
return ReachableViaWiFi;
|
||||
else if (ei.iface_up("pdp_ip0"))
|
||||
return ReachableViaWWAN;
|
||||
else
|
||||
return NotReachable;
|
||||
}
|
||||
|
||||
virtual bool reachableVia(const std::string& net_type) const
|
||||
{
|
||||
const Status r = reachable();
|
||||
if (net_type == "cellular")
|
||||
return r == ReachableViaWWAN;
|
||||
else if (net_type == "wifi")
|
||||
return r == ReachableViaWiFi;
|
||||
else
|
||||
return r != NotReachable;
|
||||
}
|
||||
|
||||
virtual std::string to_string() const
|
||||
{
|
||||
switch (reachable())
|
||||
{
|
||||
case ReachableViaWiFi:
|
||||
return "ReachableViaWiFi";
|
||||
case ReachableViaWWAN:
|
||||
return "ReachableViaWWAN";
|
||||
case NotReachable:
|
||||
return "NotReachable";
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
EnumIface ei;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user