Renamed branch to reflect that it is no longer beta.

git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@7051 e7ae566f-a301-0410-adde-c780ea21d3b5
This commit is contained in:
James Yonan 2011-03-17 04:55:47 +00:00
commit d02a86d37b
355 changed files with 104511 additions and 0 deletions

20
.svnignore Normal file
View file

@ -0,0 +1,20 @@
*.o
*.obj
config.status
config.log
config.guess
aclocal.m4
install-sh
Makefile.in
openvpn
depcomp
config.h
.deps
Makefile
config.h.in
configure
config.sub
openvpn.spec
stamp-h1
autom4te.cache
missing

1
AUTHORS Normal file
View file

@ -0,0 +1 @@
James Yonan <jim@yonan.net>

217
COPYING Normal file
View file

@ -0,0 +1,217 @@
OpenVPN (TM) -- An Open Source VPN daemon
Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
This distribution contains multiple components, some
of which fall under different licenses. By using OpenVPN
or any of the bundled components enumerated below, you
agree to be bound by the conditions of the license for
each respective component.
OpenVPN trademark
-----------------
"OpenVPN" is a trademark of OpenVPN Technologies, Inc.
OpenVPN license:
----------------
OpenVPN is distributed under the GPL license version 2 (see Below).
Special exception for linking OpenVPN with OpenSSL:
In addition, as a special exception, OpenVPN Technologies, Inc. gives
permission to link the code of this program with the OpenSSL
library (or with modified versions of OpenSSL that use the same
license as OpenSSL), and distribute linked combinations including
the two. You must obey the GNU General Public License in all
respects for all of the code used other than OpenSSL. If you modify
this file, you may extend this exception to your version of the
file, but you are not obligated to do so. If you do not wish to
do so, delete this exception statement from your version.
LZO license:
------------
LZO is Copyright (C) Markus F.X.J. Oberhumer,
and is licensed under the GPL.
Special exception for linking OpenVPN with both OpenSSL and LZO:
Hereby I grant a special exception to the OpenVPN project
(http://openvpn.net/) to link the LZO library with
the OpenSSL library (http://www.openssl.org).
Markus F.X.J. Oberhumer
TAP-Win32/TAP-Win64 Driver license:
-----------------------------------
This device driver was inspired by the CIPE-Win32 driver by
Damion K. Wilson.
The source and object code of the TAP-Win32/TAP-Win64 driver
is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., and is released under
the GPL version 2.
Windows DDK Samples:
--------------------
The Windows binary distribution includes devcon.exe, a
Microsoft DDK sample which is redistributed under the terms
of the DDK EULA.
NSIS License:
-------------
Copyright (C) 2002-2003 Joost Verburg
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute
it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented;
you must not claim that you wrote the original software.
If you use this software in a product, an acknowledgment in the
product documentation would be appreciated but is not required.
2. Altered versions must be plainly marked as such,
and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any distribution.
OpenSSL License:
----------------
The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
the OpenSSL License and the original SSLeay license apply to the toolkit.
See below for the actual license texts. Actually both licenses are BSD-style
Open Source licenses. In case of any license issues related to OpenSSL
please contact openssl-core@openssl.org.
/* ====================================================================
* Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
Original SSLeay License
-----------------------
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
GNU Public License (GPL)
------------------------
OpenVPN, LZO, and the TAP-Win32 distributions are
licensed under the GPL version 2 (see COPYRIGHT.GPL).
In the Windows binary distribution of OpenVPN, the
GPL is reproduced below.

339
COPYRIGHT.GPL Normal file
View file

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) 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
this service 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 make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. 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.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
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
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the 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 a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE 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.
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
convey 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 version 2
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; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision 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, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This 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 Library General
Public License instead of this License.

3304
ChangeLog Normal file

File diff suppressed because it is too large Load diff

343
INSTALL Normal file
View file

@ -0,0 +1,343 @@
Installation instructions for OpenVPN, a Secure Tunneling Daemon
Copyright (C) 2002-2010 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 2
as published by the Free Software Foundation.
*************************************************************************
QUICK START:
Unix:
./configure && make && make-install
Windows MinGW, using MSYS bash shell:
./domake-win (see comments in the script for more info)
Windows Visual Studio:
python win\build_all.py
*************************************************************************
To download OpenVPN, go to:
http://openvpn.net/download.html
For step-by-step installation instructions with real-world
examples see:
http://openvpn.net/howto.html
For examples see:
http://openvpn.net/examples.html
*************************************************************************
SUPPORTED PLATFORMS:
(1) Linux 2.2+
(2) Solaris
(3) OpenBSD 3.0+ (Comes with OpenSSL and TUN devices by default)
(4) Mac OS X Darwin
(5) FreeBSD
(6) NetBSD
(7) Windows (Win 2K and higher)
SUPPORTED PROCESSOR ARCHITECTURES:
In general, OpenVPN is word size and endian independent, so
most processors should be supported. Architectures known to
work include Intel x86, Alpha, Sparc, Amd64, and ARM.
REQUIRES:
(1) TUN and/or TAP driver to allow user-space programs to control
a virtual point-to-point IP or Ethernet device. See
TUN/TAP Driver Configuration section below for more info.
OPTIONAL (but recommended):
(1) OpenSSL library, necessary for encryption, version 0.9.5 or higher
required, available from http://www.openssl.org/
(2) LZO real-time compression library, required for link compression,
available from http://www.oberhumer.com/opensource/lzo/
OpenBSD users can use ports or packages to install lzo, but remember
to add "--with-lzo-headers" and "--with-lzo-lib" directives to
"configure", pointing to /usr/local/include and /usr/local/lib
respectively since gcc will not find them otherwise.
(3) Pthread library.
OPTIONAL (for developers only):
(1) Autoconf 2.50 or higher + Automake 1.5 or higher
-- available from http://www.gnu.org/software/software.html
(2) Dmalloc library
-- available from http://dmalloc.com/
*************************************************************************
CHECK OUT SOURCE FROM SUBVERSION REPOSITORY:
Check out stable version:
svn checkout http://svn.openvpn.net/projects/openvpn/trunk/openvpn openvpn
Check out beta21 branch:
svn checkout http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn openvpn
*************************************************************************
BUILD COMMANDS FROM TARBALL:
./configure
make
make install
*************************************************************************
BUILD COMMANDS FROM SUBVERSION REPOSITORY CHECKOUT:
autoreconf -i -v
./configure
make
make install
*************************************************************************
BUILD A TARBALL FROM SUBVERSION REPOSITORY CHECKOUT:
autoreconf -i -v
./configure
make dist
*************************************************************************
LOOPBACK TESTS (after BUILD):
make check (Run all tests below)
Test Crypto:
./openvpn --genkey --secret key
./openvpn --test-crypto --secret key
Test SSL/TLS negotiations (runs for 2 minutes):
./openvpn --config sample-config-files/loopback-client (In one window)
./openvpn --config sample-config-files/loopback-server (Simultaneously in another window)
*************************************************************************
OPTIONS for ./configure:
--enable-pthread Compile pthread support for
improved latency during SSL/TLS key
negotiations (Linux or Solaris only)
--disable-lzo Do not compile LZO compression support
--disable-crypto Do not compile OpenSSL crypto support
--disable-ssl Do not compile OpenSSL SSL support for
TLS-based key exchange
--with-ssl-headers=DIR Crypto/SSL Include files location
--with-ssl-lib=DIR Crypto/SSL Library location
--with-lzo-headers=DIR LZO Include files location
--with-lzo-lib=DIR LZO Library location
--with-ifconfig-path=PATH Path to ifconfig tool (only need to
specify if in a non-standard location)
--with-leak-check=TYPE Build with memory leak checking
TYPE = dmalloc or ssl
--enable-strict Enable strict compiler warnings
--enable-strict-options Enable strict options check between peers
*************************************************************************
BUILDING ON LINUX 2.4+ FROM RPM
You can build a binary RPM directly from the OpenVPN tarball file:
rpmbuild -tb [tarball]
This command will build a binary RPM file and place it in the system
RPM directory. You can then install the RPM with the standard RPM
install command:
rpm -ivh [binary-rpm]
When you install the binary RPM, it will install
sample-scripts/openvpn.init, which can be used to
automatically start or stop one or more OpenVPN tunnels on system
startup or shutdown, based on OpenVPN .conf files in /etc/openvpn.
See the comments in openvpn.init for more information.
Installing the RPM will also configure the TUN/TAP device node
for linux 2.4.
Note that the current openvpn.spec file, which instructs the rpm tool
how to build a package, will build OpenVPN with all options enabled,
including OpenSSL, LZO, and pthread linkage. Therefore all of
these packages will need to be present prior to the RPM build, unless
you edit the openvpn.spec file.
*************************************************************************
TUN/TAP Driver Configuration:
* Linux 2.4 or higher (with integrated TUN/TAP driver):
(1) make device node: mknod /dev/net/tun c 10 200
(2a) add to /etc/modules.conf: alias char-major-10-200 tun
(2b) load driver: modprobe tun
(3) enable routing: echo 1 > /proc/sys/net/ipv4/ip_forward
Note that either of steps (2a) or (2b) is sufficient. While (2a)
only needs to be done once per install, (2b) needs to be done once
per reboot. If you install from RPM (see above) and use the
openvpn.init script, these steps are taken care of for you.
* Linux 2.2 or Solaris:
You should obtain
version 1.1 of the TUN/TAP driver from
http://vtun.sourceforge.net/tun/
and follow the installation instructions.
If you use OpenVPN on Linux 2.2 or 2.4 or Solaris, you may be
suffering from a bug which causes connections to hang under heavy load.
The symptoms are very similar to the MTU problems discussed frequently
in the OpenVPN mailing lists. But it turns out that this bug is not caused by
MTU problems. It's a bug in the tun/tap driver. A patch is provided here:
http://openvpn.net/patch/tun-sb.patch
* Solaris
For 64 bit, I used the tun-1.1.tar.gz source and compiled it.
Of course there is a but :)
In the tun-1-1\solaris\Makefile I changed a line so it compiles with 64 bit
CFLAGS = $(DEFS) -m64 -O2 -Wall -D_KERNEL -I.
I just added -m64 and it worked.
The tun driver works fine as said previously, however we noticed there is a
minor problem when creating multiple tunnels on Solaris.
Mr Tycho Fruru changed the code in tun.c file where he locked the tun device
number to -1. This way it is impossible to specify the name of the tun device
but it is still possible to have multiple devices.
The modification will increment automatically meaning starting from tun0 --->
tunX I know you are not responsible for the tun coding but if you think the
modification can be useful for you feel free to use it.
http://openvpn.net/solaris/tun.c
* FreeBSD 4.1.1+:
FreeBSD ships with the TUN/TAP driver, and the device nodes for tap0,
tap1, tap2, tap3, tun0, tun1, tun2 and tun3 are made by default.
However, only the TUN driver is linked into the GENERIC kernel.
To load the TAP driver, enter:
kldload if_tap
See man rc(8) to find out how you can do this at boot time.
The easiest way is to install OpenVPN from the FreeBSD ports system,
the port includes a sample script to automatically load the TAP driver
at boot-up time.
* OpenBSD:
OpenBSD ships with tun0 and tun1 installed by default on pre-3.5 systems,
while 3.5 and later have dynamically created tun* devices so you only need
to create an empty /etc/hostname.tun0 (tun1, tun2 and so on) for each tun
you plan to use to create the device(s) at boot.
* Mac OS X:
2005.02.13: Angelo Laub has developed a GUI for OS X:
http://rechenknecht.net/OpenVPN-GUI/
2004.10.26: Mattias Nissler has developed a new TUN/TAP driver for
MAC OS X:
http://www-user.rhrk.uni-kl.de/~nissler/tuntap/
Christoph Pfisterer's old TUN driver can be obtained at
http://chrisp.de/en/projects/tunnel.html -- note that it
is no longer being maintained.
* Solaris9 Sparc/64
The kernel module for solaris
can be generated by adding the -m64 switch to a modern
gcc compiler (I'm using 3.2) The resulting kernel driver
needs to be manually copied to /kernel/drv/sparcv9/ and then a
reconfiguration reboot. (boot -r).
* Windows 2000/XP/2003/Vista
See domake-win for building instructions.
See INSTALL-win32.txt for usage info.
See the man page for more information, usage examples, and
information on firewall configuration.
*************************************************************************
CAVEATS & BUGS:
* I have noticed cases where TCP sessions tunneled over the Linux
TAP driver (kernel 2.4.21 and 2.4.22) stall when lower --mssfix
values are used. The TCP sessions appear to unstall and resume
normally when the remote VPN endpoint is pinged.
* If run through a firewall using OpenBSDs packet filter PF and the
filter rules include a "scrub" directive, you may get problems talking
to Linux hosts over the tunnel, since the scrubbing will kill packets
sent from Linux hosts if they are fragmented. This is usually seen as
tunnels where small packets and pings get through but large packets
and "regular traffic" don't. To circumvent this, add "no-df" to
the scrub directive so that the packet filter will let fragments with
the "dont fragment"-flag set through anyway.
* Mixing OFB or CFB cipher modes with static key mode is not recommended,
and is flagged as an error on OpenVPN versions 1.2.1 and greater.
If you use the --cipher option to explicitly select an OFB or CFB
cipher AND you are using static key mode, it is possible that there
could be an IV collision if the OpenVPN daemons on both sides
of the connection are started at exactly the same time, since
OpenVPN uses a timestamp combined with a sequence number as the cipher
IV for OFB and CFB modes. This is not an issue if you are
using CBC cipher mode (the default), or if you are using OFB or CFB
cipher mode with SSL/TLS authentication.
******************************************************************************
Subject: [Openvpn-users] Re: Windows XP 64 bit
From: Hypherion
Date: Thu, 14 Apr 2005 07:01:17 +0000 (UTC)
Well I managed to build a Windows XP 64 bit driver myself and it's working
great, I can connect to my server again :)
I had to use the WinDDK for Windows 2003 Service Pack 1 and just built the
driver in the Windows 2003 AMD64 environment. I had to comment out the
MAPINFO:FIXUPS directive in the SOURCES file.
Then I copied and renamed (devcon.exe/tapinstall.exe) from
C:\WINDDK\3790.1830\tools\devcon\amd64.
I had to edit the file OemWin2k.inf and change the Manufactured + Product
Section to:
[Manufacturer]
%Provider% = tap0901, NTamd64
[tap0901.NTamd64]
%DeviceDescription% = tap0901.ndi, tap0901

22
INSTALL-win32.txt Normal file
View file

@ -0,0 +1,22 @@
IMPORTANT NOTE FOR VISTA USERS
Note that on Windows Vista, you will need to run the OpenVPN
GUI with administrator privileges, so that it can add routes
to the routing table that are pulled from the OpenVPN server.
You can do this by right-clicking on the OpenVPN GUI
desktop icon, and selecting "Run as administrator".
GENERAL QUICKSTART FOR WINDOWS
The OpenVPN Client requires a configuration file
and key/certificate files. You should obtain
these and save them to \Program Files\OpenVPN\config.
To start OpenVPN, first run the OpenVPN GUI by double
clicking on the desktop icon or start menu icon.
The OpenVPN GUI is a system-tray applet, so an icon for the
GUI will appear in the lower-right corner of the screen.
Right click on the system tray icon, and a menu should appear
showing the names of your OpenVPN configuration files, and
giving you the option to connect.

157
Makefile.am Normal file
View file

@ -0,0 +1,157 @@
#
# OpenVPN -- An application to securely tunnel IP networks
# over a single UDP port, with support for SSL/TLS-based
# session authentication and key exchange,
# packet encryption, packet authentication, and
# packet compression.
#
# Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2
# 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 (see the file COPYING included with this
# distribution); if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
LDADD = @LIBOBJS@
.PHONY: plugin
# This option prevents autoreconf from overriding our COPYING and
# INSTALL targets:
AUTOMAKE_OPTIONS = foreign
MAINTAINERCLEANFILES = \
config.log config.status \
$(srcdir)/Makefile.in \
$(srcdir)/config.h.in $(srcdir)/config.h.in~ $(srcdir)/configure \
$(srcdir)/install-sh $(srcdir)/ltmain.sh $(srcdir)/missing \
$(srcdir)/depcomp $(srcdir)/aclocal.m4 \
$(srcdir)/config.guess $(srcdir)/config.sub \
$(srcdir)/openvpn.spec
CLEANFILES = openvpn.8.html
EXTRA_DIST = \
easy-rsa \
sample-config-files \
sample-keys \
sample-scripts \
suse \
tap-win32 \
contrib \
debug \
plugin \
win
SUBDIRS = \
images \
service-win32 \
install-win32
TESTS = t_lpback.sh t_cltsrv.sh
sbin_PROGRAMS = openvpn
dist_noinst_HEADERS =
dist_noinst_SCRIPTS = \
$(TESTS) \
doclean \
domake-win \
t_cltsrv-down.sh
dist_noinst_DATA = \
openvpn.spec \
COPYRIGHT.GPL \
PORTS \
INSTALL-win32.txt
openvpn_SOURCES = \
base64.c base64.h \
basic.h \
buffer.c buffer.h \
circ_list.h \
clinat.c clinat.h \
common.h \
config-win32.h \
crypto.c crypto.h \
dhcp.c dhcp.h \
errlevel.h \
error.c error.h \
event.c event.h \
fdmisc.c fdmisc.h \
forward.c forward.h forward-inline.h \
fragment.c fragment.h \
gremlin.c gremlin.h \
helper.c helper.h \
httpdigest.c httpdigest.h \
lladdr.c lladdr.h \
init.c init.h \
integer.h \
interval.c interval.h \
list.c list.h \
lzo.c lzo.h \
manage.c manage.h \
mbuf.c mbuf.h \
memdbg.h \
misc.c misc.h \
mroute.c mroute.h \
mss.c mss.h \
mtcp.c mtcp.h \
mtu.c mtu.h \
mudp.c mudp.h \
multi.c multi.h \
ntlm.c ntlm.h \
occ.c occ.h occ-inline.h \
pkcs11.c pkcs11.h \
openvpn.c openvpn.h \
openvpn-plugin.h \
options.c options.h \
otime.c otime.h \
packet_id.c packet_id.h \
perf.c perf.h \
pf.c pf.h pf-inline.h \
ping.c ping.h ping-inline.h \
plugin.c plugin.h \
pool.c pool.h \
proto.c proto.h \
proxy.c proxy.h \
ieproxy.h ieproxy.c \
ps.c ps.h \
push.c push.h \
pushlist.h \
reliable.c reliable.h \
route.c route.h \
schedule.c schedule.h \
session_id.c session_id.h \
shaper.c shaper.h \
sig.c sig.h \
socket.c socket.h \
socks.c socks.h \
ssl.c ssl.h \
status.c status.h \
syshead.h \
thread.c thread.h \
tun.c tun.h \
win32.h win32.c \
cryptoapi.h cryptoapi.c
dist-hook:
cd $(distdir) && for i in $(EXTRA_DIST) $(SUBDIRS) ; do find $$i -name .svn -type d -prune -exec rm -rf '{}' ';' ; rm -f `find $$i -type f | grep -E '(^|\/)\.?\#|\~$$|\.s?o$$'` ; done
if WIN32
dist_noinst_DATA += openvpn.8
nodist_html_DATA = openvpn.8.html
openvpn.8.html: $(srcdir)/openvpn.8
$(MAN2HTML) < $(srcdir)/openvpn.8 > openvpn.8.html
else
dist_man_MANS = openvpn.8
endif

0
NEWS Normal file
View file

94
PORTS Normal file
View file

@ -0,0 +1,94 @@
OpenVPN
Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
OpenVPN has been written to try to avoid features
that are not standardized well across different
OSes, so porting OpenVPN itself will probably be
straightforward if a tun or tap driver already exists.
Where special OS features are used, they are usually
bracketed with #ifdef HAVE_SOME_FUNCTION.
PLATFORM STATUS:
* Linux 2.2+ (supported)
* Solaris (supported)
* OpenBSD 3.0 (supported but pthreads are broken)
* Max OS X Darwin
* FreeBSD
* NetBSD
* Windows
* 64 bit platforms -- I have heard reports that
OpenVPN runs on Alpha Linux and FreeBSD.
* ARM -- I have heard of at least one case
where OpenVPN was successfully built and
run on the ARM architecture.
PORTING NOTES:
* Make sure that OpenSSL will build on your
platform.
* Make sure that a tun or tap virtual device
driver exists for your platform. See
http://vtun.sourceforge.net/tun/ for examples
of tun and tap drivers that have been written
for Linux, Solaris, and FreeBSD.
* Make sure you have autoconf 2.50+ and
automake 1.6+.
* Edit configure.ac, adding platform specific
config code, and a TARGET_YOUROS define.
* Add platform-specific includes to syshead.h.
* Add an #ifdef TARGET_YOUROS to the do_ifconfig()
function in tun.c to generate a correct "ifconfig"
command for your platform. Note that OpenVPN
determines the ifconfig path at ./configure time.
* Add an ifconfig_order() variant for your OS so
openvpn knows whether to call ifconfig before
or after tun/tap dev open.
* Add an #ifdef TARGET_YOUROS block in tun.c and define
the open_tun, close_tun, read_tun, and write_tun
functions. If your tun/tap virtual device is
sufficiently generic, you may be able to use the
default case.
* Add appropriate code to route.c to handle
the route command on your platform. This
is necessary for the --route option to
work correctly.
* After you successfully build OpenVPN, run
the loopback tests as described in INSTALL.
* For the next test, confirm that the UDP socket
functionality is working independently of the
tun device, by doing something like:
./openvpn --remote localhost --verb 9 --ping 1 --dev null
* Now try with --remote [a real host]
* Now try with a real tun/tap device, you will
need to figure out the appropriate ifconfig
command to use once openvpn has opened the tun/tap
device.
* Once you have simple tests working on the tun device,
try more complex tests such as using TLS mode.
* Stress test the link by doing ping -f across it.
* Make sure that packet fragmenting is happening
correctly by doing a ping -s 2000 or higher.
* Ensure that OpenVPN on your platform will talk
to OpenVPN on other platforms such as Linux.
Some tun/tap driver implementations will prepend
unnecessary stuff onto the datagram that must be
disabled with an explicit ioctl call if cross-platform
compatibility is to be preserved. You can see some
examples of this in tun.c.
* If your system supports pthreads, try building
with ./configure --enable-pthread and do a stress
test in TLS mode.
* Try the ultimate stress test which is --gremlin
--reneg-sec 10 in TLS mode (preferably with pthreads
enabled), then do a flood ping across the tunnel
(ping -f remote-endpoint) in both directions and let
it run overnight. --gremlin will induce massive
corruption and packet loss, but you win if you
wake up the next morning and both peers are still
running and occasionally even succeeding in their
attempted once-per-10-seconds TLS handshake.
* When it's working, submit your patch to
<openvpn-devel@lists.sourceforge.net>
and rejoice :)

75
README Normal file
View file

@ -0,0 +1,75 @@
OpenVPN -- A Secure tunneling daemon
Copyright (C) 2002-2010 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 2
as published by the Free Software Foundation.
*************************************************************************
For the latest version of OpenVPN, go to:
http://openvpn.net/
To Build and Install,
./configure
make
make install
or see the file INSTALL for more info.
*************************************************************************
For detailed information on OpenVPN, including examples, see the man page
http://openvpn.net/man.html
For a sample VPN configuration, see
http://openvpn.net/howto.html
For a description of OpenVPN's underlying protocol,
see the file ssl.h included in the source distribution.
*************************************************************************
Other Files & Directories:
* INSTALL-win32.txt -- installation instructions
for Windows
* configure.ac -- script to rebuild our configure
script and makefile.
* openvpn.spec -- RPM Spec file
To build an OpenVPN binary RPM, use the command:
rpmbuild -tb [tarball]
When you install the binary RPM, it will automatically
install sample-scripts/openvpn.init (see below)
* sample-scripts/openvpn.init
A sample init script for OpenVPN. See the file for
comments and additional information.
* sample-scripts/verify-cn
A sample perl script which can be used with OpenVPN's
--tls-verify option to provide a customized authentication
test on embedded X509 certificate fields.
* sample-keys/
Sample RSA keys and certificates. DON'T USE THESE FILES
FOR ANYTHING OTHER THAN TESTING BECAUSE THEY ARE TOTALLY INSECURE.
* sample-config-files/
A collection of OpenVPN config files and scripts from
the HOWTO at http://openvpn.net/howto.html
* easy-rsa/
A simple guide to RSA key management, scripts included.
Also see http://openvpn.net/easyrsa.html

355
acinclude.m4 Normal file
View file

@ -0,0 +1,355 @@
dnl Special Autoconf Macros for OpenVPN
dnl OPENVPN_ADD_LIBS(LIB)
AC_DEFUN([OPENVPN_ADD_LIBS], [
LIBS="$1 $LIBS"
])
dnl @synopsis AX_EMPTY_ARRAY
dnl
dnl Define EMPTY_ARRAY_SIZE to be either "0"
dnl or "" depending on which syntax the compiler
dnl prefers for empty arrays in structs.
dnl
dnl @version
dnl @author James Yonan <jim@yonan.net>
AC_DEFUN([AX_EMPTY_ARRAY], [
AC_MSG_RESULT([checking for C compiler empty array support])
AC_COMPILE_IFELSE(
[
struct { int foo; int bar[[0]]; } mystruct;
], [
AC_DEFINE_UNQUOTED(EMPTY_ARRAY_SIZE, 0, [Dimension to use for empty array declaration])
], [
AC_COMPILE_IFELSE(
[
struct { int foo; int bar[[]]; } mystruct;
], [
AC_DEFINE_UNQUOTED(EMPTY_ARRAY_SIZE,, [Dimension to use for empty array declaration])
], [
AC_MSG_ERROR([C compiler is unable to creaty empty arrays])
])
])
]
)
dnl @synopsis AX_CPP_VARARG_MACRO_GCC
dnl
dnl Test if the preprocessor understands GNU GCC-style vararg macros.
dnl If it does, defines HAVE_CPP_VARARG_MACRO_GCC to 1.
dnl
dnl @version
dnl @author James Yonan <jim@yonan.net>, Matthias Andree <matthias.andree@web.de>
AC_DEFUN([AX_CPP_VARARG_MACRO_GCC], [dnl
AS_VAR_PUSHDEF([VAR],[ax_cv_cpp_vararg_macro_gcc])dnl
AC_CACHE_CHECK([for GNU GCC vararg macro support], VAR, [dnl
AC_COMPILE_IFELSE([
#define macro(a, b...) func(a, b)
int func(int a, int b, int c);
int test() { return macro(1, 2, 3); }
], [ VAR=yes ], [VAR=no])])
if test $VAR = yes ; then
AC_DEFINE([HAVE_CPP_VARARG_MACRO_GCC], 1,
[Define to 1 if your compiler supports GNU GCC-style variadic macros])
fi
AS_VAR_POPDEF([VAR])dnl
])
dnl @synopsis AX_CPP_VARARG_MACRO_ISO
dnl
dnl Test if the preprocessor understands ISO C 1999 vararg macros.
dnl If it does, defines HAVE_CPP_VARARG_MACRO_ISO to 1.
dnl
dnl @version
dnl @author James Yonan <jim@yonan.net>, Matthias Andree <matthias.andree@web.de>
AC_DEFUN([AX_CPP_VARARG_MACRO_ISO], [dnl
AS_VAR_PUSHDEF([VAR],[ax_cv_cpp_vararg_macro_iso])dnl
AC_CACHE_CHECK([for ISO C 1999 vararg macro support], VAR, [dnl
AC_COMPILE_IFELSE([
#define macro(a, ...) func(a, __VA_ARGS__)
int func(int a, int b, int c);
int test() { return macro(1, 2, 3); }
], [ VAR=yes ], [VAR=no])])
if test $VAR = yes ; then
AC_DEFINE([HAVE_CPP_VARARG_MACRO_ISO], 1,
[Define to 1 if your compiler supports ISO C99 variadic macros])
fi
AS_VAR_POPDEF([VAR])dnl
])
dnl -- The following is taken from curl's acinclude.m4 --
dnl Check for socklen_t: historically on BSD it is an int, and in
dnl POSIX 1g it is a type of its own, but some platforms use different
dnl types for the argument to getsockopt, getpeername, etc. So we
dnl have to test to find something that will work.
AC_DEFUN([TYPE_SOCKLEN_T],
[
AC_CHECK_TYPE([socklen_t], ,[
AC_MSG_CHECKING([for socklen_t equivalent])
AC_CACHE_VAL([curl_cv_socklen_t_equiv],
[
# Systems have either "struct sockaddr *" or
# "void *" as the second argument to getpeername
curl_cv_socklen_t_equiv=
for arg2 in "struct sockaddr" void; do
for t in int size_t unsigned long "unsigned long"; do
AC_TRY_COMPILE([
#ifdef _WIN32
#include <windows.h>
#define PREFIX1 WINSOCK_API_LINKAGE
#define PREFIX2 PASCAL
#else
#include <sys/types.h>
#include <sys/socket.h>
#define PREFIX1
#define PREFIX2
#define SOCKET int
#endif
PREFIX1 int PREFIX2 getpeername (SOCKET, $arg2 *, $t *);
],[
$t len;
getpeername(0,0,&len);
],[
curl_cv_socklen_t_equiv="$t"
break
])
done
done
if test "x$curl_cv_socklen_t_equiv" = x; then
AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
fi
])
AC_MSG_RESULT($curl_cv_socklen_t_equiv)
AC_DEFINE_UNQUOTED(socklen_t, $curl_cv_socklen_t_equiv,
[type to use in place of socklen_t if not defined])],
[#include <sys/types.h>
#include <sys/socket.h>])
])
dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
dnl
dnl This macro figures out how to build C programs using POSIX
dnl threads. It sets the PTHREAD_LIBS output variable to the threads
dnl library and linker flags, and the PTHREAD_CFLAGS output variable
dnl to any special C compiler flags that are needed. (The user can also
dnl force certain compiler flags/libs to be tested by setting these
dnl environment variables.)
dnl
dnl Also sets PTHREAD_CC to any special C compiler that is needed for
dnl multi-threaded programs (defaults to the value of CC otherwise).
dnl (This is necessary on AIX to use the special cc_r compiler alias.)
dnl
dnl If you are only building threads programs, you may wish to
dnl use these variables in your default LIBS, CFLAGS, and CC:
dnl
dnl LIBS="$PTHREAD_LIBS $LIBS"
dnl CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
dnl CC="$PTHREAD_CC"
dnl
dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute
dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE
dnl to that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
dnl
dnl ACTION-IF-FOUND is a list of shell commands to run if a threads
dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands
dnl to run it if it is not found. If ACTION-IF-FOUND is not specified,
dnl the default action will define HAVE_PTHREAD.
dnl
dnl Please let the authors know if this macro fails on any platform,
dnl or if you have any other suggestions or comments. This macro was
dnl based on work by SGJ on autoconf scripts for FFTW (www.fftw.org)
dnl (with help from M. Frigo), as well as ac_pthread and hb_pthread
dnl macros posted by AFC to the autoconf macro repository. We are also
dnl grateful for the helpful feedback of numerous users.
dnl
dnl @author Steven G. Johnson <stevenj@alum.mit.edu> and Alejandro Forero Cuervo <bachue@bachue.com>
AC_DEFUN([ACX_PTHREAD], [
AC_REQUIRE([AC_CANONICAL_HOST])
acx_pthread_ok=no
# We used to check for pthread.h first, but this fails if pthread.h
# requires special compiler flags (e.g. on True64 or Sequent).
# It gets checked for in the link test anyway.
# First of all, check if the user has set any of the PTHREAD_LIBS,
# etcetera environment variables, and if threads linking works using
# them:
if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
AC_MSG_RESULT($acx_pthread_ok)
if test x"$acx_pthread_ok" = xno; then
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
fi
# We must check for the threads library under a number of different
# names; the ordering is very important because some systems
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
# libraries is broken (non-POSIX).
# Create a list of thread flags to try. Items starting with a "-" are
# C compiler flags, and other items are library names, except for "none"
# which indicates that we try without any flags at all.
acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt"
# The ordering *is* (sometimes) important. Some notes on the
# individual items follow:
# pthreads: AIX (must check this before -lpthread)
# none: in case threads are in libc; should be tried before -Kthread and
# other compiler flags to prevent continual compiler warnings
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
# -pthreads: Solaris/gcc
# -mthreads: Mingw32/gcc, Lynx/gcc
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
# doesn't hurt to check since this sometimes defines pthreads too;
# also defines -D_REENTRANT)
# pthread: Linux, etcetera
# --thread-safe: KAI C++
case "$target" in
*solaris*)
# On Solaris (at least, for some versions), libc contains stubbed
# (non-functional) versions of the pthreads routines, so link-based
# tests will erroneously succeed. (We need to link with -pthread or
# -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
# a function called by this macro, so we could check for that, but
# who knows whether they'll stub that too in a future libc.) So,
# we'll just look for -pthreads and -lpthread first:
acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags"
;;
esac
if test x"$acx_pthread_ok" = xno; then
for flag in $acx_pthread_flags; do
case $flag in
none)
AC_MSG_CHECKING([whether pthreads work without any flags])
;;
-*)
AC_MSG_CHECKING([whether pthreads work with $flag])
PTHREAD_CFLAGS="$flag"
;;
*)
AC_MSG_CHECKING([for the pthreads library -l$flag])
PTHREAD_LIBS="-l$flag"
;;
esac
save_LIBS="$LIBS"
save_CFLAGS="$CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Check for various functions. We must include pthread.h,
# since some functions may be macros. (On the Sequent, we
# need a special flag -Kthread to make this header compile.)
# We check for pthread_join because it is in -lpthread on IRIX
# while pthread_create is in libc. We check for pthread_attr_init
# due to DEC craziness with -lpthreads. We check for
# pthread_cleanup_push because it is one of the few pthread
# functions on Solaris that doesn't have a non-functional libc stub.
# We try pthread_create on general principles.
AC_TRY_LINK([#include <pthread.h>],
[pthread_t th; pthread_join(th, 0);
pthread_attr_init(0); pthread_cleanup_push(0, 0);
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
[acx_pthread_ok=yes])
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
AC_MSG_RESULT($acx_pthread_ok)
if test "x$acx_pthread_ok" = xyes; then
break;
fi
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
done
fi
# Various other checks:
if test "x$acx_pthread_ok" = xyes; then
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Detect AIX lossage: threads are created detached by default
# and the JOINABLE attribute has a nonstandard name (UNDETACHED).
AC_MSG_CHECKING([for joinable pthread attribute])
AC_TRY_LINK([#include <pthread.h>],
[int attr=PTHREAD_CREATE_JOINABLE;],
ok=PTHREAD_CREATE_JOINABLE, ok=unknown)
if test x"$ok" = xunknown; then
AC_TRY_LINK([#include <pthread.h>],
[int attr=PTHREAD_CREATE_UNDETACHED;],
ok=PTHREAD_CREATE_UNDETACHED, ok=unknown)
fi
if test x"$ok" != xPTHREAD_CREATE_JOINABLE; then
AC_DEFINE(PTHREAD_CREATE_JOINABLE, $ok,
[Define to the necessary symbol if this constant
uses a non-standard name on your system.])
fi
AC_MSG_RESULT(${ok})
if test x"$ok" = xunknown; then
AC_MSG_WARN([we do not know how to create joinable pthreads])
fi
AC_MSG_CHECKING([if more special flags are required for pthreads])
flag=no
case "$target" in
*-aix* | *-freebsd*) flag="-D_THREAD_SAFE";;
*solaris* | alpha*-osf* | *linux*) flag="-D_REENTRANT";;
esac
AC_MSG_RESULT(${flag})
if test "x$flag" != xno; then
PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
# More AIX lossage: must compile with cc_r
AC_CHECK_PROG(PTHREAD_CC, cc_r, cc_r, ${CC})
else
PTHREAD_CC="$CC"
fi
AC_SUBST(PTHREAD_LIBS)
AC_SUBST(PTHREAD_CFLAGS)
AC_SUBST(PTHREAD_CC)
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test x"$acx_pthread_ok" = xyes; then
ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
:
else
acx_pthread_ok=no
$2
fi
])dnl ACX_PTHREAD

155
base64.c Normal file
View file

@ -0,0 +1,155 @@
/*
* Copyright (c) 1995-2001 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "syshead.h"
#if defined(ENABLE_HTTP_PROXY) || defined(ENABLE_PKCS11) || defined(ENABLE_CLIENT_CR) || defined(MANAGMENT_EXTERNAL_KEY)
#include "base64.h"
#include "memdbg.h"
static char base64_chars[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int
base64_encode(const void *data, int size, char **str)
{
char *s, *p;
int i;
int c;
const unsigned char *q;
if (size < 0)
return -1;
p = s = (char *) malloc(size * 4 / 3 + 4);
if (p == NULL)
return -1;
q = (const unsigned char *) data;
i = 0;
for (i = 0; i < size;) {
c = q[i++];
c *= 256;
if (i < size)
c += q[i];
i++;
c *= 256;
if (i < size)
c += q[i];
i++;
p[0] = base64_chars[(c & 0x00fc0000) >> 18];
p[1] = base64_chars[(c & 0x0003f000) >> 12];
p[2] = base64_chars[(c & 0x00000fc0) >> 6];
p[3] = base64_chars[(c & 0x0000003f) >> 0];
if (i > size)
p[3] = '=';
if (i > size + 1)
p[2] = '=';
p += 4;
}
*p = 0;
*str = s;
return strlen(s);
}
static int
pos(char c)
{
char *p;
for (p = base64_chars; *p; p++)
if (*p == c)
return p - base64_chars;
return -1;
}
#define DECODE_ERROR 0xffffffff
static unsigned int
token_decode(const char *token)
{
int i;
unsigned int val = 0;
int marker = 0;
if (strlen(token) < 4)
return DECODE_ERROR;
for (i = 0; i < 4; i++) {
val *= 64;
if (token[i] == '=')
marker++;
else if (marker > 0)
return DECODE_ERROR;
else
val += pos(token[i]);
}
if (marker > 2)
return DECODE_ERROR;
return (marker << 24) | val;
}
int
base64_decode(const char *str, void *data, int size)
{
const char *p;
unsigned char *q;
unsigned char *e = NULL;
q = data;
if (size >= 0)
e = q + size;
for (p = str; *p && (*p == '=' || strchr(base64_chars, *p)); p += 4) {
unsigned int val = token_decode(p);
unsigned int marker = (val >> 24) & 0xff;
if (val == DECODE_ERROR)
return -1;
if (e && q >= e)
return -1;
*q++ = (val >> 16) & 0xff;
if (marker < 2)
{
if (e && q >= e)
return -1;
*q++ = (val >> 8) & 0xff;
}
if (marker < 1)
{
if (e && q >= e)
return -1;
*q++ = val & 0xff;
}
}
return q - (unsigned char *) data;
}
#else
static void dummy(void) {}
#endif /* ENABLE_HTTP_PROXY, ENABLE_PKCS11, ENABLE_CLIENT_CR */

44
base64.h Normal file
View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _BASE64_H_
#define _BASE64_H_
#if defined(ENABLE_HTTP_PROXY) || defined(ENABLE_PKCS11) || defined(ENABLE_CLIENT_CR) || defined(MANAGMENT_EXTERNAL_KEY)
int base64_encode(const void *data, int size, char **str);
int base64_decode(const char *str, void *data, int size);
#endif
#endif

49
basic.h Normal file
View file

@ -0,0 +1,49 @@
/*
* OpenVPN -- An application to securely tunnel IP networks
* over a single UDP port, with support for SSL/TLS-based
* session authentication and key exchange,
* packet encryption, packet authentication, and
* packet compression.
*
* Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* 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 (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef BASIC_H
#define BASIC_H
/* bool definitions */
#ifndef bool
#define bool int
#endif
#ifndef true
#define true 1
#endif
#ifndef false
#define false 0
#endif
#define BOOL_CAST(x) ((x) ? (true) : (false))
/* size of an array */
#define SIZE(x) (sizeof(x)/sizeof(x[0]))
/* clear an object */
#define CLEAR(x) memset(&(x), 0, sizeof(x))
#endif

1062
buffer.c Normal file

File diff suppressed because it is too large Load diff

865
buffer.h Normal file
View file

@ -0,0 +1,865 @@
/*
* OpenVPN -- An application to securely tunnel IP networks
* over a single UDP port, with support for SSL/TLS-based
* session authentication and key exchange,
* packet encryption, packet authentication, and
* packet compression.
*
* Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* 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 (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef BUFFER_H
#define BUFFER_H
#include "basic.h"
#include "thread.h"
#define BUF_SIZE_MAX 1000000
/*
* Define verify_align function, otherwise
* it will be a noop.
*/
/* #define VERIFY_ALIGNMENT */
/*
* Keep track of source file/line of buf_init calls
*/
#ifdef VERIFY_ALIGNMENT
#define BUF_INIT_TRACKING
#endif
/* basic buffer class for OpenVPN */
struct buffer
{
int capacity; /* size of buffer allocated by malloc */
int offset; /* data starts at data + offset, offset > 0 to allow for efficient prepending */
int len; /* length of data that starts at data + offset */
uint8_t *data;
#ifdef BUF_INIT_TRACKING
const char *debug_file;
int debug_line;
#endif
};
/* for garbage collection */
struct gc_entry
{
struct gc_entry *next;
};
struct gc_arena
{
struct gc_entry *list;
};
#define BPTR(buf) (buf_bptr(buf))
#define BEND(buf) (buf_bend(buf))
#define BLAST(buf) (buf_blast(buf))
#define BLEN(buf) (buf_len(buf))
#define BDEF(buf) (buf_defined(buf))
#define BSTR(buf) (buf_str(buf))
#define BCAP(buf) (buf_forward_capacity (buf))
void buf_clear (struct buffer *buf);
struct buffer clear_buf (void);
void free_buf (struct buffer *buf);
bool buf_assign (struct buffer *dest, const struct buffer *src);
void string_clear (char *str);
int string_array_len (const char **array);
size_t array_mult_safe (const size_t m1, const size_t m2, const size_t extra);
#define PA_BRACKET (1<<0)
char *print_argv (const char **p, struct gc_arena *gc, const unsigned int flags);
void buf_size_error (const size_t size);
/* for dmalloc debugging */
#ifdef DMALLOC
#define alloc_buf(size) alloc_buf_debug (size, __FILE__, __LINE__)
#define alloc_buf_gc(size, gc) alloc_buf_gc_debug (size, gc, __FILE__, __LINE__);
#define clone_buf(buf) clone_buf_debug (buf, __FILE__, __LINE__);
#define gc_malloc(size, clear, arena) gc_malloc_debug (size, clear, arena, __FILE__, __LINE__)
#define string_alloc(str, gc) string_alloc_debug (str, gc, __FILE__, __LINE__)
#define string_alloc_buf(str, gc) string_alloc_buf_debug (str, gc, __FILE__, __LINE__)
struct buffer alloc_buf_debug (size_t size, const char *file, int line);
struct buffer alloc_buf_gc_debug (size_t size, struct gc_arena *gc, const char *file, int line);
struct buffer clone_buf_debug (const struct buffer* buf, const char *file, int line);
void *gc_malloc_debug (size_t size, bool clear, struct gc_arena *a, const char *file, int line);
char *string_alloc_debug (const char *str, struct gc_arena *gc, const char *file, int line);
struct buffer string_alloc_buf_debug (const char *str, struct gc_arena *gc, const char *file, int line);
#else
struct buffer alloc_buf (size_t size);
struct buffer alloc_buf_gc (size_t size, struct gc_arena *gc); /* allocate buffer with garbage collection */
struct buffer clone_buf (const struct buffer* buf);
void *gc_malloc (size_t size, bool clear, struct gc_arena *a);
char *string_alloc (const char *str, struct gc_arena *gc);
struct buffer string_alloc_buf (const char *str, struct gc_arena *gc);
#endif
#ifdef BUF_INIT_TRACKING
#define buf_init(buf, offset) buf_init_debug (buf, offset, __FILE__, __LINE__)
bool buf_init_debug (struct buffer *buf, int offset, const char *file, int line);
#else
#define buf_init(buf, offset) buf_init_dowork (buf, offset)
#endif
/* inline functions */
static inline bool
buf_defined (const struct buffer *buf)
{
return buf->data != NULL;
}
static inline bool
buf_valid (const struct buffer *buf)
{
return likely (buf->data != NULL) && likely (buf->len >= 0);
}
static inline uint8_t *
buf_bptr (const struct buffer *buf)
{
if (buf_valid (buf))
return buf->data + buf->offset;
else
return NULL;
}
static int
buf_len (const struct buffer *buf)
{
if (buf_valid (buf))
return buf->len;
else
return 0;
}
static inline uint8_t *
buf_bend (const struct buffer *buf)
{
return buf_bptr (buf) + buf_len (buf);
}
static inline uint8_t *
buf_blast (const struct buffer *buf)
{
if (buf_len (buf) > 0)
return buf_bptr (buf) + buf_len (buf) - 1;
else
return NULL;
}
static inline bool
buf_size_valid (const size_t size)
{
return likely (size < BUF_SIZE_MAX);
}
static inline bool
buf_size_valid_signed (const int size)
{
return likely (size >= -BUF_SIZE_MAX) && likely (size < BUF_SIZE_MAX);
}
static inline char *
buf_str (const struct buffer *buf)
{
return (char *)buf_bptr(buf);
}
static inline void
buf_reset (struct buffer *buf)
{
buf->capacity = 0;
buf->offset = 0;
buf->len = 0;
buf->data = NULL;
}
static inline void
buf_reset_len (struct buffer *buf)
{
buf->len = 0;
buf->offset = 0;
}
static inline bool
buf_init_dowork (struct buffer *buf, int offset)
{
if (offset < 0 || offset > buf->capacity || buf->data == NULL)
return false;
buf->len = 0;
buf->offset = offset;
return true;
}
static inline void
buf_set_write (struct buffer *buf, uint8_t *data, int size)
{
if (!buf_size_valid (size))
buf_size_error (size);
buf->len = 0;
buf->offset = 0;
buf->capacity = size;
buf->data = data;
if (size > 0 && data)
*data = 0;
}
static inline void
buf_set_read (struct buffer *buf, const uint8_t *data, int size)
{
if (!buf_size_valid (size))
buf_size_error (size);
buf->len = buf->capacity = size;
buf->offset = 0;
buf->data = (uint8_t *)data;
}
/* Like strncpy but makes sure dest is always null terminated */
static inline void
strncpynt (char *dest, const char *src, size_t maxlen)
{
strncpy (dest, src, maxlen);
if (maxlen > 0)
dest[maxlen - 1] = 0;
}
/* return true if string contains at least one numerical digit */
static inline bool
has_digit (const unsigned char* src)
{
unsigned char c;
while ((c = *src++))
{
if (isdigit(c))
return true;
}
return false;
}
/*
* printf append to a buffer with overflow check
*/
bool buf_printf (struct buffer *buf, const char *format, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 2, 3)))
#endif
;
/*
* Like snprintf but guarantees null termination for size > 0
*/
int openvpn_snprintf(char *str, size_t size, const char *format, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 3, 4)))
#endif
;
/*
* remove/add trailing characters
*/
void buf_null_terminate (struct buffer *buf);
void buf_chomp (struct buffer *buf);
void buf_rmtail (struct buffer *buf, uint8_t remove);
/*
* non-buffer string functions
*/
void chomp (char *str);
void rm_trailing_chars (char *str, const char *what_to_delete);
const char *skip_leading_whitespace (const char *str);
void string_null_terminate (char *str, int len, int capacity);
/*
* Write string in buf to file descriptor fd.
* NOTE: requires that string be null terminated.
*/
void buf_write_string_file (const struct buffer *buf, const char *filename, int fd);
/*
* write a string to the end of a buffer that was
* truncated by buf_printf
*/
void buf_catrunc (struct buffer *buf, const char *str);
/*
* convert a multi-line output to one line
*/
void convert_to_one_line (struct buffer *buf);
/*
* Parse a string based on a given delimiter char
*/
bool buf_parse (struct buffer *buf, const int delim, char *line, const int size);
/*
* Hex dump -- Output a binary buffer to a hex string and return it.
*/
char *
format_hex_ex (const uint8_t *data, int size, int maxoutput,
int space_break, const char* separator,
struct gc_arena *gc);
static inline char *
format_hex (const uint8_t *data, int size, int maxoutput, struct gc_arena *gc)
{
return format_hex_ex (data, size, maxoutput, 4, " ", gc);
}
/*
* Return a buffer that is a subset of another buffer.
*/
struct buffer buf_sub (struct buffer *buf, int size, bool prepend);
/*
* Check if sufficient space to append to buffer.
*/
static inline bool
buf_safe (const struct buffer *buf, int len)
{
return buf_valid (buf) && buf_size_valid (len)
&& buf->offset + buf->len + len <= buf->capacity;
}
static inline bool
buf_safe_bidir (const struct buffer *buf, int len)
{
if (buf_valid (buf) && buf_size_valid_signed (len))
{
const int newlen = buf->len + len;
return newlen >= 0 && buf->offset + newlen <= buf->capacity;
}
else
return false;
}
static inline int
buf_forward_capacity (const struct buffer *buf)
{
if (buf_valid (buf))
{
int ret = buf->capacity - (buf->offset + buf->len);
if (ret < 0)
ret = 0;
return ret;
}
else
return 0;
}
static inline int
buf_forward_capacity_total (const struct buffer *buf)
{
if (buf_valid (buf))
{
int ret = buf->capacity - buf->offset;
if (ret < 0)
ret = 0;
return ret;
}
else
return 0;
}
static inline int
buf_reverse_capacity (const struct buffer *buf)
{
if (buf_valid (buf))
return buf->offset;
else
return 0;
}
static inline bool
buf_inc_len (struct buffer *buf, int inc)
{
if (!buf_safe_bidir (buf, inc))
return false;
buf->len += inc;
return true;
}
/*
* Make space to prepend to a buffer.
* Return NULL if no space.
*/
static inline uint8_t *
buf_prepend (struct buffer *buf, int size)
{
if (!buf_valid (buf) || size < 0 || size > buf->offset)
return NULL;
buf->offset -= size;
buf->len += size;
return BPTR (buf);
}
static inline bool
buf_advance (struct buffer *buf, int size)
{
if (!buf_valid (buf) || size < 0 || buf->len < size)
return false;
buf->offset += size;
buf->len -= size;
return true;
}
/*
* Return a pointer to allocated space inside a buffer.
* Return NULL if no space.
*/
static inline uint8_t *
buf_write_alloc (struct buffer *buf, int size)
{
uint8_t *ret;
if (!buf_safe (buf, size))
return NULL;
ret = BPTR (buf) + buf->len;
buf->len += size;
return ret;
}
static inline uint8_t *
buf_write_alloc_prepend (struct buffer *buf, int size, bool prepend)
{
return prepend ? buf_prepend (buf, size) : buf_write_alloc (buf, size);
}
static inline uint8_t *
buf_read_alloc (struct buffer *buf, int size)
{
uint8_t *ret;
if (size < 0 || buf->len < size)
return NULL;
ret = BPTR (buf);
buf->offset += size;
buf->len -= size;
return ret;
}
static inline bool
buf_write (struct buffer *dest, const void *src, int size)
{
uint8_t *cp = buf_write_alloc (dest, size);
if (!cp)
return false;
memcpy (cp, src, size);
return true;
}
static inline bool
buf_write_prepend (struct buffer *dest, const void *src, int size)
{
uint8_t *cp = buf_prepend (dest, size);
if (!cp)
return false;
memcpy (cp, src, size);
return true;
}
static inline bool
buf_write_u8 (struct buffer *dest, int data)
{
uint8_t u8 = (uint8_t) data;
return buf_write (dest, &u8, sizeof (uint8_t));
}
static inline bool
buf_write_u16 (struct buffer *dest, int data)
{
uint16_t u16 = htons ((uint16_t) data);
return buf_write (dest, &u16, sizeof (uint16_t));
}
static inline bool
buf_write_u32 (struct buffer *dest, int data)
{
uint32_t u32 = htonl ((uint32_t) data);
return buf_write (dest, &u32, sizeof (uint32_t));
}
static inline bool
buf_copy (struct buffer *dest, const struct buffer *src)
{
return buf_write (dest, BPTR (src), BLEN (src));
}
static inline bool
buf_copy_n (struct buffer *dest, struct buffer *src, int n)
{
uint8_t *cp = buf_read_alloc (src, n);
if (!cp)
return false;
return buf_write (dest, cp, n);
}
static inline bool
buf_copy_range (struct buffer *dest,
int dest_index,
const struct buffer *src,
int src_index,
int src_len)
{
if (src_index < 0
|| src_len < 0
|| src_index + src_len > src->len
|| dest_index < 0
|| dest->offset + dest_index + src_len > dest->capacity)
return false;
memcpy (dest->data + dest->offset + dest_index, src->data + src->offset + src_index, src_len);
if (dest_index + src_len > dest->len)
dest->len = dest_index + src_len;
return true;
}
/* truncate src to len, copy excess data beyond len to dest */
static inline bool
buf_copy_excess (struct buffer *dest,
struct buffer *src,
int len)
{
if (len < 0)
return false;
if (src->len > len)
{
struct buffer b = *src;
src->len = len;
if (!buf_advance (&b, len))
return false;
return buf_copy (dest, &b);
}
else
{
return true;
}
}
static inline bool
buf_read (struct buffer *src, void *dest, int size)
{
uint8_t *cp = buf_read_alloc (src, size);
if (!cp)
return false;
memcpy (dest, cp, size);
return true;
}
static inline int
buf_read_u8 (struct buffer *buf)
{
int ret;
if (BLEN (buf) < 1)
return -1;
ret = *BPTR(buf);
buf_advance (buf, 1);
return ret;
}
static inline int
buf_read_u16 (struct buffer *buf)
{
uint16_t ret;
if (!buf_read (buf, &ret, sizeof (uint16_t)))
return -1;
return ntohs (ret);
}
static inline uint32_t
buf_read_u32 (struct buffer *buf, bool *good)
{
uint32_t ret;
if (!buf_read (buf, &ret, sizeof (uint32_t)))
{
if (good)
*good = false;
return 0;
}
else
{
if (good)
*good = true;
return ntohl (ret);
}
}
static inline bool
buf_string_match (const struct buffer *src, const void *match, int size)
{
if (size != src->len)
return false;
return memcmp (BPTR (src), match, size) == 0;
}
static inline bool
buf_string_match_head (const struct buffer *src, const void *match, int size)
{
if (size < 0 || size > src->len)
return false;
return memcmp (BPTR (src), match, size) == 0;
}
bool buf_string_match_head_str (const struct buffer *src, const char *match);
bool buf_string_compare_advance (struct buffer *src, const char *match);
int buf_substring_len (const struct buffer *buf, int delim);
/*
* Bitwise operations
*/
static inline void
xor (uint8_t *dest, const uint8_t *src, int len)
{
while (len-- > 0)
*dest++ ^= *src++;
}
/*
* Print a string which might be NULL
*/
const char *np (const char *str);
/*#define CHARACTER_CLASS_DEBUG*/
/* character classes */
#define CC_ANY (1<<0)
#define CC_NULL (1<<1)
#define CC_ALNUM (1<<2)
#define CC_ALPHA (1<<3)
#define CC_ASCII (1<<4)
#define CC_CNTRL (1<<5)
#define CC_DIGIT (1<<6)
#define CC_PRINT (1<<7)
#define CC_PUNCT (1<<8)
#define CC_SPACE (1<<9)
#define CC_XDIGIT (1<<10)
#define CC_BLANK (1<<11)
#define CC_NEWLINE (1<<12)
#define CC_CR (1<<13)
#define CC_BACKSLASH (1<<14)
#define CC_UNDERBAR (1<<15)
#define CC_DASH (1<<16)
#define CC_DOT (1<<17)
#define CC_COMMA (1<<18)
#define CC_COLON (1<<19)
#define CC_SLASH (1<<20)
#define CC_SINGLE_QUOTE (1<<21)
#define CC_DOUBLE_QUOTE (1<<22)
#define CC_REVERSE_QUOTE (1<<23)
#define CC_AT (1<<24)
#define CC_EQUAL (1<<25)
/* macro classes */
#define CC_NAME (CC_ALNUM|CC_UNDERBAR)
#define CC_CRLF (CC_CR|CC_NEWLINE)
bool char_class (const unsigned char c, const unsigned int flags);
bool string_class (const char *str, const unsigned int inclusive, const unsigned int exclusive);
bool string_mod (char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace);
const char *string_mod_const (const char *str,
const unsigned int inclusive,
const unsigned int exclusive,
const char replace,
struct gc_arena *gc);
void string_replace_leading (char *str, const char match, const char replace);
#ifdef CHARACTER_CLASS_DEBUG
void character_class_debug (void);
#endif
/*
* Verify that a pointer is correctly aligned
*/
#ifdef VERIFY_ALIGNMENT
void valign4 (const struct buffer *buf, const char *file, const int line);
# define verify_align_4(ptr) valign4(buf, __FILE__, __LINE__)
#else
# define verify_align_4(ptr)
#endif
/*
* Very basic garbage collection, mostly for routines that return
* char ptrs to malloced strings.
*/
void gc_transfer (struct gc_arena *dest, struct gc_arena *src);
void x_gc_free (struct gc_arena *a);
static inline bool
gc_defined (struct gc_arena *a)
{
return a->list != NULL;
}
static inline void
gc_init (struct gc_arena *a)
{
a->list = NULL;
}
static inline void
gc_detach (struct gc_arena *a)
{
gc_init (a);
}
static inline struct gc_arena
gc_new (void)
{
struct gc_arena ret;
ret.list = NULL;
return ret;
}
static inline void
gc_free (struct gc_arena *a)
{
if (a->list)
x_gc_free (a);
}
static inline void
gc_reset (struct gc_arena *a)
{
gc_free (a);
}
/*
* Allocate memory to hold a structure
*/
void out_of_memory (void);
#define ALLOC_OBJ(dptr, type) \
{ \
check_malloc_return ((dptr) = (type *) malloc (sizeof (type))); \
}
#define ALLOC_OBJ_CLEAR(dptr, type) \
{ \
ALLOC_OBJ (dptr, type); \
memset ((dptr), 0, sizeof(type)); \
}
#define ALLOC_ARRAY(dptr, type, n) \
{ \
check_malloc_return ((dptr) = (type *) malloc (array_mult_safe (sizeof (type), (n), 0))); \
}
#define ALLOC_ARRAY_GC(dptr, type, n, gc) \
{ \
(dptr) = (type *) gc_malloc (array_mult_safe (sizeof (type), (n), 0), false, (gc)); \
}
#define ALLOC_ARRAY_CLEAR(dptr, type, n) \
{ \
ALLOC_ARRAY (dptr, type, n); \
memset ((dptr), 0, (array_mult_safe (sizeof(type), (n), 0))); \
}
#define ALLOC_ARRAY_CLEAR_GC(dptr, type, n, gc) \
{ \
(dptr) = (type *) gc_malloc (array_mult_safe (sizeof (type), (n), 0), true, (gc)); \
}
#define ALLOC_VAR_ARRAY_CLEAR_GC(dptr, type, atype, n, gc) \
{ \
(dptr) = (type *) gc_malloc (array_mult_safe (sizeof (atype), (n), sizeof (type)), true, (gc)); \
}
#define ALLOC_OBJ_GC(dptr, type, gc) \
{ \
(dptr) = (type *) gc_malloc (sizeof (type), false, (gc)); \
}
#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc) \
{ \
(dptr) = (type *) gc_malloc (sizeof (type), true, (gc)); \
}
static inline void
check_malloc_return (void *p)
{
void out_of_memory (void);
if (!p)
out_of_memory ();
}
/*
* Manage lists of buffers
*/
#ifdef ENABLE_BUFFER_LIST
struct buffer_entry
{
struct buffer buf;
struct buffer_entry *next;
};
struct buffer_list
{
struct buffer_entry *head; /* next item to pop/peek */
struct buffer_entry *tail; /* last item pushed */
int size; /* current number of entries */
int max_size; /* maximum size list should grow to */
};
struct buffer_list *buffer_list_new (const int max_size);
void buffer_list_free (struct buffer_list *ol);
bool buffer_list_defined (const struct buffer_list *ol);
void buffer_list_reset (struct buffer_list *ol);
void buffer_list_push (struct buffer_list *ol, const unsigned char *str);
struct buffer_entry *buffer_list_push_data (struct buffer_list *ol, const uint8_t *data, size_t size);
struct buffer *buffer_list_peek (struct buffer_list *ol);
void buffer_list_advance (struct buffer_list *ol, int n);
void buffer_list_pop (struct buffer_list *ol);
void buffer_list_aggregate (struct buffer_list *bl, const size_t max);
struct buffer_list *buffer_list_file (const char *fn, int max_line_len);
#endif
#endif /* BUFFER_H */

78
circ_list.h Normal file
View file

@ -0,0 +1,78 @@
/*
* OpenVPN -- An application to securely tunnel IP networks
* over a single UDP port, with support for SSL/TLS-based
* session authentication and key exchange,
* packet encryption, packet authentication, and
* packet compression.
*
* Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* 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 (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef CIRC_LIST_H
#define CIRC_LIST_H
#include "basic.h"
#include "integer.h"
#include "error.h"
#define CIRC_LIST(name, type) \
struct name { \
int x_head; \
int x_size; \
int x_cap; \
int x_sizeof; \
type x_list[EMPTY_ARRAY_SIZE]; \
}
#define CIRC_LIST_PUSH(obj, item) \
{ \
(obj)->x_head = modulo_add ((obj)->x_head, -1, (obj)->x_cap); \
(obj)->x_list[(obj)->x_head] = (item); \
(obj)->x_size = min_int ((obj)->x_size + 1, (obj)->x_cap); \
}
#define CIRC_LIST_SIZE(obj) \
((obj)->x_size)
#define CIRC_LIST_INDEX(obj, index) \
modulo_add ((obj)->x_head, \
index_verify ((index), (obj)->x_size, __FILE__, __LINE__), \
(obj)->x_cap)
#define CIRC_LIST_ITEM(obj, index) \
((obj)->x_list[CIRC_LIST_INDEX((obj), (index))])
#define CIRC_LIST_RESET(obj) \
{ \
(obj)->x_head = 0; \
(obj)->x_size = 0; \
}
#define CIRC_LIST_ALLOC(dest, list_type, size) \
{ \
const int so = sizeof (list_type) + sizeof ((dest)->x_list[0]) * (size); \
(dest) = (list_type *) malloc (so); \
check_malloc_return (dest); \
memset ((dest), 0, so); \
(dest)->x_cap = size; \
(dest)->x_sizeof = so; \
}
#define CIRC_LIST_FREE(dest) \
free (dest)
#endif

263
clinat.c Normal file
View file

@ -0,0 +1,263 @@
/*
* OpenVPN -- An application to securely tunnel IP networks
* over a single TCP/UDP port, with support for SSL/TLS-based
* session authentication and key exchange,
* packet encryption, packet authentication, and
* packet compression.
*
* Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* 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 (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "syshead.h"
#if defined(ENABLE_CLIENT_NAT)
#include "clinat.h"
#include "proto.h"
#include "socket.h"
#include "memdbg.h"
static bool
add_entry(struct client_nat_option_list *dest,
const struct client_nat_entry *e)
{
if (dest->n >= MAX_CLIENT_NAT)
{
msg (M_WARN, "WARNING: client-nat table overflow (max %d entries)", MAX_CLIENT_NAT);
return false;
}
else
{
dest->entries[dest->n++] = *e;
return true;
}
}
void
print_client_nat_list(const struct client_nat_option_list *list, int msglevel)
{
struct gc_arena gc = gc_new ();
int i;
msg (msglevel, "*** CNAT list");
if (list)
{
for (i = 0; i < list->n; ++i)
{
const struct client_nat_entry *e = &list->entries[i];
msg (msglevel, " CNAT[%d] t=%d %s/%s/%s",
i,
e->type,
print_in_addr_t (e->network, IA_NET_ORDER, &gc),
print_in_addr_t (e->netmask, IA_NET_ORDER, &gc),
print_in_addr_t (e->foreign_network, IA_NET_ORDER, &gc));
}
}
gc_free (&gc);
}
struct client_nat_option_list *
new_client_nat_list (struct gc_arena *gc)
{
struct client_nat_option_list *ret;
ALLOC_OBJ_CLEAR_GC (ret, struct client_nat_option_list, gc);
return ret;
}
struct client_nat_option_list *
clone_client_nat_option_list (const struct client_nat_option_list *src, struct gc_arena *gc)
{
struct client_nat_option_list *ret;
ALLOC_OBJ_GC (ret, struct client_nat_option_list, gc);
*ret = *src;
return ret;
}
void
copy_client_nat_option_list (struct client_nat_option_list *dest,
const struct client_nat_option_list *src)
{
int i;
for (i = 0; i < src->n; ++i)
{
if (!add_entry(dest, &src->entries[i]))
break;
}
}
void
add_client_nat_to_option_list (struct client_nat_option_list *dest,
const char *type,
const char *network,
const char *netmask,
const char *foreign_network,
int msglevel)
{
struct client_nat_entry e;
bool ok;
if (!strcmp(type, "snat"))
e.type = CN_SNAT;
else if (!strcmp(type, "dnat"))
e.type = CN_DNAT;
else
{
msg(msglevel, "client-nat: type must be 'snat' or 'dnat'");
return;
}
e.network = getaddr(0, network, 0, &ok, NULL);
if (!ok)
{
msg(msglevel, "client-nat: bad network: %s", network);
return;
}
e.netmask = getaddr(0, netmask, 0, &ok, NULL);
if (!ok)
{
msg(msglevel, "client-nat: bad netmask: %s", netmask);
return;
}
e.foreign_network = getaddr(0, foreign_network, 0, &ok, NULL);
if (!ok)
{
msg(msglevel, "client-nat: bad foreign network: %s", foreign_network);
return;
}
add_entry(dest, &e);
}
#if 0
static void
print_checksum (struct openvpn_iphdr *iph, const char *prefix)
{
uint16_t *sptr;
unsigned int sum = 0;
int i = 0;
for (sptr = (uint16_t *)iph; (uint8_t *)sptr < (uint8_t *)iph + sizeof(struct openvpn_iphdr); sptr++)
{
i += 1;
sum += *sptr;
}
msg (M_INFO, "** CKSUM[%d] %s %08x", i, prefix, sum);
}
#endif
static void
print_pkt (struct openvpn_iphdr *iph, const char *prefix, const int direction, const int msglevel)
{
struct gc_arena gc = gc_new ();
char *dirstr = "???";
if (direction == CN_OUTGOING)
dirstr = "OUT";
else if (direction == CN_INCOMING)
dirstr = "IN";
msg(msglevel, "** CNAT %s %s %s -> %s",
dirstr,
prefix,
print_in_addr_t (iph->saddr, IA_NET_ORDER, &gc),
print_in_addr_t (iph->daddr, IA_NET_ORDER, &gc));
gc_free (&gc);
}
void
client_nat_transform (const struct client_nat_option_list *list,
struct buffer *ipbuf,
const int direction)
{
struct ip_tcp_udp_hdr *h = (struct ip_tcp_udp_hdr *) BPTR (ipbuf);
int i;
uint32_t addr, *addr_ptr;
const uint32_t *from, *to;
int accumulate = 0;
unsigned int amask;
unsigned int alog = 0;
if (check_debug_level (D_CLIENT_NAT))
print_pkt (&h->ip, "BEFORE", direction, D_CLIENT_NAT);
for (i = 0; i < list->n; ++i)
{
const struct client_nat_entry *e = &list->entries[i]; /* current NAT rule */
if (e->type ^ direction)
{
addr = *(addr_ptr = &h->ip.daddr);
amask = 2;
}
else
{
addr = *(addr_ptr = &h->ip.saddr);
amask = 1;
}
if (direction)
{
from = &e->foreign_network;
to = &e->network;
}
else
{
from = &e->network;
to = &e->foreign_network;
}
if (((addr & e->netmask) == *from) && !(amask & alog))
{
/* pre-adjust IP checksum */
ADD_CHECKSUM_32(accumulate, addr);
/* do NAT transform */
addr = (addr & ~e->netmask) | *to;
/* post-adjust IP checksum */
SUB_CHECKSUM_32(accumulate, addr);
/* write the modified address to packet */
*addr_ptr = addr;
/* mark as modified */
alog |= amask;
}
}
if (alog)
{
if (check_debug_level (D_CLIENT_NAT))
print_pkt (&h->ip, "AFTER", direction, D_CLIENT_NAT);
ADJUST_CHECKSUM(accumulate, h->ip.check);
if (h->ip.protocol == OPENVPN_IPPROTO_TCP)
{
if (BLEN(ipbuf) >= sizeof(struct openvpn_iphdr) + sizeof(struct openvpn_tcphdr))
{
ADJUST_CHECKSUM(accumulate, h->u.tcp.check);
}
}
else if (h->ip.protocol == OPENVPN_IPPROTO_UDP)
{
if (BLEN(ipbuf) >= sizeof(struct openvpn_iphdr) + sizeof(struct openvpn_udphdr))
{
ADJUST_CHECKSUM(accumulate, h->u.udp.check);
}
}
}
}
#endif

65
clinat.h Normal file
View file

@ -0,0 +1,65 @@
/*
* OpenVPN -- An application to securely tunnel IP networks
* over a single TCP/UDP port, with support for SSL/TLS-based
* session authentication and key exchange,
* packet encryption, packet authentication, and
* packet compression.
*
* Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* 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 (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#if !defined(CLINAT_H) && defined(ENABLE_CLIENT_NAT)
#define CLINAT_H
#include "buffer.h"
#define MAX_CLIENT_NAT 64
#define CN_OUTGOING 0
#define CN_INCOMING 1
struct client_nat_entry {
# define CN_SNAT 0
# define CN_DNAT 1
int type;
in_addr_t network;
in_addr_t netmask;
in_addr_t foreign_network;
};
struct client_nat_option_list {
int n;
struct client_nat_entry entries[MAX_CLIENT_NAT];
};
struct client_nat_option_list *new_client_nat_list (struct gc_arena *gc);
struct client_nat_option_list *clone_client_nat_option_list (const struct client_nat_option_list *src, struct gc_arena *gc);
void copy_client_nat_option_list (struct client_nat_option_list *dest, const struct client_nat_option_list *src);
void print_client_nat_list(const struct client_nat_option_list *list, int msglevel);
void add_client_nat_to_option_list (struct client_nat_option_list *dest,
const char *type,
const char *network,
const char *netmask,
const char *foreign_network,
int msglevel);
void client_nat_transform (const struct client_nat_option_list *list,
struct buffer *ipbuf,
const int direction);
#endif

102
common.h Normal file
View file

@ -0,0 +1,102 @@
/*
* OpenVPN -- An application to securely tunnel IP networks
* over a single UDP port, with support for SSL/TLS-based
* session authentication and key exchange,
* packet encryption, packet authentication, and
* packet compression.
*
* Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* 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 (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef COMMON_H
#define COMMON_H
/*
* Statistics counters and associated printf formats.
*/
#ifdef USE_64_BIT_COUNTERS
typedef unsigned long long int counter_type;
# ifdef WIN32
# define counter_format "%I64u"
# else
# define counter_format "%llu"
# endif
#else
typedef unsigned int counter_type;
# define counter_format "%u"
#endif
/*
* Time intervals
*/
typedef int interval_t;
/*
* Used as an upper bound for timeouts.
*/
#define BIG_TIMEOUT (60*60*24*7) /* one week (in seconds) */
/*
* Printf formats for special types
*/
#ifdef _WIN64
#define ptr_format "0x%I64x"
#else
#define ptr_format "0x%08lx"
#endif
#define time_format "%lu"
#define fragment_header_format "0x%08x"
/* these are used to cast the arguments
* and MUST match the formats above */
typedef unsigned long time_type;
#ifdef _WIN64
typedef unsigned long long ptr_type;
#else
typedef unsigned long ptr_type;
#endif
/* the --client-config-dir default file */
#define CCD_DEFAULT "DEFAULT"
/*
* This parameter controls the TLS channel buffer size and the
* maximum size of a single TLS message (cleartext).
* This parameter must be >= PUSH_BUNDLE_SIZE
*/
#define TLS_CHANNEL_BUF_SIZE 2048
/*
* This parameter controls the maximum size of a bundle
* of pushed options.
*/
#define PUSH_BUNDLE_SIZE 1024
/*
* A sort of pseudo-filename for data provided inline within
* the configuration file.
*/
#if ENABLE_INLINE_FILES
#define INLINE_FILE_TAG "[[INLINE]]"
#endif
/*
* Script security warning
*/
#define SCRIPT_SECURITY_WARNING "openvpn_execve: external program may not be called unless '--script-security 2' or higher is enabled. Use '--script-security 3 system' for backward compatibility with 2.1_rc8 and earlier. See --help text or man page for detailed info."
#endif

305
config-win32.h Normal file
View file

@ -0,0 +1,305 @@
/*
* OpenVPN -- An application to securely tunnel IP networks
* over a single UDP port, with support for SSL/TLS-based
* session authentication and key exchange,
* packet encryption, packet authentication, and
* packet compression.
*
* Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* 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 (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Configuration header for Win32 using the MSVC environment.
*/
#include <windows.h>
#include <winsock2.h>
#include "autodefs.h" /* machine generated */
//#define sleep(x) Sleep((x)*1000)
//#define random rand
//#define srandom srand
typedef unsigned long in_addr_t;
#ifndef _SSIZE_T_
#define _SSIZE_T_
typedef unsigned int ssize_t;
#endif
/* Append a label to program startup title */
/*#define DEBUG_LABEL "DEBUG1"*/
/* Should we print debug info from driver? */
#ifdef PRODUCT_TAP_DEBUG
#define TAP_WIN32_DEBUG
#endif
/* Enable client/server capability */
#define ENABLE_CLIENT_SERVER 1
/* Enable client capability only */
#define ENABLE_CLIENT_ONLY
/* Enable management server capability */
#define ENABLE_MANAGEMENT 1
/* Enable PKCS#11 support */
/* #define USE_PKCS11 1 */
/* Enable HTTP proxy support */
#define ENABLE_HTTP_PROXY 1
/* Enable Socks proxy support */
#define ENABLE_SOCKS 1
/* Enable internal fragmentation support */
#define ENABLE_FRAGMENT 1
/* Enable smaller executable size */
/* #undef ENABLE_SMALL */
/* Enable debugging support */
#define ENABLE_DEBUG 1
/* if defined, will allow usage of the --plugin directive */
#define USE_LOAD_LIBRARY
/* Dimension size to use for empty array declaration */
#define EMPTY_ARRAY_SIZE 0
/* Define to 1 if you have the `getsockname' function. */
#define HAVE_GETSOCKNAME 1
/* Define to 1 if you have the <openssl/engine.h> header file. */
#define HAVE_OPENSSL_ENGINE_H 1
/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */
#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1
/* Define to 1 if you have the `ENGINE_register_all_complete' function. */
#define HAVE_ENGINE_REGISTER_ALL_COMPLETE 1
/* Define to 1 if you have the `ENGINE_cleanup' function. */
#define HAVE_ENGINE_CLEANUP 1
/* gettimeofday() is implemented in otime.c for Windows */
#define HAVE_GETTIMEOFDAY 1
/* Define to 1 if you have the 'chsize' function. */
#define HAVE_CHSIZE 1
/* Define to 1 if you have the `chdir' function. */
#define HAVE_CHDIR 1
/* Define to 1 if your compiler supports GNU GCC-style variadic macros */
#ifndef _MSC_VER /* Defines MSFT compiler version. Defined as 1200 for MSVC++ 6.0. */
#define HAVE_CPP_VARARG_MACRO_GCC 1
#endif
/* Define to 1 if you have the <ctype.h> header file. */
#define HAVE_CTYPE_H 1
/* Define to 1 if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 1
/* Define to 1 if you have the `EVP_CIPHER_CTX_set_key_length' function. */
#define HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH 1
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define to 1 if you have the `getsockopt' function. */
#define HAVE_GETSOCKOPT 1
/* Define to 1 if you have the `inet_ntoa' function. */
#define HAVE_INET_NTOA 1
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
to 0 otherwise. */
#define HAVE_MALLOC 1
/* Define to 1 if you have the `memset' function. */
#define HAVE_MEMSET 1
/* Define to 1 if you have the `setsockopt' function. */
#define HAVE_SETSOCKOPT 1
/* Define to 1 if you have the `socket' function. */
#define HAVE_SOCKET 1
/* Define to 1 if you have the <stdarg.h> header file. */
#define HAVE_STDARG_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#ifndef _MSC_VER
#define HAVE_STDINT_H 1
#endif
/* Define to 1 if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the `strerror' function. */
#define HAVE_STRERROR 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the `system' function. */
#define HAVE_SYSTEM 1
/* Define to 1 if you have the <sys/file.h> header file. */
#ifndef _MSC_VER
#define HAVE_SYS_FILE_H 1
#endif
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
#ifndef _MSC_VER
#define HAVE_SYS_TIME_H 1
#endif
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the `time' function. */
#define HAVE_TIME 1
/* Define to 1 if you have the <unistd.h> header file. */
#ifndef _MSC_VER
#define HAVE_UNISTD_H 1
#endif
/* Define to 1 if you have the `vsnprintf' function. */
#define HAVE_VSNPRINTF 1
/* Special Windows version of getpass() defined in io.c */
#define HAVE_GETPASS 1
/* Define to the address where bug reports for this package should be sent. */
//#define PACKAGE_BUGREPORT "openvpn-users@lists.sourceforge.net"
/* Define to the full name and version of this package. */
#ifdef DEBUG_LABEL
#define PACKAGE_STRING PACKAGE_NAME " " PACKAGE_VERSION " " DEBUG_LABEL
#else
#define PACKAGE_STRING PACKAGE_NAME " " PACKAGE_VERSION
#endif
/* Define as the return type of signal handlers (`int' or `void'). */
#define RETSIGTYPE void
/* The size of a `unsigned int', as computed by sizeof. */
#define SIZEOF_UNSIGNED_INT 4
/* The size of a `unsigned long', as computed by sizeof. */
#define SIZEOF_UNSIGNED_LONG 4
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* A string representing our target */
#ifdef _MSC_VER
#define TARGET_ALIAS "Win32-MSVC++"
#else
#define TARGET_ALIAS "Win32-MinGW"
#endif
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#ifndef _MSC_VER
#define TIME_WITH_SYS_TIME 1
#endif
/* Use OpenSSL crypto library */
#define USE_CRYPTO 1
/* Use LZO compression library */
#define USE_LZO 1
/* LZO version number */
#define LZO_VERSION_NUM "2"
/* Use lzo/ directory prefix for LZO header files (for LZO 2.0) */
#define LZO_HEADER_DIR 1
/* Use OpenSSL SSL library */
#define USE_SSL 1
/* Version number of package */
#define VERSION PACKAGE_VERSION
/* Define as `__inline' if that's what the C compiler calls it, or to nothing
if it is not supported. */
#define inline __inline
/* type to use in place of socklen_t if not defined */
#define socklen_t unsigned int
/* 32-bit unsigned type */
#define uint32_t unsigned int
/* 16-bit unsigned type */
#define uint16_t unsigned short
/* 8-bit unsigned type */
#define uint8_t unsigned char
/* Route command */
#define ROUTE_PATH "route"
/* Windows doesn't support PTHREAD yet */
#ifdef USE_PTHREAD
#error The Windows version of OpenVPN does not support PTHREAD yet
#endif
#ifdef _MSC_VER
/* MSVC++ hacks */
#pragma warning(disable:4244) // conversion from 'foo' to 'bar', possible loss of data
#pragma warning(disable:4018) // signed/unsigned mismatch
#include <io.h>
#include <direct.h>
//#define vsnprintf _vsnprintf
//#define vsnwprintf _vsnwprintf
#define snwprintf _snwprintf
#define write _write
#define open _open
#define read _read
#define close _close
#define lseek _lseek
#define chdir _chdir
#define strdup _strdup
#define strcasecmp _stricmp
#define chsize _chsize
#define S_IRUSR 0
#define S_IWUSR 0
#define TV_SEC_CAST (long)
#define TV_USEC_CAST (long)
typedef int intptr_t;
/* Visual Studio 2005 supports vararg macros */
#if _MSC_VER >= 1400
#define HAVE_CPP_VARARG_MACRO_ISO 1
#endif
#endif

932
configure.ac Normal file
View file

@ -0,0 +1,932 @@
dnl OpenVPN -- An application to securely tunnel IP networks
dnl over a single UDP port, with support for SSL/TLS-based
dnl session authentication and key exchange,
dnl packet encryption, packet authentication, and
dnl packet compression.
dnl
dnl Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
dnl
dnl This program is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
dnl the Free Software Foundation; either version 2 of the License, or
dnl (at your option) any later version.
dnl
dnl This program is distributed in the hope that it will be useful,
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
dnl GNU General Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
dnl along with this program (see the file COPYING included with this
dnl distribution); if not, write to the Free Software Foundation, Inc.,
dnl 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.50)
m4_include(version.m4)
AC_INIT([OpenVPN], [PRODUCT_VERSION], [openvpn-users@lists.sourceforge.net], [openvpn])
AM_CONFIG_HEADER(config.h)
AC_CONFIG_SRCDIR(syshead.h)
dnl Guess host type.
AC_CANONICAL_HOST
AC_CANONICAL_SYSTEM
AM_INIT_AUTOMAKE(openvpn, [$PACKAGE_VERSION])
AC_ARG_WITH(cygwin-native,
[ --with-cygwin-native Compile native win32],
[CYGWIN_NATIVE="${withval}"],
[CYGWIN_NATIVE="no"]
)
WIN32="no"
CYGWIN="no"
case "${host}" in
*-mingw*)
WIN32="yes"
cross_compiling="yes"
;;
*-cygwin*)
AC_MSG_CHECKING([cygwin mode to use])
if test "${CYGWIN_NATIVE}" = "yes"; then
AC_MSG_RESULT([Using native win32])
CFLAGS="${CFLAGS} -mno-cygwin"
CYGWIN="yes"
WIN32="yes"
else
AC_MSG_RESULT([Using cygwin])
fi
;;
*)
;;
esac
AC_ARG_ENABLE(lzo,
[ --disable-lzo Disable LZO compression support],
[LZO="$enableval"],
[LZO="yes"]
)
AC_ARG_ENABLE(lzo-stub,
[ --enable-lzo-stub Don't compile LZO compression support but still allow limited interoperability with LZO-enabled peers],
[LZO_STUB="$enableval"],
[LZO_STUB="no"]
)
AC_ARG_ENABLE(crypto,
[ --disable-crypto Disable OpenSSL crypto support],
[CRYPTO="$enableval"],
[CRYPTO="yes"]
)
AC_ARG_ENABLE(ssl,
[ --disable-ssl Disable OpenSSL SSL support for TLS-based key exchange],
[SSL="$enableval"],
[SSL="yes"]
)
AC_ARG_ENABLE(multi,
[ --disable-multi Disable client/server support (--mode server + client mode)],
[MULTI="$enableval"],
[MULTI="yes"]
)
AC_ARG_ENABLE(server,
[ --disable-server Disable server support only (but retain client support)],
[MULTI_SERVER="$enableval"],
[MULTI_SERVER="yes"]
)
AC_ARG_ENABLE(plugins,
[ --disable-plugins Disable plug-in support],
[PLUGINS="$enableval"],
[PLUGINS="yes"]
)
AC_ARG_ENABLE(management,
[ --disable-management Disable management server support],
[MANAGEMENT="$enableval"],
[MANAGEMENT="yes"]
)
AC_ARG_ENABLE(pkcs11,
[ --disable-pkcs11 Disable pkcs11 support],
[PKCS11="$enableval"],
[PKCS11="yes"]
)
AC_ARG_ENABLE(socks,
[ --disable-socks Disable Socks support],
[SOCKS="$enableval"],
[SOCKS="yes"]
)
AC_ARG_ENABLE(http,
[ --disable-http Disable HTTP proxy support],
[HTTP_PROXY="$enableval"],
[HTTP_PROXY="yes"]
)
AC_ARG_ENABLE(fragment,
[ --disable-fragment Disable internal fragmentation support (--fragment)],
[FRAGMENT="$enableval"],
[FRAGMENT="yes"]
)
AC_ARG_ENABLE(multihome,
[ --disable-multihome Disable multi-homed UDP server support (--multihome)],
[MULTIHOME="$enableval"],
[MULTIHOME="yes"]
)
AC_ARG_ENABLE(port-share,
[ --disable-port-share Disable TCP server port-share support (--port-share)],
[PORT_SHARE="$enableval"],
[PORT_SHARE="yes"]
)
AC_ARG_ENABLE(debug,
[ --disable-debug Disable debugging support (disable gremlin and verb 7+ messages)],
[DEBUG="$enableval"],
[DEBUG="yes"]
)
AC_ARG_ENABLE(small,
[ --enable-small Enable smaller executable size (disable OCC, usage message, and verb 4 parm list)],
[SMALL="$enableval"],
[SMALL="no"]
)
AC_ARG_ENABLE(pthread,
[ --enable-pthread Enable pthread support (Experimental for OpenVPN 2.0)],
[PTHREAD="$enableval"],
[PTHREAD="no"]
)
AC_ARG_ENABLE(password-save,
[ --enable-password-save Allow --askpass and --auth-user-pass passwords to be read from a file],
[PASSWORD_SAVE="$enableval"],
[PASSWORD_SAVE="no"]
)
AC_ARG_ENABLE(iproute2,
[ --enable-iproute2 Enable support for iproute2],
test $enableval = "yes" && AC_DEFINE(CONFIG_FEATURE_IPROUTE, 1, [enable iproute2 support])
)
AC_ARG_ENABLE(def-auth,
[ --disable-def-auth Disable deferred authentication],
[DEF_AUTH="$enableval"],
[DEF_AUTH="yes"]
)
AC_ARG_ENABLE(pf,
[ --disable-pf Disable internal packet filter],
[PF="$enableval"],
[PF="yes"]
)
AC_ARG_ENABLE(strict,
[ --enable-strict Enable strict compiler warnings (debugging option)],
[STRICT="$enableval"],
[STRICT="no"]
)
AC_ARG_ENABLE(pedantic,
[ --enable-pedantic Enable pedantic compiler warnings, will not generate a working executable (debugging option)],
[PEDANTIC="$enableval"],
[PEDANTIC="no"]
)
AC_ARG_ENABLE(profiling,
[ --enable-profiling Enable profiling (debugging option)],
[PROFILE="$enableval"],
[PROFILE="no"]
)
AC_ARG_ENABLE(strict-options,
[ --enable-strict-options Enable strict options check between peers (debugging option)],
[STRICT_OPTIONS="$enableval"],
[STRICT_OPTIONS="no"]
)
AC_ARG_ENABLE(selinux,
[ --disable-selinux Disable SELinux support],
[SELINUX="$enableval"],
[SELINUX="yes"]
)
AC_ARG_WITH(ssl-headers,
[ --with-ssl-headers=DIR Crypto/SSL Include files location],
[CS_HDR_DIR="$withval"]
[CPPFLAGS="$CPPFLAGS -I$withval"]
)
AC_ARG_WITH(ssl-lib,
[ --with-ssl-lib=DIR Crypto/SSL Library location],
[LDFLAGS="$LDFLAGS -L$withval"]
)
AC_ARG_WITH(lzo-headers,
[ --with-lzo-headers=DIR LZO Include files location],
[LZO_HDR_DIR="$withval"]
[CPPFLAGS="$CPPFLAGS -I$withval"]
)
AC_ARG_WITH(lzo-lib,
[ --with-lzo-lib=DIR LZO Library location],
[LDFLAGS="$LDFLAGS -L$withval"]
)
AC_ARG_WITH(pkcs11-helper-headers,
[ --with-pkcs11-helper-headers=DIR pkcs11-helper Include files location],
[PKCS11_HELPER_HDR_DIR="$withval"]
[CPPFLAGS="$CPPFLAGS -I$withval"]
)
AC_ARG_WITH(pkcs11-helper-lib,
[ --with-pkcs11-helper-lib=DIR pkcs11-helper Library location],
[LDFLAGS="$LDFLAGS -L$withval"]
)
AC_ARG_WITH(ifconfig-path,
[ --with-ifconfig-path=PATH Path to ifconfig tool],
[IFCONFIG="$withval"],
[AC_PATH_PROG([IFCONFIG], [ifconfig], [ifconfig], [$PATH:/usr/local/sbin:/usr/sbin:/sbin])]
)
AC_DEFINE_UNQUOTED(IFCONFIG_PATH, "$IFCONFIG", [Path to ifconfig tool])
AC_ARG_WITH(iproute-path,
[ --with-iproute-path=PATH Path to iproute tool],
[IPROUTE="$withval"],
[AC_PATH_PROG([IPROUTE], [ip], [ip], [$PATH:/usr/local/sbin:/usr/sbin:/sbin])]
)
AC_DEFINE_UNQUOTED(IPROUTE_PATH, "$IPROUTE", [Path to iproute tool])
AC_ARG_WITH(route-path,
[ --with-route-path=PATH Path to route tool],
[ROUTE="$withval"],
[AC_PATH_PROG([ROUTE], [route], [route], [$PATH:/usr/local/sbin:/usr/sbin:/sbin])]
)
AC_DEFINE_UNQUOTED(ROUTE_PATH, "$ROUTE", [Path to route tool])
AC_ARG_WITH(mem-check,
[ --with-mem-check=TYPE Build with debug memory checking, TYPE = dmalloc or valgrind],
[MEMCHECK="$withval"]
)
dnl fix search path, to allow compilers to find syshead.h
CPPFLAGS="$CPPFLAGS -I${srcdir}"
dnl check target OS
openvpn_target=$target
if test $target_alias; then
openvpn_target=$target_alias
fi
AC_DEFINE_UNQUOTED(TARGET_ALIAS, "$openvpn_target", [A string representing our target])
case "$target" in
*linux*)
AC_DEFINE(TARGET_LINUX, 1, [Are we running on Linux?])
dnl RH9 SSL headers workaround
if test -z $CS_HDR_DIR && test "$CRYPTO" = "yes"; then
CPPFLAGS="$CPPFLAGS $(pkg-config --cflags openssl 2>/dev/null)"
fi
;;
*solaris*)
AC_DEFINE(TARGET_SOLARIS, 1, [Are we running on Solaris?])
;;
*openbsd*)
AC_DEFINE(TARGET_OPENBSD, 1, [Are we running on OpenBSD?])
;;
*freebsd*)
AC_DEFINE(TARGET_FREEBSD, 1, [Are we running on FreeBSD?])
;;
*netbsd*)
AC_DEFINE(TARGET_NETBSD, 1, [Are we running NetBSD?])
;;
*darwin*)
dnl some Mac OS X tendering (we use vararg macros...)
AC_DEFINE(TARGET_DARWIN, 1, [Are we running on Mac OS X?])
CPPFLAGS="$CPPFLAGS -no-cpp-precomp"
;;
*mingw*)
AC_DEFINE(TARGET_WIN32, 1, [Are we running WIN32?])
OPENVPN_ADD_LIBS(-lgdi32)
OPENVPN_ADD_LIBS(-lws2_32)
OPENVPN_ADD_LIBS(-lwininet)
OPENVPN_ADD_LIBS(-lcrypt32)
OPENVPN_ADD_LIBS(-liphlpapi)
OPENVPN_ADD_LIBS(-lwinmm)
;;
*dragonfly*)
AC_DEFINE(TARGET_DRAGONFLY, 1, [Are we running on DragonFlyBSD?])
;;
esac
dnl Checks for programs.
AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_GCC_TRADITIONAL
AC_GNU_SOURCE
if test "${WIN32}" = "yes"; then
AC_ARG_VAR([MAN2HTML], [man2html utility])
AC_CHECK_PROGS([MAN2HTML], [man2html])
test -z "${MAN2HTML}" && AC_MSG_ERROR([man2html is required for win32])
fi
dnl Checks for header files.
AC_HEADER_STDC
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_C_INLINE
AC_C_VOLATILE
AC_TYPE_OFF_T
AC_TYPE_PID_T
AC_TYPE_SIZE_T
AC_TYPE_UID_T
TYPE_SOCKLEN_T
AC_HEADER_TIME
AX_CPP_VARARG_MACRO_ISO
AX_CPP_VARARG_MACRO_GCC
AX_EMPTY_ARRAY
dnl Check for more header files.
AC_CHECK_HEADERS(fcntl.h stdlib.h dnl
stdarg.h stdio.h string.h dnl
strings.h ctype.h errno.h dnl
)
if test "${WIN32}" != "yes"; then
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS(sys/time.h sys/socket.h sys/un.h sys/ioctl.h sys/stat.h dnl
sys/mman.h fcntl.h sys/file.h stdlib.h stdint.h dnl
stdarg.h unistd.h signal.h stdio.h string.h dnl
strings.h ctype.h errno.h syslog.h pwd.h grp.h dnl
net/if_tun.h net/tun/if_tun.h stropts.h sys/sockio.h dnl
netinet/in.h netinet/in_systm.h dnl
netinet/tcp.h arpa/inet.h dnl
netdb.h sys/uio.h linux/if_tun.h linux/sockios.h dnl
linux/types.h sys/poll.h sys/epoll.h err.h dnl
)
AC_CHECK_HEADERS(net/if.h,,,
[#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
])
AC_CHECK_HEADERS(netinet/ip.h,,,
[#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_NETINET_IN_SYSTM_H
# include <netinet/in_systm.h>
#endif
])
AC_CHECK_HEADERS(netinet/if_ether.h,,,
[#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
])
AC_CHECK_HEADERS(resolv.h,,,
[#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
])
AC_CHECK_HEADERS(linux/errqueue.h,,,
[#ifdef HAVE_LINUX_TYPES_H
# include <linux/types.h>
#endif
])
fi
AC_CACHE_SAVE
dnl check that in_addr_t is defined
AC_CHECK_TYPE(
[in_addr_t],
[],
[AC_DEFINE(in_addr_t, uint32_t, [Some systems don't define in_addr_t])],
[#include "syshead.h"])
dnl check for basic types
AC_CHECK_TYPE(
[uint8_t],
[],
[AC_DEFINE(uint8_t, unsigned char, [8-bit unsigned type])],
[#include "syshead.h"])
AC_CHECK_TYPE(
[uint16_t],
[],
[AC_DEFINE(uint16_t, unsigned char, [16-bit unsigned type])],
[#include "syshead.h"])
AC_CHECK_TYPE(
[uint32_t],
[],
[AC_DEFINE(uint32_t, unsigned long, [32-bit unsigned type])],
[#include "syshead.h"])
dnl check for IPv6 types
AC_CHECK_TYPE(
[struct tun_pi],
[AC_DEFINE(HAVE_TUN_PI, 1, [struct tun_pi needed for IPv6 support])],
[],
[#include "syshead.h"])
AC_CHECK_TYPE(
[struct iphdr],
[AC_DEFINE(HAVE_IPHDR, 1, [struct iphdr needed for IPv6 support])],
[],
[#include "syshead.h"])
AC_CHECK_TYPE(
[struct iovec],
[AC_DEFINE(HAVE_IOVEC, 1, [struct iovec needed for IPv6 support])],
[],
[#include "syshead.h"])
dnl check for extended socket error types
AC_CHECK_TYPE(
[struct sock_extended_err],
[AC_DEFINE(HAVE_SOCK_EXTENDED_ERR, 1, [struct sock_extended_err needed for extended socket error support])],
[],
[#include "syshead.h"])
AC_CHECK_TYPE(
[struct msghdr],
[AC_DEFINE(HAVE_MSGHDR, 1, [struct msghdr needed for extended socket error support])],
[],
[#include "syshead.h"])
AC_CHECK_TYPE(
[struct cmsghdr],
[AC_DEFINE(HAVE_CMSGHDR, 1, [struct cmsghdr needed for extended socket error support])],
[],
[#include "syshead.h"])
AC_CHECK_TYPE(
[struct in_pktinfo],
[AC_DEFINE(HAVE_IN_PKTINFO, 1, [struct in_pktinfo needed for IP_PKTINFO support])],
[],
[#include "syshead.h"])
AC_CHECK_SIZEOF(unsigned int)
AC_CHECK_SIZEOF(unsigned long)
AC_CACHE_SAVE
AC_CHECK_FUNCS([ctime memset vsnprintf strdup], ,
[AC_MSG_ERROR([Required library function not found])])
AC_CHECK_FUNCS(daemon chroot getpwnam setuid nice system getpid dup dup2 dnl
getpass strerror syslog openlog mlockall getgrnam setgid dnl
setgroups stat flock readv writev time dnl
setsid chdir putenv getpeername unlink dnl
chsize ftruncate execve getpeereid umask)
# Windows use stdcall for winsock so we cannot auto detect these
m4_define([SOCKET_FUNCS], [socket recv recvfrom send sendto listen dnl
accept connect bind select gethostbyname inet_ntoa])
m4_define([SOCKET_OPT_FUNCS], [setsockopt getsockopt getsockname poll])
if test "${WIN32}" = "yes"; then
AC_DEFINE([HAVE_GETTIMEOFDAY], [1], [We fake gettimeofday for win32 at otime.c])
m4_foreach([F], m4_split(SOCKET_FUNCS SOCKET_OPT_FUNCS),
m4_define(UF, [[m4_join([_], [HAVE], m4_toupper(F))]])
AC_DEFINE([UF], [1], [Win32 builtin]))
else
dnl check for other types
AC_TYPE_SIGNAL
dnl Check for libsocket
AC_SEARCH_LIBS(socket, socket)
dnl Check for libnsl
AC_SEARCH_LIBS(inet_ntoa, nsl)
dnl Check for libresolv
AC_SEARCH_LIBS(gethostbyname, resolv nsl)
dnl optional library functions
AC_FUNC_FORK
AC_CHECK_FUNCS(gettimeofday)
AC_CHECK_FUNCS(SOCKET_FUNCS, ,
[AC_MSG_ERROR([Required library function not found])])
AC_CHECK_FUNCS(SOCKET_OPT_FUNCS sendmsg recvmsg)
fi
dnl Required library functions
AC_FUNC_MEMCMP
dnl
dnl Check for res_init
dnl
AC_TRY_LINK([
#include <resolv.h>
], [
res_init ();
], [
AC_MSG_RESULT([res_init DEFINED])
AC_DEFINE([HAVE_RES_INIT], 1, [Indicates if res_init is available])
], [
AC_MSG_RESULT([res_init UNDEFINED])
])
dnl
dnl check libraries
dnl
dnl Checking for a working epoll
AC_CHECKING([for working epoll implementation])
OLDLDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS -Wl,--fatal-warnings"
AC_CHECK_FUNC(epoll_create, AC_DEFINE(HAVE_EPOLL_CREATE, 1, [epoll_create function is defined]))
LDFLAGS="$OLDLDFLAGS"
dnl
dnl check for valgrind tool
dnl
if test "$MEMCHECK" = "valgrind"; then
AC_CHECKING([for valgrind tool and Header files])
AC_CHECK_HEADER(valgrind/memcheck.h,
[
AC_DEFINE(USE_VALGRIND, 1, [Use valgrind memory debugging library])
CFLAGS="-g -fno-inline"
],
[AC_MSG_ERROR([valgrind headers not found.])]
)
fi
dnl
dnl check for pthread library
dnl
if test "$PTHREAD" = "yes"; then
AC_CHECKING([for pthread support])
AC_MSG_RESULT([********* WARNING: pthread support is experimental for OpenVPN 2.0])
ACX_PTHREAD(
[
case "$target" in
*openbsd*)
AC_MSG_RESULT([WARNING: pthread support on OpenBSD is unstable!])
CFLAGS="$CFLAGS -pthread"
;;
esac
LIBS="$PTHREAD_LIBS $LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
CC="$PTHREAD_CC"
AC_DEFINE(USE_PTHREAD, 1, [Use pthread-based multithreading])
],
[
AC_MSG_RESULT([I don't know how to build with pthread support on this platform.])
AC_MSG_ERROR([try ./configure --disable-pthread])
])
fi
dnl
dnl check for dmalloc library
dnl
if test "$MEMCHECK" = "dmalloc"; then
AC_CHECKING([for dmalloc Library and Header files])
AC_CHECK_HEADER(dmalloc.h,
[AC_CHECK_LIB(dmalloc, malloc,
[
if test "$PTHREAD" = "yes"; then
OPENVPN_ADD_LIBS(-ldmallocth)
else
OPENVPN_ADD_LIBS(-ldmalloc)
fi
AC_DEFINE(DMALLOC, 1, [Use dmalloc memory debugging library])
],
[AC_MSG_ERROR([dmalloc library not found.])]
)],
[AC_MSG_ERROR([dmalloc headers not found.])]
)
fi
dnl
dnl Check for dlopen -- first try libc then libdl.
dnl
if test "${WIN32}" != "yes"; then
if test "$PLUGINS" = "yes"; then
AC_CHECKING([for libdl Library and Header files])
AC_CHECK_HEADER(dlfcn.h,
[AC_CHECK_FUNC(dlopen,
[AC_DEFINE(USE_LIBDL, 1, [Use libdl for dynamic library loading])],
[AC_CHECK_LIB(dl, dlopen,
[
OPENVPN_ADD_LIBS(-ldl)
AC_DEFINE(USE_LIBDL, 1, [Use libdl for dynamic library loading])
],
[AC_MSG_RESULT([libdl library not found.])]
)],
)],
[AC_MSG_RESULT([libdl headers not found.])]
)
fi
fi
dnl
dnl Check if LoadLibrary exists on Windows
dnl
if test "${WIN32}" = "yes"; then
if test "$PLUGINS" = "yes"; then
AC_TRY_LINK([
#include <windows.h>
], [
LoadLibrary (NULL);
], [
AC_MSG_RESULT([LoadLibrary DEFINED])
AC_DEFINE(USE_LOAD_LIBRARY, 1, [Use LoadLibrary to load DLLs on Windows])
], [
AC_MSG_RESULT([LoadLibrary UNDEFINED])
])
fi
fi
dnl
dnl check for LZO library
dnl
if test "$LZO" = "yes" && test "$LZO_STUB" = "no"; then
LZO_H=""
AC_CHECKING([for LZO Library and Header files])
AC_CHECK_HEADER(lzo/lzo1x.h,
[ LZO_H="2"
lzolibs="lzo2 lzo"
AC_DEFINE(LZO_HEADER_DIR, 1, [Use lzo/ directory prefix for LZO header files (for LZO 2.0)])
],
[ AC_CHECK_HEADER(lzo1x.h, [ LZO_H="1" ; lzolibs=lzo ]) ]
)
if test -n "$LZO_H"; then
havelzolib=0
for i in $lzolibs ; do
if test $havelzolib = 1 ; then break ; fi
AC_CHECK_LIB($i, lzo1x_1_15_compress,
[
OPENVPN_ADD_LIBS(-l$i)
AC_DEFINE(USE_LZO, 1, [Use LZO compression library])
AC_DEFINE_UNQUOTED(LZO_VERSION_NUM, "$LZO_H", [LZO version number])
havelzolib=1
]
)
done
if test $havelzolib = 0 ; then
AC_MSG_ERROR([LZO headers were found but LZO library was not found])
fi
else
AC_MSG_RESULT([LZO headers were not found])
AC_MSG_RESULT([LZO library available from http://www.oberhumer.com/opensource/lzo/])
AC_MSG_ERROR([Or try ./configure --disable-lzo OR ./configure --enable-lzo-stub])
fi
fi
dnl enable multi-client mode
if test "$LZO_STUB" = "yes"; then
AC_DEFINE(LZO_STUB, 1, [Enable LZO stub capability])
fi
dnl
dnl check for OpenSSL-crypto library
dnl
if test "$CRYPTO" = "yes"; then
AC_CHECKING([for OpenSSL Crypto Library and Header files])
AC_CHECK_HEADER(openssl/evp.h,,
[AC_MSG_ERROR([OpenSSL Crypto headers not found.])])
for lib in crypto eay32; do
AC_CHECK_LIB($lib, EVP_CIPHER_CTX_init,
[
cryptofound=1
OPENVPN_ADD_LIBS(-l$lib)
]
)
done
test -n "$cryptofound" || AC_MSG_ERROR([OpenSSL Crypto library not found.])
AC_MSG_CHECKING([that OpenSSL Library is at least version 0.9.6])
AC_EGREP_CPP(yes,
[
#include <openssl/evp.h>
#if SSLEAY_VERSION_NUMBER >= 0x00906000L
yes
#endif
],
[
AC_MSG_RESULT([yes])
AC_DEFINE(USE_CRYPTO, 1, [Use OpenSSL crypto library])
AC_CHECK_FUNCS(EVP_CIPHER_CTX_set_key_length)
dnl check for OpenSSL crypto acceleration capability
AC_CHECK_HEADERS(openssl/engine.h)
AC_CHECK_FUNCS(ENGINE_load_builtin_engines)
AC_CHECK_FUNCS(ENGINE_register_all_complete)
AC_CHECK_FUNCS(ENGINE_cleanup)
],
[AC_MSG_ERROR([OpenSSL crypto Library is too old.])]
)
dnl
dnl check for OpenSSL-SSL library
dnl
if test "$SSL" = "yes"; then
AC_CHECKING([for OpenSSL SSL Library and Header files])
AC_CHECK_HEADER(openssl/ssl.h,,
[AC_MSG_ERROR([OpenSSL SSL headers not found.])]
)
for lib in ssl ssl32; do
AC_CHECK_LIB($lib, SSL_CTX_new,
[
sslfound=1
OPENVPN_ADD_LIBS(-l$lib)
]
)
done
test -n "${sslfound}" || AC_MSG_ERROR([OpenSSL SSL library not found.])
if test "$MEMCHECK" = "ssl"; then
AC_CHECKING([for Memory Debugging Capabilities in OpenSSL Library])
AC_CHECK_LIB(ssl, CRYPTO_mem_ctrl,
[
AC_DEFINE(CRYPTO_MDEBUG, 1, [Use memory debugging function in OpenSSL])
AC_MSG_RESULT([NOTE: OpenSSL library must be compiled with CRYPTO_MDEBUG])
],
[AC_MSG_ERROR([Memory Debugging function in OpenSSL library not found.])]
)
fi
AC_DEFINE(USE_SSL, 1, [Use OpenSSL SSL library])
fi
fi
dnl enable pkcs11 capability
if test "$PKCS11" = "yes"; then
AC_CHECKING([for pkcs11-helper Library and Header files])
AC_CHECK_HEADER(pkcs11-helper-1.0/pkcs11h-core.h,
[AC_CHECK_LIB(pkcs11-helper, pkcs11h_initialize,
[
AC_DEFINE(USE_PKCS11, 1, [Enable PKCS11 capability])
OPENVPN_ADD_LIBS(-lpkcs11-helper)
],
[AC_MSG_RESULT([pkcs11-helper library not found.])]
)],
[AC_MSG_RESULT([pkcs11-helper headers not found.])]
)
fi
dnl enable multi-client mode
if test "$MULTI" = "yes"; then
AC_DEFINE(ENABLE_CLIENT_SERVER, 1, [Enable client/server capability])
fi
dnl enable client mode only, not server
if test "$MULTI_SERVER" = "no"; then
AC_DEFINE(ENABLE_CLIENT_ONLY, 1, [Enable client capability only])
fi
dnl enable management server capability
if test "$MANAGEMENT" = "yes"; then
AC_DEFINE(ENABLE_MANAGEMENT, 1, [Enable management server capability])
fi
dnl enable socks
if test "$SOCKS" = "yes"; then
AC_DEFINE(ENABLE_SOCKS, 1, [Enable Socks proxy support])
fi
dnl enable HTTP proxy
if test "$HTTP_PROXY" = "yes"; then
AC_DEFINE(ENABLE_HTTP_PROXY, 1, [Enable HTTP proxy support])
fi
dnl compile --multihome option
if test "$MULTIHOME" = "yes"; then
AC_DEFINE(ENABLE_MULTIHOME, 1, [Enable multi-homed UDP server capability])
fi
dnl enable debugging
if test "$DEBUG" = "yes"; then
AC_DEFINE(ENABLE_DEBUG, 1, [Enable debugging support])
fi
dnl enable small size optimizations
if test "$SMALL" = "yes"; then
AC_DEFINE(ENABLE_SMALL, 1, [Enable smaller executable size])
fi
dnl enable --fragment
if test "$FRAGMENT" = "yes"; then
AC_DEFINE(ENABLE_FRAGMENT, 1, [Enable internal fragmentation support])
fi
dnl enable --port-share
if test "$PORT_SHARE" = "yes"; then
AC_DEFINE(ENABLE_PORT_SHARE, 1, [Enable TCP Server port sharing])
fi
dnl enable deferred auth
if test "$DEF_AUTH" = "yes"; then
AC_DEFINE(CONFIGURE_DEF_AUTH, 1, [Enable deferred authentication])
fi
dnl enable internal packet filter
if test "$PF" = "yes"; then
AC_DEFINE(CONFIGURE_PF, 1, [Enable internal packet filter])
fi
dnl enable strict compiler warnings
if test "$STRICT" = "yes"; then
CFLAGS="$CFLAGS -Wall -Wno-unused-parameter -Wno-unused-function"
fi
dnl enable pedantic compiler warnings
if test "$PEDANTIC" = "yes"; then
CFLAGS="$CFLAGS -ansi -pedantic"
fi
dnl enable profiling
if test "$PROFILE" = "yes"; then
CFLAGS="$CFLAGS -pg -DENABLE_PROFILING"
fi
dnl enable strict options check between peers
if test "$STRICT_OPTIONS" = "yes"; then
AC_DEFINE(STRICT_OPTIONS_CHECK, 1, [Enable strict options check between peers])
fi
dnl enable password save
if test "$PASSWORD_SAVE" = "yes"; then
AC_DEFINE(ENABLE_PASSWORD_SAVE, 1, [Allow --askpass and --auth-user-pass passwords to be read from a file])
fi
dnl
dnl check for SELinux library and headers
dnl
if test "$SELINUX" = "yes"; then
AC_CHECKING([for libselinux Library and Header files])
AC_CHECK_HEADER(selinux/selinux.h,
[AC_CHECK_LIB(selinux, setcon,
[
OPENVPN_ADD_LIBS(-lselinux)
AC_DEFINE(HAVE_SETCON, 1, [SELinux support])
],
[AC_MSG_RESULT([SELinux library not found.])]
)],
[AC_MSG_RESULT([SELinux headers not found.])]
)
fi
TAP_ID="PRODUCT_TAP_ID"
TAP_WIN32_MIN_MAJOR="PRODUCT_TAP_WIN32_MIN_MAJOR"
TAP_WIN32_MIN_MINOR="PRODUCT_TAP_WIN32_MIN_MINOR"
AC_DEFINE_UNQUOTED(TAP_ID, "${TAP_ID}", [The TAP-Win32 id defined in tap-win32/SOURCES])
AC_DEFINE_UNQUOTED(TAP_WIN32_MIN_MAJOR, ${TAP_WIN32_MIN_MAJOR}, [The TAP-Win32 version number is defined in tap-win32/SOURCES])
AC_DEFINE_UNQUOTED(TAP_WIN32_MIN_MINOR, ${TAP_WIN32_MIN_MINOR}, [The TAP-Win32 version number is defined in tap-win32/SOURCES])
AC_SUBST(TAP_ID)
AC_SUBST(TAP_WIN32_MIN_MAJOR)
AC_SUBST(TAP_WIN32_MIN_MINOR)
win32datadir="\${datadir}/${PACKAGE}-win32"
AC_SUBST(win32datadir)
AM_CONDITIONAL(WIN32, test "${WIN32}" = "yes")
# workaround for <autoconf-2.60
if test -z "${docdir}"; then
docdir="\$(datadir)/doc/\$(PACKAGE_NAME)"
AC_SUBST([docdir])
fi
if test -z "${htmldir}"; then
htmldir="\$(docdir)"
AC_SUBST([htmldir])
fi
# end workaround
AC_OUTPUT([
Makefile
openvpn.spec
images/Makefile
service-win32/Makefile
install-win32/Makefile
install-win32/settings
])

2
contrib/README Normal file
View file

@ -0,0 +1,2 @@
This directory contains scripts and patches contributed
by users.

View file

@ -0,0 +1,79 @@
--- /etc/init.d/openvpn 2004-05-12 20:30:06.000000000 +0200
+++ openvpn 2004-05-12 20:34:33.000000000 +0200
@@ -58,13 +58,13 @@
# returning success or failure status to caller (James Yonan).
# Location of openvpn binary
-openvpn="/usr/sbin/openvpn"
+openvpn=/usr/sbin/openvpn
# Lockfile
-lock="/var/lock/subsys/openvpn"
+lock=/var/lock/subsys/openvpn
# PID directory
-piddir="/var/run/openvpn"
+piddir=/var/run/openvpn
# Our working directory
work=/etc/openvpn
@@ -106,7 +106,7 @@
if [ -f $lock ]; then
# we were not shut down correctly
- for pidf in `/bin/ls $piddir/*.pid $piddir/*/*.pid 2>/dev/null`; do
+ for pidf in `find $piddir -name "*.pid" 2>/dev/null`; do
if [ -s $pidf ]; then
kill `cat $pidf` >/dev/null 2>&1
fi
@@ -116,12 +116,12 @@
sleep 2
fi
- rm -f $piddir/*.pid $piddir/*/*.pid
+ find $piddir -name "*.pid"|xargs rm -f
# Start every .conf in $work and run .sh if exists
errors=0
successes=0
- for c in `/bin/ls *.conf */*.conf 2>/dev/null`; do
+ for c in `find * -name "*.conf" 2>/dev/null`; do
bn=${c%%.conf}
if [ -f "$bn.sh" ]; then
. $bn.sh
@@ -147,7 +147,7 @@
;;
stop)
echo -n $"Shutting down openvpn: "
- for pidf in `/bin/ls $piddir/*.pid $piddir/*/*.pid 2>/dev/null`; do
+ for pidf in `find $piddir -name "*.pid" 2>/dev/null`; do
if [ -s $pidf ]; then
kill `cat $pidf` >/dev/null 2>&1
fi
@@ -163,7 +163,7 @@
;;
reload)
if [ -f $lock ]; then
- for pidf in `/bin/ls $piddir/*.pid $piddir/*/*.pid 2>/dev/null`; do
+ for pidf in `find $piddir -name "*.pid" 2>/dev/null`; do
if [ -s $pidf ]; then
kill -HUP `cat $pidf` >/dev/null 2>&1
fi
@@ -175,7 +175,7 @@
;;
reopen)
if [ -f $lock ]; then
- for pidf in `/bin/ls $piddir/*.pid $piddir/*/*.pid 2>/dev/null`; do
+ for pidf in `find $piddir -name "*.pid" 2>/dev/null`; do
if [ -s $pidf ]; then
kill -USR1 `cat $pidf` >/dev/null 2>&1
fi
@@ -195,7 +195,7 @@
;;
status)
if [ -f $lock ]; then
- for pidf in `/bin/ls $piddir/*.pid $piddir/*/*.pid 2>/dev/null`; do
+ for pidf in `find $piddir -name "*.pid" 2>/dev/null`; do
if [ -s $pidf ]; then
kill -USR2 `cat $pidf` >/dev/null 2>&1
fi

View file

@ -0,0 +1,44 @@
OpenVPN fwmark Routing
Sean Reifschneider, <jafo@tummy.com>
Thursday November 27, 2003
==========================
These scripts can be used with OpenVPN up and down scripts to set up
routing on a Linux system such that the VPN traffic is sent via normal
network connectivity, but other traffic to that network runs over the VPN.
The idea is to allow encryption of data to the network the remote host is
on, without interfering with the VPN traffic. You can't simply add a route
to the remote network, becaues that will cause the VPN traffic to also try
to run over the VPN, and breaks the VPN.
These scripts use the Linux "fwmark" iptables rules to specify routing
based not only on IP address, but also by port and protocol. This allows
you to effectively say "if the packet is to this IP address on this port
using this protocol, then use the normal default gateway, otherwise use the
VPN gateway.
This is set up on the client VPN system, not the VPN server. These scripts
also set up all ICMP echo-responses to run across the VPN. You can
comment the lines in the scripts to disable this, but I find this useful
at coffee shops which have networks that block ICMP.
To configure this, you need to set up these scripts as your up and down
scripts in the config file. You will need to set these values in the
config file:
up /etc/openvpn/fwmarkroute.up
down /etc/openvpn/fwmarkroute.down
up-restart
up-delay
setenv remote_netmask_bits 24
Note: For this to work, you can't set the "user" or "group" config options,
because then the scripts will not run as root.
The last setting allows you to control the size of the network the remote
system is on. The remote end has to be set up to route, probably with
masquerading or NAT. The network this netmask relates to is calculated
using the value of "remote" in the conf file.
Sean

View file

@ -0,0 +1,22 @@
#!/bin/sh
#
# Bring down vpn routing.
# calculate the network address
remote_network=`ipcalc -n "$remote"/"$remote_netmask_bits"`
remote_network="${remote_network#*=}"
# clear routing via VPN
ip route del "$remote_network"/"$remote_netmask_bits" via "$5" table vpn.out
ip route del table vpnonly.out via "$5"
iptables -D OUTPUT -t mangle -p "$proto" \
-d "$remote_network"/"$remote_netmask_bits" \
--dport "$remote_port" -j ACCEPT
iptables -D OUTPUT -t mangle -d "$remote" -j MARK --set-mark 2
# undo the ICMP ping tunneling
iptables -D OUTPUT -t mangle --protocol icmp --icmp-type echo-request \
-j MARK --set-mark 3
# flush route cache
ip route flush cache

View file

@ -0,0 +1,49 @@
#!/bin/sh
#
# Bring up vpn routing.
# calculate the network address
remote_network=`ipcalc -n "$remote"/"$remote_netmask_bits"`
remote_network="${remote_network#*=}"
# add the stuff that doesn't change if it's not already there
grep -q '^202 ' /etc/iproute2/rt_tables
if [ "$?" -ne 0 ]
then
echo 202 vpn.out >> /etc/iproute2/rt_tables
fi
grep -q '^203 ' /etc/iproute2/rt_tables
if [ "$?" -ne 0 ]
then
echo 203 vpnonly.out >> /etc/iproute2/rt_tables
fi
ip rule ls | grep -q 'lookup vpn.out *$'
if [ "$?" -ne 0 ]
then
ip rule add fwmark 2 table vpn.out
fi
ip rule ls | grep -q 'lookup vpnonly.out *$'
if [ "$?" -ne 0 ]
then
ip rule add fwmark 3 table vpnonly.out
fi
# route VPN traffic using the normal table
iptables -A OUTPUT -t mangle -p "$proto" -d "$remote" --dport "$remote_port" \
-j ACCEPT
# route all other traffic to that host via VPN
iptables -A OUTPUT -t mangle -d "$remote_network"/"$remote_netmask_bits" \
-j MARK --set-mark 2
# route all ICMP pings over the VPN
iptables -A OUTPUT -t mangle --protocol icmp --icmp-type echo-request \
-j MARK --set-mark 3
# NAT traffic going over the VPN, so it doesn't have an unknown address
iptables -t nat -A POSTROUTING -o "$1" -j SNAT --to-source "$4"
# add routing commands
ip route add "$remote_network"/"$remote_netmask_bits" via "$5" table vpn.out
ip route add table vpnonly.out via "$5"
ip route flush cache

View file

@ -0,0 +1,76 @@
#!/bin/bash
# Copyright (c) 2005-2010 OpenVPN Technologies, Inc.
# Licensed under the GPL version 2
# First version by Jesse Adelman
# someone at boldandbusted dink com
# http://www.boldandbusted.com/
# PURPOSE: This script automatically removes the /etc/resolv.conf entries previously
# set by the companion script "client.up".
# INSTALL NOTES:
# Place this in /etc/openvpn/client.down
# Then, add the following to your /etc/openvpn/<clientconfig>.conf:
# client
# pull dhcp-options
# up /etc/openvpn/client.up
# down /etc/openvpn/client.down
# Next, "chmod a+x /etc/openvpn/client.down"
# USAGE NOTES:
# Note that this script is best served with the companion "client.up"
# script.
# Only tested on Gentoo Linux 2005.0 with OpenVPN 2.0
# It should work with any GNU/Linux with /etc/resolv.conf
# This runs with the context of the OpenVPN UID/GID
# at the time of execution. This generally means that
# the client "up" script will run fine, but the "down" script
# will require the use of the OpenVPN "down-root" plugin
# which is in the plugins/ directory of the OpenVPN source tree
# A horrid work around, from a security perspective,
# is to run OpenVPN as root. THIS IS NOT RECOMMENDED. You have
# been WARNED.
# init variables
i=1
j=1
unset fopt
unset dns
unset opt
# Convert ENVs to an array
while fopt=foreign_option_$i; [ -n "${!fopt}" ]; do
{
opt[i-1]=${!fopt}
case ${opt[i-1]} in
*DOMAIN* ) domain=`echo ${opt[i-1]} | \
sed -e 's/dhcp-option DOMAIN //g'` ;;
*DNS* ) dns[j-1]=`echo ${opt[i-1]} | \
sed -e 's/dhcp-option DNS //g'`
let j++ ;;
esac
let i++
}
done
# Now, do the work
if [ -n "${dns[*]}" ]; then
for i in "${dns[@]}"; do
sed -i -e "/nameserver ${i}/D" /etc/resolv.conf || die
done
fi
if [ -n "${domain}" ]; then
sed -i -e "/search ${domain}/D" /etc/resolv.conf || die
fi
# all done...
exit 0

View file

@ -0,0 +1,75 @@
#!/bin/bash
# Copyright (c) 2005-2010 OpenVPN Technologies, Inc.
# Licensed under the GPL version 2
# First version by Jesse Adelman
# someone at boldandbusted dink com
# http://www.boldandbusted.com/
# PURPOSE: This script automatically sets the proper /etc/resolv.conf entries
# as pulled down from an OpenVPN server.
# INSTALL NOTES:
# Place this in /etc/openvpn/client.up
# Then, add the following to your /etc/openvpn/<clientconfig>.conf:
# client
# pull dhcp-options
# up /etc/openvpn/client.up
# Next, "chmod a+x /etc/openvpn/client.up"
# USAGE NOTES:
# Note that this script is best served with the companion "client.down"
# script.
# Only tested on Gentoo Linux 2005.0 with OpenVPN 2.0
# It should work with any GNU/Linux with /etc/resolv.conf
# This runs with the context of the OpenVPN UID/GID
# at the time of execution. This generally means that
# the client "up" script will run fine, but the "down" script
# will require the use of the OpenVPN "down-root" plugin
# which is in the plugins/ directory of the OpenVPN source tree
# A horrid work around, from a security perspective,
# is to run OpenVPN as root. THIS IS NOT RECOMMENDED. You have
# been WARNED.
# init variables
i=1
j=1
unset fopt
unset dns
unset opt
# Convert ENVs to an array
while fopt=foreign_option_$i; [ -n "${!fopt}" ]; do
{
opt[i-1]=${!fopt}
case ${opt[i-1]} in
*DOMAIN* ) domain=`echo ${opt[i-1]} | \
sed -e 's/dhcp-option DOMAIN //g'` ;;
*DNS* ) dns[j-1]=`echo ${opt[i-1]} | \
sed -e 's/dhcp-option DNS //g'`
let j++ ;;
esac
let i++
}
done
# Now, do the work
if [ -n "${dns[*]}" ]; then
for i in "${dns[@]}"; do
sed -i -e "1,1 i nameserver ${i}" /etc/resolv.conf || die
done
fi
if [ -n "${domain}" ]; then
sed -i -e "$j,1 i search ${domain}" /etc/resolv.conf || die
fi
# all done...
exit 0

1844
crypto.c Normal file

File diff suppressed because it is too large Load diff

421
crypto.h Normal file
View file

@ -0,0 +1,421 @@
/*
* OpenVPN -- An application to securely tunnel IP networks
* over a single TCP/UDP port, with support for SSL/TLS-based
* session authentication and key exchange,
* packet encryption, packet authentication, and
* packet compression.
*
* Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* 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 (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef CRYPTO_H
#define CRYPTO_H
#ifdef USE_CRYPTO
#define ALLOW_NON_CBC_CIPHERS
/*
* Does our OpenSSL library support crypto hardware acceleration?
*/
#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_LOAD_BUILTIN_ENGINES) && defined(HAVE_ENGINE_REGISTER_ALL_COMPLETE) && defined(HAVE_ENGINE_CLEANUP)
#define CRYPTO_ENGINE 1
#else
#define CRYPTO_ENGINE 0
#endif
#include <openssl/objects.h>
#include <openssl/rand.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/des.h>
#include <openssl/md5.h>
#if NTLM
#include <openssl/md4.h>
#endif
#include <openssl/sha.h>
#include <openssl/err.h>
#if CRYPTO_ENGINE
#include <openssl/engine.h>
#endif
#if SSLEAY_VERSION_NUMBER >= 0x00907000L
#include <openssl/des_old.h>
#endif
#include "basic.h"
#include "buffer.h"
#include "packet_id.h"
#include "mtu.h"
/*
* Workarounds for incompatibilites between OpenSSL libraries.
* Right now we accept OpenSSL libraries from 0.9.5 to 0.9.7.
*/
#if SSLEAY_VERSION_NUMBER < 0x00907000L
/* Workaround: EVP_CIPHER_mode is defined wrong in OpenSSL 0.9.6 but is fixed in 0.9.7 */
#undef EVP_CIPHER_mode
#define EVP_CIPHER_mode(e) (((e)->flags) & EVP_CIPH_MODE)
#define DES_cblock des_cblock
#define DES_is_weak_key des_is_weak_key
#define DES_check_key_parity des_check_key_parity
#define DES_set_odd_parity des_set_odd_parity
#define HMAC_CTX_init(ctx) CLEAR (*ctx)
#define HMAC_Init_ex(ctx,sec,len,md,impl) HMAC_Init(ctx, sec, len, md)
#define HMAC_CTX_cleanup(ctx) HMAC_cleanup(ctx)
#define EVP_MD_CTX_cleanup(md) CLEAR (*md)
#define INFO_CALLBACK_SSL_CONST
#endif
#ifndef INFO_CALLBACK_SSL_CONST
#define INFO_CALLBACK_SSL_CONST const
#endif
#if SSLEAY_VERSION_NUMBER < 0x00906000
#undef EVP_CIPHER_mode
#define EVP_CIPHER_mode(x) 1
#define EVP_CIPHER_CTX_mode(x) 1
#define EVP_CIPHER_flags(x) 0
#define EVP_CIPH_CBC_MODE 1
#define EVP_CIPH_CFB_MODE 0
#define EVP_CIPH_OFB_MODE 0
#define EVP_CIPH_VARIABLE_LENGTH 0
#define OPENSSL_malloc(x) malloc(x)
#define OPENSSL_free(x) free(x)
static inline int
EVP_CipherInit_ov (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, uint8_t *key, uint8_t *iv, int enc)
{
EVP_CipherInit (ctx, type, key, iv, enc);
return 1;
}
static inline int
EVP_CipherUpdate_ov (EVP_CIPHER_CTX *ctx, uint8_t *out, int *outl, uint8_t *in, int inl)
{
EVP_CipherUpdate (ctx, out, outl, in, inl);
return 1;
}
static inline bool
cipher_ok (const char* name)
{
const int i = strlen (name) - 4;
if (i >= 0)
return !strcmp (name + i, "-CBC");
else
return false;
}
#else
static inline int
EVP_CipherInit_ov (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, uint8_t *key, uint8_t *iv, int enc)
{
return EVP_CipherInit (ctx, type, key, iv, enc);
}
static inline int
EVP_CipherUpdate_ov (EVP_CIPHER_CTX *ctx, uint8_t *out, int *outl, uint8_t *in, int inl)
{
return EVP_CipherUpdate (ctx, out, outl, in, inl);
}
static inline bool
cipher_ok (const char* name)
{
return true;
}
#endif
#if SSLEAY_VERSION_NUMBER < 0x0090581f
#undef DES_check_key_parity
#define DES_check_key_parity(x) 1
#endif
#ifndef EVP_CIPHER_name
#define EVP_CIPHER_name(e) OBJ_nid2sn(EVP_CIPHER_nid(e))
#endif
#ifndef EVP_MD_name
#define EVP_MD_name(e) OBJ_nid2sn(EVP_MD_type(e))
#endif
/*
* Max size in bytes of any cipher key that might conceivably be used.
*
* This value is checked at compile time in crypto.c to make sure
* it is always at least EVP_MAX_KEY_LENGTH.
*
* We define our own value, since this parameter
* is used to control the size of static key files.
* If the OpenSSL library increases EVP_MAX_KEY_LENGTH,
* we don't want our key files to be suddenly rendered
* unusable.
*/
#define MAX_CIPHER_KEY_LENGTH 64
/*
* Max size in bytes of any HMAC key that might conceivably be used.
*
* This value is checked at compile time in crypto.c to make sure
* it is always at least EVP_MAX_MD_SIZE. We define our own value
* for the same reason as above.
*/
#define MAX_HMAC_KEY_LENGTH 64
/*
* Defines a key type and key length for both cipher and HMAC.
*/
struct key_type
{
uint8_t cipher_length;
uint8_t hmac_length;
const EVP_CIPHER *cipher;
const EVP_MD *digest;
};
/*
* A random key.
*/
struct key
{
uint8_t cipher[MAX_CIPHER_KEY_LENGTH];
uint8_t hmac[MAX_HMAC_KEY_LENGTH];
};
#define KEY_DIRECTION_BIDIRECTIONAL 0 /* same keys for both directions */
#define KEY_DIRECTION_NORMAL 1 /* encrypt with keys[0], decrypt with keys[1] */
#define KEY_DIRECTION_INVERSE 2 /* encrypt with keys[1], decrypt with keys[0] */
/*
* Dual random keys (for encrypt/decrypt)
*/
struct key2
{
int n;
struct key keys[2];
};
/*
* Used for controlling bidirectional keys
* vs. a separate key for each direction.
*/
struct key_direction_state
{
int out_key;
int in_key;
int need_keys;
};
/*
* A key context for cipher and/or HMAC.
*/
struct key_ctx
{
EVP_CIPHER_CTX *cipher;
HMAC_CTX *hmac;
};
/*
* Cipher/HMAC key context for both sending and receiving
* directions.
*/
struct key_ctx_bi
{
struct key_ctx encrypt;
struct key_ctx decrypt;
};
/*
* Options for encrypt/decrypt.
*/
struct crypto_options
{
struct key_ctx_bi *key_ctx_bi;
struct packet_id *packet_id;
struct packet_id_persist *pid_persist;
# define CO_PACKET_ID_LONG_FORM (1<<0)
# define CO_USE_IV (1<<1)
# define CO_IGNORE_PACKET_ID (1<<2)
# define CO_MUTE_REPLAY_WARNINGS (1<<3)
unsigned int flags;
};
void init_key_type (struct key_type *kt, const char *ciphername,
bool ciphername_defined, const char *authname,
bool authname_defined, int keysize,
bool cfb_ofb_allowed, bool warn);
#define RKF_MUST_SUCCEED (1<<0)
#define RKF_INLINE (1<<1)
void read_key_file (struct key2 *key2, const char *file, const unsigned int flags);
int write_key_file (const int nkeys, const char *filename);
int read_passphrase_hash (const char *passphrase_file,
const EVP_MD *digest,
uint8_t *output,
int len);
void generate_key_random (struct key *key, const struct key_type *kt);
void check_replay_iv_consistency(const struct key_type *kt, bool packet_id, bool use_iv);
bool check_key (struct key *key, const struct key_type *kt);
void fixup_key (struct key *key, const struct key_type *kt);
bool write_key (const struct key *key, const struct key_type *kt,
struct buffer *buf);
int read_key (struct key *key, const struct key_type *kt, struct buffer *buf);
bool cfb_ofb_mode (const struct key_type* kt);
const char *kt_cipher_name (const struct key_type *kt);
const char *kt_digest_name (const struct key_type *kt);
int kt_key_size (const struct key_type *kt);
/* enc parameter in init_key_ctx */
#define DO_ENCRYPT 1
#define DO_DECRYPT 0
void init_key_ctx (struct key_ctx *ctx, struct key *key,
const struct key_type *kt, int enc,
const char *prefix);
void free_key_ctx (struct key_ctx *ctx);
void free_key_ctx_bi (struct key_ctx_bi *ctx);
void openvpn_encrypt (struct buffer *buf, struct buffer work,
const struct crypto_options *opt,
const struct frame* frame);
bool openvpn_decrypt (struct buffer *buf, struct buffer work,
const struct crypto_options *opt,
const struct frame* frame);
void crypto_adjust_frame_parameters(struct frame *frame,
const struct key_type* kt,
bool cipher_defined,
bool use_iv,
bool packet_id,
bool packet_id_long_form);
#define NONCE_SECRET_LEN_MIN 16
#define NONCE_SECRET_LEN_MAX 64
void prng_init (const char *md_name, const int nonce_secret_len_parm);
void prng_bytes (uint8_t *output, int len);
void prng_uninit ();
void test_crypto (const struct crypto_options *co, struct frame* f);
const char *md5sum(uint8_t *buf, int len, int n_print_chars, struct gc_arena *gc);
void show_available_ciphers (void);
void show_available_digests (void);
void show_available_engines (void);
void init_crypto_lib_engine (const char *engine_name);
void init_crypto_lib (void);
void uninit_crypto_lib (void);
/* key direction functions */
void key_direction_state_init (struct key_direction_state *kds, int key_direction);
void verify_fix_key2 (struct key2 *key2, const struct key_type *kt, const char *shared_secret_file);
void must_have_n_keys (const char *filename, const char *option, const struct key2 *key2, int n);
int ascii2keydirection (int msglevel, const char *str);
const char *keydirection2ascii (int kd, bool remote);
/* print keys */
void key2_print (const struct key2* k,
const struct key_type *kt,
const char* prefix0,
const char* prefix1);
/* memory debugging */
void openssl_dmalloc_init (void);
#ifdef USE_SSL
#define GHK_INLINE (1<<0)
void get_tls_handshake_key (const struct key_type *key_type,
struct key_ctx_bi *ctx,
const char *passphrase_file,
const int key_direction,
const unsigned int flags);
#else
void init_ssl_lib (void);
void free_ssl_lib (void);
#endif /* USE_SSL */
/*
* Inline functions
*/
static inline bool
key_ctx_bi_defined(const struct key_ctx_bi* key)
{
return key->encrypt.cipher || key->encrypt.hmac || key->decrypt.cipher || key->decrypt.hmac;
}
/*
* md5 functions
*/
struct md5_state {
MD5_CTX ctx;
};
struct md5_digest {
uint8_t digest [MD5_DIGEST_LENGTH];
};
void md5_state_init (struct md5_state *s);
void md5_state_update (struct md5_state *s, void *data, size_t len);
void md5_state_final (struct md5_state *s, struct md5_digest *out);
void md5_digest_clear (struct md5_digest *digest);
bool md5_digest_defined (const struct md5_digest *digest);
bool md5_digest_equal (const struct md5_digest *d1, const struct md5_digest *d2);
#endif /* USE_CRYPTO */
#endif /* CRYPTO_H */

474
cryptoapi.c Normal file
View file

@ -0,0 +1,474 @@
/*
* Copyright (c) 2004 Peter 'Luna' Runestig <peter@runestig.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modifi-
* cation, are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright no-
* tice, this list of conditions and the following disclaimer in the do-
* cumentation and/or other materials provided with the distribution.
*
* o The names of the contributors may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LI-
* ABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUEN-
* TIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEV-
* ER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABI-
* LITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "syshead.h"
#if defined(WIN32) && defined(USE_CRYPTO) && defined(USE_SSL)
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <windows.h>
#include <wincrypt.h>
#include <stdio.h>
#include <ctype.h>
#include <assert.h>
#ifdef __MINGW32_VERSION
/* MinGW w32api is incomplete when it comes to CryptoAPI, as per version 3.1
* anyway. This is a hack around that problem. */
#define CALG_SSL3_SHAMD5 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SSL3SHAMD5)
#define CERT_SYSTEM_STORE_LOCATION_SHIFT 16
#define CERT_SYSTEM_STORE_CURRENT_USER_ID 1
#define CERT_SYSTEM_STORE_CURRENT_USER (CERT_SYSTEM_STORE_CURRENT_USER_ID << CERT_SYSTEM_STORE_LOCATION_SHIFT)
#define CERT_STORE_READONLY_FLAG 0x00008000
#define CERT_STORE_OPEN_EXISTING_FLAG 0x00004000
#define CRYPT_ACQUIRE_COMPARE_KEY_FLAG 0x00000004
static HINSTANCE crypt32dll = NULL;
static BOOL WINAPI (*OpenVPNCryptAcquireCertificatePrivateKey) (PCCERT_CONTEXT pCert, DWORD dwFlags,
void *pvReserved, HCRYPTPROV *phCryptProv, DWORD *pdwKeySpec, BOOL *pfCallerFreeProv) = NULL;
#else
#define OpenVPNCryptAcquireCertificatePrivateKey CryptAcquireCertificatePrivateKey
#endif
/* Size of an SSL signature: MD5+SHA1 */
#define SSL_SIG_LENGTH 36
/* try to funnel any Windows/CryptoAPI error messages to OpenSSL ERR_... */
#define ERR_LIB_CRYPTOAPI (ERR_LIB_USER + 69) /* 69 is just a number... */
#define CRYPTOAPIerr(f) err_put_ms_error(GetLastError(), (f), __FILE__, __LINE__)
#define CRYPTOAPI_F_CERT_OPEN_SYSTEM_STORE 100
#define CRYPTOAPI_F_CERT_FIND_CERTIFICATE_IN_STORE 101
#define CRYPTOAPI_F_CRYPT_ACQUIRE_CERTIFICATE_PRIVATE_KEY 102
#define CRYPTOAPI_F_CRYPT_CREATE_HASH 103
#define CRYPTOAPI_F_CRYPT_GET_HASH_PARAM 104
#define CRYPTOAPI_F_CRYPT_SET_HASH_PARAM 105
#define CRYPTOAPI_F_CRYPT_SIGN_HASH 106
#define CRYPTOAPI_F_LOAD_LIBRARY 107
#define CRYPTOAPI_F_GET_PROC_ADDRESS 108
static ERR_STRING_DATA CRYPTOAPI_str_functs[] = {
{ ERR_PACK(ERR_LIB_CRYPTOAPI, 0, 0), "microsoft cryptoapi"},
{ ERR_PACK(0, CRYPTOAPI_F_CERT_OPEN_SYSTEM_STORE, 0), "CertOpenSystemStore" },
{ ERR_PACK(0, CRYPTOAPI_F_CERT_FIND_CERTIFICATE_IN_STORE, 0), "CertFindCertificateInStore" },
{ ERR_PACK(0, CRYPTOAPI_F_CRYPT_ACQUIRE_CERTIFICATE_PRIVATE_KEY, 0), "CryptAcquireCertificatePrivateKey" },
{ ERR_PACK(0, CRYPTOAPI_F_CRYPT_CREATE_HASH, 0), "CryptCreateHash" },
{ ERR_PACK(0, CRYPTOAPI_F_CRYPT_GET_HASH_PARAM, 0), "CryptGetHashParam" },
{ ERR_PACK(0, CRYPTOAPI_F_CRYPT_SET_HASH_PARAM, 0), "CryptSetHashParam" },
{ ERR_PACK(0, CRYPTOAPI_F_CRYPT_SIGN_HASH, 0), "CryptSignHash" },
{ ERR_PACK(0, CRYPTOAPI_F_LOAD_LIBRARY, 0), "LoadLibrary" },
{ ERR_PACK(0, CRYPTOAPI_F_GET_PROC_ADDRESS, 0), "GetProcAddress" },
{ 0, NULL }
};
typedef struct _CAPI_DATA {
const CERT_CONTEXT *cert_context;
HCRYPTPROV crypt_prov;
DWORD key_spec;
BOOL free_crypt_prov;
} CAPI_DATA;
static char *ms_error_text(DWORD ms_err)
{
LPVOID lpMsgBuf = NULL;
char *rv = NULL;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, ms_err,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
(LPTSTR) &lpMsgBuf, 0, NULL);
if (lpMsgBuf) {
char *p;
rv = strdup(lpMsgBuf);
LocalFree(lpMsgBuf);
/* trim to the left */
if (rv)
for (p = rv + strlen(rv) - 1; p >= rv; p--) {
if (isspace(*p))
*p = '\0';
else
break;
}
}
return rv;
}
static void err_put_ms_error(DWORD ms_err, int func, const char *file, int line)
{
static int init = 0;
# define ERR_MAP_SZ 16
static struct {
int err;
DWORD ms_err; /* I don't think we get more than 16 *different* errors */
} err_map[ERR_MAP_SZ]; /* in here, before we give up the whole thing... */
int i;
if (ms_err == 0)
/* 0 is not an error */
return;
if (!init) {
ERR_load_strings(ERR_LIB_CRYPTOAPI, CRYPTOAPI_str_functs);
memset(&err_map, 0, sizeof(err_map));
init++;
}
/* since MS error codes are 32 bit, and the ones in the ERR_... system is
* only 12, we must have a mapping table between them. */
for (i = 0; i < ERR_MAP_SZ; i++) {
if (err_map[i].ms_err == ms_err) {
ERR_PUT_error(ERR_LIB_CRYPTOAPI, func, err_map[i].err, file, line);
break;
} else if (err_map[i].ms_err == 0 ) {
/* end of table, add new entry */
ERR_STRING_DATA *esd = calloc(2, sizeof(*esd));
if (esd == NULL)
break;
err_map[i].ms_err = ms_err;
err_map[i].err = esd->error = i + 100;
esd->string = ms_error_text(ms_err);
ERR_load_strings(ERR_LIB_CRYPTOAPI, esd);
ERR_PUT_error(ERR_LIB_CRYPTOAPI, func, err_map[i].err, file, line);
break;
}
}
}
/* encrypt */
static int rsa_pub_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)
{
/* I haven't been able to trigger this one, but I want to know if it happens... */
assert(0);
return 0;
}
/* verify arbitrary data */
static int rsa_pub_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)
{
/* I haven't been able to trigger this one, but I want to know if it happens... */
assert(0);
return 0;
}
/* sign arbitrary data */
static int rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)
{
CAPI_DATA *cd = (CAPI_DATA *) rsa->meth->app_data;
HCRYPTHASH hash;
DWORD hash_size, len, i;
unsigned char *buf;
if (cd == NULL) {
RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (padding != RSA_PKCS1_PADDING) {
/* AFAICS, CryptSignHash() *always* uses PKCS1 padding. */
RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
return 0;
}
/* Unfortunately, there is no "CryptSign()" function in CryptoAPI, that would
* be way to straightforward for M$, I guess... So we have to do it this
* tricky way instead, by creating a "Hash", and load the already-made hash
* from 'from' into it. */
/* For now, we only support NID_md5_sha1 */
if (flen != SSL_SIG_LENGTH) {
RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_INVALID_MESSAGE_LENGTH);
return 0;
}
if (!CryptCreateHash(cd->crypt_prov, CALG_SSL3_SHAMD5, 0, 0, &hash)) {
CRYPTOAPIerr(CRYPTOAPI_F_CRYPT_CREATE_HASH);
return 0;
}
len = sizeof(hash_size);
if (!CryptGetHashParam(hash, HP_HASHSIZE, (BYTE *) &hash_size, &len, 0)) {
CRYPTOAPIerr(CRYPTOAPI_F_CRYPT_GET_HASH_PARAM);
CryptDestroyHash(hash);
return 0;
}
if ((int) hash_size != flen) {
RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_INVALID_MESSAGE_LENGTH);
CryptDestroyHash(hash);
return 0;
}
if (!CryptSetHashParam(hash, HP_HASHVAL, (BYTE * ) from, 0)) {
CRYPTOAPIerr(CRYPTOAPI_F_CRYPT_SET_HASH_PARAM);
CryptDestroyHash(hash);
return 0;
}
len = RSA_size(rsa);
buf = malloc(len);
if (buf == NULL) {
RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE);
CryptDestroyHash(hash);
return 0;
}
if (!CryptSignHash(hash, cd->key_spec, NULL, 0, buf, &len)) {
CRYPTOAPIerr(CRYPTOAPI_F_CRYPT_SIGN_HASH);
CryptDestroyHash(hash);
free(buf);
return 0;
}
/* and now, we have to reverse the byte-order in the result from CryptSignHash()... */
for (i = 0; i < len; i++)
to[i] = buf[len - i - 1];
free(buf);
CryptDestroyHash(hash);
return len;
}
/* decrypt */
static int rsa_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)
{
/* I haven't been able to trigger this one, but I want to know if it happens... */
assert(0);
return 0;
}
/* called at RSA_new */
static int init(RSA *rsa)
{
return 0;
}
/* called at RSA_free */
static int finish(RSA *rsa)
{
CAPI_DATA *cd = (CAPI_DATA *) rsa->meth->app_data;
if (cd == NULL)
return 0;
if (cd->crypt_prov && cd->free_crypt_prov)
CryptReleaseContext(cd->crypt_prov, 0);
if (cd->cert_context)
CertFreeCertificateContext(cd->cert_context);
free(rsa->meth->app_data);
free((char *) rsa->meth);
rsa->meth = NULL;
return 1;
}
static const CERT_CONTEXT *find_certificate_in_store(const char *cert_prop, HCERTSTORE cert_store)
{
/* Find, and use, the desired certificate from the store. The
* 'cert_prop' certificate search string can look like this:
* SUBJ:<certificate substring to match>
* THUMB:<certificate thumbprint hex value>, e.g.
* THUMB:f6 49 24 41 01 b4 fb 44 0c ce f4 36 ae d0 c4 c9 df 7a b6 28
*/
const CERT_CONTEXT *rv = NULL;
if (!strncmp(cert_prop, "SUBJ:", 5)) {
/* skip the tag */
cert_prop += 5;
rv = CertFindCertificateInStore(cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
0, CERT_FIND_SUBJECT_STR_A, cert_prop, NULL);
} else if (!strncmp(cert_prop, "THUMB:", 6)) {
unsigned char hash[255];
char *p;
int i, x = 0;
CRYPT_HASH_BLOB blob;
/* skip the tag */
cert_prop += 6;
for (p = (char *) cert_prop, i = 0; *p && i < sizeof(hash); i++) {
if (*p >= '0' && *p <= '9')
x = (*p - '0') << 4;
else if (*p >= 'A' && *p <= 'F')
x = (*p - 'A' + 10) << 4;
else if (*p >= 'a' && *p <= 'f')
x = (*p - 'a' + 10) << 4;
if (!*++p) /* unexpected end of string */
break;
if (*p >= '0' && *p <= '9')
x += *p - '0';
else if (*p >= 'A' && *p <= 'F')
x += *p - 'A' + 10;
else if (*p >= 'a' && *p <= 'f')
x += *p - 'a' + 10;
hash[i] = x;
/* skip any space(s) between hex numbers */
for (p++; *p && *p == ' '; p++);
}
blob.cbData = i;
blob.pbData = (unsigned char *) &hash;
rv = CertFindCertificateInStore(cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
0, CERT_FIND_HASH, &blob, NULL);
}
return rv;
}
int SSL_CTX_use_CryptoAPI_certificate(SSL_CTX *ssl_ctx, const char *cert_prop)
{
HCERTSTORE cs;
X509 *cert = NULL;
RSA *rsa = NULL, *pub_rsa;
CAPI_DATA *cd = calloc(1, sizeof(*cd));
RSA_METHOD *my_rsa_method = calloc(1, sizeof(*my_rsa_method));
if (cd == NULL || my_rsa_method == NULL) {
SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_MALLOC_FAILURE);
goto err;
}
/* search CURRENT_USER first, then LOCAL_MACHINE */
cs = CertOpenStore((LPCSTR) CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER |
CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, L"MY");
if (cs == NULL) {
CRYPTOAPIerr(CRYPTOAPI_F_CERT_OPEN_SYSTEM_STORE);
goto err;
}
cd->cert_context = find_certificate_in_store(cert_prop, cs);
CertCloseStore(cs, 0);
if (!cd->cert_context) {
cs = CertOpenStore((LPCSTR) CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_LOCAL_MACHINE |
CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, L"MY");
if (cs == NULL) {
CRYPTOAPIerr(CRYPTOAPI_F_CERT_OPEN_SYSTEM_STORE);
goto err;
}
cd->cert_context = find_certificate_in_store(cert_prop, cs);
CertCloseStore(cs, 0);
if (cd->cert_context == NULL) {
CRYPTOAPIerr(CRYPTOAPI_F_CERT_FIND_CERTIFICATE_IN_STORE);
goto err;
}
}
/* cert_context->pbCertEncoded is the cert X509 DER encoded. */
cert = d2i_X509(NULL, (const unsigned char **) &cd->cert_context->pbCertEncoded,
cd->cert_context->cbCertEncoded);
if (cert == NULL) {
SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_ASN1_LIB);
goto err;
}
/* set up stuff to use the private key */
#ifdef __MINGW32_VERSION
/* MinGW w32api is incomplete when it comes to CryptoAPI, as per version 3.1
* anyway. This is a hack around that problem. */
if (crypt32dll == NULL) {
crypt32dll = LoadLibrary("crypt32");
if (crypt32dll == NULL) {
CRYPTOAPIerr(CRYPTOAPI_F_LOAD_LIBRARY);
goto err;
}
}
if (OpenVPNCryptAcquireCertificatePrivateKey == NULL) {
OpenVPNCryptAcquireCertificatePrivateKey = GetProcAddress(crypt32dll,
"CryptAcquireCertificatePrivateKey");
if (OpenVPNCryptAcquireCertificatePrivateKey == NULL) {
CRYPTOAPIerr(CRYPTOAPI_F_GET_PROC_ADDRESS);
goto err;
}
}
#endif
if (!OpenVPNCryptAcquireCertificatePrivateKey(cd->cert_context, CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
NULL, &cd->crypt_prov, &cd->key_spec, &cd->free_crypt_prov)) {
/* if we don't have a smart card reader here, and we try to access a
* smart card certificate, we get:
* "Error 1223: The operation was canceled by the user." */
CRYPTOAPIerr(CRYPTOAPI_F_CRYPT_ACQUIRE_CERTIFICATE_PRIVATE_KEY);
goto err;
}
/* here we don't need to do CryptGetUserKey() or anything; all necessary key
* info is in cd->cert_context, and then, in cd->crypt_prov. */
my_rsa_method->name = "Microsoft CryptoAPI RSA Method";
my_rsa_method->rsa_pub_enc = rsa_pub_enc;
my_rsa_method->rsa_pub_dec = rsa_pub_dec;
my_rsa_method->rsa_priv_enc = rsa_priv_enc;
my_rsa_method->rsa_priv_dec = rsa_priv_dec;
/* my_rsa_method->init = init; */
my_rsa_method->finish = finish;
my_rsa_method->flags = RSA_METHOD_FLAG_NO_CHECK;
my_rsa_method->app_data = (char *) cd;
rsa = RSA_new();
if (rsa == NULL) {
SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_MALLOC_FAILURE);
goto err;
}
/* cert->cert_info->key->pkey is NULL until we call SSL_CTX_use_certificate(),
* so we do it here then... */
if (!SSL_CTX_use_certificate(ssl_ctx, cert))
goto err;
/* the public key */
pub_rsa = cert->cert_info->key->pkey->pkey.rsa;
/* SSL_CTX_use_certificate() increased the reference count in 'cert', so
* we decrease it here with X509_free(), or it will never be cleaned up. */
X509_free(cert);
cert = NULL;
/* I'm not sure about what we have to fill in in the RSA, trying out stuff... */
/* rsa->n indicates the key size */
rsa->n = BN_dup(pub_rsa->n);
rsa->flags |= RSA_FLAG_EXT_PKEY;
if (!RSA_set_method(rsa, my_rsa_method))
goto err;
if (!SSL_CTX_use_RSAPrivateKey(ssl_ctx, rsa))
goto err;
/* SSL_CTX_use_RSAPrivateKey() increased the reference count in 'rsa', so
* we decrease it here with RSA_free(), or it will never be cleaned up. */
RSA_free(rsa);
return 1;
err:
if (cert)
X509_free(cert);
if (rsa)
RSA_free(rsa);
else {
if (my_rsa_method)
free(my_rsa_method);
if (cd) {
if (cd->free_crypt_prov && cd->crypt_prov)
CryptReleaseContext(cd->crypt_prov, 0);
if (cd->cert_context)
CertFreeCertificateContext(cd->cert_context);
free(cd);
}
}
return 0;
}
#else
static void dummy (void) {}
#endif /* WIN32 */

7
cryptoapi.h Normal file
View file

@ -0,0 +1,7 @@
#ifndef _CRYPTOAPI_H_
#define _CRYPTOAPI_H_
int SSL_CTX_use_CryptoAPI_certificate(SSL_CTX *ssl_ctx, const char *cert_prop);
#endif /* !_CRYPTOAPI_H_ */

1182
debug/valgrind-suppress Normal file

File diff suppressed because it is too large Load diff

183
dhcp.c Normal file
View file

@ -0,0 +1,183 @@
/*
* OpenVPN -- An application to securely tunnel IP networks
* over a single TCP/UDP port, with support for SSL/TLS-based
* session authentication and key exchange,
* packet encryption, packet authentication, and
* packet compression.
*
* Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* 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 (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "syshead.h"
#include "dhcp.h"
#include "socket.h"
#include "error.h"
#include "memdbg.h"
static int
get_dhcp_message_type (const struct dhcp *dhcp, const int optlen)
{
const uint8_t *p = (uint8_t *) (dhcp + 1);
int i;
for (i = 0; i < optlen; ++i)
{
const uint8_t type = p[i];
const int room = optlen - i;
if (type == DHCP_END) /* didn't find what we were looking for */
return -1;
else if (type == DHCP_PAD) /* no-operation */
;
else if (type == DHCP_MSG_TYPE) /* what we are looking for */
{
if (room >= 3)
{
if (p[i+1] == 1) /* option length should be 1 */
return p[i+2]; /* return message type */
}
return -1;
}
else /* some other option */
{
if (room >= 2)
{
const int len = p[i+1]; /* get option length */
i += (len + 1); /* advance to next option */
}
}
}
return -1;
}
static in_addr_t
do_extract (struct dhcp *dhcp, const int optlen)
{
uint8_t *p = (uint8_t *) (dhcp + 1);
int i;
in_addr_t ret = 0;
for (i = 0; i < optlen; ++i)
{
const uint8_t type = p[i];
const int room = optlen - i;
if (type == DHCP_END)
break;
else if (type == DHCP_PAD)
;
else if (type == DHCP_ROUTER)
{
if (room >= 2)
{
const int len = p[i+1]; /* get option length */
if (len <= (room-2))
{
if (!ret && len >= 4 && (len & 3) == 0)
{
memcpy (&ret, p+i+2, 4); /* get router IP address */
ret = ntohl (ret);
}
memset (p+i, DHCP_PAD, len+2); /* delete the router option by padding it out */
}
i += (len + 1); /* advance to next option */
}
}
else /* some other option */
{
if (room >= 2)
{
const int len = p[i+1]; /* get option length */
i += (len + 1); /* advance to next option */
}
}
}
return ret;
}
static uint16_t
udp_checksum (const uint8_t *buf,
const int len_udp,
const uint8_t *src_addr,
const uint8_t *dest_addr)
{
uint16_t word16;
uint32_t sum = 0;
int i;
/* make 16 bit words out of every two adjacent 8 bit words and */
/* calculate the sum of all 16 bit words */
for (i = 0; i < len_udp; i += 2){
word16 = ((buf[i] << 8) & 0xFF00) + ((i + 1 < len_udp) ? (buf[i+1] & 0xFF) : 0);
sum += word16;
}
/* add the UDP pseudo header which contains the IP source and destination addresses */
for (i = 0; i < 4; i += 2){
word16 =((src_addr[i] << 8) & 0xFF00) + (src_addr[i+1] & 0xFF);
sum += word16;
}
for (i = 0; i < 4; i += 2){
word16 =((dest_addr[i] << 8) & 0xFF00) + (dest_addr[i+1] & 0xFF);
sum += word16;
}
/* the protocol number and the length of the UDP packet */
sum += (uint16_t) OPENVPN_IPPROTO_UDP + (uint16_t) len_udp;
/* keep only the last 16 bits of the 32 bit calculated sum and add the carries */
while (sum >> 16)
sum = (sum & 0xFFFF) + (sum >> 16);
/* Take the one's complement of sum */
return ((uint16_t) ~sum);
}
in_addr_t
dhcp_extract_router_msg (struct buffer *ipbuf)
{
struct dhcp_full *df = (struct dhcp_full *) BPTR (ipbuf);
const int optlen = BLEN (ipbuf) - (sizeof (struct openvpn_iphdr) + sizeof (struct openvpn_udphdr) + sizeof (struct dhcp));
if (optlen >= 0
&& df->ip.protocol == OPENVPN_IPPROTO_UDP
&& df->udp.source == htons (BOOTPS_PORT)
&& df->udp.dest == htons (BOOTPC_PORT)
&& df->dhcp.op == BOOTREPLY
&& get_dhcp_message_type (&df->dhcp, optlen) == DHCPACK)
{
/* get the router IP address while padding out all DHCP router options */
const in_addr_t ret = do_extract (&df->dhcp, optlen);
/* recompute the UDP checksum */
df->udp.check = htons (udp_checksum ((uint8_t *) &df->udp,
sizeof (struct openvpn_udphdr) + sizeof (struct dhcp) + optlen,
(uint8_t *)&df->ip.saddr,
(uint8_t *)&df->ip.daddr));
if (ret)
{
struct gc_arena gc = gc_new ();
msg (D_ROUTE, "Extracted DHCP router address: %s", print_in_addr_t (ret, 0, &gc));
gc_free (&gc);
}
return ret;
}
else
return 0;
}

87
dhcp.h Normal file
View file

@ -0,0 +1,87 @@
/*
* OpenVPN -- An application to securely tunnel IP networks
* over a single TCP/UDP port, with support for SSL/TLS-based
* session authentication and key exchange,
* packet encryption, packet authentication, and
* packet compression.
*
* Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* 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 (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef DHCP_H
#define DHCP_H
#include "common.h"
#include "buffer.h"
#include "proto.h"
#pragma pack(1)
/* DHCP Option types */
#define DHCP_PAD 0
#define DHCP_ROUTER 3
#define DHCP_MSG_TYPE 53 /* message type (u8) */
#define DHCP_END 255
/* DHCP Messages types */
#define DHCPDISCOVER 1
#define DHCPOFFER 2
#define DHCPREQUEST 3
#define DHCPDECLINE 4
#define DHCPACK 5
#define DHCPNAK 6
#define DHCPRELEASE 7
#define DHCPINFORM 8
/* DHCP UDP port numbers */
#define BOOTPS_PORT 67
#define BOOTPC_PORT 68
struct dhcp {
# define BOOTREQUEST 1
# define BOOTREPLY 2
uint8_t op; /* message op */
uint8_t htype; /* hardware address type (e.g. '1' = 10Mb Ethernet) */
uint8_t hlen; /* hardware address length (e.g. '6' for 10Mb Ethernet) */
uint8_t hops; /* client sets to 0, may be used by relay agents */
uint32_t xid; /* transaction ID, chosen by client */
uint16_t secs; /* seconds since request process began, set by client */
uint16_t flags;
uint32_t ciaddr; /* client IP address, client sets if known */
uint32_t yiaddr; /* 'your' IP address -- server's response to client */
uint32_t siaddr; /* server IP address */
uint32_t giaddr; /* relay agent IP address */
uint8_t chaddr[16]; /* client hardware address */
uint8_t sname[64]; /* optional server host name */
uint8_t file[128]; /* boot file name */
uint32_t magic; /* must be 0x63825363 (network order) */
};
struct dhcp_full {
struct openvpn_iphdr ip;
struct openvpn_udphdr udp;
struct dhcp dhcp;
# define DHCP_OPTIONS_BUFFER_SIZE 256
uint8_t options[DHCP_OPTIONS_BUFFER_SIZE];
};
#pragma pack()
in_addr_t dhcp_extract_router_msg (struct buffer *ipbuf);
#endif

73
doclean Executable file
View file

@ -0,0 +1,73 @@
#!/bin/sh
# Let's have a fresh start. Remove all
# generated files.
#
# Run this script, then:
# autoreconf -i -v
# ./configure
# make
# make install
if ! [ "$KEEPAUTODEFS" = "yes" ]; then
rm -rf autodefs
fi
rm -f \
*.o \
service-win32/*.o \
service-win32/*.exe \
*.exe \
openvpn \
config.cache \
configure \
Makefile \
Makefile.in \
stamp-h* \
config.guess \
config.sub \
depcomp \
missing \
mkinstalldirs \
config.log \
config.status \
config.h \
config.h.in \
aclocal.m4 \
openvpn.spec \
install-sh \
openvpn.8.html \
install-win32/*.exe \
install-win32/makensis.log \
install-win32/settings \
install-win32/Makefile \
install-win32/Makefile.in \
images/Makefile \
images/Makefile.in \
service-win32/Makefile \
service-win32/Makefile.in
rm -rf \
autom4te*.cache \
.deps \
*/.deps \
windest \
gen \
tapinstall \
install-win32/tmp
rm -rf \
tap-win32/objfre_w2k_x86 \
tap-win32/dist \
tap-win32/SOURCES \
tap-win32/tapdrvr.cod \
tap-win32/buildfre_wnet_amd64.wrn \
tap-win32/buildfre_w2k_x86.wrn \
tap-win32/objfre_wnet_amd64 \
tap-win32/buildfre_wnet_amd64.log \
tap-win32/buildfre_w2k_x86.log \
tap-win32/amd64 \
tap-win32/i386/tap0901.pdb \
tap-win32/i386/OemWin2k.inf \
tap-win32/i386/tap0901.map \
tap-win32/i386/tap0901.sys

138
domake-win Normal file
View file

@ -0,0 +1,138 @@
#!/bin/sh
# This is the master OpenVPN build script for Windows.
# This script will build OpenVPN, the TAP driver, and
# the installer from source, targeting x86 on Windows
# 2000 and higher, and x64 on Windows 2003 and higher.
# For quick start options, see pre-built notes below.
#
# Note that if you are only looking to build the
# openvpn user-space binaries (openvpn.exe
# and openvpnserv.exe) you can use the
# provided autoconf/automake build environment.
#
# If you are building from an expanded .tar.gz file,
# make sure to run "./doclean" before "./domake-win".
#
# See top-level build configuration and settings in:
#
# version.m4
# install-win32/settings.in
#
# Mandatory prerequisites:
#
# MinGW -- for GNU C compiler
# MSYS -- for bash
# msysDTK -- for perl
# NSIS -- for building installer
#
# The following additional prerequisites may be omitted
# when building in pre-built mode (see note below).
#
# svn -- for checking out source code (or TortoiseSVN)
# Windows Driver Kit (6001_17121_HyperV_WDK.iso) -- for building
# TAP driver + tapinstall
#
# Required libraries (must be prebuilt)
#
# OpenSSL -- define OPENSSL_DIR in settings.in
# LZO -- define LZO_DIR in settings.in
# PKCS11-HELPER -- define PKCS11_HELPER_DIR
#
# Optional OpenVPN GUI binary (prebuilt)
# -- define OPENVPN_GUI_DIR and OPENVPN_GUI in settings.in
#
# Required source code not included in OpenVPN SVN repository
# because of MS licensing restrictions:
#
# ../tapinstall -- This is based on 'devcon' which is found in the
# Windows Driver Kit (formerly known as DDK).
# Copy the 'devcon' source tree to ../tapinstall
# Edit 'sources' and modify TARGETNAME=tapinstall
# Note that all variables referenced here such as GENOUT,
# GENOUT_PREBUILT, and CLEAN are defined in install-win32/settings.in
# SPECIAL NOTES ON PRE-BUILT MODE
# Setting up a complete tool chain to build OpenVPN and all
# dependencies on Windows can be an onerous task, so the capability
# is provided to reference a directory of pre-built components during
# the build process. When dependencies are missing to build a given
# component (such as the TAP driver), the build script will auto-detect
# this and use the pre-built version instead. This would allow you, for
# example, to build an OpenVPN installer with custom edits to
# install-win32/settings.in, but then avoid needing to build all other
# components (such as OpenSSL, LZO, Pkcs11-helper, TAP driver, Windows
# service, etc.). The procedure is as follows. First Download and expand
# the pre-built binaries from:
#
# http://openvpn.net/prebuilt/ (choose the most recent -prebuilt .tbz file)
#
# After expanding the .tbz file, cd to the top level directory and
# expand an OpenVPN source distribution taken from either the subversion
# repository or a source .tar.gz file. It's best to use an OpenVPN source
# version that is the same or slightly later than the pre-built binaries
# file. So now you have a directory containing something that looks like
# this:
#
# gen-prebuilt -> from prebuilt .tbz file
# lzo-2.02 -> from prebuilt .tbz file
# openssl-0.9.8i -> from prebuilt .tbz file
# pkcs11-helper -> from prebuilt .tbz file
# openvpn-2.1_rc13.tar.gz -> downloaded from openvpn.net
# openvpn-2.1_rc13 -> directory expanded from above file
#
# Now cd to your expanded source tree (openvpn-2.1_rc13 in the
# example above), make edits to install-win32/settings.in (or even
# patch the OpenVPN source code directly), and run this script:
#
# ./domake-win
#
# If everything runs correctly, you should have a custom installer
# written to ./gen/install
# First build the autodefs directory, containing C, sh, and NSIS versions
# of global settings, using install-win32/settings.in as source.
# These settings will then drive the rest of the build process.
install-win32/winconfig
# clean all generated files
install-win32/doclean
# Load a pre-built GENOUT directory if GENOUT_PREBUILT is defined
# and the GENOUT directory is non-existing
install-win32/getprebuilt
# Each of the scripts below build, get, and/or possibly sign a different
# OpenVPN component, placing the generated files in GENOUT. Each of these
# steps is fully indepedent, and can be executed in any order or omitted.
# The exception is the last script which gathers together all files from
# GENOUT and builds the installer.
# Make the OpenVPN user-space components (OpenVPN and service)
install-win32/makeopenvpn
# Make the OpenVPN TAP driver
install-win32/maketap
# Make the tapinstall utility, used to install the TAP driver
install-win32/maketapinstall
# Get the OpenSSL libraries from a pre-build OpenSSL tree
install-win32/getopenssl
# Get the PKCS-11 helper library from a pre-built OpenSSL tree
install-win32/getpkcs11helper
# Get the OpenVPN GUI (must be prebuilt)
install-win32/getgui
# Get the OpenVPN XML-based GUI (must be prebuilt)
install-win32/getxgui
# Produce the license text, install README, and sample config files
install-win32/maketext
# This final step builds the OpenVPN installer using generated
# files from GENOUT
install-win32/buildinstaller

4
doval Executable file
View file

@ -0,0 +1,4 @@
#!/bin/bash
PROGDIR=`dirname $0`
unset LD_LIBRARY_PATH
valgrind --tool=memcheck --error-limit=no --suppressions=$PROGDIR/debug/valgrind-suppress --gen-suppressions=all --leak-check=full --show-reachable=yes --num-callers=32 $PROGDIR/openvpn "$@"

2
dovalns Executable file
View file

@ -0,0 +1,2 @@
#!/bin/bash
valgrind --tool=memcheck --error-limit=no --gen-suppressions=all --leak-check=full --show-reachable=yes --num-callers=32 $*

161
easy-rsa/1.0/README Normal file
View file

@ -0,0 +1,161 @@
This is a small RSA key management package,
based on the openssl command line tool, that
can be found in the easy-rsa subdirectory
of the OpenVPN distribution.
These are reference notes. For step
by step instructions, see the HOWTO:
http://openvpn.net/howto.html
INSTALL
1. Edit vars.
2. Set KEY_CONFIG to point to the openssl.cnf file
included in this distribution.
3. Set KEY_DIR to point to a directory which will
contain all keys, certificates, etc. This
directory need not exist, and if it does,
it will be deleted with rm -rf, so BE
CAREFUL how you set KEY_DIR.
4. (Optional) Edit other fields in vars
per your site data. You may want to
increase KEY_SIZE to 2048 if you are
paranoid and don't mind slower key
processing, but certainly 1024 is
fine for testing purposes. KEY_SIZE
must be compatible across both peers
participating in a secure SSL/TLS
connection.
5 . vars
6. ./clean-all
7. As you create certificates, keys, and
certificate signing requests, understand that
only .key files should be kept confidential.
.crt and .csr files can be sent over insecure
channels such as plaintext email.
8. You should never need to copy a .key file
between computers. Normally each computer
will have its own certificate/key pair.
BUILD YOUR OWN ROOT CERTIFICATE AUTHORITY (CA) CERTIFICATE/KEY
1. ./build-ca
2. ca.crt and ca.key will be built in your KEY_DIR
directory
BUILD AN INTERMEDIATE CERTIFICATE AUTHORITY CERTIFICATE/KEY (optional)
1. ./build-inter inter
2. inter.crt and inter.key will be built in your KEY_DIR
directory and signed with your root certificate.
BUILD DIFFIE-HELLMAN PARAMETERS (necessary for
the server end of a SSL/TLS connection).
1. ./build-dh
BUILD A CERTIFICATE SIGNING REQUEST (If
you want to sign your certificate with a root
certificate controlled by another individual
or organization, or residing on a different machine).
1. Get ca.crt (the root certificate) from your
certificate authority. Though this
transfer can be over an insecure channel, to prevent
man-in-the-middle attacks you must confirm that
ca.crt was not tampered with. Large CAs solve this
problem by hardwiring their root certificates into
popular web browsers. A simple way to verify a root
CA is to call the issuer on the telephone and confirm
that the md5sum or sha1sum signatures on the ca.crt
files match (such as with the command: "md5sum ca.crt").
2. Choose a name for your certificate such as your computer
name. In our example we will use "mycert".
3. ./build-req mycert
4. You can ignore most of the fields, but set
"Common Name" to something unique such as your
computer's host name. Leave all password
fields blank, unless you want your private key
to be protected by password. Using a password
is not required -- it will make your key more secure
but also more inconvenient to use, because you will
need to supply your password anytime the key is used.
NOTE: if you are using a password, use ./build-req-pass
instead of ./build-req
5. Your key will be written to $KEY_DIR/mycert.key
6. Your certificate signing request will be written to
to $KEY_DIR/mycert.csr
7. Email mycert.csr to the individual or organization
which controls the root certificate. This can be
done over an insecure channel.
8. After the .csr file is signed by the root certificate
authority, you will receive a file mycert.crt
(your certificate). Place mycert.crt in your
KEY_DIR directory.
9. The combined files of mycert.crt, mycert.key,
and ca.crt can now be used to secure one end of
an SSL/TLS connection.
SIGN A CERTIFICATE SIGNING REQUEST
1. ./sign-req mycert
2. mycert.crt will be built in your KEY_DIR
directory using mycert.csr and your root CA
file as input.
BUILD AND SIGN A CERTIFICATE SIGNING REQUEST
USING A LOCALLY INSTALLED ROOT CERTIFICATE/KEY -- this
script generates and signs a certificate in one step,
but it requires that the generated certificate and private
key files be copied to the destination host over a
secure channel.
1. ./build-key mycert (no password protection)
2. OR ./build-key-pass mycert (with password protection)
3. OR ./build-key-pkcs12 mycert (PKCS #12 format)
4. OR ./build-key-server mycert (with nsCertType=server)
5. mycert.crt and mycert.key will be built in your
KEY_DIR directory, and mycert.crt will be signed
by your root CA. If ./build-key-pkcs12 was used a
mycert.p12 file will also be created including the
private key, certificate and the ca certificate.
IMPORTANT
To avoid a possible Man-in-the-Middle attack where an authorized
client tries to connect to another client by impersonating the
server, make sure to enforce some kind of server certificate
verification by clients. There are currently four different ways
of accomplishing this, listed in the order of preference:
(1) Build your server certificates with the build-key-server
script. This will designate the certificate as a
server-only certificate by setting nsCertType=server.
Now add the following line to your client configuration:
ns-cert-type server
This will block clients from connecting to any
server which lacks the nsCertType=server designation
in its certificate, even if the certificate has been
signed by the CA which is cited in the OpenVPN configuration
file (--ca directive).
(2) Use the --tls-remote directive on the client to
accept/reject the server connection based on the common
name of the server certificate.
(3) Use a --tls-verify script or plugin to accept/reject the
server connection based on a custom test of the server
certificate's embedded X509 subject details.
(4) Sign server certificates with one CA and client certificates
with a different CA. The client config "ca" directive should
reference the server-signing CA while the server config "ca"
directive should reference the client-signing CA.
NOTES
Show certificate fields:
openssl x509 -in cert.crt -text

13
easy-rsa/1.0/build-ca Executable file
View file

@ -0,0 +1,13 @@
#!/bin/sh
#
# Build a root certificate
#
if test $KEY_DIR; then
cd $KEY_DIR && \
openssl req -days 3650 -nodes -new -x509 -keyout ca.key -out ca.crt -config $KEY_CONFIG && \
chmod 0600 ca.key
else
echo you must define KEY_DIR
fi

12
easy-rsa/1.0/build-dh Executable file
View file

@ -0,0 +1,12 @@
#!/bin/sh
#
# Build Diffie-Hellman parameters for the server side
# of an SSL/TLS connection.
#
if test $KEY_DIR; then
openssl dhparam -out ${KEY_DIR}/dh${KEY_SIZE}.pem ${KEY_SIZE}
else
echo you must define KEY_DIR
fi

19
easy-rsa/1.0/build-inter Executable file
View file

@ -0,0 +1,19 @@
#!/bin/sh
#
# Make an intermediate CA certificate/private key pair using a locally generated
# root certificate.
#
if test $# -ne 1; then
echo "usage: build-inter <name>";
exit 1
fi
if test $KEY_DIR; then
cd $KEY_DIR && \
openssl req -days 3650 -nodes -new -keyout $1.key -out $1.csr -config $KEY_CONFIG && \
openssl ca -extensions v3_ca -days 3650 -out $1.crt -in $1.csr -config $KEY_CONFIG
else
echo you must define KEY_DIR
fi

20
easy-rsa/1.0/build-key Executable file
View file

@ -0,0 +1,20 @@
#!/bin/sh
#
# Make a certificate/private key pair using a locally generated
# root certificate.
#
if test $# -ne 1; then
echo "usage: build-key <name>";
exit 1
fi
if test $KEY_DIR; then
cd $KEY_DIR && \
openssl req -days 3650 -nodes -new -keyout $1.key -out $1.csr -config $KEY_CONFIG && \
openssl ca -days 3650 -out $1.crt -in $1.csr -config $KEY_CONFIG && \
chmod 0600 $1.key
else
echo you must define KEY_DIR
fi

20
easy-rsa/1.0/build-key-pass Executable file
View file

@ -0,0 +1,20 @@
#!/bin/sh
#
# Similar to build-key, but protect the private key
# with a password.
#
if test $# -ne 1; then
echo "usage: build-key-pass <name>";
exit 1
fi
if test $KEY_DIR; then
cd $KEY_DIR && \
openssl req -days 3650 -new -keyout $1.key -out $1.csr -config $KEY_CONFIG && \
openssl ca -days 3650 -out $1.crt -in $1.csr -config $KEY_CONFIG && \
chmod 0600 $1.key
else
echo you must define KEY_DIR
fi

21
easy-rsa/1.0/build-key-pkcs12 Executable file
View file

@ -0,0 +1,21 @@
#!/bin/sh
#
# Make a certificate/private key pair using a locally generated
# root certificate and convert it to a PKCS #12 file including the
# the CA certificate as well.
if test $# -ne 1; then
echo "usage: build-key-pkcs12 <name>";
exit 1
fi
if test $KEY_DIR; then
cd $KEY_DIR && \
openssl req -days 3650 -nodes -new -keyout $1.key -out $1.csr -config $KEY_CONFIG && \
openssl ca -days 3650 -out $1.crt -in $1.csr -config $KEY_CONFIG && \
openssl pkcs12 -export -inkey $1.key -in $1.crt -certfile ca.crt -out $1.p12 && \
chmod 0600 $1.key $1.p12
else
echo you must define KEY_DIR
fi

22
easy-rsa/1.0/build-key-server Executable file
View file

@ -0,0 +1,22 @@
#!/bin/sh
#
# Make a certificate/private key pair using a locally generated
# root certificate.
#
# Explicitly set nsCertType to server using the "server"
# extension in the openssl.cnf file.
if test $# -ne 1; then
echo "usage: build-key-server <name>";
exit 1
fi
if test $KEY_DIR; then
cd $KEY_DIR && \
openssl req -days 3650 -nodes -new -keyout $1.key -out $1.csr -extensions server -config $KEY_CONFIG && \
openssl ca -days 3650 -out $1.crt -in $1.csr -extensions server -config $KEY_CONFIG && \
chmod 0600 $1.key
else
echo you must define KEY_DIR
fi

18
easy-rsa/1.0/build-req Executable file
View file

@ -0,0 +1,18 @@
#!/bin/sh
#
# Build a certificate signing request and private key. Use this
# when your root certificate and key is not available locally.
#
if test $# -ne 1; then
echo "usage: build-req <name>";
exit 1
fi
if test $KEY_DIR; then
cd $KEY_DIR && \
openssl req -days 3650 -nodes -new -keyout $1.key -out $1.csr -config $KEY_CONFIG
else
echo you must define KEY_DIR
fi

18
easy-rsa/1.0/build-req-pass Executable file
View file

@ -0,0 +1,18 @@
#!/bin/sh
#
# Like build-req, but protect your private key
# with a password.
#
if test $# -ne 1; then
echo "usage: build-req-pass <name>";
exit 1
fi
if test $KEY_DIR; then
cd $KEY_DIR && \
openssl req -days 3650 -new -keyout $1.key -out $1.csr -config $KEY_CONFIG
else
echo you must define KEY_DIR
fi

19
easy-rsa/1.0/clean-all Executable file
View file

@ -0,0 +1,19 @@
#!/bin/sh
#
# Initialize the $KEY_DIR directory.
# Note that this script does a
# rm -rf on $KEY_DIR so be careful!
#
d=$KEY_DIR
if test $d; then
rm -rf $d
mkdir $d && \
chmod go-rwx $d && \
touch $d/index.txt && \
echo 01 >$d/serial
else
echo you must define KEY_DIR
fi

18
easy-rsa/1.0/list-crl Normal file
View file

@ -0,0 +1,18 @@
#!/bin/sh
#
# list revoked certificates
#
#
if test $# -ne 1; then
echo "usage: list-crl <crlfile.pem>";
exit 1
fi
if test $KEY_DIR; then
cd $KEY_DIR && \
openssl crl -text -noout -in $1
else
echo you must define KEY_DIR
fi

18
easy-rsa/1.0/make-crl Normal file
View file

@ -0,0 +1,18 @@
#!/bin/sh
#
# generate a CRL
#
#
if test $# -ne 1; then
echo "usage: make-crl <crlfile.pem>";
exit 1
fi
if test $KEY_DIR; then
cd $KEY_DIR && \
openssl ca -gencrl -out $1 -config $KEY_CONFIG
else
echo you must define KEY_DIR
fi

255
easy-rsa/1.0/openssl.cnf Normal file
View file

@ -0,0 +1,255 @@
#
# OpenSSL example configuration file.
# This is mostly being used for generation of certificate requests.
#
# This definition stops the following lines choking if HOME isn't
# defined.
HOME = .
RANDFILE = $ENV::HOME/.rnd
# Extra OBJECT IDENTIFIER info:
#oid_file = $ENV::HOME/.oid
oid_section = new_oids
# To use this configuration file with the "-extfile" option of the
# "openssl x509" utility, name here the section containing the
# X.509v3 extensions to use:
# extensions =
# (Alternatively, use a configuration file that has only
# X.509v3 extensions in its main [= default] section.)
[ new_oids ]
# We can add new OIDs in here for use by 'ca' and 'req'.
# Add a simple OID like this:
# testoid1=1.2.3.4
# Or use config file substitution like this:
# testoid2=${testoid1}.5.6
####################################################################
[ ca ]
default_ca = CA_default # The default ca section
####################################################################
[ CA_default ]
dir = $ENV::KEY_DIR # Where everything is kept
certs = $dir # Where the issued certs are kept
crl_dir = $dir # Where the issued crl are kept
database = $dir/index.txt # database index file.
new_certs_dir = $dir # default place for new certs.
certificate = $dir/ca.crt # The CA certificate
serial = $dir/serial # The current serial number
crl = $dir/crl.pem # The current CRL
private_key = $dir/ca.key # The private key
RANDFILE = $dir/.rand # private random number file
x509_extensions = usr_cert # The extentions to add to the cert
# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crl_extensions = crl_ext
default_days = 3650 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = md5 # which md to use.
preserve = no # keep passed DN ordering
# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy = policy_match
# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
####################################################################
[ req ]
default_bits = $ENV::KEY_SIZE
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca # The extentions to add to the self signed cert
# Passwords for private keys if not present they will be prompted for
# input_password = secret
# output_password = secret
# This sets a mask for permitted string types. There are several options.
# default: PrintableString, T61String, BMPString.
# pkix : PrintableString, BMPString.
# utf8only: only UTF8Strings.
# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
# MASK:XXXX a literal mask value.
# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
# so use this option with caution!
string_mask = nombstr
# req_extensions = v3_req # The extensions to add to a certificate request
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = $ENV::KEY_COUNTRY
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = $ENV::KEY_PROVINCE
localityName = Locality Name (eg, city)
localityName_default = $ENV::KEY_CITY
0.organizationName = Organization Name (eg, company)
0.organizationName_default = $ENV::KEY_ORG
# we can do this but it is not needed normally :-)
#1.organizationName = Second Organization Name (eg, company)
#1.organizationName_default = World Wide Web Pty Ltd
organizationalUnitName = Organizational Unit Name (eg, section)
#organizationalUnitName_default =
commonName = Common Name (eg, your name or your server\'s hostname)
commonName_max = 64
emailAddress = Email Address
emailAddress_default = $ENV::KEY_EMAIL
emailAddress_max = 40
# SET-ex3 = SET extension number 3
[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 4
challengePassword_max = 20
unstructuredName = An optional company name
[ usr_cert ]
# These extensions are added when 'ca' signs a request.
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# This will be displayed in Netscape's comment listbox.
nsComment = "OpenSSL Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer:always
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# Copy subject details
# issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
[ server ]
# JY ADDED -- Make a cert with nsCertType set to "server"
basicConstraints=CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer:always
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[ v3_ca ]
# Extensions for a typical CA
# PKIX recommendation.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always
# This is what PKIX recommends but some broken software chokes on critical
# extensions.
#basicConstraints = critical,CA:true
# So we do this instead.
basicConstraints = CA:true
# Key usage: this is typical for a CA certificate. However since it will
# prevent it being used as an test self-signed certificate it is best
# left out by default.
# keyUsage = cRLSign, keyCertSign
# Some might want this also
# nsCertType = sslCA, emailCA
# Include email address in subject alt name: another PKIX recommendation
# subjectAltName=email:copy
# Copy issuer details
# issuerAltName=issuer:copy
# DER hex encoding of an extension: beware experts only!
# obj=DER:02:03
# Where 'obj' is a standard or added object
# You can even override a supported extension:
# basicConstraints= critical, DER:30:03:01:01:FF
[ crl_ext ]
# CRL extensions.
# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
# issuerAltName=issuer:copy
authorityKeyIdentifier=keyid:always,issuer:always

18
easy-rsa/1.0/revoke-crt Normal file
View file

@ -0,0 +1,18 @@
#!/bin/sh
#
# revoke a certificate
#
#
if test $# -ne 1; then
echo "usage: revoke-crt <file.crt>";
exit 1
fi
if test $KEY_DIR; then
cd $KEY_DIR && \
openssl ca -revoke $1 -config $KEY_CONFIG
else
echo you must define KEY_DIR
fi

29
easy-rsa/1.0/revoke-full Executable file
View file

@ -0,0 +1,29 @@
#!/bin/sh
# revoke a certificate, regenerate CRL,
# and verify revocation
CRL=crl.pem
RT=revoke-test.pem
if test $# -ne 1; then
echo "usage: revoke-full <name>";
exit 1
fi
if test $KEY_DIR; then
cd $KEY_DIR
rm -f $RT
# revoke key and generate a new CRL
openssl ca -revoke $1.crt -config $KEY_CONFIG
# generate a new CRL
openssl ca -gencrl -out $CRL -config $KEY_CONFIG
cat ca.crt $CRL >$RT
# verify the revocation
openssl verify -CAfile $RT -crl_check $1.crt
else
echo you must define KEY_DIR
fi

18
easy-rsa/1.0/sign-req Executable file
View file

@ -0,0 +1,18 @@
#!/bin/sh
#
# Sign a certificate signing request (a .csr file)
# with a local root certificate and key.
#
if test $# -ne 1; then
echo "usage: sign-req <name>";
exit 1
fi
if test $KEY_DIR; then
cd $KEY_DIR && \
openssl ca -days 3650 -out $1.crt -in $1.csr -config $KEY_CONFIG
else
echo you must define KEY_DIR
fi

49
easy-rsa/1.0/vars Normal file
View file

@ -0,0 +1,49 @@
# easy-rsa parameter settings
# NOTE: If you installed from an RPM,
# don't edit this file in place in
# /usr/share/openvpn/easy-rsa --
# instead, you should copy the whole
# easy-rsa directory to another location
# (such as /etc/openvpn) so that your
# edits will not be wiped out by a future
# OpenVPN package upgrade.
# This variable should point to
# the top level of the easy-rsa
# tree.
export D=`pwd`
# This variable should point to
# the openssl.cnf file included
# with easy-rsa.
export KEY_CONFIG=$D/openssl.cnf
# Edit this variable to point to
# your soon-to-be-created key
# directory.
#
# WARNING: clean-all will do
# a rm -rf on this directory
# so make sure you define
# it correctly!
export KEY_DIR=$D/keys
# Issue rm -rf warning
echo NOTE: when you run ./clean-all, I will be doing a rm -rf on $KEY_DIR
# Increase this to 2048 if you
# are paranoid. This will slow
# down TLS negotiation performance
# as well as the one-time DH parms
# generation process.
export KEY_SIZE=1024
# These are the default values for fields
# which will be placed in the certificate.
# Don't leave any of these fields blank.
export KEY_COUNTRY=KG
export KEY_PROVINCE=NA
export KEY_CITY=BISHKEK
export KEY_ORG="OpenVPN-TEST"
export KEY_EMAIL="me@myhost.mydomain"

13
easy-rsa/2.0/Makefile Normal file
View file

@ -0,0 +1,13 @@
DESTDIR=
PREFIX=
all:
echo "All done."
echo "Run make install DESTDIR=/usr/share/somewhere"
install:
install -d "${DESTDIR}/${PREFIX}"
install -m 0755 build-* "${DESTDIR}/${PREFIX}"
install -m 0755 clean-all list-crl inherit-inter pkitool revoke-full sign-req whichopensslcnf "${DESTDIR}/${PREFIX}"
install -m 0644 openssl-0.9.6.cnf openssl.cnf README vars "${DESTDIR}/${PREFIX}"

229
easy-rsa/2.0/README Normal file
View file

@ -0,0 +1,229 @@
EASY-RSA Version 2.0-rc1
This is a small RSA key management package, based on the openssl
command line tool, that can be found in the easy-rsa subdirectory
of the OpenVPN distribution. While this tool is primary concerned
with key management for the SSL VPN application space, it can also
be used for building web certificates.
These are reference notes. For step-by-step instructions, see the
HOWTO:
http://openvpn.net/howto.html
This package is based on the ./pkitool script. Run ./pkitool
without arguments for a detailed help message (which is also pasted
below).
Release Notes for easy-rsa-2.0
* Most functionality has been consolidated into the pkitool
script. For compatibility, all previous scripts from 1.0 such
as build-key and build-key-server are provided as stubs
which call pkitool to do the real work.
* pkitool has a --batch flag (enabled by default) which generates
keys/certs without needing any interactive input. pkitool
can still generate certs/keys using interactive prompting by
using the --interact flag.
* The inherit-inter script has been provided for creating
a new PKI rooted on an intermediate certificate built within a
higher-level PKI. See comments in the inherit-inter script
for more info.
* The openssl.cnf file has been modified. pkitool will not
work with the openssl.cnf file included with previous
easy-rsa releases.
* The vars file has been modified -- the following extra
variables have been added: EASY_RSA, CA_EXPIRE,
KEY_EXPIRE.
* The make-crl and revoke-crt scripts have been removed and
are replaced by the revoke-full script.
* The "Organizational Unit" X509 field can be set using
the KEY_OU environmental variable before calling pkitool.
* This release only affects the Linux/Unix version of easy-rsa.
The Windows version (written to use the Windows shell) is unchanged.
* Use the revoke-full script to revoke a certificate, and generate
(or update) the crl.pem file in the keys directory (as set by the
vars script). Then use "crl-verify crl.pem" in your OpenVPN server
config file, so that OpenVPN can reject any connections coming from
clients which present a revoked certificate. Usage for the script is:
revoke-full <common-name>
Note this this procedure is primarily designed to revoke client
certificates. You could theoretically use this method to revoke
server certificates as well, but then you would need to propagate
the crl.pem file to all clients as well, and have them include
"crl-verify crl.pem" in their configuration files.
* PKCS#11 support was added.
* For those interested in using this tool to generate web certificates,
A variant of the easy-rsa package that allows the creation of multi-domain
certificates with subjectAltName can be obtained from here:
http://www.bisente.com/proyectos/easy-rsa-subjectaltname/
INSTALL easy-rsa
1. Edit vars.
2. Set KEY_CONFIG to point to the openssl.cnf file
included in this distribution.
3. Set KEY_DIR to point to a directory which will
contain all keys, certificates, etc. This
directory need not exist, and if it does,
it will be deleted with rm -rf, so BE
CAREFUL how you set KEY_DIR.
4. (Optional) Edit other fields in vars
per your site data. You may want to
increase KEY_SIZE to 2048 if you are
paranoid and don't mind slower key
processing, but certainly 1024 is
fine for testing purposes. KEY_SIZE
must be compatible across both peers
participating in a secure SSL/TLS
connection.
5. (Optional) If you intend to use PKCS#11,
install openssl >= 0.9.7, install the
following components from www.opensc.org:
- opensc >= 0.10.0
- engine_pkcs11 >= 0.1.3
Update the openssl.cnf to load the engine:
- Uncomment pkcs11 under engine_section.
- Validate path at dynamic_path under pkcs11_section.
6. . vars
7. ./clean-all
8. As you create certificates, keys, and
certificate signing requests, understand that
only .key files should be kept confidential.
.crt and .csr files can be sent over insecure
channels such as plaintext email.
IMPORTANT
To avoid a possible Man-in-the-Middle attack where an authorized
client tries to connect to another client by impersonating the
server, make sure to enforce some kind of server certificate
verification by clients. There are currently four different ways
of accomplishing this, listed in the order of preference:
(1) Build your server certificates with specific key usage and
extended key usage. The RFC3280 determine that the following
attributes should be provided for TLS connections:
Mode Key usage Extended key usage
---------------------------------------------------------------------------
Client digitalSignature TLS Web Client Authentication
keyAgreement
digitalSignature, keyAgreement
Server digitalSignature, keyEncipherment TLS Web Server Authentication
digitalSignature, keyAgreement
Now add the following line to your client configuration:
remote-cert-tls server
This will block clients from connecting to any
server which lacks the required extension designation
in its certificate, even if the certificate has been
signed by the CA which is cited in the OpenVPN configuration
file (--ca directive).
(3) Use the --tls-remote directive on the client to
accept/reject the server connection based on the common
name of the server certificate.
(3) Use a --tls-verify script or plugin to accept/reject the
server connection based on a custom test of the server
certificate's embedded X509 subject details.
(4) Sign server certificates with one CA and client certificates
with a different CA. The client config "ca" directive should
reference the server-signing CA while the server config "ca"
directive should reference the client-signing CA.
NOTES
Show certificate fields:
openssl x509 -in cert.crt -text
PKITOOL documentation
pkitool 2.0
Usage: pkitool [options...] [common-name]
Options:
--batch : batch mode (default)
--keysize : Set keysize
size : size (default=1024)
--interact : interactive mode
--server : build server cert
--initca : build root CA
--inter : build intermediate CA
--pass : encrypt private key with password
--csr : only generate a CSR, do not sign
--sign : sign an existing CSR
--pkcs12 : generate a combined PKCS#12 file
--pkcs11 : generate certificate on PKCS#11 token
lib : PKCS#11 library
slot : PKCS#11 slot
id : PKCS#11 object id (hex string)
label : PKCS#11 object label
Standalone options:
--pkcs11-slots : list PKCS#11 slots
lib : PKCS#11 library
--pkcs11-objects : list PKCS#11 token objects
lib : PKCS#11 library
slot : PKCS#11 slot
--pkcs11-init : initialize PKCS#11 token DANGEROUS!!!
lib : PKCS#11 library
slot : PKCS#11 slot
label : PKCS#11 token label
Notes:
Please edit the vars script to reflect your configuration,
then source it with "source ./vars".
Next, to start with a fresh PKI configuration and to delete any
previous certificates and keys, run "./clean-all".
Finally, you can run this tool (pkitool) to build certificates/keys.
In order to use PKCS#11 interface you must have opensc-0.10.0 or higher.
Generated files and corresponding OpenVPN directives:
(Files will be placed in the $KEY_DIR directory, defined in ./vars)
ca.crt -> root certificate (--ca)
ca.key -> root key, keep secure (not directly used by OpenVPN)
.crt files -> client/server certificates (--cert)
.key files -> private keys, keep secure (--key)
.csr files -> certificate signing request (not directly used by OpenVPN)
dh1024.pem or dh2048.pem -> Diffie Hellman parameters (--dh)
Examples:
pkitool --initca -> Build root certificate
pkitool --initca --pass -> Build root certificate with password-protected key
pkitool --server server1 -> Build "server1" certificate/key
pkitool client1 -> Build "client1" certificate/key
pkitool --pass client2 -> Build password-protected "client2" certificate/key
pkitool --pkcs12 client3 -> Build "client3" certificate/key in PKCS#12 format
pkitool --csr client4 -> Build "client4" CSR to be signed by another CA
pkitool --sign client4 -> Sign "client4" CSR
pkitool --inter interca -> Build an intermediate key-signing certificate/key
Also see ./inherit-inter script.
pkitool --pkcs11 /usr/lib/pkcs11/lib1 0 010203 "client5 id" client5
-> Build "client5" certificate/key in PKCS#11 token
Typical usage for initial PKI setup. Build myserver, client1, and client2 cert/keys.
Protect client2 key with a password. Build DH parms. Generated files in ./keys :
[edit vars with your site-specific info]
source ./vars
./clean-all
./build-dh -> takes a long time, consider backgrounding
./pkitool --initca
./pkitool --server myserver
./pkitool client1
./pkitool --pass client2
Typical usage for adding client cert to existing PKI:
source ./vars
./pkitool client-new

8
easy-rsa/2.0/build-ca Executable file
View file

@ -0,0 +1,8 @@
#!/bin/bash
#
# Build a root certificate
#
export EASY_RSA="${EASY_RSA:-.}"
"$EASY_RSA/pkitool" --interact --initca $*

11
easy-rsa/2.0/build-dh Executable file
View file

@ -0,0 +1,11 @@
#!/bin/bash
# Build Diffie-Hellman parameters for the server side
# of an SSL/TLS connection.
if [ -d $KEY_DIR ] && [ $KEY_SIZE ]; then
$OPENSSL dhparam -out ${KEY_DIR}/dh${KEY_SIZE}.pem ${KEY_SIZE}
else
echo 'Please source the vars script first (i.e. "source ./vars")'
echo 'Make sure you have edited it to reflect your configuration.'
fi

7
easy-rsa/2.0/build-inter Executable file
View file

@ -0,0 +1,7 @@
#!/bin/bash
# Make an intermediate CA certificate/private key pair using a locally generated
# root certificate.
export EASY_RSA="${EASY_RSA:-.}"
"$EASY_RSA/pkitool" --interact --inter $*

7
easy-rsa/2.0/build-key Executable file
View file

@ -0,0 +1,7 @@
#!/bin/bash
# Make a certificate/private key pair using a locally generated
# root certificate.
export EASY_RSA="${EASY_RSA:-.}"
"$EASY_RSA/pkitool" --interact $*

7
easy-rsa/2.0/build-key-pass Executable file
View file

@ -0,0 +1,7 @@
#!/bin/bash
# Similar to build-key, but protect the private key
# with a password.
export EASY_RSA="${EASY_RSA:-.}"
"$EASY_RSA/pkitool" --interact --pass $*

8
easy-rsa/2.0/build-key-pkcs12 Executable file
View file

@ -0,0 +1,8 @@
#!/bin/bash
# Make a certificate/private key pair using a locally generated
# root certificate and convert it to a PKCS #12 file including the
# the CA certificate as well.
export EASY_RSA="${EASY_RSA:-.}"
"$EASY_RSA/pkitool" --interact --pkcs12 $*

10
easy-rsa/2.0/build-key-server Executable file
View file

@ -0,0 +1,10 @@
#!/bin/bash
# Make a certificate/private key pair using a locally generated
# root certificate.
#
# Explicitly set nsCertType to server using the "server"
# extension in the openssl.cnf file.
export EASY_RSA="${EASY_RSA:-.}"
"$EASY_RSA/pkitool" --interact --server $*

7
easy-rsa/2.0/build-req Executable file
View file

@ -0,0 +1,7 @@
#!/bin/bash
# Build a certificate signing request and private key. Use this
# when your root certificate and key is not available locally.
export EASY_RSA="${EASY_RSA:-.}"
"$EASY_RSA/pkitool" --interact --csr $*

7
easy-rsa/2.0/build-req-pass Executable file
View file

@ -0,0 +1,7 @@
#!/bin/bash
# Like build-req, but protect your private key
# with a password.
export EASY_RSA="${EASY_RSA:-.}"
"$EASY_RSA/pkitool" --interact --csr --pass $*

16
easy-rsa/2.0/clean-all Executable file
View file

@ -0,0 +1,16 @@
#!/bin/bash
# Initialize the $KEY_DIR directory.
# Note that this script does a
# rm -rf on $KEY_DIR so be careful!
if [ "$KEY_DIR" ]; then
rm -rf "$KEY_DIR"
mkdir "$KEY_DIR" && \
chmod go-rwx "$KEY_DIR" && \
touch "$KEY_DIR/index.txt" && \
echo 01 >"$KEY_DIR/serial"
else
echo 'Please source the vars script first (i.e. "source ./vars")'
echo 'Make sure you have edited it to reflect your configuration.'
fi

39
easy-rsa/2.0/inherit-inter Executable file
View file

@ -0,0 +1,39 @@
#!/bin/bash
# Build a new PKI which is rooted on an intermediate certificate generated
# by ./build-inter or ./pkitool --inter from a parent PKI. The new PKI should
# have independent vars settings, and must use a different KEY_DIR directory
# from the parent. This tool can be used to generate arbitrary depth
# certificate chains.
#
# To build an intermediate CA, follow the same steps for a regular PKI but
# replace ./build-key or ./pkitool --initca with this script.
# The EXPORT_CA file will contain the CA certificate chain and should be
# referenced by the OpenVPN "ca" directive in config files. The ca.crt file
# will only contain the local intermediate CA -- it's needed by the easy-rsa
# scripts but not by OpenVPN directly.
EXPORT_CA="export-ca.crt"
if [ $# -ne 2 ]; then
echo "usage: $0 <parent-key-dir> <common-name>"
echo "parent-key-dir: the KEY_DIR directory of the parent PKI"
echo "common-name: the common name of the intermediate certificate in the parent PKI"
exit 1;
fi
if [ "$KEY_DIR" ]; then
cp "$1/$2.crt" "$KEY_DIR/ca.crt"
cp "$1/$2.key" "$KEY_DIR/ca.key"
if [ -e "$1/$EXPORT_CA" ]; then
PARENT_CA="$1/$EXPORT_CA"
else
PARENT_CA="$1/ca.crt"
fi
cp "$PARENT_CA" "$KEY_DIR/$EXPORT_CA"
cat "$KEY_DIR/ca.crt" >> "$KEY_DIR/$EXPORT_CA"
else
echo 'Please source the vars script first (i.e. "source ./vars")'
echo 'Make sure you have edited it to reflect your configuration.'
fi

13
easy-rsa/2.0/list-crl Executable file
View file

@ -0,0 +1,13 @@
#!/bin/bash
# list revoked certificates
CRL="${1:-crl.pem}"
if [ "$KEY_DIR" ]; then
cd "$KEY_DIR" && \
$OPENSSL crl -text -noout -in "$CRL"
else
echo 'Please source the vars script first (i.e. "source ./vars")'
echo 'Make sure you have edited it to reflect your configuration.'
fi

265
easy-rsa/2.0/openssl-0.9.6.cnf Executable file
View file

@ -0,0 +1,265 @@
# For use with easy-rsa version 2.0
#
# OpenSSL example configuration file.
# This is mostly being used for generation of certificate requests.
#
# This definition stops the following lines choking if HOME isn't
# defined.
HOME = .
RANDFILE = $ENV::HOME/.rnd
# Extra OBJECT IDENTIFIER info:
#oid_file = $ENV::HOME/.oid
oid_section = new_oids
# To use this configuration file with the "-extfile" option of the
# "openssl x509" utility, name here the section containing the
# X.509v3 extensions to use:
# extensions =
# (Alternatively, use a configuration file that has only
# X.509v3 extensions in its main [= default] section.)
[ new_oids ]
# We can add new OIDs in here for use by 'ca' and 'req'.
# Add a simple OID like this:
# testoid1=1.2.3.4
# Or use config file substitution like this:
# testoid2=${testoid1}.5.6
####################################################################
[ ca ]
default_ca = CA_default # The default ca section
####################################################################
[ CA_default ]
dir = $ENV::KEY_DIR # Where everything is kept
certs = $dir # Where the issued certs are kept
crl_dir = $dir # Where the issued crl are kept
database = $dir/index.txt # database index file.
new_certs_dir = $dir # default place for new certs.
certificate = $dir/ca.crt # The CA certificate
serial = $dir/serial # The current serial number
crl = $dir/crl.pem # The current CRL
private_key = $dir/ca.key # The private key
RANDFILE = $dir/.rand # private random number file
x509_extensions = usr_cert # The extentions to add to the cert
# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crl_extensions = crl_ext
default_days = 3650 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = md5 # which md to use.
preserve = no # keep passed DN ordering
# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy = policy_anything
# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
####################################################################
[ req ]
default_bits = $ENV::KEY_SIZE
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca # The extentions to add to the self signed cert
# Passwords for private keys if not present they will be prompted for
# input_password = secret
# output_password = secret
# This sets a mask for permitted string types. There are several options.
# default: PrintableString, T61String, BMPString.
# pkix : PrintableString, BMPString.
# utf8only: only UTF8Strings.
# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
# MASK:XXXX a literal mask value.
# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
# so use this option with caution!
string_mask = nombstr
# req_extensions = v3_req # The extensions to add to a certificate request
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = $ENV::KEY_COUNTRY
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = $ENV::KEY_PROVINCE
localityName = Locality Name (eg, city)
localityName_default = $ENV::KEY_CITY
0.organizationName = Organization Name (eg, company)
0.organizationName_default = $ENV::KEY_ORG
# we can do this but it is not needed normally :-)
#1.organizationName = Second Organization Name (eg, company)
#1.organizationName_default = World Wide Web Pty Ltd
organizationalUnitName = Organizational Unit Name (eg, section)
#organizationalUnitName_default =
commonName = Common Name (eg, your name or your server\'s hostname)
commonName_max = 64
emailAddress = Email Address
emailAddress_default = $ENV::KEY_EMAIL
emailAddress_max = 40
# JY -- added for batch mode
organizationalUnitName_default = $ENV::KEY_OU
commonName_default = $ENV::KEY_CN
# SET-ex3 = SET extension number 3
[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 4
challengePassword_max = 20
unstructuredName = An optional company name
[ usr_cert ]
# These extensions are added when 'ca' signs a request.
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# This will be displayed in Netscape's comment listbox.
nsComment = "Easy-RSA Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer:always
extendedKeyUsage=clientAuth
keyUsage = digitalSignature
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# Copy subject details
# issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
[ server ]
# JY ADDED -- Make a cert with nsCertType set to "server"
basicConstraints=CA:FALSE
nsCertType = server
nsComment = "Easy-RSA Generated Server Certificate"
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer:always
extendedKeyUsage=serverAuth
keyUsage = digitalSignature, keyEncipherment
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[ v3_ca ]
# Extensions for a typical CA
# PKIX recommendation.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always
# This is what PKIX recommends but some broken software chokes on critical
# extensions.
#basicConstraints = critical,CA:true
# So we do this instead.
basicConstraints = CA:true
# Key usage: this is typical for a CA certificate. However since it will
# prevent it being used as an test self-signed certificate it is best
# left out by default.
# keyUsage = cRLSign, keyCertSign
# Some might want this also
# nsCertType = sslCA, emailCA
# Include email address in subject alt name: another PKIX recommendation
# subjectAltName=email:copy
# Copy issuer details
# issuerAltName=issuer:copy
# DER hex encoding of an extension: beware experts only!
# obj=DER:02:03
# Where 'obj' is a standard or added object
# You can even override a supported extension:
# basicConstraints= critical, DER:30:03:01:01:FF
[ crl_ext ]
# CRL extensions.
# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
# issuerAltName=issuer:copy
authorityKeyIdentifier=keyid:always,issuer:always

291
easy-rsa/2.0/openssl.cnf Executable file
View file

@ -0,0 +1,291 @@
# For use with easy-rsa version 2.0
#
# OpenSSL example configuration file.
# This is mostly being used for generation of certificate requests.
#
# This definition stops the following lines choking if HOME isn't
# defined.
HOME = .
RANDFILE = $ENV::HOME/.rnd
openssl_conf = openssl_init
[ openssl_init ]
# Extra OBJECT IDENTIFIER info:
#oid_file = $ENV::HOME/.oid
oid_section = new_oids
engines = engine_section
# To use this configuration file with the "-extfile" option of the
# "openssl x509" utility, name here the section containing the
# X.509v3 extensions to use:
# extensions =
# (Alternatively, use a configuration file that has only
# X.509v3 extensions in its main [= default] section.)
[ new_oids ]
# We can add new OIDs in here for use by 'ca' and 'req'.
# Add a simple OID like this:
# testoid1=1.2.3.4
# Or use config file substitution like this:
# testoid2=${testoid1}.5.6
####################################################################
[ ca ]
default_ca = CA_default # The default ca section
####################################################################
[ CA_default ]
dir = $ENV::KEY_DIR # Where everything is kept
certs = $dir # Where the issued certs are kept
crl_dir = $dir # Where the issued crl are kept
database = $dir/index.txt # database index file.
new_certs_dir = $dir # default place for new certs.
certificate = $dir/ca.crt # The CA certificate
serial = $dir/serial # The current serial number
crl = $dir/crl.pem # The current CRL
private_key = $dir/ca.key # The private key
RANDFILE = $dir/.rand # private random number file
x509_extensions = usr_cert # The extentions to add to the cert
# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crl_extensions = crl_ext
default_days = 3650 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = md5 # which md to use.
preserve = no # keep passed DN ordering
# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy = policy_anything
# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
name = optional
emailAddress = optional
# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
name = optional
emailAddress = optional
####################################################################
[ req ]
default_bits = $ENV::KEY_SIZE
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca # The extentions to add to the self signed cert
# Passwords for private keys if not present they will be prompted for
# input_password = secret
# output_password = secret
# This sets a mask for permitted string types. There are several options.
# default: PrintableString, T61String, BMPString.
# pkix : PrintableString, BMPString.
# utf8only: only UTF8Strings.
# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
# MASK:XXXX a literal mask value.
# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
# so use this option with caution!
string_mask = nombstr
# req_extensions = v3_req # The extensions to add to a certificate request
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = $ENV::KEY_COUNTRY
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = $ENV::KEY_PROVINCE
localityName = Locality Name (eg, city)
localityName_default = $ENV::KEY_CITY
0.organizationName = Organization Name (eg, company)
0.organizationName_default = $ENV::KEY_ORG
# we can do this but it is not needed normally :-)
#1.organizationName = Second Organization Name (eg, company)
#1.organizationName_default = World Wide Web Pty Ltd
organizationalUnitName = Organizational Unit Name (eg, section)
#organizationalUnitName_default =
commonName = Common Name (eg, your name or your server\'s hostname)
commonName_max = 64
name = Name
name_max = 64
emailAddress = Email Address
emailAddress_default = $ENV::KEY_EMAIL
emailAddress_max = 40
# JY -- added for batch mode
organizationalUnitName_default = $ENV::KEY_OU
commonName_default = $ENV::KEY_CN
name_default = $ENV::KEY_NAME
# SET-ex3 = SET extension number 3
[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 4
challengePassword_max = 20
unstructuredName = An optional company name
[ usr_cert ]
# These extensions are added when 'ca' signs a request.
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# This will be displayed in Netscape's comment listbox.
nsComment = "Easy-RSA Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer:always
extendedKeyUsage=clientAuth
keyUsage = digitalSignature
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# Copy subject details
# issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
[ server ]
# JY ADDED -- Make a cert with nsCertType set to "server"
basicConstraints=CA:FALSE
nsCertType = server
nsComment = "Easy-RSA Generated Server Certificate"
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer:always
extendedKeyUsage=serverAuth
keyUsage = digitalSignature, keyEncipherment
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[ v3_ca ]
# Extensions for a typical CA
# PKIX recommendation.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always
# This is what PKIX recommends but some broken software chokes on critical
# extensions.
#basicConstraints = critical,CA:true
# So we do this instead.
basicConstraints = CA:true
# Key usage: this is typical for a CA certificate. However since it will
# prevent it being used as an test self-signed certificate it is best
# left out by default.
# keyUsage = cRLSign, keyCertSign
# Some might want this also
# nsCertType = sslCA, emailCA
# Include email address in subject alt name: another PKIX recommendation
# subjectAltName=email:copy
# Copy issuer details
# issuerAltName=issuer:copy
# DER hex encoding of an extension: beware experts only!
# obj=DER:02:03
# Where 'obj' is a standard or added object
# You can even override a supported extension:
# basicConstraints= critical, DER:30:03:01:01:FF
[ crl_ext ]
# CRL extensions.
# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
# issuerAltName=issuer:copy
authorityKeyIdentifier=keyid:always,issuer:always
[ engine_section ]
#
# If you are using PKCS#11
# Install engine_pkcs11 of opensc (www.opensc.org)
# And uncomment the following
# verify that dynamic_path points to the correct location
#
#pkcs11 = pkcs11_section
[ pkcs11_section ]
engine_id = pkcs11
dynamic_path = /usr/lib/engines/engine_pkcs11.so
MODULE_PATH = $ENV::PKCS11_MODULE_PATH
PIN = $ENV::PKCS11_PIN
init = 0

373
easy-rsa/2.0/pkitool Executable file
View file

@ -0,0 +1,373 @@
#!/bin/sh
# OpenVPN -- An application to securely tunnel IP networks
# over a single TCP/UDP port, with support for SSL/TLS-based
# session authentication and key exchange,
# packet encryption, packet authentication, and
# packet compression.
#
# Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2
# 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 (see the file COPYING included with this
# distribution); if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# pkitool is a front-end for the openssl tool.
# Calling scripts can set the certificate organizational
# unit with the KEY_OU environmental variable.
# Calling scripts can also set the KEY_NAME environmental
# variable to set the "name" X509 subject field.
PROGNAME=pkitool
VERSION=2.0
DEBUG=0
die()
{
local m="$1"
echo "$m" >&2
exit 1
}
need_vars()
{
echo ' Please edit the vars script to reflect your configuration,'
echo ' then source it with "source ./vars".'
echo ' Next, to start with a fresh PKI configuration and to delete any'
echo ' previous certificates and keys, run "./clean-all".'
echo " Finally, you can run this tool ($PROGNAME) to build certificates/keys."
}
usage()
{
echo "$PROGNAME $VERSION"
echo "Usage: $PROGNAME [options...] [common-name]"
echo "Options:"
echo " --batch : batch mode (default)"
echo " --keysize : Set keysize"
echo " size : size (default=1024)"
echo " --interact : interactive mode"
echo " --server : build server cert"
echo " --initca : build root CA"
echo " --inter : build intermediate CA"
echo " --pass : encrypt private key with password"
echo " --csr : only generate a CSR, do not sign"
echo " --sign : sign an existing CSR"
echo " --pkcs12 : generate a combined PKCS#12 file"
echo " --pkcs11 : generate certificate on PKCS#11 token"
echo " lib : PKCS#11 library"
echo " slot : PKCS#11 slot"
echo " id : PKCS#11 object id (hex string)"
echo " label : PKCS#11 object label"
echo "Standalone options:"
echo " --pkcs11-slots : list PKCS#11 slots"
echo " lib : PKCS#11 library"
echo " --pkcs11-objects : list PKCS#11 token objects"
echo " lib : PKCS#11 library"
echo " slot : PKCS#11 slot"
echo " --pkcs11-init : initialize PKCS#11 token DANGEROUS!!!"
echo " lib : PKCS#11 library"
echo " slot : PKCS#11 slot"
echo " label : PKCS#11 token label"
echo "Notes:"
need_vars
echo " In order to use PKCS#11 interface you must have opensc-0.10.0 or higher."
echo "Generated files and corresponding OpenVPN directives:"
echo '(Files will be placed in the $KEY_DIR directory, defined in ./vars)'
echo " ca.crt -> root certificate (--ca)"
echo " ca.key -> root key, keep secure (not directly used by OpenVPN)"
echo " .crt files -> client/server certificates (--cert)"
echo " .key files -> private keys, keep secure (--key)"
echo " .csr files -> certificate signing request (not directly used by OpenVPN)"
echo " dh1024.pem or dh2048.pem -> Diffie Hellman parameters (--dh)"
echo "Examples:"
echo " $PROGNAME --initca -> Build root certificate"
echo " $PROGNAME --initca --pass -> Build root certificate with password-protected key"
echo " $PROGNAME --server server1 -> Build \"server1\" certificate/key"
echo " $PROGNAME client1 -> Build \"client1\" certificate/key"
echo " $PROGNAME --pass client2 -> Build password-protected \"client2\" certificate/key"
echo " $PROGNAME --pkcs12 client3 -> Build \"client3\" certificate/key in PKCS#12 format"
echo " $PROGNAME --csr client4 -> Build \"client4\" CSR to be signed by another CA"
echo " $PROGNAME --sign client4 -> Sign \"client4\" CSR"
echo " $PROGNAME --inter interca -> Build an intermediate key-signing certificate/key"
echo " Also see ./inherit-inter script."
echo " $PROGNAME --pkcs11 /usr/lib/pkcs11/lib1 0 010203 \"client5 id\" client5"
echo " -> Build \"client5\" certificate/key in PKCS#11 token"
echo "Typical usage for initial PKI setup. Build myserver, client1, and client2 cert/keys."
echo "Protect client2 key with a password. Build DH parms. Generated files in ./keys :"
echo " [edit vars with your site-specific info]"
echo " source ./vars"
echo " ./clean-all"
echo " ./build-dh -> takes a long time, consider backgrounding"
echo " ./$PROGNAME --initca"
echo " ./$PROGNAME --server myserver"
echo " ./$PROGNAME client1"
echo " ./$PROGNAME --pass client2"
echo "Typical usage for adding client cert to existing PKI:"
echo " source ./vars"
echo " ./$PROGNAME client-new"
}
# Set tool defaults
[ -n "$OPENSSL" ] || export OPENSSL="openssl"
[ -n "$PKCS11TOOL" ] || export PKCS11TOOL="pkcs11-tool"
[ -n "$GREP" ] || export GREP="grep"
# Set defaults
DO_REQ="1"
REQ_EXT=""
DO_CA="1"
CA_EXT=""
DO_P12="0"
DO_P11="0"
DO_ROOT="0"
NODES_REQ="-nodes"
NODES_P12=""
BATCH="-batch"
CA="ca"
# must be set or errors of openssl.cnf
PKCS11_MODULE_PATH="dummy"
PKCS11_PIN="dummy"
# Process options
while [ $# -gt 0 ]; do
case "$1" in
--keysize ) KEY_SIZE=$2
shift;;
--server ) REQ_EXT="$REQ_EXT -extensions server"
CA_EXT="$CA_EXT -extensions server" ;;
--batch ) BATCH="-batch" ;;
--interact ) BATCH="" ;;
--inter ) CA_EXT="$CA_EXT -extensions v3_ca" ;;
--initca ) DO_ROOT="1" ;;
--pass ) NODES_REQ="" ;;
--csr ) DO_CA="0" ;;
--sign ) DO_REQ="0" ;;
--pkcs12 ) DO_P12="1" ;;
--pkcs11 ) DO_P11="1"
PKCS11_MODULE_PATH="$2"
PKCS11_SLOT="$3"
PKCS11_ID="$4"
PKCS11_LABEL="$5"
shift 4;;
# standalone
--pkcs11-init)
PKCS11_MODULE_PATH="$2"
PKCS11_SLOT="$3"
PKCS11_LABEL="$4"
if [ -z "$PKCS11_LABEL" ]; then
die "Please specify library name, slot and label"
fi
$PKCS11TOOL --module "$PKCS11_MODULE_PATH" --init-token --slot "$PKCS11_SLOT" \
--label "$PKCS11_LABEL" &&
$PKCS11TOOL --module "$PKCS11_MODULE_PATH" --init-pin --slot "$PKCS11_SLOT"
exit $?;;
--pkcs11-slots)
PKCS11_MODULE_PATH="$2"
if [ -z "$PKCS11_MODULE_PATH" ]; then
die "Please specify library name"
fi
$PKCS11TOOL --module "$PKCS11_MODULE_PATH" --list-slots
exit 0;;
--pkcs11-objects)
PKCS11_MODULE_PATH="$2"
PKCS11_SLOT="$3"
if [ -z "$PKCS11_SLOT" ]; then
die "Please specify library name and slot"
fi
$PKCS11TOOL --module "$PKCS11_MODULE_PATH" --list-objects --login --slot "$PKCS11_SLOT"
exit 0;;
# errors
--* ) die "$PROGNAME: unknown option: $1" ;;
* ) break ;;
esac
shift
done
if ! [ -z "$BATCH" ]; then
if $OPENSSL version | grep 0.9.6 > /dev/null; then
die "Batch mode is unsupported in openssl<0.9.7"
fi
fi
if [ $DO_P12 -eq 1 -a $DO_P11 -eq 1 ]; then
die "PKCS#11 and PKCS#12 cannot be specified together"
fi
if [ $DO_P11 -eq 1 ]; then
if ! grep "^pkcs11.*=" "$KEY_CONFIG" > /dev/null; then
die "Please edit $KEY_CONFIG and setup PKCS#11 engine"
fi
fi
# If we are generating pkcs12, only encrypt the final step
if [ $DO_P12 -eq 1 ]; then
NODES_P12="$NODES_REQ"
NODES_REQ="-nodes"
fi
if [ $DO_P11 -eq 1 ]; then
if [ -z "$PKCS11_LABEL" ]; then
die "PKCS#11 arguments incomplete"
fi
fi
# If undefined, set default key expiration intervals
if [ -z "$KEY_EXPIRE" ]; then
KEY_EXPIRE=3650
fi
if [ -z "$CA_EXPIRE" ]; then
CA_EXPIRE=3650
fi
# Set organizational unit to empty string if undefined
if [ -z "$KEY_OU" ]; then
KEY_OU=""
fi
# Set X509 Name string to empty string if undefined
if [ -z "$KEY_NAME" ]; then
KEY_NAME=""
fi
# Set KEY_CN, FN
if [ $DO_ROOT -eq 1 ]; then
if [ -z "$KEY_CN" ]; then
if [ "$1" ]; then
KEY_CN="$1"
elif [ "$KEY_ORG" ]; then
KEY_CN="$KEY_ORG CA"
fi
fi
if [ $BATCH ] && [ "$KEY_CN" ]; then
echo "Using CA Common Name:" "$KEY_CN"
fi
FN="$KEY_CN"
elif [ $BATCH ] && [ "$KEY_CN" ]; then
echo "Using Common Name:" "$KEY_CN"
FN="$KEY_CN"
if [ "$1" ]; then
FN="$1"
fi
else
if [ $# -ne 1 ]; then
usage
exit 1
else
KEY_CN="$1"
fi
FN="$KEY_CN"
fi
export CA_EXPIRE KEY_EXPIRE KEY_OU KEY_NAME KEY_CN PKCS11_MODULE_PATH PKCS11_PIN
# Show parameters (debugging)
if [ $DEBUG -eq 1 ]; then
echo DO_REQ $DO_REQ
echo REQ_EXT $REQ_EXT
echo DO_CA $DO_CA
echo CA_EXT $CA_EXT
echo NODES_REQ $NODES_REQ
echo NODES_P12 $NODES_P12
echo DO_P12 $DO_P12
echo KEY_CN $KEY_CN
echo BATCH $BATCH
echo DO_ROOT $DO_ROOT
echo KEY_EXPIRE $KEY_EXPIRE
echo CA_EXPIRE $CA_EXPIRE
echo KEY_OU $KEY_OU
echo KEY_NAME $KEY_NAME
echo DO_P11 $DO_P11
echo PKCS11_MODULE_PATH $PKCS11_MODULE_PATH
echo PKCS11_SLOT $PKCS11_SLOT
echo PKCS11_ID $PKCS11_ID
echo PKCS11_LABEL $PKCS11_LABEL
fi
# Make sure ./vars was sourced beforehand
if [ -d "$KEY_DIR" ] && [ "$KEY_CONFIG" ]; then
cd "$KEY_DIR"
# Make sure $KEY_CONFIG points to the correct version
# of openssl.cnf
if $GREP -i 'easy-rsa version 2\.[0-9]' "$KEY_CONFIG" >/dev/null; then
:
else
echo "$PROGNAME: KEY_CONFIG (set by the ./vars script) is pointing to the wrong"
echo "version of openssl.cnf: $KEY_CONFIG"
echo "The correct version should have a comment that says: easy-rsa version 2.x";
exit 1;
fi
# Build root CA
if [ $DO_ROOT -eq 1 ]; then
$OPENSSL req $BATCH -days $CA_EXPIRE $NODES_REQ -new -newkey rsa:$KEY_SIZE -sha1 \
-x509 -keyout "$CA.key" -out "$CA.crt" -config "$KEY_CONFIG" && \
chmod 0600 "$CA.key"
else
# Make sure CA key/cert is available
if [ $DO_CA -eq 1 ] || [ $DO_P12 -eq 1 ]; then
if [ ! -r "$CA.crt" ] || [ ! -r "$CA.key" ]; then
echo "$PROGNAME: Need a readable $CA.crt and $CA.key in $KEY_DIR"
echo "Try $PROGNAME --initca to build a root certificate/key."
exit 1
fi
fi
# Generate key for PKCS#11 token
PKCS11_ARGS=
if [ $DO_P11 -eq 1 ]; then
stty -echo
echo -n "User PIN: "
read -r PKCS11_PIN
stty echo
export PKCS11_PIN
echo "Generating key pair on PKCS#11 token..."
$PKCS11TOOL --module "$PKCS11_MODULE_PATH" --keypairgen \
--login --pin "$PKCS11_PIN" \
--key-type rsa:1024 \
--slot "$PKCS11_SLOT" --id "$PKCS11_ID" --label "$PKCS11_LABEL" || exit 1
PKCS11_ARGS="-engine pkcs11 -keyform engine -key $PKCS11_SLOT:$PKCS11_ID"
fi
# Build cert/key
( [ $DO_REQ -eq 0 ] || $OPENSSL req $BATCH -days $KEY_EXPIRE $NODES_REQ -new -newkey rsa:$KEY_SIZE \
-keyout "$FN.key" -out "$FN.csr" $REQ_EXT -config "$KEY_CONFIG" $PKCS11_ARGS ) && \
( [ $DO_CA -eq 0 ] || $OPENSSL ca $BATCH -days $KEY_EXPIRE -out "$FN.crt" \
-in "$FN.csr" $CA_EXT -md sha1 -config "$KEY_CONFIG" ) && \
( [ $DO_P12 -eq 0 ] || $OPENSSL pkcs12 -export -inkey "$FN.key" \
-in "$FN.crt" -certfile "$CA.crt" -out "$FN.p12" $NODES_P12 ) && \
( [ $DO_CA -eq 0 -o $DO_P11 -eq 1 ] || chmod 0600 "$FN.key" ) && \
( [ $DO_P12 -eq 0 ] || chmod 0600 "$FN.p12" )
# Load certificate into PKCS#11 token
if [ $DO_P11 -eq 1 ]; then
$OPENSSL x509 -in "$FN.crt" -inform PEM -out "$FN.crt.der" -outform DER && \
$PKCS11TOOL --module "$PKCS11_MODULE_PATH" --write-object "$FN.crt.der" --type cert \
--login --pin "$PKCS11_PIN" \
--slot "$PKCS11_SLOT" --id "$PKCS11_ID" --label "$PKCS11_LABEL"
[ -e "$FN.crt.der" ]; rm "$FN.crt.der"
fi
fi
# Need definitions
else
need_vars
fi

40
easy-rsa/2.0/revoke-full Executable file
View file

@ -0,0 +1,40 @@
#!/bin/bash
# revoke a certificate, regenerate CRL,
# and verify revocation
CRL="crl.pem"
RT="revoke-test.pem"
if [ $# -ne 1 ]; then
echo "usage: revoke-full <cert-name-base>";
exit 1
fi
if [ "$KEY_DIR" ]; then
cd "$KEY_DIR"
rm -f "$RT"
# set defaults
export KEY_CN=""
export KEY_OU=""
export KEY_NAME=""
# revoke key and generate a new CRL
$OPENSSL ca -revoke "$1.crt" -config "$KEY_CONFIG"
# generate a new CRL -- try to be compatible with
# intermediate PKIs
$OPENSSL ca -gencrl -out "$CRL" -config "$KEY_CONFIG"
if [ -e export-ca.crt ]; then
cat export-ca.crt "$CRL" >"$RT"
else
cat ca.crt "$CRL" >"$RT"
fi
# verify the revocation
$OPENSSL verify -CAfile "$RT" -crl_check "$1.crt"
else
echo 'Please source the vars script first (i.e. "source ./vars")'
echo 'Make sure you have edited it to reflect your configuration.'
fi

7
easy-rsa/2.0/sign-req Executable file
View file

@ -0,0 +1,7 @@
#!/bin/bash
# Sign a certificate signing request (a .csr file)
# with a local root certificate and key.
export EASY_RSA="${EASY_RSA:-.}"
"$EASY_RSA/pkitool" --interact --sign $*

68
easy-rsa/2.0/vars Executable file
View file

@ -0,0 +1,68 @@
# easy-rsa parameter settings
# NOTE: If you installed from an RPM,
# don't edit this file in place in
# /usr/share/openvpn/easy-rsa --
# instead, you should copy the whole
# easy-rsa directory to another location
# (such as /etc/openvpn) so that your
# edits will not be wiped out by a future
# OpenVPN package upgrade.
# This variable should point to
# the top level of the easy-rsa
# tree.
export EASY_RSA="`pwd`"
#
# This variable should point to
# the requested executables
#
export OPENSSL="openssl"
export PKCS11TOOL="pkcs11-tool"
export GREP="grep"
# This variable should point to
# the openssl.cnf file included
# with easy-rsa.
export KEY_CONFIG=`$EASY_RSA/whichopensslcnf $EASY_RSA`
# Edit this variable to point to
# your soon-to-be-created key
# directory.
#
# WARNING: clean-all will do
# a rm -rf on this directory
# so make sure you define
# it correctly!
export KEY_DIR="$EASY_RSA/keys"
# Issue rm -rf warning
echo NOTE: If you run ./clean-all, I will be doing a rm -rf on $KEY_DIR
# PKCS11 fixes
export PKCS11_MODULE_PATH="dummy"
export PKCS11_PIN="dummy"
# Increase this to 2048 if you
# are paranoid. This will slow
# down TLS negotiation performance
# as well as the one-time DH parms
# generation process.
export KEY_SIZE=1024
# In how many days should the root CA key expire?
export CA_EXPIRE=3650
# In how many days should certificates expire?
export KEY_EXPIRE=3650
# These are the default values for fields
# which will be placed in the certificate.
# Don't leave any of these fields blank.
export KEY_COUNTRY="US"
export KEY_PROVINCE="CA"
export KEY_CITY="SanFrancisco"
export KEY_ORG="Fort-Funston"
export KEY_EMAIL="me@myhost.mydomain"

13
easy-rsa/2.0/whichopensslcnf Executable file
View file

@ -0,0 +1,13 @@
#!/bin/sh
if [ "$OPENSSL" ]; then
if $OPENSSL version | grep 0.9.6 > /dev/null; then
echo "$1/openssl-0.9.6.cnf"
else
echo "$1/openssl.cnf"
fi
else
echo "$1/openssl.cnf"
fi
exit 0

View file

@ -0,0 +1,44 @@
Extract all zip'd files to the OpenVPN home directory,
including the openssl.cnf file from the top-level
"easy-rsa" directory.
First run init-config.bat
Next, edit vars.bat to adapt it to your environment, and
create the directory that will hold your key files.
To generate TLS keys:
Create new empty index and serial files (once only)
1. vars
2. clean-all
Build a CA key (once only)
1. vars
2. build-ca
Build a DH file (for server side, once only)
1. vars
2. build-dh
Build a private key/certficate for the openvpn server
1. vars
2. build-key-server <machine-name>
Build key files in PEM format (for each client machine)
1. vars
2. build-key <machine-name>
(use <machine name> for specific name within script)
or
Build key files in PKCS #12 format (for each client machine)
1. vars
2. build-key-pkcs12 <machine-name>
(use <machine name> for specific name within script)
To revoke a TLS certificate and generate a CRL file:
1. vars
2. revoke-full <machine-name>
3. verify last line of output confirms revokation
4. copy crl.pem to server directory and ensure config file uses "crl-verify <crl filename>"

View file

@ -0,0 +1,8 @@
@echo off
cd %HOME%
rem build a request for a cert that will be valid for ten years
openssl req -days 3650 -new -keyout %KEY_DIR%\%1.key -out %KEY_DIR%\%1.csr -config %KEY_CONFIG%
rem sign the cert request with our ca, creating a cert/key pair
openssl ca -days 3650 -out %KEY_DIR%\%1.crt -in %KEY_DIR%\%1.csr -config %KEY_CONFIG%
rem delete any .old files created in this process, to avoid future file creation errors
del /q %KEY_DIR%\*.old

View file

@ -0,0 +1,4 @@
@echo off
cd %HOME%
rem build a cert authority valid for ten years, starting now
openssl req -days 3650 -nodes -new -x509 -keyout %KEY_DIR%\ca.key -out %KEY_DIR%\ca.crt -config %KEY_CONFIG%

View file

@ -0,0 +1,4 @@
@echo off
cd %HOME%
rem build a dh file for the server side
openssl dhparam -out %KEY_DIR%/dh%KEY_SIZE%.pem %KEY_SIZE%

View file

@ -0,0 +1,8 @@
@echo off
cd %HOME%
rem build a request for a cert that will be valid for ten years
openssl req -days 3650 -new -keyout %KEY_DIR%\%1.key -out %KEY_DIR%\%1.csr -config %KEY_CONFIG%
rem sign the cert request with our ca, creating a cert/key pair
openssl ca -days 3650 -out %KEY_DIR%\%1.crt -in %KEY_DIR%\%1.csr -config %KEY_CONFIG%
rem delete any .old files created in this process, to avoid future file creation errors
del /q %KEY_DIR%\*.old

View file

@ -0,0 +1,10 @@
@echo off
cd %HOME%
rem build a request for a cert that will be valid for ten years
openssl req -days 3650 -nodes -new -keyout %KEY_DIR%\%1.key -out %KEY_DIR%\%1.csr -config %KEY_CONFIG%
rem sign the cert request with our ca, creating a cert/key pair
openssl ca -days 3650 -out %KEY_DIR%\%1.crt -in %KEY_DIR%\%1.csr -config %KEY_CONFIG%
rem convert the key/cert and embed the ca cert into a pkcs12 file.
openssl pkcs12 -export -inkey %KEY_DIR%\%1.key -in %KEY_DIR%\%1.crt -certfile %KEY_DIR%\ca.crt -out %KEY_DIR%\%1.p12
rem delete any .old files created in this process, to avoid future file creation errors
del /q %KEY_DIR%\*.old

View file

@ -0,0 +1,8 @@
@echo off
cd %HOME%
rem build a request for a cert that will be valid for ten years
openssl req -days 3650 -new -keyout %KEY_DIR%\%1.key -out %KEY_DIR%\%1.csr -config %KEY_CONFIG%
rem sign the cert request with our ca, creating a cert/key pair
openssl ca -days 3650 -out %KEY_DIR%\%1.crt -in %KEY_DIR%\%1.csr -extensions server -config %KEY_CONFIG%
rem delete any .old files created in this process, to avoid future file creation errors
del /q %KEY_DIR%\*.old

View file

@ -0,0 +1,8 @@
@echo off
cd %HOME%
rem build a request for a cert that will be valid for ten years
openssl req -days 3650 -nodes -new -keyout %KEY_DIR%\%1.key -out %KEY_DIR%\%1.csr -config %KEY_CONFIG%
rem sign the cert request with our ca, creating a cert/key pair
openssl ca -days 3650 -out %KEY_DIR%\%1.crt -in %KEY_DIR%\%1.csr -extensions server -config %KEY_CONFIG%
rem delete any .old files created in this process, to avoid future file creation errors
del /q %KEY_DIR%\*.old

View file

@ -0,0 +1,8 @@
@echo off
cd %HOME%
rem build a request for a cert that will be valid for ten years
openssl req -days 3650 -nodes -new -keyout %KEY_DIR%\%1.key -out %KEY_DIR%\%1.csr -config %KEY_CONFIG%
rem sign the cert request with our ca, creating a cert/key pair
openssl ca -days 3650 -out %KEY_DIR%\%1.crt -in %KEY_DIR%\%1.csr -config %KEY_CONFIG%
rem delete any .old files created in this process, to avoid future file creation errors
del /q %KEY_DIR%\*.old

View file

@ -0,0 +1,13 @@
@echo off
rem move to the HOME directory specified in VARS script
cd %HOME%
rem set a temporary KEY_DIR variable
set d=%KEY_DIR%
rem delete the KEY_DIR and any subdirs quietly
rmdir /s /q %d%
rem make a new KEY_DIR
mkdir %d%
rem copy in a fesh index file so we begin with an empty database
copy index.txt.start %d%\index.txt
rem copy in a fresh serial file so we begin generating keys at index 01
copy serial.start %d%\serial.

View file

View file

@ -0,0 +1,2 @@
copy vars.bat.sample vars.bat
copy openssl.cnf.sample openssl.cnf

View file

@ -0,0 +1,13 @@
@echo off
cd %HOME%
rem revoke cert
openssl ca -revoke %KEY_DIR%\%1.crt -config %KEY_CONFIG%
rem generate new crl
openssl ca -gencrl -out %KEY_DIR%\crl.pem -config %KEY_CONFIG%
rem test revocation
rem first concatinate ca cert with newly generated crl
copy %KEY_DIR%\ca.crt+%KEY_DIR%\crl.pem %KEY_DIR%\revoke_test_file.pem
rem now verify the revocation
openssl verify -CAfile %KEY_DIR%\revoke_test_file.pem -crl_check %KEY_DIR%\%1.crt
rem delete temporary test file
del /q %KEY_DIR%\revoke_test_file.pem

View file

@ -0,0 +1 @@
01

View file

@ -0,0 +1,35 @@
@echo off
rem Edit this variable to point to
rem the openssl.cnf file included
rem with easy-rsa.
set HOME=%ProgramFiles%\OpenVPN\easy-rsa
set KEY_CONFIG=openssl.cnf
rem Edit this variable to point to
rem your soon-to-be-created key
rem directory.
rem
rem WARNING: clean-all will do
rem a rm -rf on this directory
rem so make sure you define
rem it correctly!
set KEY_DIR=keys
rem Increase this to 2048 if you
rem are paranoid. This will slow
rem down TLS negotiation performance
rem as well as the one-time DH parms
rem generation process.
set KEY_SIZE=1024
rem These are the default values for fields
rem which will be placed in the certificate.
rem Change these to reflect your site.
rem Don't leave any of these parms blank.
set KEY_COUNTRY=US
set KEY_PROVINCE=CA
set KEY_CITY=SanFrancisco
set KEY_ORG=OpenVPN
set KEY_EMAIL=mail@host.domain

179
errlevel.h Normal file
View file

@ -0,0 +1,179 @@
/*
* OpenVPN -- An application to securely tunnel IP networks
* over a single TCP/UDP port, with support for SSL/TLS-based
* session authentication and key exchange,
* packet encryption, packet authentication, and
* packet compression.
*
* Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* 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 (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef ERRLEVEL_H
#define ERRLEVEL_H
#include "error.h"
/*
* Debug level at and above where we
* display time to microsecond resolution.
*/
#define DEBUG_LEVEL_USEC_TIME 4
/*
* In non-server modes, delay n milliseconds after certain kinds
* of non-fatal network errors to avoid a barrage of errors.
*
* To disable all delays, set to 0.
*/
#define P2P_ERROR_DELAY_MS 0
/*
* Enable D_LOG_RW
*/
#define LOG_RW
/*
* Debugging levels for various kinds
* of output.
*/
#define M_VERB0 LOGLEV(0, 0, 0) /* Messages displayed even at --verb 0 (fatal errors only) */
#define M_INFO LOGLEV(1, 0, 0) /* default informational messages */
#define D_LINK_ERRORS LOGLEV(1, 1, M_NONFATAL) /* show link errors from main event loop */
#define D_CRYPT_ERRORS LOGLEV(1, 2, M_NONFATAL) /* show errors from encrypt/decrypt */
#define D_TLS_ERRORS LOGLEV(1, 3, M_NONFATAL) /* show TLS control channel errors */
#define D_RESOLVE_ERRORS LOGLEV(1, 4, M_NONFATAL) /* show hostname resolve errors */
#define D_COMP_ERRORS LOGLEV(1, 5, M_NONFATAL) /* show compression errors */
#define D_REPLAY_ERRORS LOGLEV(1, 6, M_NONFATAL) /* show packet replay errors */
#define D_STREAM_ERRORS LOGLEV(1, 7, M_NONFATAL) /* TCP stream error requiring restart */
#define D_IMPORT_ERRORS LOGLEV(1, 8, M_NONFATAL) /* show server import option errors */
#define D_MULTI_ERRORS LOGLEV(1, 9, M_NONFATAL) /* show multi-client server errors */
#define D_EVENT_ERRORS LOGLEV(1, 10, M_NONFATAL) /* show event.[ch] errors */
#define D_PUSH_ERRORS LOGLEV(1, 11, M_NONFATAL) /* show push/pull errors */
#define D_PID_PERSIST LOGLEV(1, 12, M_NONFATAL) /* show packet_id persist errors */
#define D_FRAG_ERRORS LOGLEV(1, 13, M_NONFATAL) /* show fragmentation errors */
#define D_ALIGN_ERRORS LOGLEV(1, 14, M_NONFATAL) /* show bad struct alignments */
#define D_HANDSHAKE LOGLEV(2, 20, 0) /* show data & control channel handshakes */
#define D_CLOSE LOGLEV(2, 22, 0) /* show socket and TUN/TAP close */
#define D_PROXY LOGLEV(2, 24, 0) /* show http proxy control packets */
#define D_ARGV LOGLEV(2, 25, 0) /* show struct argv errors */
#define D_TLS_DEBUG_LOW LOGLEV(3, 20, 0) /* low frequency info from tls_session routines */
#define D_GREMLIN LOGLEV(3, 30, 0) /* show simulated outage info from gremlin module */
#define D_GENKEY LOGLEV(3, 31, 0) /* print message after key generation */
#define D_ROUTE LOGLEV(3, 0, 0) /* show routes added and deleted (don't mute) */
#define D_TUNTAP_INFO LOGLEV(3, 32, 0) /* show debugging info from TUN/TAP driver */
#define D_RESTART LOGLEV(3, 33, 0) /* show certain restart messages */
#define D_PUSH LOGLEV(3, 34, 0) /* show push/pull info */
#define D_IFCONFIG_POOL LOGLEV(3, 35, 0) /* show ifconfig pool info */
#define D_BACKTRACK LOGLEV(3, 36, 0) /* show replay backtracks */
#define D_AUTH LOGLEV(3, 37, 0) /* show user/pass auth info */
#define D_MULTI_LOW LOGLEV(3, 38, 0) /* show point-to-multipoint low-freq debug info */
#define D_PLUGIN LOGLEV(3, 39, 0) /* show plugin calls */
#define D_MANAGEMENT LOGLEV(3, 40, 0) /* show --management info */
#define D_SCHED_EXIT LOGLEV(3, 41, 0) /* show arming of scheduled exit */
#define D_ROUTE_QUOTA LOGLEV(3, 42, 0) /* show route quota exceeded messages */
#define D_OSBUF LOGLEV(3, 43, 0) /* show socket/tun/tap buffer sizes */
#define D_PS_PROXY LOGLEV(3, 44, 0) /* messages related to --port-share option */
#define D_PF_INFO LOGLEV(3, 45, 0) /* packet filter informational messages */
#define D_SHOW_PARMS LOGLEV(4, 50, 0) /* show all parameters on program initiation */
#define D_SHOW_OCC LOGLEV(4, 51, 0) /* show options compatibility string */
#define D_LOW LOGLEV(4, 52, 0) /* miscellaneous low-frequency debug info */
#define D_DHCP_OPT LOGLEV(4, 53, 0) /* show DHCP options binary string */
#define D_MBUF LOGLEV(4, 54, 0) /* mbuf.[ch] routines */
#define D_PACKET_TRUNC_ERR LOGLEV(4, 55, 0) /* PACKET_TRUNCATION_CHECK */
#define D_PF_DROPPED LOGLEV(4, 56, 0) /* packet filter dropped a packet */
#define D_MULTI_DROPPED LOGLEV(4, 57, 0) /* show point-to-multipoint packet drops */
#define D_MULTI_MEDIUM LOGLEV(4, 58, 0) /* show medium frequency multi messages */
#define D_X509_ATTR LOGLEV(4, 59, 0) /* show x509-track attributes on connection */
#define D_INIT_MEDIUM LOGLEV(4, 60, 0) /* show medium frequency init messages */
#define D_MTU_INFO LOGLEV(4, 61, 0) /* show terse MTU info */
#define D_SHOW_OCC_HASH LOGLEV(4, 62, 0) /* show MD5 hash of option compatibility string */
#define D_LOG_RW LOGLEV(5, 0, 0) /* Print 'R' or 'W' to stdout for read/write */
#define D_LINK_RW LOGLEV(6, 69, M_DEBUG) /* show TCP/UDP reads/writes (terse) */
#define D_TUN_RW LOGLEV(6, 69, M_DEBUG) /* show TUN/TAP reads/writes */
#define D_TAP_WIN32_DEBUG LOGLEV(6, 69, M_DEBUG) /* show TAP-Win32 driver debug info */
#define D_CLIENT_NAT LOGLEV(6, 69, M_DEBUG) /* show client NAT debug info */
#define D_SHOW_KEYS LOGLEV(7, 70, M_DEBUG) /* show data channel encryption keys */
#define D_SHOW_KEY_SOURCE LOGLEV(7, 70, M_DEBUG) /* show data channel key source entropy */
#define D_REL_LOW LOGLEV(7, 70, M_DEBUG) /* show low frequency info from reliable layer */
#define D_FRAG_DEBUG LOGLEV(7, 70, M_DEBUG) /* show fragment debugging info */
#define D_WIN32_IO_LOW LOGLEV(7, 70, M_DEBUG) /* low freq win32 I/O debugging info */
#define D_MTU_DEBUG LOGLEV(7, 70, M_DEBUG) /* show MTU debugging info */
#define D_PID_DEBUG_LOW LOGLEV(7, 70, M_DEBUG) /* show low-freq packet-id debugging info */
#define D_MULTI_DEBUG LOGLEV(7, 70, M_DEBUG) /* show medium-freq multi debugging info */
#define D_MSS LOGLEV(7, 70, M_DEBUG) /* show MSS adjustments */
#define D_COMP_LOW LOGLEV(7, 70, M_DEBUG) /* show adaptive compression state changes */
#define D_CONNECTION_LIST LOGLEV(7, 70, M_DEBUG) /* show <connection> list info */
#define D_SCRIPT LOGLEV(7, 70, M_DEBUG) /* show parms & env vars passed to scripts */
#define D_SHOW_NET LOGLEV(7, 70, M_DEBUG) /* show routing table and adapter list */
#define D_ROUTE_DEBUG LOGLEV(7, 70, M_DEBUG) /* show verbose route.[ch] output */
#define D_TLS_STATE_ERRORS LOGLEV(7, 70, M_DEBUG) /* no TLS state for client */
#define D_SEMAPHORE_LOW LOGLEV(7, 70, M_DEBUG) /* show Win32 semaphore waits (low freq) */
#define D_SEMAPHORE LOGLEV(7, 70, M_DEBUG) /* show Win32 semaphore waits */
#define D_TEST_FILE LOGLEV(7, 70, M_DEBUG) /* show test_file() calls */
#define D_MANAGEMENT_DEBUG LOGLEV(3, 70, M_DEBUG) /* show --management debug info */
#define D_PLUGIN_DEBUG LOGLEV(7, 70, M_DEBUG) /* show verbose plugin calls */
#define D_SOCKET_DEBUG LOGLEV(7, 70, M_DEBUG) /* show socket.[ch] debugging info */
#define D_SHOW_PKCS11 LOGLEV(7, 70, M_DEBUG) /* show PKCS#11 actions */
#define D_ALIGN_DEBUG LOGLEV(7, 70, M_DEBUG) /* show verbose struct alignment info */
#define D_PACKET_TRUNC_DEBUG LOGLEV(7, 70, M_DEBUG) /* PACKET_TRUNCATION_CHECK verbose */
#define D_PING LOGLEV(7, 70, M_DEBUG) /* PING send/receive messages */
#define D_PS_PROXY_DEBUG LOGLEV(7, 70, M_DEBUG) /* port share proxy debug */
#define D_AUTO_USERID LOGLEV(7, 70, M_DEBUG) /* AUTO_USERID debugging */
#define D_TLS_KEYSELECT LOGLEV(7, 70, M_DEBUG) /* show information on key selection for data channel */
#define D_ARGV_PARSE_CMD LOGLEV(7, 70, M_DEBUG) /* show parse_line() errors in argv_printf %sc */
#define D_CRYPTO_DEBUG LOGLEV(7, 70, M_DEBUG) /* show detailed info from crypto.c routines */
#define D_PF_DROPPED_BCAST LOGLEV(7, 71, M_DEBUG) /* packet filter dropped a broadcast packet */
#define D_PF_DEBUG LOGLEV(7, 72, M_DEBUG) /* packet filter debugging, must also define PF_DEBUG in pf.h */
#define D_HANDSHAKE_VERBOSE LOGLEV(8, 70, M_DEBUG) /* show detailed description of each handshake */
#define D_TLS_DEBUG_MED LOGLEV(8, 70, M_DEBUG) /* limited info from tls_session routines */
#define D_INTERVAL LOGLEV(8, 70, M_DEBUG) /* show interval.h debugging info */
#define D_SCHEDULER LOGLEV(8, 70, M_DEBUG) /* show scheduler debugging info */
#define D_GREMLIN_VERBOSE LOGLEV(8, 70, M_DEBUG) /* show verbose info from gremlin module */
#define D_REL_DEBUG LOGLEV(8, 70, M_DEBUG) /* show detailed info from reliable routines */
#define D_EVENT_WAIT LOGLEV(8, 70, M_DEBUG) /* show detailed info from event waits */
#define D_MULTI_TCP LOGLEV(8, 70, M_DEBUG) /* show debug info from mtcp.c */
#define D_TLS_DEBUG LOGLEV(9, 70, M_DEBUG) /* show detailed info from TLS routines */
#define D_COMP LOGLEV(9, 70, M_DEBUG) /* show compression info */
#define D_READ_WRITE LOGLEV(9, 70, M_DEBUG) /* show all tun/tcp/udp reads/writes/opens */
#define D_PACKET_CONTENT LOGLEV(9, 70, M_DEBUG) /* show before/after encryption packet content */
#define D_TLS_NO_SEND_KEY LOGLEV(9, 70, M_DEBUG) /* show when no data channel send-key exists */
#define D_PID_DEBUG LOGLEV(9, 70, M_DEBUG) /* show packet-id debugging info */
#define D_PID_PERSIST_DEBUG LOGLEV(9, 70, M_DEBUG) /* show packet-id persist debugging info */
#define D_LINK_RW_VERBOSE LOGLEV(9, 70, M_DEBUG) /* show link reads/writes with greater verbosity */
#define D_STREAM_DEBUG LOGLEV(9, 70, M_DEBUG) /* show TCP stream debug info */
#define D_WIN32_IO LOGLEV(9, 70, M_DEBUG) /* win32 I/O debugging info */
#define D_PKCS11_DEBUG LOGLEV(9, 70, M_DEBUG) /* show PKCS#11 debugging */
#define D_SHAPER_DEBUG LOGLEV(10, 70, M_DEBUG) /* show traffic shaper info */
#define D_REGISTRY LOGLEV(11, 70, M_DEBUG) /* win32 registry debugging info */
#define D_OPENSSL_LOCK LOGLEV(11, 70, M_DEBUG) /* show OpenSSL locks */
/*#define D_THREAD_DEBUG LOGLEV(4, 70, M_DEBUG)*/ /* show pthread debug information */
#endif

905
error.c Normal file
View file

@ -0,0 +1,905 @@
/*
* OpenVPN -- An application to securely tunnel IP networks
* over a single TCP/UDP port, with support for SSL/TLS-based
* session authentication and key exchange,
* packet encryption, packet authentication, and
* packet compression.
*
* Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* 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 (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "syshead.h"
#include "error.h"
#include "buffer.h"
#include "thread.h"
#include "misc.h"
#include "win32.h"
#include "socket.h"
#include "tun.h"
#include "otime.h"
#include "perf.h"
#include "status.h"
#include "integer.h"
#include "ps.h"
#ifdef USE_CRYPTO
#include <openssl/err.h>
#endif
#include "memdbg.h"
#if SYSLOG_CAPABILITY
#ifndef LOG_OPENVPN
#define LOG_OPENVPN LOG_DAEMON
#endif
#endif
/* Globals */
unsigned int x_debug_level; /* GLOBAL */
/* Mute state */
static int mute_cutoff; /* GLOBAL */
static int mute_count; /* GLOBAL */
static int mute_category; /* GLOBAL */
/*
* Output mode priorities are as follows:
*
* (1) --log-x overrides everything
* (2) syslog is used if --daemon or --inetd is defined and not --log-x
* (3) if OPENVPN_DEBUG_COMMAND_LINE is defined, output
* to constant logfile name.
* (4) Output to stdout.
*/
/* If true, indicates that stdin/stdout/stderr
have been redirected due to --log */
static bool std_redir; /* GLOBAL */
/* Should messages be written to the syslog? */
static bool use_syslog; /* GLOBAL */
/* Should timestamps be included on messages to stdout/stderr? */
static bool suppress_timestamps; /* GLOBAL */
/* The program name passed to syslog */
#if SYSLOG_CAPABILITY
static char *pgmname_syslog; /* GLOBAL */
#endif
/* If non-null, messages should be written here (used for debugging only) */
static FILE *msgfp; /* GLOBAL */
/* If true, we forked from main OpenVPN process */
static bool forked; /* GLOBAL */
/* our default output targets */
static FILE *default_out; /* GLOBAL */
static FILE *default_err; /* GLOBAL */
void
msg_forked (void)
{
forked = true;
}
bool
set_debug_level (const int level, const unsigned int flags)
{
const int ceiling = 15;
if (level >= 0 && level <= ceiling)
{
x_debug_level = level;
return true;
}
else if (flags & SDL_CONSTRAIN)
{
x_debug_level = constrain_int (level, 0, ceiling);
return true;
}
return false;
}
bool
set_mute_cutoff (const int cutoff)
{
if (cutoff >= 0)
{
mute_cutoff = cutoff;
return true;
}
else
return false;
}
int
get_debug_level (void)
{
return x_debug_level;
}
int
get_mute_cutoff (void)
{
return mute_cutoff;
}
void
set_suppress_timestamps (bool suppressed)
{
suppress_timestamps = suppressed;
}
void
error_reset ()
{
use_syslog = std_redir = false;
suppress_timestamps = false;
x_debug_level = 1;
mute_cutoff = 0;
mute_count = 0;
mute_category = 0;
default_out = OPENVPN_MSG_FP;
default_err = OPENVPN_MSG_FP;
#ifdef OPENVPN_DEBUG_COMMAND_LINE
msgfp = fopen (OPENVPN_DEBUG_FILE, "w");
if (!msgfp)
openvpn_exit (OPENVPN_EXIT_STATUS_CANNOT_OPEN_DEBUG_FILE); /* exit point */
#else
msgfp = NULL;
#endif
}
void
errors_to_stderr (void)
{
default_err = OPENVPN_ERROR_FP;
}
/*
* Return a file to print messages to before syslog is opened.
*/
FILE *
msg_fp(const unsigned int flags)
{
FILE *fp = msgfp;
if (!fp)
fp = (flags & (M_FATAL|M_USAGE_SMALL)) ? default_err : default_out;
if (!fp)
openvpn_exit (OPENVPN_EXIT_STATUS_CANNOT_OPEN_DEBUG_FILE); /* exit point */
return fp;
}
#define SWAP { tmp = m1; m1 = m2; m2 = tmp; }
int x_msg_line_num; /* GLOBAL */
void x_msg (const unsigned int flags, const char *format, ...)
{
struct gc_arena gc;
va_list arglist;
#if SYSLOG_CAPABILITY
int level;
#endif
char *m1;
char *m2;
char *tmp;
int e;
const char *prefix;
const char *prefix_sep;
void usage_small (void);
#ifndef HAVE_VARARG_MACROS
/* the macro has checked this otherwise */
if (!MSG_TEST (flags))
return;
#endif
if (flags & M_ERRNO_SOCK)
e = openvpn_errno_socket ();
else
e = openvpn_errno ();
/*
* Apply muting filter.
*/
#ifndef HAVE_VARARG_MACROS
/* the macro has checked this otherwise */
if (!dont_mute (flags))
return;
#endif
gc_init (&gc);
mutex_lock_static (L_MSG);
m1 = (char *) gc_malloc (ERR_BUF_SIZE, false, &gc);
m2 = (char *) gc_malloc (ERR_BUF_SIZE, false, &gc);
va_start (arglist, format);
vsnprintf (m1, ERR_BUF_SIZE, format, arglist);
va_end (arglist);
m1[ERR_BUF_SIZE - 1] = 0; /* windows vsnprintf needs this */
if ((flags & (M_ERRNO|M_ERRNO_SOCK)) && e)
{
openvpn_snprintf (m2, ERR_BUF_SIZE, "%s: %s (errno=%d)",
m1, strerror_ts (e, &gc), e);
SWAP;
}
#ifdef USE_CRYPTO
if (flags & M_SSL)
{
int nerrs = 0;
int err;
while ((err = ERR_get_error ()))
{
openvpn_snprintf (m2, ERR_BUF_SIZE, "%s: %s",
m1, ERR_error_string (err, NULL));
SWAP;
++nerrs;
}
if (!nerrs)
{
openvpn_snprintf (m2, ERR_BUF_SIZE, "%s (OpenSSL)", m1);
SWAP;
}
}
#endif
if (flags & M_OPTERR)
{
openvpn_snprintf (m2, ERR_BUF_SIZE, "Options error: %s", m1);
SWAP;
}
#if SYSLOG_CAPABILITY
if (flags & (M_FATAL|M_NONFATAL|M_USAGE_SMALL))
level = LOG_ERR;
else if (flags & M_WARN)
level = LOG_WARNING;
else
level = LOG_NOTICE;
#endif
/* set up client prefix */
if (flags & M_NOIPREFIX)
prefix = NULL;
else
prefix = msg_get_prefix ();
prefix_sep = " ";
if (!prefix)
prefix_sep = prefix = "";
/* virtual output capability used to copy output to management subsystem */
if (!forked)
{
const struct virtual_output *vo = msg_get_virtual_output ();
if (vo)
{
openvpn_snprintf (m2, ERR_BUF_SIZE, "%s%s%s",
prefix,
prefix_sep,
m1);
virtual_output_print (vo, flags, m2);
}
}
if (!(flags & M_MSG_VIRT_OUT))
{
if (use_syslog && !std_redir && !forked)
{
#if SYSLOG_CAPABILITY
syslog (level, "%s%s%s",
prefix,
prefix_sep,
m1);
#endif
}
else
{
FILE *fp = msg_fp(flags);
const bool show_usec = check_debug_level (DEBUG_LEVEL_USEC_TIME);
if ((flags & M_NOPREFIX) || suppress_timestamps)
{
fprintf (fp, "%s%s%s%s",
prefix,
prefix_sep,
m1,
(flags&M_NOLF) ? "" : "\n");
}
else
{
#ifdef USE_PTHREAD
fprintf (fp, "%s [%d] %s%s%s%s",
time_string (0, 0, show_usec, &gc),
(int) openvpn_thread_self (),
prefix,
prefix_sep,
m1,
(flags&M_NOLF) ? "" : "\n");
#else
fprintf (fp, "%s %s%s%s%s",
time_string (0, 0, show_usec, &gc),
prefix,
prefix_sep,
m1,
(flags&M_NOLF) ? "" : "\n");
#endif
}
fflush(fp);
++x_msg_line_num;
}
}
if (flags & M_FATAL)
msg (M_INFO, "Exiting due to fatal error");
mutex_unlock_static (L_MSG);
if (flags & M_FATAL)
openvpn_exit (OPENVPN_EXIT_STATUS_ERROR); /* exit point */
if (flags & M_USAGE_SMALL)
usage_small ();
gc_free (&gc);
}
/*
* Apply muting filter.
*/
bool
dont_mute (unsigned int flags)
{
bool ret = true;
if (mute_cutoff > 0 && !(flags & M_NOMUTE))
{
const int mute_level = DECODE_MUTE_LEVEL (flags);
if (mute_level > 0 && mute_level == mute_category)
{
if (mute_count == mute_cutoff)
msg (M_INFO | M_NOMUTE, "NOTE: --mute triggered...");
if (++mute_count > mute_cutoff)
ret = false;
}
else
{
const int suppressed = mute_count - mute_cutoff;
if (suppressed > 0)
msg (M_INFO | M_NOMUTE,
"%d variation(s) on previous %d message(s) suppressed by --mute",
suppressed,
mute_cutoff);
mute_count = 1;
mute_category = mute_level;
}
}
return ret;
}
void
assert_failed (const char *filename, int line)
{
msg (M_FATAL, "Assertion failed at %s:%d", filename, line);
}
/*
* Fail memory allocation. Don't use msg() because it tries
* to allocate memory as part of its operation.
*/
void
out_of_memory (void)
{
fprintf (stderr, PACKAGE_NAME ": Out of Memory\n");
exit (1);
}
void
open_syslog (const char *pgmname, bool stdio_to_null)
{
#if SYSLOG_CAPABILITY
if (!msgfp && !std_redir)
{
if (!use_syslog)
{
pgmname_syslog = string_alloc (pgmname ? pgmname : PACKAGE, NULL);
openlog (pgmname_syslog, LOG_PID, LOG_OPENVPN);
use_syslog = true;
/* Better idea: somehow pipe stdout/stderr output to msg() */
if (stdio_to_null)
set_std_files_to_null (false);
}
}
#else
msg (M_WARN, "Warning on use of --daemon/--inetd: this operating system lacks daemon logging features, therefore when I become a daemon, I won't be able to log status or error messages");
#endif
}
void
close_syslog ()
{
#if SYSLOG_CAPABILITY
if (use_syslog)
{
closelog();
use_syslog = false;
if (pgmname_syslog)
{
free (pgmname_syslog);
pgmname_syslog = NULL;
}
}
#endif
}
#ifdef WIN32
static HANDLE orig_stderr;
HANDLE
get_orig_stderr (void)
{
if (orig_stderr)
return orig_stderr;
else
return GetStdHandle (STD_ERROR_HANDLE);
}
#endif
void
redirect_stdout_stderr (const char *file, bool append)
{
#if defined(WIN32)
if (!std_redir)
{
HANDLE log_handle;
int log_fd;
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
log_handle = CreateFile (file,
GENERIC_WRITE,
FILE_SHARE_READ,
&saAttr,
append ? OPEN_ALWAYS : CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (log_handle == INVALID_HANDLE_VALUE)
{
msg (M_WARN|M_ERRNO, "Warning: cannot open --log file: %s", file);
return;
}
/* append to logfile? */
if (append)
{
if (SetFilePointer (log_handle, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER)
msg (M_ERR, "Error: cannot seek to end of --log file: %s", file);
}
/* save original stderr for password prompts */
orig_stderr = GetStdHandle (STD_ERROR_HANDLE);
#if 0 /* seems not be necessary with stdout/stderr redirection below*/
/* set up for redirection */
if (!SetStdHandle (STD_OUTPUT_HANDLE, log_handle)
|| !SetStdHandle (STD_ERROR_HANDLE, log_handle))
msg (M_ERR, "Error: cannot redirect stdout/stderr to --log file: %s", file);
#endif
/* direct stdout/stderr to point to log_handle */
log_fd = _open_osfhandle ((intptr_t)log_handle, _O_TEXT);
if (log_fd == -1)
msg (M_ERR, "Error: --log redirect failed due to _open_osfhandle failure");
/* open log_handle as FILE stream */
ASSERT (msgfp == NULL);
msgfp = _fdopen (log_fd, "w");
if (msgfp == NULL)
msg (M_ERR, "Error: --log redirect failed due to _fdopen");
/* redirect C-library stdout/stderr to log file */
if (_dup2 (log_fd, 1) == -1 || _dup2 (log_fd, 2) == -1)
msg (M_WARN, "Error: --log redirect of stdout/stderr failed");
std_redir = true;
}
#elif defined(HAVE_DUP2)
if (!std_redir)
{
int out = open (file,
O_CREAT | O_WRONLY | (append ? O_APPEND : O_TRUNC),
S_IRUSR | S_IWUSR);
if (out < 0)
{
msg (M_WARN|M_ERRNO, "Warning: Error redirecting stdout/stderr to --log file: %s", file);
return;
}
if (dup2 (out, 1) == -1)
msg (M_ERR, "--log file redirection error on stdout");
if (dup2 (out, 2) == -1)
msg (M_ERR, "--log file redirection error on stderr");
if (out > 2)
close (out);
std_redir = true;
}
#else
msg (M_WARN, "WARNING: The --log option is not supported on this OS because it lacks the dup2 function");
#endif
}
/*
* Functions used to check return status
* of I/O operations.
*/
unsigned int x_cs_info_level; /* GLOBAL */
unsigned int x_cs_verbose_level; /* GLOBAL */
unsigned int x_cs_err_delay_ms; /* GLOBAL */
void
reset_check_status ()
{
x_cs_info_level = 0;
x_cs_verbose_level = 0;
}
void
set_check_status (unsigned int info_level, unsigned int verbose_level)
{
x_cs_info_level = info_level;
x_cs_verbose_level = verbose_level;
}
/*
* Called after most socket or tun/tap operations, via the inline
* function check_status().
*
* Decide if we should print an error message, and see if we can
* extract any useful info from the error, such as a Path MTU hint
* from the OS.
*/
void
x_check_status (int status,
const char *description,
struct link_socket *sock,
struct tuntap *tt)
{
const int my_errno = (sock ? openvpn_errno_socket () : (int)openvpn_errno ());
const char *extended_msg = NULL;
msg (x_cs_verbose_level, "%s %s returned %d",
sock ? proto2ascii (sock->info.proto, true) : "",
description,
status);
if (status < 0)
{
struct gc_arena gc = gc_new ();
#if EXTENDED_SOCKET_ERROR_CAPABILITY
/* get extended socket error message and possible PMTU hint from OS */
if (sock)
{
int mtu;
extended_msg = format_extended_socket_error (sock->sd, &mtu, &gc);
if (mtu > 0 && sock->mtu != mtu)
{
sock->mtu = mtu;
sock->info.mtu_changed = true;
}
}
#elif defined(WIN32)
/* get possible driver error from TAP-Win32 driver */
extended_msg = tap_win32_getinfo (tt, &gc);
#endif
if (!ignore_sys_error (my_errno))
{
if (extended_msg)
msg (x_cs_info_level, "%s %s [%s]: %s (code=%d)",
description,
sock ? proto2ascii (sock->info.proto, true) : "",
extended_msg,
strerror_ts (my_errno, &gc),
my_errno);
else
msg (x_cs_info_level, "%s %s: %s (code=%d)",
description,
sock ? proto2ascii (sock->info.proto, true) : "",
strerror_ts (my_errno, &gc),
my_errno);
if (x_cs_err_delay_ms)
sleep_milliseconds (x_cs_err_delay_ms);
}
gc_free (&gc);
}
}
/*
* In multiclient mode, put a client-specific prefix
* before each message.
*/
const char *x_msg_prefix; /* GLOBAL */
#ifdef USE_PTHREAD
pthread_key_t x_msg_prefix_key; /* GLOBAL */
#endif
/*
* Allow MSG to be redirected through a virtual_output object
*/
const struct virtual_output *x_msg_virtual_output; /* GLOBAL */
/*
* Init thread-local variables
*/
void
msg_thread_init (void)
{
#ifdef USE_PTHREAD
ASSERT (!pthread_key_create (&x_msg_prefix_key, NULL));
#endif
}
void
msg_thread_uninit (void)
{
#ifdef USE_PTHREAD
pthread_key_delete (x_msg_prefix_key);
#endif
}
/*
* Exiting.
*/
void
openvpn_exit (const int status)
{
if (!forked)
{
void tun_abort();
#ifdef ENABLE_PLUGIN
void plugin_abort (void);
#endif
tun_abort();
#ifdef WIN32
uninit_win32 ();
#endif
close_syslog ();
#ifdef ENABLE_PLUGIN
plugin_abort ();
#endif
#if PORT_SHARE
if (port_share)
port_share_abort (port_share);
#endif
#ifdef ABORT_ON_ERROR
if (status == OPENVPN_EXIT_STATUS_ERROR)
abort ();
#endif
if (status == OPENVPN_EXIT_STATUS_GOOD)
perf_output_results ();
}
exit (status);
}
/*
* Translate msg flags into a string
*/
const char *
msg_flags_string (const unsigned int flags, struct gc_arena *gc)
{
struct buffer out = alloc_buf_gc (16, gc);
if (flags == M_INFO)
buf_printf (&out, "I");
if (flags & M_FATAL)
buf_printf (&out, "F");
if (flags & M_NONFATAL)
buf_printf (&out, "N");
if (flags & M_WARN)
buf_printf (&out, "W");
if (flags & M_DEBUG)
buf_printf (&out, "D");
return BSTR (&out);
}
#ifdef ENABLE_DEBUG
void
crash (void)
{
char *null = NULL;
*null = 0;
}
#endif
#ifdef WIN32
const char *
strerror_win32 (DWORD errnum, struct gc_arena *gc)
{
/*
* This code can be omitted, though often the Windows
* WSA error messages are less informative than the
* Posix equivalents.
*/
#if 1
switch (errnum) {
/*
* When the TAP-Win32 driver returns STATUS_UNSUCCESSFUL, this code
* gets returned to user space.
*/
case ERROR_GEN_FAILURE:
return "General failure (ERROR_GEN_FAILURE)";
case ERROR_IO_PENDING:
return "I/O Operation in progress (ERROR_IO_PENDING)";
case WSA_IO_INCOMPLETE:
return "I/O Operation in progress (WSA_IO_INCOMPLETE)";
case WSAEINTR:
return "Interrupted system call (WSAEINTR)";
case WSAEBADF:
return "Bad file number (WSAEBADF)";
case WSAEACCES:
return "Permission denied (WSAEACCES)";
case WSAEFAULT:
return "Bad address (WSAEFAULT)";
case WSAEINVAL:
return "Invalid argument (WSAEINVAL)";
case WSAEMFILE:
return "Too many open files (WSAEMFILE)";
case WSAEWOULDBLOCK:
return "Operation would block (WSAEWOULDBLOCK)";
case WSAEINPROGRESS:
return "Operation now in progress (WSAEINPROGRESS)";
case WSAEALREADY:
return "Operation already in progress (WSAEALREADY)";
case WSAEDESTADDRREQ:
return "Destination address required (WSAEDESTADDRREQ)";
case WSAEMSGSIZE:
return "Message too long (WSAEMSGSIZE)";
case WSAEPROTOTYPE:
return "Protocol wrong type for socket (WSAEPROTOTYPE)";
case WSAENOPROTOOPT:
return "Bad protocol option (WSAENOPROTOOPT)";
case WSAEPROTONOSUPPORT:
return "Protocol not supported (WSAEPROTONOSUPPORT)";
case WSAESOCKTNOSUPPORT:
return "Socket type not supported (WSAESOCKTNOSUPPORT)";
case WSAEOPNOTSUPP:
return "Operation not supported on socket (WSAEOPNOTSUPP)";
case WSAEPFNOSUPPORT:
return "Protocol family not supported (WSAEPFNOSUPPORT)";
case WSAEAFNOSUPPORT:
return "Address family not supported by protocol family (WSAEAFNOSUPPORT)";
case WSAEADDRINUSE:
return "Address already in use (WSAEADDRINUSE)";
case WSAENETDOWN:
return "Network is down (WSAENETDOWN)";
case WSAENETUNREACH:
return "Network is unreachable (WSAENETUNREACH)";
case WSAENETRESET:
return "Net dropped connection or reset (WSAENETRESET)";
case WSAECONNABORTED:
return "Software caused connection abort (WSAECONNABORTED)";
case WSAECONNRESET:
return "Connection reset by peer (WSAECONNRESET)";
case WSAENOBUFS:
return "No buffer space available (WSAENOBUFS)";
case WSAEISCONN:
return "Socket is already connected (WSAEISCONN)";
case WSAENOTCONN:
return "Socket is not connected (WSAENOTCONN)";
case WSAETIMEDOUT:
return "Connection timed out (WSAETIMEDOUT)";
case WSAECONNREFUSED:
return "Connection refused (WSAECONNREFUSED)";
case WSAELOOP:
return "Too many levels of symbolic links (WSAELOOP)";
case WSAENAMETOOLONG:
return "File name too long (WSAENAMETOOLONG)";
case WSAEHOSTDOWN:
return "Host is down (WSAEHOSTDOWN)";
case WSAEHOSTUNREACH:
return "No Route to Host (WSAEHOSTUNREACH)";
case WSAENOTEMPTY:
return "Directory not empty (WSAENOTEMPTY)";
case WSAEPROCLIM:
return "Too many processes (WSAEPROCLIM)";
case WSAEUSERS:
return "Too many users (WSAEUSERS)";
case WSAEDQUOT:
return "Disc Quota Exceeded (WSAEDQUOT)";
case WSAESTALE:
return "Stale NFS file handle (WSAESTALE)";
case WSASYSNOTREADY:
return "Network SubSystem is unavailable (WSASYSNOTREADY)";
case WSAVERNOTSUPPORTED:
return "WINSOCK DLL Version out of range (WSAVERNOTSUPPORTED)";
case WSANOTINITIALISED:
return "Successful WSASTARTUP not yet performed (WSANOTINITIALISED)";
case WSAEREMOTE:
return "Too many levels of remote in path (WSAEREMOTE)";
case WSAHOST_NOT_FOUND:
return "Host not found (WSAHOST_NOT_FOUND)";
default:
break;
}
#endif
/* format a windows error message */
{
char message[256];
struct buffer out = alloc_buf_gc (256, gc);
const int status = FormatMessage (
FORMAT_MESSAGE_IGNORE_INSERTS
| FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_ARGUMENT_ARRAY,
NULL,
errnum,
0,
message,
sizeof (message),
NULL);
if (!status)
{
buf_printf (&out, "[Unknown Win32 Error]");
}
else
{
char *cp;
for (cp = message; *cp != '\0'; ++cp)
{
if (*cp == '\n' || *cp == '\r')
*cp = ' ';
}
buf_printf(&out, "%s", message);
}
return BSTR (&out);
}
}
#endif

365
error.h Normal file
View file

@ -0,0 +1,365 @@
/*
* OpenVPN -- An application to securely tunnel IP networks
* over a single TCP/UDP port, with support for SSL/TLS-based
* session authentication and key exchange,
* packet encryption, packet authentication, and
* packet compression.
*
* Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* 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 (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef ERROR_H
#define ERROR_H
#include "basic.h"
#include "thread.h"
/* #define ABORT_ON_ERROR */
#ifdef ENABLE_PKCS11
#define ERR_BUF_SIZE 8192
#else
#define ERR_BUF_SIZE 1280
#endif
struct gc_arena;
/*
* Where should messages be printed before syslog is opened?
* Not used if OPENVPN_DEBUG_COMMAND_LINE is defined.
*/
#define OPENVPN_MSG_FP stdout
#define OPENVPN_ERROR_FP stderr
/*
* Exit status codes
*/
#define OPENVPN_EXIT_STATUS_GOOD 0
#define OPENVPN_EXIT_STATUS_ERROR 1
#define OPENVPN_EXIT_STATUS_USAGE 1
#define OPENVPN_EXIT_STATUS_CANNOT_OPEN_DEBUG_FILE 1
/*
* Special command line debugging mode.
* If OPENVPN_DEBUG_COMMAND_LINE
* is defined, contents of argc/argv will
* be dumped to OPENVPN_DEBUG_FILE as well
* as all other OpenVPN messages.
*/
/* #define OPENVPN_DEBUG_COMMAND_LINE */
#define OPENVPN_DEBUG_FILE PACKAGE ".log"
/* String and Error functions */
#ifdef WIN32
# define openvpn_errno() GetLastError()
# define openvpn_errno_socket() WSAGetLastError()
# define openvpn_strerror(e, gc) strerror_win32(e, gc)
const char *strerror_win32 (DWORD errnum, struct gc_arena *gc);
#else
# define openvpn_errno() errno
# define openvpn_errno_socket() errno
# define openvpn_strerror(x, gc) strerror(x)
#endif
/*
* These globals should not be accessed directly,
* but rather through macros or inline functions defined below.
*/
extern unsigned int x_debug_level;
extern int x_msg_line_num;
/* msg() flags */
#define M_DEBUG_LEVEL (0x0F) /* debug level mask */
#define M_FATAL (1<<4) /* exit program */
#define M_NONFATAL (1<<5) /* non-fatal error */
#define M_WARN (1<<6) /* call syslog with LOG_WARNING */
#define M_DEBUG (1<<7)
#define M_ERRNO (1<<8) /* show errno description */
#define M_ERRNO_SOCK (1<<9) /* show socket errno description */
#define M_SSL (1<<10) /* show SSL error */
#define M_NOMUTE (1<<11) /* don't do mute processing */
#define M_NOPREFIX (1<<12) /* don't show date/time prefix */
#define M_USAGE_SMALL (1<<13) /* fatal options error, call usage_small */
#define M_MSG_VIRT_OUT (1<<14) /* output message through msg_status_output callback */
#define M_OPTERR (1<<15) /* print "Options error:" prefix */
#define M_NOLF (1<<16) /* don't print new line */
#define M_NOIPREFIX (1<<17) /* don't print instance prefix */
/* flag combinations which are frequently used */
#define M_ERR (M_FATAL | M_ERRNO)
#define M_SOCKERR (M_FATAL | M_ERRNO_SOCK)
#define M_SSLERR (M_FATAL | M_SSL)
#define M_USAGE (M_USAGE_SMALL | M_NOPREFIX | M_OPTERR)
#define M_CLIENT (M_MSG_VIRT_OUT | M_NOMUTE | M_NOIPREFIX)
/*
* Mute levels are designed to avoid large numbers of
* mostly similar messages clogging the log file.
*
* A mute level of 0 is always printed.
*/
#define MUTE_LEVEL_SHIFT 24
#define MUTE_LEVEL_MASK 0xFF
#define ENCODE_MUTE_LEVEL(mute_level) (((mute_level) & MUTE_LEVEL_MASK) << MUTE_LEVEL_SHIFT)
#define DECODE_MUTE_LEVEL(flags) (((flags) >> MUTE_LEVEL_SHIFT) & MUTE_LEVEL_MASK)
/*
* log_level: verbosity level n (--verb n) must be >= log_level to print.
* mute_level: don't print more than n (--mute n) consecutive messages at
* a given mute level, or if 0 disable muting and print everything.
*
* Mask map:
* Bits 0-3: log level
* Bits 4-23: M_x flags
* Bits 24-31: mute level
*/
#define LOGLEV(log_level, mute_level, other) ((log_level) | ENCODE_MUTE_LEVEL(mute_level) | other)
/*
* If compiler supports variable arguments in macros, define
* msg() as a macro for optimization win.
*/
bool dont_mute (unsigned int flags); /* check muting filter */
#define MSG_TEST(flags) (unlikely((((unsigned int)flags) & M_DEBUG_LEVEL) <= x_debug_level) && dont_mute (flags))
#if defined(HAVE_CPP_VARARG_MACRO_ISO) && !defined(__LCLINT__)
# define HAVE_VARARG_MACROS
# define msg(flags, ...) do { if (MSG_TEST(flags)) x_msg((flags), __VA_ARGS__); } while (false)
# ifdef ENABLE_DEBUG
# define dmsg(flags, ...) do { if (MSG_TEST(flags)) x_msg((flags), __VA_ARGS__); } while (false)
# else
# define dmsg(flags, ...)
# endif
#elif defined(HAVE_CPP_VARARG_MACRO_GCC) && !defined(__LCLINT__)
# define HAVE_VARARG_MACROS
# define msg(flags, args...) do { if (MSG_TEST(flags)) x_msg((flags), args); } while (false)
# ifdef ENABLE_DEBUG
# define dmsg(flags, args...) do { if (MSG_TEST(flags)) x_msg((flags), args); } while (false)
# else
# define dmsg(flags, args...)
# endif
#else
# if !PEDANTIC
# ifdef _MSC_VER
# pragma message("this compiler appears to lack vararg macros which will cause a significant degradation in efficiency")
# else
# warning this compiler appears to lack vararg macros which will cause a significant degradation in efficiency (you can ignore this warning if you are using LCLINT)
# endif
# endif
# define msg x_msg
# define dmsg x_msg
#endif
void x_msg (const unsigned int flags, const char *format, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 2, 3)))
#endif
; /* should be called via msg above */
/*
* Function prototypes
*/
void error_reset (void);
/* route errors to stderr that would normally go to stdout */
void errors_to_stderr (void);
void set_suppress_timestamps (bool suppressed);
#define SDL_CONSTRAIN (1<<0)
bool set_debug_level (const int level, const unsigned int flags);
bool set_mute_cutoff (const int cutoff);
int get_debug_level (void);
int get_mute_cutoff (void);
const char *msg_flags_string (const unsigned int flags, struct gc_arena *gc);
/*
* File to print messages to before syslog is opened.
*/
FILE *msg_fp(const unsigned int flags);
/* Fatal logic errors */
#define ASSERT(x) do { if (!(x)) assert_failed(__FILE__, __LINE__); } while (false)
void assert_failed (const char *filename, int line);
#ifdef ENABLE_DEBUG
void crash (void); /* force a segfault (debugging only) */
#endif
/* Inline functions */
static inline bool
check_debug_level (unsigned int level)
{
return (level & M_DEBUG_LEVEL) <= x_debug_level;
}
/* Call if we forked */
void msg_forked (void);
/* syslog output */
void open_syslog (const char *pgmname, bool stdio_to_null);
void close_syslog ();
/* log file output */
void redirect_stdout_stderr (const char *file, bool append);
#ifdef WIN32
/* get original stderr handle, even if redirected by --log/--log-append */
HANDLE get_orig_stderr (void);
#endif
/* exit program */
void openvpn_exit (const int status);
/*
* Check the return status of read/write routines.
*/
struct link_socket;
struct tuntap;
extern unsigned int x_cs_info_level;
extern unsigned int x_cs_verbose_level;
extern unsigned int x_cs_err_delay_ms;
void reset_check_status (void);
void set_check_status (unsigned int info_level, unsigned int verbose_level);
void x_check_status (int status,
const char *description,
struct link_socket *sock,
struct tuntap *tt);
static inline void
check_status (int status, const char *description, struct link_socket *sock, struct tuntap *tt)
{
if (status < 0 || check_debug_level (x_cs_verbose_level))
x_check_status (status, description, sock, tt);
}
static inline void
set_check_status_error_delay (unsigned int milliseconds)
{
x_cs_err_delay_ms = milliseconds;
}
/*
* In multiclient mode, put a client-specific prefix
* before each message.
*
* TODO: x_msg_prefix should be thread-local
*/
extern const char *x_msg_prefix;
#ifdef USE_PTHREAD
extern pthread_key_t x_msg_prefix_key;
#endif
void msg_thread_init (void);
void msg_thread_uninit (void);
static inline void
msg_set_prefix (const char *prefix)
{
#ifdef USE_PTHREAD
if (openvpn_thread_enabled ())
{
ASSERT (!pthread_setspecific (x_msg_prefix_key, prefix));
}
else
#endif
x_msg_prefix = prefix;
}
static inline const char *
msg_get_prefix (void)
{
#ifdef USE_PTHREAD
if (openvpn_thread_enabled ())
return (const char *) pthread_getspecific (x_msg_prefix_key);
else
#endif
return x_msg_prefix;
}
/*
* Allow MSG to be redirected through a virtual_output object
*/
struct virtual_output;
extern const struct virtual_output *x_msg_virtual_output;
static inline void
msg_set_virtual_output (const struct virtual_output *vo)
{
x_msg_virtual_output = vo;
}
static inline const struct virtual_output *
msg_get_virtual_output (void)
{
return x_msg_virtual_output;
}
/*
* Return true if this is a system error
* which can be safely ignored.
*/
static inline bool
ignore_sys_error (const int err)
{
/* I/O operation pending */
#ifdef WIN32
if (err == WSAEWOULDBLOCK || err == WSAEINVAL)
return true;
#else
if (err == EAGAIN)
return true;
#endif
#if 0 /* if enabled, suppress ENOBUFS errors */
#ifdef ENOBUFS
/* No buffer space available */
if (err == ENOBUFS)
return true;
#endif
#endif
return false;
}
#include "errlevel.h"
#endif

1055
event.c Normal file

File diff suppressed because it is too large Load diff

158
event.h Normal file
View file

@ -0,0 +1,158 @@
/*
* OpenVPN -- An application to securely tunnel IP networks
* over a single TCP/UDP port, with support for SSL/TLS-based
* session authentication and key exchange,
* packet encryption, packet authentication, and
* packet compression.
*
* Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* 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 (see the file COPYING included with this
* distribution); if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef EVENT_H
#define EVENT_H
#include "win32.h"
#include "sig.h"
#include "perf.h"
/*
* rwflags passed to event_ctl and returned by
* struct event_set_return.
*/
#define EVENT_UNDEF 4
#define EVENT_READ (1<<0)
#define EVENT_WRITE (1<<1)
/*
* Initialization flags passed to event_set_init
*/
#define EVENT_METHOD_US_TIMEOUT (1<<0)
#define EVENT_METHOD_FAST (1<<1)
#ifdef WIN32
typedef const struct rw_handle *event_t;
#define UNDEFINED_EVENT (NULL)
#else
typedef int event_t;
#define UNDEFINED_EVENT (-1)
#endif
struct event_set;
struct event_set_return;
struct event_set_functions
{
void (*free)(struct event_set *es);
void (*reset)(struct event_set *es);
void (*del)(struct event_set *es, event_t event);
void (*ctl)(struct event_set *es, event_t event, unsigned int rwflags, void *arg);
/*
* Return status for wait:
* -1 on signal or error
* 0 on timeout
* length of event_set_return if at least 1 event is returned
*/
int (*wait)(struct event_set *es, const struct timeval *tv, struct event_set_return *out, int outlen);
};
struct event_set_return
{
unsigned int rwflags;
void *arg;
};
struct event_set
{
struct event_set_functions func;
};
/*
* maxevents on input: desired max number of event_t descriptors
* simultaneously set with event_ctl
* maxevents on output: may be modified down, depending on limitations
* of underlying API
* flags: EVENT_METHOD_x flags
*/
struct event_set *event_set_init (int *maxevents, unsigned int flags);
static inline void
event_free (struct event_set *es)
{
if (es)
(*es->func.free)(es);
}
static inline void
event_reset (struct event_set *es)
{
(*es->func.reset)(es);
}
static inline void
event_del (struct event_set *es, event_t event)
{
(*es->func.del)(es, event);
}
static inline void
event_ctl (struct event_set *es, event_t event, unsigned int rwflags, void *arg)
{
(*es->func.ctl)(es, event, rwflags, arg);
}
static inline int
event_wait (struct event_set *es, const struct timeval *tv, struct event_set_return *out, int outlen)
{
int ret;
perf_push (PERF_IO_WAIT);
ret = (*es->func.wait)(es, tv, out, outlen);
perf_pop ();
return ret;
}
static inline void
event_set_return_init (struct event_set_return *esr)
{
esr->rwflags = 0;
esr->arg = NULL;
}
#ifdef WIN32
static inline void
wait_signal (struct event_set *es, void *arg)
{
if (HANDLE_DEFINED (win32_signal.in.read))
event_ctl (es, &win32_signal.in, EVENT_READ, arg);
}
#else
static inline void
wait_signal (struct event_set *es, void *arg)
{
}
#endif
#endif

Some files were not shown because too many files have changed in this diff Show more